blob: 53d6077e5ff1a8e2767a91402e5f2712d1650f26 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Subrata Banik7609c652017-05-19 14:50:09 +05302
Kyösti Mälkki6046eb42019-07-14 11:07:39 +03003#define __SIMPLE_DEVICE__
4
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Subrata Banik7609c652017-05-19 14:50:09 +05307#include <device/device.h>
8#include <device/pci.h>
9#include <intelblocks/systemagent.h>
Angel Ponsffbb4b22020-10-15 23:25:58 +020010#include <security/intel/txt/txt_platform.h>
11#include <security/intel/txt/txt_register.h>
Subrata Banik7609c652017-05-19 14:50:09 +053012#include <soc/iomap.h>
13#include <soc/pci_devs.h>
14#include <soc/systemagent.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +010015
Subrata Banik7609c652017-05-19 14:50:09 +053016#include "systemagent_def.h"
Subrata Banik7609c652017-05-19 14:50:09 +053017
Subrata Banik7609c652017-05-19 14:50:09 +053018void bootblock_systemagent_early_init(void)
19{
20 uint32_t reg;
21 uint8_t pciexbar_length;
22
23 /*
24 * The PCIEXBAR is assumed to live in the memory mapped IO space under
25 * 4GiB.
26 */
27 reg = 0;
28 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
29
30 /* Get PCI Express Region Length */
31 switch (CONFIG_SA_PCIEX_LENGTH) {
32 case 256 * MiB:
33 pciexbar_length = PCIEXBAR_LENGTH_256MB;
34 break;
35 case 128 * MiB:
36 pciexbar_length = PCIEXBAR_LENGTH_128MB;
37 break;
38 case 64 * MiB:
39 pciexbar_length = PCIEXBAR_LENGTH_64MB;
40 break;
41 default:
42 pciexbar_length = PCIEXBAR_LENGTH_256MB;
43 }
44 reg = CONFIG_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
45 | PCIEXBAR_PCIEXBAREN;
46 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
47
48 /*
49 * TSEG defines the base of SMM range. BIOS determines the base
50 * of TSEG memory which must be at or below Graphics base of GTT
51 * Stolen memory, hence its better to clear TSEG register early
52 * to avoid power on default non-zero value (if any).
53 */
54 pci_write_config32(SA_DEV_ROOT, TSEG, 0);
55}
Subrata Banik7609c652017-05-19 14:50:09 +053056
57void sa_set_pci_bar(const struct sa_mmio_descriptor *fixed_set_resources,
58 size_t count)
59{
60 int i;
61
62 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053063 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053064 unsigned int index;
65
66 index = fixed_set_resources[i].index;
67 /* Check if PCI BAR already enabled */
68 base = pci_read_config32(SA_DEV_ROOT, index);
69
70 /* If enabled don't program it. */
71 if (base & 0x1)
72 return;
73
74 base = fixed_set_resources[i].base;
Subrata Banikf8d9a132020-01-21 14:28:26 +053075 if (base >> 32)
76 pci_write_config32(SA_DEV_ROOT, index + 4, base >> 32);
77 pci_write_config32(SA_DEV_ROOT, index, (base & 0xffffffff) | 1);
Subrata Banik7609c652017-05-19 14:50:09 +053078 }
79}
80
81/*
82 * There are special BARs that actually are programmed in the MCHBAR. These
83 * Intel special features, but they do consume resources that need to be
84 * accounted for.
85 */
86void sa_set_mch_bar(const struct sa_mmio_descriptor *fixed_set_resources,
87 size_t count)
88{
89 int i;
90
91 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053092 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053093 unsigned int index;
94
95 base = fixed_set_resources[i].base;
96 index = fixed_set_resources[i].index;
Subrata Banikf8d9a132020-01-21 14:28:26 +053097 if (base >> 32)
98 write32((void *)(MCH_BASE_ADDRESS + index + 4), base >> 32);
99 write32((void *)(MCH_BASE_ADDRESS + index), (base & 0xffffffff) | 1);
Subrata Banik7609c652017-05-19 14:50:09 +0530100 }
101}
102
103void enable_pam_region(void)
104{
105 /* All read and writes in this region are serviced by DRAM */
106 pci_write_config8(SA_DEV_ROOT, PAM0, 0x30);
107 pci_write_config8(SA_DEV_ROOT, PAM1, 0x33);
108 pci_write_config8(SA_DEV_ROOT, PAM2, 0x33);
109 pci_write_config8(SA_DEV_ROOT, PAM3, 0x33);
110 pci_write_config8(SA_DEV_ROOT, PAM4, 0x33);
111 pci_write_config8(SA_DEV_ROOT, PAM5, 0x33);
112 pci_write_config8(SA_DEV_ROOT, PAM6, 0x33);
113}
114
115void enable_bios_reset_cpl(void)
116{
117 u8 bios_reset_cpl;
118
119 /*
120 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
121 * that BIOS has initialized memory and power management
122 */
123 bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
124 bios_reset_cpl |= 3;
125 MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
126}
Subrata Banikbd6ac222017-08-21 16:42:15 +0530127
Subrata Banik73f448f2017-08-29 18:51:14 +0530128uintptr_t sa_get_tolud_base(void)
Subrata Banikbd6ac222017-08-21 16:42:15 +0530129{
130 /* All regions concerned for have 1 MiB alignment. */
131 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
132}
133
Matt DeVilliercbe73ea2018-06-25 14:40:53 -0500134uintptr_t sa_get_gsm_base(void)
Subrata Banik73f448f2017-08-29 18:51:14 +0530135{
136 /* All regions concerned for have 1 MiB alignment. */
137 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
138}
139
Subrata Banik73f448f2017-08-29 18:51:14 +0530140uintptr_t sa_get_tseg_base(void)
141{
142 /* All regions concerned for have 1 MiB alignment. */
143 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB);
144}
145
146size_t sa_get_tseg_size(void)
147{
148 return sa_get_gsm_base() - sa_get_tseg_base();
149}
Angel Ponsffbb4b22020-10-15 23:25:58 +0200150
151union dpr_register txt_get_chipset_dpr(void)
152{
153 return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) };
154}