coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
azalia_device.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/azalia_device.h>
7 #include <device/mmio.h>
8 #include <delay.h>
9 #include <timer.h>
10 
12 {
13  struct stopwatch sw;
14  u32 reg32;
15 
16  /* Write (val & mask) to port */
17  val &= mask;
18  reg32 = read32(port);
19  reg32 &= ~mask;
20  reg32 |= val;
21  write32(port, reg32);
22 
23  /* Wait for readback of register to match what was just written to it */
25  do {
26  /* Wait 1ms based on BKDG wait time */
27  mdelay(1);
28  reg32 = read32(port);
29  reg32 &= mask;
30  } while ((reg32 != val) && !stopwatch_expired(&sw));
31 
32  /* Timeout occurred */
33  if (stopwatch_expired(&sw))
34  return -1;
35  return 0;
36 }
37 
39 {
40  /* Set bit 0 to 0 to enter reset state (BAR + 0x8)[0] */
42 }
43 
45 {
46  /* Set bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
48 }
49 
51 {
52  struct stopwatch sw;
53  u16 reg16;
54 
55  if (azalia_exit_reset(base) < 0)
56  goto no_codec;
57 
58  if (CONFIG(AZALIA_LOCK_DOWN_R_WO_GCAP)) {
59  /* If GCAP is R/WO, lock it down after deasserting controller reset */
61  }
62 
63  /* clear STATESTS bits (BAR + 0x0e)[14:0] */
64  reg16 = read16(base + HDA_STATESTS_REG);
65  reg16 |= 0x7fff;
66  write16(base + HDA_STATESTS_REG, reg16);
67 
68  /* Wait for readback of register to
69  * match what was just written to it
70  */
72  do {
73  /* Wait 1ms based on BKDG wait time */
74  mdelay(1);
75  reg16 = read16(base + HDA_STATESTS_REG);
76  } while ((reg16 != 0) && !stopwatch_expired(&sw));
77 
78  /* Timeout occurred */
79  if (stopwatch_expired(&sw))
80  goto no_codec;
81 
82  if (azalia_enter_reset(base) < 0)
83  goto no_codec;
84 
85  if (azalia_exit_reset(base) < 0)
86  goto no_codec;
87 
88  /* Read in Codec location (BAR + 0x0e)[14:0] */
89  reg16 = read16(base + HDA_STATESTS_REG);
90  reg16 &= 0x7fff;
91  if (!reg16)
92  goto no_codec;
93 
94  return reg16;
95 
96 no_codec:
97  /* Codec Not found */
98  /* Put HDA back in reset (BAR + 0x8) [0] */
100  printk(BIOS_DEBUG, "azalia_audio: No codec!\n");
101  return 0;
102 }
103 
104 /*
105  * Find a specific entry within a verb table
106  *
107  * @param verb_table: verb table data
108  * @param verb_table_bytes: verb table size in bytes
109  * @param viddid: vendor/device to search for
110  * @param verb: pointer to entry within table
111  *
112  * Returns size of the entry within the verb table,
113  * Returns 0 if the entry is not found
114  *
115  * The HDA verb table is composed of dwords. A set of 4 dwords is
116  * grouped together to form a "jack" descriptor.
117  * Bits 31:28 - Codec Address
118  * Bits 27:20 - NID
119  * Bits 19:8 - Verb ID
120  * Bits 7:0 - Payload
121  *
122  * coreboot groups different codec verb tables into a single table
123  * and prefixes each with a specific header consisting of 3
124  * dword entries:
125  * 1 - Codec Vendor/Device ID
126  * 2 - Subsystem ID
127  * 3 - Number of jacks (groups of 4 dwords) for this codec
128  */
129 u32 azalia_find_verb(const u32 *verb_table, u32 verb_table_bytes, u32 viddid, const u32 **verb)
130 {
131  int idx = 0;
132 
133  while (idx < (verb_table_bytes / sizeof(u32))) {
134  /* Header contains the number of jacks, aka groups of 4 dwords */
135  u32 verb_size = 4 * verb_table[idx + 2];
136  if (verb_table[idx] != viddid) {
137  idx += verb_size + 3; // skip verb + header
138  continue;
139  }
140  *verb = &verb_table[idx + 3];
141  return verb_size;
142  }
143 
144  /* Not all codecs need to load another verb */
145  return 0;
146 }
147 
148 /*
149  * Wait 50usec for the codec to indicate it is ready.
150  * No response would imply that the codec is non-operative.
151  */
152 
153 static int wait_for_ready(u8 *base)
154 {
155  struct stopwatch sw;
156  /* Use a 50 usec timeout - the Linux kernel uses the same duration */
158 
159  while (!stopwatch_expired(&sw)) {
160  u32 reg32 = read32(base + HDA_ICII_REG);
161  if (!(reg32 & HDA_ICII_BUSY))
162  return 0;
163  udelay(1);
164  }
165 
166  return -1;
167 }
168 
169 /*
170  * Wait for the codec to indicate that it accepted the previous command.
171  * No response would imply that the codec is non-operative.
172  */
173 
174 static int wait_for_valid(u8 *base)
175 {
176  struct stopwatch sw;
177  u32 reg32;
178 
179  /* Send the verb to the codec */
180  reg32 = read32(base + HDA_ICII_REG);
181  reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
182  write32(base + HDA_ICII_REG, reg32);
183 
184  /*
185  * The timeout is never reached when the codec is functioning properly.
186  * Using a small timeout value can result in spurious errors with some
187  * codecs, e.g. a codec that is slow to respond but operates correctly.
188  * When a codec is non-operative, the timeout is only reached once per
189  * verb table, thus the impact on booting time is relatively small. So,
190  * use a reasonably long enough timeout to cover all possible cases.
191  */
193  while (!stopwatch_expired(&sw)) {
194  reg32 = read32(base + HDA_ICII_REG);
195  if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)
196  return 0;
197  udelay(1);
198  }
199 
200  return -1;
201 }
202 
203 static int azalia_write_verb(u8 *base, u32 verb)
204 {
205  if (wait_for_ready(base) < 0)
206  return -1;
207 
208  write32(base + HDA_IC_REG, verb);
209 
210  return wait_for_valid(base);
211 }
212 
213 int azalia_program_verb_table(u8 *base, const u32 *verbs, u32 verb_size)
214 {
215  if (!verbs)
216  return 0;
217 
218  for (u32 i = 0; i < verb_size; i++) {
219  if (azalia_write_verb(base, verbs[i]) < 0)
220  return -1;
221  }
222  return 0;
223 }
224 
226 {
227 }
228 
229 void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes)
230 {
231  u32 reg32;
232  const u32 *verb;
233  u32 verb_size;
234 
235  printk(BIOS_DEBUG, "azalia_audio: Initializing codec #%d\n", addr);
236 
237  /* 1 */
238  if (wait_for_ready(base) < 0) {
239  printk(BIOS_DEBUG, " codec not ready.\n");
240  return;
241  }
242 
243  reg32 = (addr << 28) | 0x000f0000;
244  write32(base + HDA_IC_REG, reg32);
245 
246  if (wait_for_valid(base) < 0) {
247  printk(BIOS_DEBUG, " codec not valid.\n");
248  return;
249  }
250 
251  /* 2 */
252  reg32 = read32(base + HDA_IR_REG);
253  printk(BIOS_DEBUG, "azalia_audio: codec viddid: %08x\n", reg32);
254  verb_size = azalia_find_verb(verb_table, verb_table_bytes, reg32, &verb);
255 
256  if (!verb_size) {
257  printk(BIOS_DEBUG, "azalia_audio: No verb!\n");
258  return;
259  }
260  printk(BIOS_DEBUG, "azalia_audio: verb_size: %u\n", verb_size);
261 
262  /* 3 */
263  const int rc = azalia_program_verb_table(base, verb, verb_size);
264  if (rc < 0)
265  printk(BIOS_DEBUG, "azalia_audio: verb not loaded.\n");
266  else
267  printk(BIOS_DEBUG, "azalia_audio: verb loaded.\n");
268 
270 }
271 
272 void azalia_codecs_init(u8 *base, u16 codec_mask)
273 {
274  int i;
275 
276  for (i = 14; i >= 0; i--) {
277  if (codec_mask & (1 << i))
279  }
280 
282 }
283 
284 void azalia_audio_init(struct device *dev)
285 {
286  u8 *base;
287  struct resource *res;
288  u16 codec_mask;
289 
291  if (!res)
292  return;
293 
294  // NOTE this will break as soon as the azalia_audio gets a bar above 4G.
295  // Is there anything we can do about it?
296  base = res2mmio(res, 0, 0);
297  printk(BIOS_DEBUG, "azalia_audio: base = %p\n", base);
298  codec_mask = codec_detect(base);
299 
300  if (codec_mask) {
301  printk(BIOS_DEBUG, "azalia_audio: codec_mask = %02x\n", codec_mask);
302  azalia_codecs_init(base, codec_mask);
303  }
304 }
305 
308  .set_resources = pci_dev_set_resources,
309  .enable_resources = pci_dev_enable_resources,
310  .init = azalia_audio_init,
311  .ops_pci = &pci_dev_ops_pci,
312 };
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint16_t read16(const void *addr)
Definition: mmio.h:17
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static void write16(void *addr, uint16_t val)
Definition: mmio.h:35
int azalia_enter_reset(u8 *base)
Definition: azalia_device.c:38
__weak void mainboard_azalia_program_runtime_verbs(u8 *base, u32 viddid)
void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes)
static u16 codec_detect(u8 *base)
Definition: azalia_device.c:50
static int wait_for_ready(u8 *base)
static int azalia_write_verb(u8 *base, u32 verb)
void azalia_audio_init(struct device *dev)
static int wait_for_valid(u8 *base)
int azalia_set_bits(void *port, u32 mask, u32 val)
Definition: azalia_device.c:11
int azalia_program_verb_table(u8 *base, const u32 *verbs, u32 verb_size)
void azalia_codecs_init(u8 *base, u16 codec_mask)
struct device_operations default_azalia_audio_ops
int azalia_exit_reset(u8 *base)
Definition: azalia_device.c:44
u32 azalia_find_verb(const u32 *verb_table, u32 verb_table_bytes, u32 viddid, const u32 **verb)
#define HDA_ICII_BUSY
Definition: azalia_device.h:18
const u32 cim_verb_data[]
Definition: hda_verb.c:5
#define HDA_GCTL_REG
Definition: azalia_device.h:12
#define HDA_IR_REG
Definition: azalia_device.h:16
#define HDA_GCTL_CRST
Definition: azalia_device.h:13
const u32 cim_verb_data_size
Definition: hda_verb.c:39
const u32 pc_beep_verbs[]
Definition: hda_verb.c:37
#define HDA_ICII_VALID
Definition: azalia_device.h:19
#define HDA_STATESTS_REG
Definition: azalia_device.h:14
#define HDA_GCAP_REG
Definition: azalia_device.h:11
#define HDA_ICII_REG
Definition: azalia_device.h:17
#define HDA_IC_REG
Definition: azalia_device.h:15
const u32 pc_beep_verbs_size
Definition: hda_verb.c:38
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
@ CONFIG
Definition: dsi_common.h:201
port
Definition: i915.h:29
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
struct pci_operations pci_dev_ops_pci
Default device operation for PCI devices.
Definition: pci_device.c:911
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
static void * res2mmio(const struct resource *res, unsigned long offset, unsigned long mask)
Definition: resource.h:87
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15