blob: 299f4c18a9181a886ce88e41fd7184acf16d03ec [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
Angel Pons98494882021-01-29 11:35:16 +01005#include <assert.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02006#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02007#include <device/pci_ops.h>
Subrata Banik7609c652017-05-19 14:50:09 +05308#include <device/device.h>
9#include <device/pci.h>
10#include <intelblocks/systemagent.h>
Angel Ponsffbb4b22020-10-15 23:25:58 +020011#include <security/intel/txt/txt_platform.h>
12#include <security/intel/txt/txt_register.h>
Subrata Banik7609c652017-05-19 14:50:09 +053013#include <soc/iomap.h>
14#include <soc/pci_devs.h>
15#include <soc/systemagent.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +010016
Subrata Banik7609c652017-05-19 14:50:09 +053017#include "systemagent_def.h"
Subrata Banik7609c652017-05-19 14:50:09 +053018
Subrata Banik7609c652017-05-19 14:50:09 +053019void bootblock_systemagent_early_init(void)
20{
21 uint32_t reg;
22 uint8_t pciexbar_length;
23
24 /*
25 * The PCIEXBAR is assumed to live in the memory mapped IO space under
26 * 4GiB.
27 */
28 reg = 0;
29 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
30
31 /* Get PCI Express Region Length */
Shelley Chen4e9bb332021-10-20 15:43:45 -070032 switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) {
Angel Pons98494882021-01-29 11:35:16 +010033 case 256:
Subrata Banik7609c652017-05-19 14:50:09 +053034 pciexbar_length = PCIEXBAR_LENGTH_256MB;
35 break;
Angel Pons98494882021-01-29 11:35:16 +010036 case 128:
Subrata Banik7609c652017-05-19 14:50:09 +053037 pciexbar_length = PCIEXBAR_LENGTH_128MB;
38 break;
Angel Pons98494882021-01-29 11:35:16 +010039 case 64:
Subrata Banik7609c652017-05-19 14:50:09 +053040 pciexbar_length = PCIEXBAR_LENGTH_64MB;
41 break;
42 default:
Angel Pons98494882021-01-29 11:35:16 +010043 dead_code();
Subrata Banik7609c652017-05-19 14:50:09 +053044 }
Shelley Chen4e9bb332021-10-20 15:43:45 -070045 reg = CONFIG_ECAM_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
Subrata Banik7609c652017-05-19 14:50:09 +053046 | PCIEXBAR_PCIEXBAREN;
47 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
48
49 /*
50 * TSEG defines the base of SMM range. BIOS determines the base
51 * of TSEG memory which must be at or below Graphics base of GTT
52 * Stolen memory, hence its better to clear TSEG register early
53 * to avoid power on default non-zero value (if any).
54 */
55 pci_write_config32(SA_DEV_ROOT, TSEG, 0);
56}
Subrata Banik7609c652017-05-19 14:50:09 +053057
58void sa_set_pci_bar(const struct sa_mmio_descriptor *fixed_set_resources,
59 size_t count)
60{
61 int i;
62
63 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053064 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053065 unsigned int index;
66
67 index = fixed_set_resources[i].index;
68 /* Check if PCI BAR already enabled */
69 base = pci_read_config32(SA_DEV_ROOT, index);
70
71 /* If enabled don't program it. */
Wonkyu Kim92c10422022-04-26 16:36:21 -070072 if (base & PCIEXBAR_PCIEXBAREN)
Subrata Banik7609c652017-05-19 14:50:09 +053073 return;
74
75 base = fixed_set_resources[i].base;
Subrata Banikf8d9a132020-01-21 14:28:26 +053076 if (base >> 32)
77 pci_write_config32(SA_DEV_ROOT, index + 4, base >> 32);
Wonkyu Kim92c10422022-04-26 16:36:21 -070078 pci_write_config32(SA_DEV_ROOT, index,
79 (base & 0xffffffff) | PCIEXBAR_PCIEXBAREN);
Subrata Banik7609c652017-05-19 14:50:09 +053080 }
81}
82
83/*
84 * There are special BARs that actually are programmed in the MCHBAR. These
85 * Intel special features, but they do consume resources that need to be
86 * accounted for.
87 */
88void sa_set_mch_bar(const struct sa_mmio_descriptor *fixed_set_resources,
89 size_t count)
90{
91 int i;
92
93 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053094 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053095 unsigned int index;
96
97 base = fixed_set_resources[i].base;
98 index = fixed_set_resources[i].index;
Subrata Banikf8d9a132020-01-21 14:28:26 +053099 if (base >> 32)
Patrick Rudolph38053542020-11-30 13:42:24 +0100100 write32((void *)(uintptr_t)(MCH_BASE_ADDRESS + index + 4), base >> 32);
Wonkyu Kim92c10422022-04-26 16:36:21 -0700101 write32((void *)(uintptr_t)(MCH_BASE_ADDRESS + index),
102 (base & 0xffffffff) | PCIEXBAR_PCIEXBAREN);
Subrata Banik7609c652017-05-19 14:50:09 +0530103 }
104}
105
106void enable_pam_region(void)
107{
108 /* All read and writes in this region are serviced by DRAM */
109 pci_write_config8(SA_DEV_ROOT, PAM0, 0x30);
110 pci_write_config8(SA_DEV_ROOT, PAM1, 0x33);
111 pci_write_config8(SA_DEV_ROOT, PAM2, 0x33);
112 pci_write_config8(SA_DEV_ROOT, PAM3, 0x33);
113 pci_write_config8(SA_DEV_ROOT, PAM4, 0x33);
114 pci_write_config8(SA_DEV_ROOT, PAM5, 0x33);
115 pci_write_config8(SA_DEV_ROOT, PAM6, 0x33);
116}
117
118void enable_bios_reset_cpl(void)
119{
120 u8 bios_reset_cpl;
121
122 /*
123 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
124 * that BIOS has initialized memory and power management
125 */
126 bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
127 bios_reset_cpl |= 3;
128 MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
129}
Subrata Banikbd6ac222017-08-21 16:42:15 +0530130
Subrata Banik73f448f2017-08-29 18:51:14 +0530131uintptr_t sa_get_tolud_base(void)
Subrata Banikbd6ac222017-08-21 16:42:15 +0530132{
133 /* All regions concerned for have 1 MiB alignment. */
134 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
135}
136
Matt DeVilliercbe73ea2018-06-25 14:40:53 -0500137uintptr_t sa_get_gsm_base(void)
Subrata Banik73f448f2017-08-29 18:51:14 +0530138{
139 /* All regions concerned for have 1 MiB alignment. */
140 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
141}
142
Subrata Banik73f448f2017-08-29 18:51:14 +0530143uintptr_t sa_get_tseg_base(void)
144{
145 /* All regions concerned for have 1 MiB alignment. */
146 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB);
147}
148
149size_t sa_get_tseg_size(void)
150{
151 return sa_get_gsm_base() - sa_get_tseg_base();
152}
Angel Ponsffbb4b22020-10-15 23:25:58 +0200153
154union dpr_register txt_get_chipset_dpr(void)
155{
156 return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) };
157}