coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
lpe.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <device/pci_ops.h>
5 #include <acpi/acpi_gnvs.h>
6 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/pci.h>
9 #include <device/pci_ids.h>
10 #include <reg_script.h>
11 
12 #include <soc/iomap.h>
13 #include <soc/iosf.h>
14 #include <soc/lpc.h>
15 #include <soc/device_nvs.h>
16 #include <soc/pattrs.h>
17 #include <soc/pci_devs.h>
18 #include <soc/pm.h>
19 #include <soc/ramstage.h>
20 #include "chip.h"
21 
22 /*
23  * The LPE audio devices needs 1MiB of memory reserved aligned to a 512MiB
24  * address. Just take 1MiB @ 512MiB.
25  */
26 #define FIRMWARE_PHYS_BASE (512 << 20)
27 #define FIRMWARE_PHYS_LENGTH (2 << 20)
28 #define FIRMWARE_PCI_REG_BASE 0xa8
29 #define FIRMWARE_PCI_REG_LENGTH 0xac
30 #define FIRMWARE_REG_BASE_C0 0x144000
31 #define FIRMWARE_REG_LENGTH_C0 (FIRMWARE_REG_BASE_C0 + 4)
32 
33 static void assign_device_nvs(struct device *dev, u32 *field,
34  unsigned int index)
35 {
36  struct resource *res;
37 
38  res = probe_resource(dev, index);
39  if (res)
40  *field = res->base;
41 }
42 
43 static void lpe_enable_acpi_mode(struct device *dev)
44 {
45  static const struct reg_script ops[] = {
46  /* Disable PCI interrupt, enable Memory and Bus Master */
49 
50  /* Enable ACPI mode */
51  REG_IOSF_OR(IOSF_PORT_0x58, LPE_PCICFGCTR1,
53 
55  };
56  struct device_nvs *dev_nvs = acpi_get_device_nvs();
57 
58  /* Save BAR0, BAR1, and firmware base to ACPI NVS */
62 
63  /* Device is enabled in ACPI mode */
64  dev_nvs->lpe_en = 1;
65 
66  /* Put device in ACPI mode */
68 }
69 
70 static void setup_codec_clock(struct device *dev)
71 {
72  uint32_t reg;
73  u32 *clk_reg;
75  const char *freq_str;
76 
77  config = config_of(dev);
78  switch (config->lpe_codec_clk_src) {
79  case LPE_CLK_SRC_XTAL:
80  /* XTAL driven bit2=0 */
81  freq_str = "19.2MHz External Crystal";
82  reg = CLK_SRC_XTAL;
83  break;
84 
85  case LPE_CLK_SRC_PLL:
86  /* PLL driven bit2=1 */
87  freq_str = "19.2MHz PLL";
88  reg = CLK_SRC_PLL;
89  break;
90 
91  default:
92  reg = CLK_SRC_XTAL;
93  printk(BIOS_DEBUG, "LPE codec clock default to using Crystal\n");
94  return;
95  }
96 
97  /* Default to always running. */
98  reg |= CLK_CTL_ON;
99 
100  printk(BIOS_DEBUG, "LPE Audio codec clock set to %sMHz.\n", freq_str);
101 
102  clk_reg = (u32 *)(PMC_BASE_ADDRESS + PLT_CLK_CTL_0);
103 
104  write32(clk_reg, (read32(clk_reg) & ~0x7) | reg);
105 }
106 
107 static void lpe_stash_firmware_info(struct device *dev)
108 {
109  struct resource *res;
110  struct resource *mmio;
111 
113  if (res == NULL) {
114  printk(BIOS_DEBUG, "LPE Firmware memory not found.\n");
115  return;
116  }
117  printk(BIOS_DEBUG, "LPE FW Resource: 0x%08x\n", (u32) res->base);
118 
119  /* Continue using old way of informing firmware address / size. */
122 
123  /* Also put the address in MMIO space like on C0 BTM */
124  mmio = find_resource(dev, PCI_BASE_ADDRESS_0);
125  write32((void *)(uintptr_t)(mmio->base + FIRMWARE_REG_BASE_C0), res->base);
126  write32((void *)(uintptr_t)(mmio->base + FIRMWARE_REG_LENGTH_C0), res->size);
127 }
128 
129 static void lpe_init(struct device *dev)
130 {
132 
134  setup_codec_clock(dev);
135 
136  if (config->lpe_acpi_mode)
138 }
139 
140 static void lpe_read_resources(struct device *dev)
141 {
142  struct resource *res;
144 
145  /*
146  * Allocate the BAR1 resource at index 2 to fulfill the Windows driver
147  * interface requirements even though the PCI device has only one BAR
148  */
149  res = new_resource(dev, PCI_BASE_ADDRESS_2);
150  res->base = 0;
151  res->size = 0x1000;
152  res->limit = 0xffffffff;
153  res->gran = 12;
154  res->align = 12;
155  res->flags = IORESOURCE_MEM;
156 
158  FIRMWARE_PHYS_LENGTH >> 10);
159 }
160 
161 static void lpe_set_resources(struct device *dev)
162 {
163  struct resource *res;
164 
166  if (res != NULL)
167  res->flags |= IORESOURCE_STORED;
168 
170 }
171 
172 static const struct device_operations device_ops = {
174  .set_resources = lpe_set_resources,
175  .enable_resources = pci_dev_enable_resources,
176  .init = lpe_init,
177  .ops_pci = &soc_pci_ops,
178 };
179 
180 static const struct pci_driver southcluster __pci_driver = {
181  .ops = &device_ops,
182  .vendor = PCI_VID_INTEL,
183  .device = LPE_DEVID,
184 };
void * acpi_get_device_nvs(void)
Definition: gnvs.c:53
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define LPE_PCICFGCTR1_ACPI_INT_EN
Definition: iosf.h:334
#define IOSF_PORT_0x58
Definition: iosf.h:106
#define LPE_PCICFGCTR1_PCI_CFG_DIS
Definition: iosf.h:333
#define LPE_PCICFGCTR1
Definition: iosf.h:332
#define CLK_CTL_ON
Definition: pm.h:110
#define PLT_CLK_CTL_0
Definition: pm.h:101
#define CLK_SRC_PLL
Definition: pm.h:107
#define CLK_SRC_XTAL
Definition: pm.h:106
static void lpe_enable_acpi_mode(struct device *dev)
Definition: lpe.c:43
#define FIRMWARE_PHYS_BASE
Definition: lpe.c:26
#define FIRMWARE_REG_BASE_C0
Definition: lpe.c:30
static const struct device_operations device_ops
Definition: lpe.c:172
#define FIRMWARE_PHYS_LENGTH
Definition: lpe.c:27
static const struct pci_driver southcluster __pci_driver
Definition: lpe.c:180
#define FIRMWARE_PCI_REG_LENGTH
Definition: lpe.c:29
static void lpe_set_resources(struct device *dev)
Definition: lpe.c:161
static void setup_codec_clock(struct device *dev)
Definition: lpe.c:70
static void assign_device_nvs(struct device *dev, u32 *field, unsigned int index)
Definition: lpe.c:33
static void lpe_read_resources(struct device *dev)
Definition: lpe.c:140
#define FIRMWARE_PCI_REG_BASE
Definition: lpe.c:28
#define FIRMWARE_REG_LENGTH_C0
Definition: lpe.c:31
static void lpe_init(struct device *dev)
Definition: lpe.c:129
static void lpe_stash_firmware_info(struct device *dev)
Definition: lpe.c:107
#define printk(level,...)
Definition: stdlib.h:16
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
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
struct resource * find_resource(const struct device *dev, unsigned int index)
Return an existing resource structure for a given index.
Definition: device_util.c:394
static DEVTREE_CONST void * config_of(const struct device *dev)
Definition: device.h:382
#define reserved_ram_resource(dev, idx, basek, sizek)
Definition: device.h:324
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
#define PMC_BASE_ADDRESS
Definition: iomap.h:15
static struct device_operations ops
Definition: ipmi_kcs_ops.c:416
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
enum board_config config
Definition: memory.c:448
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_BASE_ADDRESS_2
Definition: pci_def.h:65
#define PCI_COMMAND_INT_DISABLE
Definition: pci_def.h:21
#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
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
void reg_script_run_on_dev(struct device *dev, const struct reg_script *step)
Definition: reg_script.c:689
#define REG_PCI_OR16(reg_, value_)
Definition: reg_script.h:185
#define REG_SCRIPT_END
Definition: reg_script.h:427
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_STORED
Definition: resource.h:32
struct pci_operations soc_pci_ops
Definition: chip.c:51
#define LPE_DEVID
Definition: pci_devs.h:118
@ LPE_CLK_SRC_XTAL
Definition: chip.h:27
@ LPE_CLK_SRC_PLL
Definition: chip.h:28
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
u32 lpe_bar1
Definition: device_nvs.h:41
u32 lpe_bar0
Definition: device_nvs.h:36
u32 lpe_fw
Definition: device_nvs.h:44
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
unsigned long flags
Definition: resource.h:49
unsigned char align
Definition: resource.h:51
resource_t limit
Definition: resource.h:47
unsigned char gran
Definition: resource.h:52
resource_t base
Definition: resource.h:45
unsigned long index
Definition: resource.h:50
resource_t size
Definition: resource.h:46