blob: 7b0b1e56994083e236381ad0f5e91e43f5f52a51 [file] [log] [blame]
Angel Pons4b429832020-04-02 23:48:50 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Georgi2efc8802012-11-06 11:03:53 +01002
3#include <stdint.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02004#include <device/pci_ops.h>
Patrick Georgi2efc8802012-11-06 11:03:53 +01005#include <device/pci_def.h>
6#include <console/console.h>
Kyösti Mälkkicbf95712020-01-05 08:05:45 +02007#include <option.h>
Patrick Georgi2efc8802012-11-06 11:03:53 +01008
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. */
16static void enable_igd(const sysinfo_t *const sysinfo, const int no_peg)
17{
Furquan Shaikh25f75b22016-08-29 22:51:41 -070018 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);
Patrick Georgi2efc8802012-11-06 11:03:53 +010021
Patrick Georgi2efc8802012-11-06 11:03:53 +010022 printk(BIOS_DEBUG, "Enabling IGD.\n");
23
24 /* HSync/VSync */
Angel Pons3f1f8ef2021-03-27 13:52:43 +010025 mchbar_write8(0xbd0 + 3, 0x5a);
26 mchbar_write8(0xbd0 + 4, 0x5a);
Patrick Georgi2efc8802012-11-06 11:03:53 +010027
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();
Patrick Georgi2efc8802012-11-06 11:03:53 +010035
Angel Ponsb0535832020-06-08 11:46:58 +020036 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);
Patrick Georgi2efc8802012-11-06 11:03:53 +010039
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. */
Angel Ponsb0535832020-06-08 11:46:58 +020049 pci_and_config16(peg_dev, 0xa08, (u16)~(1 << 15));
Patrick Georgi2efc8802012-11-06 11:03:53 +010050
Angel Ponsb0535832020-06-08 11:46:58 +020051 pci_or_config16(peg_dev, 0xa84, 1 << 8);
Patrick Georgi2efc8802012-11-06 11:03:53 +010052
Angel Ponsb0535832020-06-08 11:46:58 +020053 pci_or_config16(peg_dev, 0xb00, (3 << 8) | (7 << 3));
Patrick Georgi2efc8802012-11-06 11:03:53 +010054
Angel Ponsb0535832020-06-08 11:46:58 +020055 pci_and_config32(peg_dev, 0xb14, ~(1 << 17));
Patrick Georgi2efc8802012-11-06 11:03:53 +010056
57 if (!(deven & 2) || no_peg) {
58 /* Disable PEG finally. */
59 printk(BIOS_DEBUG, "Finally disabling "
60 "PEG in favor of IGD.\n");
Angel Pons3f1f8ef2021-03-27 13:52:43 +010061 mchbar_setbits8(0xc14, 1 << 5 | 1 << 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +010062
Angel Ponsb0535832020-06-08 11:46:58 +020063 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 ;
Patrick Georgi2efc8802012-11-06 11:03:53 +010071
72 pci_write_config32(mch_dev, D0F0_DEVEN, deven & ~2);
Angel Pons3f1f8ef2021-03-27 13:52:43 +010073 mchbar_clrbits8(0xc14, 1 << 5 | 1 << 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +010074 }
75 }
76}
77
78static void disable_igd(const sysinfo_t *const sysinfo)
79{
Furquan Shaikh25f75b22016-08-29 22:51:41 -070080 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +010081
82 printk(BIOS_DEBUG, "Disabling IGD.\n");
83
Angel Ponsb0535832020-06-08 11:46:58 +020084 /* Disable Graphics Stolen Memory. */
85 pci_update_config16(mch_dev, D0F0_GGC, 0xff0f, 0x0002);
Patrick Georgi2efc8802012-11-06 11:03:53 +010086
Angel Pons3f1f8ef2021-03-27 13:52:43 +010087 mchbar_setbits8(0xf10, 1 << 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +010088
89 if (!(pci_read_config8(mch_dev, D0F0_CAPID0 + 4) & (1 << (33 - 32)))) {
Angel Pons3f1f8ef2021-03-27 13:52:43 +010090 mchbar_setbits16(0x1190, 1 << 14);
91 mchbar_clrsetbits16(0x119e, 7 << 13, 4 << 13);
92 mchbar_setbits16(0x119e, 1 << 12);
Patrick Georgi2efc8802012-11-06 11:03:53 +010093 }
Patrick Rudolphbb1af992017-01-21 10:43:52 +010094
95 /* Hide IGD. */
Angel Ponsb0535832020-06-08 11:46:58 +020096 pci_and_config32(mch_dev, D0F0_DEVEN, ~(3 << 3));
Patrick Georgi2efc8802012-11-06 11:03:53 +010097}
98
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +020099void init_igd(const sysinfo_t *const sysinfo)
Patrick Georgi2efc8802012-11-06 11:03:53 +0100100{
Furquan Shaikh25f75b22016-08-29 22:51:41 -0700101 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Patrick Georgi2efc8802012-11-06 11:03:53 +0100102
103 const u8 capid = pci_read_config8(mch_dev, D0F0_CAPID0 + 4);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200104 if (!sysinfo->enable_igd || (capid & (1 << (33 - 32))))
Patrick Georgi2efc8802012-11-06 11:03:53 +0100105 disable_igd(sysinfo);
106 else
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200107 enable_igd(sysinfo, !sysinfo->enable_peg);
108}
109
110void igd_compute_ggc(sysinfo_t *const sysinfo)
111{
Furquan Shaikh25f75b22016-08-29 22:51:41 -0700112 const pci_devfn_t mch_dev = PCI_DEV(0, 0, 0);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200113
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 {
Elyes HAOUAS2119d0b2020-02-16 10:01:33 +0100118 /* 4 for 32MB, default if not set in CMOS */
Angel Pons88dcb312021-04-26 17:10:28 +0200119 u8 gfxsize = get_uint_option("gfx_uma_size", 4);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200120
121 /* Graphics Stolen Memory: 2MB GTT (0x0300) when VT-d disabled,
122 2MB GTT + 2MB shadow GTT (0x0b00) else. */
Angel Ponsf9c93902020-11-02 22:21:54 +0100123
Elyes HAOUAS2119d0b2020-02-16 10:01:33 +0100124 /* Handle invalid CMOS settings */
Arthur Heymansd65ff222017-06-13 20:57:05 +0200125 /* Only allow settings between 32MB and 352MB */
126 gfxsize = MIN(MAX(gfxsize, 4), 12);
127
Arthur Heymans7afcfe02016-05-19 15:34:49 +0200128 sysinfo->ggc = 0x0300 | ((gfxsize + 1) << 4);
Vladimir Serbinenko56ae8a02014-08-16 10:59:02 +0200129 if (!(capid & (1 << (48 - 32))))
130 sysinfo->ggc |= 0x0800;
131 }
Patrick Georgi2efc8802012-11-06 11:03:53 +0100132}