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