1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 5 6 #include <linux/string_helpers.h> 7 8 #include <drm/drm_managed.h> 9 #include <drm/drm_print.h> 10 #include <drm/intel/intel_pcode_regs.h> 11 12 #include "intel_de.h" 13 #include "intel_display_core.h" 14 #include "intel_display_utils.h" 15 #include "intel_display_regs.h" 16 #include "intel_dram.h" 17 #include "intel_mchbar.h" 18 #include "intel_parent.h" 19 #include "vlv_sideband.h" 20 21 struct dram_dimm_info { 22 u16 size; 23 u8 width, ranks; 24 }; 25 26 struct dram_channel_info { 27 struct dram_dimm_info dimm_l, dimm_s; 28 u8 ranks; 29 bool is_16gb_dimm; 30 }; 31 32 #define DRAM_TYPE_STR(type) [INTEL_DRAM_ ## type] = #type 33 34 const char *intel_dram_type_str(enum intel_dram_type type) 35 { 36 static const char * const str[] = { 37 DRAM_TYPE_STR(UNKNOWN), 38 DRAM_TYPE_STR(DDR2), 39 DRAM_TYPE_STR(DDR3), 40 DRAM_TYPE_STR(DDR4), 41 DRAM_TYPE_STR(LPDDR3), 42 DRAM_TYPE_STR(LPDDR4), 43 DRAM_TYPE_STR(DDR5), 44 DRAM_TYPE_STR(LPDDR5), 45 DRAM_TYPE_STR(GDDR), 46 DRAM_TYPE_STR(GDDR_ECC), 47 }; 48 49 BUILD_BUG_ON(ARRAY_SIZE(str) != __INTEL_DRAM_TYPE_MAX); 50 51 if (type >= ARRAY_SIZE(str)) 52 type = INTEL_DRAM_UNKNOWN; 53 54 return str[type]; 55 } 56 57 #undef DRAM_TYPE_STR 58 59 static enum intel_dram_type pnv_dram_type(struct intel_display *display) 60 { 61 return intel_mchbar_read(display, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? 62 INTEL_DRAM_DDR3 : INTEL_DRAM_DDR2; 63 } 64 65 static unsigned int pnv_mem_freq(struct intel_display *display) 66 { 67 u32 tmp; 68 69 tmp = intel_mchbar_read(display, CLKCFG); 70 71 switch (tmp & CLKCFG_MEM_MASK) { 72 case CLKCFG_MEM_533: 73 return 533333; 74 case CLKCFG_MEM_667: 75 return 666667; 76 case CLKCFG_MEM_800: 77 return 800000; 78 } 79 80 return 0; 81 } 82 83 static unsigned int ilk_mem_freq(struct intel_display *display) 84 { 85 u16 ddrpll; 86 87 ddrpll = intel_mchbar_read16(display, DDRMPLL1); 88 switch (ddrpll & 0xff) { 89 case 0xc: 90 return 800000; 91 case 0x10: 92 return 1066667; 93 case 0x14: 94 return 1333333; 95 case 0x18: 96 return 1600000; 97 default: 98 drm_dbg_kms(display->drm, "unknown memory frequency 0x%02x\n", 99 ddrpll & 0xff); 100 return 0; 101 } 102 } 103 104 static unsigned int chv_mem_freq(struct intel_display *display) 105 { 106 u32 val; 107 108 vlv_cck_get(display); 109 val = vlv_cck_read(display, CCK_FUSE_REG); 110 vlv_cck_put(display); 111 112 switch ((val >> 2) & 0x7) { 113 case 3: 114 return 2000000; 115 default: 116 return 1600000; 117 } 118 } 119 120 static unsigned int vlv_mem_freq(struct intel_display *display) 121 { 122 u32 val; 123 124 vlv_punit_get(display); 125 val = vlv_punit_read(display, PUNIT_REG_GPU_FREQ_STS); 126 vlv_punit_put(display); 127 128 switch ((val >> 6) & 3) { 129 case 0: 130 case 1: 131 return 800000; 132 case 2: 133 return 1066667; 134 case 3: 135 return 1333333; 136 } 137 138 return 0; 139 } 140 141 unsigned int intel_mem_freq(struct intel_display *display) 142 { 143 if (display->platform.pineview) 144 return pnv_mem_freq(display); 145 else if (DISPLAY_VER(display) == 5) 146 return ilk_mem_freq(display); 147 else if (display->platform.cherryview) 148 return chv_mem_freq(display); 149 else if (display->platform.valleyview) 150 return vlv_mem_freq(display); 151 else 152 return 0; 153 } 154 155 static unsigned int i9xx_fsb_freq(struct intel_display *display) 156 { 157 u32 fsb; 158 159 /* 160 * Note that this only reads the state of the FSB 161 * straps, not the actual FSB frequency. Some BIOSen 162 * let you configure each independently. Ideally we'd 163 * read out the actual FSB frequency but sadly we 164 * don't know which registers have that information, 165 * and all the relevant docs have gone to bit heaven :( 166 */ 167 fsb = intel_mchbar_read(display, CLKCFG) & CLKCFG_FSB_MASK; 168 169 if (display->platform.pineview || display->platform.mobile) { 170 switch (fsb) { 171 case CLKCFG_FSB_400: 172 return 400000; 173 case CLKCFG_FSB_533: 174 return 533333; 175 case CLKCFG_FSB_667: 176 return 666667; 177 case CLKCFG_FSB_800: 178 return 800000; 179 case CLKCFG_FSB_1067: 180 return 1066667; 181 case CLKCFG_FSB_1333: 182 return 1333333; 183 default: 184 MISSING_CASE(fsb); 185 return 1333333; 186 } 187 } else { 188 switch (fsb) { 189 case CLKCFG_FSB_400_ALT: 190 return 400000; 191 case CLKCFG_FSB_533: 192 return 533333; 193 case CLKCFG_FSB_667: 194 return 666667; 195 case CLKCFG_FSB_800: 196 return 800000; 197 case CLKCFG_FSB_1067_ALT: 198 return 1066667; 199 case CLKCFG_FSB_1333_ALT: 200 return 1333333; 201 case CLKCFG_FSB_1600_ALT: 202 return 1600000; 203 default: 204 MISSING_CASE(fsb); 205 return 1333333; 206 } 207 } 208 } 209 210 static unsigned int ilk_fsb_freq(struct intel_display *display) 211 { 212 u16 fsb; 213 214 fsb = intel_mchbar_read16(display, CSIPLL0) & 0x3ff; 215 216 switch (fsb) { 217 case 0x00c: 218 return 3200000; 219 case 0x00e: 220 return 3733333; 221 case 0x010: 222 return 4266667; 223 case 0x012: 224 return 4800000; 225 case 0x014: 226 return 5333333; 227 case 0x016: 228 return 5866667; 229 case 0x018: 230 return 6400000; 231 default: 232 drm_dbg_kms(display->drm, "unknown fsb frequency 0x%04x\n", fsb); 233 return 0; 234 } 235 } 236 237 unsigned int intel_fsb_freq(struct intel_display *display) 238 { 239 if (DISPLAY_VER(display) == 5) 240 return ilk_fsb_freq(display); 241 else if (IS_DISPLAY_VER(display, 3, 4)) 242 return i9xx_fsb_freq(display); 243 else 244 return 0; 245 } 246 247 static int i915_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 248 { 249 dram_info->fsb_freq = intel_fsb_freq(display); 250 if (dram_info->fsb_freq) 251 drm_dbg_kms(display->drm, "FSB frequency: %d kHz\n", dram_info->fsb_freq); 252 253 dram_info->mem_freq = intel_mem_freq(display); 254 if (dram_info->mem_freq) 255 drm_dbg_kms(display->drm, "DDR speed: %d kHz\n", dram_info->mem_freq); 256 257 if (display->platform.pineview) 258 dram_info->type = pnv_dram_type(display); 259 260 return 0; 261 } 262 263 static int intel_dimm_num_devices(const struct dram_dimm_info *dimm) 264 { 265 return dimm->ranks * 64 / (dimm->width ?: 1); 266 } 267 268 /* Returns total Gb for the whole DIMM */ 269 static int skl_get_dimm_s_size(u32 val) 270 { 271 return REG_FIELD_GET(SKL_DIMM_S_SIZE_MASK, val) * 8; 272 } 273 274 static int skl_get_dimm_l_size(u32 val) 275 { 276 return REG_FIELD_GET(SKL_DIMM_L_SIZE_MASK, val) * 8; 277 } 278 279 static int skl_get_dimm_s_width(u32 val) 280 { 281 if (skl_get_dimm_s_size(val) == 0) 282 return 0; 283 284 switch (val & SKL_DIMM_S_WIDTH_MASK) { 285 case SKL_DIMM_S_WIDTH_X8: 286 case SKL_DIMM_S_WIDTH_X16: 287 case SKL_DIMM_S_WIDTH_X32: 288 return 8 << REG_FIELD_GET(SKL_DIMM_S_WIDTH_MASK, val); 289 default: 290 MISSING_CASE(val); 291 return 0; 292 } 293 } 294 295 static int skl_get_dimm_l_width(u32 val) 296 { 297 if (skl_get_dimm_l_size(val) == 0) 298 return 0; 299 300 switch (val & SKL_DIMM_L_WIDTH_MASK) { 301 case SKL_DIMM_L_WIDTH_X8: 302 case SKL_DIMM_L_WIDTH_X16: 303 case SKL_DIMM_L_WIDTH_X32: 304 return 8 << REG_FIELD_GET(SKL_DIMM_L_WIDTH_MASK, val); 305 default: 306 MISSING_CASE(val); 307 return 0; 308 } 309 } 310 311 static int skl_get_dimm_s_ranks(u32 val) 312 { 313 if (skl_get_dimm_s_size(val) == 0) 314 return 0; 315 316 return REG_FIELD_GET(SKL_DIMM_S_RANK_MASK, val) + 1; 317 } 318 319 static int skl_get_dimm_l_ranks(u32 val) 320 { 321 if (skl_get_dimm_l_size(val) == 0) 322 return 0; 323 324 return REG_FIELD_GET(SKL_DIMM_L_RANK_MASK, val) + 1; 325 } 326 327 /* Returns total Gb for the whole DIMM */ 328 static int icl_get_dimm_s_size(u32 val) 329 { 330 return REG_FIELD_GET(ICL_DIMM_S_SIZE_MASK, val) * 8 / 2; 331 } 332 333 static int icl_get_dimm_l_size(u32 val) 334 { 335 return REG_FIELD_GET(ICL_DIMM_L_SIZE_MASK, val) * 8 / 2; 336 } 337 338 static int icl_get_dimm_s_width(u32 val) 339 { 340 if (icl_get_dimm_s_size(val) == 0) 341 return 0; 342 343 switch (val & ICL_DIMM_S_WIDTH_MASK) { 344 case ICL_DIMM_S_WIDTH_X8: 345 case ICL_DIMM_S_WIDTH_X16: 346 case ICL_DIMM_S_WIDTH_X32: 347 return 8 << REG_FIELD_GET(ICL_DIMM_S_WIDTH_MASK, val); 348 default: 349 MISSING_CASE(val); 350 return 0; 351 } 352 } 353 354 static int icl_get_dimm_l_width(u32 val) 355 { 356 if (icl_get_dimm_l_size(val) == 0) 357 return 0; 358 359 switch (val & ICL_DIMM_L_WIDTH_MASK) { 360 case ICL_DIMM_L_WIDTH_X8: 361 case ICL_DIMM_L_WIDTH_X16: 362 case ICL_DIMM_L_WIDTH_X32: 363 return 8 << REG_FIELD_GET(ICL_DIMM_L_WIDTH_MASK, val); 364 default: 365 MISSING_CASE(val); 366 return 0; 367 } 368 } 369 370 static int icl_get_dimm_s_ranks(u32 val) 371 { 372 if (icl_get_dimm_s_size(val) == 0) 373 return 0; 374 375 return REG_FIELD_GET(ICL_DIMM_S_RANK_MASK, val) + 1; 376 } 377 378 static int icl_get_dimm_l_ranks(u32 val) 379 { 380 if (icl_get_dimm_l_size(val) == 0) 381 return 0; 382 383 return REG_FIELD_GET(ICL_DIMM_L_RANK_MASK, val) + 1; 384 } 385 386 static bool 387 skl_is_16gb_dimm(const struct dram_dimm_info *dimm) 388 { 389 /* Convert total Gb to Gb per DRAM device */ 390 return dimm->size / (intel_dimm_num_devices(dimm) ?: 1) >= 16; 391 } 392 393 static void 394 skl_dram_print_dimm_info(struct intel_display *display, 395 struct dram_dimm_info *dimm, 396 int channel, char dimm_name) 397 { 398 drm_dbg_kms(display->drm, 399 "CH%u DIMM %c size: %u Gb, width: X%u, ranks: %u, 16Gb+ DIMMs: %s\n", 400 channel, dimm_name, dimm->size, dimm->width, dimm->ranks, 401 str_yes_no(skl_is_16gb_dimm(dimm))); 402 } 403 404 static void 405 skl_dram_get_dimm_l_info(struct intel_display *display, 406 struct dram_dimm_info *dimm, 407 int channel, u32 val) 408 { 409 if (DISPLAY_VER(display) >= 11) { 410 dimm->size = icl_get_dimm_l_size(val); 411 dimm->width = icl_get_dimm_l_width(val); 412 dimm->ranks = icl_get_dimm_l_ranks(val); 413 } else { 414 dimm->size = skl_get_dimm_l_size(val); 415 dimm->width = skl_get_dimm_l_width(val); 416 dimm->ranks = skl_get_dimm_l_ranks(val); 417 } 418 419 skl_dram_print_dimm_info(display, dimm, channel, 'L'); 420 } 421 422 static void 423 skl_dram_get_dimm_s_info(struct intel_display *display, 424 struct dram_dimm_info *dimm, 425 int channel, u32 val) 426 { 427 if (DISPLAY_VER(display) >= 11) { 428 dimm->size = icl_get_dimm_s_size(val); 429 dimm->width = icl_get_dimm_s_width(val); 430 dimm->ranks = icl_get_dimm_s_ranks(val); 431 } else { 432 dimm->size = skl_get_dimm_s_size(val); 433 dimm->width = skl_get_dimm_s_width(val); 434 dimm->ranks = skl_get_dimm_s_ranks(val); 435 } 436 437 skl_dram_print_dimm_info(display, dimm, channel, 'S'); 438 } 439 440 static int 441 skl_dram_get_channel_info(struct intel_display *display, 442 struct dram_channel_info *ch, 443 int channel, u32 val) 444 { 445 skl_dram_get_dimm_l_info(display, &ch->dimm_l, channel, val); 446 skl_dram_get_dimm_s_info(display, &ch->dimm_s, channel, val); 447 448 if (ch->dimm_l.size == 0 && ch->dimm_s.size == 0) { 449 drm_dbg_kms(display->drm, "CH%u not populated\n", channel); 450 return -EINVAL; 451 } 452 453 if (ch->dimm_l.ranks == 2 || ch->dimm_s.ranks == 2) 454 ch->ranks = 2; 455 else if (ch->dimm_l.ranks == 1 && ch->dimm_s.ranks == 1) 456 ch->ranks = 2; 457 else 458 ch->ranks = 1; 459 460 ch->is_16gb_dimm = skl_is_16gb_dimm(&ch->dimm_l) || 461 skl_is_16gb_dimm(&ch->dimm_s); 462 463 drm_dbg_kms(display->drm, "CH%u ranks: %u, 16Gb+ DIMMs: %s\n", 464 channel, ch->ranks, str_yes_no(ch->is_16gb_dimm)); 465 466 return 0; 467 } 468 469 static bool 470 intel_is_dram_symmetric(const struct dram_channel_info *ch0, 471 const struct dram_channel_info *ch1) 472 { 473 return !memcmp(ch0, ch1, sizeof(*ch0)) && 474 (ch0->dimm_s.size == 0 || 475 !memcmp(&ch0->dimm_l, &ch0->dimm_s, sizeof(ch0->dimm_l))); 476 } 477 478 static int 479 skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram_info) 480 { 481 struct dram_channel_info ch0 = {}, ch1 = {}; 482 u32 val; 483 int ret; 484 485 /* Assume 16Gb+ DIMMs are present until proven otherwise */ 486 dram_info->has_16gb_dimms = true; 487 488 val = intel_mchbar_read(display, SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); 489 ret = skl_dram_get_channel_info(display, &ch0, 0, val); 490 if (ret == 0) 491 dram_info->num_channels++; 492 493 val = intel_mchbar_read(display, SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); 494 ret = skl_dram_get_channel_info(display, &ch1, 1, val); 495 if (ret == 0) 496 dram_info->num_channels++; 497 498 if (dram_info->num_channels == 0) { 499 drm_info(display->drm, "Number of memory channels is zero\n"); 500 return -EINVAL; 501 } 502 503 if (ch0.ranks == 0 && ch1.ranks == 0) { 504 drm_info(display->drm, "couldn't get memory rank information\n"); 505 return -EINVAL; 506 } 507 508 dram_info->has_16gb_dimms = ch0.is_16gb_dimm || ch1.is_16gb_dimm; 509 510 dram_info->symmetric_memory = intel_is_dram_symmetric(&ch0, &ch1); 511 512 drm_dbg_kms(display->drm, "Memory configuration is symmetric? %s\n", 513 str_yes_no(dram_info->symmetric_memory)); 514 515 drm_dbg_kms(display->drm, "16Gb+ DIMMs: %s\n", 516 str_yes_no(dram_info->has_16gb_dimms)); 517 518 return 0; 519 } 520 521 static enum intel_dram_type 522 skl_get_dram_type(struct intel_display *display) 523 { 524 u32 val; 525 526 val = intel_mchbar_read(display, SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); 527 528 switch (val & SKL_DRAM_DDR_TYPE_MASK) { 529 case SKL_DRAM_DDR_TYPE_DDR3: 530 return INTEL_DRAM_DDR3; 531 case SKL_DRAM_DDR_TYPE_DDR4: 532 return INTEL_DRAM_DDR4; 533 case SKL_DRAM_DDR_TYPE_LPDDR3: 534 return INTEL_DRAM_LPDDR3; 535 case SKL_DRAM_DDR_TYPE_LPDDR4: 536 return INTEL_DRAM_LPDDR4; 537 default: 538 MISSING_CASE(val); 539 return INTEL_DRAM_UNKNOWN; 540 } 541 } 542 543 static int 544 skl_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 545 { 546 int ret; 547 548 dram_info->type = skl_get_dram_type(display); 549 550 ret = skl_dram_get_channels_info(display, dram_info); 551 if (ret) 552 return ret; 553 554 return 0; 555 } 556 557 /* Returns Gb per DRAM device */ 558 static int bxt_get_dimm_size(u32 val) 559 { 560 switch (val & BXT_DRAM_SIZE_MASK) { 561 case BXT_DRAM_SIZE_4GBIT: 562 return 4; 563 case BXT_DRAM_SIZE_6GBIT: 564 return 6; 565 case BXT_DRAM_SIZE_8GBIT: 566 return 8; 567 case BXT_DRAM_SIZE_12GBIT: 568 return 12; 569 case BXT_DRAM_SIZE_16GBIT: 570 return 16; 571 default: 572 MISSING_CASE(val); 573 return 0; 574 } 575 } 576 577 static int bxt_get_dimm_width(u32 val) 578 { 579 if (!bxt_get_dimm_size(val)) 580 return 0; 581 582 val = (val & BXT_DRAM_WIDTH_MASK) >> BXT_DRAM_WIDTH_SHIFT; 583 584 return 8 << val; 585 } 586 587 static int bxt_get_dimm_ranks(u32 val) 588 { 589 if (!bxt_get_dimm_size(val)) 590 return 0; 591 592 switch (val & BXT_DRAM_RANK_MASK) { 593 case BXT_DRAM_RANK_SINGLE: 594 return 1; 595 case BXT_DRAM_RANK_DUAL: 596 return 2; 597 default: 598 MISSING_CASE(val); 599 return 0; 600 } 601 } 602 603 static enum intel_dram_type bxt_get_dimm_type(u32 val) 604 { 605 if (!bxt_get_dimm_size(val)) 606 return INTEL_DRAM_UNKNOWN; 607 608 switch (val & BXT_DRAM_TYPE_MASK) { 609 case BXT_DRAM_TYPE_DDR3: 610 return INTEL_DRAM_DDR3; 611 case BXT_DRAM_TYPE_LPDDR3: 612 return INTEL_DRAM_LPDDR3; 613 case BXT_DRAM_TYPE_DDR4: 614 return INTEL_DRAM_DDR4; 615 case BXT_DRAM_TYPE_LPDDR4: 616 return INTEL_DRAM_LPDDR4; 617 default: 618 MISSING_CASE(val); 619 return INTEL_DRAM_UNKNOWN; 620 } 621 } 622 623 static void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val) 624 { 625 dimm->width = bxt_get_dimm_width(val); 626 dimm->ranks = bxt_get_dimm_ranks(val); 627 628 /* 629 * Size in register is Gb per DRAM device. Convert to total 630 * Gb to match the way we report this for non-LP platforms. 631 */ 632 dimm->size = bxt_get_dimm_size(val) * intel_dimm_num_devices(dimm); 633 } 634 635 static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 636 { 637 u32 val; 638 u8 valid_ranks = 0; 639 int i; 640 641 /* 642 * Now read each DUNIT8/9/10/11 to check the rank of each dimms. 643 */ 644 for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) { 645 struct dram_dimm_info dimm; 646 enum intel_dram_type type; 647 648 val = intel_mchbar_read(display, BXT_D_CR_DRP0_DUNIT(i)); 649 if (val == 0xFFFFFFFF) 650 continue; 651 652 dram_info->num_channels++; 653 654 bxt_get_dimm_info(&dimm, val); 655 type = bxt_get_dimm_type(val); 656 657 drm_WARN_ON(display->drm, type != INTEL_DRAM_UNKNOWN && 658 dram_info->type != INTEL_DRAM_UNKNOWN && 659 dram_info->type != type); 660 661 drm_dbg_kms(display->drm, 662 "CH%u DIMM size: %u Gb, width: X%u, ranks: %u\n", 663 i - BXT_D_CR_DRP0_DUNIT_START, 664 dimm.size, dimm.width, dimm.ranks); 665 666 if (valid_ranks == 0) 667 valid_ranks = dimm.ranks; 668 669 if (type != INTEL_DRAM_UNKNOWN) 670 dram_info->type = type; 671 } 672 673 if (dram_info->type == INTEL_DRAM_UNKNOWN || valid_ranks == 0) { 674 drm_info(display->drm, "couldn't get memory information\n"); 675 return -EINVAL; 676 } 677 678 return 0; 679 } 680 681 static int icl_pcode_read_mem_global_info(struct intel_display *display, 682 struct dram_info *dram_info) 683 { 684 u32 val = 0; 685 int ret; 686 687 ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 688 ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL); 689 if (ret) 690 return ret; 691 692 if (DISPLAY_VER(display) >= 12) { 693 switch (val & 0xf) { 694 case 0: 695 dram_info->type = INTEL_DRAM_DDR4; 696 break; 697 case 1: 698 dram_info->type = INTEL_DRAM_DDR5; 699 break; 700 case 2: 701 dram_info->type = INTEL_DRAM_LPDDR5; 702 break; 703 case 3: 704 dram_info->type = INTEL_DRAM_LPDDR4; 705 break; 706 case 4: 707 dram_info->type = INTEL_DRAM_DDR3; 708 break; 709 case 5: 710 dram_info->type = INTEL_DRAM_LPDDR3; 711 break; 712 default: 713 MISSING_CASE(val & 0xf); 714 return -EINVAL; 715 } 716 } else { 717 switch (val & 0xf) { 718 case 0: 719 dram_info->type = INTEL_DRAM_DDR4; 720 break; 721 case 1: 722 dram_info->type = INTEL_DRAM_DDR3; 723 break; 724 case 2: 725 dram_info->type = INTEL_DRAM_LPDDR3; 726 break; 727 case 3: 728 dram_info->type = INTEL_DRAM_LPDDR4; 729 break; 730 default: 731 MISSING_CASE(val & 0xf); 732 return -EINVAL; 733 } 734 } 735 736 dram_info->num_channels = (val & 0xf0) >> 4; 737 dram_info->num_qgv_points = (val & 0xf00) >> 8; 738 dram_info->num_psf_gv_points = (val & 0x3000) >> 12; 739 740 return 0; 741 } 742 743 static int gen11_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 744 { 745 int ret; 746 747 ret = skl_dram_get_channels_info(display, dram_info); 748 if (ret) 749 return ret; 750 751 return icl_pcode_read_mem_global_info(display, dram_info); 752 } 753 754 static int gen12_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 755 { 756 return icl_pcode_read_mem_global_info(display, dram_info); 757 } 758 759 static int xelpdp_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 760 { 761 u32 val = intel_de_read(display, MTL_MEM_SS_INFO_GLOBAL); 762 763 switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { 764 case 0: 765 dram_info->type = INTEL_DRAM_DDR4; 766 break; 767 case 1: 768 dram_info->type = INTEL_DRAM_DDR5; 769 break; 770 case 2: 771 dram_info->type = INTEL_DRAM_LPDDR5; 772 break; 773 case 3: 774 dram_info->type = INTEL_DRAM_LPDDR4; 775 break; 776 case 4: 777 dram_info->type = INTEL_DRAM_DDR3; 778 break; 779 case 5: 780 dram_info->type = INTEL_DRAM_LPDDR3; 781 break; 782 case 8: 783 drm_WARN_ON(display->drm, !display->platform.dgfx); 784 dram_info->type = INTEL_DRAM_GDDR; 785 break; 786 case 9: 787 drm_WARN_ON(display->drm, !display->platform.dgfx); 788 dram_info->type = INTEL_DRAM_GDDR_ECC; 789 break; 790 default: 791 MISSING_CASE(val); 792 return -EINVAL; 793 } 794 795 dram_info->num_channels = REG_FIELD_GET(MTL_N_OF_POPULATED_CH_MASK, val); 796 dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val); 797 /* PSF GV points not supported in D14+ */ 798 799 if (DISPLAY_VER(display) >= 35) 800 dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val); 801 802 return 0; 803 } 804 805 int intel_dram_detect(struct intel_display *display) 806 { 807 struct dram_info *dram_info; 808 int ret; 809 810 if (display->platform.dg2 || !HAS_DISPLAY(display)) 811 return 0; 812 813 dram_info = drmm_kzalloc(display->drm, sizeof(*dram_info), GFP_KERNEL); 814 if (!dram_info) 815 return -ENOMEM; 816 817 display->dram.info = dram_info; 818 819 if (DISPLAY_VER(display) >= 14) 820 ret = xelpdp_get_dram_info(display, dram_info); 821 else if (DISPLAY_VER(display) >= 12) 822 ret = gen12_get_dram_info(display, dram_info); 823 else if (DISPLAY_VER(display) >= 11) 824 ret = gen11_get_dram_info(display, dram_info); 825 else if (display->platform.broxton || display->platform.geminilake) 826 ret = bxt_get_dram_info(display, dram_info); 827 else if (DISPLAY_VER(display) >= 9) 828 ret = skl_get_dram_info(display, dram_info); 829 else 830 ret = i915_get_dram_info(display, dram_info); 831 832 drm_dbg_kms(display->drm, "DRAM type: %s\n", 833 intel_dram_type_str(dram_info->type)); 834 835 drm_dbg_kms(display->drm, "DRAM channels: %u\n", dram_info->num_channels); 836 837 drm_dbg_kms(display->drm, "Num QGV points %u\n", dram_info->num_qgv_points); 838 drm_dbg_kms(display->drm, "Num PSF GV points %u\n", dram_info->num_psf_gv_points); 839 840 /* TODO: Do we want to abort probe on dram detection failures? */ 841 if (ret) 842 return 0; 843 844 return 0; 845 } 846 847 /* 848 * Returns NULL for platforms that don't have dram info. Avoid overzealous NULL 849 * checks, and prefer not dereferencing on platforms that shouldn't look at dram 850 * info, to catch accidental and incorrect dram info checks. 851 */ 852 const struct dram_info *intel_dram_info(struct intel_display *display) 853 { 854 return display->dram.info; 855 } 856