blob: b0ecfe1d64bcc1101da1dd502d29c61b0308c741 [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>
15#include <southbridge/intel/i82801gx/nvs.h>
16#include <cbmem.h>
Damien Zammit51fdb922016-01-18 18:34:52 +110017#include <pc80/vga.h>
18#include <pc80/vga_io.h>
Elyes HAOUAS51401c32019-05-15 21:09:30 +020019#include <types.h>
20
21#include "chip.h"
22#include "pineview.h"
Damien Zammit51fdb922016-01-18 18:34:52 +110023
Angel Pons39ff7032020-03-09 21:39:44 +010024#define GTTSIZE (512 * 1024)
Damien Zammit51fdb922016-01-18 18:34:52 +110025
26#define PGETBL2_CTL 0x20c4
27#define PGETBL2_1MB (1 << 8)
28
29#define PGETBL_CTL 0x2020
30#define PGETBL_1MB (3 << 1)
31#define PGETBL_512KB 0
32#define PGETBL_ENABLED 0x1
33
34#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020035 ADPA_CRT_HOTPLUG_WARMUP_10MS | \
36 ADPA_CRT_HOTPLUG_MONITOR_COLOR| \
37 ADPA_CRT_HOTPLUG_SAMPLE_4S | \
38 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
39 ADPA_CRT_HOTPLUG_VOLREF_325MV | \
40 ADPA_CRT_HOTPLUG_ENABLE)
Damien Zammit51fdb922016-01-18 18:34:52 +110041
Angel Pons39ff7032020-03-09 21:39:44 +010042static struct resource *gtt_res = NULL;
Damien Zammit51fdb922016-01-18 18:34:52 +110043static struct resource *mmio_res = NULL;
44
Patrick Rudolphbb98b382017-09-30 09:13:53 +020045uintptr_t gma_get_gnvs_aslb(const void *gnvs)
46{
47 const global_nvs_t *gnvs_ptr = gnvs;
48 return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0);
49}
50
51void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb)
52{
53 global_nvs_t *gnvs_ptr = gnvs;
54 if (gnvs_ptr)
55 gnvs_ptr->aslb = aslb;
56}
57
Damien Zammit51fdb922016-01-18 18:34:52 +110058static int gtt_setup(u8 *mmiobase)
59{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020060 u32 gttbase;
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030061 struct device *dev = pcidev_on_root(0, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110062
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020063 gttbase = pci_read_config32(dev, BGSM);
64 printk(BIOS_DEBUG, "gttbase = %08x\n", gttbase);
Damien Zammit51fdb922016-01-18 18:34:52 +110065
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020066 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
67 udelay(50);
68 write32(mmiobase + PGETBL_CTL, gttbase | PGETBL_512KB);
Damien Zammit51fdb922016-01-18 18:34:52 +110069
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020070 write32(mmiobase + GFX_FLSH_CNTL, 0);
Damien Zammit51fdb922016-01-18 18:34:52 +110071
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020072 return 0;
Damien Zammit51fdb922016-01-18 18:34:52 +110073}
74
75static void intel_gma_init(const struct northbridge_intel_pineview_config *info,
76 struct device *vga, u8 *mmio, u8 *gtt, u32 physbase, u16 piobase)
77{
78 int i;
79 u32 hactive, vactive;
80 u32 temp;
81
82 printk(BIOS_SPEW, "gtt %x mmio %x addrport %x physbase %x\n",
83 (u32)gtt, (u32)mmio, piobase, physbase);
84
85 gtt_setup(mmio);
86
Elyes HAOUASef20ecc2018-10-04 13:50:14 +020087 pci_write_config16(vga, GGC, 0x130);
Damien Zammit51fdb922016-01-18 18:34:52 +110088
89 /* Disable VGA. */
90 write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
91
92 /* Disable pipes. */
93 write32(mmio + PIPECONF(0), 0);
94 write32(mmio + PIPECONF(1), 0);
95
96 write32(mmio + INSTPM, 0x800);
97
98 vga_gr_write(0x18, 0);
99
100 write32(mmio + VGA0, 0x200074);
101 write32(mmio + VGA1, 0x200074);
102
103 write32(mmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
104 write32(mmio + DSPCLK_GATE_D, 0);
105 write32(mmio + FW_BLC, 0x03060106);
106 write32(mmio + FW_BLC2, 0x00000306);
107
108 write32(mmio + ADPA, ADPA_DAC_ENABLE
109 | ADPA_PIPE_A_SELECT
110 | ADPA_HOTPLUG_BITS
111 | ADPA_USE_VGA_HVPOLARITY
112 | ADPA_VSYNC_CNTL_ENABLE
113 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100114 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100115
116 write32(mmio + 0x7041c, 0x0);
117
118 write32(mmio + DPLL_MD(0), 0x3);
119 write32(mmio + DPLL_MD(1), 0x3);
120 write32(mmio + DSPCNTR(1), 0x1000000);
121 write32(mmio + PIPESRC(1), 0x027f01df);
122
123 vga_misc_write(0x67);
Angel Pons39ff7032020-03-09 21:39:44 +0100124 const u8 cr[25] = {
125 0x5f, 0x4f, 0x50, 0x82, 0x55,
126 0x81, 0xbf, 0x1f, 0x00, 0x4f,
127 0x0d, 0x0e, 0x00, 0x00, 0x00,
128 0x00, 0x9c, 0x8e, 0x8f, 0x28,
129 0x1f, 0x96, 0xb9, 0xa3, 0xff,
Damien Zammit51fdb922016-01-18 18:34:52 +1100130 };
131 vga_cr_write(0x11, 0);
132
Angel Pons39ff7032020-03-09 21:39:44 +0100133 for (i = 0; i < ARRAY_SIZE(cr); i++)
Damien Zammit51fdb922016-01-18 18:34:52 +1100134 vga_cr_write(i, cr[i]);
135
136 // Disable screen memory to prevent garbage from appearing.
137 vga_sr_write(1, vga_sr_read(1) | 0x20);
138 hactive = 640;
139 vactive = 400;
140
141 mdelay(1);
142 write32(mmio + DPLL(0),
143 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
144 | DPLL_VGA_MODE_DIS
145 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100146 | 0x400601);
147
Damien Zammit51fdb922016-01-18 18:34:52 +1100148 mdelay(1);
149 write32(mmio + DPLL(0),
150 DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
151 | DPLL_VGA_MODE_DIS
152 | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
Angel Pons39ff7032020-03-09 21:39:44 +0100153 | 0x400601);
Damien Zammit51fdb922016-01-18 18:34:52 +1100154
155 write32(mmio + ADPA, ADPA_DAC_ENABLE
156 | ADPA_PIPE_A_SELECT
157 | ADPA_HOTPLUG_BITS
158 | ADPA_USE_VGA_HVPOLARITY
159 | ADPA_VSYNC_CNTL_ENABLE
160 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100161 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100162
163 write32(mmio + HTOTAL(1), 0x031f027f);
164 write32(mmio + HBLANK(1), 0x03170287);
165 write32(mmio + HSYNC(1), 0x02ef028f);
166 write32(mmio + VTOTAL(1), 0x020c01df);
167 write32(mmio + VBLANK(1), 0x020401e7);
168 write32(mmio + VSYNC(1), 0x01eb01e9);
169
Angel Pons39ff7032020-03-09 21:39:44 +0100170 write32(mmio + HTOTAL(0), ((hactive - 1) << 16) | (hactive - 1));
171 write32(mmio + HBLANK(0), ((hactive - 1) << 16) | (hactive - 1));
172 write32(mmio + HSYNC(0), ((hactive - 1) << 16) | (hactive - 1));
173 write32(mmio + VTOTAL(0), ((vactive - 1) << 16) | (vactive - 1));
174 write32(mmio + VBLANK(0), ((vactive - 1) << 16) | (vactive - 1));
175 write32(mmio + VSYNC(0), ((vactive - 1) << 16) | (vactive - 1));
Damien Zammit51fdb922016-01-18 18:34:52 +1100176
177 write32(mmio + PF_WIN_POS(0), 0);
178
179 write32(mmio + PIPESRC(0), (639 << 16) | 399);
180 write32(mmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
181 write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
182 write32(mmio + PFIT_CONTROL, 0x0);
183
184 mdelay(1);
185
186 write32(mmio + FDI_RX_CTL(0), 0x00002040);
187 mdelay(1);
188 write32(mmio + FDI_RX_CTL(0), 0x80002050);
189 write32(mmio + FDI_TX_CTL(0), 0x00044000);
190 mdelay(1);
191 write32(mmio + FDI_TX_CTL(0), 0x80044000);
192 write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
193
194 write32(mmio + VGACNTRL, 0x0);
195 write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
196 mdelay(1);
197
198 write32(mmio + ADPA, ADPA_DAC_ENABLE
199 | ADPA_PIPE_A_SELECT
200 | ADPA_HOTPLUG_BITS
201 | ADPA_USE_VGA_HVPOLARITY
202 | ADPA_VSYNC_CNTL_ENABLE
203 | ADPA_HSYNC_CNTL_ENABLE
Angel Pons39ff7032020-03-09 21:39:44 +0100204 | ADPA_DPMS_ON);
Damien Zammit51fdb922016-01-18 18:34:52 +1100205
206 write32(mmio + DSPFW3, 0x7f3f00c1);
207 write32(mmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
208 write32(mmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
209 write32(mmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
210
211 for (i = 0; i < (8192 - 512) / 4; i++) {
212 outl((i << 2) | 1, piobase);
213 outl(physbase + (i << 12) + 1, piobase + 4);
214 }
215
216 temp = read32(mmio + PGETBL_CTL);
217 printk(BIOS_INFO, "GTT PGETBL_CTL register : 0x%08x\n", temp);
218 temp = read32(mmio + PGETBL2_CTL);
219 printk(BIOS_INFO, "GTT PGETBL2_CTL register: 0x%08x\n", temp);
220
Angel Pons39ff7032020-03-09 21:39:44 +0100221 /* Clear interrupts */
222 write32(mmio + DEIIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100223 write32(mmio + SDEIIR, 0xffffffff);
Angel Pons39ff7032020-03-09 21:39:44 +0100224 write32(mmio + IIR, 0xffffffff);
225 write32(mmio + IMR, 0xffffffff);
226 write32(mmio + EIR, 0xffffffff);
Damien Zammit51fdb922016-01-18 18:34:52 +1100227
228 vga_textmode_init();
229
Angel Pons39ff7032020-03-09 21:39:44 +0100230 /* Enable screen memory */
Damien Zammit51fdb922016-01-18 18:34:52 +1100231 vga_sr_write(1, vga_sr_read(1) & ~0x20);
232}
233
234static void gma_func0_init(struct device *dev)
235{
236 u32 reg32;
237
238 /* IGD needs to be Bus Master */
239 reg32 = pci_read_config32(dev, PCI_COMMAND);
240 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
241 pci_write_config32(dev, PCI_COMMAND, reg32);
242
Julius Wernercd49cce2019-03-05 16:53:33 -0800243 if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) {
Angel Pons39ff7032020-03-09 21:39:44 +0100244 /* PCI init, will run VBIOS */
Damien Zammit51fdb922016-01-18 18:34:52 +1100245 pci_dev_init(dev);
246 } else {
247 u32 physbase;
248 struct resource *pio_res;
249 struct northbridge_intel_pineview_config *conf = dev->chip_info;
250
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200251 int vga_disable = (pci_read_config16(dev, GGC) & 2) >> 1;
252
Damien Zammit51fdb922016-01-18 18:34:52 +1100253 /* Find base addresses */
254 mmio_res = find_resource(dev, 0x10);
Angel Pons39ff7032020-03-09 21:39:44 +0100255 gtt_res = find_resource(dev, 0x1c);
256 pio_res = find_resource(dev, 0x14);
Damien Zammit51fdb922016-01-18 18:34:52 +1100257 physbase = pci_read_config32(dev, 0x5c) & ~0xf;
258
259 if (gtt_res && gtt_res->base && physbase && pio_res && pio_res->base) {
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200260 if (vga_disable) {
Angel Pons39ff7032020-03-09 21:39:44 +0100261 printk(BIOS_INFO, "IGD is not decoding legacy VGA MEM and IO: "
262 "skipping NATIVE graphic init\n");
Arthur Heymanse6c8f7e2018-08-09 11:31:51 +0200263 } else {
264 printk(BIOS_SPEW, "Initializing VGA. MMIO 0x%llx\n",
265 mmio_res->base);
266 intel_gma_init(conf, dev,
267 res2mmio(mmio_res, 0, 0),
268 res2mmio(gtt_res, 0, 0),
269 physbase, pio_res->base);
270 }
Damien Zammit51fdb922016-01-18 18:34:52 +1100271 }
272
273 /* Linux relies on VBT for panel info. */
Arthur Heymansd3284a62016-09-25 22:48:00 +0200274 generate_fake_intel_oprom(&conf->gfx, dev, "$VBT PINEVIEW");
Damien Zammit51fdb922016-01-18 18:34:52 +1100275 }
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200276
277 intel_gma_restore_opregion();
Damien Zammit51fdb922016-01-18 18:34:52 +1100278}
279
Furquan Shaikh0f007d82020-04-24 06:41:18 -0700280static unsigned long gma_write_acpi_tables(const struct device *const dev,
281 unsigned long current,
Angel Pons39ff7032020-03-09 21:39:44 +0100282 struct acpi_rsdp *const rsdp)
Patrick Rudolphbb98b382017-09-30 09:13:53 +0200283{
284 igd_opregion_t *opregion = (igd_opregion_t *)current;
285 global_nvs_t *gnvs;
286
287 if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
288 return current;
289
290 current += sizeof(igd_opregion_t);
291
292 /* GNVS has been already set up */
293 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
294 if (gnvs) {
295 /* IGD OpRegion Base Address */
296 gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
297 } else {
298 printk(BIOS_ERR, "Error: GNVS table not found.\n");
299 }
300
301 current = acpi_align_current(current);
302 return current;
303}
304
305static const char *gma_acpi_name(const struct device *dev)
306{
307 return "GFX0";
308}
309
Damien Zammit51fdb922016-01-18 18:34:52 +1100310static struct pci_operations gma_pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530311 .set_subsystem = pci_dev_set_subsystem,
Damien Zammit51fdb922016-01-18 18:34:52 +1100312};
313
314static struct device_operations gma_func0_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +0200315 .read_resources = pci_dev_read_resources,
316 .set_resources = pci_dev_set_resources,
317 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200318 .init = gma_func0_init,
Nico Huber68680dd2020-03-31 17:34:52 +0200319 .ops_pci = &gma_pci_ops,
320 .acpi_name = gma_acpi_name,
321 .write_acpi_tables = gma_write_acpi_tables,
Damien Zammit51fdb922016-01-18 18:34:52 +1100322};
323
324static const unsigned short pci_device_ids[] =
325{
Angel Pons39ff7032020-03-09 21:39:44 +0100326 0xa001, 0,
Damien Zammit51fdb922016-01-18 18:34:52 +1100327};
328
329static const struct pci_driver gma __pci_driver = {
Angel Pons39ff7032020-03-09 21:39:44 +0100330 .ops = &gma_func0_ops,
331 .vendor = PCI_VENDOR_ID_INTEL,
Damien Zammit51fdb922016-01-18 18:34:52 +1100332 .devices = pci_device_ids,
333};