coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
lpss.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdint.h>
4 #include <acpi/acpi_gnvs.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <reg_script.h>
10 
11 #include <soc/iosf.h>
12 #include <soc/nvs.h>
13 #include <soc/device_nvs.h>
14 #include <soc/pci_devs.h>
15 #include <soc/ramstage.h>
16 
17 #include "chip.h"
18 
19 static void dev_enable_acpi_mode(struct device *dev, int iosf_reg, int nvs_index)
20 {
21  struct reg_script ops[] = {
22  /* Disable PCI interrupt, enable Memory and Bus Master */
25  /* Enable ACPI mode */
26  REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
28 
30  };
31  struct resource *bar;
32  struct device_nvs *dev_nvs = acpi_get_device_nvs();
33 
34  /* Save BAR0 and BAR1 to ACPI NVS */
36  if (bar)
37  dev_nvs->lpss_bar0[nvs_index] = (u32)bar->base;
38 
40  if (bar)
41  dev_nvs->lpss_bar1[nvs_index] = (u32)bar->base;
42 
43  /* Device is enabled in ACPI mode */
44  dev_nvs->lpss_en[nvs_index] = 1;
45 
46  /* Put device in ACPI mode */
48 }
49 
50 static void dev_enable_snoop_and_pm(struct device *dev, int iosf_reg)
51 {
52  struct reg_script ops[] = {
53  REG_IOSF_RMW(IOSF_PORT_LPSS, iosf_reg,
57  };
58 
60 }
61 
62 #define SET_IOSF_REG(name_) \
63  case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
64  do { \
65  *iosf_reg = LPSS_ ## name_ ## _CTL; \
66  *nvs_index = LPSS_NVS_ ## name_; \
67  } while (0)
68 
69 static void dev_ctl_reg(struct device *dev, int *iosf_reg, int *nvs_index)
70 {
71  *iosf_reg = -1;
72  *nvs_index = -1;
73 
74  switch (dev->path.pci.devfn) {
75  SET_IOSF_REG(SIO_DMA1);
76  break;
78  break;
80  break;
82  break;
84  break;
86  break;
88  break;
90  break;
91  SET_IOSF_REG(SIO_DMA2);
92  break;
93  SET_IOSF_REG(PWM1);
94  break;
95  SET_IOSF_REG(PWM2);
96  break;
97  SET_IOSF_REG(HSUART1);
98  break;
99  SET_IOSF_REG(HSUART2);
100  break;
101  SET_IOSF_REG(SPI);
102  break;
103  }
104 }
105 
106 #define CASE_I2C(name_) case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC)
107 
108 static void i2c_disable_resets(struct device *dev)
109 {
110  /* Release the I2C devices from reset. */
111  static const struct reg_script ops[] = {
112  REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x804, 0x3),
114  };
115 
116  switch (dev->path.pci.devfn) {
117  CASE_I2C(I2C1):
118  CASE_I2C(I2C2):
119  CASE_I2C(I2C3):
120  CASE_I2C(I2C4):
121  CASE_I2C(I2C5):
122  CASE_I2C(I2C6):
123  CASE_I2C(I2C7):
124  printk(BIOS_DEBUG, "Releasing I2C device from reset.\n");
126  break;
127  default:
128  return;
129  }
130 }
131 
132 static void lpss_init(struct device *dev)
133 {
135  int iosf_reg, nvs_index;
136 
137  dev_ctl_reg(dev, &iosf_reg, &nvs_index);
138 
139  if (iosf_reg < 0) {
140  int slot = PCI_SLOT(dev->path.pci.devfn);
141  int func = PCI_FUNC(dev->path.pci.devfn);
142  printk(BIOS_DEBUG, "Could not find iosf_reg for %02x.%01x\n", slot, func);
143  return;
144  }
145  dev_enable_snoop_and_pm(dev, iosf_reg);
146  i2c_disable_resets(dev);
147 
148  if (config->lpss_acpi_mode)
149  dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
150 }
151 
152 static struct device_operations device_ops = {
154  .set_resources = pci_dev_set_resources,
155  .enable_resources = pci_dev_enable_resources,
156  .init = lpss_init,
157  .ops_pci = &soc_pci_ops,
158 };
159 
160 static const unsigned short pci_device_ids[] = {
162  I2C1_DEVID,
163  I2C2_DEVID,
164  I2C3_DEVID,
165  I2C4_DEVID,
166  I2C5_DEVID,
167  I2C6_DEVID,
168  I2C7_DEVID,
170  PWM1_DEVID,
171  PWM2_DEVID,
174  SPI_DEVID,
175  0,
176 };
177 
178 static const struct pci_driver southcluster __pci_driver = {
179  .ops = &device_ops,
180  .vendor = PCI_VID_INTEL,
181  .devices = pci_device_ids,
182 };
void * acpi_get_device_nvs(void)
Definition: gnvs.c:53
#define LPSS_CTL_SNOOP
Definition: iosf.h:277
#define LPSS_CTL_NOSNOOP
Definition: iosf.h:278
#define IOSF_PORT_LPSS
Definition: iosf.h:111
#define LPSS_CTL_PCI_CFG_DIS
Definition: iosf.h:276
#define LPSS_CTL_ACPI_INT_EN
Definition: iosf.h:275
#define LPSS_CTL_PM_CAP_PRSNT
Definition: iosf.h:279
static struct device_operations device_ops
Definition: lpss.c:152
static void dev_ctl_reg(struct device *dev, int *iosf_reg, int *nvs_index)
Definition: lpss.c:69
static void lpss_init(struct device *dev)
Definition: lpss.c:132
static const struct pci_driver southcluster __pci_driver
Definition: lpss.c:178
#define CASE_I2C(name_)
Definition: lpss.c:106
static const unsigned short pci_device_ids[]
Definition: lpss.c:160
static void i2c_disable_resets(struct device *dev)
Definition: lpss.c:108
#define SET_IOSF_REG(name_)
Definition: lpss.c:62
static void dev_enable_snoop_and_pm(struct device *dev, int iosf_reg)
Definition: lpss.c:50
static void dev_enable_acpi_mode(struct device *dev, int iosf_reg, int nvs_index)
Definition: lpss.c:19
#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 DEVTREE_CONST void * config_of(const struct device *dev)
Definition: device.h:382
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_FUNC(devfn)
Definition: pci_def.h:550
#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
#define PCI_BASE_ADDRESS_1
Definition: pci_def.h:64
#define PCI_SLOT(devfn)
Definition: pci_def.h:549
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
#define REG_RES_WRITE32(bar_, reg_, value_)
Definition: reg_script.h:325
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
struct pci_operations soc_pci_ops
Definition: chip.c:51
#define PWM2_DEVID
Definition: pci_devs.h:137
#define PWM1_DEVID
Definition: pci_devs.h:136
#define I2C1_DEVID
Definition: pci_devs.h:121
#define I2C7_DEVID
Definition: pci_devs.h:127
#define HSUART2_DEVID
Definition: pci_devs.h:139
#define SIO_DMA2_DEVID
Definition: pci_devs.h:135
#define SIO_DMA1_DEVID
Definition: pci_devs.h:120
#define I2C4_DEVID
Definition: pci_devs.h:124
#define HSUART1_DEVID
Definition: pci_devs.h:138
#define I2C6_DEVID
Definition: pci_devs.h:126
#define SPI_DEVID
Definition: pci_devs.h:140
#define I2C5_DEVID
Definition: pci_devs.h:125
#define I2C3_DEVID
Definition: pci_devs.h:123
#define I2C2_DEVID
Definition: pci_devs.h:122
@ I2C7
Definition: i2c.h:57
@ I2C4
Definition: i2c.h:54
@ I2C5
Definition: i2c.h:55
@ I2C3
Definition: i2c.h:53
@ I2C2
Definition: i2c.h:52
@ I2C1
Definition: i2c.h:51
@ I2C6
Definition: i2c.h:56
uint32_t u32
Definition: stdint.h:51
u8 lpss_en[14]
Definition: device_nvs.h:29
u32 lpss_bar1[14]
Definition: device_nvs.h:39
u32 lpss_bar0[14]
Definition: device_nvs.h:34
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
unsigned int devfn
Definition: path.h:54
struct device * dev
Definition: reg_script.h:78
resource_t base
Definition: resource.h:45