aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorMaruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu@amd.com>2016-04-26 10:54:38 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-08-31 15:21:07 -0400
commit9139d731fdaa52b85543f2713d65ca860e0ce884 (patch)
treeafa48d7ab93a8b78ca08c8d08db6b871dbf366b8 /drivers/gpu/drm/amd/amdgpu
parentda69c161448d6a682b3761d9bc444161cbf25337 (diff)
drm/amdgpu: add si dpm support in amdgpu_atombios
v2: renamed _atom_ to _atombios_ for consistency added ulClockParams to _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 and _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 to avoid build break Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c158
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h16
2 files changed, 173 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 1b621160b52e..59961db9c390 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -978,6 +978,48 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
978 return -EINVAL; 978 return -EINVAL;
979 979
980 switch (crev) { 980 switch (crev) {
981 case 2:
982 case 3:
983 case 5:
984 /* r6xx, r7xx, evergreen, ni, si.
985 * TODO: add support for asic_type <= CHIP_RV770*/
986 if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
987 args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
988
989 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
990
991 dividers->post_div = args.v3.ucPostDiv;
992 dividers->enable_post_div = (args.v3.ucCntlFlag &
993 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
994 dividers->enable_dithen = (args.v3.ucCntlFlag &
995 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
996 dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
997 dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
998 dividers->ref_div = args.v3.ucRefDiv;
999 dividers->vco_mode = (args.v3.ucCntlFlag &
1000 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
1001 } else {
1002 /* for SI we use ComputeMemoryClockParam for memory plls */
1003 if (adev->asic_type >= CHIP_TAHITI)
1004 return -EINVAL;
1005 args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
1006 if (strobe_mode)
1007 args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
1008
1009 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1010
1011 dividers->post_div = args.v5.ucPostDiv;
1012 dividers->enable_post_div = (args.v5.ucCntlFlag &
1013 ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
1014 dividers->enable_dithen = (args.v5.ucCntlFlag &
1015 ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
1016 dividers->whole_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDiv);
1017 dividers->frac_fb_div = le16_to_cpu(args.v5.ulFbDiv.usFbDivFrac);
1018 dividers->ref_div = args.v5.ucRefDiv;
1019 dividers->vco_mode = (args.v5.ucCntlFlag &
1020 ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
1021 }
1022 break;
981 case 4: 1023 case 4:
982 /* fusion */ 1024 /* fusion */
983 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */ 1025 args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */
@@ -1122,6 +1164,32 @@ void amdgpu_atombios_set_engine_dram_timings(struct amdgpu_device *adev,
1122 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args); 1164 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1123} 1165}
1124 1166
1167void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
1168 u16 *vddc, u16 *vddci, u16 *mvdd)
1169{
1170 struct amdgpu_mode_info *mode_info = &adev->mode_info;
1171 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
1172 u8 frev, crev;
1173 u16 data_offset;
1174 union firmware_info *firmware_info;
1175
1176 *vddc = 0;
1177 *vddci = 0;
1178 *mvdd = 0;
1179
1180 if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
1181 &frev, &crev, &data_offset)) {
1182 firmware_info =
1183 (union firmware_info *)(mode_info->atom_context->bios +
1184 data_offset);
1185 *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
1186 if ((frev == 2) && (crev >= 2)) {
1187 *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
1188 *mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
1189 }
1190 }
1191}
1192
1125union set_voltage { 1193union set_voltage {
1126 struct _SET_VOLTAGE_PS_ALLOCATION alloc; 1194 struct _SET_VOLTAGE_PS_ALLOCATION alloc;
1127 struct _SET_VOLTAGE_PARAMETERS v1; 1195 struct _SET_VOLTAGE_PARAMETERS v1;
@@ -1129,6 +1197,52 @@ union set_voltage {
1129 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3; 1197 struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
1130}; 1198};
1131 1199
1200int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
1201 u16 voltage_id, u16 *voltage)
1202{
1203 union set_voltage args;
1204 int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
1205 u8 frev, crev;
1206
1207 if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))
1208 return -EINVAL;
1209
1210 switch (crev) {
1211 case 1:
1212 return -EINVAL;
1213 case 2:
1214 args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
1215 args.v2.ucVoltageMode = 0;
1216 args.v2.usVoltageLevel = 0;
1217
1218 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1219
1220 *voltage = le16_to_cpu(args.v2.usVoltageLevel);
1221 break;
1222 case 3:
1223 args.v3.ucVoltageType = voltage_type;
1224 args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
1225 args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
1226
1227 amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
1228
1229 *voltage = le16_to_cpu(args.v3.usVoltageLevel);
1230 break;
1231 default:
1232 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
1233 return -EINVAL;
1234 }
1235
1236 return 0;
1237}
1238
1239int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
1240 u16 *voltage,
1241 u16 leakage_idx)
1242{
1243 return amdgpu_atombios_get_max_vddc(adev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
1244}
1245
1132void amdgpu_atombios_set_voltage(struct amdgpu_device *adev, 1246void amdgpu_atombios_set_voltage(struct amdgpu_device *adev,
1133 u16 voltage_level, 1247 u16 voltage_level,
1134 u8 voltage_type) 1248 u8 voltage_type)
@@ -1349,6 +1463,50 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL
1349 return NULL; 1463 return NULL;
1350} 1464}
1351 1465
1466int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
1467 u8 voltage_type,
1468 u8 *svd_gpio_id, u8 *svc_gpio_id)
1469{
1470 int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
1471 u8 frev, crev;
1472 u16 data_offset, size;
1473 union voltage_object_info *voltage_info;
1474 union voltage_object *voltage_object = NULL;
1475
1476 if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size,
1477 &frev, &crev, &data_offset)) {
1478 voltage_info = (union voltage_object_info *)
1479 (adev->mode_info.atom_context->bios + data_offset);
1480
1481 switch (frev) {
1482 case 3:
1483 switch (crev) {
1484 case 1:
1485 voltage_object = (union voltage_object *)
1486 amdgpu_atombios_lookup_voltage_object_v3(&voltage_info->v3,
1487 voltage_type,
1488 VOLTAGE_OBJ_SVID2);
1489 if (voltage_object) {
1490 *svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;
1491 *svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;
1492 } else {
1493 return -EINVAL;
1494 }
1495 break;
1496 default:
1497 DRM_ERROR("unknown voltage object table\n");
1498 return -EINVAL;
1499 }
1500 break;
1501 default:
1502 DRM_ERROR("unknown voltage object table\n");
1503 return -EINVAL;
1504 }
1505
1506 }
1507 return 0;
1508}
1509
1352bool 1510bool
1353amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev, 1511amdgpu_atombios_is_voltage_gpio(struct amdgpu_device *adev,
1354 u8 voltage_type, u8 voltage_mode) 1512 u8 voltage_type, u8 voltage_mode)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
index 15dd43ec38bb..17356151db38 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
@@ -208,5 +208,19 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
208void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev); 208void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
209 209
210void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); 210void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
211 211int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
212 u16 voltage_id, u16 *voltage);
213int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
214 u16 *voltage,
215 u16 leakage_idx);
216void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
217 u16 *vddc, u16 *vddci, u16 *mvdd);
218int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
219 u8 clock_type,
220 u32 clock,
221 bool strobe_mode,
222 struct atom_clock_dividers *dividers);
223int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
224 u8 voltage_type,
225 u8 *svd_gpio_id, u8 *svc_gpio_id);
212#endif 226#endif