soc: Remove copyright notices
[coreboot.git] / src / soc / intel / baytrail / lpss.c
blob71b6dacbb553c4e84b825b78a6f6845331b5d3ee
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <stdint.h>
16 #include <cbmem.h>
17 #include <console/console.h>
18 #include <device/device.h>
19 #include <device/pci.h>
20 #include <device/pci_ids.h>
21 #include <reg_script.h>
23 #include <soc/iosf.h>
24 #include <soc/nvs.h>
25 #include <soc/pci_devs.h>
26 #include <soc/ramstage.h>
28 #include "chip.h"
30 static void dev_enable_acpi_mode(struct device *dev, int iosf_reg,
31 int nvs_index)
33 struct reg_script ops[] = {
34 /* Disable PCI interrupt, enable Memory and Bus Master */
35 REG_PCI_OR32(PCI_COMMAND,
36 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
37 /* Enable ACPI mode */
38 REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
39 LPSS_CTL_PCI_CFG_DIS | LPSS_CTL_ACPI_INT_EN),
40 REG_SCRIPT_END
42 struct resource *bar;
43 global_nvs_t *gnvs;
45 /* Find ACPI NVS to update BARs */
46 gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
47 if (!gnvs) {
48 printk(BIOS_ERR, "Unable to locate Global NVS\n");
49 return;
52 /* Save BAR0 and BAR1 to ACPI NVS */
53 bar = find_resource(dev, PCI_BASE_ADDRESS_0);
54 if (bar)
55 gnvs->dev.lpss_bar0[nvs_index] = (u32)bar->base;
57 bar = find_resource(dev, PCI_BASE_ADDRESS_1);
58 if (bar)
59 gnvs->dev.lpss_bar1[nvs_index] = (u32)bar->base;
61 /* Device is enabled in ACPI mode */
62 gnvs->dev.lpss_en[nvs_index] = 1;
64 /* Put device in ACPI mode */
65 reg_script_run_on_dev(dev, ops);
68 static void dev_enable_snoop_and_pm(struct device *dev, int iosf_reg)
70 struct reg_script ops[] = {
71 REG_IOSF_RMW(IOSF_PORT_LPSS, iosf_reg,
72 ~(LPSS_CTL_SNOOP | LPSS_CTL_NOSNOOP),
73 LPSS_CTL_SNOOP | LPSS_CTL_PM_CAP_PRSNT),
74 REG_SCRIPT_END,
77 reg_script_run_on_dev(dev, ops);
80 static void dev_ctl_reg(struct device *dev, int *iosf_reg, int *nvs_index)
82 *iosf_reg = -1;
83 *nvs_index = -1;
84 #define SET_IOSF_REG(name_) \
85 case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
86 *iosf_reg = LPSS_ ## name_ ## _CTL; \
87 *nvs_index = LPSS_NVS_ ## name_
89 switch (dev->path.pci.devfn) {
90 SET_IOSF_REG(SIO_DMA1);
91 break;
92 SET_IOSF_REG(I2C1);
93 break;
94 SET_IOSF_REG(I2C2);
95 break;
96 SET_IOSF_REG(I2C3);
97 break;
98 SET_IOSF_REG(I2C4);
99 break;
100 SET_IOSF_REG(I2C5);
101 break;
102 SET_IOSF_REG(I2C6);
103 break;
104 SET_IOSF_REG(I2C7);
105 break;
106 SET_IOSF_REG(SIO_DMA2);
107 break;
108 SET_IOSF_REG(PWM1);
109 break;
110 SET_IOSF_REG(PWM2);
111 break;
112 SET_IOSF_REG(HSUART1);
113 break;
114 SET_IOSF_REG(HSUART2);
115 break;
116 SET_IOSF_REG(SPI);
117 break;
121 static void i2c_disable_resets(struct device *dev)
123 /* Release the I2C devices from reset. */
124 static const struct reg_script ops[] = {
125 REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x804, 0x3),
126 REG_SCRIPT_END,
129 #define CASE_I2C(name_) \
130 case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC)
132 switch (dev->path.pci.devfn) {
133 CASE_I2C(I2C1):
134 CASE_I2C(I2C2):
135 CASE_I2C(I2C3):
136 CASE_I2C(I2C4):
137 CASE_I2C(I2C5):
138 CASE_I2C(I2C6):
139 CASE_I2C(I2C7):
140 printk(BIOS_DEBUG, "Releasing I2C device from reset.\n");
141 reg_script_run_on_dev(dev, ops);
142 break;
143 default:
144 return;
148 static void lpss_init(struct device *dev)
150 struct soc_intel_baytrail_config *config = config_of(dev);
151 int iosf_reg, nvs_index;
153 dev_ctl_reg(dev, &iosf_reg, &nvs_index);
155 if (iosf_reg < 0) {
156 int slot = PCI_SLOT(dev->path.pci.devfn);
157 int func = PCI_FUNC(dev->path.pci.devfn);
158 printk(BIOS_DEBUG, "Could not find iosf_reg for %02x.%01x\n",
159 slot, func);
160 return;
162 dev_enable_snoop_and_pm(dev, iosf_reg);
163 i2c_disable_resets(dev);
165 if (config->lpss_acpi_mode)
166 dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
169 static struct device_operations device_ops = {
170 .read_resources = pci_dev_read_resources,
171 .set_resources = pci_dev_set_resources,
172 .enable_resources = pci_dev_enable_resources,
173 .init = lpss_init,
174 .enable = NULL,
175 .scan_bus = NULL,
176 .ops_pci = &soc_pci_ops,
179 static const unsigned short pci_device_ids[] = {
180 SIO_DMA1_DEVID,
181 I2C1_DEVID,
182 I2C2_DEVID,
183 I2C3_DEVID,
184 I2C4_DEVID,
185 I2C5_DEVID,
186 I2C6_DEVID,
187 I2C7_DEVID,
188 SIO_DMA2_DEVID,
189 PWM1_DEVID,
190 PWM2_DEVID,
191 HSUART1_DEVID,
192 HSUART2_DEVID,
193 SPI_DEVID,
197 static const struct pci_driver southcluster __pci_driver = {
198 .ops = &device_ops,
199 .vendor = PCI_VENDOR_ID_INTEL,
200 .devices = pci_device_ids,