1 /* 2 * From coreboot src/soc/intel/broadwell/igd.c 3 * 4 * Copyright (C) 2016 Google, Inc 5 * 6 * SPDX-License-Identifier: GPL-2.0 7 */ 8 9 #include <common.h> 10 #include <bios_emul.h> 11 #include <dm.h> 12 #include <vbe.h> 13 #include <video.h> 14 #include <asm/cpu.h> 15 #include <asm/intel_regs.h> 16 #include <asm/io.h> 17 #include <asm/mtrr.h> 18 #include <asm/arch/cpu.h> 19 #include <asm/arch/iomap.h> 20 #include <asm/arch/pch.h> 21 #include "i915_reg.h" 22 23 struct broadwell_igd_priv { 24 u8 *regs; 25 }; 26 27 struct broadwell_igd_plat { 28 u32 dp_hotplug[3]; 29 30 int port_select; 31 int power_up_delay; 32 int power_backlight_on_delay; 33 int power_down_delay; 34 int power_backlight_off_delay; 35 int power_cycle_delay; 36 int cpu_backlight; 37 int pch_backlight; 38 int cdclk; 39 int pre_graphics_delay; 40 }; 41 42 #define GT_RETRY 1000 43 #define GT_CDCLK_337 0 44 #define GT_CDCLK_450 1 45 #define GT_CDCLK_540 2 46 #define GT_CDCLK_675 3 47 48 u32 board_map_oprom_vendev(u32 vendev) 49 { 50 return SA_IGD_OPROM_VENDEV; 51 } 52 53 static int poll32(u8 *addr, uint mask, uint value) 54 { 55 ulong start; 56 57 start = get_timer(0); 58 debug("%s: addr %p = %x\n", __func__, addr, readl(addr)); 59 while ((readl(addr) & mask) != value) { 60 if (get_timer(start) > GT_RETRY) { 61 debug("poll32: timeout: %x\n", readl(addr)); 62 return -ETIMEDOUT; 63 } 64 } 65 66 return 0; 67 } 68 69 static int haswell_early_init(struct udevice *dev) 70 { 71 struct broadwell_igd_priv *priv = dev_get_priv(dev); 72 u8 *regs = priv->regs; 73 int ret; 74 75 /* Enable Force Wake */ 76 writel(0x00000020, regs + 0xa180); 77 writel(0x00010001, regs + 0xa188); 78 ret = poll32(regs + 0x130044, 1, 1); 79 if (ret) 80 goto err; 81 82 /* Enable Counters */ 83 setbits_le32(regs + 0xa248, 0x00000016); 84 85 /* GFXPAUSE settings */ 86 writel(0x00070020, regs + 0xa000); 87 88 /* ECO Settings */ 89 clrsetbits_le32(regs + 0xa180, ~0xff3fffff, 0x15000000); 90 91 /* Enable DOP Clock Gating */ 92 writel(0x000003fd, regs + 0x9424); 93 94 /* Enable Unit Level Clock Gating */ 95 writel(0x00000080, regs + 0x9400); 96 writel(0x40401000, regs + 0x9404); 97 writel(0x00000000, regs + 0x9408); 98 writel(0x02000001, regs + 0x940c); 99 100 /* 101 * RC6 Settings 102 */ 103 104 /* Wake Rate Limits */ 105 setbits_le32(regs + 0xa090, 0x00000000); 106 setbits_le32(regs + 0xa098, 0x03e80000); 107 setbits_le32(regs + 0xa09c, 0x00280000); 108 setbits_le32(regs + 0xa0a8, 0x0001e848); 109 setbits_le32(regs + 0xa0ac, 0x00000019); 110 111 /* Render/Video/Blitter Idle Max Count */ 112 writel(0x0000000a, regs + 0x02054); 113 writel(0x0000000a, regs + 0x12054); 114 writel(0x0000000a, regs + 0x22054); 115 writel(0x0000000a, regs + 0x1a054); 116 117 /* RC Sleep / RCx Thresholds */ 118 setbits_le32(regs + 0xa0b0, 0x00000000); 119 setbits_le32(regs + 0xa0b4, 0x000003e8); 120 setbits_le32(regs + 0xa0b8, 0x0000c350); 121 122 /* RP Settings */ 123 setbits_le32(regs + 0xa010, 0x000f4240); 124 setbits_le32(regs + 0xa014, 0x12060000); 125 setbits_le32(regs + 0xa02c, 0x0000e808); 126 setbits_le32(regs + 0xa030, 0x0003bd08); 127 setbits_le32(regs + 0xa068, 0x000101d0); 128 setbits_le32(regs + 0xa06c, 0x00055730); 129 setbits_le32(regs + 0xa070, 0x0000000a); 130 131 /* RP Control */ 132 writel(0x00000b92, regs + 0xa024); 133 134 /* HW RC6 Control */ 135 writel(0x88040000, regs + 0xa090); 136 137 /* Video Frequency Request */ 138 writel(0x08000000, regs + 0xa00c); 139 140 /* Set RC6 VIDs */ 141 ret = poll32(regs + 0x138124, (1 << 31), 0); 142 if (ret) 143 goto err; 144 writel(0, regs + 0x138128); 145 writel(0x80000004, regs + 0x138124); 146 ret = poll32(regs + 0x138124, (1 << 31), 0); 147 if (ret) 148 goto err; 149 150 /* Enable PM Interrupts */ 151 writel(0x03000076, regs + 0x4402c); 152 153 /* Enable RC6 in idle */ 154 writel(0x00040000, regs + 0xa094); 155 156 return 0; 157 err: 158 debug("%s: ret=%d\n", __func__, ret); 159 return ret; 160 }; 161 162 static int haswell_late_init(struct udevice *dev) 163 { 164 struct broadwell_igd_priv *priv = dev_get_priv(dev); 165 u8 *regs = priv->regs; 166 int ret; 167 168 /* Lock settings */ 169 setbits_le32(regs + 0x0a248, (1 << 31)); 170 setbits_le32(regs + 0x0a004, (1 << 4)); 171 setbits_le32(regs + 0x0a080, (1 << 2)); 172 setbits_le32(regs + 0x0a180, (1 << 31)); 173 174 /* Disable Force Wake */ 175 writel(0x00010000, regs + 0xa188); 176 ret = poll32(regs + 0x130044, 1, 0); 177 if (ret) 178 goto err; 179 writel(0x00000001, regs + 0xa188); 180 181 /* Enable power well for DP and Audio */ 182 setbits_le32(regs + 0x45400, (1 << 31)); 183 ret = poll32(regs + 0x45400, 1 << 30, 1 << 30); 184 if (ret) 185 goto err; 186 187 return 0; 188 err: 189 debug("%s: ret=%d\n", __func__, ret); 190 return ret; 191 }; 192 193 static int broadwell_early_init(struct udevice *dev) 194 { 195 struct broadwell_igd_priv *priv = dev_get_priv(dev); 196 u8 *regs = priv->regs; 197 int ret; 198 199 /* Enable Force Wake */ 200 writel(0x00010001, regs + 0xa188); 201 ret = poll32(regs + 0x130044, 1, 1); 202 if (ret) 203 goto err; 204 205 /* Enable push bus metric control and shift */ 206 writel(0x00000004, regs + 0xa248); 207 writel(0x000000ff, regs + 0xa250); 208 writel(0x00000010, regs + 0xa25c); 209 210 /* GFXPAUSE settings (set based on stepping) */ 211 212 /* ECO Settings */ 213 writel(0x45200000, regs + 0xa180); 214 215 /* Enable DOP Clock Gating */ 216 writel(0x000000fd, regs + 0x9424); 217 218 /* Enable Unit Level Clock Gating */ 219 writel(0x00000000, regs + 0x9400); 220 writel(0x40401000, regs + 0x9404); 221 writel(0x00000000, regs + 0x9408); 222 writel(0x02000001, regs + 0x940c); 223 writel(0x0000000a, regs + 0x1a054); 224 225 /* Video Frequency Request */ 226 writel(0x08000000, regs + 0xa00c); 227 228 writel(0x00000009, regs + 0x138158); 229 writel(0x0000000d, regs + 0x13815c); 230 231 /* 232 * RC6 Settings 233 */ 234 235 /* Wake Rate Limits */ 236 clrsetbits_le32(regs + 0x0a090, ~0, 0); 237 setbits_le32(regs + 0x0a098, 0x03e80000); 238 setbits_le32(regs + 0x0a09c, 0x00280000); 239 setbits_le32(regs + 0x0a0a8, 0x0001e848); 240 setbits_le32(regs + 0x0a0ac, 0x00000019); 241 242 /* Render/Video/Blitter Idle Max Count */ 243 writel(0x0000000a, regs + 0x02054); 244 writel(0x0000000a, regs + 0x12054); 245 writel(0x0000000a, regs + 0x22054); 246 247 /* RC Sleep / RCx Thresholds */ 248 setbits_le32(regs + 0x0a0b0, 0x00000000); 249 setbits_le32(regs + 0x0a0b8, 0x00000271); 250 251 /* RP Settings */ 252 setbits_le32(regs + 0x0a010, 0x000f4240); 253 setbits_le32(regs + 0x0a014, 0x12060000); 254 setbits_le32(regs + 0x0a02c, 0x0000e808); 255 setbits_le32(regs + 0x0a030, 0x0003bd08); 256 setbits_le32(regs + 0x0a068, 0x000101d0); 257 setbits_le32(regs + 0x0a06c, 0x00055730); 258 setbits_le32(regs + 0x0a070, 0x0000000a); 259 setbits_le32(regs + 0x0a168, 0x00000006); 260 261 /* RP Control */ 262 writel(0x00000b92, regs + 0xa024); 263 264 /* HW RC6 Control */ 265 writel(0x90040000, regs + 0xa090); 266 267 /* Set RC6 VIDs */ 268 ret = poll32(regs + 0x138124, (1 << 31), 0); 269 if (ret) 270 goto err; 271 writel(0, regs + 0x138128); 272 writel(0x80000004, regs + 0x138124); 273 ret = poll32(regs + 0x138124, (1 << 31), 0); 274 if (ret) 275 goto err; 276 277 /* Enable PM Interrupts */ 278 writel(0x03000076, regs + 0x4402c); 279 280 /* Enable RC6 in idle */ 281 writel(0x00040000, regs + 0xa094); 282 283 return 0; 284 err: 285 debug("%s: ret=%d\n", __func__, ret); 286 return ret; 287 } 288 289 static int broadwell_late_init(struct udevice *dev) 290 { 291 struct broadwell_igd_priv *priv = dev_get_priv(dev); 292 u8 *regs = priv->regs; 293 int ret; 294 295 /* Lock settings */ 296 setbits_le32(regs + 0x0a248, 1 << 31); 297 setbits_le32(regs + 0x0a000, 1 << 18); 298 setbits_le32(regs + 0x0a180, 1 << 31); 299 300 /* Disable Force Wake */ 301 writel(0x00010000, regs + 0xa188); 302 ret = poll32(regs + 0x130044, 1, 0); 303 if (ret) 304 goto err; 305 306 /* Enable power well for DP and Audio */ 307 setbits_le32(regs + 0x45400, 1 << 31); 308 ret = poll32(regs + 0x45400, 1 << 30, 1 << 30); 309 if (ret) 310 goto err; 311 312 return 0; 313 err: 314 debug("%s: ret=%d\n", __func__, ret); 315 return ret; 316 }; 317 318 319 static unsigned long gtt_read(struct broadwell_igd_priv *priv, 320 unsigned long reg) 321 { 322 return readl(priv->regs + reg); 323 } 324 325 static void gtt_write(struct broadwell_igd_priv *priv, unsigned long reg, 326 unsigned long data) 327 { 328 writel(data, priv->regs + reg); 329 } 330 331 static inline void gtt_clrsetbits(struct broadwell_igd_priv *priv, u32 reg, 332 u32 bic, u32 or) 333 { 334 clrsetbits_le32(priv->regs + reg, bic, or); 335 } 336 337 static int gtt_poll(struct broadwell_igd_priv *priv, u32 reg, u32 mask, 338 u32 value) 339 { 340 unsigned try = GT_RETRY; 341 u32 data; 342 343 while (try--) { 344 data = gtt_read(priv, reg); 345 if ((data & mask) == value) 346 return 0; 347 udelay(10); 348 } 349 350 debug("GT init timeout\n"); 351 return -ETIMEDOUT; 352 } 353 354 static void igd_setup_panel(struct udevice *dev) 355 { 356 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 357 struct broadwell_igd_priv *priv = dev_get_priv(dev); 358 u32 reg32; 359 360 /* Setup Digital Port Hotplug */ 361 reg32 = (plat->dp_hotplug[0] & 0x7) << 2; 362 reg32 |= (plat->dp_hotplug[1] & 0x7) << 10; 363 reg32 |= (plat->dp_hotplug[2] & 0x7) << 18; 364 gtt_write(priv, PCH_PORT_HOTPLUG, reg32); 365 366 /* Setup Panel Power On Delays */ 367 reg32 = (plat->port_select & 0x3) << 30; 368 reg32 |= (plat->power_up_delay & 0x1fff) << 16; 369 reg32 |= (plat->power_backlight_on_delay & 0x1fff); 370 gtt_write(priv, PCH_PP_ON_DELAYS, reg32); 371 372 /* Setup Panel Power Off Delays */ 373 reg32 = (plat->power_down_delay & 0x1fff) << 16; 374 reg32 |= (plat->power_backlight_off_delay & 0x1fff); 375 gtt_write(priv, PCH_PP_OFF_DELAYS, reg32); 376 377 /* Setup Panel Power Cycle Delay */ 378 if (plat->power_cycle_delay) { 379 reg32 = gtt_read(priv, PCH_PP_DIVISOR); 380 reg32 &= ~0xff; 381 reg32 |= plat->power_cycle_delay & 0xff; 382 gtt_write(priv, PCH_PP_DIVISOR, reg32); 383 } 384 385 /* Enable Backlight if needed */ 386 if (plat->cpu_backlight) { 387 gtt_write(priv, BLC_PWM_CPU_CTL2, BLC_PWM2_ENABLE); 388 gtt_write(priv, BLC_PWM_CPU_CTL, plat->cpu_backlight); 389 } 390 if (plat->pch_backlight) { 391 gtt_write(priv, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE); 392 gtt_write(priv, BLC_PWM_PCH_CTL2, plat->pch_backlight); 393 } 394 } 395 396 static int igd_cdclk_init_haswell(struct udevice *dev) 397 { 398 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 399 struct broadwell_igd_priv *priv = dev_get_priv(dev); 400 int cdclk = plat->cdclk; 401 u16 devid; 402 int gpu_is_ulx = 0; 403 u32 dpdiv, lpcll; 404 int ret; 405 406 dm_pci_read_config16(dev, PCI_DEVICE_ID, &devid); 407 408 /* Check for ULX GT1 or GT2 */ 409 if (devid == 0x0a0e || devid == 0x0a1e) 410 gpu_is_ulx = 1; 411 412 /* 675MHz is not supported on haswell */ 413 if (cdclk == GT_CDCLK_675) 414 cdclk = GT_CDCLK_337; 415 416 /* If CD clock is fixed or ULT then set to 450MHz */ 417 if ((gtt_read(priv, 0x42014) & 0x1000000) || cpu_is_ult()) 418 cdclk = GT_CDCLK_450; 419 420 /* 540MHz is not supported on ULX */ 421 if (gpu_is_ulx && cdclk == GT_CDCLK_540) 422 cdclk = GT_CDCLK_337; 423 424 /* 337.5MHz is not supported on non-ULT/ULX */ 425 if (!gpu_is_ulx && !cpu_is_ult() && cdclk == GT_CDCLK_337) 426 cdclk = GT_CDCLK_450; 427 428 /* Set variables based on CD Clock setting */ 429 switch (cdclk) { 430 case GT_CDCLK_337: 431 dpdiv = 169; 432 lpcll = (1 << 26); 433 break; 434 case GT_CDCLK_450: 435 dpdiv = 225; 436 lpcll = 0; 437 break; 438 case GT_CDCLK_540: 439 dpdiv = 270; 440 lpcll = (1 << 26); 441 break; 442 default: 443 ret = -EDOM; 444 goto err; 445 } 446 447 /* Set LPCLL_CTL CD Clock Frequency Select */ 448 gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll); 449 450 /* ULX: Inform power controller of selected frequency */ 451 if (gpu_is_ulx) { 452 if (cdclk == GT_CDCLK_450) 453 gtt_write(priv, 0x138128, 0x00000000); /* 450MHz */ 454 else 455 gtt_write(priv, 0x138128, 0x00000001); /* 337.5MHz */ 456 gtt_write(priv, 0x13812c, 0x00000000); 457 gtt_write(priv, 0x138124, 0x80000017); 458 } 459 460 /* Set CPU DP AUX 2X bit clock dividers */ 461 gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv); 462 gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv); 463 464 return 0; 465 err: 466 debug("%s: ret=%d\n", __func__, ret); 467 return ret; 468 } 469 470 static int igd_cdclk_init_broadwell(struct udevice *dev) 471 { 472 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 473 struct broadwell_igd_priv *priv = dev_get_priv(dev); 474 int cdclk = plat->cdclk; 475 u32 dpdiv, lpcll, pwctl, cdset; 476 int ret; 477 478 /* Inform power controller of upcoming frequency change */ 479 gtt_write(priv, 0x138128, 0); 480 gtt_write(priv, 0x13812c, 0); 481 gtt_write(priv, 0x138124, 0x80000018); 482 483 /* Poll GT driver mailbox for run/busy clear */ 484 if (gtt_poll(priv, 0x138124, 1 << 31, 0 << 31)) 485 cdclk = GT_CDCLK_450; 486 487 if (gtt_read(priv, 0x42014) & 0x1000000) { 488 /* If CD clock is fixed then set to 450MHz */ 489 cdclk = GT_CDCLK_450; 490 } else { 491 /* Program CD clock to highest supported freq */ 492 if (cpu_is_ult()) 493 cdclk = GT_CDCLK_540; 494 else 495 cdclk = GT_CDCLK_675; 496 } 497 498 /* CD clock frequency 675MHz not supported on ULT */ 499 if (cpu_is_ult() && cdclk == GT_CDCLK_675) 500 cdclk = GT_CDCLK_540; 501 502 /* Set variables based on CD Clock setting */ 503 switch (cdclk) { 504 case GT_CDCLK_337: 505 cdset = 337; 506 lpcll = (1 << 27); 507 pwctl = 2; 508 dpdiv = 169; 509 break; 510 case GT_CDCLK_450: 511 cdset = 449; 512 lpcll = 0; 513 pwctl = 0; 514 dpdiv = 225; 515 break; 516 case GT_CDCLK_540: 517 cdset = 539; 518 lpcll = (1 << 26); 519 pwctl = 1; 520 dpdiv = 270; 521 break; 522 case GT_CDCLK_675: 523 cdset = 674; 524 lpcll = (1 << 26) | (1 << 27); 525 pwctl = 3; 526 dpdiv = 338; 527 break; 528 default: 529 ret = -EDOM; 530 goto err; 531 } 532 debug("%s: frequency = %d\n", __func__, cdclk); 533 534 /* Set LPCLL_CTL CD Clock Frequency Select */ 535 gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll); 536 537 /* Inform power controller of selected frequency */ 538 gtt_write(priv, 0x138128, pwctl); 539 gtt_write(priv, 0x13812c, 0); 540 gtt_write(priv, 0x138124, 0x80000017); 541 542 /* Program CD Clock Frequency */ 543 gtt_clrsetbits(priv, 0x46200, ~0xfffffc00, cdset); 544 545 /* Set CPU DP AUX 2X bit clock dividers */ 546 gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv); 547 gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv); 548 549 return 0; 550 err: 551 debug("%s: ret=%d\n", __func__, ret); 552 return ret; 553 } 554 555 u8 systemagent_revision(struct udevice *bus) 556 { 557 ulong val; 558 559 pci_bus_read_config(bus, PCI_BDF(0, 0, 0), PCI_REVISION_ID, &val, 560 PCI_SIZE_32); 561 562 return val; 563 } 564 565 static int igd_pre_init(struct udevice *dev, bool is_broadwell) 566 { 567 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 568 struct broadwell_igd_priv *priv = dev_get_priv(dev); 569 u32 rp1_gfx_freq; 570 int ret; 571 572 mdelay(plat->pre_graphics_delay); 573 574 /* Early init steps */ 575 if (is_broadwell) { 576 ret = broadwell_early_init(dev); 577 if (ret) 578 goto err; 579 580 /* Set GFXPAUSE based on stepping */ 581 if (cpu_get_stepping() <= (CPUID_BROADWELL_E0 & 0xf) && 582 systemagent_revision(pci_get_controller(dev)) <= 9) { 583 gtt_write(priv, 0xa000, 0x300ff); 584 } else { 585 gtt_write(priv, 0xa000, 0x30020); 586 } 587 } else { 588 ret = haswell_early_init(dev); 589 if (ret) 590 goto err; 591 } 592 593 /* Set RP1 graphics frequency */ 594 rp1_gfx_freq = (readl(MCHBAR_REG(0x5998)) >> 8) & 0xff; 595 gtt_write(priv, 0xa008, rp1_gfx_freq << 24); 596 597 /* Post VBIOS panel setup */ 598 igd_setup_panel(dev); 599 600 return 0; 601 err: 602 debug("%s: ret=%d\n", __func__, ret); 603 return ret; 604 } 605 606 static int igd_post_init(struct udevice *dev, bool is_broadwell) 607 { 608 int ret; 609 610 /* Late init steps */ 611 if (is_broadwell) { 612 ret = igd_cdclk_init_broadwell(dev); 613 if (ret) 614 return ret; 615 ret = broadwell_late_init(dev); 616 if (ret) 617 return ret; 618 } else { 619 igd_cdclk_init_haswell(dev); 620 ret = haswell_late_init(dev); 621 if (ret) 622 return ret; 623 } 624 625 return 0; 626 } 627 628 static int broadwell_igd_int15_handler(void) 629 { 630 int res = 0; 631 632 debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX); 633 634 switch (M.x86.R_AX) { 635 case 0x5f35: 636 /* 637 * Boot Display Device Hook: 638 * bit 0 = CRT 639 * bit 1 = TV (eDP) 640 * bit 2 = EFP 641 * bit 3 = LFP 642 * bit 4 = CRT2 643 * bit 5 = TV2 (eDP) 644 * bit 6 = EFP2 645 * bit 7 = LFP2 646 */ 647 M.x86.R_AX = 0x005f; 648 M.x86.R_CX = 0x0000; /* Use video bios default */ 649 res = 1; 650 break; 651 default: 652 debug("Unknown INT15 function %04x!\n", M.x86.R_AX); 653 break; 654 } 655 656 return res; 657 } 658 659 static int broadwell_igd_probe(struct udevice *dev) 660 { 661 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 662 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 663 bool is_broadwell; 664 int ret; 665 666 if (!ll_boot_init()) { 667 /* 668 * If we are running from EFI or coreboot, this driver can't 669 * work. 670 */ 671 printf("Not available (previous bootloader prevents it)\n"); 672 return -EPERM; 673 } 674 is_broadwell = cpu_get_family_model() == BROADWELL_FAMILY_ULT; 675 bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); 676 debug("%s: is_broadwell=%d\n", __func__, is_broadwell); 677 ret = igd_pre_init(dev, is_broadwell); 678 if (!ret) { 679 ret = vbe_setup_video(dev, broadwell_igd_int15_handler); 680 if (ret) 681 debug("failed to run video BIOS: %d\n", ret); 682 } 683 if (!ret) 684 ret = igd_post_init(dev, is_broadwell); 685 bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); 686 if (ret) 687 return ret; 688 689 /* Use write-combining for the graphics memory, 256MB */ 690 ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20); 691 if (!ret) 692 ret = mtrr_commit(true); 693 if (ret && ret != -ENOSYS) { 694 printf("Failed to add MTRR: Display will be slow (err %d)\n", 695 ret); 696 } 697 698 debug("fb=%lx, size %x, display size=%d %d %d\n", plat->base, 699 plat->size, uc_priv->xsize, uc_priv->ysize, uc_priv->bpix); 700 701 return 0; 702 } 703 704 static int broadwell_igd_ofdata_to_platdata(struct udevice *dev) 705 { 706 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 707 struct broadwell_igd_priv *priv = dev_get_priv(dev); 708 int node = dev->of_offset; 709 const void *blob = gd->fdt_blob; 710 711 if (fdtdec_get_int_array(blob, node, "intel,dp-hotplug", 712 plat->dp_hotplug, 713 ARRAY_SIZE(plat->dp_hotplug))) 714 return -EINVAL; 715 plat->port_select = fdtdec_get_int(blob, node, "intel,port-select", 0); 716 plat->power_cycle_delay = fdtdec_get_int(blob, node, 717 "intel,power-cycle-delay", 0); 718 plat->power_up_delay = fdtdec_get_int(blob, node, 719 "intel,power-up-delay", 0); 720 plat->power_down_delay = fdtdec_get_int(blob, node, 721 "intel,power-down-delay", 0); 722 plat->power_backlight_on_delay = fdtdec_get_int(blob, node, 723 "intel,power-backlight-on-delay", 0); 724 plat->power_backlight_off_delay = fdtdec_get_int(blob, node, 725 "intel,power-backlight-off-delay", 0); 726 plat->cpu_backlight = fdtdec_get_int(blob, node, 727 "intel,cpu-backlight", 0); 728 plat->pch_backlight = fdtdec_get_int(blob, node, 729 "intel,pch-backlight", 0); 730 plat->pre_graphics_delay = fdtdec_get_int(blob, node, 731 "intel,pre-graphics-delay", 0); 732 priv->regs = (u8 *)dm_pci_read_bar32(dev, 0); 733 debug("%s: regs at %p\n", __func__, priv->regs); 734 debug("dp_hotplug %d %d %d\n", plat->dp_hotplug[0], plat->dp_hotplug[1], 735 plat->dp_hotplug[2]); 736 debug("port_select = %d\n", plat->port_select); 737 debug("power_up_delay = %d\n", plat->power_up_delay); 738 debug("power_backlight_on_delay = %d\n", 739 plat->power_backlight_on_delay); 740 debug("power_down_delay = %d\n", plat->power_down_delay); 741 debug("power_backlight_off_delay = %d\n", 742 plat->power_backlight_off_delay); 743 debug("power_cycle_delay = %d\n", plat->power_cycle_delay); 744 debug("cpu_backlight = %x\n", plat->cpu_backlight); 745 debug("pch_backlight = %x\n", plat->pch_backlight); 746 debug("cdclk = %d\n", plat->cdclk); 747 debug("pre_graphics_delay = %d\n", plat->pre_graphics_delay); 748 749 return 0; 750 } 751 752 static const struct video_ops broadwell_igd_ops = { 753 }; 754 755 static const struct udevice_id broadwell_igd_ids[] = { 756 { .compatible = "intel,broadwell-igd" }, 757 { } 758 }; 759 760 U_BOOT_DRIVER(broadwell_igd) = { 761 .name = "broadwell_igd", 762 .id = UCLASS_VIDEO, 763 .of_match = broadwell_igd_ids, 764 .ops = &broadwell_igd_ops, 765 .ofdata_to_platdata = broadwell_igd_ofdata_to_platdata, 766 .probe = broadwell_igd_probe, 767 .priv_auto_alloc_size = sizeof(struct broadwell_igd_priv), 768 .platdata_auto_alloc_size = sizeof(struct broadwell_igd_plat), 769 }; 770