374e56c32e5d39841b69fbb95f1348e49058773a
[coreboot.git] / src / southbridge / intel / sch / audio.c
1 /*
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
29 #define HDA_ICII_REG 0x68
30 #define   HDA_ICII_BUSY (1 << 0)
31 #define   HDA_ICII_VALID  (1 << 1)
32
33 typedef struct southbridge_intel_sch_config config_t;
34
35 static int set_bits(u32 port, u32 mask, u32 val)
36 {
37         u32 reg32;
38         int count;
39
40         /* Write (val & mask) to port */
41         val &= mask;
42         reg32 = read32(port);
43         reg32 &= ~mask;
44         reg32 |= val;
45         write32(port, reg32);
46
47         /* Wait for readback of register to
48          * match what was just written to it
49          */
50         count = 50;
51         do {
52                 /* Wait 1ms based on BKDG wait time */
53                 mdelay(1);
54                 reg32 = read32(port);
55                 reg32 &= mask;
56         } while ((reg32 != val) && --count);
57
58         /* Timeout occurred */
59         if (!count)
60                 return -1;
61         return 0;
62 }
63
64 static int codec_detect(u32 base)
65 {
66         u32 reg32;
67         int count;
68
69         /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
70         if (set_bits(base + 0x08, 1, 1) == -1)
71                 goto no_codec;
72
73         /* clear STATESTS bits (BAR + 0xE)[2:0] */
74         reg32 = read32(base + 0x0E);
75         reg32 |= 7;
76         write32(base + 0x0E, reg32);
77
78         /* Wait for readback of register to
79          * match what was just written to it
80          */
81         count = 50;
82         do {
83                 /* Wait 1ms based on BKDG wait time */
84                 mdelay(1);
85                 reg32 = read32(base + 0x0E);
86         } while ((reg32 != 0) && --count);
87         /* Timeout occured */
88         if (!count)
89                 goto no_codec;
90
91         /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
92         if (set_bits(base + 0x08, 1, 0) == -1)
93                 goto no_codec;
94
95         /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
96         if (set_bits(base + 0x08, 1, 1) == -1)
97                 goto no_codec;
98
99         /* Read in Codec location (BAR + 0xe)[2..0]*/
100         reg32 = read32(base + 0xe);
101         reg32 &= 0x0f;
102         if (!reg32)
103                 goto no_codec;
104
105         return reg32;
106
107 no_codec:
108         /* Codec Not found */
109         /* Put HDA back in reset (BAR + 0x8) [0] */
110         set_bits(base + 0x08, 1, 0);
111         printk(BIOS_DEBUG, "sch_audio: No codec!\n");
112         return 0;
113 }
114
115 const u32 * cim_verb_data = NULL;
116 u32 cim_verb_data_size = 0;
117
118 static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
119 {
120         printk(BIOS_DEBUG, "sch_audio: dev=%s\n", dev_path(dev));
121         printk(BIOS_DEBUG, "sch_audio: Reading viddid=%x\n", viddid);
122
123         int idx=0;
124
125         while (idx < (cim_verb_data_size / sizeof(u32))) {
126                 u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
127                 verb_size++; // we ship an additional gain value
128                 if (cim_verb_data[idx] != viddid) {
129                         idx += verb_size + 3; // skip verb + header
130                         continue;
131                 }
132                 *verb = &cim_verb_data[idx+3];
133                 return verb_size;
134         }
135
136         /* Not all codecs need to load another verb */
137         return 0;
138 }
139
140 /**
141  *  Wait 50usec for the codec to indicate it is ready
142  *  no response would imply that the codec is non-operative
143  */
144
145 static int wait_for_ready(u32 base)
146 {
147         /* Use a 50 usec timeout - the Linux kernel uses the
148          * same duration */
149
150         int timeout = 50;
151
152         while(timeout--) {
153                 u32 reg32 = read32(base +  HDA_ICII_REG);
154                 if (!(reg32 & HDA_ICII_BUSY))
155                         return 0;
156                 udelay(1);
157         }
158
159         return -1;
160 }
161
162 /**
163  *  Wait 50usec for the codec to indicate that it accepted
164  *  the previous command.  No response would imply that the code
165  *  is non-operative
166  */
167
168 static int wait_for_valid(u32 base)
169 {
170         /* Use a 50 usec timeout - the Linux kernel uses the
171          * same duration */
172
173         int timeout = 25;
174
175         write32(base + 0x68, 1);
176         while(timeout--)
177         {
178                 udelay(1);
179         }
180         timeout = 50;
181         while(timeout--)
182         {
183                 u32 reg32 = read32(base + 0x68);
184                 if ((reg32 & ((1 << 1) | (1 << 0))) ==(1 << 1))
185                 {
186
187                         write32(base + 0x68, 2);
188                         return 0;
189                 }
190                 udelay(1);
191         }
192
193
194         return 1;
195 }
196
197 static void codec_init(struct device *dev, u32 base, int addr)
198 {
199         u32 reg32;
200         const u32 *verb;
201         u32 verb_size;
202         int i;
203
204         printk(BIOS_DEBUG, "sch_audio: Initializing codec #%d\n", addr);
205
206         /* 1 */
207         if (wait_for_ready(base) == -1)
208                 return;
209
210         reg32 = (addr << 28) | 0x000f0000;
211         write32(base + 0x60, reg32);
212
213         if (wait_for_valid(base) == -1)
214                 return;
215
216
217         reg32 = read32(base + 0x0);
218         printk(BIOS_DEBUG, "sch_audio: GCAP: %08x\n", reg32);
219
220         reg32 = read32(base + 0x4);
221         printk(BIOS_DEBUG, "sch_audio: OUTPAY: %08x\n", reg32);
222         reg32 = read32(base + 0x6);
223         printk(BIOS_DEBUG, "sch_audio: INPAY: %08x\n", reg32);
224
225         reg32 = read32(base + 0x64);
226
227         /* 2 */
228         printk(BIOS_DEBUG, "sch_audio: codec viddid: %08x\n", reg32);
229         verb_size = find_verb(dev, reg32, &verb);
230
231         if (!verb_size) {
232                 printk(BIOS_DEBUG, "sch_audio: No verb!\n");
233                 return;
234         }
235         printk(BIOS_DEBUG, "sch_audio: verb_size: %d\n", verb_size);
236
237         /* 3 */
238         for (i = 0; i < verb_size; i++) {
239                 if (wait_for_ready(base) == -1)
240                         return;
241
242                 write32(base + 0x60, verb[i]);
243
244                 if (wait_for_valid(base) == -1)
245                         return;
246         }
247         printk(BIOS_DEBUG, "sch_audio: verb loaded.\n");
248 }
249
250 static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
251 {
252         int i;
253         for (i = 2; i >= 0; i--) {
254                 if (codec_mask & (1 << i))
255                         codec_init(dev, base, i);
256         }
257 }
258
259 static void sch_audio_init(struct device *dev)
260 {
261         u32 base;
262         struct resource *res;
263         u32 codec_mask;
264         u32 reg32;
265
266
267
268         res = find_resource(dev, 0x10);
269         if (!res)
270                 return;
271
272         reg32 = pci_read_config32(dev, PCI_COMMAND);
273         pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MEMORY);
274
275         // NOTE this will break as soon as the sch_audio get's a bar above
276         // 4G. Is there anything we can do about it?
277         base = (u32)res->base;
278         printk(BIOS_DEBUG, "sch_audio: base = %08x\n", (u32)base);
279         codec_mask = codec_detect(base);
280
281         if (codec_mask) {
282                 printk(BIOS_DEBUG, "sch_audio: codec_mask = %02x\n", codec_mask);
283                 codecs_init(dev, base, codec_mask);
284         }
285         else
286         {
287                 /* No audio codecs found disable HD audio controller*/
288                 pci_write_config32(dev, 0x10, 0);
289                 pci_write_config32(dev, PCI_COMMAND, 0);
290                 reg32 = pci_read_config32(dev, 0xFC);
291                 pci_write_config32(dev, 0xFC, reg32 | 1);
292         }
293 }
294
295 static void sch_audio_set_subsystem(device_t dev, unsigned vendor, unsigned device)
296 {
297         if (!vendor || !device) {
298                 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
299                                 pci_read_config32(dev, PCI_VENDOR_ID));
300         } else {
301                 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
302                                 ((device & 0xffff) << 16) | (vendor & 0xffff));
303         }
304 }
305
306 static struct pci_operations sch_audio_pci_ops = {
307         .set_subsystem    = sch_audio_set_subsystem,
308 };
309
310 static struct device_operations sch_audio_ops = {
311         .read_resources         = pci_dev_read_resources,
312         .set_resources          = pci_dev_set_resources,
313         .enable_resources       = pci_dev_enable_resources,
314         .init                   = sch_audio_init,
315         .scan_bus               = 0,
316         .ops_pci                = &sch_audio_pci_ops,
317 };
318
319 /* SCH audio function */
320 static const struct pci_driver sch_audio __pci_driver = {
321         .ops    = &sch_audio_ops,
322         .vendor = PCI_VENDOR_ID_INTEL,
323         .device = 0x811B,
324 };
325