blob: 2fdb073cd076367b18caff8b1f2a91d80af1b16b [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Vladimir Serbinenko888d5592013-11-13 17:53:38 +01002
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>
Vladimir Serbinenko888d5592013-11-13 17:53:38 +01009#include <delay.h>
Vladimir Serbinenko75c83872014-09-05 01:01:31 +020010#include <device/azalia_device.h>
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010011#include "pch.h"
12
13#define HDA_ICII_REG 0x68
14#define HDA_ICII_BUSY (1 << 0)
15#define HDA_ICII_VALID (1 << 1)
16
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080017static int set_bits(void *port, u32 mask, u32 val)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010018{
19 u32 reg32;
20 int count;
21
22 /* Write (val & mask) to port */
23 val &= mask;
24 reg32 = read32(port);
25 reg32 &= ~mask;
26 reg32 |= val;
27 write32(port, reg32);
28
29 /* Wait for readback of register to
30 * match what was just written to it
31 */
32 count = 50;
33 do {
34 /* Wait 1ms based on BKDG wait time */
35 mdelay(1);
36 reg32 = read32(port);
37 reg32 &= mask;
38 } while ((reg32 != val) && --count);
39
40 /* Timeout occurred */
41 if (!count)
42 return -1;
43 return 0;
44}
45
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080046static int codec_detect(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010047{
48 u8 reg8;
49
50 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
51 if (set_bits(base + 0x08, 1, 1) == -1)
52 goto no_codec;
53
54 /* Write back the value once reset bit is set. */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080055 write16(base + 0x0,
56 read16(base + 0x0));
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010057
58 /* Read in Codec location (BAR + 0xe)[2..0]*/
59 reg8 = read8(base + 0xe);
60 reg8 &= 0x0f;
61 if (!reg8)
62 goto no_codec;
63
64 return reg8;
65
66no_codec:
67 /* Codec Not found */
68 /* Put HDA back in reset (BAR + 0x8) [0] */
69 set_bits(base + 0x08, 1, 0);
70 printk(BIOS_DEBUG, "Azalia: No codec!\n");
71 return 0;
72}
73
Elyes HAOUASe414a4e2019-01-03 10:40:43 +010074static u32 find_verb(struct device *dev, u32 viddid, const u32 **verb)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010075{
76 int idx=0;
77
78 while (idx < (cim_verb_data_size / sizeof(u32))) {
79 u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
80 if (cim_verb_data[idx] != viddid) {
81 idx += verb_size + 3; // skip verb + header
82 continue;
83 }
84 *verb = &cim_verb_data[idx+3];
85 return verb_size;
86 }
87
88 /* Not all codecs need to load another verb */
89 return 0;
90}
91
92/**
93 * Wait 50usec for the codec to indicate it is ready
94 * no response would imply that the codec is non-operative
95 */
96
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080097static int wait_for_ready(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010098{
99 /* Use a 1msec timeout */
100
101 int timeout = 1000;
102
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200103 while (timeout--) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800104 u32 reg32 = read32(base + HDA_ICII_REG);
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100105 if (!(reg32 & HDA_ICII_BUSY))
106 return 0;
107 udelay(1);
108 }
109
110 return -1;
111}
112
113/**
114 * Wait 50usec for the codec to indicate that it accepted
115 * the previous command. No response would imply that the code
116 * is non-operative
117 */
118
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800119static int wait_for_valid(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100120{
121 u32 reg32;
122
123 /* Send the verb to the codec */
124 reg32 = read32(base + HDA_ICII_REG);
125 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
126 write32(base + HDA_ICII_REG, reg32);
127
128 /* Use a 1msec timeout */
129
130 int timeout = 1000;
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200131 while (timeout--) {
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100132 reg32 = read32(base + HDA_ICII_REG);
133 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
134 HDA_ICII_VALID)
135 return 0;
136 udelay(1);
137 }
138
139 return -1;
140}
141
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800142static void codec_init(struct device *dev, u8 *base, int addr)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100143{
144 u32 reg32;
145 const u32 *verb;
146 u32 verb_size;
147 int i;
148
149 printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
150
151 /* 1 */
152 if (wait_for_ready(base) == -1) {
153 printk(BIOS_DEBUG, " codec not ready.\n");
154 return;
155 }
156
157 reg32 = (addr << 28) | 0x000f0000;
158 write32(base + 0x60, reg32);
159
160 if (wait_for_valid(base) == -1) {
161 printk(BIOS_DEBUG, " codec not valid.\n");
162 return;
163 }
164
165 reg32 = read32(base + 0x64);
166
167 /* 2 */
168 printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
169 verb_size = find_verb(dev, reg32, &verb);
170
171 if (!verb_size) {
172 printk(BIOS_DEBUG, "Azalia: No verb!\n");
173 return;
174 }
175 printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
176
177 /* 3 */
178 for (i = 0; i < verb_size; i++) {
179 if (wait_for_ready(base) == -1)
180 return;
181
182 write32(base + 0x60, verb[i]);
183
184 if (wait_for_valid(base) == -1)
185 return;
186 }
187 printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
188}
189
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800190static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100191{
192 int i;
193 for (i = 3; i >= 0; i--) {
194 if (codec_mask & (1 << i))
195 codec_init(dev, base, i);
196 }
197
198 for (i = 0; i < pc_beep_verbs_size; i++) {
199 if (wait_for_ready(base) == -1)
200 return;
201
202 write32(base + 0x60, pc_beep_verbs[i]);
203
204 if (wait_for_valid(base) == -1)
205 return;
206 }
207}
208
209static void azalia_init(struct device *dev)
210{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800211 u8 *base;
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100212 struct resource *res;
213 u32 codec_mask;
214 u8 reg8;
215 u16 reg16;
216 u32 reg32;
217
218 /* Find base address */
219 res = find_resource(dev, PCI_BASE_ADDRESS_0);
220 if (!res)
221 return;
222
223 // NOTE this will break as soon as the Azalia get's a bar above
224 // 4G. Is there anything we can do about it?
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800225 base = res2mmio(res, 0, 0);
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100226 printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
227
228 if (RCBA32(0x2030) & (1 << 31)) {
229 reg32 = pci_read_config32(dev, 0x120);
230 reg32 &= 0xf8ffff01;
231 reg32 |= (1 << 24); // 2 << 24 for server
232 reg32 |= RCBA32(0x2030) & 0xfe;
233 pci_write_config32(dev, 0x120, reg32);
234
235 reg16 = pci_read_config16(dev, 0x78);
236 reg16 |= (1 << 11);
237 pci_write_config16(dev, 0x78, reg16);
238 } else
239 printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
240
241 reg32 = pci_read_config32(dev, 0x114);
242 reg32 &= ~0xfe;
243 pci_write_config32(dev, 0x114, reg32);
244
245 // Set VCi enable bit
246 reg32 = pci_read_config32(dev, 0x120);
247 reg32 |= (1 << 31);
248 pci_write_config32(dev, 0x120, reg32);
249
250 // Enable HDMI codec:
251 reg32 = pci_read_config32(dev, 0xc4);
252 reg32 |= (1 << 1);
253 pci_write_config32(dev, 0xc4, reg32);
254
255 reg8 = pci_read_config8(dev, 0x43);
256 reg8 |= (1 << 6);
257 pci_write_config8(dev, 0x43, reg8);
258
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100259 reg32 = pci_read_config32(dev, 0xd0);
260 reg32 &= ~(1 << 31);
261 pci_write_config32(dev, 0xd0, reg32);
262
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100263 /* Set Bus Master */
Elyes HAOUAS8b6dfde2020-04-28 09:58:21 +0200264 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100265
266 pci_write_config8(dev, 0x3c, 0x0a); // unused?
267
268 /* Codec Initialization Programming Sequence */
269
270 /* Take controller out of reset */
271 reg32 = read32(base + 0x08);
272 reg32 |= (1 << 0);
273 write32(base + 0x08, reg32);
274 /* Wait 1ms */
275 udelay(1000);
276
277 //
278 reg8 = pci_read_config8(dev, 0x40); // Audio Control
279 reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
280 pci_write_config8(dev, 0x40, reg8);
281
282 reg8 = pci_read_config8(dev, 0x4d); // Docking Status
283 reg8 &= ~(1 << 7); // Docking not supported
284 pci_write_config8(dev, 0x4d, reg8);
285
286 codec_mask = codec_detect(base);
287
288 if (codec_mask) {
289 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
290 codecs_init(dev, base, codec_mask);
291 }
292
293 /* Enable dynamic clock gating */
294 reg8 = pci_read_config8(dev, 0x43);
295 reg8 &= ~0x7;
296 reg8 |= (1 << 2) | (1 << 0);
297 pci_write_config8(dev, 0x43, reg8);
298}
299
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100300static struct pci_operations azalia_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530301 .set_subsystem = pci_dev_set_subsystem,
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100302};
303
304static struct device_operations azalia_ops = {
305 .read_resources = pci_dev_read_resources,
306 .set_resources = pci_dev_set_resources,
307 .enable_resources = pci_dev_enable_resources,
308 .init = azalia_init,
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100309 .ops_pci = &azalia_pci_ops,
310};
311
Felix Singer838fbc72019-11-21 21:23:32 +0100312static const unsigned short pci_device_ids[] = {
313 0x1c20,
314 0x1e20,
315 PCI_DID_INTEL_IBEXPEAK_AUDIO,
316 0
317};
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100318
319static const struct pci_driver pch_azalia __pci_driver = {
320 .ops = &azalia_ops,
321 .vendor = PCI_VENDOR_ID_INTEL,
322 .devices = pci_device_ids,
323};