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 <stdint.h>
4 #include <device/pci_ops.h>
5 #if CONFIG(SOUTHBRIDGE_INTEL_I82801GX)
6 #include <southbridge/intel/i82801gx/i82801gx.h> /* DEFAULT_PMBASE */
7 #else
8 #include <southbridge/intel/i82801jx/i82801jx.h> /* DEFAULT_PMBASE */
9 #endif
10 #include <option.h>
11 #include "x4x.h"
12 #include <console/console.h>
13 
14 void x4x_early_init(void)
15 {
16  /* Setup MCHBAR. */
17  pci_write_config32(HOST_BRIDGE, D0F0_MCHBAR_LO, CONFIG_FIXED_MCHBAR_MMIO_BASE | 1);
18 
19  /* Setup DMIBAR. */
20  pci_write_config32(HOST_BRIDGE, D0F0_DMIBAR_LO, CONFIG_FIXED_DMIBAR_MMIO_BASE | 1);
21 
22  /* Setup EPBAR. */
23  pci_write_config32(HOST_BRIDGE, D0F0_EPBAR_LO, CONFIG_FIXED_EPBAR_MMIO_BASE | 1);
24 
25  /* Setup HECIBAR */
27 
28  /* Set C0000-FFFFF to access RAM on both reads and writes */
36 
37  if (!(pci_read_config32(HOST_BRIDGE, D0F0_CAPID0 + 4) & (1 << (46 - 32)))) {
38  /* Enable internal GFX */
40 
41  /* Set preallocated IGD size from CMOS, or default to 64 MiB */
42  u8 gfxsize = get_uint_option("gfx_uma_size", 6);
43  if (gfxsize > 12)
44  gfxsize = 6;
45  /* Need at least 4M for cbmem_top alignment */
46  else if (gfxsize < 1)
47  gfxsize = 1;
48  /* Set GTT size to 2+2M */
49  pci_write_config16(HOST_BRIDGE, D0F0_GGC, 0x0b00 | (gfxsize + 1) << 4);
50  } else { /* Does not feature internal graphics */
53  }
54 }
55 
56 static void init_egress(void)
57 {
58  u32 reg32;
59 
60  /* VC0: TC0 only */
63 
65  case 0x0:
66  /* FSB 1066 */
67  epbar_write32(EPVC1ITC, 0x0001a6db);
68  break;
69  case 0x2:
70  /* FSB 800 */
71  epbar_write32(EPVC1ITC, 0x00014514);
72  break;
73  default:
74  case 0x4:
75  /* FSB 1333 */
76  epbar_write32(EPVC1ITC, 0x00022861);
77  break;
78  }
79  epbar_write32(EPVC1MTS, 0x0a0a0a0a);
80  epbar_clrsetbits8(EPPVCCTL, 7 << 1, 1 << 1);
81  epbar_clrsetbits32(EPVC1RCAP, 0x7f << 16, 0x0a << 16);
82  mchbar_setbits8(0x3c, 7);
83 
84  /* VC1: ID1, TC7 */
85  reg32 = (epbar_read32(EPVC1RCTL) & ~(7 << 24)) | (1 << 24);
86  reg32 = (reg32 & ~0xfe) | (1 << 7);
87  epbar_write32(EPVC1RCTL, reg32);
88 
89  /* Init VC1 port arbitration table */
90  epbar_write32(EP_PORTARB(0), 0x001000001);
91  epbar_write32(EP_PORTARB(1), 0x000040000);
92  epbar_write32(EP_PORTARB(2), 0x000001000);
93  epbar_write32(EP_PORTARB(3), 0x000000040);
94  epbar_write32(EP_PORTARB(4), 0x001000001);
95  epbar_write32(EP_PORTARB(5), 0x000040000);
96  epbar_write32(EP_PORTARB(6), 0x000001000);
97  epbar_write32(EP_PORTARB(7), 0x000000040);
98 
99  /* Load table */
100  reg32 = epbar_read32(EPVC1RCTL) | (1 << 16);
101  epbar_write32(EPVC1RCTL, reg32);
102  asm("nop");
103  epbar_write32(EPVC1RCTL, reg32);
104 
105  /* Wait for table load */
106  while ((epbar_read8(EPVC1RSTS) & (1 << 0)) != 0)
107  ;
108 
109  /* VC1: enable */
110  epbar_setbits32(EPVC1RCTL, 1 << 31);
111 
112  /* Wait for VC1 */
113  while ((epbar_read8(EPVC1RSTS) & (1 << 1)) != 0)
114  ;
115 
116  printk(BIOS_DEBUG, "Done Egress Port\n");
117 }
118 
119 static void init_dmi(void)
120 {
121  u32 reg32;
122 
123  /* Assume IGD present */
124 
125  /* Clear error status */
126  dmibar_write32(DMIUESTS, 0xffffffff);
127  dmibar_write32(DMICESTS, 0xffffffff);
128 
129  /* VC0: TC0 only */
132 
133  /* VC1: ID1, TC7 */
134  reg32 = (dmibar_read32(DMIVC1RCTL) & ~(7 << 24)) | (1 << 24);
135  reg32 = (reg32 & ~0xff) | 1 << 7;
136 
137  /* VC1: enable */
138  reg32 |= 1 << 31;
139  reg32 = (reg32 & ~(0x7 << 17)) | (0x4 << 17);
140 
141  dmibar_write32(DMIVC1RCTL, reg32);
142 
143  /* Set up VCs in southbridge RCBA */
144  RCBA8(0x3022) &= ~1;
145 
146  reg32 = (0x5 << 28) | (1 << 6); /* PCIe x4 */
147  RCBA32(0x2020) = (RCBA32(0x2020) & ~((0xf << 28) | (0x7 << 6))) | reg32;
148 
149  /* Assign VC1 id 1 */
150  RCBA32(0x20) = (RCBA32(0x20) & ~(0x7 << 24)) | (1 << 24);
151 
152  /* Map TC7 to VC1 */
153  RCBA8(0x20) &= 1;
154  RCBA8(0x20) |= 1 << 7;
155 
156  /* Map TC0 to VC0 */
157  RCBA8(0x14) &= 1;
158 
159  /* Init DMI VC1 port arbitration table */
160  RCBA32(0x20) &= 0xfff1ffff;
161  RCBA32(0x20) |= 1 << 19;
162 
163  RCBA32(0x30) = 0x0000000f;
164  RCBA32(0x34) = 0x000f0000;
165  RCBA32(0x38) = 0;
166  RCBA32(0x3c) = 0x000000f0;
167  RCBA32(0x40) = 0x0f000000;
168  RCBA32(0x44) = 0;
169  RCBA32(0x48) = 0x0000f000;
170  RCBA32(0x4c) = 0;
171  RCBA32(0x50) = 0x0000000f;
172  RCBA32(0x54) = 0x000f0000;
173  RCBA32(0x58) = 0;
174  RCBA32(0x5c) = 0x000000f0;
175  RCBA32(0x60) = 0x0f000000;
176  RCBA32(0x64) = 0;
177  RCBA32(0x68) = 0x0000f000;
178  RCBA32(0x6c) = 0;
179 
180  RCBA32(0x20) |= 1 << 16;
181 
182  /* Enable VC1 */
183  RCBA32(0x20) |= 1 << 31;
184 
185  /* Wait for VC1 */
186  while ((RCBA8(0x26) & (1 << 1)) != 0)
187  ;
188 
189  /* Wait for table load */
190  while ((RCBA8(0x26) & (1 << 0)) != 0)
191  ;
192 
193  /* ASPM on DMI link */
194  RCBA16(0x1a8) &= ~0x3;
195  /* FIXME: Do we need to read RCBA16(0x1a8)? */
196  RCBA16(0x1a8);
197  RCBA32(0x2010) = (RCBA32(0x2010) & ~(0x3 << 10)) | (1 << 10);
198  /* FIXME: Do we need to read RCBA32(0x2010)? */
199  RCBA32(0x2010);
200 
201  /* Set up VC1 max time */
202  RCBA32(0x1c) = (RCBA32(0x1c) & ~0x7f0000) | 0x120000;
203 
204  while ((dmibar_read32(DMIVC1RSTS) & VC1NP) != 0)
205  ;
206  printk(BIOS_DEBUG, "Done DMI setup\n");
207 
208  /* ASPM on DMI */
209  dmibar_clrbits32(0x200, 3 << 26);
210  dmibar_clrsetbits16(0x210, 0xff7, 0x101);
213  /* FIXME: Do we need to read RCBA16(DMILCTL)? Probably not. */
215 }
216 
217 void x4x_late_init(void)
218 {
219  init_egress();
220  init_dmi();
221 }
#define printk(level,...)
Definition: stdlib.h:16
#define D0F0_PAM(x)
Definition: mainboard.c:13
static __always_inline void dmibar_write8(const uintptr_t offset, const uint8_t value)
Definition: fixed_bars.h:81
static __always_inline uint32_t epbar_read32(const uintptr_t offset)
Definition: fixed_bars.h:131
static __always_inline void epbar_clrsetbits32(uintptr_t offset, uint32_t clear, uint32_t set)
Definition: fixed_bars.h:161
#define dmibar_clrbits32(addr, clear)
Definition: fixed_bars.h:117
static __always_inline void epbar_clrsetbits8(uintptr_t offset, uint8_t clear, uint8_t set)
Definition: fixed_bars.h:151
static __always_inline uint32_t dmibar_read32(const uintptr_t offset)
Definition: fixed_bars.h:76
static __always_inline void dmibar_write32(const uintptr_t offset, const uint32_t value)
Definition: fixed_bars.h:91
static __always_inline uint16_t dmibar_read16(const uintptr_t offset)
Definition: fixed_bars.h:71
#define mchbar_setbits8(addr, set)
Definition: fixed_bars.h:56
#define dmibar_setbits32(addr, set)
Definition: fixed_bars.h:113
static __always_inline uint32_t mchbar_read32(const uintptr_t offset)
Definition: fixed_bars.h:21
static __always_inline void epbar_write8(const uintptr_t offset, const uint8_t value)
Definition: fixed_bars.h:136
static __always_inline uint8_t epbar_read8(const uintptr_t offset)
Definition: fixed_bars.h:121
static __always_inline void dmibar_clrsetbits16(uintptr_t offset, uint16_t clear, uint16_t set)
Definition: fixed_bars.h:101
static __always_inline void epbar_write32(const uintptr_t offset, const uint32_t value)
Definition: fixed_bars.h:146
#define epbar_setbits32(addr, set)
Definition: fixed_bars.h:168
#define EPPVCCTL
Definition: gm45.h:372
#define EPVC0RCTL
Definition: gm45.h:375
#define VC1NP
Definition: gm45.h:354
#define CLKCFG_MCHBAR
Definition: gm45.h:229
#define DMIVC0RCTL
Definition: gm45.h:347
#define EPPVCCAP1
Definition: gm45.h:371
#define DMIPVCCAP1
Definition: gm45.h:344
#define DMIVC1RSTS
Definition: gm45.h:353
#define D0F0_EPBAR_LO
Definition: gm45.h:172
#define CLKCFG_FSBCLK_MASK
Definition: gm45.h:231
#define EPVC1RCTL
Definition: gm45.h:379
#define EPVC1ITC
Definition: gm45.h:383
#define DMILCTL
Definition: gm45.h:364
#define D0F0_MCHBAR_LO
Definition: gm45.h:174
#define DMIVC1RCTL
Definition: gm45.h:352
#define EPVC1RCAP
Definition: gm45.h:378
#define EPVC1MTS
Definition: gm45.h:382
#define D0F0_DMIBAR_LO
Definition: gm45.h:180
#define EP_PORTARB(x)
Definition: gm45.h:394
#define D0F0_DEVEN
Definition: gm45.h:177
#define D0F0_GGC
Definition: gm45.h:176
#define EPVC1RSTS
Definition: gm45.h:380
#define D0F0_CAPID0
Definition: gm45.h:192
#define DMIUESTS
Definition: dmibar.h:46
#define DMICESTS
Definition: dmibar.h:47
#define BOARD_DEVEN
Definition: i945.h:42
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
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 BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void x4x_early_init(void)
Definition: early_init.c:14
static void init_dmi(void)
Definition: early_init.c:119
static void init_egress(void)
Definition: early_init.c:56
void x4x_late_init(void)
Definition: early_init.c:217
#define DEFAULT_HECIBAR
Definition: memmap.h:6
unsigned int get_uint_option(const char *name, const unsigned int fallback)
Definition: option.c:116
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
@ HOST_BRIDGE
Definition: reg_access.h:23
#define RCBA16(x)
Definition: rcba.h:13
#define RCBA8(x)
Definition: rcba.h:12
#define RCBA32(x)
Definition: rcba.h:14
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
#define D1EN
Definition: host_bridge.h:13
#define D0EN
Definition: host_bridge.h:12
#define PEG1EN
Definition: host_bridge.h:20