Remove address from GPLv2 headers
[coreboot.git] / src / soc / intel / broadwell / pch.c
blob97c840718fbe4104717ae41e40e6038a9cdd732c
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2014 Google Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.
21 #include <console/console.h>
22 #include <delay.h>
23 #include <arch/io.h>
24 #include <device/device.h>
25 #include <device/pci.h>
26 #include <device/pci_def.h>
27 #include <soc/iobp.h>
28 #include <soc/pch.h>
29 #include <soc/pci_devs.h>
30 #include <soc/ramstage.h>
31 #include <soc/rcba.h>
32 #include <soc/serialio.h>
33 #include <soc/spi.h>
35 u8 pch_revision(void)
37 return pci_read_config8(PCH_DEV_LPC, PCI_REVISION_ID);
40 u16 pch_type(void)
42 return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID);
45 /* Return 1 if PCH type is WildcatPoint */
46 int pch_is_wpt(void)
48 return ((pch_type() & 0xfff0) == 0x9cc0) ? 1 : 0;
51 /* Return 1 if PCH type is WildcatPoint ULX */
52 int pch_is_wpt_ulx(void)
54 u16 lpcid = pch_type();
56 switch (lpcid) {
57 case PCH_WPT_BDW_Y_SAMPLE:
58 case PCH_WPT_BDW_Y_PREMIUM:
59 case PCH_WPT_BDW_Y_BASE:
60 return 1;
63 return 0;
66 u32 pch_read_soft_strap(int id)
68 u32 fdoc;
70 fdoc = SPIBAR32(SPIBAR_FDOC);
71 fdoc &= ~0x00007ffc;
72 SPIBAR32(SPIBAR_FDOC) = fdoc;
74 fdoc |= 0x00004000;
75 fdoc |= id * 4;
76 SPIBAR32(SPIBAR_FDOC) = fdoc;
78 return SPIBAR32(SPIBAR_FDOD);
81 #ifndef __PRE_RAM__
83 /* Put device in D3Hot Power State */
84 static void pch_enable_d3hot(device_t dev)
86 u32 reg32 = pci_read_config32(dev, PCH_PCS);
87 reg32 |= PCH_PCS_PS_D3HOT;
88 pci_write_config32(dev, PCH_PCS, reg32);
91 /* RCBA function disable and posting read to flush the transaction */
92 static void rcba_function_disable(u32 reg, u32 bit)
94 RCBA32_OR(reg, bit);
95 RCBA32(reg);
98 /* Set bit in Function Disable register to hide this device */
99 void pch_disable_devfn(device_t dev)
101 switch (dev->path.pci.devfn) {
102 case PCH_DEVFN_ADSP: /* Audio DSP */
103 rcba_function_disable(FD, PCH_DISABLE_ADSPD);
104 break;
105 case PCH_DEVFN_XHCI: /* XHCI */
106 rcba_function_disable(FD, PCH_DISABLE_XHCI);
107 break;
108 case PCH_DEVFN_SDMA: /* DMA */
109 pch_enable_d3hot(dev);
110 pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS);
111 break;
112 case PCH_DEVFN_I2C0: /* I2C0 */
113 pch_enable_d3hot(dev);
114 pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS);
115 break;
116 case PCH_DEVFN_I2C1: /* I2C1 */
117 pch_enable_d3hot(dev);
118 pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS);
119 break;
120 case PCH_DEVFN_SPI0: /* SPI0 */
121 pch_enable_d3hot(dev);
122 pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS);
123 break;
124 case PCH_DEVFN_SPI1: /* SPI1 */
125 pch_enable_d3hot(dev);
126 pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS);
127 break;
128 case PCH_DEVFN_UART0: /* UART0 */
129 pch_enable_d3hot(dev);
130 pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS);
131 break;
132 case PCH_DEVFN_UART1: /* UART1 */
133 pch_enable_d3hot(dev);
134 pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS);
135 break;
136 case PCH_DEVFN_ME: /* MEI #1 */
137 rcba_function_disable(FD2, PCH_DISABLE_MEI1);
138 break;
139 case PCH_DEVFN_ME_2: /* MEI #2 */
140 rcba_function_disable(FD2, PCH_DISABLE_MEI2);
141 break;
142 case PCH_DEVFN_ME_IDER: /* IDE-R */
143 rcba_function_disable(FD2, PCH_DISABLE_IDER);
144 break;
145 case PCH_DEVFN_ME_KT: /* KT */
146 rcba_function_disable(FD2, PCH_DISABLE_KT);
147 break;
148 case PCH_DEVFN_SDIO: /* SDIO */
149 pch_enable_d3hot(dev);
150 pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS);
151 break;
152 case PCH_DEVFN_GBE: /* Gigabit Ethernet */
153 rcba_function_disable(BUC, PCH_DISABLE_GBE);
154 break;
155 case PCH_DEVFN_HDA: /* HD Audio Controller */
156 rcba_function_disable(FD, PCH_DISABLE_HD_AUDIO);
157 break;
158 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 0): /* PCI Express Root Port 1 */
159 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 1): /* PCI Express Root Port 2 */
160 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 2): /* PCI Express Root Port 3 */
161 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 3): /* PCI Express Root Port 4 */
162 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 4): /* PCI Express Root Port 5 */
163 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 5): /* PCI Express Root Port 6 */
164 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 6): /* PCI Express Root Port 7 */
165 case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 7): /* PCI Express Root Port 8 */
166 rcba_function_disable(FD,
167 PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
168 break;
169 case PCH_DEVFN_EHCI: /* EHCI #1 */
170 rcba_function_disable(FD, PCH_DISABLE_EHCI1);
171 break;
172 case PCH_DEVFN_LPC: /* LPC */
173 rcba_function_disable(FD, PCH_DISABLE_LPC);
174 break;
175 case PCH_DEVFN_SATA: /* SATA #1 */
176 rcba_function_disable(FD, PCH_DISABLE_SATA1);
177 break;
178 case PCH_DEVFN_SMBUS: /* SMBUS */
179 rcba_function_disable(FD, PCH_DISABLE_SMBUS);
180 break;
181 case PCH_DEVFN_SATA2: /* SATA #2 */
182 rcba_function_disable(FD, PCH_DISABLE_SATA2);
183 break;
184 case PCH_DEVFN_THERMAL: /* Thermal Subsystem */
185 rcba_function_disable(FD, PCH_DISABLE_THERMAL);
186 break;
190 void broadwell_pch_enable_dev(device_t dev)
192 u32 reg32;
194 /* These devices need special enable/disable handling */
195 switch (PCI_SLOT(dev->path.pci.devfn)) {
196 case PCH_DEV_SLOT_PCIE:
197 case PCH_DEV_SLOT_EHCI:
198 case PCH_DEV_SLOT_HDA:
199 return;
202 if (!dev->enabled) {
203 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
205 /* Ensure memory, io, and bus master are all disabled */
206 reg32 = pci_read_config32(dev, PCI_COMMAND);
207 reg32 &= ~(PCI_COMMAND_MASTER |
208 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
209 pci_write_config32(dev, PCI_COMMAND, reg32);
211 /* Disable this device if possible */
212 pch_disable_devfn(dev);
213 } else {
214 /* Enable SERR */
215 reg32 = pci_read_config32(dev, PCI_COMMAND);
216 reg32 |= PCI_COMMAND_SERR;
217 pci_write_config32(dev, PCI_COMMAND, reg32);
221 #endif