drm/radeon: update radeon_atom_is_voltage_gpio() for SI

SI uses a new atom table.  Required for DPM on SI.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index f26cefe..e0d315e 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2529,13 +2529,13 @@
 	eg_pi->smu_uvd_hs = true;
 
 	pi->voltage_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
 
 	pi->mvdd_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
 
 	eg_pi->vddci_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
 	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                    &frev, &crev, &data_offset)) {
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index 0b7b319..7108580 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -2022,13 +2022,13 @@
 	pi->lmp = RV770_LMP_DFLT;
 
 	pi->voltage_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
 
 	pi->mvdd_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
 
 	eg_pi->vddci_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
 	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                    &frev, &crev, &data_offset)) {
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 7530ee9..3cf8d9b 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -3977,13 +3977,13 @@
 	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
 
 	pi->voltage_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
 
 	pi->mvdd_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
 
 	eg_pi->vddci_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
 
 	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                    &frev, &crev, &data_offset)) {
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1fb1d3f..fdc36e8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -244,7 +244,8 @@
 int radeon_atom_get_voltage_table(struct radeon_device *rdev,
 				  u8 voltage_type,
 				  struct atom_voltage_table *voltage_table);
-bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type);
+bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
+				 u8 voltage_type, u8 voltage_mode);
 void radeon_atom_update_memory_dll(struct radeon_device *rdev,
 				   u32 mem_clock);
 void radeon_atom_set_ac_timing(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 45a6f5d..0da95eb 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3102,12 +3102,14 @@
 }
 
 union voltage_object_info {
-	struct  _ATOM_VOLTAGE_OBJECT_INFO v1;
-	struct  _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
+	struct _ATOM_VOLTAGE_OBJECT_INFO v1;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
 };
 
 bool
-radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type)
+radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
+			    u8 voltage_type, u8 voltage_mode)
 {
 	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
 	u8 frev, crev;
@@ -3120,27 +3122,54 @@
 		voltage_info = (union voltage_object_info *)
 			(rdev->mode_info.atom_context->bios + data_offset);
 
-		switch (crev) {
+		switch (frev) {
 		case 1:
-			num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
-				sizeof(ATOM_VOLTAGE_OBJECT);
+		case 2:
+			switch (crev) {
+			case 1:
+				num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+					sizeof(ATOM_VOLTAGE_OBJECT);
 
-			for (i = 0; i < num_indices; i++) {
-				if ((voltage_info->v1.asVoltageObj[i].ucVoltageType == voltage_type) &&
-				    (voltage_info->v1.asVoltageObj[i].asControl.ucVoltageControlId ==
-				     VOLTAGE_CONTROLLED_BY_GPIO))
-					return true;
+				for (i = 0; i < num_indices; i++) {
+					if ((voltage_info->v1.asVoltageObj[i].ucVoltageType == voltage_type) &&
+					    (voltage_info->v1.asVoltageObj[i].asControl.ucVoltageControlId ==
+					     VOLTAGE_CONTROLLED_BY_GPIO))
+						return true;
+				}
+				break;
+			case 2:
+				num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+					sizeof(ATOM_VOLTAGE_OBJECT_INFO_V2);
+
+				for (i = 0; i < num_indices; i++) {
+					if ((voltage_info->v2.asVoltageObj[i].ucVoltageType == voltage_type) &&
+					    (voltage_info->v2.asVoltageObj[i].asControl.ucVoltageControlId ==
+					     VOLTAGE_CONTROLLED_BY_GPIO))
+						return true;
+				}
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return false;
 			}
 			break;
-		case 2:
-			num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
-				sizeof(ATOM_VOLTAGE_OBJECT_INFO_V2);
+		case 3:
+			switch (crev) {
+			case 1:
+				num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+					sizeof(ATOM_VOLTAGE_OBJECT_INFO_V3_1);
 
-			for (i = 0; i < num_indices; i++) {
-				if ((voltage_info->v2.asVoltageObj[i].ucVoltageType == voltage_type) &&
-				    (voltage_info->v2.asVoltageObj[i].asControl.ucVoltageControlId ==
-				     VOLTAGE_CONTROLLED_BY_GPIO))
-					return true;
+				for (i = 0; i < num_indices; i++) {
+					if ((voltage_info->v3.asVoltageObj[i].asGpioVoltageObj.sHeader.ucVoltageType ==
+					     voltage_type) &&
+					    (voltage_info->v3.asVoltageObj[i].asGpioVoltageObj.sHeader.ucVoltageMode ==
+					     voltage_mode))
+						return true;
+				}
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return false;
 			}
 			break;
 		default:
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index e8f07b1..cc2a7c2 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -1933,7 +1933,7 @@
 		pi->fb_div_scale = 0;
 
 	pi->voltage_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
 
 	pi->gfx_clock_gating = true;
 
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index 3c2866e..aa38764 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -2301,10 +2301,10 @@
 	pi->lmp = RV770_LMP_DFLT;
 
 	pi->voltage_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
 
 	pi->mvdd_control =
-		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
 
 	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                    &frev, &crev, &data_offset)) {