blob: ba6f39c5b464627ad6852c6d7f591399afcba428 [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>
Elyes HAOUASa4dd33c2020-08-11 09:39:43 +02009#include <device/pci_def.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110010#include <device/pci_ids.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110011#include <device/pci_ops.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110012#include <drivers/intel/gma/i915_reg.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110013#include <drivers/intel/gma/intel_bios.h>
14#include <drivers/intel/gma/i915.h>
Patrick Rudolphbb98b382017-09-30 09:13:53 +020015#include <drivers/intel/gma/opregion.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110016#include <pc80/vga.h>
17#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020018#include <types.h>
19
20#include "chip.h"
21#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110022
Angel Pons39ff7032020-03-09 21:39:44 +010023#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110024
25#define PGETBL2_CTL 0x20c4
26#define PGETBL2_1MB (1 << 8)
27
28#define PGETBL_CTL 0x2020
29#define PGETBL_1MB (3 << 1)
30#define PGETBL_512KB 0
31#define PGETBL_ENABLED 0x1
32
33#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020034 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
35 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
36 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
37 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
38 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
39 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110040
Angel Pons39ff7032020-03-09 21:39:44 +010041static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110042static struct resource *mmio_res = NULL;
43
44static int gtt_setup(u8 *mmiobase)
45{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020046 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030047 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110048
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020049 gttbase = pci_read_config32(dev, BGSM);
50 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110051
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020052 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
53 udelay(50);
54 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110055
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020056 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110057
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020058 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110059}
60
61static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
62 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
63{
64 int i;
65 u32 hactive, vactive;
66 u32 temp;
67
68 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
69 (u32)gtt, (u32)mmio, piobase, physbase);
70
71 gtt_setup(mmio);
72
Elyes HAOUASef20ecc2018-10-04 13:50:14 +020073 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +110074
75 /* Disable VGA. */
76 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
77
78 /* Disable pipes. */
79 write32(mmio + PIPECONF(0), 0);
80 write32(mmio + PIPECONF(1), 0);
81
82 write32(mmio + INSTPM, 0x800);
83
84 vga_gr_write(0x18, 0);
85
86 write32(mmio + VGA0, 0x200074);
87 write32(mmio + VGA1, 0x200074);
88
89 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
90 write32(mmio + DSPCLK_GATE_D, 0);
91 write32(mmio + FW_BLC, 0x03060106);
92 write32(mmio + FW_BLC2, 0x00000306);
93
94 write32(mmio + ADPA, ADPA_DAC_ENABLE
95 | ADPA_PIPE_A_SELECT
96 | ADPA_HOTPLUG_BITS
97 | ADPA_USE_VGA_HVPOLARITY
98 | ADPA_VSYNC_CNTL_ENABLE
99 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100100 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100101
102 write32(mmio + 0x7041c, 0x0);
103
104 write32(mmio + DPLL_MD(0), 0x3);
105 write32(mmio + DPLL_MD(1), 0x3);
106 write32(mmio + DSPCNTR(1), 0x1000000);
107 write32(mmio + PIPESRC(1), 0x027f01df);
108
109 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100110 const u8 cr[25] = {
111 0x5f, 0x4f, 0x50, 0x82, 0x55,
112 0x81, 0xbf, 0x1f, 0x00, 0x4f,
113 0x0d, 0x0e, 0x00, 0x00, 0x00,
114 0x00, 0x9c, 0x8e, 0x8f, 0x28,
115 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100116 };
117 vga_cr_write(0x11, 0);
118
Angel Pons39ff7032020-03-09 21:39:44 +0100119 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100120 vga_cr_write(i, cr[i]);
121
122 // Disable screen memory to prevent garbage from appearing.
123 vga_sr_write(1, vga_sr_read(1) | 0x20);
124 hactive = 640;
125 vactive = 400;
126
127 mdelay(1);
128 write32(mmio + DPLL(0),
129 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
130 | DPLL_VGA_MODE_DIS
131 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100132 | 0x400601);
133
Damien Zammit51fdb922016-01-18 18:34:52 +1100134 mdelay(1);
135 write32(mmio + DPLL(0),
136 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
137 | DPLL_VGA_MODE_DIS
138 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100139 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100140
141 write32(mmio + ADPA, ADPA_DAC_ENABLE
142 | ADPA_PIPE_A_SELECT
143 | ADPA_HOTPLUG_BITS
144 | ADPA_USE_VGA_HVPOLARITY
145 | ADPA_VSYNC_CNTL_ENABLE
146 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100147 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100148
149 write32(mmio + HTOTAL(1), 0x031f027f);
150 write32(mmio + HBLANK(1), 0x03170287);
151 write32(mmio + HSYNC(1), 0x02ef028f);
152 write32(mmio + VTOTAL(1), 0x020c01df);
153 write32(mmio + VBLANK(1), 0x020401e7);
154 write32(mmio + VSYNC(1), 0x01eb01e9);
155
Angel Pons39ff7032020-03-09 21:39:44 +0100156 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
157 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
158 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
159 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
160 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
161 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100162
163 write32(mmio + PF_WIN_POS(0), 0);
164
165 write32(mmio + PIPESRC(0), (639 << 16) | 399);
166 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
167 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
168 write32(mmio + PFIT_CONTROL, 0x0);
169
170 mdelay(1);
171
172 write32(mmio + FDI_RX_CTL(0), 0x00002040);
173 mdelay(1);
174 write32(mmio + FDI_RX_CTL(0), 0x80002050);
175 write32(mmio + FDI_TX_CTL(0), 0x00044000);
176 mdelay(1);
177 write32(mmio + FDI_TX_CTL(0), 0x80044000);
178 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
179
180 write32(mmio + VGACNTRL, 0x0);
181 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
182 mdelay(1);
183
184 write32(mmio + ADPA, ADPA_DAC_ENABLE
185 | ADPA_PIPE_A_SELECT
186 | ADPA_HOTPLUG_BITS
187 | ADPA_USE_VGA_HVPOLARITY
188 | ADPA_VSYNC_CNTL_ENABLE
189 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100190 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100191
192 write32(mmio + DSPFW3, 0x7f3f00c1);
193 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
194 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
195 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
196
197 for (i = 0; i < (8192 - 512) / 4; i++) {
198 outl((i << 2) | 1, piobase);
199 outl(physbase + (i << 12) + 1, piobase + 4);
200 }
201
202 temp = read32(mmio + PGETBL_CTL);
203 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
204 temp = read32(mmio + PGETBL2_CTL);
205 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
206
Angel Pons39ff7032020-03-09 21:39:44 +0100207 /* Clear interrupts */
208 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100209 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100210 write32(mmio + IIR, 0xffffffff);
211 write32(mmio + IMR, 0xffffffff);
212 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100213
214 vga_textmode_init();
215
Angel Pons39ff7032020-03-09 21:39:44 +0100216 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100217 vga_sr_write(1, vga_sr_read(1) & ~0x20);
218}
219
220static void gma_func0_init(struct device *dev)
221{
Nico Huberf2a0be22020-04-26 17:01:25 +0200222 intel_gma_init_igd_opregion();
223
Nico Huberdd597622020-04-26 19:46:35 +0200224 if (!CONFIG(NO_GFX_INIT))
225 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
Damien Zammit51fdb922016-01-18 18:34:52 +1100226
Julius Wernercd49cce2019-03-05 16:53:33 -0800227 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100228 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100229 pci_dev_init(dev);
230 } else {
231 u32 physbase;
232 struct resource *pio_res;
233 struct northbridge_intel_pineview_config *conf = dev->chip_info;
234
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200235 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
236
Damien Zammit51fdb922016-01-18 18:34:52 +1100237 /* Find base addresses */
Elyes HAOUASa4dd33c2020-08-11 09:39:43 +0200238 mmio_res = find_resource(dev, PCI_BASE_ADDRESS_0);
239 gtt_res = find_resource(dev, PCI_BASE_ADDRESS_3);
240 pio_res = find_resource(dev, PCI_BASE_ADDRESS_1);
Damien Zammit51fdb922016-01-18 18:34:52 +1100241 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
242
243 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200244 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100245 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
246 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200247 } else {
248 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
249 mmio_res->base);
250 intel_gma_init(conf, dev,
251 res2mmio(mmio_res, 0, 0),
252 res2mmio(gtt_res, 0, 0),
253 physbase, pio_res->base);
254 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100255 }
256
257 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200258 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100259 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200260}
261
262static const char *gma_acpi_name(const struct device *dev)
263{
264 return "GFX0";
265}
266
Damien Zammit51fdb922016-01-18 18:34:52 +1100267static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200268 .read_resources = pci_dev_read_resources,
269 .set_resources = pci_dev_set_resources,
270 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200271 .init = gma_func0_init,
Angel Pons1fc0edd2020-05-31 00:03:28 +0200272 .ops_pci = &pci_dev_ops_pci,
Nico Huber68680dd2020-03-31 17:34:52 +0200273 .acpi_name = gma_acpi_name,
Damien Zammit51fdb922016-01-18 18:34:52 +1100274};
275
276static const unsigned short pci_device_ids[] =
277{
Angel Pons39ff7032020-03-09 21:39:44 +0100278 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100279};
280
281static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100282 .ops = &gma_func0_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100283 .vendor = PCI_VID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100284 .devices = pci_device_ids,
285};