blob: ffb6404aa2290db503712ccc965525e157fc73c9 [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>
10#include <soc/iomap.h>
11#include <soc/pci_devs.h>
12#include <soc/systemagent.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +010013
Subrata Banik7609c652017-05-19 14:50:09 +053014#include "systemagent_def.h"
Subrata Banik7609c652017-05-19 14:50:09 +053015
Subrata Banik7609c652017-05-19 14:50:09 +053016void bootblock_systemagent_early_init(void)
17{
18 uint32_t reg;
19 uint8_t pciexbar_length;
20
21 /*
22 * The PCIEXBAR is assumed to live in the memory mapped IO space under
23 * 4GiB.
24 */
25 reg = 0;
26 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
27
28 /* Get PCI Express Region Length */
29 switch (CONFIG_SA_PCIEX_LENGTH) {
30 case 256 * MiB:
31 pciexbar_length = PCIEXBAR_LENGTH_256MB;
32 break;
33 case 128 * MiB:
34 pciexbar_length = PCIEXBAR_LENGTH_128MB;
35 break;
36 case 64 * MiB:
37 pciexbar_length = PCIEXBAR_LENGTH_64MB;
38 break;
39 default:
40 pciexbar_length = PCIEXBAR_LENGTH_256MB;
41 }
42 reg = CONFIG_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
43 | PCIEXBAR_PCIEXBAREN;
44 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
45
46 /*
47 * TSEG defines the base of SMM range. BIOS determines the base
48 * of TSEG memory which must be at or below Graphics base of GTT
49 * Stolen memory, hence its better to clear TSEG register early
50 * to avoid power on default non-zero value (if any).
51 */
52 pci_write_config32(SA_DEV_ROOT, TSEG, 0);
53}
Subrata Banik7609c652017-05-19 14:50:09 +053054
55void sa_set_pci_bar(const struct sa_mmio_descriptor *fixed_set_resources,
56 size_t count)
57{
58 int i;
59
60 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053061 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053062 unsigned int index;
63
64 index = fixed_set_resources[i].index;
65 /* Check if PCI BAR already enabled */
66 base = pci_read_config32(SA_DEV_ROOT, index);
67
68 /* If enabled don't program it. */
69 if (base & 0x1)
70 return;
71
72 base = fixed_set_resources[i].base;
Subrata Banikf8d9a132020-01-21 14:28:26 +053073 if (base >> 32)
74 pci_write_config32(SA_DEV_ROOT, index + 4, base >> 32);
75 pci_write_config32(SA_DEV_ROOT, index, (base & 0xffffffff) | 1);
Subrata Banik7609c652017-05-19 14:50:09 +053076 }
77}
78
79/*
80 * There are special BARs that actually are programmed in the MCHBAR. These
81 * Intel special features, but they do consume resources that need to be
82 * accounted for.
83 */
84void sa_set_mch_bar(const struct sa_mmio_descriptor *fixed_set_resources,
85 size_t count)
86{
87 int i;
88
89 for (i = 0; i < count; i++) {
Subrata Banikf8d9a132020-01-21 14:28:26 +053090 uint64_t base;
Subrata Banik7609c652017-05-19 14:50:09 +053091 unsigned int index;
92
93 base = fixed_set_resources[i].base;
94 index = fixed_set_resources[i].index;
Subrata Banikf8d9a132020-01-21 14:28:26 +053095 if (base >> 32)
96 write32((void *)(MCH_BASE_ADDRESS + index + 4), base >> 32);
97 write32((void *)(MCH_BASE_ADDRESS + index), (base & 0xffffffff) | 1);
Subrata Banik7609c652017-05-19 14:50:09 +053098 }
99}
100
101void enable_pam_region(void)
102{
103 /* All read and writes in this region are serviced by DRAM */
104 pci_write_config8(SA_DEV_ROOT, PAM0, 0x30);
105 pci_write_config8(SA_DEV_ROOT, PAM1, 0x33);
106 pci_write_config8(SA_DEV_ROOT, PAM2, 0x33);
107 pci_write_config8(SA_DEV_ROOT, PAM3, 0x33);
108 pci_write_config8(SA_DEV_ROOT, PAM4, 0x33);
109 pci_write_config8(SA_DEV_ROOT, PAM5, 0x33);
110 pci_write_config8(SA_DEV_ROOT, PAM6, 0x33);
111}
112
113void enable_bios_reset_cpl(void)
114{
115 u8 bios_reset_cpl;
116
117 /*
118 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
119 * that BIOS has initialized memory and power management
120 */
121 bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
122 bios_reset_cpl |= 3;
123 MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
124}
Subrata Banikbd6ac222017-08-21 16:42:15 +0530125
Subrata Banik73f448f2017-08-29 18:51:14 +0530126uintptr_t sa_get_tolud_base(void)
Subrata Banikbd6ac222017-08-21 16:42:15 +0530127{
128 /* All regions concerned for have 1 MiB alignment. */
129 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
130}
131
Matt DeVilliercbe73ea2018-06-25 14:40:53 -0500132uintptr_t sa_get_gsm_base(void)
Subrata Banik73f448f2017-08-29 18:51:14 +0530133{
134 /* All regions concerned for have 1 MiB alignment. */
135 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
136}
137
Subrata Banik73f448f2017-08-29 18:51:14 +0530138uintptr_t sa_get_tseg_base(void)
139{
140 /* All regions concerned for have 1 MiB alignment. */
141 return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB);
142}
143
144size_t sa_get_tseg_size(void)
145{
146 return sa_get_gsm_base() - sa_get_tseg_base();
147}