diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2016-08-19 08:42:09 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-09-19 13:22:14 -0400 |
commit | ac43f0800f46f6648b49231b54646034a4143145 (patch) | |
tree | 22f05eae8af6cd656a36c55492189bd401afc6b7 /drivers/gpu | |
parent | 1ff55f4651037821b1d8b028bb0541e2b404f044 (diff) |
drm/amd/powerplay: use smu7 common functions and data on Tonga.
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c | 201 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | 657 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h | 33 |
3 files changed, 117 insertions, 774 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c index 3acdbffed88c..4dfd3f60a967 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c | |||
@@ -347,27 +347,27 @@ static int tonga_populate_smc_voltage_tables(struct pp_hwmgr *hwmgr, | |||
347 | int result; | 347 | int result; |
348 | 348 | ||
349 | result = tonga_populate_smc_vddc_table(hwmgr, table); | 349 | result = tonga_populate_smc_vddc_table(hwmgr, table); |
350 | PP_ASSERT_WITH_CODE(0 == result, | 350 | PP_ASSERT_WITH_CODE(!result, |
351 | "can not populate VDDC voltage table to SMC", | 351 | "can not populate VDDC voltage table to SMC", |
352 | return -EINVAL); | 352 | return -EINVAL); |
353 | 353 | ||
354 | result = tonga_populate_smc_vdd_ci_table(hwmgr, table); | 354 | result = tonga_populate_smc_vdd_ci_table(hwmgr, table); |
355 | PP_ASSERT_WITH_CODE(0 == result, | 355 | PP_ASSERT_WITH_CODE(!result, |
356 | "can not populate VDDCI voltage table to SMC", | 356 | "can not populate VDDCI voltage table to SMC", |
357 | return -EINVAL); | 357 | return -EINVAL); |
358 | 358 | ||
359 | result = tonga_populate_smc_vdd_gfx_table(hwmgr, table); | 359 | result = tonga_populate_smc_vdd_gfx_table(hwmgr, table); |
360 | PP_ASSERT_WITH_CODE(0 == result, | 360 | PP_ASSERT_WITH_CODE(!result, |
361 | "can not populate VDDGFX voltage table to SMC", | 361 | "can not populate VDDGFX voltage table to SMC", |
362 | return -EINVAL); | 362 | return -EINVAL); |
363 | 363 | ||
364 | result = tonga_populate_smc_mvdd_table(hwmgr, table); | 364 | result = tonga_populate_smc_mvdd_table(hwmgr, table); |
365 | PP_ASSERT_WITH_CODE(0 == result, | 365 | PP_ASSERT_WITH_CODE(!result, |
366 | "can not populate MVDD voltage table to SMC", | 366 | "can not populate MVDD voltage table to SMC", |
367 | return -EINVAL); | 367 | return -EINVAL); |
368 | 368 | ||
369 | result = tonga_populate_cac_tables(hwmgr, table); | 369 | result = tonga_populate_cac_tables(hwmgr, table); |
370 | PP_ASSERT_WITH_CODE(0 == result, | 370 | PP_ASSERT_WITH_CODE(!result, |
371 | "can not populate CAC voltage tables to SMC", | 371 | "can not populate CAC voltage tables to SMC", |
372 | return -EINVAL); | 372 | return -EINVAL); |
373 | 373 | ||
@@ -542,7 +542,7 @@ static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, | |||
542 | result = tonga_get_dependecy_volt_by_clk(hwmgr, | 542 | result = tonga_get_dependecy_volt_by_clk(hwmgr, |
543 | pptable_info->vdd_dep_on_sclk, engine_clock, | 543 | pptable_info->vdd_dep_on_sclk, engine_clock, |
544 | &graphic_level->MinVoltage, &mvdd); | 544 | &graphic_level->MinVoltage, &mvdd); |
545 | PP_ASSERT_WITH_CODE((0 == result), | 545 | PP_ASSERT_WITH_CODE((!result), |
546 | "can not find VDDC voltage value for VDDC " | 546 | "can not find VDDC voltage value for VDDC " |
547 | "engine clock dependency table", return result); | 547 | "engine clock dependency table", return result); |
548 | 548 | ||
@@ -574,7 +574,7 @@ static int tonga_populate_single_graphic_level(struct pp_hwmgr *hwmgr, | |||
574 | /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ | 574 | /* Default to slow, highest DPM level will be set to PPSMC_DISPLAY_WATERMARK_LOW later.*/ |
575 | graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; | 575 | graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; |
576 | 576 | ||
577 | if (0 == result) { | 577 | if (!result) { |
578 | /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/ | 578 | /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVoltage);*/ |
579 | /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);*/ | 579 | /* CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->MinVddcPhases);*/ |
580 | CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); | 580 | CONVERT_FROM_HOST_TO_SMC_UL(graphic_level->SclkFrequency); |
@@ -603,7 +603,7 @@ int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) | |||
603 | struct smu7_dpm_table *dpm_table = &data->dpm_table; | 603 | struct smu7_dpm_table *dpm_table = &data->dpm_table; |
604 | struct phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table; | 604 | struct phm_ppt_v1_pcie_table *pcie_table = pptable_info->pcie_table; |
605 | uint8_t pcie_entry_count = (uint8_t) data->dpm_table.pcie_speed_table.count; | 605 | uint8_t pcie_entry_count = (uint8_t) data->dpm_table.pcie_speed_table.count; |
606 | uint32_t level_array_address = smu_data->dpm_table_start + | 606 | uint32_t level_array_address = smu_data->smu7_data.dpm_table_start + |
607 | offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); | 607 | offsetof(SMU72_Discrete_DpmTable, GraphicsLevel); |
608 | 608 | ||
609 | uint32_t level_array_size = sizeof(SMU72_Discrete_GraphicsLevel) * | 609 | uint32_t level_array_size = sizeof(SMU72_Discrete_GraphicsLevel) * |
@@ -690,7 +690,7 @@ int tonga_populate_all_graphic_levels(struct pp_hwmgr *hwmgr) | |||
690 | smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; | 690 | smu_data->smc_state_table.GraphicsLevel[1].pcieDpmLevel = mid_pcie_level_enabled; |
691 | } | 691 | } |
692 | /* level count will send to smc once at init smc table and never change*/ | 692 | /* level count will send to smc once at init smc table and never change*/ |
693 | result = tonga_copy_bytes_to_smc(hwmgr->smumgr, level_array_address, | 693 | result = smu7_copy_bytes_to_smc(hwmgr->smumgr, level_array_address, |
694 | (uint8_t *)levels, (uint32_t)level_array_size, | 694 | (uint8_t *)levels, (uint32_t)level_array_size, |
695 | SMC_RAM_END); | 695 | SMC_RAM_END); |
696 | 696 | ||
@@ -730,7 +730,7 @@ static int tonga_calculate_mclk_params( | |||
730 | result = atomctrl_get_memory_pll_dividers_si(hwmgr, | 730 | result = atomctrl_get_memory_pll_dividers_si(hwmgr, |
731 | memory_clock, &mpll_param, strobe_mode); | 731 | memory_clock, &mpll_param, strobe_mode); |
732 | PP_ASSERT_WITH_CODE( | 732 | PP_ASSERT_WITH_CODE( |
733 | 0 == result, | 733 | !result, |
734 | "Error retrieving Memory Clock Parameters from VBIOS.", | 734 | "Error retrieving Memory Clock Parameters from VBIOS.", |
735 | return result); | 735 | return result); |
736 | 736 | ||
@@ -900,7 +900,7 @@ static int tonga_populate_single_memory_level( | |||
900 | memory_clock, | 900 | memory_clock, |
901 | &memory_level->MinVoltage, &mvdd); | 901 | &memory_level->MinVoltage, &mvdd); |
902 | PP_ASSERT_WITH_CODE( | 902 | PP_ASSERT_WITH_CODE( |
903 | 0 == result, | 903 | !result, |
904 | "can not find MinVddc voltage value from memory VDDC " | 904 | "can not find MinVddc voltage value from memory VDDC " |
905 | "voltage dependency table", | 905 | "voltage dependency table", |
906 | return result); | 906 | return result); |
@@ -1008,7 +1008,7 @@ int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr) | |||
1008 | 1008 | ||
1009 | /* populate MCLK dpm table to SMU7 */ | 1009 | /* populate MCLK dpm table to SMU7 */ |
1010 | uint32_t level_array_address = | 1010 | uint32_t level_array_address = |
1011 | smu_data->dpm_table_start + | 1011 | smu_data->smu7_data.dpm_table_start + |
1012 | offsetof(SMU72_Discrete_DpmTable, MemoryLevel); | 1012 | offsetof(SMU72_Discrete_DpmTable, MemoryLevel); |
1013 | uint32_t level_array_size = | 1013 | uint32_t level_array_size = |
1014 | sizeof(SMU72_Discrete_MemoryLevel) * | 1014 | sizeof(SMU72_Discrete_MemoryLevel) * |
@@ -1048,11 +1048,10 @@ int tonga_populate_all_memory_levels(struct pp_hwmgr *hwmgr) | |||
1048 | smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; | 1048 | smu_data->smc_state_table.MemoryLevel[dpm_table->mclk_table.count-1].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; |
1049 | 1049 | ||
1050 | /* level count will send to smc once at init smc table and never change*/ | 1050 | /* level count will send to smc once at init smc table and never change*/ |
1051 | result = tonga_copy_bytes_to_smc(hwmgr->smumgr, | 1051 | result = smu7_copy_bytes_to_smc(hwmgr->smumgr, |
1052 | level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, | 1052 | level_array_address, (uint8_t *)levels, (uint32_t)level_array_size, |
1053 | SMC_RAM_END); | 1053 | SMC_RAM_END); |
1054 | 1054 | ||
1055 | |||
1056 | return result; | 1055 | return result; |
1057 | } | 1056 | } |
1058 | 1057 | ||
@@ -1257,7 +1256,7 @@ static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, | |||
1257 | table->UvdLevel[count].VclkFrequency, | 1256 | table->UvdLevel[count].VclkFrequency, |
1258 | ÷rs); | 1257 | ÷rs); |
1259 | 1258 | ||
1260 | PP_ASSERT_WITH_CODE((0 == result), | 1259 | PP_ASSERT_WITH_CODE((!result), |
1261 | "can not find divide id for Vclk clock", | 1260 | "can not find divide id for Vclk clock", |
1262 | return result); | 1261 | return result); |
1263 | 1262 | ||
@@ -1265,7 +1264,7 @@ static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, | |||
1265 | 1264 | ||
1266 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, | 1265 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, |
1267 | table->UvdLevel[count].DclkFrequency, ÷rs); | 1266 | table->UvdLevel[count].DclkFrequency, ÷rs); |
1268 | PP_ASSERT_WITH_CODE((0 == result), | 1267 | PP_ASSERT_WITH_CODE((!result), |
1269 | "can not find divide id for Dclk clock", | 1268 | "can not find divide id for Dclk clock", |
1270 | return result); | 1269 | return result); |
1271 | 1270 | ||
@@ -1314,7 +1313,7 @@ static int tonga_populate_smc_vce_level(struct pp_hwmgr *hwmgr, | |||
1314 | /* retrieve divider value for VBIOS */ | 1313 | /* retrieve divider value for VBIOS */ |
1315 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, | 1314 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, |
1316 | table->VceLevel[count].Frequency, ÷rs); | 1315 | table->VceLevel[count].Frequency, ÷rs); |
1317 | PP_ASSERT_WITH_CODE((0 == result), | 1316 | PP_ASSERT_WITH_CODE((!result), |
1318 | "can not find divide id for VCE engine clock", | 1317 | "can not find divide id for VCE engine clock", |
1319 | return result); | 1318 | return result); |
1320 | 1319 | ||
@@ -1359,7 +1358,7 @@ static int tonga_populate_smc_acp_level(struct pp_hwmgr *hwmgr, | |||
1359 | /* retrieve divider value for VBIOS */ | 1358 | /* retrieve divider value for VBIOS */ |
1360 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, | 1359 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, |
1361 | table->AcpLevel[count].Frequency, ÷rs); | 1360 | table->AcpLevel[count].Frequency, ÷rs); |
1362 | PP_ASSERT_WITH_CODE((0 == result), | 1361 | PP_ASSERT_WITH_CODE((!result), |
1363 | "can not find divide id for engine clock", return result); | 1362 | "can not find divide id for engine clock", return result); |
1364 | 1363 | ||
1365 | table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; | 1364 | table->AcpLevel[count].Divider = (uint8_t)dividers.pll_post_divider; |
@@ -1404,7 +1403,7 @@ static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr, | |||
1404 | /* retrieve divider value for VBIOS */ | 1403 | /* retrieve divider value for VBIOS */ |
1405 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, | 1404 | result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, |
1406 | table->SamuLevel[count].Frequency, ÷rs); | 1405 | table->SamuLevel[count].Frequency, ÷rs); |
1407 | PP_ASSERT_WITH_CODE((0 == result), | 1406 | PP_ASSERT_WITH_CODE((!result), |
1408 | "can not find divide id for samu clock", return result); | 1407 | "can not find divide id for samu clock", return result); |
1409 | 1408 | ||
1410 | table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; | 1409 | table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; |
@@ -1474,10 +1473,10 @@ static int tonga_program_memory_timing_parameters(struct pp_hwmgr *hwmgr) | |||
1474 | } | 1473 | } |
1475 | } | 1474 | } |
1476 | 1475 | ||
1477 | if (0 == result) { | 1476 | if (!result) { |
1478 | result = tonga_copy_bytes_to_smc( | 1477 | result = smu7_copy_bytes_to_smc( |
1479 | hwmgr->smumgr, | 1478 | hwmgr->smumgr, |
1480 | smu_data->arb_table_start, | 1479 | smu_data->smu7_data.arb_table_start, |
1481 | (uint8_t *)&arb_regs, | 1480 | (uint8_t *)&arb_regs, |
1482 | sizeof(SMU72_Discrete_MCArbDramTimingTable), | 1481 | sizeof(SMU72_Discrete_MCArbDramTimingTable), |
1483 | SMC_RAM_END | 1482 | SMC_RAM_END |
@@ -1502,7 +1501,7 @@ static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr, | |||
1502 | data->vbios_boot_state.sclk_bootup_value, | 1501 | data->vbios_boot_state.sclk_bootup_value, |
1503 | (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); | 1502 | (uint32_t *)&(smu_data->smc_state_table.GraphicsBootLevel)); |
1504 | 1503 | ||
1505 | if (0 != result) { | 1504 | if (result != 0) { |
1506 | smu_data->smc_state_table.GraphicsBootLevel = 0; | 1505 | smu_data->smc_state_table.GraphicsBootLevel = 0; |
1507 | printk(KERN_ERR "[powerplay] VBIOS did not find boot engine " | 1506 | printk(KERN_ERR "[powerplay] VBIOS did not find boot engine " |
1508 | "clock value in dependency table. " | 1507 | "clock value in dependency table. " |
@@ -1514,7 +1513,7 @@ static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr, | |||
1514 | data->vbios_boot_state.mclk_bootup_value, | 1513 | data->vbios_boot_state.mclk_bootup_value, |
1515 | (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); | 1514 | (uint32_t *)&(smu_data->smc_state_table.MemoryBootLevel)); |
1516 | 1515 | ||
1517 | if (0 != result) { | 1516 | if (result != 0) { |
1518 | smu_data->smc_state_table.MemoryBootLevel = 0; | 1517 | smu_data->smc_state_table.MemoryBootLevel = 0; |
1519 | printk(KERN_ERR "[powerplay] VBIOS did not find boot " | 1518 | printk(KERN_ERR "[powerplay] VBIOS did not find boot " |
1520 | "engine clock value in dependency table." | 1519 | "engine clock value in dependency table." |
@@ -1538,7 +1537,6 @@ static int tonga_populate_smc_boot_level(struct pp_hwmgr *hwmgr, | |||
1538 | return result; | 1537 | return result; |
1539 | } | 1538 | } |
1540 | 1539 | ||
1541 | |||
1542 | static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) | 1540 | static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) |
1543 | { | 1541 | { |
1544 | uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, | 1542 | uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, |
@@ -1591,6 +1589,7 @@ static int tonga_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) | |||
1591 | /* Populate Stretch amount */ | 1589 | /* Populate Stretch amount */ |
1592 | smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; | 1590 | smu_data->smc_state_table.ClockStretcherAmount = stretch_amount; |
1593 | 1591 | ||
1592 | |||
1594 | /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ | 1593 | /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ |
1595 | for (i = 0; i < sclk_table->count; i++) { | 1594 | for (i = 0; i < sclk_table->count; i++) { |
1596 | smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= | 1595 | smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |= |
@@ -1798,17 +1797,17 @@ static int tonga_init_arb_table_index(struct pp_smumgr *smumgr) | |||
1798 | * In reality this field should not be in that structure | 1797 | * In reality this field should not be in that structure |
1799 | * but in a soft register. | 1798 | * but in a soft register. |
1800 | */ | 1799 | */ |
1801 | result = tonga_read_smc_sram_dword(smumgr, | 1800 | result = smu7_read_smc_sram_dword(smumgr, |
1802 | smu_data->arb_table_start, &tmp, SMC_RAM_END); | 1801 | smu_data->smu7_data.arb_table_start, &tmp, SMC_RAM_END); |
1803 | 1802 | ||
1804 | if (0 != result) | 1803 | if (result != 0) |
1805 | return result; | 1804 | return result; |
1806 | 1805 | ||
1807 | tmp &= 0x00FFFFFF; | 1806 | tmp &= 0x00FFFFFF; |
1808 | tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; | 1807 | tmp |= ((uint32_t)MC_CG_ARB_FREQ_F1) << 24; |
1809 | 1808 | ||
1810 | return tonga_write_smc_sram_dword(smumgr, | 1809 | return smu7_write_smc_sram_dword(smumgr, |
1811 | smu_data->arb_table_start, tmp, SMC_RAM_END); | 1810 | smu_data->smu7_data.arb_table_start, tmp, SMC_RAM_END); |
1812 | } | 1811 | } |
1813 | 1812 | ||
1814 | 1813 | ||
@@ -1903,7 +1902,7 @@ static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset | |||
1903 | struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; | 1902 | struct tonga_pt_defaults *defaults = smu_data->power_tune_defaults; |
1904 | uint32_t temp; | 1903 | uint32_t temp; |
1905 | 1904 | ||
1906 | if (tonga_read_smc_sram_dword(hwmgr->smumgr, | 1905 | if (smu7_read_smc_sram_dword(hwmgr->smumgr, |
1907 | fuse_table_offset + | 1906 | fuse_table_offset + |
1908 | offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), | 1907 | offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), |
1909 | (uint32_t *)&temp, SMC_RAM_END)) | 1908 | (uint32_t *)&temp, SMC_RAM_END)) |
@@ -1994,7 +1993,7 @@ static int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) | |||
1994 | 1993 | ||
1995 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 1994 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
1996 | PHM_PlatformCaps_PowerContainment)) { | 1995 | PHM_PlatformCaps_PowerContainment)) { |
1997 | if (tonga_read_smc_sram_dword(hwmgr->smumgr, | 1996 | if (smu7_read_smc_sram_dword(hwmgr->smumgr, |
1998 | SMU72_FIRMWARE_HEADER_LOCATION + | 1997 | SMU72_FIRMWARE_HEADER_LOCATION + |
1999 | offsetof(SMU72_Firmware_Header, PmFuseTable), | 1998 | offsetof(SMU72_Firmware_Header, PmFuseTable), |
2000 | &pm_fuse_table_offset, SMC_RAM_END)) | 1999 | &pm_fuse_table_offset, SMC_RAM_END)) |
@@ -2052,7 +2051,7 @@ static int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) | |||
2052 | "Hi and Lo Sidd Failed !", | 2051 | "Hi and Lo Sidd Failed !", |
2053 | return -EINVAL); | 2052 | return -EINVAL); |
2054 | 2053 | ||
2055 | if (tonga_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, | 2054 | if (smu7_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, |
2056 | (uint8_t *)&smu_data->power_tune_table, | 2055 | (uint8_t *)&smu_data->power_tune_table, |
2057 | sizeof(struct SMU72_Discrete_PmFuses), SMC_RAM_END)) | 2056 | sizeof(struct SMU72_Discrete_PmFuses), SMC_RAM_END)) |
2058 | PP_ASSERT_WITH_CODE(false, | 2057 | PP_ASSERT_WITH_CODE(false, |
@@ -2173,10 +2172,10 @@ static int tonga_update_and_upload_mc_reg_table(struct pp_hwmgr *hwmgr) | |||
2173 | return result; | 2172 | return result; |
2174 | 2173 | ||
2175 | 2174 | ||
2176 | address = smu_data->mc_reg_table_start + | 2175 | address = smu_data->smu7_data.mc_reg_table_start + |
2177 | (uint32_t)offsetof(SMU72_Discrete_MCRegisters, data[0]); | 2176 | (uint32_t)offsetof(SMU72_Discrete_MCRegisters, data[0]); |
2178 | 2177 | ||
2179 | return tonga_copy_bytes_to_smc( | 2178 | return smu7_copy_bytes_to_smc( |
2180 | hwmgr->smumgr, address, | 2179 | hwmgr->smumgr, address, |
2181 | (uint8_t *)&smu_data->mc_regs.data[0], | 2180 | (uint8_t *)&smu_data->mc_regs.data[0], |
2182 | sizeof(SMU72_Discrete_MCRegisterSet) * | 2181 | sizeof(SMU72_Discrete_MCRegisterSet) * |
@@ -2192,16 +2191,16 @@ static int tonga_populate_initial_mc_reg_table(struct pp_hwmgr *hwmgr) | |||
2192 | 2191 | ||
2193 | memset(&smu_data->mc_regs, 0x00, sizeof(SMU72_Discrete_MCRegisters)); | 2192 | memset(&smu_data->mc_regs, 0x00, sizeof(SMU72_Discrete_MCRegisters)); |
2194 | result = tonga_populate_mc_reg_address(smumgr, &(smu_data->mc_regs)); | 2193 | result = tonga_populate_mc_reg_address(smumgr, &(smu_data->mc_regs)); |
2195 | PP_ASSERT_WITH_CODE(0 == result, | 2194 | PP_ASSERT_WITH_CODE(!result, |
2196 | "Failed to initialize MCRegTable for the MC register addresses !", | 2195 | "Failed to initialize MCRegTable for the MC register addresses !", |
2197 | return result;); | 2196 | return result;); |
2198 | 2197 | ||
2199 | result = tonga_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); | 2198 | result = tonga_convert_mc_reg_table_to_smc(hwmgr, &smu_data->mc_regs); |
2200 | PP_ASSERT_WITH_CODE(0 == result, | 2199 | PP_ASSERT_WITH_CODE(!result, |
2201 | "Failed to initialize MCRegTable for driver state !", | 2200 | "Failed to initialize MCRegTable for driver state !", |
2202 | return result;); | 2201 | return result;); |
2203 | 2202 | ||
2204 | return tonga_copy_bytes_to_smc(smumgr, smu_data->mc_reg_table_start, | 2203 | return smu7_copy_bytes_to_smc(smumgr, smu_data->smu7_data.mc_reg_table_start, |
2205 | (uint8_t *)&smu_data->mc_regs, sizeof(SMU72_Discrete_MCRegisters), SMC_RAM_END); | 2204 | (uint8_t *)&smu_data->mc_regs, sizeof(SMU72_Discrete_MCRegisters), SMC_RAM_END); |
2206 | } | 2205 | } |
2207 | 2206 | ||
@@ -2268,7 +2267,7 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2268 | 2267 | ||
2269 | if (data->ulv_supported && table_info->us_ulv_voltage_offset) { | 2268 | if (data->ulv_supported && table_info->us_ulv_voltage_offset) { |
2270 | result = tonga_populate_ulv_state(hwmgr, table); | 2269 | result = tonga_populate_ulv_state(hwmgr, table); |
2271 | PP_ASSERT_WITH_CODE(0 == result, | 2270 | PP_ASSERT_WITH_CODE(!result, |
2272 | "Failed to initialize ULV state !", | 2271 | "Failed to initialize ULV state !", |
2273 | return result;); | 2272 | return result;); |
2274 | 2273 | ||
@@ -2277,31 +2276,31 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2277 | } | 2276 | } |
2278 | 2277 | ||
2279 | result = tonga_populate_smc_link_level(hwmgr, table); | 2278 | result = tonga_populate_smc_link_level(hwmgr, table); |
2280 | PP_ASSERT_WITH_CODE(0 == result, | 2279 | PP_ASSERT_WITH_CODE(!result, |
2281 | "Failed to initialize Link Level !", return result); | 2280 | "Failed to initialize Link Level !", return result); |
2282 | 2281 | ||
2283 | result = tonga_populate_all_graphic_levels(hwmgr); | 2282 | result = tonga_populate_all_graphic_levels(hwmgr); |
2284 | PP_ASSERT_WITH_CODE(0 == result, | 2283 | PP_ASSERT_WITH_CODE(!result, |
2285 | "Failed to initialize Graphics Level !", return result); | 2284 | "Failed to initialize Graphics Level !", return result); |
2286 | 2285 | ||
2287 | result = tonga_populate_all_memory_levels(hwmgr); | 2286 | result = tonga_populate_all_memory_levels(hwmgr); |
2288 | PP_ASSERT_WITH_CODE(0 == result, | 2287 | PP_ASSERT_WITH_CODE(!result, |
2289 | "Failed to initialize Memory Level !", return result); | 2288 | "Failed to initialize Memory Level !", return result); |
2290 | 2289 | ||
2291 | result = tonga_populate_smc_acpi_level(hwmgr, table); | 2290 | result = tonga_populate_smc_acpi_level(hwmgr, table); |
2292 | PP_ASSERT_WITH_CODE(0 == result, | 2291 | PP_ASSERT_WITH_CODE(!result, |
2293 | "Failed to initialize ACPI Level !", return result); | 2292 | "Failed to initialize ACPI Level !", return result); |
2294 | 2293 | ||
2295 | result = tonga_populate_smc_vce_level(hwmgr, table); | 2294 | result = tonga_populate_smc_vce_level(hwmgr, table); |
2296 | PP_ASSERT_WITH_CODE(0 == result, | 2295 | PP_ASSERT_WITH_CODE(!result, |
2297 | "Failed to initialize VCE Level !", return result); | 2296 | "Failed to initialize VCE Level !", return result); |
2298 | 2297 | ||
2299 | result = tonga_populate_smc_acp_level(hwmgr, table); | 2298 | result = tonga_populate_smc_acp_level(hwmgr, table); |
2300 | PP_ASSERT_WITH_CODE(0 == result, | 2299 | PP_ASSERT_WITH_CODE(!result, |
2301 | "Failed to initialize ACP Level !", return result); | 2300 | "Failed to initialize ACP Level !", return result); |
2302 | 2301 | ||
2303 | result = tonga_populate_smc_samu_level(hwmgr, table); | 2302 | result = tonga_populate_smc_samu_level(hwmgr, table); |
2304 | PP_ASSERT_WITH_CODE(0 == result, | 2303 | PP_ASSERT_WITH_CODE(!result, |
2305 | "Failed to initialize SAMU Level !", return result); | 2304 | "Failed to initialize SAMU Level !", return result); |
2306 | 2305 | ||
2307 | /* Since only the initial state is completely set up at this | 2306 | /* Since only the initial state is completely set up at this |
@@ -2309,26 +2308,26 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2309 | * need to populate the ARB settings for the initial state. | 2308 | * need to populate the ARB settings for the initial state. |
2310 | */ | 2309 | */ |
2311 | result = tonga_program_memory_timing_parameters(hwmgr); | 2310 | result = tonga_program_memory_timing_parameters(hwmgr); |
2312 | PP_ASSERT_WITH_CODE(0 == result, | 2311 | PP_ASSERT_WITH_CODE(!result, |
2313 | "Failed to Write ARB settings for the initial state.", | 2312 | "Failed to Write ARB settings for the initial state.", |
2314 | return result;); | 2313 | return result;); |
2315 | 2314 | ||
2316 | result = tonga_populate_smc_uvd_level(hwmgr, table); | 2315 | result = tonga_populate_smc_uvd_level(hwmgr, table); |
2317 | PP_ASSERT_WITH_CODE(0 == result, | 2316 | PP_ASSERT_WITH_CODE(!result, |
2318 | "Failed to initialize UVD Level !", return result); | 2317 | "Failed to initialize UVD Level !", return result); |
2319 | 2318 | ||
2320 | result = tonga_populate_smc_boot_level(hwmgr, table); | 2319 | result = tonga_populate_smc_boot_level(hwmgr, table); |
2321 | PP_ASSERT_WITH_CODE(0 == result, | 2320 | PP_ASSERT_WITH_CODE(!result, |
2322 | "Failed to initialize Boot Level !", return result); | 2321 | "Failed to initialize Boot Level !", return result); |
2323 | 2322 | ||
2324 | tonga_populate_bapm_parameters_in_dpm_table(hwmgr); | 2323 | tonga_populate_bapm_parameters_in_dpm_table(hwmgr); |
2325 | PP_ASSERT_WITH_CODE(0 == result, | 2324 | PP_ASSERT_WITH_CODE(!result, |
2326 | "Failed to populate BAPM Parameters !", return result); | 2325 | "Failed to populate BAPM Parameters !", return result); |
2327 | 2326 | ||
2328 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 2327 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
2329 | PHM_PlatformCaps_ClockStretcher)) { | 2328 | PHM_PlatformCaps_ClockStretcher)) { |
2330 | result = tonga_populate_clock_stretcher_data_table(hwmgr); | 2329 | result = tonga_populate_clock_stretcher_data_table(hwmgr); |
2331 | PP_ASSERT_WITH_CODE(0 == result, | 2330 | PP_ASSERT_WITH_CODE(!result, |
2332 | "Failed to populate Clock Stretcher Data Table !", | 2331 | "Failed to populate Clock Stretcher Data Table !", |
2333 | return result;); | 2332 | return result;); |
2334 | } | 2333 | } |
@@ -2367,7 +2366,7 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2367 | table->PCIeGenInterval = 1; | 2366 | table->PCIeGenInterval = 1; |
2368 | 2367 | ||
2369 | result = tonga_populate_vr_config(hwmgr, table); | 2368 | result = tonga_populate_vr_config(hwmgr, table); |
2370 | PP_ASSERT_WITH_CODE(0 == result, | 2369 | PP_ASSERT_WITH_CODE(!result, |
2371 | "Failed to populate VRConfig setting !", return result); | 2370 | "Failed to populate VRConfig setting !", return result); |
2372 | 2371 | ||
2373 | table->ThermGpio = 17; | 2372 | table->ThermGpio = 17; |
@@ -2448,26 +2447,26 @@ int tonga_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2448 | CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); | 2447 | CONVERT_FROM_HOST_TO_SMC_US(table->PhaseResponseTime); |
2449 | 2448 | ||
2450 | /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ | 2449 | /* Upload all dpm data to SMC memory.(dpm level, dpm level count etc) */ |
2451 | result = tonga_copy_bytes_to_smc( | 2450 | result = smu7_copy_bytes_to_smc( |
2452 | hwmgr->smumgr, | 2451 | hwmgr->smumgr, |
2453 | smu_data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, SystemFlags), | 2452 | smu_data->smu7_data.dpm_table_start + offsetof(SMU72_Discrete_DpmTable, SystemFlags), |
2454 | (uint8_t *)&(table->SystemFlags), | 2453 | (uint8_t *)&(table->SystemFlags), |
2455 | sizeof(SMU72_Discrete_DpmTable) - 3 * sizeof(SMU72_PIDController), | 2454 | sizeof(SMU72_Discrete_DpmTable) - 3 * sizeof(SMU72_PIDController), |
2456 | SMC_RAM_END); | 2455 | SMC_RAM_END); |
2457 | 2456 | ||
2458 | PP_ASSERT_WITH_CODE(0 == result, | 2457 | PP_ASSERT_WITH_CODE(!result, |
2459 | "Failed to upload dpm data to SMC memory !", return result;); | 2458 | "Failed to upload dpm data to SMC memory !", return result;); |
2460 | 2459 | ||
2461 | result = tonga_init_arb_table_index(hwmgr->smumgr); | 2460 | result = tonga_init_arb_table_index(hwmgr->smumgr); |
2462 | PP_ASSERT_WITH_CODE(0 == result, | 2461 | PP_ASSERT_WITH_CODE(!result, |
2463 | "Failed to upload arb data to SMC memory !", return result); | 2462 | "Failed to upload arb data to SMC memory !", return result); |
2464 | 2463 | ||
2465 | tonga_populate_pm_fuses(hwmgr); | 2464 | tonga_populate_pm_fuses(hwmgr); |
2466 | PP_ASSERT_WITH_CODE((0 == result), | 2465 | PP_ASSERT_WITH_CODE((!result), |
2467 | "Failed to populate initialize pm fuses !", return result); | 2466 | "Failed to populate initialize pm fuses !", return result); |
2468 | 2467 | ||
2469 | result = tonga_populate_initial_mc_reg_table(hwmgr); | 2468 | result = tonga_populate_initial_mc_reg_table(hwmgr); |
2470 | PP_ASSERT_WITH_CODE((0 == result), | 2469 | PP_ASSERT_WITH_CODE((!result), |
2471 | "Failed to populate initialize MC Reg table !", return result); | 2470 | "Failed to populate initialize MC Reg table !", return result); |
2472 | 2471 | ||
2473 | return 0; | 2472 | return 0; |
@@ -2498,7 +2497,7 @@ int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) | |||
2498 | PHM_PlatformCaps_MicrocodeFanControl)) | 2497 | PHM_PlatformCaps_MicrocodeFanControl)) |
2499 | return 0; | 2498 | return 0; |
2500 | 2499 | ||
2501 | if (0 == smu_data->fan_table_start) { | 2500 | if (0 == smu_data->smu7_data.fan_table_start) { |
2502 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | 2501 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, |
2503 | PHM_PlatformCaps_MicrocodeFanControl); | 2502 | PHM_PlatformCaps_MicrocodeFanControl); |
2504 | return 0; | 2503 | return 0; |
@@ -2558,19 +2557,12 @@ int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr) | |||
2558 | 2557 | ||
2559 | fan_table.FanControl_GL_Flag = 1; | 2558 | fan_table.FanControl_GL_Flag = 1; |
2560 | 2559 | ||
2561 | res = tonga_copy_bytes_to_smc(hwmgr->smumgr, smu_data->fan_table_start, (uint8_t *)&fan_table, (uint32_t)sizeof(fan_table), SMC_RAM_END); | 2560 | res = smu7_copy_bytes_to_smc(hwmgr->smumgr, |
2562 | /* TO DO FOR SOME DEVICE ID 0X692b, send this msg return invalid command. | 2561 | smu_data->smu7_data.fan_table_start, |
2563 | if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit != 0) | 2562 | (uint8_t *)&fan_table, |
2564 | res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanMinPwm, \ | 2563 | (uint32_t)sizeof(fan_table), |
2565 | hwmgr->thermal_controller.advanceFanControlParameters.ucMinimumPWMLimit) ? 0 : -1); | 2564 | SMC_RAM_END); |
2566 | 2565 | ||
2567 | if (res == 0 && hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit != 0) | ||
2568 | res = (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanSclkTarget, \ | ||
2569 | hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit) ? 0 : -1); | ||
2570 | |||
2571 | if (0 != res) | ||
2572 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); | ||
2573 | */ | ||
2574 | return 0; | 2566 | return 0; |
2575 | } | 2567 | } |
2576 | 2568 | ||
@@ -2606,9 +2598,9 @@ int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) | |||
2606 | 2598 | ||
2607 | CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); | 2599 | CONVERT_FROM_HOST_TO_SMC_UL(low_sclk_interrupt_threshold); |
2608 | 2600 | ||
2609 | result = tonga_copy_bytes_to_smc( | 2601 | result = smu7_copy_bytes_to_smc( |
2610 | hwmgr->smumgr, | 2602 | hwmgr->smumgr, |
2611 | smu_data->dpm_table_start + | 2603 | smu_data->smu7_data.dpm_table_start + |
2612 | offsetof(SMU72_Discrete_DpmTable, | 2604 | offsetof(SMU72_Discrete_DpmTable, |
2613 | LowSclkInterruptThreshold), | 2605 | LowSclkInterruptThreshold), |
2614 | (uint8_t *)&low_sclk_interrupt_threshold, | 2606 | (uint8_t *)&low_sclk_interrupt_threshold, |
@@ -2618,7 +2610,7 @@ int tonga_update_sclk_threshold(struct pp_hwmgr *hwmgr) | |||
2618 | 2610 | ||
2619 | result = tonga_update_and_upload_mc_reg_table(hwmgr); | 2611 | result = tonga_update_and_upload_mc_reg_table(hwmgr); |
2620 | 2612 | ||
2621 | PP_ASSERT_WITH_CODE((0 == result), | 2613 | PP_ASSERT_WITH_CODE((!result), |
2622 | "Failed to upload MC reg table !", | 2614 | "Failed to upload MC reg table !", |
2623 | return result); | 2615 | return result); |
2624 | 2616 | ||
@@ -2645,6 +2637,8 @@ uint32_t tonga_get_offsetof(uint32_t type, uint32_t member) | |||
2645 | return offsetof(SMU72_SoftRegisters, PreVBlankGap); | 2637 | return offsetof(SMU72_SoftRegisters, PreVBlankGap); |
2646 | case VBlankTimeout: | 2638 | case VBlankTimeout: |
2647 | return offsetof(SMU72_SoftRegisters, VBlankTimeout); | 2639 | return offsetof(SMU72_SoftRegisters, VBlankTimeout); |
2640 | case UcodeLoadStatus: | ||
2641 | return offsetof(SMU72_SoftRegisters, UcodeLoadStatus); | ||
2648 | } | 2642 | } |
2649 | case SMU_Discrete_DpmTable: | 2643 | case SMU_Discrete_DpmTable: |
2650 | switch (member) { | 2644 | switch (member) { |
@@ -2700,7 +2694,7 @@ static int tonga_update_uvd_smc_table(struct pp_hwmgr *hwmgr) | |||
2700 | if (table_info->mm_dep_table->count > 0) | 2694 | if (table_info->mm_dep_table->count > 0) |
2701 | smu_data->smc_state_table.UvdBootLevel = | 2695 | smu_data->smc_state_table.UvdBootLevel = |
2702 | (uint8_t) (table_info->mm_dep_table->count - 1); | 2696 | (uint8_t) (table_info->mm_dep_table->count - 1); |
2703 | mm_boot_level_offset = smu_data->dpm_table_start + | 2697 | mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + |
2704 | offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); | 2698 | offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); |
2705 | mm_boot_level_offset /= 4; | 2699 | mm_boot_level_offset /= 4; |
2706 | mm_boot_level_offset *= 4; | 2700 | mm_boot_level_offset *= 4; |
@@ -2734,7 +2728,7 @@ static int tonga_update_vce_smc_table(struct pp_hwmgr *hwmgr) | |||
2734 | smu_data->smc_state_table.VceBootLevel = | 2728 | smu_data->smc_state_table.VceBootLevel = |
2735 | (uint8_t) (table_info->mm_dep_table->count - 1); | 2729 | (uint8_t) (table_info->mm_dep_table->count - 1); |
2736 | 2730 | ||
2737 | mm_boot_level_offset = smu_data->dpm_table_start + | 2731 | mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + |
2738 | offsetof(SMU72_Discrete_DpmTable, VceBootLevel); | 2732 | offsetof(SMU72_Discrete_DpmTable, VceBootLevel); |
2739 | mm_boot_level_offset /= 4; | 2733 | mm_boot_level_offset /= 4; |
2740 | mm_boot_level_offset *= 4; | 2734 | mm_boot_level_offset *= 4; |
@@ -2759,7 +2753,7 @@ static int tonga_update_samu_smc_table(struct pp_hwmgr *hwmgr) | |||
2759 | uint32_t mm_boot_level_offset, mm_boot_level_value; | 2753 | uint32_t mm_boot_level_offset, mm_boot_level_value; |
2760 | 2754 | ||
2761 | smu_data->smc_state_table.SamuBootLevel = 0; | 2755 | smu_data->smc_state_table.SamuBootLevel = 0; |
2762 | mm_boot_level_offset = smu_data->dpm_table_start + | 2756 | mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + |
2763 | offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); | 2757 | offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); |
2764 | 2758 | ||
2765 | mm_boot_level_offset /= 4; | 2759 | mm_boot_level_offset /= 4; |
@@ -2813,67 +2807,66 @@ int tonga_process_firmware_header(struct pp_hwmgr *hwmgr) | |||
2813 | int result; | 2807 | int result; |
2814 | bool error = false; | 2808 | bool error = false; |
2815 | 2809 | ||
2816 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | 2810 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, |
2817 | SMU72_FIRMWARE_HEADER_LOCATION + | 2811 | SMU72_FIRMWARE_HEADER_LOCATION + |
2818 | offsetof(SMU72_Firmware_Header, DpmTable), | 2812 | offsetof(SMU72_Firmware_Header, DpmTable), |
2819 | &tmp, SMC_RAM_END); | 2813 | &tmp, SMC_RAM_END); |
2820 | 2814 | ||
2821 | if (0 == result) | 2815 | if (!result) |
2822 | smu_data->dpm_table_start = tmp; | 2816 | smu_data->smu7_data.dpm_table_start = tmp; |
2823 | 2817 | ||
2824 | error |= (0 != result); | 2818 | error |= (result != 0); |
2825 | 2819 | ||
2826 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | 2820 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, |
2827 | SMU72_FIRMWARE_HEADER_LOCATION + | 2821 | SMU72_FIRMWARE_HEADER_LOCATION + |
2828 | offsetof(SMU72_Firmware_Header, SoftRegisters), | 2822 | offsetof(SMU72_Firmware_Header, SoftRegisters), |
2829 | &tmp, SMC_RAM_END); | 2823 | &tmp, SMC_RAM_END); |
2830 | 2824 | ||
2831 | if (0 == result) { | 2825 | if (!result) { |
2832 | data->soft_regs_start = tmp; | 2826 | data->soft_regs_start = tmp; |
2833 | smu_data->soft_regs_start = tmp; | 2827 | smu_data->smu7_data.soft_regs_start = tmp; |
2834 | } | 2828 | } |
2835 | 2829 | ||
2836 | error |= (0 != result); | 2830 | error |= (result != 0); |
2837 | 2831 | ||
2838 | 2832 | ||
2839 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | 2833 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, |
2840 | SMU72_FIRMWARE_HEADER_LOCATION + | 2834 | SMU72_FIRMWARE_HEADER_LOCATION + |
2841 | offsetof(SMU72_Firmware_Header, mcRegisterTable), | 2835 | offsetof(SMU72_Firmware_Header, mcRegisterTable), |
2842 | &tmp, SMC_RAM_END); | 2836 | &tmp, SMC_RAM_END); |
2843 | 2837 | ||
2844 | if (0 == result) | 2838 | if (!result) |
2845 | smu_data->mc_reg_table_start = tmp; | 2839 | smu_data->smu7_data.mc_reg_table_start = tmp; |
2846 | 2840 | ||
2847 | 2841 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, | |
2848 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | ||
2849 | SMU72_FIRMWARE_HEADER_LOCATION + | 2842 | SMU72_FIRMWARE_HEADER_LOCATION + |
2850 | offsetof(SMU72_Firmware_Header, FanTable), | 2843 | offsetof(SMU72_Firmware_Header, FanTable), |
2851 | &tmp, SMC_RAM_END); | 2844 | &tmp, SMC_RAM_END); |
2852 | 2845 | ||
2853 | if (0 == result) | 2846 | if (!result) |
2854 | smu_data->fan_table_start = tmp; | 2847 | smu_data->smu7_data.fan_table_start = tmp; |
2855 | 2848 | ||
2856 | error |= (0 != result); | 2849 | error |= (result != 0); |
2857 | 2850 | ||
2858 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | 2851 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, |
2859 | SMU72_FIRMWARE_HEADER_LOCATION + | 2852 | SMU72_FIRMWARE_HEADER_LOCATION + |
2860 | offsetof(SMU72_Firmware_Header, mcArbDramTimingTable), | 2853 | offsetof(SMU72_Firmware_Header, mcArbDramTimingTable), |
2861 | &tmp, SMC_RAM_END); | 2854 | &tmp, SMC_RAM_END); |
2862 | 2855 | ||
2863 | if (0 == result) | 2856 | if (!result) |
2864 | smu_data->arb_table_start = tmp; | 2857 | smu_data->smu7_data.arb_table_start = tmp; |
2865 | 2858 | ||
2866 | error |= (0 != result); | 2859 | error |= (result != 0); |
2867 | 2860 | ||
2868 | result = tonga_read_smc_sram_dword(hwmgr->smumgr, | 2861 | result = smu7_read_smc_sram_dword(hwmgr->smumgr, |
2869 | SMU72_FIRMWARE_HEADER_LOCATION + | 2862 | SMU72_FIRMWARE_HEADER_LOCATION + |
2870 | offsetof(SMU72_Firmware_Header, Version), | 2863 | offsetof(SMU72_Firmware_Header, Version), |
2871 | &tmp, SMC_RAM_END); | 2864 | &tmp, SMC_RAM_END); |
2872 | 2865 | ||
2873 | if (0 == result) | 2866 | if (!result) |
2874 | hwmgr->microcode_version_info.SMC = tmp; | 2867 | hwmgr->microcode_version_info.SMC = tmp; |
2875 | 2868 | ||
2876 | error |= (0 != result); | 2869 | error |= (result != 0); |
2877 | 2870 | ||
2878 | return error ? 1 : 0; | 2871 | return error ? 1 : 0; |
2879 | } | 2872 | } |
@@ -3141,7 +3134,7 @@ int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) | |||
3141 | 3134 | ||
3142 | table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); | 3135 | table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); |
3143 | 3136 | ||
3144 | if (NULL == table) | 3137 | if (table == NULL) |
3145 | return -ENOMEM; | 3138 | return -ENOMEM; |
3146 | 3139 | ||
3147 | /* Program additional LP registers that are no longer programmed by VBIOS */ | 3140 | /* Program additional LP registers that are no longer programmed by VBIOS */ |
@@ -3190,15 +3183,15 @@ int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) | |||
3190 | 3183 | ||
3191 | result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); | 3184 | result = atomctrl_initialize_mc_reg_table(hwmgr, module_index, table); |
3192 | 3185 | ||
3193 | if (0 == result) | 3186 | if (!result) |
3194 | result = tonga_copy_vbios_smc_reg_table(table, ni_table); | 3187 | result = tonga_copy_vbios_smc_reg_table(table, ni_table); |
3195 | 3188 | ||
3196 | if (0 == result) { | 3189 | if (!result) { |
3197 | tonga_set_s0_mc_reg_index(ni_table); | 3190 | tonga_set_s0_mc_reg_index(ni_table); |
3198 | result = tonga_set_mc_special_registers(hwmgr, ni_table); | 3191 | result = tonga_set_mc_special_registers(hwmgr, ni_table); |
3199 | } | 3192 | } |
3200 | 3193 | ||
3201 | if (0 == result) | 3194 | if (!result) |
3202 | tonga_set_valid_flag(ni_table); | 3195 | tonga_set_valid_flag(ni_table); |
3203 | 3196 | ||
3204 | kfree(table); | 3197 | kfree(table); |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index b543d6c0f96a..5f9124046b9b 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | |||
@@ -34,587 +34,8 @@ | |||
34 | #include "smu/smu_7_1_2_sh_mask.h" | 34 | #include "smu/smu_7_1_2_sh_mask.h" |
35 | #include "cgs_common.h" | 35 | #include "cgs_common.h" |
36 | #include "tonga_smc.h" | 36 | #include "tonga_smc.h" |
37 | #include "smu7_smumgr.h" | ||
37 | 38 | ||
38 | #define TONGA_SMC_SIZE 0x20000 | ||
39 | #define BUFFER_SIZE 80000 | ||
40 | #define MAX_STRING_SIZE 15 | ||
41 | #define BUFFER_SIZETWO 131072 /*128 *1024*/ | ||
42 | |||
43 | /** | ||
44 | * Set the address for reading/writing the SMC SRAM space. | ||
45 | * @param smumgr the address of the powerplay hardware manager. | ||
46 | * @param smcAddress the address in the SMC RAM to access. | ||
47 | */ | ||
48 | static int tonga_set_smc_sram_address(struct pp_smumgr *smumgr, | ||
49 | uint32_t smcAddress, uint32_t limit) | ||
50 | { | ||
51 | if (smumgr == NULL || smumgr->device == NULL) | ||
52 | return -EINVAL; | ||
53 | PP_ASSERT_WITH_CODE((0 == (3 & smcAddress)), | ||
54 | "SMC address must be 4 byte aligned.", | ||
55 | return -1;); | ||
56 | |||
57 | PP_ASSERT_WITH_CODE((limit > (smcAddress + 3)), | ||
58 | "SMC address is beyond the SMC RAM area.", | ||
59 | return -1;); | ||
60 | |||
61 | cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smcAddress); | ||
62 | SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_11, 0); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * Copy bytes from an array into the SMC RAM space. | ||
69 | * | ||
70 | * @param smumgr the address of the powerplay SMU manager. | ||
71 | * @param smcStartAddress the start address in the SMC RAM to copy bytes to. | ||
72 | * @param src the byte array to copy the bytes from. | ||
73 | * @param byteCount the number of bytes to copy. | ||
74 | */ | ||
75 | int tonga_copy_bytes_to_smc(struct pp_smumgr *smumgr, | ||
76 | uint32_t smcStartAddress, const uint8_t *src, | ||
77 | uint32_t byteCount, uint32_t limit) | ||
78 | { | ||
79 | uint32_t addr; | ||
80 | uint32_t data, orig_data; | ||
81 | int result = 0; | ||
82 | uint32_t extra_shift; | ||
83 | |||
84 | if (smumgr == NULL || smumgr->device == NULL) | ||
85 | return -EINVAL; | ||
86 | PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)), | ||
87 | "SMC address must be 4 byte aligned.", | ||
88 | return 0;); | ||
89 | |||
90 | PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)), | ||
91 | "SMC address is beyond the SMC RAM area.", | ||
92 | return 0;); | ||
93 | |||
94 | addr = smcStartAddress; | ||
95 | |||
96 | while (byteCount >= 4) { | ||
97 | /* | ||
98 | * Bytes are written into the | ||
99 | * SMC address space with the MSB first | ||
100 | */ | ||
101 | data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3]; | ||
102 | |||
103 | result = tonga_set_smc_sram_address(smumgr, addr, limit); | ||
104 | |||
105 | if (result) | ||
106 | goto out; | ||
107 | |||
108 | cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); | ||
109 | |||
110 | src += 4; | ||
111 | byteCount -= 4; | ||
112 | addr += 4; | ||
113 | } | ||
114 | |||
115 | if (0 != byteCount) { | ||
116 | /* Now write odd bytes left, do a read modify write cycle */ | ||
117 | data = 0; | ||
118 | |||
119 | result = tonga_set_smc_sram_address(smumgr, addr, limit); | ||
120 | if (result) | ||
121 | goto out; | ||
122 | |||
123 | orig_data = cgs_read_register(smumgr->device, | ||
124 | mmSMC_IND_DATA_0); | ||
125 | extra_shift = 8 * (4 - byteCount); | ||
126 | |||
127 | while (byteCount > 0) { | ||
128 | data = (data << 8) + *src++; | ||
129 | byteCount--; | ||
130 | } | ||
131 | |||
132 | data <<= extra_shift; | ||
133 | data |= (orig_data & ~((~0UL) << extra_shift)); | ||
134 | |||
135 | result = tonga_set_smc_sram_address(smumgr, addr, limit); | ||
136 | if (result) | ||
137 | goto out; | ||
138 | |||
139 | cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data); | ||
140 | } | ||
141 | |||
142 | out: | ||
143 | return result; | ||
144 | } | ||
145 | |||
146 | |||
147 | int tonga_program_jump_on_start(struct pp_smumgr *smumgr) | ||
148 | { | ||
149 | static const unsigned char pData[] = { 0xE0, 0x00, 0x80, 0x40 }; | ||
150 | |||
151 | tonga_copy_bytes_to_smc(smumgr, 0x0, pData, 4, sizeof(pData)+1); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Return if the SMC is currently running. | ||
158 | * | ||
159 | * @param smumgr the address of the powerplay hardware manager. | ||
160 | */ | ||
161 | static int tonga_is_smc_ram_running(struct pp_smumgr *smumgr) | ||
162 | { | ||
163 | return ((0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, | ||
164 | SMC_SYSCON_CLOCK_CNTL_0, ck_disable)) | ||
165 | && (0x20100 <= cgs_read_ind_register(smumgr->device, | ||
166 | CGS_IND_REG__SMC, ixSMC_PC_C))); | ||
167 | } | ||
168 | |||
169 | static int tonga_send_msg_to_smc_offset(struct pp_smumgr *smumgr) | ||
170 | { | ||
171 | if (smumgr == NULL || smumgr->device == NULL) | ||
172 | return -EINVAL; | ||
173 | |||
174 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
175 | |||
176 | cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, 0x20000); | ||
177 | cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, PPSMC_MSG_Test); | ||
178 | |||
179 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Send a message to the SMC, and wait for its response. | ||
186 | * | ||
187 | * @param smumgr the address of the powerplay hardware manager. | ||
188 | * @param msg the message to send. | ||
189 | * @return The response that came from the SMC. | ||
190 | */ | ||
191 | static int tonga_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg) | ||
192 | { | ||
193 | if (smumgr == NULL || smumgr->device == NULL) | ||
194 | return -EINVAL; | ||
195 | |||
196 | if (!tonga_is_smc_ram_running(smumgr)) | ||
197 | return -1; | ||
198 | |||
199 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
200 | PP_ASSERT_WITH_CODE( | ||
201 | 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP), | ||
202 | "Failed to send Previous Message.", | ||
203 | ); | ||
204 | |||
205 | cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg); | ||
206 | |||
207 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
208 | PP_ASSERT_WITH_CODE( | ||
209 | 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP), | ||
210 | "Failed to send Message.", | ||
211 | ); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Send a message to the SMC, and do not wait for its response. | ||
218 | * | ||
219 | * @param smumgr the address of the powerplay hardware manager. | ||
220 | * @param msg the message to send. | ||
221 | * @return The response that came from the SMC. | ||
222 | */ | ||
223 | static int tonga_send_msg_to_smc_without_waiting | ||
224 | (struct pp_smumgr *smumgr, uint16_t msg) | ||
225 | { | ||
226 | if (smumgr == NULL || smumgr->device == NULL) | ||
227 | return -EINVAL; | ||
228 | |||
229 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
230 | PP_ASSERT_WITH_CODE( | ||
231 | 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP), | ||
232 | "Failed to send Previous Message.", | ||
233 | ); | ||
234 | cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * Send a message to the SMC with parameter | ||
241 | * | ||
242 | * @param smumgr: the address of the powerplay hardware manager. | ||
243 | * @param msg: the message to send. | ||
244 | * @param parameter: the parameter to send | ||
245 | * @return The response that came from the SMC. | ||
246 | */ | ||
247 | static int tonga_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr, | ||
248 | uint16_t msg, uint32_t parameter) | ||
249 | { | ||
250 | if (smumgr == NULL || smumgr->device == NULL) | ||
251 | return -EINVAL; | ||
252 | |||
253 | if (!tonga_is_smc_ram_running(smumgr)) | ||
254 | return PPSMC_Result_Failed; | ||
255 | |||
256 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
257 | cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter); | ||
258 | |||
259 | return tonga_send_msg_to_smc(smumgr, msg); | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * Send a message to the SMC with parameter, do not wait for response | ||
264 | * | ||
265 | * @param smumgr: the address of the powerplay hardware manager. | ||
266 | * @param msg: the message to send. | ||
267 | * @param parameter: the parameter to send | ||
268 | * @return The response that came from the SMC. | ||
269 | */ | ||
270 | static int tonga_send_msg_to_smc_with_parameter_without_waiting( | ||
271 | struct pp_smumgr *smumgr, | ||
272 | uint16_t msg, uint32_t parameter) | ||
273 | { | ||
274 | if (smumgr == NULL || smumgr->device == NULL) | ||
275 | return -EINVAL; | ||
276 | |||
277 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | ||
278 | |||
279 | cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter); | ||
280 | |||
281 | return tonga_send_msg_to_smc_without_waiting(smumgr, msg); | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Read a 32bit value from the SMC SRAM space. | ||
286 | * ALL PARAMETERS ARE IN HOST BYTE ORDER. | ||
287 | * @param smumgr the address of the powerplay hardware manager. | ||
288 | * @param smcAddress the address in the SMC RAM to access. | ||
289 | * @param value and output parameter for the data read from the SMC SRAM. | ||
290 | */ | ||
291 | int tonga_read_smc_sram_dword(struct pp_smumgr *smumgr, | ||
292 | uint32_t smcAddress, uint32_t *value, | ||
293 | uint32_t limit) | ||
294 | { | ||
295 | int result; | ||
296 | |||
297 | result = tonga_set_smc_sram_address(smumgr, smcAddress, limit); | ||
298 | |||
299 | if (0 != result) | ||
300 | return result; | ||
301 | |||
302 | *value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Write a 32bit value to the SMC SRAM space. | ||
309 | * ALL PARAMETERS ARE IN HOST BYTE ORDER. | ||
310 | * @param smumgr the address of the powerplay hardware manager. | ||
311 | * @param smcAddress the address in the SMC RAM to access. | ||
312 | * @param value to write to the SMC SRAM. | ||
313 | */ | ||
314 | int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, | ||
315 | uint32_t smcAddress, uint32_t value, | ||
316 | uint32_t limit) | ||
317 | { | ||
318 | int result; | ||
319 | |||
320 | result = tonga_set_smc_sram_address(smumgr, smcAddress, limit); | ||
321 | |||
322 | if (0 != result) | ||
323 | return result; | ||
324 | |||
325 | cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int tonga_smu_fini(struct pp_smumgr *smumgr) | ||
331 | { | ||
332 | struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend); | ||
333 | |||
334 | smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle); | ||
335 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
336 | |||
337 | if (smumgr->backend != NULL) { | ||
338 | kfree(smumgr->backend); | ||
339 | smumgr->backend = NULL; | ||
340 | } | ||
341 | |||
342 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static enum cgs_ucode_id tonga_convert_fw_type_to_cgs(uint32_t fw_type) | ||
347 | { | ||
348 | enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM; | ||
349 | |||
350 | switch (fw_type) { | ||
351 | case UCODE_ID_SMU: | ||
352 | result = CGS_UCODE_ID_SMU; | ||
353 | break; | ||
354 | case UCODE_ID_SDMA0: | ||
355 | result = CGS_UCODE_ID_SDMA0; | ||
356 | break; | ||
357 | case UCODE_ID_SDMA1: | ||
358 | result = CGS_UCODE_ID_SDMA1; | ||
359 | break; | ||
360 | case UCODE_ID_CP_CE: | ||
361 | result = CGS_UCODE_ID_CP_CE; | ||
362 | break; | ||
363 | case UCODE_ID_CP_PFP: | ||
364 | result = CGS_UCODE_ID_CP_PFP; | ||
365 | break; | ||
366 | case UCODE_ID_CP_ME: | ||
367 | result = CGS_UCODE_ID_CP_ME; | ||
368 | break; | ||
369 | case UCODE_ID_CP_MEC: | ||
370 | result = CGS_UCODE_ID_CP_MEC; | ||
371 | break; | ||
372 | case UCODE_ID_CP_MEC_JT1: | ||
373 | result = CGS_UCODE_ID_CP_MEC_JT1; | ||
374 | break; | ||
375 | case UCODE_ID_CP_MEC_JT2: | ||
376 | result = CGS_UCODE_ID_CP_MEC_JT2; | ||
377 | break; | ||
378 | case UCODE_ID_RLC_G: | ||
379 | result = CGS_UCODE_ID_RLC_G; | ||
380 | break; | ||
381 | default: | ||
382 | break; | ||
383 | } | ||
384 | |||
385 | return result; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * Convert the PPIRI firmware type to SMU type mask. | ||
390 | * For MEC, we need to check all MEC related type | ||
391 | */ | ||
392 | static uint16_t tonga_get_mask_for_firmware_type(uint16_t firmwareType) | ||
393 | { | ||
394 | uint16_t result = 0; | ||
395 | |||
396 | switch (firmwareType) { | ||
397 | case UCODE_ID_SDMA0: | ||
398 | result = UCODE_ID_SDMA0_MASK; | ||
399 | break; | ||
400 | case UCODE_ID_SDMA1: | ||
401 | result = UCODE_ID_SDMA1_MASK; | ||
402 | break; | ||
403 | case UCODE_ID_CP_CE: | ||
404 | result = UCODE_ID_CP_CE_MASK; | ||
405 | break; | ||
406 | case UCODE_ID_CP_PFP: | ||
407 | result = UCODE_ID_CP_PFP_MASK; | ||
408 | break; | ||
409 | case UCODE_ID_CP_ME: | ||
410 | result = UCODE_ID_CP_ME_MASK; | ||
411 | break; | ||
412 | case UCODE_ID_CP_MEC: | ||
413 | case UCODE_ID_CP_MEC_JT1: | ||
414 | case UCODE_ID_CP_MEC_JT2: | ||
415 | result = UCODE_ID_CP_MEC_MASK; | ||
416 | break; | ||
417 | case UCODE_ID_RLC_G: | ||
418 | result = UCODE_ID_RLC_G_MASK; | ||
419 | break; | ||
420 | default: | ||
421 | break; | ||
422 | } | ||
423 | |||
424 | return result; | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * Check if the FW has been loaded, | ||
429 | * SMU will not return if loading has not finished. | ||
430 | */ | ||
431 | static int tonga_check_fw_load_finish(struct pp_smumgr *smumgr, uint32_t fwType) | ||
432 | { | ||
433 | uint16_t fwMask = tonga_get_mask_for_firmware_type(fwType); | ||
434 | |||
435 | if (0 != SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND, | ||
436 | SOFT_REGISTERS_TABLE_28, fwMask, fwMask)) { | ||
437 | printk(KERN_ERR "[ powerplay ] check firmware loading failed\n"); | ||
438 | return -EINVAL; | ||
439 | } | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | /* Populate one firmware image to the data structure */ | ||
445 | static int tonga_populate_single_firmware_entry(struct pp_smumgr *smumgr, | ||
446 | uint16_t firmware_type, | ||
447 | struct SMU_Entry *pentry) | ||
448 | { | ||
449 | int result; | ||
450 | struct cgs_firmware_info info = {0}; | ||
451 | |||
452 | result = cgs_get_firmware_info( | ||
453 | smumgr->device, | ||
454 | tonga_convert_fw_type_to_cgs(firmware_type), | ||
455 | &info); | ||
456 | |||
457 | if (result == 0) { | ||
458 | pentry->version = 0; | ||
459 | pentry->id = (uint16_t)firmware_type; | ||
460 | pentry->image_addr_high = smu_upper_32_bits(info.mc_addr); | ||
461 | pentry->image_addr_low = smu_lower_32_bits(info.mc_addr); | ||
462 | pentry->meta_data_addr_high = 0; | ||
463 | pentry->meta_data_addr_low = 0; | ||
464 | pentry->data_size_byte = info.image_size; | ||
465 | pentry->num_register_entries = 0; | ||
466 | |||
467 | if (firmware_type == UCODE_ID_RLC_G) | ||
468 | pentry->flags = 1; | ||
469 | else | ||
470 | pentry->flags = 0; | ||
471 | } else { | ||
472 | return result; | ||
473 | } | ||
474 | |||
475 | return result; | ||
476 | } | ||
477 | |||
478 | static int tonga_request_smu_reload_fw(struct pp_smumgr *smumgr) | ||
479 | { | ||
480 | struct tonga_smumgr *tonga_smu = | ||
481 | (struct tonga_smumgr *)(smumgr->backend); | ||
482 | uint16_t fw_to_load; | ||
483 | struct SMU_DRAMData_TOC *toc; | ||
484 | /** | ||
485 | * First time this gets called during SmuMgr init, | ||
486 | * we haven't processed SMU header file yet, | ||
487 | * so Soft Register Start offset is unknown. | ||
488 | * However, for this case, UcodeLoadStatus is already 0, | ||
489 | * so we can skip this if the Soft Registers Start offset is 0. | ||
490 | */ | ||
491 | cgs_write_ind_register(smumgr->device, | ||
492 | CGS_IND_REG__SMC, ixSOFT_REGISTERS_TABLE_28, 0); | ||
493 | |||
494 | tonga_send_msg_to_smc_with_parameter(smumgr, | ||
495 | PPSMC_MSG_SMU_DRAM_ADDR_HI, | ||
496 | tonga_smu->smu_buffer.mc_addr_high); | ||
497 | tonga_send_msg_to_smc_with_parameter(smumgr, | ||
498 | PPSMC_MSG_SMU_DRAM_ADDR_LO, | ||
499 | tonga_smu->smu_buffer.mc_addr_low); | ||
500 | |||
501 | toc = (struct SMU_DRAMData_TOC *)tonga_smu->pHeader; | ||
502 | toc->num_entries = 0; | ||
503 | toc->structure_version = 1; | ||
504 | |||
505 | PP_ASSERT_WITH_CODE( | ||
506 | 0 == tonga_populate_single_firmware_entry(smumgr, | ||
507 | UCODE_ID_RLC_G, | ||
508 | &toc->entry[toc->num_entries++]), | ||
509 | "Failed to Get Firmware Entry.\n", | ||
510 | return -1); | ||
511 | PP_ASSERT_WITH_CODE( | ||
512 | 0 == tonga_populate_single_firmware_entry(smumgr, | ||
513 | UCODE_ID_CP_CE, | ||
514 | &toc->entry[toc->num_entries++]), | ||
515 | "Failed to Get Firmware Entry.\n", | ||
516 | return -1); | ||
517 | PP_ASSERT_WITH_CODE( | ||
518 | 0 == tonga_populate_single_firmware_entry | ||
519 | (smumgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), | ||
520 | "Failed to Get Firmware Entry.\n", return -1); | ||
521 | PP_ASSERT_WITH_CODE( | ||
522 | 0 == tonga_populate_single_firmware_entry | ||
523 | (smumgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), | ||
524 | "Failed to Get Firmware Entry.\n", return -1); | ||
525 | PP_ASSERT_WITH_CODE( | ||
526 | 0 == tonga_populate_single_firmware_entry | ||
527 | (smumgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), | ||
528 | "Failed to Get Firmware Entry.\n", return -1); | ||
529 | PP_ASSERT_WITH_CODE( | ||
530 | 0 == tonga_populate_single_firmware_entry | ||
531 | (smumgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), | ||
532 | "Failed to Get Firmware Entry.\n", return -1); | ||
533 | PP_ASSERT_WITH_CODE( | ||
534 | 0 == tonga_populate_single_firmware_entry | ||
535 | (smumgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), | ||
536 | "Failed to Get Firmware Entry.\n", return -1); | ||
537 | PP_ASSERT_WITH_CODE( | ||
538 | 0 == tonga_populate_single_firmware_entry | ||
539 | (smumgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), | ||
540 | "Failed to Get Firmware Entry.\n", return -1); | ||
541 | PP_ASSERT_WITH_CODE( | ||
542 | 0 == tonga_populate_single_firmware_entry | ||
543 | (smumgr, UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), | ||
544 | "Failed to Get Firmware Entry.\n", return -1); | ||
545 | |||
546 | tonga_send_msg_to_smc_with_parameter(smumgr, | ||
547 | PPSMC_MSG_DRV_DRAM_ADDR_HI, | ||
548 | tonga_smu->header_buffer.mc_addr_high); | ||
549 | tonga_send_msg_to_smc_with_parameter(smumgr, | ||
550 | PPSMC_MSG_DRV_DRAM_ADDR_LO, | ||
551 | tonga_smu->header_buffer.mc_addr_low); | ||
552 | |||
553 | fw_to_load = UCODE_ID_RLC_G_MASK | ||
554 | + UCODE_ID_SDMA0_MASK | ||
555 | + UCODE_ID_SDMA1_MASK | ||
556 | + UCODE_ID_CP_CE_MASK | ||
557 | + UCODE_ID_CP_ME_MASK | ||
558 | + UCODE_ID_CP_PFP_MASK | ||
559 | + UCODE_ID_CP_MEC_MASK; | ||
560 | |||
561 | PP_ASSERT_WITH_CODE( | ||
562 | 0 == tonga_send_msg_to_smc_with_parameter_without_waiting( | ||
563 | smumgr, PPSMC_MSG_LoadUcodes, fw_to_load), | ||
564 | "Fail to Request SMU Load uCode", return 0); | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static int tonga_request_smu_load_specific_fw(struct pp_smumgr *smumgr, | ||
570 | uint32_t firmwareType) | ||
571 | { | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | /** | ||
576 | * Upload the SMC firmware to the SMC microcontroller. | ||
577 | * | ||
578 | * @param smumgr the address of the powerplay hardware manager. | ||
579 | * @param pFirmware the data structure containing the various sections of the firmware. | ||
580 | */ | ||
581 | static int tonga_smu_upload_firmware_image(struct pp_smumgr *smumgr) | ||
582 | { | ||
583 | const uint8_t *src; | ||
584 | uint32_t byte_count; | ||
585 | uint32_t *data; | ||
586 | struct cgs_firmware_info info = {0}; | ||
587 | |||
588 | if (smumgr == NULL || smumgr->device == NULL) | ||
589 | return -EINVAL; | ||
590 | |||
591 | cgs_get_firmware_info(smumgr->device, | ||
592 | tonga_convert_fw_type_to_cgs(UCODE_ID_SMU), &info); | ||
593 | |||
594 | if (info.image_size & 3) { | ||
595 | printk(KERN_ERR "[ powerplay ] SMC ucode is not 4 bytes aligned\n"); | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | |||
599 | if (info.image_size > TONGA_SMC_SIZE) { | ||
600 | printk(KERN_ERR "[ powerplay ] SMC address is beyond the SMC RAM area\n"); | ||
601 | return -EINVAL; | ||
602 | } | ||
603 | |||
604 | cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, 0x20000); | ||
605 | SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1); | ||
606 | |||
607 | byte_count = info.image_size; | ||
608 | src = (const uint8_t *)info.kptr; | ||
609 | |||
610 | data = (uint32_t *)src; | ||
611 | for (; byte_count >= 4; data++, byte_count -= 4) | ||
612 | cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data[0]); | ||
613 | |||
614 | SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0); | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | 39 | ||
619 | static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr) | 40 | static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr) |
620 | { | 41 | { |
@@ -624,7 +45,7 @@ static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr) | |||
624 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, | 45 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, |
625 | SMC_SYSCON_RESET_CNTL, rst_reg, 1); | 46 | SMC_SYSCON_RESET_CNTL, rst_reg, 1); |
626 | 47 | ||
627 | result = tonga_smu_upload_firmware_image(smumgr); | 48 | result = smu7_upload_smu_firmware_image(smumgr); |
628 | if (result) | 49 | if (result) |
629 | return result; | 50 | return result; |
630 | 51 | ||
@@ -654,7 +75,7 @@ static int tonga_start_in_protection_mode(struct pp_smumgr *smumgr) | |||
654 | /** | 75 | /** |
655 | * Call Test SMU message with 0x20000 offset to trigger SMU start | 76 | * Call Test SMU message with 0x20000 offset to trigger SMU start |
656 | */ | 77 | */ |
657 | tonga_send_msg_to_smc_offset(smumgr); | 78 | smu7_send_msg_to_smc_offset(smumgr); |
658 | 79 | ||
659 | /* Wait for done bit to be set */ | 80 | /* Wait for done bit to be set */ |
660 | SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, | 81 | SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, |
@@ -691,13 +112,13 @@ static int tonga_start_in_non_protection_mode(struct pp_smumgr *smumgr) | |||
691 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, | 112 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, |
692 | SMC_SYSCON_RESET_CNTL, rst_reg, 1); | 113 | SMC_SYSCON_RESET_CNTL, rst_reg, 1); |
693 | 114 | ||
694 | result = tonga_smu_upload_firmware_image(smumgr); | 115 | result = smu7_upload_smu_firmware_image(smumgr); |
695 | 116 | ||
696 | if (result != 0) | 117 | if (result != 0) |
697 | return result; | 118 | return result; |
698 | 119 | ||
699 | /* Set smc instruct start point at 0x0 */ | 120 | /* Set smc instruct start point at 0x0 */ |
700 | tonga_program_jump_on_start(smumgr); | 121 | smu7_program_jump_on_start(smumgr); |
701 | 122 | ||
702 | 123 | ||
703 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, | 124 | SMUM_WRITE_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, |
@@ -719,7 +140,7 @@ static int tonga_start_smu(struct pp_smumgr *smumgr) | |||
719 | int result; | 140 | int result; |
720 | 141 | ||
721 | /* Only start SMC if SMC RAM is not running */ | 142 | /* Only start SMC if SMC RAM is not running */ |
722 | if (!tonga_is_smc_ram_running(smumgr)) { | 143 | if (!smu7_is_smc_ram_running(smumgr)) { |
723 | /*Check if SMU is running in protected mode*/ | 144 | /*Check if SMU is running in protected mode*/ |
724 | if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, | 145 | if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC, |
725 | SMU_FIRMWARE, SMU_MODE)) { | 146 | SMU_FIRMWARE, SMU_MODE)) { |
@@ -733,7 +154,7 @@ static int tonga_start_smu(struct pp_smumgr *smumgr) | |||
733 | } | 154 | } |
734 | } | 155 | } |
735 | 156 | ||
736 | result = tonga_request_smu_reload_fw(smumgr); | 157 | result = smu7_request_smu_load_fw(smumgr); |
737 | 158 | ||
738 | return result; | 159 | return result; |
739 | } | 160 | } |
@@ -747,70 +168,28 @@ static int tonga_start_smu(struct pp_smumgr *smumgr) | |||
747 | */ | 168 | */ |
748 | static int tonga_smu_init(struct pp_smumgr *smumgr) | 169 | static int tonga_smu_init(struct pp_smumgr *smumgr) |
749 | { | 170 | { |
750 | struct tonga_smumgr *tonga_smu; | 171 | struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(smumgr->backend); |
751 | uint8_t *internal_buf; | 172 | |
752 | uint64_t mc_addr = 0; | ||
753 | int i; | 173 | int i; |
754 | 174 | ||
755 | /* Allocate memory for backend private data */ | 175 | if (smu7_init(smumgr)) |
756 | tonga_smu = (struct tonga_smumgr *)(smumgr->backend); | 176 | return -EINVAL; |
757 | tonga_smu->header_buffer.data_size = | ||
758 | ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096; | ||
759 | tonga_smu->smu_buffer.data_size = 200*4096; | ||
760 | |||
761 | smu_allocate_memory(smumgr->device, | ||
762 | tonga_smu->header_buffer.data_size, | ||
763 | CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB, | ||
764 | PAGE_SIZE, | ||
765 | &mc_addr, | ||
766 | &tonga_smu->header_buffer.kaddr, | ||
767 | &tonga_smu->header_buffer.handle); | ||
768 | |||
769 | tonga_smu->pHeader = tonga_smu->header_buffer.kaddr; | ||
770 | tonga_smu->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr); | ||
771 | tonga_smu->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr); | ||
772 | |||
773 | PP_ASSERT_WITH_CODE((NULL != tonga_smu->pHeader), | ||
774 | "Out of memory.", | ||
775 | kfree(smumgr->backend); | ||
776 | cgs_free_gpu_mem(smumgr->device, | ||
777 | (cgs_handle_t)tonga_smu->header_buffer.handle); | ||
778 | return -1); | ||
779 | |||
780 | smu_allocate_memory(smumgr->device, | ||
781 | tonga_smu->smu_buffer.data_size, | ||
782 | CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB, | ||
783 | PAGE_SIZE, | ||
784 | &mc_addr, | ||
785 | &tonga_smu->smu_buffer.kaddr, | ||
786 | &tonga_smu->smu_buffer.handle); | ||
787 | |||
788 | internal_buf = tonga_smu->smu_buffer.kaddr; | ||
789 | tonga_smu->smu_buffer.mc_addr_high = smu_upper_32_bits(mc_addr); | ||
790 | tonga_smu->smu_buffer.mc_addr_low = smu_lower_32_bits(mc_addr); | ||
791 | |||
792 | PP_ASSERT_WITH_CODE((NULL != internal_buf), | ||
793 | "Out of memory.", | ||
794 | kfree(smumgr->backend); | ||
795 | cgs_free_gpu_mem(smumgr->device, | ||
796 | (cgs_handle_t)tonga_smu->smu_buffer.handle); | ||
797 | return -1;); | ||
798 | 177 | ||
799 | for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++) | 178 | for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++) |
800 | tonga_smu->activity_target[i] = 30; | 179 | smu_data->activity_target[i] = 30; |
801 | 180 | ||
802 | return 0; | 181 | return 0; |
803 | } | 182 | } |
804 | 183 | ||
805 | static const struct pp_smumgr_func tonga_smu_funcs = { | 184 | static const struct pp_smumgr_func tonga_smu_funcs = { |
806 | .smu_init = &tonga_smu_init, | 185 | .smu_init = &tonga_smu_init, |
807 | .smu_fini = &tonga_smu_fini, | 186 | .smu_fini = &smu7_smu_fini, |
808 | .start_smu = &tonga_start_smu, | 187 | .start_smu = &tonga_start_smu, |
809 | .check_fw_load_finish = &tonga_check_fw_load_finish, | 188 | .check_fw_load_finish = &smu7_check_fw_load_finish, |
810 | .request_smu_load_fw = &tonga_request_smu_reload_fw, | 189 | .request_smu_load_fw = &smu7_request_smu_load_fw, |
811 | .request_smu_load_specific_fw = &tonga_request_smu_load_specific_fw, | 190 | .request_smu_load_specific_fw = NULL, |
812 | .send_msg_to_smc = &tonga_send_msg_to_smc, | 191 | .send_msg_to_smc = &smu7_send_msg_to_smc, |
813 | .send_msg_to_smc_with_parameter = &tonga_send_msg_to_smc_with_parameter, | 192 | .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter, |
814 | .download_pptable_settings = NULL, | 193 | .download_pptable_settings = NULL, |
815 | .upload_pptable_settings = NULL, | 194 | .upload_pptable_settings = NULL, |
816 | .update_smc_table = tonga_update_smc_table, | 195 | .update_smc_table = tonga_update_smc_table, |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h index b2ad232506c1..edb5f203f7f5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.h | |||
@@ -26,16 +26,7 @@ | |||
26 | 26 | ||
27 | #include "smu72_discrete.h" | 27 | #include "smu72_discrete.h" |
28 | 28 | ||
29 | #define SMC_RAM_END 0x40000 | 29 | #include "smu7_smumgr.h" |
30 | |||
31 | struct tonga_buffer_entry { | ||
32 | uint32_t data_size; | ||
33 | uint32_t mc_addr_low; | ||
34 | uint32_t mc_addr_high; | ||
35 | void *kaddr; | ||
36 | unsigned long handle; | ||
37 | }; | ||
38 | |||
39 | 30 | ||
40 | struct tonga_mc_reg_entry { | 31 | struct tonga_mc_reg_entry { |
41 | uint32_t mclk_max; | 32 | uint32_t mclk_max; |
@@ -52,19 +43,8 @@ struct tonga_mc_reg_table { | |||
52 | 43 | ||
53 | 44 | ||
54 | struct tonga_smumgr { | 45 | struct tonga_smumgr { |
55 | uint8_t *pHeader; | ||
56 | uint8_t *pMecImage; | ||
57 | |||
58 | |||
59 | uint32_t soft_regs_start; | ||
60 | uint32_t dpm_table_start; | ||
61 | uint32_t mc_reg_table_start; | ||
62 | uint32_t fan_table_start; | ||
63 | uint32_t arb_table_start; | ||
64 | |||
65 | struct tonga_buffer_entry header_buffer; | ||
66 | struct tonga_buffer_entry smu_buffer; | ||
67 | 46 | ||
47 | struct smu7_smumgr smu7_data; | ||
68 | struct SMU72_Discrete_DpmTable smc_state_table; | 48 | struct SMU72_Discrete_DpmTable smc_state_table; |
69 | struct SMU72_Discrete_Ulv ulv_setting; | 49 | struct SMU72_Discrete_Ulv ulv_setting; |
70 | struct SMU72_Discrete_PmFuses power_tune_table; | 50 | struct SMU72_Discrete_PmFuses power_tune_table; |
@@ -76,13 +56,4 @@ struct tonga_smumgr { | |||
76 | 56 | ||
77 | }; | 57 | }; |
78 | 58 | ||
79 | extern int tonga_smum_init(struct pp_smumgr *smumgr); | ||
80 | extern int tonga_copy_bytes_to_smc(struct pp_smumgr *smumgr, | ||
81 | uint32_t smcStartAddress, const uint8_t *src, | ||
82 | uint32_t byteCount, uint32_t limit); | ||
83 | extern int tonga_read_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smcAddress, | ||
84 | uint32_t *value, uint32_t limit); | ||
85 | extern int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, uint32_t smcAddress, | ||
86 | uint32_t value, uint32_t limit); | ||
87 | |||
88 | #endif | 59 | #endif |