blob: e2d0d18badd9e4bf390f281eae4167a5b0ade1f2 [file] [log] [blame]
Angel Pons4b429832020-04-02 23:48:50 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Damien Zammit51fdb922016-01-18 18:34:52 +11002
3#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Damien Zammit51fdb922016-01-18 18:34:52 +11005#include <console/console.h>
6#include <delay.h>
7#include <device/device.h>
8#include <device/pci.h>
9#include <device/pci_ids.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110010#include <device/pci_ops.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110011#include <drivers/intel/gma/i915_reg.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110012#include <drivers/intel/gma/intel_bios.h>
13#include <drivers/intel/gma/i915.h>
Patrick Rudolphbb98b382017-09-30 09:13:53 +020014#include <drivers/intel/gma/opregion.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110015#include <pc80/vga.h>
16#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020017#include <types.h>
18
19#include "chip.h"
20#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110021
Angel Pons39ff7032020-03-09 21:39:44 +010022#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110023
24#define PGETBL2_CTL 0x20c4
25#define PGETBL2_1MB (1 << 8)
26
27#define PGETBL_CTL 0x2020
28#define PGETBL_1MB (3 << 1)
29#define PGETBL_512KB 0
30#define PGETBL_ENABLED 0x1
31
32#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020033 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
34 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
35 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
36 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
37 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
38 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110039
Angel Pons39ff7032020-03-09 21:39:44 +010040static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110041static struct resource *mmio_res = NULL;
42
43static int gtt_setup(u8 *mmiobase)
44{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020045 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030046 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110047
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020048 gttbase = pci_read_config32(dev, BGSM);
49 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110050
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020051 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
52 udelay(50);
53 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110054
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020055 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110056
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020057 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110058}
59
60static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
61 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
62{
63 int i;
64 u32 hactive, vactive;
65 u32 temp;
66
67 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
68 (u32)gtt, (u32)mmio, piobase, physbase);
69
70 gtt_setup(mmio);
71
Elyes HAOUASef20ecc2018-10-04 13:50:14 +020072 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +110073
74 /* Disable VGA. */
75 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
76
77 /* Disable pipes. */
78 write32(mmio + PIPECONF(0), 0);
79 write32(mmio + PIPECONF(1), 0);
80
81 write32(mmio + INSTPM, 0x800);
82
83 vga_gr_write(0x18, 0);
84
85 write32(mmio + VGA0, 0x200074);
86 write32(mmio + VGA1, 0x200074);
87
88 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
89 write32(mmio + DSPCLK_GATE_D, 0);
90 write32(mmio + FW_BLC, 0x03060106);
91 write32(mmio + FW_BLC2, 0x00000306);
92
93 write32(mmio + ADPA, ADPA_DAC_ENABLE
94 | ADPA_PIPE_A_SELECT
95 | ADPA_HOTPLUG_BITS
96 | ADPA_USE_VGA_HVPOLARITY
97 | ADPA_VSYNC_CNTL_ENABLE
98 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +010099 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100100
101 write32(mmio + 0x7041c, 0x0);
102
103 write32(mmio + DPLL_MD(0), 0x3);
104 write32(mmio + DPLL_MD(1), 0x3);
105 write32(mmio + DSPCNTR(1), 0x1000000);
106 write32(mmio + PIPESRC(1), 0x027f01df);
107
108 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100109 const u8 cr[25] = {
110 0x5f, 0x4f, 0x50, 0x82, 0x55,
111 0x81, 0xbf, 0x1f, 0x00, 0x4f,
112 0x0d, 0x0e, 0x00, 0x00, 0x00,
113 0x00, 0x9c, 0x8e, 0x8f, 0x28,
114 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100115 };
116 vga_cr_write(0x11, 0);
117
Angel Pons39ff7032020-03-09 21:39:44 +0100118 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100119 vga_cr_write(i, cr[i]);
120
121 // Disable screen memory to prevent garbage from appearing.
122 vga_sr_write(1, vga_sr_read(1) | 0x20);
123 hactive = 640;
124 vactive = 400;
125
126 mdelay(1);
127 write32(mmio + DPLL(0),
128 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
129 | DPLL_VGA_MODE_DIS
130 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100131 | 0x400601);
132
Damien Zammit51fdb922016-01-18 18:34:52 +1100133 mdelay(1);
134 write32(mmio + DPLL(0),
135 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
136 | DPLL_VGA_MODE_DIS
137 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100138 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100139
140 write32(mmio + ADPA, ADPA_DAC_ENABLE
141 | ADPA_PIPE_A_SELECT
142 | ADPA_HOTPLUG_BITS
143 | ADPA_USE_VGA_HVPOLARITY
144 | ADPA_VSYNC_CNTL_ENABLE
145 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100146 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100147
148 write32(mmio + HTOTAL(1), 0x031f027f);
149 write32(mmio + HBLANK(1), 0x03170287);
150 write32(mmio + HSYNC(1), 0x02ef028f);
151 write32(mmio + VTOTAL(1), 0x020c01df);
152 write32(mmio + VBLANK(1), 0x020401e7);
153 write32(mmio + VSYNC(1), 0x01eb01e9);
154
Angel Pons39ff7032020-03-09 21:39:44 +0100155 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
156 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
157 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
158 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
159 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
160 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100161
162 write32(mmio + PF_WIN_POS(0), 0);
163
164 write32(mmio + PIPESRC(0), (639 << 16) | 399);
165 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
166 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
167 write32(mmio + PFIT_CONTROL, 0x0);
168
169 mdelay(1);
170
171 write32(mmio + FDI_RX_CTL(0), 0x00002040);
172 mdelay(1);
173 write32(mmio + FDI_RX_CTL(0), 0x80002050);
174 write32(mmio + FDI_TX_CTL(0), 0x00044000);
175 mdelay(1);
176 write32(mmio + FDI_TX_CTL(0), 0x80044000);
177 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
178
179 write32(mmio + VGACNTRL, 0x0);
180 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
181 mdelay(1);
182
183 write32(mmio + ADPA, ADPA_DAC_ENABLE
184 | ADPA_PIPE_A_SELECT
185 | ADPA_HOTPLUG_BITS
186 | ADPA_USE_VGA_HVPOLARITY
187 | ADPA_VSYNC_CNTL_ENABLE
188 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100189 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100190
191 write32(mmio + DSPFW3, 0x7f3f00c1);
192 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
193 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
194 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
195
196 for (i = 0; i < (8192 - 512) / 4; i++) {
197 outl((i << 2) | 1, piobase);
198 outl(physbase + (i << 12) + 1, piobase + 4);
199 }
200
201 temp = read32(mmio + PGETBL_CTL);
202 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
203 temp = read32(mmio + PGETBL2_CTL);
204 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
205
Angel Pons39ff7032020-03-09 21:39:44 +0100206 /* Clear interrupts */
207 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100208 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100209 write32(mmio + IIR, 0xffffffff);
210 write32(mmio + IMR, 0xffffffff);
211 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100212
213 vga_textmode_init();
214
Angel Pons39ff7032020-03-09 21:39:44 +0100215 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100216 vga_sr_write(1, vga_sr_read(1) & ~0x20);
217}
218
219static void gma_func0_init(struct device *dev)
220{
221 u32 reg32;
222
Nico Huberf2a0be22020-04-26 17:01:25 +0200223 intel_gma_init_igd_opregion();
224
Damien Zammit51fdb922016-01-18 18:34:52 +1100225 /* IGD needs to be Bus Master */
226 reg32 = pci_read_config32(dev, PCI_COMMAND);
227 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
228 pci_write_config32(dev, PCI_COMMAND, reg32);
229
Julius Wernercd49cce2019-03-05 16:53:33 -0800230 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100231 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100232 pci_dev_init(dev);
233 } else {
234 u32 physbase;
235 struct resource *pio_res;
236 struct northbridge_intel_pineview_config *conf = dev->chip_info;
237
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200238 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
239
Damien Zammit51fdb922016-01-18 18:34:52 +1100240 /* Find base addresses */
241 mmio_res = find_resource(dev, 0x10);
Angel Pons39ff7032020-03-09 21:39:44 +0100242 gtt_res = find_resource(dev, 0x1c);
243 pio_res = find_resource(dev, 0x14);
Damien Zammit51fdb922016-01-18 18:34:52 +1100244 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
245
246 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200247 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100248 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
249 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200250 } else {
251 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
252 mmio_res->base);
253 intel_gma_init(conf, dev,
254 res2mmio(mmio_res, 0, 0),
255 res2mmio(gtt_res, 0, 0),
256 physbase, pio_res->base);
257 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100258 }
259
260 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200261 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100262 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200263}
264
265static const char *gma_acpi_name(const struct device *dev)
266{
267 return "GFX0";
268}
269
Damien Zammit51fdb922016-01-18 18:34:52 +1100270static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530271 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100272};
273
274static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200275 .read_resources = pci_dev_read_resources,
276 .set_resources = pci_dev_set_resources,
277 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200278 .init = gma_func0_init,
Nico Huber68680dd2020-03-31 17:34:52 +0200279 .ops_pci = &gma_pci_ops,
280 .acpi_name = gma_acpi_name,
Damien Zammit51fdb922016-01-18 18:34:52 +1100281};
282
283static const unsigned short pci_device_ids[] =
284{
Angel Pons39ff7032020-03-09 21:39:44 +0100285 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100286};
287
288static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100289 .ops = &gma_func0_ops,
290 .vendor = PCI_VENDOR_ID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100291 .devices = pci_device_ids,
292};