blob: ddb51ccf12f1599d5cd498081d73c07bb7cdc681 [file] [log] [blame]
Angel Ponsf94ac9a2020-04-05 15:46:48 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Lauriec88c54c2014-04-30 16:36:13 -07002
3#include <console/console.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02004#include <device/pci_ops.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -07005#include <device/device.h>
6#include <device/pci.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -07007#include <soc/pch.h>
8#include <soc/pci_devs.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -07009#include <soc/rcba.h>
10#include <soc/serialio.h>
11#include <soc/spi.h>
Angel Ponsc423ce22021-04-19 16:13:31 +020012#include <southbridge/intel/lynxpoint/iobp.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070013
14u8 pch_revision(void)
15{
16 return pci_read_config8(PCH_DEV_LPC, PCI_REVISION_ID);
17}
18
19u16 pch_type(void)
20{
21 return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID);
22}
23
24/* Return 1 if PCH type is WildcatPoint */
25int pch_is_wpt(void)
26{
27 return ((pch_type() & 0xfff0) == 0x9cc0) ? 1 : 0;
28}
29
30/* Return 1 if PCH type is WildcatPoint ULX */
31int pch_is_wpt_ulx(void)
32{
33 u16 lpcid = pch_type();
34
35 switch (lpcid) {
36 case PCH_WPT_BDW_Y_SAMPLE:
37 case PCH_WPT_BDW_Y_PREMIUM:
38 case PCH_WPT_BDW_Y_BASE:
39 return 1;
40 }
41
42 return 0;
43}
44
45u32 pch_read_soft_strap(int id)
46{
47 u32 fdoc;
48
49 fdoc = SPIBAR32(SPIBAR_FDOC);
50 fdoc &= ~0x00007ffc;
51 SPIBAR32(SPIBAR_FDOC) = fdoc;
52
53 fdoc |= 0x00004000;
54 fdoc |= id * 4;
55 SPIBAR32(SPIBAR_FDOC) = fdoc;
56
57 return SPIBAR32(SPIBAR_FDOD);
58}
59
Kyösti Mälkki55d0ab52019-09-12 15:44:28 +030060#ifndef __SIMPLE_DEVICE__
Duncan Lauriec88c54c2014-04-30 16:36:13 -070061
62/* Put device in D3Hot Power State */
Elyes HAOUAS4658a982018-09-20 08:46:35 +020063static void pch_enable_d3hot(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070064{
Angel Pons2ead3632020-09-24 16:50:05 +020065 pci_or_config32(dev, PCH_PCS, PCH_PCS_PS_D3HOT);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070066}
67
Wenkai Duaec24422014-10-15 11:19:16 -070068/* RCBA function disable and posting read to flush the transaction */
69static void rcba_function_disable(u32 reg, u32 bit)
70{
71 RCBA32_OR(reg, bit);
72 RCBA32(reg);
73}
74
Martin Rothde7ed6f2014-12-07 14:58:18 -070075/* Set bit in Function Disable register to hide this device */
Elyes HAOUAS4658a982018-09-20 08:46:35 +020076void pch_disable_devfn(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070077{
78 switch (dev->path.pci.devfn) {
Duncan Laurie61680272014-05-05 12:42:35 -050079 case PCH_DEVFN_ADSP: /* Audio DSP */
Wenkai Duaec24422014-10-15 11:19:16 -070080 rcba_function_disable(FD, PCH_DISABLE_ADSPD);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070081 break;
Duncan Laurie61680272014-05-05 12:42:35 -050082 case PCH_DEVFN_XHCI: /* XHCI */
Wenkai Duaec24422014-10-15 11:19:16 -070083 rcba_function_disable(FD, PCH_DISABLE_XHCI);
Duncan Lauriec88c54c2014-04-30 16:36:13 -070084 break;
Duncan Laurie61680272014-05-05 12:42:35 -050085 case PCH_DEVFN_SDMA: /* DMA */
Duncan Lauriec88c54c2014-04-30 16:36:13 -070086 pch_enable_d3hot(dev);
87 pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS);
88 break;
Duncan Laurie61680272014-05-05 12:42:35 -050089 case PCH_DEVFN_I2C0: /* I2C0 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -070090 pch_enable_d3hot(dev);
91 pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS);
92 break;
Duncan Laurie61680272014-05-05 12:42:35 -050093 case PCH_DEVFN_I2C1: /* I2C1 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -070094 pch_enable_d3hot(dev);
95 pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS);
96 break;
Duncan Laurie61680272014-05-05 12:42:35 -050097 case PCH_DEVFN_SPI0: /* SPI0 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -070098 pch_enable_d3hot(dev);
99 pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS);
100 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500101 case PCH_DEVFN_SPI1: /* SPI1 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700102 pch_enable_d3hot(dev);
103 pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS);
104 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500105 case PCH_DEVFN_UART0: /* UART0 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700106 pch_enable_d3hot(dev);
107 pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS);
108 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500109 case PCH_DEVFN_UART1: /* UART1 */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700110 pch_enable_d3hot(dev);
111 pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS);
112 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500113 case PCH_DEVFN_ME: /* MEI #1 */
Wenkai Duaec24422014-10-15 11:19:16 -0700114 rcba_function_disable(FD2, PCH_DISABLE_MEI1);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700115 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500116 case PCH_DEVFN_ME_2: /* MEI #2 */
Wenkai Duaec24422014-10-15 11:19:16 -0700117 rcba_function_disable(FD2, PCH_DISABLE_MEI2);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700118 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500119 case PCH_DEVFN_ME_IDER: /* IDE-R */
Wenkai Duaec24422014-10-15 11:19:16 -0700120 rcba_function_disable(FD2, PCH_DISABLE_IDER);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700121 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500122 case PCH_DEVFN_ME_KT: /* KT */
Wenkai Duaec24422014-10-15 11:19:16 -0700123 rcba_function_disable(FD2, PCH_DISABLE_KT);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700124 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500125 case PCH_DEVFN_SDIO: /* SDIO */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700126 pch_enable_d3hot(dev);
127 pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS);
128 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500129 case PCH_DEVFN_GBE: /* Gigabit Ethernet */
Wenkai Duaec24422014-10-15 11:19:16 -0700130 rcba_function_disable(BUC, PCH_DISABLE_GBE);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700131 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500132 case PCH_DEVFN_HDA: /* HD Audio Controller */
Wenkai Duaec24422014-10-15 11:19:16 -0700133 rcba_function_disable(FD, PCH_DISABLE_HD_AUDIO);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700134 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500135 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 0): /* PCI Express Root Port 1 */
136 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 1): /* PCI Express Root Port 2 */
137 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 2): /* PCI Express Root Port 3 */
138 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 3): /* PCI Express Root Port 4 */
139 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 4): /* PCI Express Root Port 5 */
140 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 5): /* PCI Express Root Port 6 */
141 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 6): /* PCI Express Root Port 7 */
142 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 7): /* PCI Express Root Port 8 */
Wenkai Duaec24422014-10-15 11:19:16 -0700143 rcba_function_disable(FD,
144 PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700145 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500146 case PCH_DEVFN_EHCI: /* EHCI #1 */
Wenkai Duaec24422014-10-15 11:19:16 -0700147 rcba_function_disable(FD, PCH_DISABLE_EHCI1);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700148 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500149 case PCH_DEVFN_LPC: /* LPC */
Wenkai Duaec24422014-10-15 11:19:16 -0700150 rcba_function_disable(FD, PCH_DISABLE_LPC);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700151 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500152 case PCH_DEVFN_SATA: /* SATA #1 */
Wenkai Duaec24422014-10-15 11:19:16 -0700153 rcba_function_disable(FD, PCH_DISABLE_SATA1);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700154 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500155 case PCH_DEVFN_SMBUS: /* SMBUS */
Wenkai Duaec24422014-10-15 11:19:16 -0700156 rcba_function_disable(FD, PCH_DISABLE_SMBUS);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700157 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500158 case PCH_DEVFN_SATA2: /* SATA #2 */
Wenkai Duaec24422014-10-15 11:19:16 -0700159 rcba_function_disable(FD, PCH_DISABLE_SATA2);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700160 break;
Duncan Laurie61680272014-05-05 12:42:35 -0500161 case PCH_DEVFN_THERMAL: /* Thermal Subsystem */
Wenkai Duaec24422014-10-15 11:19:16 -0700162 rcba_function_disable(FD, PCH_DISABLE_THERMAL);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700163 break;
164 }
165}
166
Angel Pons3cc2c382020-10-23 20:38:23 +0200167static void broadwell_pch_enable_dev(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700168{
Angel Pons3cc2c382020-10-23 20:38:23 +0200169 if (dev->path.type != DEVICE_PATH_PCI)
170 return;
171
172 if (dev->ops && dev->ops->enable)
173 return;
174
Duncan Laurie61680272014-05-05 12:42:35 -0500175 /* These devices need special enable/disable handling */
176 switch (PCI_SLOT(dev->path.pci.devfn)) {
177 case PCH_DEV_SLOT_PCIE:
178 case PCH_DEV_SLOT_EHCI:
179 case PCH_DEV_SLOT_HDA:
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700180 return;
Duncan Laurie61680272014-05-05 12:42:35 -0500181 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700182
183 if (!dev->enabled) {
184 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
185
186 /* Ensure memory, io, and bus master are all disabled */
Angel Pons6b486e12020-10-28 14:16:06 +0100187 pci_and_config16(dev, PCI_COMMAND,
188 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700189
190 /* Disable this device if possible */
191 pch_disable_devfn(dev);
192 } else {
193 /* Enable SERR */
Elyes HAOUASb887adf2020-04-29 10:42:34 +0200194 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700195 }
196}
197
Angel Pons3cc2c382020-10-23 20:38:23 +0200198struct chip_operations soc_intel_broadwell_pch_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +0900199 .name = "Intel Broadwell PCH",
Angel Pons3cc2c382020-10-23 20:38:23 +0200200 .enable_dev = &broadwell_pch_enable_dev,
201};
202
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700203#endif