coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
early_init.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <device/device.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_def.h>
8 #include <option.h>
9 #include <types.h>
10 
11 #include "sandybridge.h"
12 
13 static void systemagent_vtd_init(void)
14 {
15  const u32 capid0_a = pci_read_config32(HOST_BRIDGE, CAPID0_A);
16  if (capid0_a & (1 << 23))
17  return;
18 
19  /* Setup BARs */
24 
25  /* Lock policies */
26  write32((void *)(GFXVT_BASE + 0xff0), 0x80000000);
27 
28  const struct device *const azalia = pcidev_on_root(0x1b, 0);
29  if (azalia && azalia->enabled) {
30  write32((void *)(VTVC0_BASE + 0xff0), 0x20000000);
31  write32((void *)(VTVC0_BASE + 0xff0), 0xa0000000);
32  } else {
33  write32((void *)(VTVC0_BASE + 0xff0), 0x80000000);
34  }
35 }
36 
37 static void enable_pam_region(void)
38 {
46 }
47 
48 static void sandybridge_setup_bars(void)
49 {
50  printk(BIOS_DEBUG, "Setting up static northbridge registers...");
51  /* Set up all hardcoded northbridge BARs */
52  pci_write_config32(HOST_BRIDGE, EPBAR, CONFIG_FIXED_EPBAR_MMIO_BASE | 1);
54  pci_write_config32(HOST_BRIDGE, MCHBAR, CONFIG_FIXED_MCHBAR_MMIO_BASE | 1);
56  pci_write_config32(HOST_BRIDGE, DMIBAR, CONFIG_FIXED_DMIBAR_MMIO_BASE | 1);
58 
59  printk(BIOS_DEBUG, " done\n");
60 }
61 
62 static void sandybridge_setup_graphics(void)
63 {
64  u16 reg16;
65  u8 gfxsize;
66 
67  reg16 = pci_read_config16(PCI_DEV(0, 2, 0), PCI_DEVICE_ID);
68  switch (reg16) {
69  case 0x0102: /* GT1 Desktop */
70  case 0x0106: /* GT1 Mobile */
71  case 0x010a: /* GT1 Server */
72  case 0x0112: /* GT2 Desktop */
73  case 0x0116: /* GT2 Mobile */
74  case 0x0122: /* GT2 Desktop >=1.3GHz */
75  case 0x0126: /* GT2 Mobile >=1.3GHz */
76  case 0x0152: /* IvyBridge */
77  case 0x0156: /* IvyBridge */
78  case 0x0162: /* IvyBridge */
79  case 0x0166: /* IvyBridge */
80  case 0x016a: /* IvyBridge */
81  break;
82  default:
83  printk(BIOS_DEBUG, "Graphics not supported by this CPU/chipset.\n");
84  return;
85  }
86 
87  printk(BIOS_DEBUG, "Initializing Graphics...\n");
88 
89  /* Fall back to 32 MiB for IGD memory by setting GGC[7:3] = 1 */
90  gfxsize = get_uint_option("gfx_uma_size", 0);
91 
93  reg16 &= ~0x00f8;
94  reg16 |= (gfxsize + 1) << 3;
95  /* Program GTT memory by setting GGC[9:8] = 2MB */
96  reg16 &= ~0x0300;
97  reg16 |= 2 << 8;
98  /* Enable VGA decode */
99  reg16 &= ~0x0002;
101 
102  /* Enable 256MB aperture */
103  pci_update_config8(PCI_DEV(0, 2, 0), MSAC, ~0x06, 0x02);
104 
105  /* Erratum workarounds */
106  mchbar_setbits32(SAPMCTL, 1 << 9 | 1 << 10);
107 
108  /* Enable SA Clock Gating */
109  mchbar_setbits32(SAPMCTL, 1 << 0);
110 
111  /* GPU RC6 workaround for sighting 366252 */
112  mchbar_setbits32(SSKPD_HI, 1 << 31);
113 
114  /* VLW (Virtual Legacy Wire?) */
115  mchbar_clrbits32(0x6120, 1 << 0);
116 
117  mchbar_setbits32(INTRDIRCTL, 1 << 4 | 1 << 5);
118 }
119 
120 static void start_peg_link_training(void)
121 {
122  u32 deven;
123 
125  /*
126  * PEG on IvyBridge+ needs a special startup sequence.
127  * As the MRC has its own initialization code skip it.
128  */
129  if ((base_rev != BASE_REV_IVB) || CONFIG(HAVE_MRC))
130  return;
131 
133 
134  /*
135  * For each PEG device, set bit 5 to use three retries for OC (Offset Calibration).
136  * We also clear DEFER_OC (bit 16) in order to start PEG training.
137  */
138  if (deven & DEVEN_PEG10)
139  pci_update_config32(PCI_DEV(0, 1, 0), AFE_PWRON, ~(1 << 16), 1 << 5);
140 
141  if (deven & DEVEN_PEG11)
142  pci_update_config32(PCI_DEV(0, 1, 1), AFE_PWRON, ~(1 << 16), 1 << 5);
143 
144  if (deven & DEVEN_PEG12)
145  pci_update_config32(PCI_DEV(0, 1, 2), AFE_PWRON, ~(1 << 16), 1 << 5);
146 
147  if (deven & DEVEN_PEG60)
148  pci_update_config32(PCI_DEV(0, 6, 0), AFE_PWRON, ~(1 << 16), 1 << 5);
149 }
150 
152 {
153  u32 capid0_a;
154  u8 reg8;
155 
156  /* Device ID Override Enable should be done very early */
158  if (capid0_a & (1 << 10)) {
159  const size_t is_mobile = get_platform_type() == PLATFORM_MOBILE;
160 
162  reg8 &= ~7; /* Clear 2:0 */
163 
164  if (is_mobile)
165  reg8 |= 1; /* Set bit 0 */
166 
168  }
169 
170  /* Setup all BARs required for early PCIe and raminit */
172 
173  /* Set C0000-FFFFF to access RAM on both reads and writes */
175 
176  /* Setup IOMMU BARs */
178 
179  /* Device Enable, don't touch PEG bits */
181 
183 
184  /*
185  * Write magic values to start PEG link training. This should be done in PCI device
186  * enumeration, but the PCIe specification requires to wait at least 100msec after
187  * reset for devices to come up. As we don't want to increase boot time, enable it
188  * early and assume that PEG is up as soon as PCI enumeration starts.
189  *
190  * TODO: use timestamps to ensure the timings are met.
191  */
193 }
194 
196 {
197  mchbar_write16(SSKPD_HI, 0xcafe);
198 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
#define printk(level,...)
Definition: stdlib.h:16
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
@ CONFIG
Definition: dsi_common.h:201
#define mchbar_setbits32(addr, set)
Definition: fixed_bars.h:58
static __always_inline void mchbar_write16(const uintptr_t offset, const uint16_t value)
Definition: fixed_bars.h:31
static __always_inline void mchbar_write32(const uintptr_t offset, const uint32_t value)
Definition: fixed_bars.h:36
#define mchbar_clrbits32(addr, clear)
Definition: fixed_bars.h:62
#define PAM0
Definition: host_bridge.h:38
#define PAM6
Definition: host_bridge.h:44
#define GGC
Definition: host_bridge.h:9
#define PAM5
Definition: host_bridge.h:43
#define CAPID0_A
Definition: host_bridge.h:65
#define MCHBAR
Definition: host_bridge.h:7
#define PAM2
Definition: host_bridge.h:40
#define PAM1
Definition: host_bridge.h:39
#define DMIBAR
Definition: host_bridge.h:33
#define EPBAR
Definition: host_bridge.h:6
#define DEVEN
Definition: host_bridge.h:16
#define PAM3
Definition: host_bridge.h:41
#define PAM4
Definition: host_bridge.h:42
#define SAPMCTL
Definition: mchbar.h:65
#define INTRDIRCTL
Definition: mchbar.h:21
#define VTVC0BAR
Definition: mchbar.h:20
#define GFXVTBAR
Definition: mchbar.h:18
static __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Definition: pci_ops.h:120
static __always_inline void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Definition: pci_ops.h:88
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define DEVEN_PEG10
Definition: host_bridge.h:11
#define DEVEN_IGD
Definition: host_bridge.h:10
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define MSAC
Definition: haswell.h:21
enum platform_type get_platform_type(void)
Definition: common.c:8
static void sandybridge_setup_bars(void)
Definition: early_init.c:48
static void sandybridge_setup_graphics(void)
Definition: early_init.c:62
static void start_peg_link_training(void)
Definition: early_init.c:120
void systemagent_early_init(void)
Definition: early_init.c:151
void northbridge_romstage_finalize(void)
Definition: early_init.c:195
static void enable_pam_region(void)
Definition: early_init.c:37
static void systemagent_vtd_init(void)
Definition: early_init.c:13
#define VTVC0_BASE
Definition: memmap.h:7
#define GFXVT_BASE
Definition: memmap.h:6
unsigned int get_uint_option(const char *name, const unsigned int fallback)
Definition: option.c:116
#define PCI_DEVICE_ID
Definition: pci_def.h:9
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
#define DEVEN_PEG60
Definition: host_bridge.h:12
#define DEVEN_PEG12
Definition: host_bridge.h:17
#define DIDOR
Definition: host_bridge.h:62
#define DEVEN_PEG11
Definition: host_bridge.h:16
#define SSKPD_HI
Definition: mchbar.h:506
#define AFE_PWRON
Definition: sandybridge.h:30
#define BASE_REV_MASK
Definition: sandybridge.h:9
#define BASE_REV_IVB
Definition: sandybridge.h:8
@ PLATFORM_MOBILE
Definition: sandybridge.h:19
@ HOST_BRIDGE
Definition: reg_access.h:23
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
Definition: device.h:107
unsigned int enabled
Definition: device.h:122