2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Google Inc.
5 * Copyright (C) 2015 Intel Corporation.
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.
19 #include <console/console.h>
20 #include <device/device.h>
21 #include <device/pci_def.h>
22 #include <reg_script.h>
23 #include <soc/iomap.h>
27 #include <soc/pci_devs.h>
30 #include <soc/romstage.h>
31 #include <soc/smbus.h>
33 /* Max PXRC registers in ITSS*/
34 #define MAX_PXRC_CONFIG 0x08
36 static const u8 pch_interrupt_routing
[] = {
37 11, /* PARC: PIRQA -> IRQ11 */
38 10, /* PBRC: PIRQB -> IRQ10 */
39 11, /* PCRC: PIRQC -> IRQ11 */
40 11, /* PDRC: PIRQD -> IRQ11 */
41 11, /* PERC: PIRQE -> IRQ11 */
42 11, /* PFRC: PIRQF -> IRQ11 */
43 11, /* PGRC: PIRQG -> IRQ11 */
44 11 /* PHRC: PIRQH -> IRQ11 */
47 static void pch_enable_lpc(void)
49 /* Lookup device tree in romstage */
50 const struct device
*dev
;
51 const config_t
*config
;
55 lpc_en
= COMA_RANGE
| (COMB_RANGE
<< 4);
56 pci_write_config16(PCH_DEV_LPC
, LPC_IO_DEC
, lpc_en
);
57 pcr_write16(PID_DMI
, R_PCH_PCR_DMI_LPCIOD
, lpc_en
);
59 /* IO Decode Enable */
60 lpc_en
= COMA_LPC_EN
| KBC_LPC_EN
| MC_LPC_EN
;
61 pci_write_config16(PCH_DEV_LPC
, LPC_EN
, lpc_en
);
62 pcr_write16(PID_DMI
, R_PCH_PCR_DMI_LPCIOE
, lpc_en
);
64 dev
= dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC
, 0));
65 if (!dev
|| !dev
->chip_info
)
67 config
= dev
->chip_info
;
69 /* Set in PCI generic decode range registers */
70 pci_write_config32(PCH_DEV_LPC
, LPC_GEN1_DEC
, config
->gen1_dec
);
71 pci_write_config32(PCH_DEV_LPC
, LPC_GEN2_DEC
, config
->gen2_dec
);
72 pci_write_config32(PCH_DEV_LPC
, LPC_GEN3_DEC
, config
->gen3_dec
);
73 pci_write_config32(PCH_DEV_LPC
, LPC_GEN4_DEC
, config
->gen4_dec
);
75 /* Mirror these same settings in DMI PCR */
76 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_LPCLGIR1
, config
->gen1_dec
);
77 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_LPCLGIR2
, config
->gen2_dec
);
78 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_LPCLGIR3
, config
->gen3_dec
);
79 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_LPCLGIR4
, config
->gen4_dec
);
82 static void pch_interrupt_init(void)
86 for (index
= 0; index
< MAX_PXRC_CONFIG
; index
++) {
87 if (pch_interrupt_routing
[index
] < 16 &&
88 pch_interrupt_routing
[index
] > 2 &&
89 pch_interrupt_routing
[index
] != 8 &&
90 pch_interrupt_routing
[index
] != 13) {
92 (R_PCH_PCR_ITSS_PIRQA_ROUT
+ index
),
93 pch_interrupt_routing
[index
]);
98 static void soc_config_acpibase(void)
102 /* Disable ABASE in PMC Device first before changing Base Address*/
103 reg32
= pci_read_config32(PCH_DEV_PMC
, ACTL
);
104 pci_write_config32(PCH_DEV_PMC
, ACTL
, reg32
& ~ACPI_EN
);
106 /* Program ACPI Base */
107 pci_write_config32(PCH_DEV_PMC
, ABASE
, ACPI_BASE_ADDRESS
);
109 /* Enable ACPI in PMC */
110 pci_write_config32(PCH_DEV_PMC
, ACTL
, reg32
| ACPI_EN
);
113 * Program "ACPI Base Address" PCR[DMI] + 27B4h[23:18, 15:2, 0]
114 * to [0x3F, PMC PCI Offset 40h bit[15:2], 1]
116 reg32
= ((0x3f << 18) | ACPI_BASE_ADDRESS
| 1);
117 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_ACPIBA
, reg32
);
118 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_ACPIBDID
, 0x23A0);
121 static void soc_config_pwrmbase(void)
125 /* Disable PWRMBASE in PMC Device first before changing Base address */
126 reg32
= pci_read_config32(PCH_DEV_PMC
, ACTL
);
127 pci_write_config32(PCH_DEV_PMC
, ACTL
, reg32
& ~PWRM_EN
);
129 /* Program PWRM Base */
130 pci_write_config32(PCH_DEV_PMC
, PWRMBASE
, PCH_PWRM_BASE_ADDRESS
);
132 /* Enable PWRM in PMC */
133 pci_write_config32(PCH_DEV_PMC
, ACTL
, reg32
| PWRM_EN
);
136 * Program "PM Base Address Memory Range Base" PCR[DMI] + 27ACh[15:0]
137 * to the same value programmed in PMC PCI Offset 48h bit[31:16],
138 * this has an implication of making sure the PWRMBASE to be
141 * Program "PM Base Address Memory Range Limit" PCR[DMI] + 27ACh[31:16]
142 * to the value programmed in PMC PCI Offset 48h bit[31:16], this has an
143 * implication of making sure the memory allocated to PWRMBASE to be 64KB
146 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_PMBASEA
,
147 ((PCH_PWRM_BASE_ADDRESS
& 0xFFFF0000) |
148 (PCH_PWRM_BASE_ADDRESS
>> 16)));
149 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_PMBASEC
, 0x800023A0);
152 static void soc_config_tco(void)
158 /* Disable TCO in SMBUS Device first before changing Base Address */
159 reg32
= pci_read_config32(PCH_DEV_SMBUS
, TCOCTL
);
160 reg32
&= ~SMBUS_TCO_EN
;
161 pci_write_config32(PCH_DEV_SMBUS
, TCOCTL
, reg32
);
163 /* Program TCO Base */
164 pci_write_config32(PCH_DEV_SMBUS
, TCOBASE
, TCO_BASE_ADDDRESS
);
166 /* Enable TCO in SMBUS */
167 pci_write_config32(PCH_DEV_SMBUS
, TCOCTL
, reg32
| SMBUS_TCO_EN
);
170 * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1]
171 * to [SMBUS PCI offset 50h[15:5], 1].
173 pcr_write32(PID_DMI
, R_PCH_PCR_DMI_TCOBASE
,
174 (TCO_BASE_ADDDRESS
| (1 << 1)));
176 /* Program TCO timer halt */
177 tcobase
= pci_read_config16(PCH_DEV_SMBUS
, TCOBASE
);
179 tcocnt
= inw(tcobase
+ TCO1_CNT
);
180 tcocnt
|= TCO_TMR_HLT
;
181 outw(tcocnt
, tcobase
+ TCO1_CNT
);
184 static void soc_config_rtc(void)
186 /* Enable upper 128 bytes of CMOS */
187 pcr_andthenor32(PID_RTC
, R_PCH_PCR_RTC_CONF
, ~0,
188 B_PCH_PCR_RTC_CONF_UCMOS_EN
);
191 void pch_early_init(void)
194 * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT,
195 * GPE0_STS, GPE0_EN registers.
197 soc_config_acpibase();
200 * Enabling PWRM Base for accessing
201 * Global Reset Cause Register.
203 soc_config_pwrmbase();
205 /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */
209 * Interrupt Configuration Register Programming
210 * PIRQx to IRQ Programming
212 pch_interrupt_init();
214 /* Program generic IO Decode Range */
217 /* Program SMBUS_BASE_ADDRESS and Enable it */