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 
11 #include "pch.h"
12 #include "hda_verb.h"
13 
14 static void azalia_pch_init(struct device *dev, u8 *base)
15 {
16  u8 reg8;
17  u16 reg16;
18  u32 reg32;
19 
20  if (RCBA32(0x2030) & (1 << 31)) {
21  reg32 = pci_read_config32(dev, 0x120);
22  reg32 &= 0xf8ffff01;
23  reg32 |= (1 << 25);
24  reg32 |= RCBA32(0x2030) & 0xfe;
25  pci_write_config32(dev, 0x120, reg32);
26 
27  if (!pch_is_lp()) {
28  pci_and_config16(dev, 0x78, ~(1 << 11));
29  }
30  } else
31  printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
32 
33  reg32 = pci_read_config32(dev, 0x114);
34  reg32 &= ~0xfe;
35  pci_write_config32(dev, 0x114, reg32);
36 
37  // Set VCi enable bit
38  if (pci_read_config32(dev, 0x120) & ((1 << 24) | (1 << 25) | (1 << 26))) {
39  reg32 = pci_read_config32(dev, 0x120);
40  if (pch_is_lp())
41  reg32 &= ~(1 << 31);
42  else
43  reg32 |= (1 << 31);
44  pci_write_config32(dev, 0x120, reg32);
45  }
46 
47  reg8 = pci_read_config8(dev, 0x43);
48  if (pch_is_lp())
49  reg8 &= ~(1 << 6);
50  else
51  reg8 |= (1 << 4);
52  pci_write_config8(dev, 0x43, reg8);
53 
54  if (!pch_is_lp())
55  pci_or_config32(dev, 0xc0, 1 << 17);
56 
57  /* Additional programming steps */
58  reg32 = pci_read_config32(dev, 0xc4);
59  if (pch_is_lp())
60  reg32 |= (1 << 24);
61  else
62  reg32 |= (1 << 14);
63  pci_write_config32(dev, 0xc4, reg32);
64 
65  if (!pch_is_lp())
66  pci_and_config32(dev, 0xd0, ~(1 << 31));
67 
68  // Docking not supported
69  pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
70 
71  if (pch_is_lp()) {
72  reg16 = read32(base + 0x0012);
73  reg16 |= (1 << 0);
74  write32(base + 0x0012, reg16);
75 
76  /* disable Auto Voltage Detector */
77  pci_or_config8(dev, 0x42, 1 << 2);
78  }
79 }
80 
81 static void azalia_init(struct device *dev)
82 {
83  u8 *base;
84  struct resource *res;
85  u32 codec_mask;
86 
87  /* Find base address */
89  if (!res)
90  return;
91 
92  base = res2mmio(res, 0, 0);
93  printk(BIOS_DEBUG, "Azalia: base = %p\n", base);
94 
95  /* Set Bus Master */
97 
98  azalia_pch_init(dev, base);
99 
100  codec_mask = hda_codec_detect(base);
101 
102  if (codec_mask) {
103  printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
104  azalia_codecs_init(base, codec_mask);
105  }
106 }
107 
108 static void azalia_final(struct device *dev)
109 {
110  /* Set HDCFG.BCLD */
111  pci_or_config16(dev, 0x40, 1 << 1);
112 }
113 
114 static struct device_operations azalia_ops = {
116  .set_resources = pci_dev_set_resources,
117  .enable_resources = pci_dev_enable_resources,
118  .init = azalia_init,
119  .final = azalia_final,
120  .ops_pci = &pci_dev_ops_pci,
121 };
122 
123 static const unsigned short pci_device_ids[] = {
126  0
127 };
128 
129 static const struct pci_driver pch_azalia __pci_driver = {
130  .ops = &azalia_ops,
131  .vendor = PCI_VID_INTEL,
132  .devices = pci_device_ids,
133 };
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void azalia_codecs_init(u8 *base, u16 codec_mask)
#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 __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline void pci_and_config16(const struct device *dev, u16 reg, u16 andmask)
Definition: pci_ops.h:147
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_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
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
Definition: pci_ops.h:158
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static void azalia_final(struct device *dev)
Definition: azalia.c:108
static const unsigned short pci_device_ids[]
Definition: azalia.c:123
static void azalia_pch_init(struct device *dev, u8 *base)
Definition: azalia.c:14
static void azalia_init(struct device *dev)
Definition: azalia.c:81
static struct device_operations azalia_ops
Definition: azalia.c:114
static const struct pci_driver pch_azalia __pci_driver
Definition: azalia.c:129
#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_LPT_LP_AUDIO
Definition: pci_ids.h:4182
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
#define PCI_DID_INTEL_LPT_H_AUDIO
Definition: pci_ids.h:4181
static void * res2mmio(const struct resource *res, unsigned long offset, unsigned long mask)
Definition: resource.h:87
uintptr_t base
Definition: uart.c:17
int hda_codec_detect(u8 *base)
Definition: hda_verb.c:10
#define RCBA32(x)
Definition: rcba.h:14
static int pch_is_lp(void)
Definition: pch.h:104
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