coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
igd.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 #include <device/pci_def.h>
6 #include <console/console.h>
7 #include <option.h>
8 
9 #include "gm45.h"
10 
11 /* TODO: Chipset supports Protected Audio Video Path (PAVP) */
12 
13 /* TODO: We could pass DVMT structure in GetBIOSData() SCI interface */
14 
15 /* The PEG settings have to be set before ASPM is setup on DMI. */
16 static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
17 {
18  const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
19  const pci_devfn_t peg_dev = PCI_DEV(0, 1, 0);
20  const pci_devfn_t igd_dev = PCI_DEV(0, 2, 0);
21 
22  printk(BIOS_DEBUG, "Enabling IGD.\n");
23 
24  /* HSync/VSync */
25  mchbar_write8(0xbd0 + 3, 0x5a);
26  mchbar_write8(0xbd0 + 4, 0x5a);
27 
28  static const u16 display_clock_from_f0_and_vco[][4] = {
29  /* VCO 2666 VCO 3200 VCO 4000 VCO 5333 */
30  { 222, 228, 222, 222, },
31  { 333, 320, 333, 333, },
32  };
33  const int f0_12 = (pci_read_config16(igd_dev, 0xf0) >> 12) & 1;
34  const int vco = raminit_read_vco_index();
35 
36  pci_update_config16(igd_dev, 0xcc, 0xfc00, display_clock_from_f0_and_vco[f0_12][vco]);
37 
38  pci_update_config16(mch_dev, D0F0_GGC, 0xf00f, sysinfo->ggc);
39 
40  if ((sysinfo->gfx_type != GMCH_GL40) &&
41  (sysinfo->gfx_type != GMCH_GS40) &&
42  (sysinfo->gfx_type != GMCH_GL43)) {
43  const u32 deven = pci_read_config32(mch_dev, D0F0_DEVEN);
44  if (!(deven & 2))
45  /* Enable PEG temporarily to access D1:F0. */
46  pci_write_config32(mch_dev, D0F0_DEVEN, deven | 2);
47 
48  /* Some IGD related settings on D1:F0. */
49  pci_and_config16(peg_dev, 0xa08, (u16)~(1 << 15));
50 
51  pci_or_config16(peg_dev, 0xa84, 1 << 8);
52 
53  pci_or_config16(peg_dev, 0xb00, (3 << 8) | (7 << 3));
54 
55  pci_and_config32(peg_dev, 0xb14, ~(1 << 17));
56 
57  if (!(deven & 2) || no_peg) {
58  /* Disable PEG finally. */
59  printk(BIOS_DEBUG, "Finally disabling "
60  "PEG in favor of IGD.\n");
61  mchbar_setbits8(0xc14, 1 << 5 | 1 << 0);
62 
63  pci_or_config32(peg_dev, 0x200, 1 << 18);
64 
65  pci_or_config16(peg_dev, 0x224, 1 << 8);
66 
67  pci_and_config32(peg_dev, 0x200, ~(1 << 18));
68 
69  while (pci_read_config32(peg_dev, 0x214) & (0xf << 16))
70  ;
71 
72  pci_write_config32(mch_dev, D0F0_DEVEN, deven & ~2);
73  mchbar_clrbits8(0xc14, 1 << 5 | 1 << 0);
74  }
75  }
76 }
77 
78 static void disable_igd(const sysinfo_t *const sysinfo)
79 {
80  const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
81 
82  printk(BIOS_DEBUG, "Disabling IGD.\n");
83 
84  /* Disable Graphics Stolen Memory. */
85  pci_update_config16(mch_dev, D0F0_GGC, 0xff0f, 0x0002);
86 
87  mchbar_setbits8(0xf10, 1 << 0);
88 
89  if (!(pci_read_config8(mch_dev, D0F0_CAPID0 + 4) & (1 << (33 - 32)))) {
90  mchbar_setbits16(0x1190, 1 << 14);
91  mchbar_clrsetbits16(0x119e, 7 << 13, 4 << 13);
92  mchbar_setbits16(0x119e, 1 << 12);
93  }
94 
95  /* Hide IGD. */
96  pci_and_config32(mch_dev, D0F0_DEVEN, ~(3 << 3));
97 }
98 
99 void init_igd(const sysinfo_t *const sysinfo)
100 {
101  const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
102 
103  const u8 capid = pci_read_config8(mch_dev, D0F0_CAPID0 + 4);
104  if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
106  else
108 }
109 
111 {
112  const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
113 
114  const u32 capid = pci_read_config32(mch_dev, D0F0_CAPID0 + 4);
115  if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
116  sysinfo->ggc = 0x0002;
117  else {
118  /* 4 for 32MB, default if not set in CMOS */
119  u8 gfxsize = get_uint_option("gfx_uma_size", 4);
120 
121  /* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
122  2MB GTT + 2MB shadow GTT (0x0b00) else. */
123 
124  /* Handle invalid CMOS settings */
125  /* Only allow settings between 32MB and 352MB */
126  gfxsize = MIN(MAX(gfxsize, 4), 12);
127 
128  sysinfo->ggc = 0x0300 | ((gfxsize + 1) << 4);
129  if (!(capid & (1 << (48 - 32))))
130  sysinfo->ggc |= 0x0800;
131  }
132 }
#define MIN(a, b)
Definition: helpers.h:37
#define MAX(a, b)
Definition: helpers.h:40
#define printk(level,...)
Definition: stdlib.h:16
static __always_inline void mchbar_write8(const uintptr_t offset, const uint8_t value)
Definition: fixed_bars.h:26
#define mchbar_clrbits8(addr, clear)
Definition: fixed_bars.h:60
#define mchbar_setbits8(addr, set)
Definition: fixed_bars.h:56
static __always_inline void mchbar_clrsetbits16(uintptr_t offset, uint16_t clear, uint16_t set)
Definition: fixed_bars.h:46
#define mchbar_setbits16(addr, set)
Definition: fixed_bars.h:57
int raminit_read_vco_index(void)
Definition: raminit.c:733
@ GMCH_GS40
Definition: gm45.h:35
@ GMCH_GL40
Definition: gm45.h:33
@ GMCH_GL43
Definition: gm45.h:34
#define D0F0_DEVEN
Definition: gm45.h:177
#define D0F0_GGC
Definition: gm45.h:176
#define D0F0_CAPID0
Definition: gm45.h:192
void igd_compute_ggc(sysinfo_t *const sysinfo)
Definition: igd.c:110
static void disable_igd(const sysinfo_t *const sysinfo)
Definition: igd.c:78
void init_igd(const sysinfo_t *const sysinfo)
Definition: igd.c:99
static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
Definition: igd.c:16
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_and_config16(const struct device *dev, u16 reg, u16 andmask)
Definition: pci_ops.h:147
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
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_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Definition: pci_ops.h:104
static __always_inline void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
Definition: pci_ops.h:158
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
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
u32 pci_devfn_t
Definition: pci_type.h:8
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
int enable_peg
Definition: raminit.h:106
int enable_igd
Definition: raminit.h:105
u16 ggc
Definition: raminit.h:107