blob: dd6cb325969b25b0869449ab8adad100f49dd4ae [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
39#define GTTSIZE (512*1024)
40
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
57static struct resource *gtt_res = NULL;
58static 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
129 | ADPA_DPMS_ON
130 );
131
132 write32(mmio + 0x7041c, 0x0);
133
134 write32(mmio + DPLL_MD(0), 0x3);
135 write32(mmio + DPLL_MD(1), 0x3);
136 write32(mmio + DSPCNTR(1), 0x1000000);
137 write32(mmio + PIPESRC(1), 0x027f01df);
138
139 vga_misc_write(0x67);
140 const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
141 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
142 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
143 0xff
144 };
145 vga_cr_write(0x11, 0);
146
147 for (i = 0; i <= 0x18; i++)
148 vga_cr_write(i, cr[i]);
149
150 // Disable screen memory to prevent garbage from appearing.
151 vga_sr_write(1, vga_sr_read(1) | 0x20);
152 hactive = 640;
153 vactive = 400;
154
155 mdelay(1);
156 write32(mmio + DPLL(0),
157 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
158 | DPLL_VGA_MODE_DIS
159 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
160 | 0x400601
161 );
162 mdelay(1);
163 write32(mmio + DPLL(0),
164 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
165 | DPLL_VGA_MODE_DIS
166 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
167 | 0x400601
168 );
169
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
176 | ADPA_DPMS_ON
177 );
178
179 write32(mmio + HTOTAL(1), 0x031f027f);
180 write32(mmio + HBLANK(1), 0x03170287);
181 write32(mmio + HSYNC(1), 0x02ef028f);
182 write32(mmio + VTOTAL(1), 0x020c01df);
183 write32(mmio + VBLANK(1), 0x020401e7);
184 write32(mmio + VSYNC(1), 0x01eb01e9);
185
186 write32(mmio + HTOTAL(0),
187 ((hactive - 1) << 16)
188 | (hactive - 1));
189 write32(mmio + HBLANK(0),
190 ((hactive - 1) << 16)
191 | (hactive - 1));
192 write32(mmio + HSYNC(0),
193 ((hactive - 1) << 16)
194 | (hactive - 1));
195
196 write32(mmio + VTOTAL(0), ((vactive - 1) << 16)
197 | (vactive - 1));
198 write32(mmio + VBLANK(0), ((vactive - 1) << 16)
199 | (vactive - 1));
200 write32(mmio + VSYNC(0),
201 ((vactive - 1) << 16)
202 | (vactive - 1));
203
204 write32(mmio + PF_WIN_POS(0), 0);
205
206 write32(mmio + PIPESRC(0), (639 << 16) | 399);
207 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
208 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
209 write32(mmio + PFIT_CONTROL, 0x0);
210
211 mdelay(1);
212
213 write32(mmio + FDI_RX_CTL(0), 0x00002040);
214 mdelay(1);
215 write32(mmio + FDI_RX_CTL(0), 0x80002050);
216 write32(mmio + FDI_TX_CTL(0), 0x00044000);
217 mdelay(1);
218 write32(mmio + FDI_TX_CTL(0), 0x80044000);
219 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
220
221 write32(mmio + VGACNTRL, 0x0);
222 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
223 mdelay(1);
224
225 write32(mmio + ADPA, ADPA_DAC_ENABLE
226 | ADPA_PIPE_A_SELECT
227 | ADPA_HOTPLUG_BITS
228 | ADPA_USE_VGA_HVPOLARITY
229 | ADPA_VSYNC_CNTL_ENABLE
230 | ADPA_HSYNC_CNTL_ENABLE
231 | ADPA_DPMS_ON
232 );
233
234 write32(mmio + DSPFW3, 0x7f3f00c1);
235 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
236 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
237 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
238
239 for (i = 0; i < (8192 - 512) / 4; i++) {
240 outl((i << 2) | 1, piobase);
241 outl(physbase + (i << 12) + 1, piobase + 4);
242 }
243
244 temp = read32(mmio + PGETBL_CTL);
245 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
246 temp = read32(mmio + PGETBL2_CTL);
247 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
248
249 /* Clear interrupts. */
250 write32(mmio + DEIIR, 0xffffffff);
251 write32(mmio + SDEIIR, 0xffffffff);
252 write32(mmio + IIR, 0xffffffff);
253 write32(mmio + IMR, 0xffffffff);
254 write32(mmio + EIR, 0xffffffff);
255
256 vga_textmode_init();
257
258 /* Enable screen memory. */
259 vga_sr_write(1, vga_sr_read(1) & ~0x20);
260}
261
262static void gma_func0_init(struct device *dev)
263{
264 u32 reg32;
265
266 /* IGD needs to be Bus Master */
267 reg32 = pci_read_config32(dev, PCI_COMMAND);
268 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
269 pci_write_config32(dev, PCI_COMMAND, reg32);
270
Julius Wernercd49cce2019-03-05 16:53:33 -0800271 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Damien Zammit51fdb922016-01-18 18:34:52 +1100272 /* PCI Init, will run VBIOS */
273 pci_dev_init(dev);
274 } else {
275 u32 physbase;
276 struct resource *pio_res;
277 struct northbridge_intel_pineview_config *conf = dev->chip_info;
278
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200279 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
280
Damien Zammit51fdb922016-01-18 18:34:52 +1100281 /* Find base addresses */
282 mmio_res = find_resource(dev, 0x10);
283 gtt_res = find_resource(dev, 0x1c);
284 pio_res = find_resource(dev, 0x14);
285 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
286
287 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200288 if (vga_disable) {
289 printk(BIOS_INFO,
290 "IGD is not decoding legacy VGA MEM and IO: skipping NATIVE graphic init\n");
291 } else {
292 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
293 mmio_res->base);
294 intel_gma_init(conf, dev,
295 res2mmio(mmio_res, 0, 0),
296 res2mmio(gtt_res, 0, 0),
297 physbase, pio_res->base);
298 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100299 }
300
301 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200302 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100303 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200304
305 intel_gma_restore_opregion();
Damien Zammit51fdb922016-01-18 18:34:52 +1100306}
307
Damien Zammit51fdb922016-01-18 18:34:52 +1100308const struct i915_gpu_controller_info *intel_gma_get_controller_info(void)
309{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300310 struct device *dev = pcidev_on_root(0x2, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +1100311 if (!dev) {
312 printk(BIOS_WARNING, "WARNING: Can't find IGD (0,2,0)\n");
313 return NULL;
314 }
315 struct northbridge_intel_pineview_config *chip = dev->chip_info;
316 return &chip->gfx;
317}
318
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200319static unsigned long
320gma_write_acpi_tables(struct device *const dev,
321 unsigned long current,
322 struct acpi_rsdp *const rsdp)
323{
324 igd_opregion_t *opregion = (igd_opregion_t *)current;
325 global_nvs_t *gnvs;
326
327 if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
328 return current;
329
330 current += sizeof(igd_opregion_t);
331
332 /* GNVS has been already set up */
333 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
334 if (gnvs) {
335 /* IGD OpRegion Base Address */
336 gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
337 } else {
338 printk(BIOS_ERR, "Error: GNVS table not found.\n");
339 }
340
341 current = acpi_align_current(current);
342 return current;
343}
344
345static const char *gma_acpi_name(const struct device *dev)
346{
347 return "GFX0";
348}
349
Damien Zammit51fdb922016-01-18 18:34:52 +1100350static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530351 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100352};
353
354static struct device_operations gma_func0_ops = {
355 .read_resources = pci_dev_read_resources,
356 .set_resources = pci_dev_set_resources,
357 .enable_resources = pci_dev_enable_resources,
358 .acpi_fill_ssdt_generator = 0,
359 .init = gma_func0_init,
360 .scan_bus = 0,
361 .enable = 0,
362 .ops_pci = &gma_pci_ops,
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200363 .acpi_name = gma_acpi_name,
364 .write_acpi_tables = gma_write_acpi_tables,
Damien Zammit51fdb922016-01-18 18:34:52 +1100365};
366
367static const unsigned short pci_device_ids[] =
368{
369 0xa001, 0
370};
371
372static const struct pci_driver gma __pci_driver = {
373 .ops = &gma_func0_ops,
374 .vendor = PCI_VENDOR_ID_INTEL,
375 .devices = pci_device_ids,
376};