blob: 8f7cdb8cc0467c5be48bb09d7a2dfed0de0ab514 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin76c37002012-10-30 09:03:43 -05002
3#include <console/console.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02004#include <device/pci_ops.h>
Aaron Durbin76c37002012-10-30 09:03:43 -05005#include <device/device.h>
6#include <device/pci.h>
Stefan Reinauer5605f1b2013-03-21 18:43:51 -07007#include <device/pci_def.h>
Angel Pons2178b722020-05-31 00:55:35 +02008#include "iobp.h"
Aaron Durbin76c37002012-10-30 09:03:43 -05009#include "pch.h"
10
Elyes HAOUAS1dcd8db2018-12-05 10:59:42 +010011#ifdef __SIMPLE_DEVICE__
12static pci_devfn_t pch_get_lpc_device(void)
Duncan Laurie5cc51c02013-03-07 14:06:43 -080013{
Duncan Laurie5cc51c02013-03-07 14:06:43 -080014 return PCI_DEV(0, 0x1f, 0);
Duncan Laurie5cc51c02013-03-07 14:06:43 -080015}
Elyes HAOUAS1dcd8db2018-12-05 10:59:42 +010016#else
17static struct device *pch_get_lpc_device(void)
18{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030019 return pcidev_on_root(0x1f, 0);
Elyes HAOUAS1dcd8db2018-12-05 10:59:42 +010020}
21#endif
Aaron Durbin76c37002012-10-30 09:03:43 -050022
23int pch_silicon_revision(void)
24{
Duncan Laurie5cc51c02013-03-07 14:06:43 -080025 static int pch_revision_id = -1;
26
Aaron Durbin76c37002012-10-30 09:03:43 -050027 if (pch_revision_id < 0)
Duncan Laurie5cc51c02013-03-07 14:06:43 -080028 pch_revision_id = pci_read_config8(pch_get_lpc_device(),
29 PCI_REVISION_ID);
Aaron Durbin76c37002012-10-30 09:03:43 -050030 return pch_revision_id;
31}
32
Tristan Corrickd3f01b22018-12-06 22:46:58 +130033int pch_silicon_id(void)
34{
35 static int pch_id = -1;
36
37 if (pch_id < 0)
38 pch_id = pci_read_config16(pch_get_lpc_device(), PCI_DEVICE_ID);
39
40 return pch_id;
41}
42
Angel Pons31739932020-07-03 23:14:40 +020043enum pch_platform_type get_pch_platform_type(void)
Aaron Durbin76c37002012-10-30 09:03:43 -050044{
Angel Pons31739932020-07-03 23:14:40 +020045 const u16 did = pci_read_config16(pch_get_lpc_device(), PCI_DEVICE_ID);
Duncan Laurie5cc51c02013-03-07 14:06:43 -080046
Angel Pons31739932020-07-03 23:14:40 +020047 /* Check if this is a LPT-LP or WPT-LP device ID */
48 if ((did & 0xff00) == 0x9c00)
49 return PCH_TYPE_ULT;
50
51 /* Non-LP laptop SKUs have an odd device ID (least significant bit is one) */
52 if (did & 1)
53 return PCH_TYPE_MOBILE;
54
55 /* Desktop and Server SKUs have an even device ID */
56 return PCH_TYPE_DESKTOP;
Aaron Durbin76c37002012-10-30 09:03:43 -050057}
58
Duncan Laurie1ad55642013-03-07 14:08:04 -080059u16 get_pmbase(void)
60{
61 static u16 pmbase;
62
63 if (!pmbase)
64 pmbase = pci_read_config16(pch_get_lpc_device(),
65 PMBASE) & 0xfffc;
66 return pmbase;
67}
68
69u16 get_gpiobase(void)
70{
71 static u16 gpiobase;
72
73 if (!gpiobase)
74 gpiobase = pci_read_config16(pch_get_lpc_device(),
75 GPIOBASE) & 0xfffc;
76 return gpiobase;
77}
78
Kyösti Mälkki21d6a272019-11-05 18:50:38 +020079#ifndef __SIMPLE_DEVICE__
Duncan Laurie5cc51c02013-03-07 14:06:43 -080080
Duncan Laurie98c40622013-05-21 16:37:40 -070081/* Put device in D3Hot Power State */
Elyes HAOUAS38f1d132018-09-17 08:44:18 +020082static void pch_enable_d3hot(struct device *dev)
Aaron Durbin76c37002012-10-30 09:03:43 -050083{
Angel Ponsbf9bc502020-06-08 00:12:43 +020084 pci_or_config32(dev, PCH_PCS, PCH_PCS_PS_D3HOT);
Duncan Laurie98c40622013-05-21 16:37:40 -070085}
86
Frans Hendrikse6bf51f2019-05-01 10:48:31 +020087/* Set bit in function disable register to hide this device */
Elyes HAOUAS38f1d132018-09-17 08:44:18 +020088void pch_disable_devfn(struct device *dev)
Duncan Laurie98c40622013-05-21 16:37:40 -070089{
90 switch (dev->path.pci.devfn) {
Duncan Laurie26e7dd72012-12-19 09:12:31 -080091 case PCI_DEVFN(19, 0): /* Audio DSP */
92 RCBA32_OR(FD, PCH_DISABLE_ADSPD);
93 break;
94 case PCI_DEVFN(20, 0): /* XHCI */
95 RCBA32_OR(FD, PCH_DISABLE_XHCI);
96 break;
Duncan Laurie71346c02013-01-10 13:20:40 -080097 case PCI_DEVFN(21, 0): /* DMA */
Duncan Laurie98c40622013-05-21 16:37:40 -070098 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +020099 pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800100 break;
101 case PCI_DEVFN(21, 1): /* I2C0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700102 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200103 pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800104 break;
105 case PCI_DEVFN(21, 2): /* I2C1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700106 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200107 pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800108 break;
109 case PCI_DEVFN(21, 3): /* SPI0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700110 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200111 pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800112 break;
113 case PCI_DEVFN(21, 4): /* SPI1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700114 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200115 pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800116 break;
117 case PCI_DEVFN(21, 5): /* UART0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700118 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200119 pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800120 break;
121 case PCI_DEVFN(21, 6): /* UART1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700122 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200123 pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800124 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500125 case PCI_DEVFN(22, 0): /* MEI #1 */
126 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
127 break;
128 case PCI_DEVFN(22, 1): /* MEI #2 */
129 RCBA32_OR(FD2, PCH_DISABLE_MEI2);
130 break;
131 case PCI_DEVFN(22, 2): /* IDE-R */
132 RCBA32_OR(FD2, PCH_DISABLE_IDER);
133 break;
134 case PCI_DEVFN(22, 3): /* KT */
135 RCBA32_OR(FD2, PCH_DISABLE_KT);
136 break;
Duncan Laurie71346c02013-01-10 13:20:40 -0800137 case PCI_DEVFN(23, 0): /* SDIO */
Duncan Laurie98c40622013-05-21 16:37:40 -0700138 pch_enable_d3hot(dev);
Angel Pons8963f7d2020-10-24 12:20:28 +0200139 pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0, SIO_IOBP_FUNCDIS_DIS);
Duncan Laurie71346c02013-01-10 13:20:40 -0800140 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500141 case PCI_DEVFN(25, 0): /* Gigabit Ethernet */
142 RCBA32_OR(BUC, PCH_DISABLE_GBE);
143 break;
144 case PCI_DEVFN(26, 0): /* EHCI #2 */
145 RCBA32_OR(FD, PCH_DISABLE_EHCI2);
146 break;
147 case PCI_DEVFN(27, 0): /* HD Audio Controller */
148 RCBA32_OR(FD, PCH_DISABLE_HD_AUDIO);
149 break;
150 case PCI_DEVFN(28, 0): /* PCI Express Root Port 1 */
151 case PCI_DEVFN(28, 1): /* PCI Express Root Port 2 */
152 case PCI_DEVFN(28, 2): /* PCI Express Root Port 3 */
153 case PCI_DEVFN(28, 3): /* PCI Express Root Port 4 */
154 case PCI_DEVFN(28, 4): /* PCI Express Root Port 5 */
155 case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */
156 case PCI_DEVFN(28, 6): /* PCI Express Root Port 7 */
157 case PCI_DEVFN(28, 7): /* PCI Express Root Port 8 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700158 RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
Aaron Durbin76c37002012-10-30 09:03:43 -0500159 break;
160 case PCI_DEVFN(29, 0): /* EHCI #1 */
161 RCBA32_OR(FD, PCH_DISABLE_EHCI1);
162 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500163 case PCI_DEVFN(31, 0): /* LPC */
164 RCBA32_OR(FD, PCH_DISABLE_LPC);
165 break;
166 case PCI_DEVFN(31, 2): /* SATA #1 */
167 RCBA32_OR(FD, PCH_DISABLE_SATA1);
168 break;
169 case PCI_DEVFN(31, 3): /* SMBUS */
170 RCBA32_OR(FD, PCH_DISABLE_SMBUS);
171 break;
Duncan Laurie26e7dd72012-12-19 09:12:31 -0800172 case PCI_DEVFN(31, 5): /* SATA #2 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500173 RCBA32_OR(FD, PCH_DISABLE_SATA2);
174 break;
175 case PCI_DEVFN(31, 6): /* Thermal Subsystem */
176 RCBA32_OR(FD, PCH_DISABLE_THERMAL);
177 break;
178 }
179}
180
Elyes HAOUAS38f1d132018-09-17 08:44:18 +0200181void pch_enable(struct device *dev)
Aaron Durbin76c37002012-10-30 09:03:43 -0500182{
Aaron Durbinc0254e62013-06-20 01:20:30 -0500183 /* PCH PCIe Root Ports are handled in PCIe driver. */
Aaron Durbin76c37002012-10-30 09:03:43 -0500184 if (PCI_SLOT(dev->path.pci.devfn) == PCH_PCIE_DEV_SLOT)
Aaron Durbinc0254e62013-06-20 01:20:30 -0500185 return;
Aaron Durbin76c37002012-10-30 09:03:43 -0500186
187 if (!dev->enabled) {
188 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
189
190 /* Ensure memory, io, and bus master are all disabled */
Angel Ponsbf9bc502020-06-08 00:12:43 +0200191 pci_and_config16(dev, PCI_COMMAND,
192 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
Aaron Durbin76c37002012-10-30 09:03:43 -0500193
Aaron Durbin3fcd3562013-06-19 13:20:37 -0500194 /* Disable this device if possible */
195 pch_disable_devfn(dev);
Aaron Durbin76c37002012-10-30 09:03:43 -0500196 } else {
197 /* Enable SERR */
Elyes HAOUAS73ae0762020-04-28 10:13:05 +0200198 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
Aaron Durbin76c37002012-10-30 09:03:43 -0500199 }
200}
201
202struct chip_operations southbridge_intel_lynxpoint_ops = {
203 CHIP_NAME("Intel Series 8 (Lynx Point) Southbridge")
204 .enable_dev = pch_enable,
205};
Duncan Laurie5cc51c02013-03-07 14:06:43 -0800206
Kyösti Mälkki21d6a272019-11-05 18:50:38 +0200207#endif /* __SIMPLE_DEVICE__ */