blob: a7ff32fe931dc1001366e00b9c6e454629ccc079 [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);
Petr Cvekd6fb4252022-06-16 15:17:50 +0200198 outl((physbase + (i << 12)) | 1, piobase + 4);
Damien Zammit51fdb922016-01-18 18:34:52 +1100199 }
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{
Nico Huberf2a0be22020-04-26 17:01:25 +0200221 intel_gma_init_igd_opregion();
222
Nico Huberdd597622020-04-26 19:46:35 +0200223 if (!CONFIG(NO_GFX_INIT))
224 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
Damien Zammit51fdb922016-01-18 18:34:52 +1100225
Julius Wernercd49cce2019-03-05 16:53:33 -0800226 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100227 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100228 pci_dev_init(dev);
229 } else {
230 u32 physbase;
231 struct resource *pio_res;
232 struct northbridge_intel_pineview_config *conf = dev->chip_info;
233
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200234 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
235
Damien Zammit51fdb922016-01-18 18:34:52 +1100236 /* Find base addresses */
Elyes HAOUASa4dd33c2020-08-11 09:39:43 +0200237 mmio_res = find_resource(dev, PCI_BASE_ADDRESS_0);
238 gtt_res = find_resource(dev, PCI_BASE_ADDRESS_3);
239 pio_res = find_resource(dev, PCI_BASE_ADDRESS_1);
Damien Zammit51fdb922016-01-18 18:34:52 +1100240 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
241
242 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200243 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100244 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
245 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200246 } else {
247 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
248 mmio_res->base);
249 intel_gma_init(conf, dev,
250 res2mmio(mmio_res, 0, 0),
251 res2mmio(gtt_res, 0, 0),
252 physbase, pio_res->base);
253 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100254 }
255
256 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200257 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100258 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200259}
260
261static const char *gma_acpi_name(const struct device *dev)
262{
263 return "GFX0";
264}
265
Damien Zammit51fdb922016-01-18 18:34:52 +1100266static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200267 .read_resources = pci_dev_read_resources,
268 .set_resources = pci_dev_set_resources,
269 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200270 .init = gma_func0_init,
Angel Pons1fc0edd2020-05-31 00:03:28 +0200271 .ops_pci = &pci_dev_ops_pci,
Nico Huber68680dd2020-03-31 17:34:52 +0200272 .acpi_name = gma_acpi_name,
Damien Zammit51fdb922016-01-18 18:34:52 +1100273};
274
275static const unsigned short pci_device_ids[] =
276{
Angel Pons39ff7032020-03-09 21:39:44 +0100277 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100278};
279
280static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100281 .ops = &gma_func0_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100282 .vendor = PCI_VID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100283 .devices = pci_device_ids,
284};