blob: dab1038931fcd70921cbb3c43686de3b96f7a8dd [file] [log] [blame]
Andrew Wub7bb70d2013-08-12 20:07:47 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 DMP Electronics Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Andrew Wub7bb70d2013-08-12 20:07:47 +080014 */
15
16#include <console/console.h>
17#include <device/device.h>
18#include <device/pci.h>
19#include <device/pci_ids.h>
20#include <device/pci_ops.h>
21#include <device/azalia_device.h>
22#include <arch/io.h>
23#include <delay.h>
24
25#define HDA_ICII_REG 0x68
26#define HDA_ICII_BUSY (1 << 0)
27#define HDA_ICII_VALID (1 << 1)
28
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080029static int set_bits(void *port, u32 mask, u32 val)
Andrew Wub7bb70d2013-08-12 20:07:47 +080030{
31 u32 reg32;
32 int count;
33
34 /* Write (val & mask) to port */
35 val &= mask;
36 reg32 = read32(port);
37 reg32 &= ~mask;
38 reg32 |= val;
39 write32(port, reg32);
40
41 /* Wait for readback of register to
42 * match what was just written to it
43 */
44 count = 50;
45 do {
46 /* Wait 1ms based on BKDG wait time */
47 mdelay(1);
48 reg32 = read32(port);
49 reg32 &= mask;
50 } while ((reg32 != val) && --count);
51
52 /* Timeout occurred */
53 if (!count)
54 return -1;
55 return 0;
56}
57
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080058static int codec_detect(u8 *base)
Andrew Wub7bb70d2013-08-12 20:07:47 +080059{
60 u32 reg32;
61 int count;
62
63 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
64 if (set_bits(base + 0x08, 1, 1) == -1)
65 goto no_codec;
66
67 /* clear STATESTS bits (BAR + 0xE)[2:0] */
68 reg32 = read32(base + 0x0E);
69 reg32 |= 7;
70 write32(base + 0x0E, reg32);
71
72 /* Wait for readback of register to
73 * match what was just written to it
74 */
75 count = 50;
76 do {
77 /* Wait 1ms based on BKDG wait time */
78 mdelay(1);
79 reg32 = read32(base + 0x0E);
80 } while ((reg32 != 0) && --count);
81 /* Timeout occured */
82 if (!count)
83 goto no_codec;
84
85 /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
86 if (set_bits(base + 0x08, 1, 0) == -1)
87 goto no_codec;
88
89 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
90 if (set_bits(base + 0x08, 1, 1) == -1)
91 goto no_codec;
92
93 /* Read in Codec location (BAR + 0xe)[2..0] */
94 reg32 = read32(base + 0xe);
95 reg32 &= 0x0f;
96 if (!reg32)
97 goto no_codec;
98
99 return reg32;
100
101no_codec:
102 /* Codec Not found */
103 /* Put HDA back in reset (BAR + 0x8) [0] */
104 set_bits(base + 0x08, 1, 0);
105 printk(BIOS_DEBUG, "azalia_audio: No codec!\n");
106 return 0;
107}
108
Andrew Wub7bb70d2013-08-12 20:07:47 +0800109static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
110{
111 printk(BIOS_DEBUG, "azalia_audio: dev=%s\n", dev_path(dev));
112 printk(BIOS_DEBUG, "azalia_audio: Reading viddid=%x\n", viddid);
113
114 int idx = 0;
115
116 while (idx < (cim_verb_data_size / sizeof(u32))) {
117 u32 verb_size = 4 * cim_verb_data[idx + 2]; // in u32
118 if (cim_verb_data[idx] != viddid) {
119 idx += verb_size + 3; // skip verb + header
120 continue;
121 }
122 *verb = &cim_verb_data[idx + 3];
123 return verb_size;
124 }
125
126 /* Not all codecs need to load another verb */
127 return 0;
128}
129
130/**
131 * Wait 50usec for the codec to indicate it is ready
132 * no response would imply that the codec is non-operative
133 */
134
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800135static int wait_for_ready(u8 *base)
Andrew Wub7bb70d2013-08-12 20:07:47 +0800136{
137 /* Use a 50 usec timeout - the Linux kernel uses the
138 * same duration */
139
140 int timeout = 50;
141
142 while (timeout--) {
143 u32 reg32 = read32(base + HDA_ICII_REG);
144 if (!(reg32 & HDA_ICII_BUSY))
145 return 0;
146 udelay(1);
147 }
148
149 return -1;
150}
151
152/**
153 * Wait 50usec for the codec to indicate that it accepted
154 * the previous command. No response would imply that the code
155 * is non-operative
156 */
157
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800158static int wait_for_valid(u8 *base)
Andrew Wub7bb70d2013-08-12 20:07:47 +0800159{
160 /* Use a 50 usec timeout - the Linux kernel uses the
161 * same duration */
162
163 int timeout = 25;
164
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800165 write32(base + HDA_ICII_REG,
166 HDA_ICII_VALID | HDA_ICII_BUSY);
Andrew Wub7bb70d2013-08-12 20:07:47 +0800167 while (timeout--) {
168 udelay(1);
169 }
170 timeout = 50;
171 while (timeout--) {
172 u32 reg32 = read32(base + HDA_ICII_REG);
173 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
174 HDA_ICII_VALID)
175 return 0;
176 udelay(1);
177 }
178
179 return -1;
180}
181
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800182static void codec_init(struct device *dev, u8 *base, int addr)
Andrew Wub7bb70d2013-08-12 20:07:47 +0800183{
184 u32 reg32;
185 const u32 *verb;
186 u32 verb_size;
187 int i;
188
189 printk(BIOS_DEBUG, "azalia_audio: Initializing codec #%d\n", addr);
190
191 /* 1 */
192 if (wait_for_ready(base) == -1)
193 return;
194
195 reg32 = (addr << 28) | 0x000f0000;
196 write32(base + 0x60, reg32);
197
198 if (wait_for_valid(base) == -1)
199 return;
200
201 reg32 = read32(base + 0x64);
202
203 /* 2 */
204 printk(BIOS_DEBUG, "azalia_audio: codec viddid: %08x\n", reg32);
205 verb_size = find_verb(dev, reg32, &verb);
206
207 if (!verb_size) {
208 printk(BIOS_DEBUG, "azalia_audio: No verb!\n");
209 return;
210 }
211 printk(BIOS_DEBUG, "azalia_audio: verb_size: %d\n", verb_size);
212
213 /* 3 */
214 for (i = 0; i < verb_size; i++) {
215 if (wait_for_ready(base) == -1)
216 return;
217
218 write32(base + 0x60, verb[i]);
219
220 if (wait_for_valid(base) == -1)
221 return;
222 }
223 printk(BIOS_DEBUG, "azalia_audio: verb loaded.\n");
224}
225
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800226static void codecs_init(struct device *dev, u8 *base, u32 codec_mask)
Andrew Wub7bb70d2013-08-12 20:07:47 +0800227{
228 int i;
229
230 for (i = 2; i >= 0; i--) {
231 if (codec_mask & (1 << i))
232 codec_init(dev, base, i);
233 }
234}
235
236void azalia_audio_init(struct device *dev)
237{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800238 u8 *base;
Andrew Wub7bb70d2013-08-12 20:07:47 +0800239 struct resource *res;
240 u32 codec_mask;
241
242 res = find_resource(dev, 0x10);
243 if (!res)
244 return;
245
246 // NOTE this will break as soon as the azalia_audio get's a bar above
247 // 4G. Is there anything we can do about it?
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800248 base = res2mmio(res, 0, 0);
249 printk(BIOS_DEBUG, "azalia_audio: base = %p\n", base);
Andrew Wub7bb70d2013-08-12 20:07:47 +0800250 codec_mask = codec_detect(base);
251
252 if (codec_mask) {
253 printk(BIOS_DEBUG, "azalia_audio: codec_mask = %02x\n",
254 codec_mask);
255 codecs_init(dev, base, codec_mask);
256 }
257}
258
259struct pci_operations azalia_audio_pci_ops = {
260 .set_subsystem = pci_dev_set_subsystem,
261};
262
263struct device_operations default_azalia_audio_ops = {
264 .read_resources = pci_dev_read_resources,
265 .set_resources = pci_dev_set_resources,
266 .enable_resources = pci_dev_enable_resources,
267 .init = azalia_audio_init,
268 .scan_bus = 0,
269 .ops_pci = &azalia_audio_pci_ops,
270};