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 u32 val; 327 328 val = readl(priv->regs + reg); 329 return val; 330 } 331 332 static void gtt_write(struct broadwell_igd_priv *priv, unsigned long reg, 333 unsigned long data) 334 { 335 writel(data, priv->regs + reg); 336 } 337 338 static inline void gtt_clrsetbits(struct broadwell_igd_priv *priv, u32 reg, 339 u32 bic, u32 or) 340 { 341 clrsetbits_le32(priv->regs + reg, bic, or); 342 } 343 344 static int gtt_poll(struct broadwell_igd_priv *priv, u32 reg, u32 mask, 345 u32 value) 346 { 347 unsigned try = GT_RETRY; 348 u32 data; 349 350 while (try--) { 351 data = gtt_read(priv, reg); 352 if ((data & mask) == value) 353 return 0; 354 udelay(10); 355 } 356 357 debug("GT init timeout\n"); 358 return -ETIMEDOUT; 359 } 360 361 static void igd_setup_panel(struct udevice *dev) 362 { 363 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 364 struct broadwell_igd_priv *priv = dev_get_priv(dev); 365 u32 reg32; 366 367 /* Setup Digital Port Hotplug */ 368 reg32 = (plat->dp_hotplug[0] & 0x7) << 2; 369 reg32 |= (plat->dp_hotplug[1] & 0x7) << 10; 370 reg32 |= (plat->dp_hotplug[2] & 0x7) << 18; 371 gtt_write(priv, PCH_PORT_HOTPLUG, reg32); 372 373 /* Setup Panel Power On Delays */ 374 reg32 = (plat->port_select & 0x3) << 30; 375 reg32 |= (plat->power_up_delay & 0x1fff) << 16; 376 reg32 |= (plat->power_backlight_on_delay & 0x1fff); 377 gtt_write(priv, PCH_PP_ON_DELAYS, reg32); 378 379 /* Setup Panel Power Off Delays */ 380 reg32 = (plat->power_down_delay & 0x1fff) << 16; 381 reg32 |= (plat->power_backlight_off_delay & 0x1fff); 382 gtt_write(priv, PCH_PP_OFF_DELAYS, reg32); 383 384 /* Setup Panel Power Cycle Delay */ 385 if (plat->power_cycle_delay) { 386 reg32 = gtt_read(priv, PCH_PP_DIVISOR); 387 reg32 &= ~0xff; 388 reg32 |= plat->power_cycle_delay & 0xff; 389 gtt_write(priv, PCH_PP_DIVISOR, reg32); 390 } 391 392 /* Enable Backlight if needed */ 393 if (plat->cpu_backlight) { 394 gtt_write(priv, BLC_PWM_CPU_CTL2, BLC_PWM2_ENABLE); 395 gtt_write(priv, BLC_PWM_CPU_CTL, plat->cpu_backlight); 396 } 397 if (plat->pch_backlight) { 398 gtt_write(priv, BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE); 399 gtt_write(priv, BLC_PWM_PCH_CTL2, plat->pch_backlight); 400 } 401 } 402 403 static int igd_cdclk_init_haswell(struct udevice *dev) 404 { 405 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 406 struct broadwell_igd_priv *priv = dev_get_priv(dev); 407 int cdclk = plat->cdclk; 408 u16 devid; 409 int gpu_is_ulx = 0; 410 u32 dpdiv, lpcll; 411 int ret; 412 413 dm_pci_read_config16(dev, PCI_DEVICE_ID, &devid); 414 415 /* Check for ULX GT1 or GT2 */ 416 if (devid == 0x0a0e || devid == 0x0a1e) 417 gpu_is_ulx = 1; 418 419 /* 675MHz is not supported on haswell */ 420 if (cdclk == GT_CDCLK_675) 421 cdclk = GT_CDCLK_337; 422 423 /* If CD clock is fixed or ULT then set to 450MHz */ 424 if ((gtt_read(priv, 0x42014) & 0x1000000) || cpu_is_ult()) 425 cdclk = GT_CDCLK_450; 426 427 /* 540MHz is not supported on ULX */ 428 if (gpu_is_ulx && cdclk == GT_CDCLK_540) 429 cdclk = GT_CDCLK_337; 430 431 /* 337.5MHz is not supported on non-ULT/ULX */ 432 if (!gpu_is_ulx && !cpu_is_ult() && cdclk == GT_CDCLK_337) 433 cdclk = GT_CDCLK_450; 434 435 /* Set variables based on CD Clock setting */ 436 switch (cdclk) { 437 case GT_CDCLK_337: 438 dpdiv = 169; 439 lpcll = (1 << 26); 440 break; 441 case GT_CDCLK_450: 442 dpdiv = 225; 443 lpcll = 0; 444 break; 445 case GT_CDCLK_540: 446 dpdiv = 270; 447 lpcll = (1 << 26); 448 break; 449 default: 450 ret = -EDOM; 451 goto err; 452 } 453 454 /* Set LPCLL_CTL CD Clock Frequency Select */ 455 gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll); 456 457 /* ULX: Inform power controller of selected frequency */ 458 if (gpu_is_ulx) { 459 if (cdclk == GT_CDCLK_450) 460 gtt_write(priv, 0x138128, 0x00000000); /* 450MHz */ 461 else 462 gtt_write(priv, 0x138128, 0x00000001); /* 337.5MHz */ 463 gtt_write(priv, 0x13812c, 0x00000000); 464 gtt_write(priv, 0x138124, 0x80000017); 465 } 466 467 /* Set CPU DP AUX 2X bit clock dividers */ 468 gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv); 469 gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv); 470 471 return 0; 472 err: 473 debug("%s: ret=%d\n", __func__, ret); 474 return ret; 475 } 476 477 static int igd_cdclk_init_broadwell(struct udevice *dev) 478 { 479 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 480 struct broadwell_igd_priv *priv = dev_get_priv(dev); 481 int cdclk = plat->cdclk; 482 u32 dpdiv, lpcll, pwctl, cdset; 483 int ret; 484 485 /* Inform power controller of upcoming frequency change */ 486 gtt_write(priv, 0x138128, 0); 487 gtt_write(priv, 0x13812c, 0); 488 gtt_write(priv, 0x138124, 0x80000018); 489 490 /* Poll GT driver mailbox for run/busy clear */ 491 if (gtt_poll(priv, 0x138124, 1 << 31, 0 << 31)) 492 cdclk = GT_CDCLK_450; 493 494 if (gtt_read(priv, 0x42014) & 0x1000000) { 495 /* If CD clock is fixed then set to 450MHz */ 496 cdclk = GT_CDCLK_450; 497 } else { 498 /* Program CD clock to highest supported freq */ 499 if (cpu_is_ult()) 500 cdclk = GT_CDCLK_540; 501 else 502 cdclk = GT_CDCLK_675; 503 } 504 505 /* CD clock frequency 675MHz not supported on ULT */ 506 if (cpu_is_ult() && cdclk == GT_CDCLK_675) 507 cdclk = GT_CDCLK_540; 508 509 /* Set variables based on CD Clock setting */ 510 switch (cdclk) { 511 case GT_CDCLK_337: 512 cdset = 337; 513 lpcll = (1 << 27); 514 pwctl = 2; 515 dpdiv = 169; 516 break; 517 case GT_CDCLK_450: 518 cdset = 449; 519 lpcll = 0; 520 pwctl = 0; 521 dpdiv = 225; 522 break; 523 case GT_CDCLK_540: 524 cdset = 539; 525 lpcll = (1 << 26); 526 pwctl = 1; 527 dpdiv = 270; 528 break; 529 case GT_CDCLK_675: 530 cdset = 674; 531 lpcll = (1 << 26) | (1 << 27); 532 pwctl = 3; 533 dpdiv = 338; 534 break; 535 default: 536 ret = -EDOM; 537 goto err; 538 } 539 debug("%s: frequency = %d\n", __func__, cdclk); 540 541 /* Set LPCLL_CTL CD Clock Frequency Select */ 542 gtt_clrsetbits(priv, 0x130040, ~0xf3ffffff, lpcll); 543 544 /* Inform power controller of selected frequency */ 545 gtt_write(priv, 0x138128, pwctl); 546 gtt_write(priv, 0x13812c, 0); 547 gtt_write(priv, 0x138124, 0x80000017); 548 549 /* Program CD Clock Frequency */ 550 gtt_clrsetbits(priv, 0x46200, ~0xfffffc00, cdset); 551 552 /* Set CPU DP AUX 2X bit clock dividers */ 553 gtt_clrsetbits(priv, 0x64010, ~0xfffff800, dpdiv); 554 gtt_clrsetbits(priv, 0x64810, ~0xfffff800, dpdiv); 555 556 return 0; 557 err: 558 debug("%s: ret=%d\n", __func__, ret); 559 return ret; 560 } 561 562 u8 systemagent_revision(struct udevice *bus) 563 { 564 ulong val; 565 566 pci_bus_read_config(bus, PCI_BDF(0, 0, 0), PCI_REVISION_ID, &val, 567 PCI_SIZE_32); 568 569 return val; 570 } 571 572 static int igd_pre_init(struct udevice *dev, bool is_broadwell) 573 { 574 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 575 struct broadwell_igd_priv *priv = dev_get_priv(dev); 576 u32 rp1_gfx_freq; 577 int ret; 578 579 mdelay(plat->pre_graphics_delay); 580 581 /* Early init steps */ 582 if (is_broadwell) { 583 ret = broadwell_early_init(dev); 584 if (ret) 585 goto err; 586 587 /* Set GFXPAUSE based on stepping */ 588 if (cpu_get_stepping() <= (CPUID_BROADWELL_E0 & 0xf) && 589 systemagent_revision(pci_get_controller(dev)) <= 9) { 590 gtt_write(priv, 0xa000, 0x300ff); 591 } else { 592 gtt_write(priv, 0xa000, 0x30020); 593 } 594 } else { 595 ret = haswell_early_init(dev); 596 if (ret) 597 goto err; 598 } 599 600 /* Set RP1 graphics frequency */ 601 rp1_gfx_freq = (readl(MCHBAR_REG(0x5998)) >> 8) & 0xff; 602 gtt_write(priv, 0xa008, rp1_gfx_freq << 24); 603 604 /* Post VBIOS panel setup */ 605 igd_setup_panel(dev); 606 607 return 0; 608 err: 609 debug("%s: ret=%d\n", __func__, ret); 610 return ret; 611 } 612 613 static int igd_post_init(struct udevice *dev, bool is_broadwell) 614 { 615 int ret; 616 617 /* Late init steps */ 618 if (is_broadwell) { 619 ret = igd_cdclk_init_broadwell(dev); 620 if (ret) 621 return ret; 622 ret = broadwell_late_init(dev); 623 if (ret) 624 return ret; 625 } else { 626 igd_cdclk_init_haswell(dev); 627 ret = haswell_late_init(dev); 628 if (ret) 629 return ret; 630 } 631 632 return 0; 633 } 634 635 static int broadwell_igd_int15_handler(void) 636 { 637 int res = 0; 638 639 debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX); 640 641 switch (M.x86.R_AX) { 642 case 0x5f35: 643 /* 644 * Boot Display Device Hook: 645 * bit 0 = CRT 646 * bit 1 = TV (eDP) 647 * bit 2 = EFP 648 * bit 3 = LFP 649 * bit 4 = CRT2 650 * bit 5 = TV2 (eDP) 651 * bit 6 = EFP2 652 * bit 7 = LFP2 653 */ 654 M.x86.R_AX = 0x005f; 655 M.x86.R_CX = 0x0000; /* Use video bios default */ 656 res = 1; 657 break; 658 default: 659 debug("Unknown INT15 function %04x!\n", M.x86.R_AX); 660 break; 661 } 662 663 return res; 664 } 665 666 static int broadwell_igd_probe(struct udevice *dev) 667 { 668 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 669 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 670 struct broadwell_igd_priv *priv = dev_get_priv(dev); 671 bool is_broadwell; 672 GraphicDevice *gdev = &priv->ctfb; 673 int bits_per_pixel; 674 int ret; 675 676 if (!ll_boot_init()) { 677 /* 678 * If we are running from EFI or coreboot, this driver can't 679 * work. 680 */ 681 printf("Not available (previous bootloader prevents it)\n"); 682 return -EPERM; 683 } 684 is_broadwell = cpu_get_family_model() == BROADWELL_FAMILY_ULT; 685 bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); 686 debug("%s: is_broadwell=%d\n", __func__, is_broadwell); 687 ret = igd_pre_init(dev, is_broadwell); 688 if (!ret) { 689 ret = dm_pci_run_vga_bios(dev, broadwell_igd_int15_handler, 690 PCI_ROM_USE_NATIVE | 691 PCI_ROM_ALLOW_FALLBACK); 692 if (ret) { 693 printf("failed to run video BIOS: %d\n", ret); 694 ret = -EIO; 695 } 696 } 697 if (!ret) 698 ret = igd_post_init(dev, is_broadwell); 699 bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); 700 if (ret) 701 return ret; 702 703 if (vbe_get_video_info(gdev)) { 704 printf("No video mode configured\n"); 705 return -ENXIO; 706 } 707 708 /* Use write-through for the graphics memory, 256MB */ 709 ret = mtrr_add_request(MTRR_TYPE_WRTHROUGH, gdev->pciBase, 256 << 20); 710 if (!ret) 711 ret = mtrr_commit(true); 712 if (ret && ret != -ENOSYS) { 713 printf("Failed to add MTRR: Display will be slow (err %d)\n", 714 ret); 715 } 716 717 bits_per_pixel = gdev->gdfBytesPP * 8; 718 sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, 719 bits_per_pixel); 720 printf("%s\n", gdev->modeIdent); 721 uc_priv->xsize = gdev->winSizeX; 722 uc_priv->ysize = gdev->winSizeY; 723 uc_priv->bpix = ilog2(bits_per_pixel); 724 plat->base = gdev->pciBase; 725 plat->size = gdev->memSize; 726 debug("fb=%x, size %x, display size=%d %d %d\n", gdev->pciBase, 727 gdev->memSize, uc_priv->xsize, uc_priv->ysize, uc_priv->bpix); 728 729 return 0; 730 } 731 732 static int broadwell_igd_ofdata_to_platdata(struct udevice *dev) 733 { 734 struct broadwell_igd_plat *plat = dev_get_platdata(dev); 735 struct broadwell_igd_priv *priv = dev_get_priv(dev); 736 int node = dev->of_offset; 737 const void *blob = gd->fdt_blob; 738 739 if (fdtdec_get_int_array(blob, node, "intel,dp-hotplug", 740 plat->dp_hotplug, 741 ARRAY_SIZE(plat->dp_hotplug))) 742 return -EINVAL; 743 plat->port_select = fdtdec_get_int(blob, node, "intel,port-select", 0); 744 plat->power_cycle_delay = fdtdec_get_int(blob, node, 745 "intel,power-cycle-delay", 0); 746 plat->power_up_delay = fdtdec_get_int(blob, node, 747 "intel,power-up-delay", 0); 748 plat->power_down_delay = fdtdec_get_int(blob, node, 749 "intel,power-down-delay", 0); 750 plat->power_backlight_on_delay = fdtdec_get_int(blob, node, 751 "intel,power-backlight-on-delay", 0); 752 plat->power_backlight_off_delay = fdtdec_get_int(blob, node, 753 "intel,power-backlight-off-delay", 0); 754 plat->cpu_backlight = fdtdec_get_int(blob, node, 755 "intel,cpu-backlight", 0); 756 plat->pch_backlight = fdtdec_get_int(blob, node, 757 "intel,pch-backlight", 0); 758 plat->pre_graphics_delay = fdtdec_get_int(blob, node, 759 "intel,pre-graphics-delay", 0); 760 priv->regs = (u8 *)dm_pci_read_bar32(dev, 0); 761 debug("%s: regs at %p\n", __func__, priv->regs); 762 debug("dp_hotplug %d %d %d\n", plat->dp_hotplug[0], plat->dp_hotplug[1], 763 plat->dp_hotplug[2]); 764 debug("port_select = %d\n", plat->port_select); 765 debug("power_up_delay = %d\n", plat->power_up_delay); 766 debug("power_backlight_on_delay = %d\n", 767 plat->power_backlight_on_delay); 768 debug("power_down_delay = %d\n", plat->power_down_delay); 769 debug("power_backlight_off_delay = %d\n", 770 plat->power_backlight_off_delay); 771 debug("power_cycle_delay = %d\n", plat->power_cycle_delay); 772 debug("cpu_backlight = %x\n", plat->cpu_backlight); 773 debug("pch_backlight = %x\n", plat->pch_backlight); 774 debug("cdclk = %d\n", plat->cdclk); 775 debug("pre_graphics_delay = %d\n", plat->pre_graphics_delay); 776 777 return 0; 778 } 779 780 static const struct video_ops broadwell_igd_ops = { 781 }; 782 783 static const struct udevice_id broadwell_igd_ids[] = { 784 { .compatible = "intel,broadwell-igd" }, 785 { } 786 }; 787 788 U_BOOT_DRIVER(broadwell_igd) = { 789 .name = "broadwell_igd", 790 .id = UCLASS_VIDEO, 791 .of_match = broadwell_igd_ids, 792 .ops = &broadwell_igd_ops, 793 .ofdata_to_platdata = broadwell_igd_ofdata_to_platdata, 794 .probe = broadwell_igd_probe, 795 .priv_auto_alloc_size = sizeof(struct broadwell_igd_priv), 796 .platdata_auto_alloc_size = sizeof(struct broadwell_igd_plat), 797 }; 798