blob: 067d0f3980db4280df0a7086804ffa160c79e5c6 [file] [log] [blame]
Stefan Reinauer679c9f92009-01-20 22:54:59 +00001/*
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 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <console/console.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <device/pci_ops.h>
26#include <arch/io.h>
27#include <delay.h>
28#include "i82801gx.h"
29
30#define HDA_ICII_REG 0x68
31#define HDA_ICII_BUSY (1 << 0)
32#define HDA_ICII_VALID (1 << 1)
33
34static int set_bits(u8 * port, u32 mask, u32 val)
35{
36 u32 dword;
37 int count;
38
39 val &= mask;
40 dword = readl(port);
41 dword &= ~mask;
42 dword |= val;
43 writel(dword, port);
44
45 count = 50;
46 do {
47 dword = readl(port);
48 dword &= mask;
49 udelay(100);
50 } while ((dword != val) && --count);
51
52 if (!count)
53 return -1;
54
55 udelay(540);
56 return 0;
57}
58
59static int codec_detect(u8 * base)
60{
61 u32 dword;
62
63 /* 1 */
64 set_bits(base + 0x08, 1, 1);
65
66 /* 2 */
67 dword = readl(base + 0x0e);
68 dword |= 7;
69 writel(dword, base + 0x0e);
70
71 /* 3 */
72 set_bits(base + 0x08, 1, 0);
73
74 /* 4 */
75 set_bits(base + 0x08, 1, 1);
76
77 /* 5 */
78 dword = readl(base + 0xe);
79 dword &= 7;
80
81 /* 6 */
82 if (!dword) {
83 set_bits(base + 0x08, 1, 0);
84 printk_debug("No codec!\n");
85 return 0;
86 }
87 return dword;
88
89}
90
91static u32 cim_verb_data[] = {
92 0x00172000,
93 0x00172100,
94 0x001722EC,
95 0x00172310,
96
97 /* Pin Complex (NID 0x12) */
98 0x01271CF0,
99 0x01271D11,
100 0x01271E11,
101 0x01271F41,
102 /* Pin Complex (NID 0x14) */
103 0x01471C10,
104 0x01471D01,
105 0x01471E13,
106 0x01471F99,
107 /* Pin Complex (NID 0x15) */
108 0x01571C20,
109 0x01571D40,
110 0x01571E21,
111 0x01571F01,
112 /* Pin Complex (NID 0x16) */
113 0x01671CF0,
114 0x01671D11,
115 0x01671E11,
116 0x01671F41,
117 /* Pin Complex (NID 0x18) */
118 0x01871C30,
119 0x01871D98,
120 0x01871EA1,
121 0x01871F01,
122 /* Pin Complex (NID 0x19) */
123 0x01971C31,
124 0x01971D09,
125 0x01971EA3,
126 0x01971F99,
127 /* Pin Complex (NID 0x1A) */
128 0x01A71C3F,
129 0x01A71D98,
130 0x01A71EA1,
131 0x01A71F02,
132 /* Pin Complex (NID 0x1B) */
133 0x01B71C1F,
134 0x01B71D40,
135 0x01B71E21,
136 0x01B71F02,
137 /* Pin Complex (NID 0x1C) */
138 0x01C71CF0,
139 0x01C71D11,
140 0x01C71E11,
141 0x01C71F41,
142 /* Pin Complex (NID 0x1D) */
143 0x01D71CF0,
144 0x01D71D11,
145 0x01D71E11,
146 0x01D71F41,
147 /* Pin Complex (NID 0x1E) */
148 0x01E71CF0,
149 0x01E71D11,
150 0x01E71E11,
151 0x01E71F41,
152 /* Pin Complex (NID 0x1F) */
153 0x01F71CF0,
154 0x01F71D11,
155 0x01F71E11,
156 0x01F71F41,
157};
158
159static unsigned find_verb(u32 viddid, u32 ** verb)
160{
161 device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
162 struct southbridge_intel_i82801gx_config *cfg =
163 (struct southbridge_intel_i82801gx_config *)azalia_dev->chip_info;
164 printk_debug("Dev=%s\n", dev_path(azalia_dev));
165 printk_debug("Default viddid=%x\n", cfg->hda_viddid);
166 printk_debug("Reading viddid=%x\n", viddid);
167 if (!cfg)
168 return 0;
169 if (viddid != cfg->hda_viddid)
170 return 0;
171 *verb = (u32 *) cim_verb_data;
172 return sizeof(cim_verb_data) / sizeof(u32);
173}
174
175/**
176 * Wait 50usec for for the codec to indicate it is ready
177 * no response would imply that the codec is non-operative
178 */
179
180static int wait_for_ready(u8 *base)
181{
182 /* Use a 50 usec timeout - the Linux kernel uses the
183 * same duration */
184
185 int timeout = 50;
186
187 while(timeout--) {
188 u32 dword=readl(base + HDA_ICII_REG);
189 if (!(dword & HDA_ICII_BUSY))
190 return 0;
191 udelay(1);
192 }
193
194 return -1;
195}
196
197/**
198 * Wait 50usec for for the codec to indicate that it accepted
199 * the previous command. No response would imply that the code
200 * is non-operative
201 */
202
203static int wait_for_valid(u8 *base)
204{
205 /* Use a 50 usec timeout - the Linux kernel uses the
206 * same duration */
207
208 int timeout = 50;
209 while(timeout--) {
210 u32 dword = readl(base + HDA_ICII_REG);
211 if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
212 HDA_ICII_VALID)
213 return 0;
214 udelay(1);
215 }
216
217 return 1;
218}
219
220static void codec_init(u8 * base, int addr)
221{
222 u32 dword;
223 u32 *verb;
224 u32 verb_size;
225 int i;
226
227 /* 1 */
228 if (wait_for_ready(base) == -1)
229 return;
230
231 dword = (addr << 28) | 0x000f0000;
232 writel(dword, base + 0x60);
233
234 if (wait_for_valid(base) == -1)
235 return;
236
237 dword = readl(base + 0x64);
238
239 /* 2 */
240 printk_debug("codec viddid: %08x\n", dword);
241 verb_size = find_verb(dword, &verb);
242
243 if (!verb_size) {
244 printk_debug("No verb!\n");
245 return;
246 }
247
248 printk_debug("verb_size: %d\n", verb_size);
249 /* 3 */
250 for (i = 0; i < verb_size; i++) {
251 if (wait_for_ready(base) == -1)
252 return;
253
254 writel(verb[i], base + 0x60);
255
256 if (wait_for_valid(base) == -1)
257 return;
258 }
259 printk_debug("verb loaded!\n");
260}
261
262static void codecs_init(u8 * base, u32 codec_mask)
263{
264 int i;
265 for (i = 2; i >= 0; i--) {
266 if (codec_mask & (1 << i))
267 codec_init(base, i);
268 }
269}
270
271static void azalia_init(struct device *dev)
272{
273 u8 *base;
274 struct resource *res;
275 u32 codec_mask;
276
277 /* Set routing pin */
278 pci_write_config32(dev, 0xf8, 0x0);
279 pci_write_config8(dev, 0xfc, 0xAA);
280
281 /* Set INTA */
282 pci_write_config8(dev, 0x63, 0x0);
283
284 /* Enable azalia, disable ac97 */
285 // pm_iowrite(0x59, 0xB);
286
287 res = find_resource(dev, 0x10);
288 if (!res)
289 return;
290
291 base = (u8 *) ((u32)res->base);
292 printk_debug("base = %08x\n", base);
293 codec_mask = codec_detect(base);
294
295 if (codec_mask) {
296 printk_debug("codec_mask = %02x\n", codec_mask);
297 codecs_init(base, codec_mask);
298 }
299}
300
301static struct device_operations azalia_ops = {
302 .read_resources = pci_dev_read_resources,
303 .set_resources = pci_dev_set_resources,
304 .enable_resources = pci_dev_enable_resources,
305 .init = azalia_init,
306 .scan_bus = 0,
307 .enable = i82801gx_enable,
308};
309
310/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
311static const struct pci_driver i82801gx_azalia __pci_driver = {
312 .ops = &azalia_ops,
313 .vendor = PCI_VENDOR_ID_INTEL,
314 .device = 0x27d8,
315};
316