blob: 3cec2a9d9ffebe10fc23df17dd0fd04ac21bf1ca [file] [log] [blame]
Vladimir Serbinenko888d5592013-11-13 17:53:38 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 * Copyright (C) 2008-2009 coresystems GmbH
6 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010016 */
17
18#include <console/console.h>
19#include <device/device.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
22#include <device/pci_ops.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020023#include <device/mmio.h>
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010024#include <delay.h>
Vladimir Serbinenko75c83872014-09-05 01:01:31 +020025#include <device/azalia_device.h>
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010026#include "pch.h"
27
28#define HDA_ICII_REG 0x68
29#define HDA_ICII_BUSY (1 << 0)
30#define HDA_ICII_VALID (1 << 1)
31
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080032static int set_bits(void *port, u32 mask, u32 val)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010033{
34 u32 reg32;
35 int count;
36
37 /* Write (val & mask) to port */
38 val &= mask;
39 reg32 = read32(port);
40 reg32 &= ~mask;
41 reg32 |= val;
42 write32(port, reg32);
43
44 /* Wait for readback of register to
45 * match what was just written to it
46 */
47 count = 50;
48 do {
49 /* Wait 1ms based on BKDG wait time */
50 mdelay(1);
51 reg32 = read32(port);
52 reg32 &= mask;
53 } while ((reg32 != val) && --count);
54
55 /* Timeout occurred */
56 if (!count)
57 return -1;
58 return 0;
59}
60
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080061static int codec_detect(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010062{
63 u8 reg8;
64
65 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
66 if (set_bits(base + 0x08, 1, 1) == -1)
67 goto no_codec;
68
69 /* Write back the value once reset bit is set. */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080070 write16(base + 0x0,
71 read16(base + 0x0));
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010072
73 /* Read in Codec location (BAR + 0xe)[2..0]*/
74 reg8 = read8(base + 0xe);
75 reg8 &= 0x0f;
76 if (!reg8)
77 goto no_codec;
78
79 return reg8;
80
81no_codec:
82 /* Codec Not found */
83 /* Put HDA back in reset (BAR + 0x8) [0] */
84 set_bits(base + 0x08, 1, 0);
85 printk(BIOS_DEBUG, "Azalia: No codec!\n");
86 return 0;
87}
88
Elyes HAOUASe414a4e2019-01-03 10:40:43 +010089static u32 find_verb(struct device *dev, u32 viddid, const u32 **verb)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +010090{
91 int idx=0;
92
93 while (idx < (cim_verb_data_size / sizeof(u32))) {
94 u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
95 if (cim_verb_data[idx] != viddid) {
96 idx += verb_size + 3; // skip verb + header
97 continue;
98 }
99 *verb = &cim_verb_data[idx+3];
100 return verb_size;
101 }
102
103 /* Not all codecs need to load another verb */
104 return 0;
105}
106
107/**
108 * Wait 50usec for the codec to indicate it is ready
109 * no response would imply that the codec is non-operative
110 */
111
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800112static int wait_for_ready(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100113{
114 /* Use a 1msec timeout */
115
116 int timeout = 1000;
117
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200118 while (timeout--) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800119 u32 reg32 = read32(base + HDA_ICII_REG);
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100120 if (!(reg32 & HDA_ICII_BUSY))
121 return 0;
122 udelay(1);
123 }
124
125 return -1;
126}
127
128/**
129 * Wait 50usec for the codec to indicate that it accepted
130 * the previous command. No response would imply that the code
131 * is non-operative
132 */
133
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800134static int wait_for_valid(u8 *base)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100135{
136 u32 reg32;
137
138 /* Send the verb to the codec */
139 reg32 = read32(base + HDA_ICII_REG);
140 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
141 write32(base + HDA_ICII_REG, reg32);
142
143 /* Use a 1msec timeout */
144
145 int timeout = 1000;
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200146 while (timeout--) {
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100147 reg32 = read32(base + HDA_ICII_REG);
148 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
149 HDA_ICII_VALID)
150 return 0;
151 udelay(1);
152 }
153
154 return -1;
155}
156
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800157static void codec_init(struct device *dev, u8 *base, int addr)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100158{
159 u32 reg32;
160 const u32 *verb;
161 u32 verb_size;
162 int i;
163
164 printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
165
166 /* 1 */
167 if (wait_for_ready(base) == -1) {
168 printk(BIOS_DEBUG, " codec not ready.\n");
169 return;
170 }
171
172 reg32 = (addr << 28) | 0x000f0000;
173 write32(base + 0x60, reg32);
174
175 if (wait_for_valid(base) == -1) {
176 printk(BIOS_DEBUG, " codec not valid.\n");
177 return;
178 }
179
180 reg32 = read32(base + 0x64);
181
182 /* 2 */
183 printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
184 verb_size = find_verb(dev, reg32, &verb);
185
186 if (!verb_size) {
187 printk(BIOS_DEBUG, "Azalia: No verb!\n");
188 return;
189 }
190 printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
191
192 /* 3 */
193 for (i = 0; i < verb_size; i++) {
194 if (wait_for_ready(base) == -1)
195 return;
196
197 write32(base + 0x60, verb[i]);
198
199 if (wait_for_valid(base) == -1)
200 return;
201 }
202 printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
203}
204
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800205static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100206{
207 int i;
208 for (i = 3; i >= 0; i--) {
209 if (codec_mask & (1 << i))
210 codec_init(dev, base, i);
211 }
212
213 for (i = 0; i < pc_beep_verbs_size; i++) {
214 if (wait_for_ready(base) == -1)
215 return;
216
217 write32(base + 0x60, pc_beep_verbs[i]);
218
219 if (wait_for_valid(base) == -1)
220 return;
221 }
222}
223
224static void azalia_init(struct device *dev)
225{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800226 u8 *base;
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100227 struct resource *res;
228 u32 codec_mask;
229 u8 reg8;
230 u16 reg16;
231 u32 reg32;
232
233 /* Find base address */
234 res = find_resource(dev, PCI_BASE_ADDRESS_0);
235 if (!res)
236 return;
237
238 // NOTE this will break as soon as the Azalia get's a bar above
239 // 4G. Is there anything we can do about it?
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800240 base = res2mmio(res, 0, 0);
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100241 printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
242
243 if (RCBA32(0x2030) & (1 << 31)) {
244 reg32 = pci_read_config32(dev, 0x120);
245 reg32 &= 0xf8ffff01;
246 reg32 |= (1 << 24); // 2 << 24 for server
247 reg32 |= RCBA32(0x2030) & 0xfe;
248 pci_write_config32(dev, 0x120, reg32);
249
250 reg16 = pci_read_config16(dev, 0x78);
251 reg16 |= (1 << 11);
252 pci_write_config16(dev, 0x78, reg16);
253 } else
254 printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
255
256 reg32 = pci_read_config32(dev, 0x114);
257 reg32 &= ~0xfe;
258 pci_write_config32(dev, 0x114, reg32);
259
260 // Set VCi enable bit
261 reg32 = pci_read_config32(dev, 0x120);
262 reg32 |= (1 << 31);
263 pci_write_config32(dev, 0x120, reg32);
264
265 // Enable HDMI codec:
266 reg32 = pci_read_config32(dev, 0xc4);
267 reg32 |= (1 << 1);
268 pci_write_config32(dev, 0xc4, reg32);
269
270 reg8 = pci_read_config8(dev, 0x43);
271 reg8 |= (1 << 6);
272 pci_write_config8(dev, 0x43, reg8);
273
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100274 reg32 = pci_read_config32(dev, 0xd0);
275 reg32 &= ~(1 << 31);
276 pci_write_config32(dev, 0xd0, reg32);
277
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100278 /* Set Bus Master */
279 reg32 = pci_read_config32(dev, PCI_COMMAND);
280 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
281
282 pci_write_config8(dev, 0x3c, 0x0a); // unused?
283
284 /* Codec Initialization Programming Sequence */
285
286 /* Take controller out of reset */
287 reg32 = read32(base + 0x08);
288 reg32 |= (1 << 0);
289 write32(base + 0x08, reg32);
290 /* Wait 1ms */
291 udelay(1000);
292
293 //
294 reg8 = pci_read_config8(dev, 0x40); // Audio Control
295 reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
296 pci_write_config8(dev, 0x40, reg8);
297
298 reg8 = pci_read_config8(dev, 0x4d); // Docking Status
299 reg8 &= ~(1 << 7); // Docking not supported
300 pci_write_config8(dev, 0x4d, reg8);
301
302 codec_mask = codec_detect(base);
303
304 if (codec_mask) {
305 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
306 codecs_init(dev, base, codec_mask);
307 }
308
309 /* Enable dynamic clock gating */
310 reg8 = pci_read_config8(dev, 0x43);
311 reg8 &= ~0x7;
312 reg8 |= (1 << 2) | (1 << 0);
313 pci_write_config8(dev, 0x43, reg8);
314}
315
Elyes HAOUASbe841402018-05-13 13:40:39 +0200316static void azalia_set_subsystem(struct device *dev, unsigned vendor,
317 unsigned device)
Vladimir Serbinenko888d5592013-11-13 17:53:38 +0100318{
319 if (!vendor || !device) {
320 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
321 pci_read_config32(dev, PCI_VENDOR_ID));
322 } else {
323 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
324 ((device & 0xffff) << 16) | (vendor & 0xffff));
325 }
326}
327
328static struct pci_operations azalia_pci_ops = {
329 .set_subsystem = azalia_set_subsystem,
330};
331
332static struct device_operations azalia_ops = {
333 .read_resources = pci_dev_read_resources,
334 .set_resources = pci_dev_set_resources,
335 .enable_resources = pci_dev_enable_resources,
336 .init = azalia_init,
337 .scan_bus = 0,
338 .ops_pci = &azalia_pci_ops,
339};
340
341static const unsigned short pci_device_ids[] = { 0x1c20, 0x1e20, 0x3b56, 0 };
342
343static const struct pci_driver pch_azalia __pci_driver = {
344 .ops = &azalia_ops,
345 .vendor = PCI_VENDOR_ID_INTEL,
346 .devices = pci_device_ids,
347};