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