xref: /rk3399_rockchip-uboot/drivers/video/broadwell_igd.c (revision 21342d4aed6c77a4aa7a5b2579b3c23e21aea31a)
197cb0927SSimon Glass /*
297cb0927SSimon Glass  * From coreboot src/soc/intel/broadwell/igd.c
397cb0927SSimon Glass  *
497cb0927SSimon Glass  * Copyright (C) 2016 Google, Inc
597cb0927SSimon Glass  *
697cb0927SSimon Glass  * SPDX-License-Identifier:	GPL-2.0
797cb0927SSimon Glass  */
897cb0927SSimon Glass 
997cb0927SSimon Glass #include <common.h>
1097cb0927SSimon Glass #include <bios_emul.h>
1197cb0927SSimon Glass #include <dm.h>
1297cb0927SSimon Glass #include <vbe.h>
1397cb0927SSimon Glass #include <video.h>
1497cb0927SSimon Glass #include <asm/cpu.h>
1597cb0927SSimon Glass #include <asm/intel_regs.h>
1697cb0927SSimon Glass #include <asm/io.h>
1797cb0927SSimon Glass #include <asm/mtrr.h>
1897cb0927SSimon Glass #include <asm/arch/cpu.h>
1997cb0927SSimon Glass #include <asm/arch/iomap.h>
2097cb0927SSimon Glass #include <asm/arch/pch.h>
2197cb0927SSimon Glass #include "i915_reg.h"
2297cb0927SSimon Glass 
2397cb0927SSimon Glass struct broadwell_igd_priv {
2497cb0927SSimon Glass 	u8 *regs;
2597cb0927SSimon Glass };
2697cb0927SSimon Glass 
2797cb0927SSimon Glass struct broadwell_igd_plat {
2897cb0927SSimon Glass 	u32 dp_hotplug[3];
2997cb0927SSimon Glass 
3097cb0927SSimon Glass 	int port_select;
3197cb0927SSimon Glass 	int power_up_delay;
3297cb0927SSimon Glass 	int power_backlight_on_delay;
3397cb0927SSimon Glass 	int power_down_delay;
3497cb0927SSimon Glass 	int power_backlight_off_delay;
3597cb0927SSimon Glass 	int power_cycle_delay;
3697cb0927SSimon Glass 	int cpu_backlight;
3797cb0927SSimon Glass 	int pch_backlight;
3897cb0927SSimon Glass 	int cdclk;
3997cb0927SSimon Glass 	int pre_graphics_delay;
4097cb0927SSimon Glass };
4197cb0927SSimon Glass 
4297cb0927SSimon Glass #define GT_RETRY		1000
4397cb0927SSimon Glass #define GT_CDCLK_337		0
4497cb0927SSimon Glass #define GT_CDCLK_450		1
4597cb0927SSimon Glass #define GT_CDCLK_540		2
4697cb0927SSimon Glass #define GT_CDCLK_675		3
4797cb0927SSimon Glass 
board_map_oprom_vendev(u32 vendev)4897cb0927SSimon Glass u32 board_map_oprom_vendev(u32 vendev)
4997cb0927SSimon Glass {
5097cb0927SSimon Glass 	return SA_IGD_OPROM_VENDEV;
5197cb0927SSimon Glass }
5297cb0927SSimon Glass 
poll32(u8 * addr,uint mask,uint value)5397cb0927SSimon Glass static int poll32(u8 *addr, uint mask, uint value)
5497cb0927SSimon Glass {
5597cb0927SSimon Glass 	ulong start;
5697cb0927SSimon Glass 
5797cb0927SSimon Glass 	start = get_timer(0);
5897cb0927SSimon Glass 	debug("%s: addr %p = %x\n", __func__, addr, readl(addr));
5997cb0927SSimon Glass 	while ((readl(addr) & mask) != value) {
6097cb0927SSimon Glass 		if (get_timer(start) > GT_RETRY) {
6197cb0927SSimon Glass 			debug("poll32: timeout: %x\n", readl(addr));
6297cb0927SSimon Glass 			return -ETIMEDOUT;
6397cb0927SSimon Glass 		}
6497cb0927SSimon Glass 	}
6597cb0927SSimon Glass 
6697cb0927SSimon Glass 	return 0;
6797cb0927SSimon Glass }
6897cb0927SSimon Glass 
haswell_early_init(struct udevice * dev)6997cb0927SSimon Glass static int haswell_early_init(struct udevice *dev)
7097cb0927SSimon Glass {
7197cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
7297cb0927SSimon Glass 	u8 *regs = priv->regs;
7397cb0927SSimon Glass 	int ret;
7497cb0927SSimon Glass 
7597cb0927SSimon Glass 	/* Enable Force Wake */
7697cb0927SSimon Glass 	writel(0x00000020, regs + 0xa180);
7797cb0927SSimon Glass 	writel(0x00010001, regs + 0xa188);
7897cb0927SSimon Glass 	ret = poll32(regs + 0x130044, 1, 1);
7997cb0927SSimon Glass 	if (ret)
8097cb0927SSimon Glass 		goto err;
8197cb0927SSimon Glass 
8297cb0927SSimon Glass 	/* Enable Counters */
8397cb0927SSimon Glass 	setbits_le32(regs + 0xa248, 0x00000016);
8497cb0927SSimon Glass 
8597cb0927SSimon Glass 	/* GFXPAUSE settings */
8697cb0927SSimon Glass 	writel(0x00070020, regs + 0xa000);
8797cb0927SSimon Glass 
8897cb0927SSimon Glass 	/* ECO Settings */
8997cb0927SSimon Glass 	clrsetbits_le32(regs + 0xa180, ~0xff3fffff, 0x15000000);
9097cb0927SSimon Glass 
9197cb0927SSimon Glass 	/* Enable DOP Clock Gating */
9297cb0927SSimon Glass 	writel(0x000003fd, regs + 0x9424);
9397cb0927SSimon Glass 
9497cb0927SSimon Glass 	/* Enable Unit Level Clock Gating */
9597cb0927SSimon Glass 	writel(0x00000080, regs + 0x9400);
9697cb0927SSimon Glass 	writel(0x40401000, regs + 0x9404);
9797cb0927SSimon Glass 	writel(0x00000000, regs + 0x9408);
9897cb0927SSimon Glass 	writel(0x02000001, regs + 0x940c);
9997cb0927SSimon Glass 
10097cb0927SSimon Glass 	/*
10197cb0927SSimon Glass 	 * RC6 Settings
10297cb0927SSimon Glass 	 */
10397cb0927SSimon Glass 
10497cb0927SSimon Glass 	/* Wake Rate Limits */
10597cb0927SSimon Glass 	setbits_le32(regs + 0xa090, 0x00000000);
10697cb0927SSimon Glass 	setbits_le32(regs + 0xa098, 0x03e80000);
10797cb0927SSimon Glass 	setbits_le32(regs + 0xa09c, 0x00280000);
10897cb0927SSimon Glass 	setbits_le32(regs + 0xa0a8, 0x0001e848);
10997cb0927SSimon Glass 	setbits_le32(regs + 0xa0ac, 0x00000019);
11097cb0927SSimon Glass 
11197cb0927SSimon Glass 	/* Render/Video/Blitter Idle Max Count */
11297cb0927SSimon Glass 	writel(0x0000000a, regs + 0x02054);
11397cb0927SSimon Glass 	writel(0x0000000a, regs + 0x12054);
11497cb0927SSimon Glass 	writel(0x0000000a, regs + 0x22054);
11597cb0927SSimon Glass 	writel(0x0000000a, regs + 0x1a054);
11697cb0927SSimon Glass 
11797cb0927SSimon Glass 	/* RC Sleep / RCx Thresholds */
11897cb0927SSimon Glass 	setbits_le32(regs + 0xa0b0, 0x00000000);
11997cb0927SSimon Glass 	setbits_le32(regs + 0xa0b4, 0x000003e8);
12097cb0927SSimon Glass 	setbits_le32(regs + 0xa0b8, 0x0000c350);
12197cb0927SSimon Glass 
12297cb0927SSimon Glass 	/* RP Settings */
12397cb0927SSimon Glass 	setbits_le32(regs + 0xa010, 0x000f4240);
12497cb0927SSimon Glass 	setbits_le32(regs + 0xa014, 0x12060000);
12597cb0927SSimon Glass 	setbits_le32(regs + 0xa02c, 0x0000e808);
12697cb0927SSimon Glass 	setbits_le32(regs + 0xa030, 0x0003bd08);
12797cb0927SSimon Glass 	setbits_le32(regs + 0xa068, 0x000101d0);
12897cb0927SSimon Glass 	setbits_le32(regs + 0xa06c, 0x00055730);
12997cb0927SSimon Glass 	setbits_le32(regs + 0xa070, 0x0000000a);
13097cb0927SSimon Glass 
13197cb0927SSimon Glass 	/* RP Control */
13297cb0927SSimon Glass 	writel(0x00000b92, regs + 0xa024);
13397cb0927SSimon Glass 
13497cb0927SSimon Glass 	/* HW RC6 Control */
13597cb0927SSimon Glass 	writel(0x88040000, regs + 0xa090);
13697cb0927SSimon Glass 
13797cb0927SSimon Glass 	/* Video Frequency Request */
13897cb0927SSimon Glass 	writel(0x08000000, regs + 0xa00c);
13997cb0927SSimon Glass 
14097cb0927SSimon Glass 	/* Set RC6 VIDs */
14197cb0927SSimon Glass 	ret = poll32(regs + 0x138124, (1 << 31), 0);
14297cb0927SSimon Glass 	if (ret)
14397cb0927SSimon Glass 		goto err;
14497cb0927SSimon Glass 	writel(0, regs + 0x138128);
14597cb0927SSimon Glass 	writel(0x80000004, regs + 0x138124);
14697cb0927SSimon Glass 	ret = poll32(regs + 0x138124, (1 << 31), 0);
14797cb0927SSimon Glass 	if (ret)
14897cb0927SSimon Glass 		goto err;
14997cb0927SSimon Glass 
15097cb0927SSimon Glass 	/* Enable PM Interrupts */
15197cb0927SSimon Glass 	writel(0x03000076, regs + 0x4402c);
15297cb0927SSimon Glass 
15397cb0927SSimon Glass 	/* Enable RC6 in idle */
15497cb0927SSimon Glass 	writel(0x00040000, regs + 0xa094);
15597cb0927SSimon Glass 
15697cb0927SSimon Glass 	return 0;
15797cb0927SSimon Glass err:
15897cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
15997cb0927SSimon Glass 	return ret;
16097cb0927SSimon Glass };
16197cb0927SSimon Glass 
haswell_late_init(struct udevice * dev)16297cb0927SSimon Glass static int haswell_late_init(struct udevice *dev)
16397cb0927SSimon Glass {
16497cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
16597cb0927SSimon Glass 	u8 *regs = priv->regs;
16697cb0927SSimon Glass 	int ret;
16797cb0927SSimon Glass 
16897cb0927SSimon Glass 	/* Lock settings */
16997cb0927SSimon Glass 	setbits_le32(regs + 0x0a248, (1 << 31));
17097cb0927SSimon Glass 	setbits_le32(regs + 0x0a004, (1 << 4));
17197cb0927SSimon Glass 	setbits_le32(regs + 0x0a080, (1 << 2));
17297cb0927SSimon Glass 	setbits_le32(regs + 0x0a180, (1 << 31));
17397cb0927SSimon Glass 
17497cb0927SSimon Glass 	/* Disable Force Wake */
17597cb0927SSimon Glass 	writel(0x00010000, regs + 0xa188);
17697cb0927SSimon Glass 	ret = poll32(regs + 0x130044, 1, 0);
17797cb0927SSimon Glass 	if (ret)
17897cb0927SSimon Glass 		goto err;
17997cb0927SSimon Glass 	writel(0x00000001, regs + 0xa188);
18097cb0927SSimon Glass 
18197cb0927SSimon Glass 	/* Enable power well for DP and Audio */
18297cb0927SSimon Glass 	setbits_le32(regs + 0x45400, (1 << 31));
18397cb0927SSimon Glass 	ret = poll32(regs + 0x45400, 1 << 30, 1 << 30);
18497cb0927SSimon Glass 	if (ret)
18597cb0927SSimon Glass 		goto err;
18697cb0927SSimon Glass 
18797cb0927SSimon Glass 	return 0;
18897cb0927SSimon Glass err:
18997cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
19097cb0927SSimon Glass 	return ret;
19197cb0927SSimon Glass };
19297cb0927SSimon Glass 
broadwell_early_init(struct udevice * dev)19397cb0927SSimon Glass static int broadwell_early_init(struct udevice *dev)
19497cb0927SSimon Glass {
19597cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
19697cb0927SSimon Glass 	u8 *regs = priv->regs;
19797cb0927SSimon Glass 	int ret;
19897cb0927SSimon Glass 
19997cb0927SSimon Glass 	/* Enable Force Wake */
20097cb0927SSimon Glass 	writel(0x00010001, regs + 0xa188);
20197cb0927SSimon Glass 	ret = poll32(regs + 0x130044, 1, 1);
20297cb0927SSimon Glass 	if (ret)
20397cb0927SSimon Glass 		goto err;
20497cb0927SSimon Glass 
20597cb0927SSimon Glass 	/* Enable push bus metric control and shift */
20697cb0927SSimon Glass 	writel(0x00000004, regs + 0xa248);
20797cb0927SSimon Glass 	writel(0x000000ff, regs + 0xa250);
20897cb0927SSimon Glass 	writel(0x00000010, regs + 0xa25c);
20997cb0927SSimon Glass 
21097cb0927SSimon Glass 	/* GFXPAUSE settings (set based on stepping) */
21197cb0927SSimon Glass 
21297cb0927SSimon Glass 	/* ECO Settings */
21397cb0927SSimon Glass 	writel(0x45200000, regs + 0xa180);
21497cb0927SSimon Glass 
21597cb0927SSimon Glass 	/* Enable DOP Clock Gating */
21697cb0927SSimon Glass 	writel(0x000000fd, regs + 0x9424);
21797cb0927SSimon Glass 
21897cb0927SSimon Glass 	/* Enable Unit Level Clock Gating */
21997cb0927SSimon Glass 	writel(0x00000000, regs + 0x9400);
22097cb0927SSimon Glass 	writel(0x40401000, regs + 0x9404);
22197cb0927SSimon Glass 	writel(0x00000000, regs + 0x9408);
22297cb0927SSimon Glass 	writel(0x02000001, regs + 0x940c);
22397cb0927SSimon Glass 	writel(0x0000000a, regs + 0x1a054);
22497cb0927SSimon Glass 
22597cb0927SSimon Glass 	/* Video Frequency Request */
22697cb0927SSimon Glass 	writel(0x08000000, regs + 0xa00c);
22797cb0927SSimon Glass 
22897cb0927SSimon Glass 	writel(0x00000009, regs + 0x138158);
22997cb0927SSimon Glass 	writel(0x0000000d, regs + 0x13815c);
23097cb0927SSimon Glass 
23197cb0927SSimon Glass 	/*
23297cb0927SSimon Glass 	 * RC6 Settings
23397cb0927SSimon Glass 	 */
23497cb0927SSimon Glass 
23597cb0927SSimon Glass 	/* Wake Rate Limits */
23697cb0927SSimon Glass 	clrsetbits_le32(regs + 0x0a090, ~0, 0);
23797cb0927SSimon Glass 	setbits_le32(regs + 0x0a098, 0x03e80000);
23897cb0927SSimon Glass 	setbits_le32(regs + 0x0a09c, 0x00280000);
23997cb0927SSimon Glass 	setbits_le32(regs + 0x0a0a8, 0x0001e848);
24097cb0927SSimon Glass 	setbits_le32(regs + 0x0a0ac, 0x00000019);
24197cb0927SSimon Glass 
24297cb0927SSimon Glass 	/* Render/Video/Blitter Idle Max Count */
24397cb0927SSimon Glass 	writel(0x0000000a, regs + 0x02054);
24497cb0927SSimon Glass 	writel(0x0000000a, regs + 0x12054);
24597cb0927SSimon Glass 	writel(0x0000000a, regs + 0x22054);
24697cb0927SSimon Glass 
24797cb0927SSimon Glass 	/* RC Sleep / RCx Thresholds */
24897cb0927SSimon Glass 	setbits_le32(regs + 0x0a0b0, 0x00000000);
24997cb0927SSimon Glass 	setbits_le32(regs + 0x0a0b8, 0x00000271);
25097cb0927SSimon Glass 
25197cb0927SSimon Glass 	/* RP Settings */
25297cb0927SSimon Glass 	setbits_le32(regs + 0x0a010, 0x000f4240);
25397cb0927SSimon Glass 	setbits_le32(regs + 0x0a014, 0x12060000);
25497cb0927SSimon Glass 	setbits_le32(regs + 0x0a02c, 0x0000e808);
25597cb0927SSimon Glass 	setbits_le32(regs + 0x0a030, 0x0003bd08);
25697cb0927SSimon Glass 	setbits_le32(regs + 0x0a068, 0x000101d0);
25797cb0927SSimon Glass 	setbits_le32(regs + 0x0a06c, 0x00055730);
25897cb0927SSimon Glass 	setbits_le32(regs + 0x0a070, 0x0000000a);
25997cb0927SSimon Glass 	setbits_le32(regs + 0x0a168, 0x00000006);
26097cb0927SSimon Glass 
26197cb0927SSimon Glass 	/* RP Control */
26297cb0927SSimon Glass 	writel(0x00000b92, regs + 0xa024);
26397cb0927SSimon Glass 
26497cb0927SSimon Glass 	/* HW RC6 Control */
26597cb0927SSimon Glass 	writel(0x90040000, regs + 0xa090);
26697cb0927SSimon Glass 
26797cb0927SSimon Glass 	/* Set RC6 VIDs */
26897cb0927SSimon Glass 	ret = poll32(regs + 0x138124, (1 << 31), 0);
26997cb0927SSimon Glass 	if (ret)
27097cb0927SSimon Glass 		goto err;
27197cb0927SSimon Glass 	writel(0, regs + 0x138128);
27297cb0927SSimon Glass 	writel(0x80000004, regs + 0x138124);
27397cb0927SSimon Glass 	ret = poll32(regs + 0x138124, (1 << 31), 0);
27497cb0927SSimon Glass 	if (ret)
27597cb0927SSimon Glass 		goto err;
27697cb0927SSimon Glass 
27797cb0927SSimon Glass 	/* Enable PM Interrupts */
27897cb0927SSimon Glass 	writel(0x03000076, regs + 0x4402c);
27997cb0927SSimon Glass 
28097cb0927SSimon Glass 	/* Enable RC6 in idle */
28197cb0927SSimon Glass 	writel(0x00040000, regs + 0xa094);
28297cb0927SSimon Glass 
28397cb0927SSimon Glass 	return 0;
28497cb0927SSimon Glass err:
28597cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
28697cb0927SSimon Glass 	return ret;
28797cb0927SSimon Glass }
28897cb0927SSimon Glass 
broadwell_late_init(struct udevice * dev)28997cb0927SSimon Glass static int broadwell_late_init(struct udevice *dev)
29097cb0927SSimon Glass {
29197cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
29297cb0927SSimon Glass 	u8 *regs = priv->regs;
29397cb0927SSimon Glass 	int ret;
29497cb0927SSimon Glass 
29597cb0927SSimon Glass 	/* Lock settings */
29697cb0927SSimon Glass 	setbits_le32(regs + 0x0a248, 1 << 31);
29797cb0927SSimon Glass 	setbits_le32(regs + 0x0a000, 1 << 18);
29897cb0927SSimon Glass 	setbits_le32(regs + 0x0a180, 1 << 31);
29997cb0927SSimon Glass 
30097cb0927SSimon Glass 	/* Disable Force Wake */
30197cb0927SSimon Glass 	writel(0x00010000, regs + 0xa188);
30297cb0927SSimon Glass 	ret = poll32(regs + 0x130044, 1, 0);
30397cb0927SSimon Glass 	if (ret)
30497cb0927SSimon Glass 		goto err;
30597cb0927SSimon Glass 
30697cb0927SSimon Glass 	/* Enable power well for DP and Audio */
30797cb0927SSimon Glass 	setbits_le32(regs + 0x45400, 1 << 31);
30897cb0927SSimon Glass 	ret = poll32(regs + 0x45400, 1 << 30, 1 << 30);
30997cb0927SSimon Glass 	if (ret)
31097cb0927SSimon Glass 		goto err;
31197cb0927SSimon Glass 
31297cb0927SSimon Glass 	return 0;
31397cb0927SSimon Glass err:
31497cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
31597cb0927SSimon Glass 	return ret;
31697cb0927SSimon Glass };
31797cb0927SSimon Glass 
31897cb0927SSimon Glass 
gtt_read(struct broadwell_igd_priv * priv,unsigned long reg)31997cb0927SSimon Glass static unsigned long gtt_read(struct broadwell_igd_priv *priv,
32097cb0927SSimon Glass 			      unsigned long reg)
32197cb0927SSimon Glass {
322720873bfSMasahiro Yamada 	return readl(priv->regs + reg);
32397cb0927SSimon Glass }
32497cb0927SSimon Glass 
gtt_write(struct broadwell_igd_priv * priv,unsigned long reg,unsigned long data)32597cb0927SSimon Glass static void gtt_write(struct broadwell_igd_priv *priv, unsigned long reg,
32697cb0927SSimon Glass 		      unsigned long data)
32797cb0927SSimon Glass {
32897cb0927SSimon Glass 	writel(data, priv->regs + reg);
32997cb0927SSimon Glass }
33097cb0927SSimon Glass 
gtt_clrsetbits(struct broadwell_igd_priv * priv,u32 reg,u32 bic,u32 or)33197cb0927SSimon Glass static inline void gtt_clrsetbits(struct broadwell_igd_priv *priv, u32 reg,
33297cb0927SSimon Glass 				  u32 bic, u32 or)
33397cb0927SSimon Glass {
33497cb0927SSimon Glass 	clrsetbits_le32(priv->regs + reg, bic, or);
33597cb0927SSimon Glass }
33697cb0927SSimon Glass 
gtt_poll(struct broadwell_igd_priv * priv,u32 reg,u32 mask,u32 value)33797cb0927SSimon Glass static int gtt_poll(struct broadwell_igd_priv *priv, u32 reg, u32 mask,
33897cb0927SSimon Glass 		    u32 value)
33997cb0927SSimon Glass {
34097cb0927SSimon Glass 	unsigned try = GT_RETRY;
34197cb0927SSimon Glass 	u32 data;
34297cb0927SSimon Glass 
34397cb0927SSimon Glass 	while (try--) {
34497cb0927SSimon Glass 		data = gtt_read(priv, reg);
34597cb0927SSimon Glass 		if ((data & mask) == value)
34697cb0927SSimon Glass 			return 0;
34797cb0927SSimon Glass 		udelay(10);
34897cb0927SSimon Glass 	}
34997cb0927SSimon Glass 
35097cb0927SSimon Glass 	debug("GT init timeout\n");
35197cb0927SSimon Glass 	return -ETIMEDOUT;
35297cb0927SSimon Glass }
35397cb0927SSimon Glass 
igd_setup_panel(struct udevice * dev)35497cb0927SSimon Glass static void igd_setup_panel(struct udevice *dev)
35597cb0927SSimon Glass {
35697cb0927SSimon Glass 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
35797cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
35897cb0927SSimon Glass 	u32 reg32;
35997cb0927SSimon Glass 
36097cb0927SSimon Glass 	/* Setup Digital Port Hotplug */
36197cb0927SSimon Glass 	reg32 = (plat->dp_hotplug[0] & 0x7) << 2;
36297cb0927SSimon Glass 	reg32 |= (plat->dp_hotplug[1] & 0x7) << 10;
36397cb0927SSimon Glass 	reg32 |= (plat->dp_hotplug[2] & 0x7) << 18;
36497cb0927SSimon Glass 	gtt_write(priv, PCH_PORT_HOTPLUG, reg32);
36597cb0927SSimon Glass 
36697cb0927SSimon Glass 	/* Setup Panel Power On Delays */
36797cb0927SSimon Glass 	reg32 = (plat->port_select & 0x3) << 30;
36897cb0927SSimon Glass 	reg32 |= (plat->power_up_delay & 0x1fff) << 16;
36997cb0927SSimon Glass 	reg32 |= (plat->power_backlight_on_delay & 0x1fff);
37097cb0927SSimon Glass 	gtt_write(priv, PCH_PP_ON_DELAYS, reg32);
37197cb0927SSimon Glass 
37297cb0927SSimon Glass 	/* Setup Panel Power Off Delays */
37397cb0927SSimon Glass 	reg32 = (plat->power_down_delay & 0x1fff) << 16;
37497cb0927SSimon Glass 	reg32 |= (plat->power_backlight_off_delay & 0x1fff);
37597cb0927SSimon Glass 	gtt_write(priv, PCH_PP_OFF_DELAYS, reg32);
37697cb0927SSimon Glass 
37797cb0927SSimon Glass 	/* Setup Panel Power Cycle Delay */
37897cb0927SSimon Glass 	if (plat->power_cycle_delay) {
37997cb0927SSimon Glass 		reg32 = gtt_read(priv, PCH_PP_DIVISOR);
38097cb0927SSimon Glass 		reg32 &= ~0xff;
38197cb0927SSimon Glass 		reg32 |= plat->power_cycle_delay & 0xff;
38297cb0927SSimon Glass 		gtt_write(priv, PCH_PP_DIVISOR, reg32);
38397cb0927SSimon Glass 	}
38497cb0927SSimon Glass 
38597cb0927SSimon Glass 	/* Enable Backlight if needed */
38697cb0927SSimon Glass 	if (plat->cpu_backlight) {
38797cb0927SSimon Glass 		gtt_write(priv, BLC_PWM_CPU_CTL2, BLC_PWM2_ENABLE);
38897cb0927SSimon Glass 		gtt_write(priv, BLC_PWM_CPU_CTL, plat->cpu_backlight);
38997cb0927SSimon Glass 	}
39097cb0927SSimon Glass 	if (plat->pch_backlight) {
39197cb0927SSimon Glass 		gtt_write(priv, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE);
39297cb0927SSimon Glass 		gtt_write(priv, BLC_PWM_PCH_CTL2, plat->pch_backlight);
39397cb0927SSimon Glass 	}
39497cb0927SSimon Glass }
39597cb0927SSimon Glass 
igd_cdclk_init_haswell(struct udevice * dev)39697cb0927SSimon Glass static int igd_cdclk_init_haswell(struct udevice *dev)
39797cb0927SSimon Glass {
39897cb0927SSimon Glass 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
39997cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
40097cb0927SSimon Glass 	int cdclk = plat->cdclk;
40197cb0927SSimon Glass 	u16 devid;
40297cb0927SSimon Glass 	int gpu_is_ulx = 0;
40397cb0927SSimon Glass 	u32 dpdiv, lpcll;
40497cb0927SSimon Glass 	int ret;
40597cb0927SSimon Glass 
40697cb0927SSimon Glass 	dm_pci_read_config16(dev, PCI_DEVICE_ID, &devid);
40797cb0927SSimon Glass 
40897cb0927SSimon Glass 	/* Check for ULX GT1 or GT2 */
40997cb0927SSimon Glass 	if (devid == 0x0a0e || devid == 0x0a1e)
41097cb0927SSimon Glass 		gpu_is_ulx = 1;
41197cb0927SSimon Glass 
41297cb0927SSimon Glass 	/* 675MHz is not supported on haswell */
41397cb0927SSimon Glass 	if (cdclk == GT_CDCLK_675)
41497cb0927SSimon Glass 		cdclk = GT_CDCLK_337;
41597cb0927SSimon Glass 
41697cb0927SSimon Glass 	/* If CD clock is fixed or ULT then set to 450MHz */
41797cb0927SSimon Glass 	if ((gtt_read(priv, 0x42014) & 0x1000000) || cpu_is_ult())
41897cb0927SSimon Glass 		cdclk = GT_CDCLK_450;
41997cb0927SSimon Glass 
42097cb0927SSimon Glass 	/* 540MHz is not supported on ULX */
42197cb0927SSimon Glass 	if (gpu_is_ulx && cdclk == GT_CDCLK_540)
42297cb0927SSimon Glass 		cdclk = GT_CDCLK_337;
42397cb0927SSimon Glass 
42497cb0927SSimon Glass 	/* 337.5MHz is not supported on non-ULT/ULX */
42597cb0927SSimon Glass 	if (!gpu_is_ulx && !cpu_is_ult() && cdclk == GT_CDCLK_337)
42697cb0927SSimon Glass 		cdclk = GT_CDCLK_450;
42797cb0927SSimon Glass 
42897cb0927SSimon Glass 	/* Set variables based on CD Clock setting */
42997cb0927SSimon Glass 	switch (cdclk) {
43097cb0927SSimon Glass 	case GT_CDCLK_337:
43197cb0927SSimon Glass 		dpdiv = 169;
43297cb0927SSimon Glass 		lpcll = (1 << 26);
43397cb0927SSimon Glass 		break;
43497cb0927SSimon Glass 	case GT_CDCLK_450:
43597cb0927SSimon Glass 		dpdiv = 225;
43697cb0927SSimon Glass 		lpcll = 0;
43797cb0927SSimon Glass 		break;
43897cb0927SSimon Glass 	case GT_CDCLK_540:
43997cb0927SSimon Glass 		dpdiv = 270;
44097cb0927SSimon Glass 		lpcll = (1 << 26);
44197cb0927SSimon Glass 		break;
44297cb0927SSimon Glass 	default:
44397cb0927SSimon Glass 		ret = -EDOM;
44497cb0927SSimon Glass 		goto err;
44597cb0927SSimon Glass 	}
44697cb0927SSimon Glass 
44797cb0927SSimon Glass 	/* Set LPCLL_CTL CD Clock Frequency Select */
44897cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll);
44997cb0927SSimon Glass 
45097cb0927SSimon Glass 	/* ULX: Inform power controller of selected frequency */
45197cb0927SSimon Glass 	if (gpu_is_ulx) {
45297cb0927SSimon Glass 		if (cdclk == GT_CDCLK_450)
45397cb0927SSimon Glass 			gtt_write(priv, 0x138128, 0x00000000); /* 450MHz */
45497cb0927SSimon Glass 		else
45597cb0927SSimon Glass 			gtt_write(priv, 0x138128, 0x00000001); /* 337.5MHz */
45697cb0927SSimon Glass 		gtt_write(priv, 0x13812c, 0x00000000);
45797cb0927SSimon Glass 		gtt_write(priv, 0x138124, 0x80000017);
45897cb0927SSimon Glass 	}
45997cb0927SSimon Glass 
46097cb0927SSimon Glass 	/* Set CPU DP AUX 2X bit clock dividers */
46197cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv);
46297cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv);
46397cb0927SSimon Glass 
46497cb0927SSimon Glass 	return 0;
46597cb0927SSimon Glass err:
46697cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
46797cb0927SSimon Glass 	return ret;
46897cb0927SSimon Glass }
46997cb0927SSimon Glass 
igd_cdclk_init_broadwell(struct udevice * dev)47097cb0927SSimon Glass static int igd_cdclk_init_broadwell(struct udevice *dev)
47197cb0927SSimon Glass {
47297cb0927SSimon Glass 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
47397cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
47497cb0927SSimon Glass 	int cdclk = plat->cdclk;
47597cb0927SSimon Glass 	u32 dpdiv, lpcll, pwctl, cdset;
47697cb0927SSimon Glass 	int ret;
47797cb0927SSimon Glass 
47897cb0927SSimon Glass 	/* Inform power controller of upcoming frequency change */
47997cb0927SSimon Glass 	gtt_write(priv, 0x138128, 0);
48097cb0927SSimon Glass 	gtt_write(priv, 0x13812c, 0);
48197cb0927SSimon Glass 	gtt_write(priv, 0x138124, 0x80000018);
48297cb0927SSimon Glass 
48397cb0927SSimon Glass 	/* Poll GT driver mailbox for run/busy clear */
48497cb0927SSimon Glass 	if (gtt_poll(priv, 0x138124, 1 << 31, 0 << 31))
48597cb0927SSimon Glass 		cdclk = GT_CDCLK_450;
48697cb0927SSimon Glass 
48797cb0927SSimon Glass 	if (gtt_read(priv, 0x42014) & 0x1000000) {
48897cb0927SSimon Glass 		/* If CD clock is fixed then set to 450MHz */
48997cb0927SSimon Glass 		cdclk = GT_CDCLK_450;
49097cb0927SSimon Glass 	} else {
49197cb0927SSimon Glass 		/* Program CD clock to highest supported freq */
49297cb0927SSimon Glass 		if (cpu_is_ult())
49397cb0927SSimon Glass 			cdclk = GT_CDCLK_540;
49497cb0927SSimon Glass 		else
49597cb0927SSimon Glass 			cdclk = GT_CDCLK_675;
49697cb0927SSimon Glass 	}
49797cb0927SSimon Glass 
49897cb0927SSimon Glass 	/* CD clock frequency 675MHz not supported on ULT */
49997cb0927SSimon Glass 	if (cpu_is_ult() && cdclk == GT_CDCLK_675)
50097cb0927SSimon Glass 		cdclk = GT_CDCLK_540;
50197cb0927SSimon Glass 
50297cb0927SSimon Glass 	/* Set variables based on CD Clock setting */
50397cb0927SSimon Glass 	switch (cdclk) {
50497cb0927SSimon Glass 	case GT_CDCLK_337:
50597cb0927SSimon Glass 		cdset = 337;
50697cb0927SSimon Glass 		lpcll = (1 << 27);
50797cb0927SSimon Glass 		pwctl = 2;
50897cb0927SSimon Glass 		dpdiv = 169;
50997cb0927SSimon Glass 		break;
51097cb0927SSimon Glass 	case GT_CDCLK_450:
51197cb0927SSimon Glass 		cdset = 449;
51297cb0927SSimon Glass 		lpcll = 0;
51397cb0927SSimon Glass 		pwctl = 0;
51497cb0927SSimon Glass 		dpdiv = 225;
51597cb0927SSimon Glass 		break;
51697cb0927SSimon Glass 	case GT_CDCLK_540:
51797cb0927SSimon Glass 		cdset = 539;
51897cb0927SSimon Glass 		lpcll = (1 << 26);
51997cb0927SSimon Glass 		pwctl = 1;
52097cb0927SSimon Glass 		dpdiv = 270;
52197cb0927SSimon Glass 		break;
52297cb0927SSimon Glass 	case GT_CDCLK_675:
52397cb0927SSimon Glass 		cdset = 674;
52497cb0927SSimon Glass 		lpcll = (1 << 26) | (1 << 27);
52597cb0927SSimon Glass 		pwctl = 3;
52697cb0927SSimon Glass 		dpdiv = 338;
52797cb0927SSimon Glass 		break;
52897cb0927SSimon Glass 	default:
52997cb0927SSimon Glass 		ret = -EDOM;
53097cb0927SSimon Glass 		goto err;
53197cb0927SSimon Glass 	}
53297cb0927SSimon Glass 	debug("%s: frequency = %d\n", __func__, cdclk);
53397cb0927SSimon Glass 
53497cb0927SSimon Glass 	/* Set LPCLL_CTL CD Clock Frequency Select */
53597cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll);
53697cb0927SSimon Glass 
53797cb0927SSimon Glass 	/* Inform power controller of selected frequency */
53897cb0927SSimon Glass 	gtt_write(priv, 0x138128, pwctl);
53997cb0927SSimon Glass 	gtt_write(priv, 0x13812c, 0);
54097cb0927SSimon Glass 	gtt_write(priv, 0x138124, 0x80000017);
54197cb0927SSimon Glass 
54297cb0927SSimon Glass 	/* Program CD Clock Frequency */
54397cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x46200, ~0xfffffc00, cdset);
54497cb0927SSimon Glass 
54597cb0927SSimon Glass 	/* Set CPU DP AUX 2X bit clock dividers */
54697cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv);
54797cb0927SSimon Glass 	gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv);
54897cb0927SSimon Glass 
54997cb0927SSimon Glass 	return 0;
55097cb0927SSimon Glass err:
55197cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
55297cb0927SSimon Glass 	return ret;
55397cb0927SSimon Glass }
55497cb0927SSimon Glass 
systemagent_revision(struct udevice * bus)55597cb0927SSimon Glass u8 systemagent_revision(struct udevice *bus)
55697cb0927SSimon Glass {
55797cb0927SSimon Glass 	ulong val;
55897cb0927SSimon Glass 
55997cb0927SSimon Glass 	pci_bus_read_config(bus, PCI_BDF(0, 0, 0), PCI_REVISION_ID, &val,
56097cb0927SSimon Glass 			    PCI_SIZE_32);
56197cb0927SSimon Glass 
56297cb0927SSimon Glass 	return val;
56397cb0927SSimon Glass }
56497cb0927SSimon Glass 
igd_pre_init(struct udevice * dev,bool is_broadwell)56597cb0927SSimon Glass static int igd_pre_init(struct udevice *dev, bool is_broadwell)
56697cb0927SSimon Glass {
56797cb0927SSimon Glass 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
56897cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
56997cb0927SSimon Glass 	u32 rp1_gfx_freq;
57097cb0927SSimon Glass 	int ret;
57197cb0927SSimon Glass 
57297cb0927SSimon Glass 	mdelay(plat->pre_graphics_delay);
57397cb0927SSimon Glass 
57497cb0927SSimon Glass 	/* Early init steps */
57597cb0927SSimon Glass 	if (is_broadwell) {
57697cb0927SSimon Glass 		ret = broadwell_early_init(dev);
57797cb0927SSimon Glass 		if (ret)
57897cb0927SSimon Glass 			goto err;
57997cb0927SSimon Glass 
58097cb0927SSimon Glass 		/* Set GFXPAUSE based on stepping */
58197cb0927SSimon Glass 		if (cpu_get_stepping() <= (CPUID_BROADWELL_E0 & 0xf) &&
58297cb0927SSimon Glass 		    systemagent_revision(pci_get_controller(dev)) <= 9) {
58397cb0927SSimon Glass 			gtt_write(priv, 0xa000, 0x300ff);
58497cb0927SSimon Glass 		} else {
58597cb0927SSimon Glass 			gtt_write(priv, 0xa000, 0x30020);
58697cb0927SSimon Glass 		}
58797cb0927SSimon Glass 	} else {
58897cb0927SSimon Glass 		ret = haswell_early_init(dev);
58997cb0927SSimon Glass 		if (ret)
59097cb0927SSimon Glass 			goto err;
59197cb0927SSimon Glass 	}
59297cb0927SSimon Glass 
59397cb0927SSimon Glass 	/* Set RP1 graphics frequency */
59497cb0927SSimon Glass 	rp1_gfx_freq = (readl(MCHBAR_REG(0x5998)) >> 8) & 0xff;
59597cb0927SSimon Glass 	gtt_write(priv, 0xa008, rp1_gfx_freq << 24);
59697cb0927SSimon Glass 
59797cb0927SSimon Glass 	/* Post VBIOS panel setup */
59897cb0927SSimon Glass 	igd_setup_panel(dev);
59997cb0927SSimon Glass 
60097cb0927SSimon Glass 	return 0;
60197cb0927SSimon Glass err:
60297cb0927SSimon Glass 	debug("%s: ret=%d\n", __func__, ret);
60397cb0927SSimon Glass 	return ret;
60497cb0927SSimon Glass }
60597cb0927SSimon Glass 
igd_post_init(struct udevice * dev,bool is_broadwell)60697cb0927SSimon Glass static int igd_post_init(struct udevice *dev, bool is_broadwell)
60797cb0927SSimon Glass {
60897cb0927SSimon Glass 	int ret;
60997cb0927SSimon Glass 
61097cb0927SSimon Glass 	/* Late init steps */
61197cb0927SSimon Glass 	if (is_broadwell) {
61297cb0927SSimon Glass 		ret = igd_cdclk_init_broadwell(dev);
61397cb0927SSimon Glass 		if (ret)
61497cb0927SSimon Glass 			return ret;
61597cb0927SSimon Glass 		ret = broadwell_late_init(dev);
61697cb0927SSimon Glass 		if (ret)
61797cb0927SSimon Glass 			return ret;
61897cb0927SSimon Glass 	} else {
61997cb0927SSimon Glass 		igd_cdclk_init_haswell(dev);
62097cb0927SSimon Glass 		ret = haswell_late_init(dev);
62197cb0927SSimon Glass 		if (ret)
62297cb0927SSimon Glass 			return ret;
62397cb0927SSimon Glass 	}
62497cb0927SSimon Glass 
62597cb0927SSimon Glass 	return 0;
62697cb0927SSimon Glass }
62797cb0927SSimon Glass 
broadwell_igd_int15_handler(void)62897cb0927SSimon Glass static int broadwell_igd_int15_handler(void)
62997cb0927SSimon Glass {
63097cb0927SSimon Glass 	int res = 0;
63197cb0927SSimon Glass 
63297cb0927SSimon Glass 	debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX);
63397cb0927SSimon Glass 
63497cb0927SSimon Glass 	switch (M.x86.R_AX) {
63597cb0927SSimon Glass 	case 0x5f35:
63697cb0927SSimon Glass 		/*
63797cb0927SSimon Glass 		 * Boot Display Device Hook:
63897cb0927SSimon Glass 		 *  bit 0 = CRT
63997cb0927SSimon Glass 		 *  bit 1 = TV (eDP)
64097cb0927SSimon Glass 		 *  bit 2 = EFP
64197cb0927SSimon Glass 		 *  bit 3 = LFP
64297cb0927SSimon Glass 		 *  bit 4 = CRT2
64397cb0927SSimon Glass 		 *  bit 5 = TV2 (eDP)
64497cb0927SSimon Glass 		 *  bit 6 = EFP2
64597cb0927SSimon Glass 		 *  bit 7 = LFP2
64697cb0927SSimon Glass 		 */
64797cb0927SSimon Glass 		M.x86.R_AX = 0x005f;
64897cb0927SSimon Glass 		M.x86.R_CX = 0x0000; /* Use video bios default */
64997cb0927SSimon Glass 		res = 1;
65097cb0927SSimon Glass 		break;
65197cb0927SSimon Glass 	default:
65297cb0927SSimon Glass 		debug("Unknown INT15 function %04x!\n", M.x86.R_AX);
65397cb0927SSimon Glass 		break;
65497cb0927SSimon Glass 	}
65597cb0927SSimon Glass 
65697cb0927SSimon Glass 	return res;
65797cb0927SSimon Glass }
65897cb0927SSimon Glass 
broadwell_igd_probe(struct udevice * dev)65997cb0927SSimon Glass static int broadwell_igd_probe(struct udevice *dev)
66097cb0927SSimon Glass {
66197cb0927SSimon Glass 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
66297cb0927SSimon Glass 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
66397cb0927SSimon Glass 	bool is_broadwell;
66497cb0927SSimon Glass 	int ret;
66597cb0927SSimon Glass 
66697cb0927SSimon Glass 	if (!ll_boot_init()) {
66797cb0927SSimon Glass 		/*
66897cb0927SSimon Glass 		 * If we are running from EFI or coreboot, this driver can't
66997cb0927SSimon Glass 		 * work.
67097cb0927SSimon Glass 		 */
67197cb0927SSimon Glass 		printf("Not available (previous bootloader prevents it)\n");
67297cb0927SSimon Glass 		return -EPERM;
67397cb0927SSimon Glass 	}
67497cb0927SSimon Glass 	is_broadwell = cpu_get_family_model() == BROADWELL_FAMILY_ULT;
67597cb0927SSimon Glass 	bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display");
67697cb0927SSimon Glass 	debug("%s: is_broadwell=%d\n", __func__, is_broadwell);
67797cb0927SSimon Glass 	ret = igd_pre_init(dev, is_broadwell);
67897cb0927SSimon Glass 	if (!ret) {
679443ffe50SSimon Glass 		ret = vbe_setup_video(dev, broadwell_igd_int15_handler);
680443ffe50SSimon Glass 		if (ret)
681443ffe50SSimon Glass 			debug("failed to run video BIOS: %d\n", ret);
68297cb0927SSimon Glass 	}
68397cb0927SSimon Glass 	if (!ret)
68497cb0927SSimon Glass 		ret = igd_post_init(dev, is_broadwell);
68597cb0927SSimon Glass 	bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
68697cb0927SSimon Glass 	if (ret)
68797cb0927SSimon Glass 		return ret;
68897cb0927SSimon Glass 
689443ffe50SSimon Glass 	/* Use write-combining for the graphics memory, 256MB */
690443ffe50SSimon Glass 	ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20);
69197cb0927SSimon Glass 	if (!ret)
69297cb0927SSimon Glass 		ret = mtrr_commit(true);
69397cb0927SSimon Glass 	if (ret && ret != -ENOSYS) {
69497cb0927SSimon Glass 		printf("Failed to add MTRR: Display will be slow (err %d)\n",
69597cb0927SSimon Glass 		       ret);
69697cb0927SSimon Glass 	}
69797cb0927SSimon Glass 
698443ffe50SSimon Glass 	debug("fb=%lx, size %x, display size=%d %d %d\n", plat->base,
699443ffe50SSimon Glass 	      plat->size, uc_priv->xsize, uc_priv->ysize, uc_priv->bpix);
70097cb0927SSimon Glass 
70197cb0927SSimon Glass 	return 0;
70297cb0927SSimon Glass }
70397cb0927SSimon Glass 
broadwell_igd_ofdata_to_platdata(struct udevice * dev)70497cb0927SSimon Glass static int broadwell_igd_ofdata_to_platdata(struct udevice *dev)
70597cb0927SSimon Glass {
70697cb0927SSimon Glass 	struct broadwell_igd_plat *plat = dev_get_platdata(dev);
70797cb0927SSimon Glass 	struct broadwell_igd_priv *priv = dev_get_priv(dev);
708*e160f7d4SSimon Glass 	int node = dev_of_offset(dev);
70997cb0927SSimon Glass 	const void *blob = gd->fdt_blob;
71097cb0927SSimon Glass 
71197cb0927SSimon Glass 	if (fdtdec_get_int_array(blob, node, "intel,dp-hotplug",
71297cb0927SSimon Glass 				 plat->dp_hotplug,
71397cb0927SSimon Glass 				 ARRAY_SIZE(plat->dp_hotplug)))
71497cb0927SSimon Glass 		return -EINVAL;
71597cb0927SSimon Glass 	plat->port_select = fdtdec_get_int(blob, node, "intel,port-select", 0);
71697cb0927SSimon Glass 	plat->power_cycle_delay = fdtdec_get_int(blob, node,
71797cb0927SSimon Glass 			"intel,power-cycle-delay", 0);
71897cb0927SSimon Glass 	plat->power_up_delay = fdtdec_get_int(blob, node,
71997cb0927SSimon Glass 			"intel,power-up-delay", 0);
72097cb0927SSimon Glass 	plat->power_down_delay = fdtdec_get_int(blob, node,
72197cb0927SSimon Glass 			"intel,power-down-delay", 0);
72297cb0927SSimon Glass 	plat->power_backlight_on_delay = fdtdec_get_int(blob, node,
72397cb0927SSimon Glass 			"intel,power-backlight-on-delay", 0);
72497cb0927SSimon Glass 	plat->power_backlight_off_delay = fdtdec_get_int(blob, node,
72597cb0927SSimon Glass 			"intel,power-backlight-off-delay", 0);
72697cb0927SSimon Glass 	plat->cpu_backlight = fdtdec_get_int(blob, node,
72797cb0927SSimon Glass 			"intel,cpu-backlight", 0);
72897cb0927SSimon Glass 	plat->pch_backlight = fdtdec_get_int(blob, node,
72997cb0927SSimon Glass 			"intel,pch-backlight", 0);
73097cb0927SSimon Glass 	plat->pre_graphics_delay = fdtdec_get_int(blob, node,
73197cb0927SSimon Glass 			"intel,pre-graphics-delay", 0);
73297cb0927SSimon Glass 	priv->regs = (u8 *)dm_pci_read_bar32(dev, 0);
73397cb0927SSimon Glass 	debug("%s: regs at %p\n", __func__, priv->regs);
73497cb0927SSimon Glass 	debug("dp_hotplug %d %d %d\n", plat->dp_hotplug[0], plat->dp_hotplug[1],
73597cb0927SSimon Glass 	      plat->dp_hotplug[2]);
73697cb0927SSimon Glass 	debug("port_select = %d\n", plat->port_select);
73797cb0927SSimon Glass 	debug("power_up_delay = %d\n", plat->power_up_delay);
73897cb0927SSimon Glass 	debug("power_backlight_on_delay = %d\n",
73997cb0927SSimon Glass 	      plat->power_backlight_on_delay);
74097cb0927SSimon Glass 	debug("power_down_delay = %d\n", plat->power_down_delay);
74197cb0927SSimon Glass 	debug("power_backlight_off_delay = %d\n",
74297cb0927SSimon Glass 	      plat->power_backlight_off_delay);
74397cb0927SSimon Glass 	debug("power_cycle_delay = %d\n", plat->power_cycle_delay);
74497cb0927SSimon Glass 	debug("cpu_backlight = %x\n", plat->cpu_backlight);
74597cb0927SSimon Glass 	debug("pch_backlight = %x\n", plat->pch_backlight);
74697cb0927SSimon Glass 	debug("cdclk = %d\n", plat->cdclk);
74797cb0927SSimon Glass 	debug("pre_graphics_delay = %d\n", plat->pre_graphics_delay);
74897cb0927SSimon Glass 
74997cb0927SSimon Glass 	return 0;
75097cb0927SSimon Glass }
75197cb0927SSimon Glass 
75297cb0927SSimon Glass static const struct video_ops broadwell_igd_ops = {
75397cb0927SSimon Glass };
75497cb0927SSimon Glass 
75597cb0927SSimon Glass static const struct udevice_id broadwell_igd_ids[] = {
75697cb0927SSimon Glass 	{ .compatible = "intel,broadwell-igd" },
75797cb0927SSimon Glass 	{ }
75897cb0927SSimon Glass };
75997cb0927SSimon Glass 
76097cb0927SSimon Glass U_BOOT_DRIVER(broadwell_igd) = {
76197cb0927SSimon Glass 	.name	= "broadwell_igd",
76297cb0927SSimon Glass 	.id	= UCLASS_VIDEO,
76397cb0927SSimon Glass 	.of_match = broadwell_igd_ids,
76497cb0927SSimon Glass 	.ops	= &broadwell_igd_ops,
76597cb0927SSimon Glass 	.ofdata_to_platdata = broadwell_igd_ofdata_to_platdata,
76697cb0927SSimon Glass 	.probe	= broadwell_igd_probe,
76797cb0927SSimon Glass 	.priv_auto_alloc_size	= sizeof(struct broadwell_igd_priv),
76897cb0927SSimon Glass 	.platdata_auto_alloc_size	= sizeof(struct broadwell_igd_plat),
76997cb0927SSimon Glass };
770