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