blob: 307529d60bb1930daebb20e987b12ed72b0d4a80 [file] [log] [blame]
Damien Zammit51fdb922016-01-18 18:34:52 +11001/*
2 * This file is part of the coreboot project.
3 *
Damien Zammit51fdb922016-01-18 18:34:52 +11004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020016#include <device/mmio.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110017#include <console/console.h>
18#include <delay.h>
19#include <device/device.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110022#include <device/pci_ops.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110023#include <drivers/intel/gma/i915_reg.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110024#include <drivers/intel/gma/intel_bios.h>
25#include <drivers/intel/gma/i915.h>
Patrick Rudolphbb98b382017-09-30 09:13:53 +020026#include <drivers/intel/gma/opregion.h>
27#include <southbridge/intel/i82801gx/nvs.h>
28#include <cbmem.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110029#include <pc80/vga.h>
30#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020031#include <types.h>
32
33#include "chip.h"
34#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110035
Angel Pons39ff7032020-03-09 21:39:44 +010036#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110037
38#define PGETBL2_CTL 0x20c4
39#define PGETBL2_1MB (1 << 8)
40
41#define PGETBL_CTL 0x2020
42#define PGETBL_1MB (3 << 1)
43#define PGETBL_512KB 0
44#define PGETBL_ENABLED 0x1
45
46#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020047 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
48 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
49 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
50 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
51 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
52 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110053
Angel Pons39ff7032020-03-09 21:39:44 +010054static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110055static struct resource *mmio_res = NULL;
56
Patrick Rudolphbb98b382017-09-30 09:13:53 +020057uintptr_t gma_get_gnvs_aslb(const void *gnvs)
58{
59 const global_nvs_t *gnvs_ptr = gnvs;
60 return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0);
61}
62
63void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb)
64{
65 global_nvs_t *gnvs_ptr = gnvs;
66 if (gnvs_ptr)
67 gnvs_ptr->aslb = aslb;
68}
69
Damien Zammit51fdb922016-01-18 18:34:52 +110070static int gtt_setup(u8 *mmiobase)
71{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020072 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030073 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110074
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020075 gttbase = pci_read_config32(dev, BGSM);
76 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110077
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020078 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
79 udelay(50);
80 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110081
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020082 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110083
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020084 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110085}
86
87static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
88 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
89{
90 int i;
91 u32 hactive, vactive;
92 u32 temp;
93
94 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
95 (u32)gtt, (u32)mmio, piobase, physbase);
96
97 gtt_setup(mmio);
98
Elyes HAOUASef20ecc2018-10-04 13:50:14 +020099 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +1100100
101 /* Disable VGA. */
102 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
103
104 /* Disable pipes. */
105 write32(mmio + PIPECONF(0), 0);
106 write32(mmio + PIPECONF(1), 0);
107
108 write32(mmio + INSTPM, 0x800);
109
110 vga_gr_write(0x18, 0);
111
112 write32(mmio + VGA0, 0x200074);
113 write32(mmio + VGA1, 0x200074);
114
115 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
116 write32(mmio + DSPCLK_GATE_D, 0);
117 write32(mmio + FW_BLC, 0x03060106);
118 write32(mmio + FW_BLC2, 0x00000306);
119
120 write32(mmio + ADPA, ADPA_DAC_ENABLE
121 | ADPA_PIPE_A_SELECT
122 | ADPA_HOTPLUG_BITS
123 | ADPA_USE_VGA_HVPOLARITY
124 | ADPA_VSYNC_CNTL_ENABLE
125 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100126 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100127
128 write32(mmio + 0x7041c, 0x0);
129
130 write32(mmio + DPLL_MD(0), 0x3);
131 write32(mmio + DPLL_MD(1), 0x3);
132 write32(mmio + DSPCNTR(1), 0x1000000);
133 write32(mmio + PIPESRC(1), 0x027f01df);
134
135 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100136 const u8 cr[25] = {
137 0x5f, 0x4f, 0x50, 0x82, 0x55,
138 0x81, 0xbf, 0x1f, 0x00, 0x4f,
139 0x0d, 0x0e, 0x00, 0x00, 0x00,
140 0x00, 0x9c, 0x8e, 0x8f, 0x28,
141 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100142 };
143 vga_cr_write(0x11, 0);
144
Angel Pons39ff7032020-03-09 21:39:44 +0100145 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100146 vga_cr_write(i, cr[i]);
147
148 // Disable screen memory to prevent garbage from appearing.
149 vga_sr_write(1, vga_sr_read(1) | 0x20);
150 hactive = 640;
151 vactive = 400;
152
153 mdelay(1);
154 write32(mmio + DPLL(0),
155 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
156 | DPLL_VGA_MODE_DIS
157 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100158 | 0x400601);
159
Damien Zammit51fdb922016-01-18 18:34:52 +1100160 mdelay(1);
161 write32(mmio + DPLL(0),
162 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
163 | DPLL_VGA_MODE_DIS
164 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100165 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100166
167 write32(mmio + ADPA, ADPA_DAC_ENABLE
168 | ADPA_PIPE_A_SELECT
169 | ADPA_HOTPLUG_BITS
170 | ADPA_USE_VGA_HVPOLARITY
171 | ADPA_VSYNC_CNTL_ENABLE
172 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100173 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100174
175 write32(mmio + HTOTAL(1), 0x031f027f);
176 write32(mmio + HBLANK(1), 0x03170287);
177 write32(mmio + HSYNC(1), 0x02ef028f);
178 write32(mmio + VTOTAL(1), 0x020c01df);
179 write32(mmio + VBLANK(1), 0x020401e7);
180 write32(mmio + VSYNC(1), 0x01eb01e9);
181
Angel Pons39ff7032020-03-09 21:39:44 +0100182 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
183 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
184 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
185 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
186 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
187 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100188
189 write32(mmio + PF_WIN_POS(0), 0);
190
191 write32(mmio + PIPESRC(0), (639 << 16) | 399);
192 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
193 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
194 write32(mmio + PFIT_CONTROL, 0x0);
195
196 mdelay(1);
197
198 write32(mmio + FDI_RX_CTL(0), 0x00002040);
199 mdelay(1);
200 write32(mmio + FDI_RX_CTL(0), 0x80002050);
201 write32(mmio + FDI_TX_CTL(0), 0x00044000);
202 mdelay(1);
203 write32(mmio + FDI_TX_CTL(0), 0x80044000);
204 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
205
206 write32(mmio + VGACNTRL, 0x0);
207 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
208 mdelay(1);
209
210 write32(mmio + ADPA, ADPA_DAC_ENABLE
211 | ADPA_PIPE_A_SELECT
212 | ADPA_HOTPLUG_BITS
213 | ADPA_USE_VGA_HVPOLARITY
214 | ADPA_VSYNC_CNTL_ENABLE
215 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100216 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100217
218 write32(mmio + DSPFW3, 0x7f3f00c1);
219 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
220 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
221 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
222
223 for (i = 0; i < (8192 - 512) / 4; i++) {
224 outl((i << 2) | 1, piobase);
225 outl(physbase + (i << 12) + 1, piobase + 4);
226 }
227
228 temp = read32(mmio + PGETBL_CTL);
229 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
230 temp = read32(mmio + PGETBL2_CTL);
231 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
232
Angel Pons39ff7032020-03-09 21:39:44 +0100233 /* Clear interrupts */
234 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100235 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100236 write32(mmio + IIR, 0xffffffff);
237 write32(mmio + IMR, 0xffffffff);
238 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100239
240 vga_textmode_init();
241
Angel Pons39ff7032020-03-09 21:39:44 +0100242 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100243 vga_sr_write(1, vga_sr_read(1) & ~0x20);
244}
245
246static void gma_func0_init(struct device *dev)
247{
248 u32 reg32;
249
250 /* IGD needs to be Bus Master */
251 reg32 = pci_read_config32(dev, PCI_COMMAND);
252 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
253 pci_write_config32(dev, PCI_COMMAND, reg32);
254
Julius Wernercd49cce2019-03-05 16:53:33 -0800255 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100256 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100257 pci_dev_init(dev);
258 } else {
259 u32 physbase;
260 struct resource *pio_res;
261 struct northbridge_intel_pineview_config *conf = dev->chip_info;
262
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200263 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
264
Damien Zammit51fdb922016-01-18 18:34:52 +1100265 /* Find base addresses */
266 mmio_res = find_resource(dev, 0x10);
Angel Pons39ff7032020-03-09 21:39:44 +0100267 gtt_res = find_resource(dev, 0x1c);
268 pio_res = find_resource(dev, 0x14);
Damien Zammit51fdb922016-01-18 18:34:52 +1100269 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
270
271 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200272 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100273 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
274 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200275 } else {
276 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
277 mmio_res->base);
278 intel_gma_init(conf, dev,
279 res2mmio(mmio_res, 0, 0),
280 res2mmio(gtt_res, 0, 0),
281 physbase, pio_res->base);
282 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100283 }
284
285 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200286 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100287 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200288
289 intel_gma_restore_opregion();
Damien Zammit51fdb922016-01-18 18:34:52 +1100290}
291
Damien Zammit51fdb922016-01-18 18:34:52 +1100292const struct i915_gpu_controller_info *intel_gma_get_controller_info(void)
293{
Angel Pons39ff7032020-03-09 21:39:44 +0100294 struct device *dev = pcidev_on_root(2, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +1100295 if (!dev) {
296 printk(BIOS_WARNING, "WARNING: Can't find IGD (0,2,0)\n");
297 return NULL;
298 }
299 struct northbridge_intel_pineview_config *chip = dev->chip_info;
300 return &chip->gfx;
301}
302
Angel Pons39ff7032020-03-09 21:39:44 +0100303static unsigned long gma_write_acpi_tables(struct device *const dev, unsigned long current,
304 struct acpi_rsdp *const rsdp)
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200305{
306 igd_opregion_t *opregion = (igd_opregion_t *)current;
307 global_nvs_t *gnvs;
308
309 if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
310 return current;
311
312 current += sizeof(igd_opregion_t);
313
314 /* GNVS has been already set up */
315 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
316 if (gnvs) {
317 /* IGD OpRegion Base Address */
318 gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
319 } else {
320 printk(BIOS_ERR, "Error: GNVS table not found.\n");
321 }
322
323 current = acpi_align_current(current);
324 return current;
325}
326
327static const char *gma_acpi_name(const struct device *dev)
328{
329 return "GFX0";
330}
331
Damien Zammit51fdb922016-01-18 18:34:52 +1100332static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530333 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100334};
335
336static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200337 .read_resources = pci_dev_read_resources,
338 .set_resources = pci_dev_set_resources,
339 .enable_resources = pci_dev_enable_resources,
340 .acpi_fill_ssdt = NULL,
341 .init = gma_func0_init,
342 .scan_bus = NULL,
343 .enable = NULL,
344 .ops_pci = &gma_pci_ops,
345 .acpi_name = gma_acpi_name,
346 .write_acpi_tables = gma_write_acpi_tables,
Damien Zammit51fdb922016-01-18 18:34:52 +1100347};
348
349static const unsigned short pci_device_ids[] =
350{
Angel Pons39ff7032020-03-09 21:39:44 +0100351 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100352};
353
354static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100355 .ops = &gma_func0_ops,
356 .vendor = PCI_VENDOR_ID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100357 .devices = pci_device_ids,
358};