blob: dc70a4f6c74a418020cbd1934707a94ecec75e49 [file] [log] [blame]
Andrey Petrovf35804b2017-06-05 13:22:41 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
5 * Copyright (C) 2017 Intel Corporation.
6 *
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.
10 *
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.
15 */
16
17#include <device/device.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070018#include <intelblocks/fast_spi.h>
Furquan Shaikh1876f3a2017-12-07 18:39:34 -080019#include <intelblocks/gspi.h>
Caveh Jalali1428f012018-01-23 22:15:24 -080020#include <intelblocks/lpc_lib.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070021#include <intelblocks/pcr.h>
22#include <intelblocks/rtc.h>
Lijian Zhao031020e2017-12-15 12:58:07 -080023#include <intelblocks/pmclib.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070024#include <intelblocks/smbus.h>
25#include <soc/bootblock.h>
26#include <soc/iomap.h>
27#include <soc/lpc.h>
28#include <soc/p2sb.h>
29#include <soc/pci_devs.h>
30#include <soc/pcr_ids.h>
Lijian Zhaob3dfcb82017-08-16 22:18:52 -070031#include <soc/pm.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070032#include <soc/smbus.h>
33
34#define PCR_PSF3_TO_SHDW_PMC_REG_BASE 0x1400
35#define PCR_PSFX_TO_SHDW_BAR0 0
36#define PCR_PSFX_TO_SHDW_BAR1 0x4
37#define PCR_PSFX_TO_SHDW_BAR2 0x8
38#define PCR_PSFX_TO_SHDW_BAR3 0xC
39#define PCR_PSFX_TO_SHDW_BAR4 0x10
40#define PCR_PSFX_TO_SHDW_PCIEN_IOEN 0x01
41#define PCR_PSFX_T0_SHDW_PCIEN 0x1C
42
Andrey Petrovf35804b2017-06-05 13:22:41 -070043#define PCR_DMI_ACPIBA 0x27B4
44#define PCR_DMI_ACPIBDID 0x27B8
45#define PCR_DMI_PMBASEA 0x27AC
46#define PCR_DMI_PMBASEC 0x27B0
47#define PCR_DMI_TCOBASE 0x2778
48#define TCOEN (1 << 1) /* Enable TCO I/O range decode. */
49
50#define PCR_DMI_LPCIOD 0x2770
51#define PCR_DMI_LPCIOE 0x2774
52
53static void enable_p2sbbar(void)
54{
Elyes HAOUASc8a649c2018-06-10 23:36:44 +020055 pci_devfn_t dev = PCH_DEV_P2SB;
Andrey Petrovf35804b2017-06-05 13:22:41 -070056
57 /* Enable PCR Base address in PCH */
58 pci_write_config32(dev, PCI_BASE_ADDRESS_0, CONFIG_PCR_BASE_ADDRESS);
59
60 /* Enable P2SB MSE */
61 pci_write_config8(dev, PCI_COMMAND,
62 PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
63 /*
64 * Enable decoding for HPET memory address range.
65 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
66 * the High Performance Timer memory address range
67 * selected by bits 1:0
68 */
69 pci_write_config8(dev, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT);
70}
71
72static void soc_config_pwrmbase(void)
73{
74 uint32_t reg32;
75
76 /* Assign Resources to PWRMBASE */
77 /* Clear BIT 1-2 Command Register */
78 reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND);
79 reg32 &= ~(PCI_COMMAND_MEMORY);
80 pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32);
81
82 /* Program PWRM Base */
83 pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS);
84
85 /* Enable Bus Master and MMIO Space */
86 reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND);
87 reg32 |= PCI_COMMAND_MEMORY;
88 pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32);
89
90 /* Enable PWRM in PMC */
91 reg32 = read32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL));
92 write32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL), reg32 | PWRM_EN);
93}
94
95void bootblock_pch_early_init(void)
96{
97 fast_spi_early_init(SPI_BASE_ADDRESS);
Furquan Shaikh1876f3a2017-12-07 18:39:34 -080098 gspi_early_bar_init();
Andrey Petrovf35804b2017-06-05 13:22:41 -070099 enable_p2sbbar();
100 /*
101 * Enabling PWRM Base for accessing
102 * Global Reset Cause Register.
103 */
104 soc_config_pwrmbase();
105}
106
107
108static void soc_config_acpibase(void)
109{
110 uint32_t pmc_reg_value;
111
112 pmc_reg_value = pcr_read32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE +
113 PCR_PSFX_TO_SHDW_BAR4);
114
115 if (pmc_reg_value != 0xFFFFFFFF)
116 {
117 /* Disable Io Space before changing the address */
118 pcr_rmw32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE +
119 PCR_PSFX_T0_SHDW_PCIEN,
120 ~PCR_PSFX_TO_SHDW_PCIEN_IOEN, 0);
121 /* Program ABASE in PSF3 PMC space BAR4*/
122 pcr_write32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE +
123 PCR_PSFX_TO_SHDW_BAR4,
124 ACPI_BASE_ADDRESS);
125 /* Enable IO Space */
126 pcr_rmw32(PID_PSF3, PCR_PSF3_TO_SHDW_PMC_REG_BASE +
127 PCR_PSFX_T0_SHDW_PCIEN,
128 ~0, PCR_PSFX_TO_SHDW_PCIEN_IOEN);
129 }
130}
131
132static void soc_config_tco(void)
133{
134 uint32_t reg32;
135 uint16_t tcobase;
136 uint16_t tcocnt;
137
138 /* Disable TCO in SMBUS Device first before changing Base Address */
139 reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL);
Lijian Zhao6dc125f2017-07-13 19:11:45 -0700140 reg32 &= ~TCO_BASE_EN;
Andrey Petrovf35804b2017-06-05 13:22:41 -0700141 pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32);
142
143 /* Program TCO Base */
144 tcobase = TCO_BASE_ADDRESS;
145 pci_write_config32(PCH_DEV_SMBUS, TCOBASE, tcobase);
146
147 /* Enable TCO in SMBUS */
148 pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | TCO_BASE_EN);
149
150 /*
151 * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1]
152 */
153 pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN);
154
155 /* Program TCO timer halt */
156 tcocnt = inw(tcobase + TCO1_CNT);
157 tcocnt |= TCO_TMR_HLT;
158 outw(tcocnt, tcobase + TCO1_CNT);
159}
160
161void pch_early_iorange_init(void)
162{
163 uint16_t dec_rng, dec_en = 0;
164
165 /* IO Decode Range */
166 if (IS_ENABLED(CONFIG_DRIVERS_UART_8250IO) &&
167 IS_ENABLED(CONFIG_UART_DEBUG)) {
168 dec_rng = COMA_RANGE | (COMB_RANGE << 4);
169 dec_en = COMA_LPC_EN | COMB_LPC_EN;
170 pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, dec_rng);
171 pcr_write16(PID_DMI, PCR_DMI_LPCIOD, dec_rng);
172 }
173
174 /* IO Decode Enable */
Lijian Zhao9b50a572017-12-21 13:40:07 -0800175 dec_en |= SE_LPC_EN | KBC_LPC_EN | MC1_LPC_EN | GAMEL_LPC_EN;
Andrey Petrovf35804b2017-06-05 13:22:41 -0700176 pci_write_config16(PCH_DEV_LPC, LPC_EN, dec_en);
177 pcr_write16(PID_DMI, PCR_DMI_LPCIOE, dec_en);
Caveh Jalali1428f012018-01-23 22:15:24 -0800178
179 /* Program generic IO Decode Range */
180 pch_enable_lpc();
Andrey Petrovf35804b2017-06-05 13:22:41 -0700181}
182
183void pch_early_init(void)
184{
185 /*
186 * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT,
187 * GPE0_STS, GPE0_EN registers.
188 */
189 soc_config_acpibase();
190
191 /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */
192 soc_config_tco();
193
194 /* Program SMBUS_BASE_ADDRESS and Enable it */
195 smbus_common_init();
196
Lijian Zhao031020e2017-12-15 12:58:07 -0800197 /* Set up GPE configuration */
198 pmc_gpe_init();
199
Andrey Petrovf35804b2017-06-05 13:22:41 -0700200 enable_rtc_upper_bank();
Andrey Petrovf35804b2017-06-05 13:22:41 -0700201}