blob: b250f3da7b62372407054388dd904645b3d193dd [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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <console/console.h>
21#include <device/device.h>
22#include <device/pci.h>
23#include <device/pci_ids.h>
24#include <device/pci_ops.h>
25#include <device/azalia_device.h>
26#include <arch/io.h>
27#include <delay.h>
28
29#define HDA_ICII_REG 0x68
30#define HDA_ICII_BUSY (1 << 0)
31#define HDA_ICII_VALID (1 << 1)
32
33static int set_bits(u32 port, u32 mask, u32 val)
34{
35 u32 reg32;
36 int count;
37
38 /* Write (val & mask) to port */
39 val &= mask;
40 reg32 = read32(port);
41 reg32 &= ~mask;
42 reg32 |= val;
43 write32(port, reg32);
44
45 /* Wait for readback of register to
46 * match what was just written to it
47 */
48 count = 50;
49 do {
50 /* Wait 1ms based on BKDG wait time */
51 mdelay(1);
52 reg32 = read32(port);
53 reg32 &= mask;
54 } while ((reg32 != val) && --count);
55
56 /* Timeout occurred */
57 if (!count)
58 return -1;
59 return 0;
60}
61
62static int codec_detect(u32 base)
63{
64 u32 reg32;
65 int count;
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 /* clear STATESTS bits (BAR + 0xE)[2:0] */
72 reg32 = read32(base + 0x0E);
73 reg32 |= 7;
74 write32(base + 0x0E, reg32);
75
76 /* Wait for readback of register to
77 * match what was just written to it
78 */
79 count = 50;
80 do {
81 /* Wait 1ms based on BKDG wait time */
82 mdelay(1);
83 reg32 = read32(base + 0x0E);
84 } while ((reg32 != 0) && --count);
85 /* Timeout occured */
86 if (!count)
87 goto no_codec;
88
89 /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
90 if (set_bits(base + 0x08, 1, 0) == -1)
91 goto no_codec;
92
93 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
94 if (set_bits(base + 0x08, 1, 1) == -1)
95 goto no_codec;
96
97 /* Read in Codec location (BAR + 0xe)[2..0] */
98 reg32 = read32(base + 0xe);
99 reg32 &= 0x0f;
100 if (!reg32)
101 goto no_codec;
102
103 return reg32;
104
105no_codec:
106 /* Codec Not found */
107 /* Put HDA back in reset (BAR + 0x8) [0] */
108 set_bits(base + 0x08, 1, 0);
109 printk(BIOS_DEBUG, "azalia_audio: No codec!\n");
110 return 0;
111}
112
Andrew Wub7bb70d2013-08-12 20:07:47 +0800113static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
114{
115 printk(BIOS_DEBUG, "azalia_audio: dev=%s\n", dev_path(dev));
116 printk(BIOS_DEBUG, "azalia_audio: Reading viddid=%x\n", viddid);
117
118 int idx = 0;
119
120 while (idx < (cim_verb_data_size / sizeof(u32))) {
121 u32 verb_size = 4 * cim_verb_data[idx + 2]; // in u32
122 if (cim_verb_data[idx] != viddid) {
123 idx += verb_size + 3; // skip verb + header
124 continue;
125 }
126 *verb = &cim_verb_data[idx + 3];
127 return verb_size;
128 }
129
130 /* Not all codecs need to load another verb */
131 return 0;
132}
133
134/**
135 * Wait 50usec for the codec to indicate it is ready
136 * no response would imply that the codec is non-operative
137 */
138
139static int wait_for_ready(u32 base)
140{
141 /* Use a 50 usec timeout - the Linux kernel uses the
142 * same duration */
143
144 int timeout = 50;
145
146 while (timeout--) {
147 u32 reg32 = read32(base + HDA_ICII_REG);
148 if (!(reg32 & HDA_ICII_BUSY))
149 return 0;
150 udelay(1);
151 }
152
153 return -1;
154}
155
156/**
157 * Wait 50usec for the codec to indicate that it accepted
158 * the previous command. No response would imply that the code
159 * is non-operative
160 */
161
162static int wait_for_valid(u32 base)
163{
164 /* Use a 50 usec timeout - the Linux kernel uses the
165 * same duration */
166
167 int timeout = 25;
168
169 write32(base + HDA_ICII_REG, HDA_ICII_VALID | HDA_ICII_BUSY);
170 while (timeout--) {
171 udelay(1);
172 }
173 timeout = 50;
174 while (timeout--) {
175 u32 reg32 = read32(base + HDA_ICII_REG);
176 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
177 HDA_ICII_VALID)
178 return 0;
179 udelay(1);
180 }
181
182 return -1;
183}
184
185static void codec_init(struct device *dev, u32 base, int addr)
186{
187 u32 reg32;
188 const u32 *verb;
189 u32 verb_size;
190 int i;
191
192 printk(BIOS_DEBUG, "azalia_audio: Initializing codec #%d\n", addr);
193
194 /* 1 */
195 if (wait_for_ready(base) == -1)
196 return;
197
198 reg32 = (addr << 28) | 0x000f0000;
199 write32(base + 0x60, reg32);
200
201 if (wait_for_valid(base) == -1)
202 return;
203
204 reg32 = read32(base + 0x64);
205
206 /* 2 */
207 printk(BIOS_DEBUG, "azalia_audio: codec viddid: %08x\n", reg32);
208 verb_size = find_verb(dev, reg32, &verb);
209
210 if (!verb_size) {
211 printk(BIOS_DEBUG, "azalia_audio: No verb!\n");
212 return;
213 }
214 printk(BIOS_DEBUG, "azalia_audio: verb_size: %d\n", verb_size);
215
216 /* 3 */
217 for (i = 0; i < verb_size; i++) {
218 if (wait_for_ready(base) == -1)
219 return;
220
221 write32(base + 0x60, verb[i]);
222
223 if (wait_for_valid(base) == -1)
224 return;
225 }
226 printk(BIOS_DEBUG, "azalia_audio: verb loaded.\n");
227}
228
229static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
230{
231 int i;
232
233 for (i = 2; i >= 0; i--) {
234 if (codec_mask & (1 << i))
235 codec_init(dev, base, i);
236 }
237}
238
239void azalia_audio_init(struct device *dev)
240{
241 u32 base;
242 struct resource *res;
243 u32 codec_mask;
244
245 res = find_resource(dev, 0x10);
246 if (!res)
247 return;
248
249 // NOTE this will break as soon as the azalia_audio get's a bar above
250 // 4G. Is there anything we can do about it?
251 base = (u32) res->base;
252 printk(BIOS_DEBUG, "azalia_audio: base = %08x\n", (u32) base);
253 codec_mask = codec_detect(base);
254
255 if (codec_mask) {
256 printk(BIOS_DEBUG, "azalia_audio: codec_mask = %02x\n",
257 codec_mask);
258 codecs_init(dev, base, codec_mask);
259 }
260}
261
262struct pci_operations azalia_audio_pci_ops = {
263 .set_subsystem = pci_dev_set_subsystem,
264};
265
266struct device_operations default_azalia_audio_ops = {
267 .read_resources = pci_dev_read_resources,
268 .set_resources = pci_dev_set_resources,
269 .enable_resources = pci_dev_enable_resources,
270 .init = azalia_audio_init,
271 .scan_bus = 0,
272 .ops_pci = &azalia_audio_pci_ops,
273};