coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
azalia.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/pci_ids.h>
7 #include <device/pci_ops.h>
8 #include <device/mmio.h>
9 #include <device/azalia_device.h>
10 #include "chip.h"
11 #include "i82801ix.h"
12 
13 static int codec_detect(u8 *base)
14 {
15  u32 reg32;
16 
17  if (azalia_enter_reset(base) < 0)
18  goto no_codec;
19 
20  if (azalia_exit_reset(base) < 0)
21  goto no_codec;
22 
23  /* Read in Codec location (BAR + 0xe)[2..0] */
24  reg32 = read32(base + HDA_STATESTS_REG);
25  reg32 &= 0x0f;
26  if (!reg32)
27  goto no_codec;
28 
29  return reg32;
30 
31 no_codec:
32  /* Codec not found, put HDA back in reset */
34  printk(BIOS_DEBUG, "Azalia: No codec!\n");
35  return 0;
36 }
37 
38 static void azalia_init(struct device *dev)
39 {
40  u8 *base;
41  struct resource *res;
42  u32 codec_mask;
43 
44  // ESD
45  pci_update_config32(dev, 0x134, ~0x00ff0000, 2 << 16);
46 
47  // Link1 description
48  pci_update_config32(dev, 0x140, ~0x00ff0000, 2 << 16);
49 
50  // Port VC0 Resource Control Register
51  pci_update_config32(dev, 0x114, ~0x000000ff, 1);
52 
53  // VCi traffic class
54  pci_or_config8(dev, 0x44, 7 << 0); // TC7
55 
56  // VCi Resource Control
57  pci_or_config32(dev, 0x120, (1 << 31) | (1 << 24) | (0x80 << 0)); /* VCi ID and map */
58 
59  /* Set Bus Master */
61 
62  // Docking not supported
63  pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
64 
65  /* Lock some R/WO bits by writing their current value. */
66  pci_update_config32(dev, 0x74, ~0, 0);
67 
69  if (!res)
70  return;
71 
72  // NOTE this will break as soon as the Azalia gets a bar above 4G.
73  // Is there anything we can do about it?
74  base = res2mmio(res, 0, 0);
75  printk(BIOS_DEBUG, "Azalia: base = %p\n", base);
76  codec_mask = codec_detect(base);
77 
78  if (codec_mask) {
79  printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
80  azalia_codecs_init(base, codec_mask);
81  }
82 }
83 
84 static struct device_operations azalia_ops = {
86  .set_resources = pci_dev_set_resources,
87  .enable_resources = pci_dev_enable_resources,
88  .init = azalia_init,
89  .ops_pci = &pci_dev_ops_pci,
90 };
91 
92 /* ICH9DH/ICH9DO/ICH9R/ICH9/ICH9M-E/ICH9M */
93 static const struct pci_driver i82801ix_azalia __pci_driver = {
94  .ops = &azalia_ops,
95  .vendor = PCI_VID_INTEL,
97 };
static uint32_t read32(const void *addr)
Definition: mmio.h:22
int azalia_enter_reset(u8 *base)
Definition: azalia_device.c:38
void azalia_codecs_init(u8 *base, u16 codec_mask)
int azalia_exit_reset(u8 *base)
Definition: azalia_device.c:44
#define HDA_STATESTS_REG
Definition: azalia_device.h:14
#define printk(level,...)
Definition: stdlib.h:16
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
static const struct pci_driver i82801ix_azalia __pci_driver
Definition: azalia.c:93
static int codec_detect(u8 *base)
Definition: azalia.c:13
static void azalia_init(struct device *dev)
Definition: azalia.c:38
static struct device_operations azalia_ops
Definition: azalia.c:84
static __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
Definition: pci_ops.h:136
static __always_inline void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Definition: pci_ops.h:120
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
static __always_inline void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
Definition: pci_ops.h:169
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
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
#define PCI_DID_INTEL_82801IB_HD_AUDIO
Definition: pci_ids.h:2647
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
static void * res2mmio(const struct resource *res, unsigned long offset, unsigned long mask)
Definition: resource.h:87
uintptr_t base
Definition: uart.c:17
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107