blob: 7cf78e735221ca6e6f3f5766a7929937da8a654c [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
16#include <arch/io.h>
17#include <delay.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <intelblocks/systemagent.h>
21#include <soc/iomap.h>
22#include <soc/pci_devs.h>
23#include <soc/systemagent.h>
24#include "systemagent_def.h"
25#include <timer.h>
26
27#if !ENV_RAMSTAGE
28void bootblock_systemagent_early_init(void)
29{
30 uint32_t reg;
31 uint8_t pciexbar_length;
32
33 /*
34 * The PCIEXBAR is assumed to live in the memory mapped IO space under
35 * 4GiB.
36 */
37 reg = 0;
38 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
39
40 /* Get PCI Express Region Length */
41 switch (CONFIG_SA_PCIEX_LENGTH) {
42 case 256 * MiB:
43 pciexbar_length = PCIEXBAR_LENGTH_256MB;
44 break;
45 case 128 * MiB:
46 pciexbar_length = PCIEXBAR_LENGTH_128MB;
47 break;
48 case 64 * MiB:
49 pciexbar_length = PCIEXBAR_LENGTH_64MB;
50 break;
51 default:
52 pciexbar_length = PCIEXBAR_LENGTH_256MB;
53 }
54 reg = CONFIG_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
55 | PCIEXBAR_PCIEXBAREN;
56 pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
57
58 /*
59 * TSEG defines the base of SMM range. BIOS determines the base
60 * of TSEG memory which must be at or below Graphics base of GTT
61 * Stolen memory, hence its better to clear TSEG register early
62 * to avoid power on default non-zero value (if any).
63 */
64 pci_write_config32(SA_DEV_ROOT, TSEG, 0);
65}
66#endif
67
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}