1 /* SPDX-License-Identifier: GPL-2.0-only */
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>
13 #include <soc/device_nvs.h>
14 #include <soc/pci_devs.h>
15 #include <soc/ramstage.h>
19 static void dev_enable_acpi_mode(struct device
*dev
, int iosf_reg
, int nvs_index
)
21 struct reg_script ops
[] = {
22 /* Disable PCI interrupt, enable Memory and Bus Master */
23 REG_PCI_OR16(PCI_COMMAND
,
24 PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
| PCI_COMMAND_INT_DISABLE
),
25 /* Enable ACPI mode */
26 REG_IOSF_OR(IOSF_PORT_LPSS
, iosf_reg
,
27 LPSS_CTL_PCI_CFG_DIS
| LPSS_CTL_ACPI_INT_EN
),
32 struct device_nvs
*dev_nvs
= acpi_get_device_nvs();
34 /* Save BAR0 and BAR1 to ACPI NVS */
35 bar
= probe_resource(dev
, PCI_BASE_ADDRESS_0
);
37 dev_nvs
->lpss_bar0
[nvs_index
] = (u32
)bar
->base
;
39 bar
= probe_resource(dev
, PCI_BASE_ADDRESS_1
);
41 dev_nvs
->lpss_bar1
[nvs_index
] = (u32
)bar
->base
;
43 /* Device is enabled in ACPI mode */
44 dev_nvs
->lpss_en
[nvs_index
] = 1;
46 /* Put device in ACPI mode */
47 reg_script_run_on_dev(dev
, ops
);
50 static void dev_enable_snoop_and_pm(struct device
*dev
, int iosf_reg
)
52 struct reg_script ops
[] = {
53 REG_IOSF_RMW(IOSF_PORT_LPSS
, iosf_reg
,
54 ~(LPSS_CTL_SNOOP
| LPSS_CTL_NOSNOOP
),
55 LPSS_CTL_SNOOP
| LPSS_CTL_PM_CAP_PRSNT
),
59 reg_script_run_on_dev(dev
, ops
);
62 #define SET_IOSF_REG(name_) \
63 case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
65 *iosf_reg = LPSS_ ## name_ ## _CTL; \
66 *nvs_index = LPSS_NVS_ ## name_; \
69 static void dev_ctl_reg(struct device
*dev
, int *iosf_reg
, int *nvs_index
)
74 switch (dev
->path
.pci
.devfn
) {
75 SET_IOSF_REG(SIO_DMA1
);
91 SET_IOSF_REG(SIO_DMA2
);
97 SET_IOSF_REG(HSUART1
);
99 SET_IOSF_REG(HSUART2
);
106 #define CASE_I2C(name_) case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC)
108 static void i2c_disable_resets(struct device
*dev
)
110 /* Release the I2C devices from reset. */
111 static const struct reg_script ops
[] = {
112 REG_RES_WRITE32(PCI_BASE_ADDRESS_0
, 0x804, 0x3),
116 switch (dev
->path
.pci
.devfn
) {
124 printk(BIOS_DEBUG
, "Releasing I2C device from reset.\n");
125 reg_script_run_on_dev(dev
, ops
);
132 static void lpss_init(struct device
*dev
)
134 struct soc_intel_baytrail_config
*config
= config_of(dev
);
135 int iosf_reg
, nvs_index
;
137 dev_ctl_reg(dev
, &iosf_reg
, &nvs_index
);
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
);
145 dev_enable_snoop_and_pm(dev
, iosf_reg
);
146 i2c_disable_resets(dev
);
148 if (config
->lpss_acpi_mode
)
149 dev_enable_acpi_mode(dev
, iosf_reg
, nvs_index
);
152 static struct device_operations device_ops
= {
153 .read_resources
= pci_dev_read_resources
,
154 .set_resources
= pci_dev_set_resources
,
155 .enable_resources
= pci_dev_enable_resources
,
157 .ops_pci
= &soc_pci_ops
,
160 static const unsigned short pci_device_ids
[] = {
178 static const struct pci_driver southcluster __pci_driver
= {
180 .vendor
= PCI_VID_INTEL
,
181 .devices
= pci_device_ids
,