blob: 32223c2c34a9accffac841f38cf26f4d44297614 [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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Stefan Reinauer8e073822012-04-04 00:07:22 +020020 */
21
22#include <console/console.h>
23#include <device/device.h>
24#include <device/pci.h>
25#include <device/pci_ids.h>
26#include <device/pci_ops.h>
27#include <arch/io.h>
28#include <delay.h>
Vladimir Serbinenko75c83872014-09-05 01:01:31 +020029#include <device/azalia_device.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020030#include "pch.h"
31
32#define HDA_ICII_REG 0x68
Andrew Wuae8d0692013-08-02 19:29:17 +080033#define HDA_ICII_BUSY (1 << 0)
34#define HDA_ICII_VALID (1 << 1)
Stefan Reinauer8e073822012-04-04 00:07:22 +020035
36typedef struct southbridge_intel_bd82x6x_config config_t;
37
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080038static int set_bits(void *port, u32 mask, u32 val)
Stefan Reinauer8e073822012-04-04 00:07:22 +020039{
40 u32 reg32;
41 int count;
42
43 /* Write (val & mask) to port */
44 val &= mask;
45 reg32 = read32(port);
46 reg32 &= ~mask;
47 reg32 |= val;
48 write32(port, reg32);
49
50 /* Wait for readback of register to
51 * match what was just written to it
52 */
53 count = 50;
54 do {
55 /* Wait 1ms based on BKDG wait time */
56 mdelay(1);
57 reg32 = read32(port);
58 reg32 &= mask;
59 } while ((reg32 != val) && --count);
60
61 /* Timeout occurred */
62 if (!count)
63 return -1;
64 return 0;
65}
66
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080067static int codec_detect(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +020068{
69 u8 reg8;
70
71 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
72 if (set_bits(base + 0x08, 1, 1) == -1)
73 goto no_codec;
74
75 /* Write back the value once reset bit is set. */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080076 write16(base + 0x0,
77 read16(base + 0x0));
Stefan Reinauer8e073822012-04-04 00:07:22 +020078
79 /* Read in Codec location (BAR + 0xe)[2..0]*/
80 reg8 = read8(base + 0xe);
81 reg8 &= 0x0f;
82 if (!reg8)
83 goto no_codec;
84
85 return reg8;
86
87no_codec:
88 /* Codec Not found */
89 /* Put HDA back in reset (BAR + 0x8) [0] */
90 set_bits(base + 0x08, 1, 0);
91 printk(BIOS_DEBUG, "Azalia: No codec!\n");
92 return 0;
93}
94
Stefan Reinauer8e073822012-04-04 00:07:22 +020095static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
96{
97 int idx=0;
98
99 while (idx < (cim_verb_data_size / sizeof(u32))) {
100 u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
101 if (cim_verb_data[idx] != viddid) {
102 idx += verb_size + 3; // skip verb + header
103 continue;
104 }
105 *verb = &cim_verb_data[idx+3];
106 return verb_size;
107 }
108
109 /* Not all codecs need to load another verb */
110 return 0;
111}
112
113/**
114 * Wait 50usec for the codec to indicate it is ready
115 * no response would imply that the codec is non-operative
116 */
117
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800118static int wait_for_ready(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200119{
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800120 /* Use a 1msec timeout */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200121
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800122 int timeout = 1000;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200123
124 while(timeout--) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800125 u32 reg32 = read32(base + HDA_ICII_REG);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200126 if (!(reg32 & HDA_ICII_BUSY))
127 return 0;
128 udelay(1);
129 }
130
131 return -1;
132}
133
134/**
135 * Wait 50usec for the codec to indicate that it accepted
136 * the previous command. No response would imply that the code
137 * is non-operative
138 */
139
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800140static int wait_for_valid(u8 *base)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200141{
142 u32 reg32;
143
144 /* Send the verb to the codec */
145 reg32 = read32(base + HDA_ICII_REG);
146 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
147 write32(base + HDA_ICII_REG, reg32);
148
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800149 /* Use a 1msec timeout */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200150
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800151 int timeout = 1000;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200152 while(timeout--) {
153 reg32 = read32(base + HDA_ICII_REG);
154 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
155 HDA_ICII_VALID)
156 return 0;
157 udelay(1);
158 }
159
160 return -1;
161}
162
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800163static void codec_init(struct device *dev, u8 *base, int addr)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200164{
165 u32 reg32;
166 const u32 *verb;
167 u32 verb_size;
168 int i;
169
170 printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
171
172 /* 1 */
173 if (wait_for_ready(base) == -1) {
174 printk(BIOS_DEBUG, " codec not ready.\n");
175 return;
176 }
177
178 reg32 = (addr << 28) | 0x000f0000;
179 write32(base + 0x60, reg32);
180
181 if (wait_for_valid(base) == -1) {
182 printk(BIOS_DEBUG, " codec not valid.\n");
183 return;
184 }
185
186 reg32 = read32(base + 0x64);
187
188 /* 2 */
189 printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
190 verb_size = find_verb(dev, reg32, &verb);
191
192 if (!verb_size) {
193 printk(BIOS_DEBUG, "Azalia: No verb!\n");
194 return;
195 }
196 printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
197
198 /* 3 */
199 for (i = 0; i < verb_size; i++) {
200 if (wait_for_ready(base) == -1)
201 return;
202
203 write32(base + 0x60, verb[i]);
204
205 if (wait_for_valid(base) == -1)
206 return;
207 }
208 printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
209}
210
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800211static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200212{
213 int i;
214 for (i = 3; i >= 0; i--) {
215 if (codec_mask & (1 << i))
216 codec_init(dev, base, i);
217 }
Dylan Reidb98d0782012-04-27 11:37:33 -0700218
219 for (i = 0; i < pc_beep_verbs_size; i++) {
220 if (wait_for_ready(base) == -1)
221 return;
222
223 write32(base + 0x60, pc_beep_verbs[i]);
224
225 if (wait_for_valid(base) == -1)
226 return;
227 }
Stefan Reinauer8e073822012-04-04 00:07:22 +0200228}
229
230static void azalia_init(struct device *dev)
231{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800232 u8 *base;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200233 struct resource *res;
234 u32 codec_mask;
235 u8 reg8;
236 u16 reg16;
237 u32 reg32;
238
239 /* Find base address */
240 res = find_resource(dev, PCI_BASE_ADDRESS_0);
241 if (!res)
242 return;
243
244 // NOTE this will break as soon as the Azalia get's a bar above
245 // 4G. Is there anything we can do about it?
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800246 base = res2mmio(res, 0, 0);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200247 printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
248
249 if (RCBA32(0x2030) & (1 << 31)) {
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300250 reg32 = pci_read_config32(dev, 0x120);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200251 reg32 &= 0xf8ffff01;
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800252 reg32 |= (1 << 24); // 2 << 24 for server
Stefan Reinauer8e073822012-04-04 00:07:22 +0200253 reg32 |= RCBA32(0x2030) & 0xfe;
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300254 pci_write_config32(dev, 0x120, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200255
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300256 reg16 = pci_read_config16(dev, 0x78);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800257 reg16 |= (1 << 11);
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300258 pci_write_config16(dev, 0x78, reg16);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200259 } else
260 printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
261
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300262 reg32 = pci_read_config32(dev, 0x114);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200263 reg32 &= ~0xfe;
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300264 pci_write_config32(dev, 0x114, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200265
266 // Set VCi enable bit
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300267 reg32 = pci_read_config32(dev, 0x120);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800268 reg32 |= (1 << 31);
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300269 pci_write_config32(dev, 0x120, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200270
271 // Enable HDMI codec:
272 reg32 = pci_read_config32(dev, 0xc4);
273 reg32 |= (1 << 1);
274 pci_write_config32(dev, 0xc4, reg32);
275
276 reg8 = pci_read_config8(dev, 0x43);
277 reg8 |= (1 << 6);
278 pci_write_config8(dev, 0x43, reg8);
279
280 /* Additional programming steps */
281 reg32 = pci_read_config32(dev, 0xc4);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200282 reg32 |= (1 << 13);
283 pci_write_config32(dev, 0xc4, reg32);
284
285 reg32 = pci_read_config32(dev, 0xc4);
286 reg32 |= (1 << 10);
287 pci_write_config32(dev, 0xc4, reg32);
288
289 reg32 = pci_read_config32(dev, 0xd0);
290 reg32 &= ~(1 << 31);
291 pci_write_config32(dev, 0xd0, reg32);
292
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800293 if (dev->device == 0x1e20) {
294 /* Additional step on Panther Point */
295 reg32 = pci_read_config32(dev, 0xc4);
296 reg32 |= (1 << 17);
297 pci_write_config32(dev, 0xc4, reg32);
298 }
299
Stefan Reinauer8e073822012-04-04 00:07:22 +0200300 /* Set Bus Master */
301 reg32 = pci_read_config32(dev, PCI_COMMAND);
302 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
303
304 pci_write_config8(dev, 0x3c, 0x0a); // unused?
305
306 /* Codec Initialization Programming Sequence */
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800307
308 /* Take controller out of reset */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200309 reg32 = read32(base + 0x08);
310 reg32 |= (1 << 0);
311 write32(base + 0x08, reg32);
Stefan Reinauer15ba2bc2012-11-14 12:25:15 -0800312 /* Wait 1ms */
313 udelay(1000);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200314
315 //
316 reg8 = pci_read_config8(dev, 0x40); // Audio Control
317 reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
318 pci_write_config8(dev, 0x40, reg8);
319
320 reg8 = pci_read_config8(dev, 0x4d); // Docking Status
321 reg8 &= ~(1 << 7); // Docking not supported
322 pci_write_config8(dev, 0x4d, reg8);
323
324 codec_mask = codec_detect(base);
325
326 if (codec_mask) {
327 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
328 codecs_init(dev, base, codec_mask);
329 }
330
331 /* Enable dynamic clock gating */
332 reg8 = pci_read_config8(dev, 0x43);
333 reg8 &= ~0x7;
334 reg8 |= (1 << 2) | (1 << 0);
335 pci_write_config8(dev, 0x43, reg8);
336}
337
338static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
339{
340 if (!vendor || !device) {
341 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
342 pci_read_config32(dev, PCI_VENDOR_ID));
343 } else {
344 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
345 ((device & 0xffff) << 16) | (vendor & 0xffff));
346 }
347}
348
349static struct pci_operations azalia_pci_ops = {
350 .set_subsystem = azalia_set_subsystem,
351};
352
353static struct device_operations azalia_ops = {
354 .read_resources = pci_dev_read_resources,
355 .set_resources = pci_dev_set_resources,
356 .enable_resources = pci_dev_enable_resources,
357 .init = azalia_init,
358 .scan_bus = 0,
359 .ops_pci = &azalia_pci_ops,
360};
361
Stefan Reinauer9a380ab2012-06-22 13:16:11 -0700362static const unsigned short pci_device_ids[] = { 0x1c20, 0x1e20, 0 };
Stefan Reinauer8e073822012-04-04 00:07:22 +0200363
Stefan Reinauer9a380ab2012-06-22 13:16:11 -0700364static const struct pci_driver pch_azalia __pci_driver = {
365 .ops = &azalia_ops,
366 .vendor = PCI_VENDOR_ID_INTEL,
367 .devices = pci_device_ids,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200368};