blob: db2bb825b736bc43ee7646d49548e19be34b529b [file] [log] [blame]
Damien Zammit51fdb922016-01-18 18:34:52 +11001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 Chromium OS Authors
5 * Copyright (C) 2013 Vladimir Serbinenko
6 * Copyright (C) 2015 Damien Zammit <damien@zamaudio.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020019#include <device/mmio.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110020#include <console/console.h>
21#include <delay.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110025#include <device/pci_ops.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110026#include <drivers/intel/gma/i915_reg.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110027#include <drivers/intel/gma/intel_bios.h>
28#include <drivers/intel/gma/i915.h>
Patrick Rudolphbb98b382017-09-30 09:13:53 +020029#include <drivers/intel/gma/opregion.h>
30#include <southbridge/intel/i82801gx/nvs.h>
31#include <cbmem.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110032#include <pc80/vga.h>
33#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020034#include <types.h>
35
36#include "chip.h"
37#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110038
Angel Pons39ff7032020-03-09 21:39:44 +010039#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110040
41#define PGETBL2_CTL 0x20c4
42#define PGETBL2_1MB (1 << 8)
43
44#define PGETBL_CTL 0x2020
45#define PGETBL_1MB (3 << 1)
46#define PGETBL_512KB 0
47#define PGETBL_ENABLED 0x1
48
49#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020050 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
51 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
52 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
53 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
54 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
55 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110056
Angel Pons39ff7032020-03-09 21:39:44 +010057static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110058static struct resource *mmio_res = NULL;
59
Patrick Rudolphbb98b382017-09-30 09:13:53 +020060uintptr_t gma_get_gnvs_aslb(const void *gnvs)
61{
62 const global_nvs_t *gnvs_ptr = gnvs;
63 return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0);
64}
65
66void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb)
67{
68 global_nvs_t *gnvs_ptr = gnvs;
69 if (gnvs_ptr)
70 gnvs_ptr->aslb = aslb;
71}
72
Damien Zammit51fdb922016-01-18 18:34:52 +110073static int gtt_setup(u8 *mmiobase)
74{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020075 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030076 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110077
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020078 gttbase = pci_read_config32(dev, BGSM);
79 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110080
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020081 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
82 udelay(50);
83 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110084
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020085 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110086
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020087 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110088}
89
90static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
91 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
92{
93 int i;
94 u32 hactive, vactive;
95 u32 temp;
96
97 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
98 (u32)gtt, (u32)mmio, piobase, physbase);
99
100 gtt_setup(mmio);
101
Elyes HAOUASef20ecc2018-10-04 13:50:14 +0200102 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +1100103
104 /* Disable VGA. */
105 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
106
107 /* Disable pipes. */
108 write32(mmio + PIPECONF(0), 0);
109 write32(mmio + PIPECONF(1), 0);
110
111 write32(mmio + INSTPM, 0x800);
112
113 vga_gr_write(0x18, 0);
114
115 write32(mmio + VGA0, 0x200074);
116 write32(mmio + VGA1, 0x200074);
117
118 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
119 write32(mmio + DSPCLK_GATE_D, 0);
120 write32(mmio + FW_BLC, 0x03060106);
121 write32(mmio + FW_BLC2, 0x00000306);
122
123 write32(mmio + ADPA, ADPA_DAC_ENABLE
124 | ADPA_PIPE_A_SELECT
125 | ADPA_HOTPLUG_BITS
126 | ADPA_USE_VGA_HVPOLARITY
127 | ADPA_VSYNC_CNTL_ENABLE
128 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100129 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100130
131 write32(mmio + 0x7041c, 0x0);
132
133 write32(mmio + DPLL_MD(0), 0x3);
134 write32(mmio + DPLL_MD(1), 0x3);
135 write32(mmio + DSPCNTR(1), 0x1000000);
136 write32(mmio + PIPESRC(1), 0x027f01df);
137
138 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100139 const u8 cr[25] = {
140 0x5f, 0x4f, 0x50, 0x82, 0x55,
141 0x81, 0xbf, 0x1f, 0x00, 0x4f,
142 0x0d, 0x0e, 0x00, 0x00, 0x00,
143 0x00, 0x9c, 0x8e, 0x8f, 0x28,
144 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100145 };
146 vga_cr_write(0x11, 0);
147
Angel Pons39ff7032020-03-09 21:39:44 +0100148 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100149 vga_cr_write(i, cr[i]);
150
151 // Disable screen memory to prevent garbage from appearing.
152 vga_sr_write(1, vga_sr_read(1) | 0x20);
153 hactive = 640;
154 vactive = 400;
155
156 mdelay(1);
157 write32(mmio + DPLL(0),
158 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
159 | DPLL_VGA_MODE_DIS
160 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100161 | 0x400601);
162
Damien Zammit51fdb922016-01-18 18:34:52 +1100163 mdelay(1);
164 write32(mmio + DPLL(0),
165 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
166 | DPLL_VGA_MODE_DIS
167 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100168 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100169
170 write32(mmio + ADPA, ADPA_DAC_ENABLE
171 | ADPA_PIPE_A_SELECT
172 | ADPA_HOTPLUG_BITS
173 | ADPA_USE_VGA_HVPOLARITY
174 | ADPA_VSYNC_CNTL_ENABLE
175 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100176 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100177
178 write32(mmio + HTOTAL(1), 0x031f027f);
179 write32(mmio + HBLANK(1), 0x03170287);
180 write32(mmio + HSYNC(1), 0x02ef028f);
181 write32(mmio + VTOTAL(1), 0x020c01df);
182 write32(mmio + VBLANK(1), 0x020401e7);
183 write32(mmio + VSYNC(1), 0x01eb01e9);
184
Angel Pons39ff7032020-03-09 21:39:44 +0100185 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
186 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
187 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
188 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
189 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
190 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100191
192 write32(mmio + PF_WIN_POS(0), 0);
193
194 write32(mmio + PIPESRC(0), (639 << 16) | 399);
195 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
196 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
197 write32(mmio + PFIT_CONTROL, 0x0);
198
199 mdelay(1);
200
201 write32(mmio + FDI_RX_CTL(0), 0x00002040);
202 mdelay(1);
203 write32(mmio + FDI_RX_CTL(0), 0x80002050);
204 write32(mmio + FDI_TX_CTL(0), 0x00044000);
205 mdelay(1);
206 write32(mmio + FDI_TX_CTL(0), 0x80044000);
207 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
208
209 write32(mmio + VGACNTRL, 0x0);
210 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
211 mdelay(1);
212
213 write32(mmio + ADPA, ADPA_DAC_ENABLE
214 | ADPA_PIPE_A_SELECT
215 | ADPA_HOTPLUG_BITS
216 | ADPA_USE_VGA_HVPOLARITY
217 | ADPA_VSYNC_CNTL_ENABLE
218 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100219 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100220
221 write32(mmio + DSPFW3, 0x7f3f00c1);
222 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
223 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
224 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
225
226 for (i = 0; i < (8192 - 512) / 4; i++) {
227 outl((i << 2) | 1, piobase);
228 outl(physbase + (i << 12) + 1, piobase + 4);
229 }
230
231 temp = read32(mmio + PGETBL_CTL);
232 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
233 temp = read32(mmio + PGETBL2_CTL);
234 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
235
Angel Pons39ff7032020-03-09 21:39:44 +0100236 /* Clear interrupts */
237 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100238 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100239 write32(mmio + IIR, 0xffffffff);
240 write32(mmio + IMR, 0xffffffff);
241 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100242
243 vga_textmode_init();
244
Angel Pons39ff7032020-03-09 21:39:44 +0100245 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100246 vga_sr_write(1, vga_sr_read(1) & ~0x20);
247}
248
249static void gma_func0_init(struct device *dev)
250{
251 u32 reg32;
252
253 /* IGD needs to be Bus Master */
254 reg32 = pci_read_config32(dev, PCI_COMMAND);
255 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
256 pci_write_config32(dev, PCI_COMMAND, reg32);
257
Julius Wernercd49cce2019-03-05 16:53:33 -0800258 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100259 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100260 pci_dev_init(dev);
261 } else {
262 u32 physbase;
263 struct resource *pio_res;
264 struct northbridge_intel_pineview_config *conf = dev->chip_info;
265
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200266 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
267
Damien Zammit51fdb922016-01-18 18:34:52 +1100268 /* Find base addresses */
269 mmio_res = find_resource(dev, 0x10);
Angel Pons39ff7032020-03-09 21:39:44 +0100270 gtt_res = find_resource(dev, 0x1c);
271 pio_res = find_resource(dev, 0x14);
Damien Zammit51fdb922016-01-18 18:34:52 +1100272 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
273
274 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200275 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100276 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
277 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200278 } else {
279 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
280 mmio_res->base);
281 intel_gma_init(conf, dev,
282 res2mmio(mmio_res, 0, 0),
283 res2mmio(gtt_res, 0, 0),
284 physbase, pio_res->base);
285 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100286 }
287
288 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200289 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100290 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200291
292 intel_gma_restore_opregion();
Damien Zammit51fdb922016-01-18 18:34:52 +1100293}
294
Damien Zammit51fdb922016-01-18 18:34:52 +1100295const struct i915_gpu_controller_info *intel_gma_get_controller_info(void)
296{
Angel Pons39ff7032020-03-09 21:39:44 +0100297 struct device *dev = pcidev_on_root(2, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +1100298 if (!dev) {
299 printk(BIOS_WARNING, "WARNING: Can't find IGD (0,2,0)\n");
300 return NULL;
301 }
302 struct northbridge_intel_pineview_config *chip = dev->chip_info;
303 return &chip->gfx;
304}
305
Angel Pons39ff7032020-03-09 21:39:44 +0100306static unsigned long gma_write_acpi_tables(struct device *const dev, unsigned long current,
307 struct acpi_rsdp *const rsdp)
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200308{
309 igd_opregion_t *opregion = (igd_opregion_t *)current;
310 global_nvs_t *gnvs;
311
312 if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
313 return current;
314
315 current += sizeof(igd_opregion_t);
316
317 /* GNVS has been already set up */
318 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
319 if (gnvs) {
320 /* IGD OpRegion Base Address */
321 gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
322 } else {
323 printk(BIOS_ERR, "Error: GNVS table not found.\n");
324 }
325
326 current = acpi_align_current(current);
327 return current;
328}
329
330static const char *gma_acpi_name(const struct device *dev)
331{
332 return "GFX0";
333}
334
Damien Zammit51fdb922016-01-18 18:34:52 +1100335static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530336 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100337};
338
339static struct device_operations gma_func0_ops = {
Angel Pons39ff7032020-03-09 21:39:44 +0100340 .read_resources = pci_dev_read_resources,
341 .set_resources = pci_dev_set_resources,
342 .enable_resources = pci_dev_enable_resources,
343 .acpi_fill_ssdt_generator = NULL,
344 .init = gma_func0_init,
345 .scan_bus = NULL,
346 .enable = NULL,
347 .ops_pci = &gma_pci_ops,
348 .acpi_name = gma_acpi_name,
349 .write_acpi_tables = gma_write_acpi_tables,
Damien Zammit51fdb922016-01-18 18:34:52 +1100350};
351
352static const unsigned short pci_device_ids[] =
353{
Angel Pons39ff7032020-03-09 21:39:44 +0100354 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100355};
356
357static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100358 .ops = &gma_func0_ops,
359 .vendor = PCI_VENDOR_ID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100360 .devices = pci_device_ids,
361};