blob: bb8aec40d9c468b5475066cb630a822f03a4d4b6 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Arthur Heymans7b9c1392017-04-09 20:40:39 +02002
3#include <console/console.h>
4#include <device/device.h>
5#include <device/pci.h>
6#include <device/pci_ids.h>
7#include <device/pci_ops.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02008#include <device/mmio.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +02009#include <delay.h>
10#include <device/azalia_device.h>
Kyösti Mälkki12b121c2019-08-18 16:33:39 +030011#include "chip.h"
Arthur Heymans349e0852017-04-09 20:48:37 +020012#include "i82801jx.h"
Arthur Heymans7b9c1392017-04-09 20:40:39 +020013
Arthur Heymans7b9c1392017-04-09 20:40:39 +020014static int codec_detect(u8 *base)
15{
16 u32 reg32;
17
Angel Pons2e0053b2020-12-05 19:06:55 +010018 if (azalia_enter_reset(base) < 0)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020019 goto no_codec;
20
Angel Pons7f839f62020-12-05 19:02:14 +010021 if (azalia_exit_reset(base) < 0)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020022 goto no_codec;
23
Elyes HAOUAS6ea24ff2020-08-11 09:21:24 +020024 /* Read in Codec location (BAR + 0xe)[2..0] */
Elyes HAOUAS388c88b2020-08-03 15:36:20 +020025 reg32 = read32(base + HDA_STATESTS_REG);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020026 reg32 &= 0x0f;
27 if (!reg32)
28 goto no_codec;
29
30 return reg32;
31
32no_codec:
Angel Pons2e0053b2020-12-05 19:06:55 +010033 /* Codec not found, put HDA back in reset */
34 azalia_enter_reset(base);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020035 printk(BIOS_DEBUG, "Azalia: No codec!\n");
36 return 0;
37}
38
Arthur Heymans7b9c1392017-04-09 20:40:39 +020039static void azalia_init(struct device *dev)
40{
41 u8 *base;
42 struct resource *res;
43 u32 codec_mask;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020044
45 // ESD
Angel Pons2048cb42020-06-08 02:09:33 +020046 pci_update_config32(dev, 0x134, ~0x00ff0000, 2 << 16);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020047
48 // Link1 description
Angel Pons2048cb42020-06-08 02:09:33 +020049 pci_update_config32(dev, 0x140, ~0x00ff0000, 2 << 16);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020050
51 // Port VC0 Resource Control Register
Angel Pons2048cb42020-06-08 02:09:33 +020052 pci_update_config32(dev, 0x114, ~0x000000ff, 1);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020053
54 // VCi traffic class
Angel Pons7a2864b2020-06-21 13:29:28 +020055 pci_or_config8(dev, 0x44, 7 << 0); // TC7
Arthur Heymans7b9c1392017-04-09 20:40:39 +020056
57 // VCi Resource Control
Angel Pons2048cb42020-06-08 02:09:33 +020058 pci_or_config32(dev, 0x120, (1 << 31) | (1 << 24) | (0x80 << 0)); /* VCi ID and map */
Arthur Heymans7b9c1392017-04-09 20:40:39 +020059
60 /* Set Bus Master */
Elyes HAOUASca4ff252020-04-28 10:29:11 +020061 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020062
Angel Pons2048cb42020-06-08 02:09:33 +020063 // Docking not supported
64 pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
Arthur Heymans7b9c1392017-04-09 20:40:39 +020065
66 /* Lock some R/WO bits by writing their current value. */
Angel Pons2048cb42020-06-08 02:09:33 +020067 pci_update_config32(dev, 0x74, ~0, 0);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020068
Angel Ponsf32ae102021-11-03 13:07:14 +010069 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020070 if (!res)
71 return;
72
Martin Roth26f97f92021-10-01 14:53:22 -060073 // NOTE this will break as soon as the Azalia gets a bar above 4G.
Elyes HAOUAS6ea24ff2020-08-11 09:21:24 +020074 // Is there anything we can do about it?
Arthur Heymans7b9c1392017-04-09 20:40:39 +020075 base = res2mmio(res, 0, 0);
Angel Pons7a2864b2020-06-21 13:29:28 +020076 printk(BIOS_DEBUG, "Azalia: base = %p\n", base);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020077 codec_mask = codec_detect(base);
78
79 if (codec_mask) {
80 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
Angel Ponsaae6b552021-11-10 18:10:38 +010081 azalia_codecs_init(base, codec_mask);
Arthur Heymans7b9c1392017-04-09 20:40:39 +020082 }
83}
84
Arthur Heymans7b9c1392017-04-09 20:40:39 +020085static struct device_operations azalia_ops = {
86 .read_resources = pci_dev_read_resources,
87 .set_resources = pci_dev_set_resources,
88 .enable_resources = pci_dev_enable_resources,
89 .init = azalia_init,
Angel Pons1fc0edd2020-05-31 00:03:28 +020090 .ops_pci = &pci_dev_ops_pci,
Arthur Heymans7b9c1392017-04-09 20:40:39 +020091};
92
Arthur Heymans349e0852017-04-09 20:48:37 +020093static const unsigned short pci_device_ids[] = {
94 0x3a3e,
95 0x3a6e,
96 0
97};
98
99static const struct pci_driver i82801jx_azalia __pci_driver = {
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200100 .ops = &azalia_ops,
101 .vendor = PCI_VENDOR_ID_INTEL,
Arthur Heymans349e0852017-04-09 20:48:37 +0200102 .devices = pci_device_ids,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200103};