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