1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/pci_ops.h>
5 #include <device/pci_def.h>
6 #include <console/console.h>
11 /* TODO: Chipset supports Protected Audio Video Path (PAVP) */
13 /* TODO: We could pass DVMT structure in GetBIOSData() SCI interface */
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
)
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);
22 printk(BIOS_DEBUG
, "Enabling IGD.\n");
25 mchbar_write8(0xbd0 + 3, 0x5a);
26 mchbar_write8(0xbd0 + 4, 0x5a);
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, },
33 const int f0_12
= (pci_read_config16(igd_dev
, 0xf0) >> 12) & 1;
34 const int vco
= raminit_read_vco_index();
36 pci_update_config16(igd_dev
, 0xcc, 0xfc00, display_clock_from_f0_and_vco
[f0_12
][vco
]);
38 pci_update_config16(mch_dev
, D0F0_GGC
, 0xf00f, sysinfo
->ggc
);
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
);
45 /* Enable PEG temporarily to access D1:F0. */
46 pci_write_config32(mch_dev
, D0F0_DEVEN
, deven
| 2);
48 /* Some IGD related settings on D1:F0. */
49 pci_and_config16(peg_dev
, 0xa08, (u16
)~(1 << 15));
51 pci_or_config16(peg_dev
, 0xa84, 1 << 8);
53 pci_or_config16(peg_dev
, 0xb00, (3 << 8) | (7 << 3));
55 pci_and_config32(peg_dev
, 0xb14, ~(1 << 17));
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);
63 pci_or_config32(peg_dev
, 0x200, 1 << 18);
65 pci_or_config16(peg_dev
, 0x224, 1 << 8);
67 pci_and_config32(peg_dev
, 0x200, ~(1 << 18));
69 while (pci_read_config32(peg_dev
, 0x214) & (0xf << 16))
72 pci_write_config32(mch_dev
, D0F0_DEVEN
, deven
& ~2);
73 mchbar_clrbits8(0xc14, 1 << 5 | 1 << 0);
78 static void disable_igd(const sysinfo_t
*const sysinfo
)
80 const pci_devfn_t mch_dev
= PCI_DEV(0, 0, 0);
82 printk(BIOS_DEBUG
, "Disabling IGD.\n");
84 /* Disable Graphics Stolen Memory. */
85 pci_update_config16(mch_dev
, D0F0_GGC
, 0xff0f, 0x0002);
87 mchbar_setbits8(0xf10, 1 << 0);
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);
96 pci_and_config32(mch_dev
, D0F0_DEVEN
, ~(3 << 3));
99 void init_igd(const sysinfo_t
*const sysinfo
)
101 const pci_devfn_t mch_dev
= PCI_DEV(0, 0, 0);
103 const u8 capid
= pci_read_config8(mch_dev
, D0F0_CAPID0
+ 4);
104 if (!sysinfo
->enable_igd
|| (capid
& (1 << (33 - 32))))
105 disable_igd(sysinfo
);
107 enable_igd(sysinfo
, !sysinfo
->enable_peg
);
110 void igd_compute_ggc(sysinfo_t
*const sysinfo
)
112 const pci_devfn_t mch_dev
= PCI_DEV(0, 0, 0);
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;
118 /* 4 for 32MB, default if not set in CMOS */
119 u8 gfxsize
= get_uint_option("gfx_uma_size", 4);
121 /* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
122 2MB GTT + 2MB shadow GTT (0x0b00) else. */
124 /* Handle invalid CMOS settings */
125 /* Only allow settings between 32MB and 352MB */
126 gfxsize
= MIN(MAX(gfxsize
, 4), 12);
128 sysinfo
->ggc
= 0x0300 | ((gfxsize
+ 1) << 4);
129 if (!(capid
& (1 << (48 - 32))))
130 sysinfo
->ggc
|= 0x0800;