Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/pm: add edc leakage controller setting

Enable edc controller table setting.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Evan Quan and committed by
Alex Deucher
8f0804c6 9610a3bf

+252
+16
drivers/gpu/drm/amd/include/atombios.h
··· 5655 5655 UCHAR max_texture_channel_caches; 5656 5656 }ATOM_GFX_INFO_V2_1; 5657 5657 5658 + typedef struct _ATOM_GFX_INFO_V2_3 5659 + { 5660 + ATOM_COMMON_TABLE_HEADER asHeader; 5661 + UCHAR GfxIpMinVer; 5662 + UCHAR GfxIpMajVer; 5663 + UCHAR max_shader_engines; 5664 + UCHAR max_tile_pipes; 5665 + UCHAR max_cu_per_sh; 5666 + UCHAR max_sh_per_se; 5667 + UCHAR max_backends_per_se; 5668 + UCHAR max_texture_channel_caches; 5669 + USHORT usHiLoLeakageThreshold; 5670 + USHORT usEdcDidtLoDpm7TableOffset; //offset of DPM7 low leakage table _ATOM_EDC_DIDT_TABLE_V1 5671 + USHORT usEdcDidtHiDpm7TableOffset; //offset of DPM7 high leakage table _ATOM_EDC_DIDT_TABLE_V1 5672 + USHORT usReserverd[3]; 5673 + }ATOM_GFX_INFO_V2_3; 5658 5674 5659 5675 typedef struct _ATOM_POWER_SOURCE_OBJECT 5660 5676 {
+3
drivers/gpu/drm/amd/pm/inc/smu7_ppsmc.h
··· 404 404 #define PPSMC_MSG_EnableDpmDidt ((uint16_t) 0x309) 405 405 #define PPSMC_MSG_DisableDpmDidt ((uint16_t) 0x30A) 406 406 407 + #define PPSMC_MSG_EnableEDCController ((uint16_t) 0x316) 408 + #define PPSMC_MSG_DisableEDCController ((uint16_t) 0x317) 409 + 407 410 #define PPSMC_MSG_SecureSRBMWrite ((uint16_t) 0x600) 408 411 #define PPSMC_MSG_SecureSRBMRead ((uint16_t) 0x601) 409 412 #define PPSMC_MSG_SetAddress ((uint16_t) 0x800)
+53
drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
··· 1566 1566 *max_vddc = 0; 1567 1567 *min_vddc = 0; 1568 1568 } 1569 + 1570 + int atomctrl_get_edc_hilo_leakage_offset_table(struct pp_hwmgr *hwmgr, 1571 + AtomCtrl_HiLoLeakageOffsetTable *table) 1572 + { 1573 + ATOM_GFX_INFO_V2_3 *gfxinfo = smu_atom_get_data_table(hwmgr->adev, 1574 + GetIndexIntoMasterTable(DATA, GFX_Info), 1575 + NULL, NULL, NULL); 1576 + if (!gfxinfo) 1577 + return -ENOENT; 1578 + 1579 + table->usHiLoLeakageThreshold = gfxinfo->usHiLoLeakageThreshold; 1580 + table->usEdcDidtLoDpm7TableOffset = gfxinfo->usEdcDidtLoDpm7TableOffset; 1581 + table->usEdcDidtHiDpm7TableOffset = gfxinfo->usEdcDidtHiDpm7TableOffset; 1582 + 1583 + return 0; 1584 + } 1585 + 1586 + static AtomCtrl_EDCLeakgeTable *get_edc_leakage_table(struct pp_hwmgr *hwmgr, 1587 + uint16_t offset) 1588 + { 1589 + void *table_address; 1590 + char *temp; 1591 + 1592 + table_address = smu_atom_get_data_table(hwmgr->adev, 1593 + GetIndexIntoMasterTable(DATA, GFX_Info), 1594 + NULL, NULL, NULL); 1595 + if (!table_address) 1596 + return NULL; 1597 + 1598 + temp = (char *)table_address; 1599 + table_address += offset; 1600 + 1601 + return (AtomCtrl_EDCLeakgeTable *)temp; 1602 + } 1603 + 1604 + int atomctrl_get_edc_leakage_table(struct pp_hwmgr *hwmgr, 1605 + AtomCtrl_EDCLeakgeTable *table, 1606 + uint16_t offset) 1607 + { 1608 + uint32_t length, i; 1609 + AtomCtrl_EDCLeakgeTable *leakage_table = 1610 + get_edc_leakage_table(hwmgr, offset); 1611 + 1612 + if (!leakage_table) 1613 + return -ENOENT; 1614 + 1615 + length = sizeof(leakage_table->DIDT_REG) / 1616 + sizeof(leakage_table->DIDT_REG[0]); 1617 + for (i = 0; i < length; i++) 1618 + table->DIDT_REG[i] = leakage_table->DIDT_REG[i]; 1619 + 1620 + return 0; 1621 + }
+22
drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.h
··· 278 278 uint8_t ucReserved; 279 279 }; 280 280 281 + struct _AtomCtrl_HiLoLeakageOffsetTable 282 + { 283 + USHORT usHiLoLeakageThreshold; 284 + USHORT usEdcDidtLoDpm7TableOffset; 285 + USHORT usEdcDidtHiDpm7TableOffset; 286 + }; 287 + typedef struct _AtomCtrl_HiLoLeakageOffsetTable AtomCtrl_HiLoLeakageOffsetTable; 288 + 289 + struct _AtomCtrl_EDCLeakgeTable 290 + { 291 + ULONG DIDT_REG[24]; 292 + }; 293 + typedef struct _AtomCtrl_EDCLeakgeTable AtomCtrl_EDCLeakgeTable; 294 + 281 295 extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment); 282 296 extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage); 283 297 extern int atomctrl_get_voltage_evv(struct pp_hwmgr *hwmgr, uint16_t virtual_voltage_id, uint16_t *voltage); ··· 338 324 339 325 extern void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc, 340 326 uint32_t *min_vddc); 327 + 328 + extern int atomctrl_get_edc_hilo_leakage_offset_table(struct pp_hwmgr *hwmgr, 329 + AtomCtrl_HiLoLeakageOffsetTable *table); 330 + 331 + extern int atomctrl_get_edc_leakage_table(struct pp_hwmgr *hwmgr, 332 + AtomCtrl_EDCLeakgeTable *table, 333 + uint16_t offset); 334 + 341 335 #endif 342 336
+154
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
··· 109 109 DPM_EVENT_SRC_DIGITAL_OR_EXTERNAL = 4 110 110 }; 111 111 112 + #define ixDIDT_SQ_EDC_CTRL 0x0013 113 + #define ixDIDT_SQ_EDC_THRESHOLD 0x0014 114 + #define ixDIDT_SQ_EDC_STALL_PATTERN_1_2 0x0015 115 + #define ixDIDT_SQ_EDC_STALL_PATTERN_3_4 0x0016 116 + #define ixDIDT_SQ_EDC_STALL_PATTERN_5_6 0x0017 117 + #define ixDIDT_SQ_EDC_STALL_PATTERN_7 0x0018 118 + 119 + #define ixDIDT_TD_EDC_CTRL 0x0053 120 + #define ixDIDT_TD_EDC_THRESHOLD 0x0054 121 + #define ixDIDT_TD_EDC_STALL_PATTERN_1_2 0x0055 122 + #define ixDIDT_TD_EDC_STALL_PATTERN_3_4 0x0056 123 + #define ixDIDT_TD_EDC_STALL_PATTERN_5_6 0x0057 124 + #define ixDIDT_TD_EDC_STALL_PATTERN_7 0x0058 125 + 126 + #define ixDIDT_TCP_EDC_CTRL 0x0073 127 + #define ixDIDT_TCP_EDC_THRESHOLD 0x0074 128 + #define ixDIDT_TCP_EDC_STALL_PATTERN_1_2 0x0075 129 + #define ixDIDT_TCP_EDC_STALL_PATTERN_3_4 0x0076 130 + #define ixDIDT_TCP_EDC_STALL_PATTERN_5_6 0x0077 131 + #define ixDIDT_TCP_EDC_STALL_PATTERN_7 0x0078 132 + 133 + #define ixDIDT_DB_EDC_CTRL 0x0033 134 + #define ixDIDT_DB_EDC_THRESHOLD 0x0034 135 + #define ixDIDT_DB_EDC_STALL_PATTERN_1_2 0x0035 136 + #define ixDIDT_DB_EDC_STALL_PATTERN_3_4 0x0036 137 + #define ixDIDT_DB_EDC_STALL_PATTERN_5_6 0x0037 138 + #define ixDIDT_DB_EDC_STALL_PATTERN_7 0x0038 139 + 140 + uint32_t DIDTEDCConfig_P12[] = { 141 + ixDIDT_SQ_EDC_STALL_PATTERN_1_2, 142 + ixDIDT_SQ_EDC_STALL_PATTERN_3_4, 143 + ixDIDT_SQ_EDC_STALL_PATTERN_5_6, 144 + ixDIDT_SQ_EDC_STALL_PATTERN_7, 145 + ixDIDT_SQ_EDC_THRESHOLD, 146 + ixDIDT_SQ_EDC_CTRL, 147 + ixDIDT_TD_EDC_STALL_PATTERN_1_2, 148 + ixDIDT_TD_EDC_STALL_PATTERN_3_4, 149 + ixDIDT_TD_EDC_STALL_PATTERN_5_6, 150 + ixDIDT_TD_EDC_STALL_PATTERN_7, 151 + ixDIDT_TD_EDC_THRESHOLD, 152 + ixDIDT_TD_EDC_CTRL, 153 + ixDIDT_TCP_EDC_STALL_PATTERN_1_2, 154 + ixDIDT_TCP_EDC_STALL_PATTERN_3_4, 155 + ixDIDT_TCP_EDC_STALL_PATTERN_5_6, 156 + ixDIDT_TCP_EDC_STALL_PATTERN_7, 157 + ixDIDT_TCP_EDC_THRESHOLD, 158 + ixDIDT_TCP_EDC_CTRL, 159 + ixDIDT_DB_EDC_STALL_PATTERN_1_2, 160 + ixDIDT_DB_EDC_STALL_PATTERN_3_4, 161 + ixDIDT_DB_EDC_STALL_PATTERN_5_6, 162 + ixDIDT_DB_EDC_STALL_PATTERN_7, 163 + ixDIDT_DB_EDC_THRESHOLD, 164 + ixDIDT_DB_EDC_CTRL, 165 + 0xFFFFFFFF // End of list 166 + }; 167 + 112 168 static const unsigned long PhwVIslands_Magic = (unsigned long)(PHM_VIslands_Magic); 113 169 static int smu7_force_clock_level(struct pp_hwmgr *hwmgr, 114 170 enum pp_clock_type type, uint32_t mask); ··· 1390 1334 return 0; 1391 1335 } 1392 1336 1337 + static int smu7_program_edc_didt_registers(struct pp_hwmgr *hwmgr, 1338 + uint32_t *cac_config_regs, 1339 + AtomCtrl_EDCLeakgeTable *edc_leakage_table) 1340 + { 1341 + uint32_t data, i = 0; 1342 + 1343 + while (cac_config_regs[i] != 0xFFFFFFFF) { 1344 + data = edc_leakage_table->DIDT_REG[i]; 1345 + cgs_write_ind_register(hwmgr->device, 1346 + CGS_IND_REG__DIDT, 1347 + cac_config_regs[i], 1348 + data); 1349 + i++; 1350 + } 1351 + 1352 + return 0; 1353 + } 1354 + 1355 + static int smu7_populate_edc_leakage_registers(struct pp_hwmgr *hwmgr) 1356 + { 1357 + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1358 + int ret = 0; 1359 + 1360 + if (!data->disable_edc_leakage_controller && 1361 + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset && 1362 + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset) { 1363 + ret = smu7_program_edc_didt_registers(hwmgr, 1364 + DIDTEDCConfig_P12, 1365 + &data->edc_leakage_table); 1366 + if (ret) 1367 + return ret; 1368 + 1369 + ret = smum_send_msg_to_smc(hwmgr, 1370 + (PPSMC_Msg)PPSMC_MSG_EnableEDCController, 1371 + NULL); 1372 + } else { 1373 + ret = smum_send_msg_to_smc(hwmgr, 1374 + (PPSMC_Msg)PPSMC_MSG_DisableEDCController, 1375 + NULL); 1376 + } 1377 + 1378 + return ret; 1379 + } 1380 + 1393 1381 static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) 1394 1382 { 1395 1383 int tmp_result = 0; ··· 1499 1399 "Failed to enable VR hot GPIO interrupt!", result = tmp_result); 1500 1400 1501 1401 smum_send_msg_to_smc(hwmgr, (PPSMC_Msg)PPSMC_NoDisplay, NULL); 1402 + 1403 + if (hwmgr->chip_id >= CHIP_POLARIS10 && 1404 + hwmgr->chip_id <= CHIP_VEGAM) { 1405 + tmp_result = smu7_populate_edc_leakage_registers(hwmgr); 1406 + PP_ASSERT_WITH_CODE((0 == tmp_result), 1407 + "Failed to populate edc leakage registers!", result = tmp_result); 1408 + } 1502 1409 1503 1410 tmp_result = smu7_enable_sclk_control(hwmgr); 1504 1411 PP_ASSERT_WITH_CODE((0 == tmp_result), ··· 1804 1697 if (adev->pg_flags & AMD_PG_SUPPORT_VCE) 1805 1698 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 1806 1699 PHM_PlatformCaps_VCEPowerGating); 1700 + 1701 + data->disable_edc_leakage_controller = true; 1702 + if (((adev->asic_type == CHIP_POLARIS10) && hwmgr->is_kicker) || 1703 + ((adev->asic_type == CHIP_POLARIS11) && hwmgr->is_kicker) || 1704 + (adev->asic_type == CHIP_POLARIS12) || 1705 + (adev->asic_type == CHIP_VEGAM)) 1706 + data->disable_edc_leakage_controller = false; 1807 1707 } 1808 1708 1809 1709 static int smu7_calculate_ro_range(struct pp_hwmgr *hwmgr) ··· 2725 2611 return 0; 2726 2612 } 2727 2613 2614 + #define LEAKAGE_ID_MSB 463 2615 + #define LEAKAGE_ID_LSB 454 2616 + 2617 + static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) 2618 + { 2619 + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 2620 + uint32_t efuse; 2621 + uint16_t offset; 2622 + int ret = 0; 2623 + 2624 + if (data->disable_edc_leakage_controller) 2625 + return 0; 2626 + 2627 + ret = atomctrl_get_edc_hilo_leakage_offset_table(hwmgr, 2628 + &data->edc_hilo_leakage_offset_from_vbios); 2629 + if (ret) 2630 + return ret; 2631 + 2632 + if (data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset && 2633 + data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset) { 2634 + atomctrl_read_efuse(hwmgr, LEAKAGE_ID_LSB, LEAKAGE_ID_MSB, &efuse); 2635 + if (efuse < data->edc_hilo_leakage_offset_from_vbios.usHiLoLeakageThreshold) 2636 + offset = data->edc_hilo_leakage_offset_from_vbios.usEdcDidtLoDpm7TableOffset; 2637 + else 2638 + offset = data->edc_hilo_leakage_offset_from_vbios.usEdcDidtHiDpm7TableOffset; 2639 + 2640 + ret = atomctrl_get_edc_leakage_table(hwmgr, 2641 + &data->edc_leakage_table, 2642 + offset); 2643 + if (ret) 2644 + return ret; 2645 + } 2646 + 2647 + return ret; 2648 + } 2649 + 2728 2650 static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) 2729 2651 { 2730 2652 struct smu7_hwmgr *data; ··· 2821 2671 /* Ignore return value in here, we are cleaning up a mess. */ 2822 2672 smu7_hwmgr_backend_fini(hwmgr); 2823 2673 } 2674 + 2675 + result = smu7_update_edc_leakage_table(hwmgr); 2676 + if (result) 2677 + return result; 2824 2678 2825 2679 return 0; 2826 2680 }
+4
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.h
··· 331 331 332 332 uint32_t ro_range_minimum; 333 333 uint32_t ro_range_maximum; 334 + 335 + bool disable_edc_leakage_controller; 336 + AtomCtrl_HiLoLeakageOffsetTable edc_hilo_leakage_offset_from_vbios; 337 + AtomCtrl_EDCLeakgeTable edc_leakage_table; 334 338 }; 335 339 336 340 /* To convert to Q8.8 format for firmware */