blob: 9c8eaf6bffba3b35a9cdbbd5397df7358cebbb22 [file] [log] [blame]
Stefan Reinauer8e073822012-04-04 00:07:22 +02001/*
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.
Stefan Reinauer8e073822012-04-04 00:07:22 +020016 */
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>
23#include <arch/io.h>
24#include <delay.h>
Vladimir Serbinenko75c83872014-09-05 01:01:31 +020025#include <device/azalia_device.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020026#include "pch.h"
27
28#define HDA_ICII_REG 0x68
Andrew Wuae8d0692013-08-02 19:29:17 +080029#define HDA_ICII_BUSY (1 << 0)
30#define HDA_ICII_VALID (1 << 1)
Stefan Reinauer8e073822012-04-04 00:07:22 +020031
32typedef struct southbridge_intel_bd82x6x_config config_t;
33
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080034static int set_bits(void *port, u32 mask, u32 val)
Stefan Reinauer8e073822012-04-04 00:07:22 +020035{
36 u32 reg32;
37 int count;
38
39 /* Write (val & mask) to port */
40 val &= mask;
41 reg32 = read32(port);
42 reg32 &= ~mask;
43 reg32 |= val;
44 write32(port, reg32);
45
46 /* Wait for readback of register to
47 * match what was just written to it
48 */
49 count = 50;
50 do {
51 /* Wait 1ms based on BKDG wait time */
52 mdelay(1);
53 reg32 = read32(port);
54 reg32 &= mask;
55 } while ((reg32 != val) && --count);
56
57 /* Timeout occurred */
58 if (!count)
59 return -1;
60 return 0;
61}
62
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080063static int codec_detect(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +020064{
65 u8 reg8;
66
67 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
68 if (set_bits(base + 0x08, 1, 1) == -1)
69 goto no_codec;
70
71 /* Write back the value once reset bit is set. */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080072 write16(base + 0x0,
73 read16(base + 0x0));
Stefan Reinauer8e073822012-04-04 00:07:22 +020074
75 /* Read in Codec location (BAR + 0xe)[2..0]*/
76 reg8 = read8(base + 0xe);
77 reg8 &= 0x0f;
78 if (!reg8)
79 goto no_codec;
80
81 return reg8;
82
83no_codec:
84 /* Codec Not found */
85 /* Put HDA back in reset (BAR + 0x8) [0] */
86 set_bits(base + 0x08, 1, 0);
87 printk(BIOS_DEBUG, "Azalia: No codec!\n");
88 return 0;
89}
90
Stefan Reinauer8e073822012-04-04 00:07:22 +020091static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
92{
93 int idx=0;
94
95 while (idx < (cim_verb_data_size / sizeof(u32))) {
96 u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
97 if (cim_verb_data[idx] != viddid) {
98 idx += verb_size + 3; // skip verb + header
99 continue;
100 }
101 *verb = &cim_verb_data[idx+3];
102 return verb_size;
103 }
104
105 /* Not all codecs need to load another verb */
106 return 0;
107}
108
109/**
110 * Wait 50usec for the codec to indicate it is ready
111 * no response would imply that the codec is non-operative
112 */
113
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800114static int wait_for_ready(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200115{
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800116 /* Use a 1msec timeout */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200117
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800118 int timeout = 1000;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200119
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200120 while (timeout--) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800121 u32 reg32 = read32(base + HDA_ICII_REG);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200122 if (!(reg32 & HDA_ICII_BUSY))
123 return 0;
124 udelay(1);
125 }
126
127 return -1;
128}
129
130/**
131 * Wait 50usec for the codec to indicate that it accepted
132 * the previous command. No response would imply that the code
133 * is non-operative
134 */
135
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800136static int wait_for_valid(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200137{
138 u32 reg32;
139
140 /* Send the verb to the codec */
141 reg32 = read32(base + HDA_ICII_REG);
142 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
143 write32(base + HDA_ICII_REG, reg32);
144
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800145 /* Use a 1msec timeout */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200146
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800147 int timeout = 1000;
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200148 while (timeout--) {
Stefan Reinauer8e073822012-04-04 00:07:22 +0200149 reg32 = read32(base + HDA_ICII_REG);
150 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
151 HDA_ICII_VALID)
152 return 0;
153 udelay(1);
154 }
155
156 return -1;
157}
158
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800159static void codec_init(struct device *dev, u8 *base, int addr)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200160{
161 u32 reg32;
162 const u32 *verb;
163 u32 verb_size;
164 int i;
165
166 printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
167
168 /* 1 */
169 if (wait_for_ready(base) == -1) {
170 printk(BIOS_DEBUG, " codec not ready.\n");
171 return;
172 }
173
174 reg32 = (addr << 28) | 0x000f0000;
175 write32(base + 0x60, reg32);
176
177 if (wait_for_valid(base) == -1) {
178 printk(BIOS_DEBUG, " codec not valid.\n");
179 return;
180 }
181
182 reg32 = read32(base + 0x64);
183
184 /* 2 */
185 printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
186 verb_size = find_verb(dev, reg32, &verb);
187
188 if (!verb_size) {
189 printk(BIOS_DEBUG, "Azalia: No verb!\n");
190 return;
191 }
192 printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
193
194 /* 3 */
195 for (i = 0; i < verb_size; i++) {
196 if (wait_for_ready(base) == -1)
197 return;
198
199 write32(base + 0x60, verb[i]);
200
201 if (wait_for_valid(base) == -1)
202 return;
203 }
204 printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
205}
206
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800207static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200208{
209 int i;
210 for (i = 3; i >= 0; i--) {
211 if (codec_mask & (1 << i))
212 codec_init(dev, base, i);
213 }
Dylan Reidb98d0782012-04-27 11:37:33 -0700214
215 for (i = 0; i < pc_beep_verbs_size; i++) {
216 if (wait_for_ready(base) == -1)
217 return;
218
219 write32(base + 0x60, pc_beep_verbs[i]);
220
221 if (wait_for_valid(base) == -1)
222 return;
223 }
Stefan Reinauer8e073822012-04-04 00:07:22 +0200224}
225
226static void azalia_init(struct device *dev)
227{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800228 u8 *base;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200229 struct resource *res;
230 u32 codec_mask;
231 u8 reg8;
232 u16 reg16;
233 u32 reg32;
234
235 /* Find base address */
236 res = find_resource(dev, PCI_BASE_ADDRESS_0);
237 if (!res)
238 return;
239
240 // NOTE this will break as soon as the Azalia get's a bar above
241 // 4G. Is there anything we can do about it?
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800242 base = res2mmio(res, 0, 0);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200243 printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
244
245 if (RCBA32(0x2030) & (1 << 31)) {
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300246 reg32 = pci_read_config32(dev, 0x120);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200247 reg32 &= 0xf8ffff01;
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800248 reg32 |= (1 << 24); // 2 << 24 for server
Stefan Reinauer8e073822012-04-04 00:07:22 +0200249 reg32 |= RCBA32(0x2030) & 0xfe;
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300250 pci_write_config32(dev, 0x120, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200251
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300252 reg16 = pci_read_config16(dev, 0x78);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800253 reg16 |= (1 << 11);
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300254 pci_write_config16(dev, 0x78, reg16);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200255 } else
256 printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
257
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300258 reg32 = pci_read_config32(dev, 0x114);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200259 reg32 &= ~0xfe;
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300260 pci_write_config32(dev, 0x114, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200261
262 // Set VCi enable bit
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300263 reg32 = pci_read_config32(dev, 0x120);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800264 reg32 |= (1 << 31);
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300265 pci_write_config32(dev, 0x120, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200266
267 // Enable HDMI codec:
268 reg32 = pci_read_config32(dev, 0xc4);
269 reg32 |= (1 << 1);
270 pci_write_config32(dev, 0xc4, reg32);
271
272 reg8 = pci_read_config8(dev, 0x43);
273 reg8 |= (1 << 6);
274 pci_write_config8(dev, 0x43, reg8);
275
276 /* Additional programming steps */
277 reg32 = pci_read_config32(dev, 0xc4);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200278 reg32 |= (1 << 13);
279 pci_write_config32(dev, 0xc4, reg32);
280
281 reg32 = pci_read_config32(dev, 0xc4);
282 reg32 |= (1 << 10);
283 pci_write_config32(dev, 0xc4, reg32);
284
285 reg32 = pci_read_config32(dev, 0xd0);
286 reg32 &= ~(1 << 31);
287 pci_write_config32(dev, 0xd0, reg32);
288
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800289 if (dev->device == 0x1e20) {
290 /* Additional step on Panther Point */
291 reg32 = pci_read_config32(dev, 0xc4);
292 reg32 |= (1 << 17);
293 pci_write_config32(dev, 0xc4, reg32);
294 }
295
Stefan Reinauer8e073822012-04-04 00:07:22 +0200296 /* Set Bus Master */
297 reg32 = pci_read_config32(dev, PCI_COMMAND);
298 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
299
300 pci_write_config8(dev, 0x3c, 0x0a); // unused?
301
302 /* Codec Initialization Programming Sequence */
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800303
304 /* Take controller out of reset */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200305 reg32 = read32(base + 0x08);
306 reg32 |= (1 << 0);
307 write32(base + 0x08, reg32);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800308 /* Wait 1ms */
309 udelay(1000);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200310
311 //
312 reg8 = pci_read_config8(dev, 0x40); // Audio Control
313 reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
314 pci_write_config8(dev, 0x40, reg8);
315
316 reg8 = pci_read_config8(dev, 0x4d); // Docking Status
317 reg8 &= ~(1 << 7); // Docking not supported
318 pci_write_config8(dev, 0x4d, reg8);
319
320 codec_mask = codec_detect(base);
321
322 if (codec_mask) {
323 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
324 codecs_init(dev, base, codec_mask);
325 }
326
327 /* Enable dynamic clock gating */
328 reg8 = pci_read_config8(dev, 0x43);
329 reg8 &= ~0x7;
330 reg8 |= (1 << 2) | (1 << 0);
331 pci_write_config8(dev, 0x43, reg8);
332}
333
Aaron Durbinaa090cb2017-09-13 16:01:52 -0600334static const char *azalia_acpi_name(const struct device *dev)
Patrick Rudolph604f6982017-06-07 09:46:52 +0200335{
336 return "HDEF";
337}
338
Stefan Reinauer8e073822012-04-04 00:07:22 +0200339static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
340{
341 if (!vendor || !device) {
342 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
343 pci_read_config32(dev, PCI_VENDOR_ID));
344 } else {
345 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
346 ((device & 0xffff) << 16) | (vendor & 0xffff));
347 }
348}
349
350static struct pci_operations azalia_pci_ops = {
351 .set_subsystem = azalia_set_subsystem,
352};
353
354static struct device_operations azalia_ops = {
355 .read_resources = pci_dev_read_resources,
356 .set_resources = pci_dev_set_resources,
357 .enable_resources = pci_dev_enable_resources,
358 .init = azalia_init,
359 .scan_bus = 0,
360 .ops_pci = &azalia_pci_ops,
Patrick Rudolph604f6982017-06-07 09:46:52 +0200361 .acpi_name = azalia_acpi_name,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200362};
363
Stefan Reinauer9a380ab2012-06-22 13:16:11 -0700364static const unsigned short pci_device_ids[] = { 0x1c20, 0x1e20, 0 };
Stefan Reinauer8e073822012-04-04 00:07:22 +0200365
Stefan Reinauer9a380ab2012-06-22 13:16:11 -0700366static const struct pci_driver pch_azalia __pci_driver = {
367 .ops = &azalia_ops,
368 .vendor = PCI_VENDOR_ID_INTEL,
369 .devices = pci_device_ids,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200370};