src: Use "foo **bar" instead of "foo ** bar"
[coreboot.git] / src / southbridge / intel / lynxpoint / hda_verb.c
blob93a004eb79d19372570533c021387f2c18dc779b
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 * Copyright (C) 2008-2009 coresystems GmbH
6 * Copyright (C) 2011 Google Inc.
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.
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.
18 #include <console/console.h>
19 #include <arch/io.h>
20 #include <delay.h>
21 #include "pch.h"
22 #include "hda_verb.h"
24 /**
25 * Set bits in a register and wait for status
27 static int set_bits(void *port, u32 mask, u32 val)
29 u32 reg32;
30 int count;
32 /* Write (val & mask) to port */
33 val &= mask;
34 reg32 = read32(port);
35 reg32 &= ~mask;
36 reg32 |= val;
37 write32(port, reg32);
39 /* Wait for readback of register to
40 * match what was just written to it
42 count = 50;
43 do {
44 /* Wait 1ms based on BKDG wait time */
45 mdelay(1);
46 reg32 = read32(port);
47 reg32 &= mask;
48 } while ((reg32 != val) && --count);
50 /* Timeout occurred */
51 if (!count)
52 return -1;
53 return 0;
56 /**
57 * Probe for supported codecs
59 int hda_codec_detect(u8 *base)
61 u8 reg8;
63 /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
64 if (set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, HDA_GCTL_CRST) < 0)
65 goto no_codec;
67 /* Write back the value once reset bit is set. */
68 write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
70 /* Read in Codec location (BAR + 0xe)[2..0]*/
71 reg8 = read8(base + HDA_STATESTS_REG);
72 reg8 &= 0x0f;
73 if (!reg8)
74 goto no_codec;
76 return reg8;
78 no_codec:
79 /* Codec Not found */
80 /* Put HDA back in reset (BAR + 0x8) [0] */
81 set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, 0);
82 printk(BIOS_DEBUG, "HDA: No codec!\n");
83 return 0;
86 /**
87 * Wait 50usec for the codec to indicate it is ready
88 * no response would imply that the codec is non-operative
90 static int hda_wait_for_ready(u8 *base)
92 /* Use a 50 usec timeout - the Linux kernel uses the
93 * same duration */
95 int timeout = 50;
97 while (timeout--) {
98 u32 reg32 = read32(base + HDA_ICII_REG);
99 if (!(reg32 & HDA_ICII_BUSY))
100 return 0;
101 udelay(1);
104 return -1;
108 * Wait 50usec for the codec to indicate that it accepted
109 * the previous command. No response would imply that the code
110 * is non-operative
112 static int hda_wait_for_valid(u8 *base)
114 u32 reg32;
116 /* Send the verb to the codec */
117 reg32 = read32(base + HDA_ICII_REG);
118 reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
119 write32(base + HDA_ICII_REG, reg32);
121 /* Use a 50 usec timeout - the Linux kernel uses the
122 * same duration */
124 int timeout = 50;
125 while (timeout--) {
126 reg32 = read32(base + HDA_ICII_REG);
127 if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
128 HDA_ICII_VALID)
129 return 0;
130 udelay(1);
133 return -1;
137 * Find a specific entry within a verb table
139 * @param verb_table_bytes: verb table size in bytes
140 * @param verb_table_data: verb table data
141 * @param viddid: vendor/device to search for
142 * @param **verb: pointer to entry within table
144 * Returns size of the entry within the verb table,
145 * Returns 0 if the entry is not found
147 * The HDA verb table is composed of dwords. A set of 4 dwords is
148 * grouped together to form a "jack" descriptor.
149 * Bits 31:28 - Codec Address
150 * Bits 27:20 - NID
151 * Bits 19:8 - Verb ID
152 * Bits 7:0 - Payload
154 * coreboot groups different codec verb tables into a single table
155 * and prefixes each with a specific header consisting of 3
156 * dword entries:
157 * 1 - Codec Vendor/Device ID
158 * 2 - Subsystem ID
159 * 3 - Number of jacks (groups of 4 dwords) for this codec
161 static u32 hda_find_verb(u32 verb_table_bytes,
162 const u32 *verb_table_data,
163 u32 viddid, const u32 **verb)
165 int idx=0;
167 while (idx < (verb_table_bytes / sizeof(u32))) {
168 u32 verb_size = 4 * verb_table_data[idx+2]; // in u32
169 if (verb_table_data[idx] != viddid) {
170 idx += verb_size + 3; // skip verb + header
171 continue;
173 *verb = &verb_table_data[idx+3];
174 return verb_size;
177 /* Not all codecs need to load another verb */
178 return 0;
182 * Write a supplied verb table
184 int hda_codec_write(u8 *base, u32 size, const u32 *data)
186 int i;
188 for (i = 0; i < size; i++) {
189 if (hda_wait_for_ready(base) < 0)
190 return -1;
192 write32(base + HDA_IC_REG, data[i]);
194 if (hda_wait_for_valid(base) < 0)
195 return -1;
198 return 0;
202 * Initialize codec, then find the verb table and write it
204 int hda_codec_init(u8 *base, int addr, int verb_size, const u32 *verb_data)
206 const u32 *verb;
207 u32 reg32, size;
208 int rc;
210 printk(BIOS_DEBUG, "HDA: Initializing codec #%d\n", addr);
212 if (!verb_size || !verb_data) {
213 printk(BIOS_DEBUG, "HDA: No verb list!\n");
214 return -1;
217 /* 1 */
218 if (hda_wait_for_ready(base) < 0) {
219 printk(BIOS_DEBUG, " codec not ready.\n");
220 return -1;
223 reg32 = (addr << 28) | 0x000f0000;
224 write32(base + HDA_IC_REG, reg32);
226 if (hda_wait_for_valid(base) < 0) {
227 printk(BIOS_DEBUG, " codec not valid.\n");
228 return -1;
231 /* 2 */
232 reg32 = read32(base + HDA_IR_REG);
233 printk(BIOS_DEBUG, "HDA: codec viddid: %08x\n", reg32);
235 size = hda_find_verb(verb_size, verb_data, reg32, &verb);
236 if (!size) {
237 printk(BIOS_DEBUG, "HDA: No verb table entry found\n");
238 return -1;
241 /* 3 */
242 rc = hda_codec_write(base, size, verb);
244 if (rc < 0)
245 printk(BIOS_DEBUG, "HDA: verb not loaded\n");
246 else
247 printk(BIOS_DEBUG, "HDA: verb loaded.\n");
249 return rc;