blob: 173af1bc5c0e6b7dc59413708fa1cf47c6140961 [file] [log] [blame]
Angel Pons4b429832020-04-02 23:48:50 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Patrick Georgi2efc8802012-11-06 11:03:53 +01003
4#include <stdint.h>
5#include <stddef.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Patrick Georgi2efc8802012-11-06 11:03:53 +01007#include <device/pci_def.h>
8#include <console/console.h>
Kyösti Mälkkicbf95712020-01-05 08:05:45 +02009#include <option.h>
Patrick Georgi2efc8802012-11-06 11:03:53 +010010
11#include "gm45.h"
12
13/* TODO: Chipset supports Protected Audio Video Path (PAVP) */
14
15/* TODO: We could pass DVMT structure in GetBIOSData() SCI interface */
16
17/* The PEG settings have to be set before ASPM is setup on DMI. */
18static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
19{
Furquan Shaikh25f75b22016-08-29 22:51:41 -070020 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
21 const pci_devfn_t peg_dev = PCI_DEV(0, 1, 0);
22 const pci_devfn_t igd_dev = PCI_DEV(0, 2, 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +010023
24 u16 reg16;
25 u32 reg32;
26
27 printk(BIOS_DEBUG, "Enabling IGD.\n");
28
29 /* HSync/VSync */
30 MCHBAR8(0xbd0 + 3) = 0x5a;
31 MCHBAR8(0xbd0 + 4) = 0x5a;
32
33 static const u16 display_clock_from_f0_and_vco[][4] = {
34 /* VCO 2666 VCO 3200 VCO 4000 VCO 5333 */
35 { 222, 228, 222, 222, },
36 { 333, 320, 333, 333, },
37 };
38 const int f0_12 = (pci_read_config16(igd_dev, 0xf0) >> 12) & 1;
39 const int vco = raminit_read_vco_index();
40 reg16 = pci_read_config16(igd_dev, 0xcc);
41 reg16 &= 0xfc00;
42 reg16 |= display_clock_from_f0_and_vco[f0_12][vco];
43 pci_write_config16(igd_dev, 0xcc, reg16);
44
Patrick Georgi2efc8802012-11-06 11:03:53 +010045 reg16 = pci_read_config16(mch_dev, D0F0_GGC);
46 reg16 &= 0xf00f;
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +020047 reg16 |= sysinfo->ggc;
Patrick Georgi2efc8802012-11-06 11:03:53 +010048 pci_write_config16(mch_dev, D0F0_GGC, reg16);
49
50 if ((sysinfo->gfx_type != GMCH_GL40) &&
51 (sysinfo->gfx_type != GMCH_GS40) &&
52 (sysinfo->gfx_type != GMCH_GL43)) {
53 const u32 deven = pci_read_config32(mch_dev, D0F0_DEVEN);
54 if (!(deven & 2))
55 /* Enable PEG temporarily to access D1:F0. */
56 pci_write_config32(mch_dev, D0F0_DEVEN, deven | 2);
57
58 /* Some IGD related settings on D1:F0. */
59 reg16 = pci_read_config16(peg_dev, 0xa08);
60 reg16 &= ~(1 << 15);
61 pci_write_config16(peg_dev, 0xa08, reg16);
62
63 reg16 = pci_read_config16(peg_dev, 0xa84);
64 reg16 |= (1 << 8);
65 pci_write_config16(peg_dev, 0xa84, reg16);
66
67 reg16 = pci_read_config16(peg_dev, 0xb00);
68 reg16 |= (3 << 8) | (7 << 3);
69 pci_write_config16(peg_dev, 0xb00, reg16);
70
71 reg32 = pci_read_config32(peg_dev, 0xb14);
72 reg32 &= ~(1 << 17);
73 pci_write_config32(peg_dev, 0xb14, reg32);
74
75 if (!(deven & 2) || no_peg) {
76 /* Disable PEG finally. */
77 printk(BIOS_DEBUG, "Finally disabling "
78 "PEG in favor of IGD.\n");
79 MCHBAR8(0xc14) |= (1 << 5) | (1 << 0);
80
81 reg32 = pci_read_config32(peg_dev, 0x200);
82 reg32 |= (1 << 18);
83 pci_write_config32(peg_dev, 0x200, reg32);
84 reg16 = pci_read_config16(peg_dev, 0x224);
85 reg16 |= (1 << 8);
86 pci_write_config16(peg_dev, 0x224, reg16);
87 reg32 = pci_read_config32(peg_dev, 0x200);
88 reg32 &= ~(1 << 18);
89 pci_write_config32(peg_dev, 0x200, reg32);
90 while (pci_read_config32(peg_dev, 0x214) & 0x000f0000);
91
92 pci_write_config32(mch_dev, D0F0_DEVEN, deven & ~2);
93 MCHBAR8(0xc14) &= ~((1 << 5) | (1 << 0));
94 }
95 }
96}
97
98static void disable_igd(const sysinfo_t *const sysinfo)
99{
Furquan Shaikh25f75b22016-08-29 22:51:41 -0700100 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +0100101
102 printk(BIOS_DEBUG, "Disabling IGD.\n");
103
104 u16 reg16;
105
106 reg16 = pci_read_config16(mch_dev, D0F0_GGC);
107 reg16 &= 0xff0f; /* Disable Graphics Stolen Memory. */
108 reg16 |= 0x0002; /* Disable IGD. */
109 pci_write_config16(mch_dev, D0F0_GGC, reg16);
110 MCHBAR8(0xf10) |= (1 << 0);
111
112 if (!(pci_read_config8(mch_dev, D0F0_CAPID0 + 4) & (1 << (33 - 32)))) {
113 MCHBAR16(0x1190) |= (1 << 14);
114 MCHBAR16(0x119e) = (MCHBAR16(0x119e) & ~(7 << 13)) | (4 << 13);
115 MCHBAR16(0x119e) |= (1 << 12);
116 }
Patrick Rudolphbb1af992017-01-21 10:43:52 +0100117
118 /* Hide IGD. */
119 u32 deven = pci_read_config32(mch_dev, D0F0_DEVEN);
120 deven &= ~(3 << 3);
121 pci_write_config32(mch_dev, D0F0_DEVEN, deven);
Patrick Georgi2efc8802012-11-06 11:03:53 +0100122}
123
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200124void init_igd(const sysinfo_t *const sysinfo)
Patrick Georgi2efc8802012-11-06 11:03:53 +0100125{
Furquan Shaikh25f75b22016-08-29 22:51:41 -0700126 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +0100127
128 const u8 capid = pci_read_config8(mch_dev, D0F0_CAPID0 + 4);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200129 if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
Patrick Georgi2efc8802012-11-06 11:03:53 +0100130 disable_igd(sysinfo);
131 else
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200132 enable_igd(sysinfo, !sysinfo->enable_peg);
133}
134
135void igd_compute_ggc(sysinfo_t *const sysinfo)
136{
Furquan Shaikh25f75b22016-08-29 22:51:41 -0700137 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200138
139 const u32 capid = pci_read_config32(mch_dev, D0F0_CAPID0 + 4);
140 if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
141 sysinfo->ggc = 0x0002;
142 else {
Elyes HAOUAS2119d0b2020-02-16 10:01:33 +0100143 /* 4 for 32MB, default if not set in CMOS */
Arthur Heymansd65ff222017-06-13 20:57:05 +0200144 u8 gfxsize = 4;
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200145
146 /* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
147 2MB GTT + 2MB shadow GTT (0x0b00) else. */
Arthur Heymansd65ff222017-06-13 20:57:05 +0200148 get_option(&gfxsize, "gfx_uma_size");
Elyes HAOUAS2119d0b2020-02-16 10:01:33 +0100149 /* Handle invalid CMOS settings */
Arthur Heymansd65ff222017-06-13 20:57:05 +0200150 /* Only allow settings between 32MB and 352MB */
151 gfxsize = MIN(MAX(gfxsize, 4), 12);
152
Arthur Heymans7afcfe02016-05-19 15:34:49 +0200153 sysinfo->ggc = 0x0300 | ((gfxsize + 1) << 4);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200154 if (!(capid & (1 << (48 - 32))))
155 sysinfo->ggc |= 0x0800;
156 }
Patrick Georgi2efc8802012-11-06 11:03:53 +0100157}