blob: 3ef084a858b82f3ae87003d61dad375628949b85 [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
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053017#include <console/console.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070018#include <device/device.h>
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053019#include <device/pci_ids.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070020#include <intelblocks/fast_spi.h>
Furquan Shaikh1876f3a2017-12-07 18:39:34 -080021#include <intelblocks/gspi.h>
Caveh Jalali1428f012018-01-23 22:15:24 -080022#include <intelblocks/lpc_lib.h>
Subrata Banik7837c202018-05-07 17:13:40 +053023#include <intelblocks/p2sb.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070024#include <intelblocks/pcr.h>
Lijian Zhao031020e2017-12-15 12:58:07 -080025#include <intelblocks/pmclib.h>
Subrata Banik7837c202018-05-07 17:13:40 +053026#include <intelblocks/rtc.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070027#include <intelblocks/smbus.h>
28#include <soc/bootblock.h>
29#include <soc/iomap.h>
30#include <soc/lpc.h>
31#include <soc/p2sb.h>
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053032#include <soc/pch.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070033#include <soc/pci_devs.h>
34#include <soc/pcr_ids.h>
Lijian Zhaob3dfcb82017-08-16 22:18:52 -070035#include <soc/pm.h>
Andrey Petrovf35804b2017-06-05 13:22:41 -070036#include <soc/smbus.h>
37
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053038#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP 0x1400
39#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H 0x0980
40
Andrey Petrovf35804b2017-06-05 13:22:41 -070041#define PCR_PSFX_TO_SHDW_BAR0 0
42#define PCR_PSFX_TO_SHDW_BAR1 0x4
43#define PCR_PSFX_TO_SHDW_BAR2 0x8
44#define PCR_PSFX_TO_SHDW_BAR3 0xC
45#define PCR_PSFX_TO_SHDW_BAR4 0x10
46#define PCR_PSFX_TO_SHDW_PCIEN_IOEN 0x01
47#define PCR_PSFX_T0_SHDW_PCIEN 0x1C
48
Andrey Petrovf35804b2017-06-05 13:22:41 -070049#define PCR_DMI_ACPIBA 0x27B4
50#define PCR_DMI_ACPIBDID 0x27B8
51#define PCR_DMI_PMBASEA 0x27AC
52#define PCR_DMI_PMBASEC 0x27B0
53#define PCR_DMI_TCOBASE 0x2778
54#define TCOEN (1 << 1) /* Enable TCO I/O range decode. */
55
56#define PCR_DMI_LPCIOD 0x2770
57#define PCR_DMI_LPCIOE 0x2774
58
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053059static uint32_t get_pmc_reg_base(void)
60{
61 uint8_t pch_series;
62
63 pch_series = get_pch_series();
64
65 if (pch_series == PCH_H)
66 return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H;
67 else if (pch_series == PCH_LP)
68 return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP;
69 else
70 return 0;
71}
72
Andrey Petrovf35804b2017-06-05 13:22:41 -070073static void soc_config_pwrmbase(void)
74{
75 uint32_t reg32;
76
Maulik V Vaghela9b08a182018-07-17 21:52:27 +053077 /*
78 * Assign Resources to PWRMBASE
79 * Clear BIT 1-2 Command Register
80 */
Andrey Petrovf35804b2017-06-05 13:22:41 -070081 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);
Furquan Shaikh1876f3a2017-12-07 18:39:34 -0800101 gspi_early_bar_init();
Subrata Banik7837c202018-05-07 17:13:40 +0530102 p2sb_enable_bar();
103 p2sb_configure_hpet();
Subrata Banikafa07f72018-05-24 12:21:06 +0530104
Andrey Petrovf35804b2017-06-05 13:22:41 -0700105 /*
106 * Enabling PWRM Base for accessing
107 * Global Reset Cause Register.
108 */
109 soc_config_pwrmbase();
110}
111
112
113static void soc_config_acpibase(void)
114{
115 uint32_t pmc_reg_value;
Maulik V Vaghela9b08a182018-07-17 21:52:27 +0530116 uint32_t pmc_base_reg;
Andrey Petrovf35804b2017-06-05 13:22:41 -0700117
Maulik V Vaghela9b08a182018-07-17 21:52:27 +0530118 pmc_base_reg = get_pmc_reg_base();
119 if (!pmc_base_reg)
120 die("Invalid PMC base address\n");
121
122 pmc_reg_value = pcr_read32(PID_PSF3, pmc_base_reg +
123 PCR_PSFX_TO_SHDW_BAR4);
Andrey Petrovf35804b2017-06-05 13:22:41 -0700124
125 if (pmc_reg_value != 0xFFFFFFFF)
126 {
127 /* Disable Io Space before changing the address */
Maulik V Vaghela9b08a182018-07-17 21:52:27 +0530128 pcr_rmw32(PID_PSF3, pmc_base_reg +
Andrey Petrovf35804b2017-06-05 13:22:41 -0700129 PCR_PSFX_T0_SHDW_PCIEN,
130 ~PCR_PSFX_TO_SHDW_PCIEN_IOEN, 0);
131 /* Program ABASE in PSF3 PMC space BAR4*/
Maulik V Vaghela9b08a182018-07-17 21:52:27 +0530132 pcr_write32(PID_PSF3, pmc_base_reg +
Andrey Petrovf35804b2017-06-05 13:22:41 -0700133 PCR_PSFX_TO_SHDW_BAR4,
134 ACPI_BASE_ADDRESS);
135 /* Enable IO Space */
Maulik V Vaghela9b08a182018-07-17 21:52:27 +0530136 pcr_rmw32(PID_PSF3, pmc_base_reg +
Andrey Petrovf35804b2017-06-05 13:22:41 -0700137 PCR_PSFX_T0_SHDW_PCIEN,
138 ~0, PCR_PSFX_TO_SHDW_PCIEN_IOEN);
139 }
140}
141
142static void soc_config_tco(void)
143{
144 uint32_t reg32;
145 uint16_t tcobase;
146 uint16_t tcocnt;
147
148 /* Disable TCO in SMBUS Device first before changing Base Address */
149 reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL);
Lijian Zhao6dc125f2017-07-13 19:11:45 -0700150 reg32 &= ~TCO_BASE_EN;
Andrey Petrovf35804b2017-06-05 13:22:41 -0700151 pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32);
152
153 /* Program TCO Base */
154 tcobase = TCO_BASE_ADDRESS;
155 pci_write_config32(PCH_DEV_SMBUS, TCOBASE, tcobase);
156
157 /* Enable TCO in SMBUS */
158 pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | TCO_BASE_EN);
159
160 /*
161 * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1]
162 */
163 pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN);
164
165 /* Program TCO timer halt */
166 tcocnt = inw(tcobase + TCO1_CNT);
167 tcocnt |= TCO_TMR_HLT;
168 outw(tcocnt, tcobase + TCO1_CNT);
169}
170
171void pch_early_iorange_init(void)
172{
173 uint16_t dec_rng, dec_en = 0;
174
175 /* IO Decode Range */
176 if (IS_ENABLED(CONFIG_DRIVERS_UART_8250IO) &&
177 IS_ENABLED(CONFIG_UART_DEBUG)) {
178 dec_rng = COMA_RANGE | (COMB_RANGE << 4);
179 dec_en = COMA_LPC_EN | COMB_LPC_EN;
180 pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, dec_rng);
181 pcr_write16(PID_DMI, PCR_DMI_LPCIOD, dec_rng);
182 }
183
184 /* IO Decode Enable */
Lijian Zhao9b50a572017-12-21 13:40:07 -0800185 dec_en |= SE_LPC_EN | KBC_LPC_EN | MC1_LPC_EN | GAMEL_LPC_EN;
Andrey Petrovf35804b2017-06-05 13:22:41 -0700186 pci_write_config16(PCH_DEV_LPC, LPC_EN, dec_en);
187 pcr_write16(PID_DMI, PCR_DMI_LPCIOE, dec_en);
Caveh Jalali1428f012018-01-23 22:15:24 -0800188
189 /* Program generic IO Decode Range */
190 pch_enable_lpc();
Andrey Petrovf35804b2017-06-05 13:22:41 -0700191}
192
193void pch_early_init(void)
194{
195 /*
196 * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT,
197 * GPE0_STS, GPE0_EN registers.
198 */
199 soc_config_acpibase();
200
201 /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */
202 soc_config_tco();
203
204 /* Program SMBUS_BASE_ADDRESS and Enable it */
205 smbus_common_init();
206
Lijian Zhao031020e2017-12-15 12:58:07 -0800207 /* Set up GPE configuration */
208 pmc_gpe_init();
209
Andrey Petrovf35804b2017-06-05 13:22:41 -0700210 enable_rtc_upper_bank();
Andrey Petrovf35804b2017-06-05 13:22:41 -0700211}