azalia: Drop unused parameter from `azalia_find_verb`
[coreboot.git] / src / southbridge / intel / i82801gx / azalia.c
blob71f7647ac158ef3c18eeed1475f536fea17a30ae
1 /* SPDX-License-Identifier: GPL-2.0-only */
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>
8 #include <device/mmio.h>
9 #include <delay.h>
10 #include <device/azalia_device.h>
11 #include "chip.h"
12 #include "i82801gx.h"
14 static int codec_detect(u8 *base)
16 u32 reg32;
18 /* Set Bit 0 to 0 to enter reset state (BAR + 0x8)[0] */
19 if (azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, 0) < 0)
20 goto no_codec;
22 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
23 if (azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, HDA_GCTL_CRST) < 0)
24 goto no_codec;
26 /* Read in Codec location (BAR + 0xe)[2..0] */
27 reg32 = read32(base + HDA_STATESTS_REG);
28 reg32 &= 0x0f;
29 if (!reg32)
30 goto no_codec;
32 return reg32;
34 no_codec:
35 /* Codec Not found */
36 /* Put HDA back in reset (BAR + 0x8) [0] */
37 azalia_set_bits(base + HDA_GCTL_REG, 1, 0);
38 printk(BIOS_DEBUG, "Azalia: No codec!\n");
39 return 0;
43 * Wait 50usec for the codec to indicate it is ready.
44 * No response would imply that the codec is non-operative.
47 static int wait_for_ready(u8 *base)
49 /* Use a 50 usec timeout - the Linux kernel uses the same duration */
50 int timeout = 50;
52 while (timeout--) {
53 u32 reg32 = read32(base + HDA_ICII_REG);
54 if (!(reg32 & HDA_ICII_BUSY))
55 return 0;
56 udelay(1);
59 return -1;
63 * Wait 50usec for the codec to indicate that it accepted the previous command.
64 * No response would imply that the code is non-operative.
67 static int wait_for_valid(u8 *base)
69 u32 reg32;
70 /* Use a 50 usec timeout - the Linux kernel uses the same duration */
71 int timeout = 50;
73 /* Send the verb to the codec */
74 reg32 = read32(base + HDA_ICII_REG);
75 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
76 write32(base + HDA_ICII_REG, reg32);
78 while (timeout--) {
79 reg32 = read32(base + HDA_ICII_REG);
80 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)
81 return 0;
82 udelay(1);
85 return -1;
88 static void codec_init(struct device *dev, u8 *base, int addr)
90 u32 reg32;
91 const u32 *verb;
92 u32 verb_size;
93 int i;
95 printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
97 /* 1 */
98 if (wait_for_ready(base) < 0) {
99 printk(BIOS_DEBUG, " codec not ready.\n");
100 return;
103 reg32 = (addr << 28) | 0x000f0000;
104 write32(base + HDA_IC_REG, reg32);
106 if (wait_for_valid(base) < 0) {
107 printk(BIOS_DEBUG, " codec not valid.\n");
108 return;
111 /* 2 */
112 reg32 = read32(base + HDA_IR_REG);
113 printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
114 verb_size = azalia_find_verb(reg32, &verb);
116 if (!verb_size) {
117 printk(BIOS_DEBUG, "Azalia: No verb!\n");
118 return;
120 printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
122 /* 3 */
123 for (i = 0; i < verb_size; i++) {
124 if (wait_for_ready(base) < 0)
125 return;
127 write32(base + HDA_IC_REG, verb[i]);
129 if (wait_for_valid(base) < 0)
130 return;
132 printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
135 static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
137 int i;
139 for (i = 2; i >= 0; i--) {
140 if (codec_mask & (1 << i))
141 codec_init(dev, base, i);
145 static void azalia_init(struct device *dev)
147 u8 *base;
148 struct resource *res;
149 u32 codec_mask;
150 u8 reg8;
152 // ESD
153 pci_update_config32(dev, 0x134, ~(0xff << 16), 2 << 16);
155 // Link1 description
156 pci_update_config32(dev, 0x140, ~(0xff << 16), 2 << 16);
158 // Port VC0 Resource Control Register
159 pci_update_config32(dev, 0x114, ~(0xff << 0), 1);
161 // VCi traffic class
162 pci_or_config8(dev, 0x44, 7 << 0); // TC7
164 // VCi Resource Control
165 pci_or_config32(dev, 0x120, (1 << 31) | (1 << 24) | (0x80 << 0)); /* VCi ID and map */
167 /* Set Bus Master */
168 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
170 pci_write_config8(dev, 0x3c, 0x0a); // unused?
172 // TODO Actually check if we're AC97 or HDA instead of hardcoding this
173 // here, in devicetree.cb and/or romstage.c.
174 reg8 = pci_read_config8(dev, 0x40);
175 reg8 |= (1 << 3); // Clear Clock Detect Bit
176 pci_write_config8(dev, 0x40, reg8);
177 reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over
178 pci_write_config8(dev, 0x40, reg8);
179 reg8 |= (1 << 2); // Enable clock detection
180 pci_write_config8(dev, 0x40, reg8);
181 mdelay(1);
182 reg8 = pci_read_config8(dev, 0x40);
183 printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97");
185 // Select Azalia mode. This needs to be controlled via devicetree.cb
186 pci_or_config8(dev, 0x40, 1); // Audio Control
188 // Docking not supported
189 pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
191 res = find_resource(dev, PCI_BASE_ADDRESS_0);
192 if (!res)
193 return;
195 // NOTE this will break as soon as the Azalia get's a bar above 4G.
196 // Is there anything we can do about it?
197 base = res2mmio(res, 0, 0);
198 printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
199 codec_mask = codec_detect(base);
201 if (codec_mask) {
202 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
203 codecs_init(dev, base, codec_mask);
207 static struct device_operations azalia_ops = {
208 .read_resources = pci_dev_read_resources,
209 .set_resources = pci_dev_set_resources,
210 .enable_resources = pci_dev_enable_resources,
211 .init = azalia_init,
212 .enable = i82801gx_enable,
213 .ops_pci = &pci_dev_ops_pci,
216 /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
217 static const struct pci_driver i82801gx_azalia __pci_driver = {
218 .ops = &azalia_ops,
219 .vendor = PCI_VENDOR_ID_INTEL,
220 .device = 0x27d8,