blob: 8c89c07e26a4138d491b84bc62132e648abb8443 [file] [log] [blame]
Subrata Banik7609c652017-05-19 14:50:09 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2017 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Kyösti Mälkki6046eb42019-07-14 11:07:39 +030016#define __SIMPLE_DEVICE__
17
Kyösti Mälkki13f66502019-03-03 08:01:05 +020018#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020019#include <device/pci_ops.h>
Subrata Banik7609c652017-05-19 14:50:09 +053020#include <device/device.h>
21#include <device/pci.h>
22#include <intelblocks/systemagent.h>
23#include <soc/iomap.h>
24#include <soc/pci_devs.h>
25#include <soc/systemagent.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +010026
Subrata Banik7609c652017-05-19 14:50:09 +053027#include "systemagent_def.h"
Subrata Banik7609c652017-05-19 14:50:09 +053028
Subrata Banik7609c652017-05-19 14:50:09 +053029void bootblock_systemagent_early_init(void)
30{
31 uint32_t reg;
32 uint8_t pciexbar_length;
33
34 /*
35 * The PCIEXBAR is assumed to live in the memory mapped IO space under
36 * 4GiB.
37 */
38 reg = 0;
39 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
40
41 /* Get PCI Express Region Length */
42 switch (CONFIG_SA_PCIEX_LENGTH) {
43 case 256 * MiB:
44 pciexbar_length = PCIEXBAR_LENGTH_256MB;
45 break;
46 case 128 * MiB:
47 pciexbar_length = PCIEXBAR_LENGTH_128MB;
48 break;
49 case 64 * MiB:
50 pciexbar_length = PCIEXBAR_LENGTH_64MB;
51 break;
52 default:
53 pciexbar_length = PCIEXBAR_LENGTH_256MB;
54 }
55 reg = CONFIG_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
56 | PCIEXBAR_PCIEXBAREN;
57 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
58
59 /*
60 * TSEG defines the base of SMM range. BIOS determines the base
61 * of TSEG memory which must be at or below Graphics base of GTT
62 * Stolen memory, hence its better to clear TSEG register early
63 * to avoid power on default non-zero value (if any).
64 */
65 pci_write_config32(SA_DEV_ROOT, TSEG, 0);
66}
Subrata Banik7609c652017-05-19 14:50:09 +053067
68void sa_set_pci_bar(const struct sa_mmio_descriptor *fixed_set_resources,
69 size_t count)
70{
71 int i;
72
73 for (i = 0; i < count; i++) {
74 uintptr_t base;
75 unsigned int index;
76
77 index = fixed_set_resources[i].index;
78 /* Check if PCI BAR already enabled */
79 base = pci_read_config32(SA_DEV_ROOT, index);
80
81 /* If enabled don't program it. */
82 if (base & 0x1)
83 return;
84
85 base = fixed_set_resources[i].base;
86
87 pci_write_config32(SA_DEV_ROOT, index, base | 1);
88 }
89}
90
91/*
92 * There are special BARs that actually are programmed in the MCHBAR. These
93 * Intel special features, but they do consume resources that need to be
94 * accounted for.
95 */
96void sa_set_mch_bar(const struct sa_mmio_descriptor *fixed_set_resources,
97 size_t count)
98{
99 int i;
100
101 for (i = 0; i < count; i++) {
102 uintptr_t base;
103 unsigned int index;
104
105 base = fixed_set_resources[i].base;
106 index = fixed_set_resources[i].index;
107 write32((void *)(MCH_BASE_ADDRESS + index), base | 1);
108 }
109}
110
111void enable_pam_region(void)
112{
113 /* All read and writes in this region are serviced by DRAM */
114 pci_write_config8(SA_DEV_ROOT, PAM0, 0x30);
115 pci_write_config8(SA_DEV_ROOT, PAM1, 0x33);
116 pci_write_config8(SA_DEV_ROOT, PAM2, 0x33);
117 pci_write_config8(SA_DEV_ROOT, PAM3, 0x33);
118 pci_write_config8(SA_DEV_ROOT, PAM4, 0x33);
119 pci_write_config8(SA_DEV_ROOT, PAM5, 0x33);
120 pci_write_config8(SA_DEV_ROOT, PAM6, 0x33);
121}
122
123void enable_bios_reset_cpl(void)
124{
125 u8 bios_reset_cpl;
126
127 /*
128 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
129 * that BIOS has initialized memory and power management
130 */
131 bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
132 bios_reset_cpl |= 3;
133 MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
134}
Subrata Banikbd6ac222017-08-21 16:42:15 +0530135
Subrata Banik73f448f2017-08-29 18:51:14 +0530136uintptr_t sa_get_tolud_base(void)
Subrata Banikbd6ac222017-08-21 16:42:15 +0530137{
138 /* All regions concerned for have 1 MiB alignment. */
139 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
140}
141
142static uint16_t sa_get_ggc_reg(void)
143{
144 return pci_read_config16(SA_DEV_ROOT, GGC);
145}
146
Subrata Banik445368c2018-04-02 11:34:59 +0530147/*
148 * Internal Graphics Pre-allocated Memory - As per Intel FSP UPD Header
149 * definition, size of memory preallocatred for internal graphics can be
150 * configured based on below lists:
151 *
152 * 0x00:0MB, 0x01:32MB, 0x02:64MB, 0x03:96MB, 0x04:128MB, 0x05:160MB,
153 * 0xF0:4MB, 0xF1:8MB, 0xF2:12MB, 0xF3:16MB, 0xF4:20MB, 0xF5:24MB, 0xF6:28MB,
154 * 0xF7:32MB, 0xF8:36MB, 0xF9:40MB, 0xFA:44MB, 0xFB:48MB, 0xFC:52MB, 0xFD:56MB,
155 * 0xFE:60MB
156 *
157 * Today all existing SoCs(except Cannonlake) are supported under intel
158 * common code block design may not need to use any other values than 0x0-0x05
159 * for GFX DSM range. DSM memory ranges between 0xF0-0xF6 are majorly for
160 * early SoC samples and validation requirement. This code block to justify
161 * all differnet possible ranges that FSP may support for a platform.
162 */
Subrata Banikbd6ac222017-08-21 16:42:15 +0530163size_t sa_get_dsm_size(void)
164{
Subrata Banik445368c2018-04-02 11:34:59 +0530165 uint32_t prealloc_memory;
166 uint16_t ggc;
167
168 ggc = sa_get_ggc_reg();
169 prealloc_memory = (ggc & G_GMS_MASK) >> G_GMS_OFFSET;
170
171 if (prealloc_memory < 0xF0)
172 return prealloc_memory * 32*MiB;
173 else
174 return (prealloc_memory - 0xEF) * 4*MiB;
Subrata Banikbd6ac222017-08-21 16:42:15 +0530175}
176
Matt DeVilliercbe73ea2018-06-25 14:40:53 -0500177uintptr_t sa_get_gsm_base(void)
Subrata Banik73f448f2017-08-29 18:51:14 +0530178{
179 /* All regions concerned for have 1 MiB alignment. */
180 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
181}
182
Subrata Banikbd6ac222017-08-21 16:42:15 +0530183size_t sa_get_gsm_size(void)
184{
185 uint8_t ggms;
186
187 ggms = (sa_get_ggc_reg() & G_GGMS_MASK) >> G_GGMS_OFFSET;
188
189 /*
190 * Size of GSM: 0x0: No Preallocated Memory 0x1: 2MB Memory
191 * 0x2: 4MB Memory 0x3: 8MB Memory
192 */
193 if (ggms)
194 return 1*MiB << ggms;
195 else
196 return 0;
197}
198
Subrata Banik73f448f2017-08-29 18:51:14 +0530199uintptr_t sa_get_tseg_base(void)
200{
201 /* All regions concerned for have 1 MiB alignment. */
202 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB);
203}
204
205size_t sa_get_tseg_size(void)
206{
207 return sa_get_gsm_base() - sa_get_tseg_base();
208}
209
Subrata Banikbd6ac222017-08-21 16:42:15 +0530210/*
211 * Get DPR size in case CONFIG_SA_ENABLE_DPR is selected by SoC.
212 */
213size_t sa_get_dpr_size(void)
214{
215 uintptr_t dpr_reg;
216 size_t size = 0;
217 /*
218 * DMA Protected Range can be reserved below TSEG for PCODE patch
219 * or TXT/BootGuard related data. Rather than report a base address
220 * the DPR register reports the TOP of the region, which is the same
221 * as TSEG base. The region size is reported in MiB in bits 11:4.
222 */
223 dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR);
224 if (dpr_reg & DPR_EPM)
225 size = (dpr_reg & DPR_SIZE_MASK) << 16;
226
227 return size;
228}