Same write-OOB and read-OOB as the Tonga fix, across seven Vega10 sub-table
parsers: get_vddc_lookup_table(), get_mm_clock_voltage_table(),
get_socclk/mclk/gfxclk/pixclk/dcefclk_voltage_dependency_table().
The GFXCLK table selects the correct record size per revision.
Fixes: f83a9991648b ("drm/amd/powerplay: add Vega10 powerplay support (v5)")
Signed-off-by: Asad Kamal <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
---
.../powerplay/hwmgr/vega10_processpptables.c | 133 ++++++++++++++----
1 file changed, 102 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
index 3be616af327e..34646a562f3b 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
@@ -344,20 +344,29 @@ static int get_mm_clock_voltage_table(
const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table)
{
uint32_t i;
+ uint32_t num_entries;
const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record;
phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- mm_table = kzalloc(struct_size(mm_table, entries,
mm_dependency_table->ucNumEntries),
+ num_entries = min_t(uint32_t, mm_dependency_table->ucNumEntries,
+ pp_entries_max(hwmgr, mm_dependency_table,
+ sizeof(*mm_dependency_table),
+
sizeof(ATOM_Vega10_MM_Dependency_Record)));
+ if (num_entries < mm_dependency_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 MM dependency table: clamping
ucNumEntries %u -> %u\n",
+ mm_dependency_table->ucNumEntries, num_entries);
+
+ mm_table = kzalloc(struct_size(mm_table, entries, num_entries),
GFP_KERNEL);
if (!mm_table)
return -ENOMEM;
- mm_table->count = mm_dependency_table->ucNumEntries;
+ mm_table->count = num_entries;
- for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
mm_dependency_record = &mm_dependency_table->entries[i];
mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
mm_table->entries[i].samclock =
@@ -568,19 +577,28 @@ static int get_socclk_voltage_dependency_table(
const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_clock_voltage_dependency_table *clk_table;
PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc(struct_size(clk_table, entries,
clk_dep_table->ucNumEntries),
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+
sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 SOCCLK dependency table: clamping
ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc(struct_size(clk_table, entries, num_entries),
GFP_KERNEL);
if (!clk_table)
return -ENOMEM;
- clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
- for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -598,19 +616,28 @@ static int get_mclk_voltage_dependency_table(
const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
"Invalid PowerPlay Table!", return -1);
- mclk_table = kzalloc(struct_size(mclk_table, entries,
mclk_dep_table->ucNumEntries),
+ num_entries = min_t(uint32_t, mclk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, mclk_dep_table,
+ sizeof(*mclk_dep_table),
+
sizeof(ATOM_Vega10_MCLK_Dependency_Record)));
+ if (num_entries < mclk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 MCLK dependency table: clamping
ucNumEntries %u -> %u\n",
+ mclk_dep_table->ucNumEntries, num_entries);
+
+ mclk_table = kzalloc(struct_size(mclk_table, entries, num_entries),
GFP_KERNEL);
if (!mclk_table)
return -ENOMEM;
- mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
+ mclk_table->count = num_entries;
- for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
mclk_table->entries[i].vddInd =
mclk_dep_table->entries[i].ucVddInd;
mclk_table->entries[i].vddciInd =
@@ -633,6 +660,7 @@ static int get_gfxclk_voltage_dependency_table(
const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
@@ -640,15 +668,35 @@ static int get_gfxclk_voltage_dependency_table(
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc(struct_size(clk_table, entries,
clk_dep_table->ucNumEntries),
+ if (clk_dep_table->ucRevId == 0) {
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+
sizeof(ATOM_Vega10_GFXCLK_Dependency_Record)));
+ } else if (clk_dep_table->ucRevId == 1) {
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+
sizeof(ATOM_Vega10_GFXCLK_Dependency_Record_V2)));
+ } else {
+ PP_ASSERT_WITH_CODE(false,
+ "Unsupported GFXClockDependencyTable Revision!",
+ return -EINVAL);
+ }
+
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 GFXCLK dependency table: clamping
ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc(struct_size(clk_table, entries, num_entries),
GFP_KERNEL);
if (!clk_table)
return -ENOMEM;
- clk_table->count = clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
if (clk_dep_table->ucRevId == 0) {
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -661,9 +709,9 @@ static int get_gfxclk_voltage_dependency_table(
clk_table->entries[i].sclk_offset =
le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset);
}
- } else if (clk_dep_table->ucRevId == 1) {
+ } else {
patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2
*)clk_dep_table->entries;
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
patom_record_v2->ucVddInd;
clk_table->entries[i].clk =
@@ -677,11 +725,6 @@ static int get_gfxclk_voltage_dependency_table(
le16_to_cpu(patom_record_v2->usAVFSOffset);
patom_record_v2++;
}
- } else {
- kfree(clk_table);
- PP_ASSERT_WITH_CODE(false,
- "Unsupported GFXClockDependencyTable Revision!",
- return -EINVAL);
}
*pp_vega10_clk_dep_table = clk_table;
@@ -696,20 +739,29 @@ static int get_pix_clk_voltage_dependency_table(
const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc(struct_size(clk_table, entries,
clk_dep_table->ucNumEntries),
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+
sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 PIXCLK dependency table: clamping
ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc(struct_size(clk_table, entries, num_entries),
GFP_KERNEL);
if (!clk_table)
return -ENOMEM;
- clk_table->count = clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -728,6 +780,7 @@ static int get_dcefclk_voltage_dependency_table(
const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t safe_entries;
uint8_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
@@ -738,6 +791,14 @@ static int get_dcefclk_voltage_dependency_table(
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
+ safe_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+
sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (safe_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 DCEFCLK dependency table: clamping
ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, safe_entries);
+
/*
* workaround needed to add another DPM level for pioneer cards
* as VBIOS is locked down.
@@ -747,12 +808,12 @@ static int get_dcefclk_voltage_dependency_table(
dev_id = adev->pdev->device;
rev_id = adev->pdev->revision;
- if (dev_id == 0x6863 && rev_id == 0 &&
- clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk <
90000)
- num_entries = clk_dep_table->ucNumEntries + 1 >
NUM_DSPCLK_LEVELS ?
- NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries
+ 1;
+ if (dev_id == 0x6863 && rev_id == 0 && safe_entries > 0 &&
+ clk_dep_table->entries[safe_entries - 1].ulClk < 90000)
+ num_entries = safe_entries + 1 > NUM_DSPCLK_LEVELS ?
+ NUM_DSPCLK_LEVELS : safe_entries + 1;
else
- num_entries = clk_dep_table->ucNumEntries;
+ num_entries = safe_entries;
clk_table = kzalloc(struct_size(clk_table, entries, num_entries),
@@ -762,7 +823,7 @@ static int get_dcefclk_voltage_dependency_table(
clk_table->count = (uint32_t)num_entries;
- for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < safe_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -1036,18 +1097,28 @@ static int get_vddc_lookup_table(
uint32_t max_levels)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_voltage_lookup_table *table;
PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
"Invalid SOC_VDDD Lookup Table!", return 1);
- table = kzalloc(struct_size(table, entries, max_levels), GFP_KERNEL);
+ num_entries = min_t(uint32_t, vddc_lookup_pp_tables->ucNumEntries,
+ min_t(uint32_t, max_levels,
+ pp_entries_max(hwmgr, vddc_lookup_pp_tables,
+ sizeof(*vddc_lookup_pp_tables),
+
sizeof(ATOM_Vega10_Voltage_Lookup_Record))));
+ if (num_entries < vddc_lookup_pp_tables->ucNumEntries)
+ pr_warn("amdgpu: Vega10 VddcLookup table: clamping ucNumEntries
%u -> %u\n",
+ vddc_lookup_pp_tables->ucNumEntries, num_entries);
+
+ table = kzalloc(struct_size(table, entries, num_entries), GFP_KERNEL);
if (!table)
return -ENOMEM;
- table->count = vddc_lookup_pp_tables->ucNumEntries;
+ table->count = num_entries;
- for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
+ for (i = 0; i < num_entries; i++)
table->entries[i].us_vdd =
le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);
--
2.46.0