blob: d398b55347e661e0d698f6291c0eabde12ca5645 [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. */
Damien Zammit51fdb922016-01-18 18:34:52 +11003
4#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Damien Zammit51fdb922016-01-18 18:34:52 +11006#include <console/console.h>
7#include <delay.h>
8#include <device/device.h>
9#include <device/pci.h>
10#include <device/pci_ids.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110011#include <device/pci_ops.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110012#include <drivers/intel/gma/i915_reg.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110013#include <drivers/intel/gma/intel_bios.h>
14#include <drivers/intel/gma/i915.h>
Patrick Rudolphbb98b382017-09-30 09:13:53 +020015#include <drivers/intel/gma/opregion.h>
16#include <southbridge/intel/i82801gx/nvs.h>
17#include <cbmem.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110018#include <pc80/vga.h>
19#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020020#include <types.h>
21
22#include "chip.h"
23#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110024
Angel Pons39ff7032020-03-09 21:39:44 +010025#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110026
27#define PGETBL2_CTL 0x20c4
28#define PGETBL2_1MB (1 << 8)
29
30#define PGETBL_CTL 0x2020
31#define PGETBL_1MB (3 << 1)
32#define PGETBL_512KB 0
33#define PGETBL_ENABLED 0x1
34
35#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020036 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
37 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
38 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
39 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
40 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
41 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110042
Angel Pons39ff7032020-03-09 21:39:44 +010043static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110044static struct resource *mmio_res = NULL;
45
Patrick Rudolphbb98b382017-09-30 09:13:53 +020046uintptr_t gma_get_gnvs_aslb(const void *gnvs)
47{
48 const global_nvs_t *gnvs_ptr = gnvs;
49 return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0);
50}
51
52void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb)
53{
54 global_nvs_t *gnvs_ptr = gnvs;
55 if (gnvs_ptr)
56 gnvs_ptr->aslb = aslb;
57}
58
Damien Zammit51fdb922016-01-18 18:34:52 +110059static int gtt_setup(u8 *mmiobase)
60{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020061 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030062 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110063
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020064 gttbase = pci_read_config32(dev, BGSM);
65 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110066
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020067 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
68 udelay(50);
69 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110070
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020071 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110072
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020073 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110074}
75
76static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
77 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
78{
79 int i;
80 u32 hactive, vactive;
81 u32 temp;
82
83 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
84 (u32)gtt, (u32)mmio, piobase, physbase);
85
86 gtt_setup(mmio);
87
Elyes HAOUASef20ecc2018-10-04 13:50:14 +020088 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +110089
90 /* Disable VGA. */
91 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
92
93 /* Disable pipes. */
94 write32(mmio + PIPECONF(0), 0);
95 write32(mmio + PIPECONF(1), 0);
96
97 write32(mmio + INSTPM, 0x800);
98
99 vga_gr_write(0x18, 0);
100
101 write32(mmio + VGA0, 0x200074);
102 write32(mmio + VGA1, 0x200074);
103
104 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
105 write32(mmio + DSPCLK_GATE_D, 0);
106 write32(mmio + FW_BLC, 0x03060106);
107 write32(mmio + FW_BLC2, 0x00000306);
108
109 write32(mmio + ADPA, ADPA_DAC_ENABLE
110 | ADPA_PIPE_A_SELECT
111 | ADPA_HOTPLUG_BITS
112 | ADPA_USE_VGA_HVPOLARITY
113 | ADPA_VSYNC_CNTL_ENABLE
114 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100115 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100116
117 write32(mmio + 0x7041c, 0x0);
118
119 write32(mmio + DPLL_MD(0), 0x3);
120 write32(mmio + DPLL_MD(1), 0x3);
121 write32(mmio + DSPCNTR(1), 0x1000000);
122 write32(mmio + PIPESRC(1), 0x027f01df);
123
124 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100125 const u8 cr[25] = {
126 0x5f, 0x4f, 0x50, 0x82, 0x55,
127 0x81, 0xbf, 0x1f, 0x00, 0x4f,
128 0x0d, 0x0e, 0x00, 0x00, 0x00,
129 0x00, 0x9c, 0x8e, 0x8f, 0x28,
130 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100131 };
132 vga_cr_write(0x11, 0);
133
Angel Pons39ff7032020-03-09 21:39:44 +0100134 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100135 vga_cr_write(i, cr[i]);
136
137 // Disable screen memory to prevent garbage from appearing.
138 vga_sr_write(1, vga_sr_read(1) | 0x20);
139 hactive = 640;
140 vactive = 400;
141
142 mdelay(1);
143 write32(mmio + DPLL(0),
144 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
145 | DPLL_VGA_MODE_DIS
146 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100147 | 0x400601);
148
Damien Zammit51fdb922016-01-18 18:34:52 +1100149 mdelay(1);
150 write32(mmio + DPLL(0),
151 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
152 | DPLL_VGA_MODE_DIS
153 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100154 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100155
156 write32(mmio + ADPA, ADPA_DAC_ENABLE
157 | ADPA_PIPE_A_SELECT
158 | ADPA_HOTPLUG_BITS
159 | ADPA_USE_VGA_HVPOLARITY
160 | ADPA_VSYNC_CNTL_ENABLE
161 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100162 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100163
164 write32(mmio + HTOTAL(1), 0x031f027f);
165 write32(mmio + HBLANK(1), 0x03170287);
166 write32(mmio + HSYNC(1), 0x02ef028f);
167 write32(mmio + VTOTAL(1), 0x020c01df);
168 write32(mmio + VBLANK(1), 0x020401e7);
169 write32(mmio + VSYNC(1), 0x01eb01e9);
170
Angel Pons39ff7032020-03-09 21:39:44 +0100171 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
172 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
173 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
174 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
175 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
176 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100177
178 write32(mmio + PF_WIN_POS(0), 0);
179
180 write32(mmio + PIPESRC(0), (639 << 16) | 399);
181 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
182 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
183 write32(mmio + PFIT_CONTROL, 0x0);
184
185 mdelay(1);
186
187 write32(mmio + FDI_RX_CTL(0), 0x00002040);
188 mdelay(1);
189 write32(mmio + FDI_RX_CTL(0), 0x80002050);
190 write32(mmio + FDI_TX_CTL(0), 0x00044000);
191 mdelay(1);
192 write32(mmio + FDI_TX_CTL(0), 0x80044000);
193 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
194
195 write32(mmio + VGACNTRL, 0x0);
196 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
197 mdelay(1);
198
199 write32(mmio + ADPA, ADPA_DAC_ENABLE
200 | ADPA_PIPE_A_SELECT
201 | ADPA_HOTPLUG_BITS
202 | ADPA_USE_VGA_HVPOLARITY
203 | ADPA_VSYNC_CNTL_ENABLE
204 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100205 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100206
207 write32(mmio + DSPFW3, 0x7f3f00c1);
208 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
209 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
210 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
211
212 for (i = 0; i < (8192 - 512) / 4; i++) {
213 outl((i << 2) | 1, piobase);
214 outl(physbase + (i << 12) + 1, piobase + 4);
215 }
216
217 temp = read32(mmio + PGETBL_CTL);
218 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
219 temp = read32(mmio + PGETBL2_CTL);
220 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
221
Angel Pons39ff7032020-03-09 21:39:44 +0100222 /* Clear interrupts */
223 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100224 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100225 write32(mmio + IIR, 0xffffffff);
226 write32(mmio + IMR, 0xffffffff);
227 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100228
229 vga_textmode_init();
230
Angel Pons39ff7032020-03-09 21:39:44 +0100231 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100232 vga_sr_write(1, vga_sr_read(1) & ~0x20);
233}
234
235static void gma_func0_init(struct device *dev)
236{
237 u32 reg32;
238
239 /* IGD needs to be Bus Master */
240 reg32 = pci_read_config32(dev, PCI_COMMAND);
241 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
242 pci_write_config32(dev, PCI_COMMAND, reg32);
243
Julius Wernercd49cce2019-03-05 16:53:33 -0800244 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100245 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100246 pci_dev_init(dev);
247 } else {
248 u32 physbase;
249 struct resource *pio_res;
250 struct northbridge_intel_pineview_config *conf = dev->chip_info;
251
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200252 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
253
Damien Zammit51fdb922016-01-18 18:34:52 +1100254 /* Find base addresses */
255 mmio_res = find_resource(dev, 0x10);
Angel Pons39ff7032020-03-09 21:39:44 +0100256 gtt_res = find_resource(dev, 0x1c);
257 pio_res = find_resource(dev, 0x14);
Damien Zammit51fdb922016-01-18 18:34:52 +1100258 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
259
260 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200261 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100262 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
263 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200264 } else {
265 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
266 mmio_res->base);
267 intel_gma_init(conf, dev,
268 res2mmio(mmio_res, 0, 0),
269 res2mmio(gtt_res, 0, 0),
270 physbase, pio_res->base);
271 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100272 }
273
274 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200275 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100276 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200277
278 intel_gma_restore_opregion();
Damien Zammit51fdb922016-01-18 18:34:52 +1100279}
280
Angel Pons39ff7032020-03-09 21:39:44 +0100281static unsigned long gma_write_acpi_tables(struct device *const dev, unsigned long current,
282 struct acpi_rsdp *const rsdp)
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200283{
284 igd_opregion_t *opregion = (igd_opregion_t *)current;
285 global_nvs_t *gnvs;
286
287 if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
288 return current;
289
290 current += sizeof(igd_opregion_t);
291
292 /* GNVS has been already set up */
293 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
294 if (gnvs) {
295 /* IGD OpRegion Base Address */
296 gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
297 } else {
298 printk(BIOS_ERR, "Error: GNVS table not found.\n");
299 }
300
301 current = acpi_align_current(current);
302 return current;
303}
304
305static const char *gma_acpi_name(const struct device *dev)
306{
307 return "GFX0";
308}
309
Damien Zammit51fdb922016-01-18 18:34:52 +1100310static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530311 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100312};
313
314static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200315 .read_resources = pci_dev_read_resources,
316 .set_resources = pci_dev_set_resources,
317 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200318 .init = gma_func0_init,
Nico Huber68680dd2020-03-31 17:34:52 +0200319 .ops_pci = &gma_pci_ops,
320 .acpi_name = gma_acpi_name,
321 .write_acpi_tables = gma_write_acpi_tables,
Damien Zammit51fdb922016-01-18 18:34:52 +1100322};
323
324static const unsigned short pci_device_ids[] =
325{
Angel Pons39ff7032020-03-09 21:39:44 +0100326 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100327};
328
329static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100330 .ops = &gma_func0_ops,
331 .vendor = PCI_VENDOR_ID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100332 .devices = pci_device_ids,
333};