Rev 3764 | Rev 5128 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3764 | Rev 5078 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | #include "radeon.h" |
28 | #include "radeon.h" |
Line 29... | Line 29... | ||
29 | 29 | ||
30 | #include "atom.h" |
30 | #include "atom.h" |
Line 31... | Line -... | ||
31 | #include "atom-bits.h" |
- | |
32 | - | ||
33 | /* from radeon_encoder.c */ |
- | |
34 | extern uint32_t |
- | |
35 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
- | |
36 | uint8_t dac); |
31 | #include "atom-bits.h" |
37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
32 | |
38 | extern void |
33 | extern void |
Line 39... | Line -... | ||
39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
- | |
40 | uint32_t supported_device, u16 caps); |
- | |
41 | - | ||
42 | /* from radeon_connector.c */ |
- | |
43 | extern void |
- | |
44 | radeon_add_atom_connector(struct drm_device *dev, |
- | |
45 | uint32_t connector_id, |
- | |
46 | uint32_t supported_device, |
- | |
47 | int connector_type, |
- | |
48 | struct radeon_i2c_bus_rec *i2c_bus, |
- | |
49 | uint32_t igp_lane_info, |
- | |
50 | uint16_t connector_object_id, |
- | |
51 | struct radeon_hpd *hpd, |
34 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
52 | struct radeon_router *router); |
35 | uint32_t supported_device, u16 caps); |
53 | 36 | ||
54 | /* from radeon_legacy_encoder.c */ |
37 | /* from radeon_legacy_encoder.c */ |
Line 55... | Line -... | ||
55 | extern void |
- | |
56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
- | |
57 | uint32_t supported_device); |
- | |
58 | - | ||
59 | /* local */ |
38 | extern void |
60 | static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, |
39 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
61 | u16 voltage_id, u16 *voltage); |
40 | uint32_t supported_device); |
62 | 41 | ||
63 | union atom_supported_devices { |
42 | union atom_supported_devices { |
Line 165... | Line 144... | ||
165 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
144 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
Line 166... | Line 145... | ||
166 | 145 | ||
167 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
146 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
Line -... | Line 147... | ||
- | 147 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); |
|
168 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); |
148 | |
169 | - | ||
Line 170... | Line 149... | ||
170 | for (i = 0; i < num_indices; i++) { |
149 | gpio = &i2c_info->asGPIO_Info[0]; |
Line 171... | Line 150... | ||
171 | gpio = &i2c_info->asGPIO_Info[i]; |
150 | for (i = 0; i < num_indices; i++) { |
172 | 151 | ||
173 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
152 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
174 | 153 | ||
- | 154 | if (gpio->sucI2cId.ucAccess == id) { |
|
- | 155 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
|
175 | if (gpio->sucI2cId.ucAccess == id) { |
156 | break; |
176 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
157 | } |
Line 177... | Line 158... | ||
177 | break; |
158 | gpio = (ATOM_GPIO_I2C_ASSIGMENT *) |
178 | } |
159 | ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT)); |
Line 197... | Line 178... | ||
197 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
178 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
Line 198... | Line 179... | ||
198 | 179 | ||
199 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
180 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
Line -... | Line 181... | ||
- | 181 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); |
|
200 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); |
182 | |
201 | - | ||
202 | for (i = 0; i < num_indices; i++) { |
- | |
203 | gpio = &i2c_info->asGPIO_Info[i]; |
183 | gpio = &i2c_info->asGPIO_Info[0]; |
Line 204... | Line 184... | ||
204 | 184 | for (i = 0; i < num_indices; i++) { |
|
Line 205... | Line 185... | ||
205 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
185 | radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); |
206 | 186 | ||
207 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
187 | i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); |
208 | 188 | ||
- | 189 | if (i2c.valid) { |
|
- | 190 | sprintf(stmp, "0x%x", i2c.i2c_id); |
|
209 | if (i2c.valid) { |
191 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); |
210 | sprintf(stmp, "0x%x", i2c.i2c_id); |
192 | } |
211 | rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); |
193 | gpio = (ATOM_GPIO_I2C_ASSIGMENT *) |
Line 212... | Line 194... | ||
212 | } |
194 | ((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT)); |
Line 232... | Line 214... | ||
232 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); |
214 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); |
Line 233... | Line 215... | ||
233 | 215 | ||
234 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
216 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
Line -... | Line 217... | ||
- | 217 | sizeof(ATOM_GPIO_PIN_ASSIGNMENT); |
|
235 | sizeof(ATOM_GPIO_PIN_ASSIGNMENT); |
218 | |
236 | - | ||
237 | for (i = 0; i < num_indices; i++) { |
219 | pin = gpio_info->asGPIO_Pin; |
238 | pin = &gpio_info->asGPIO_Pin[i]; |
220 | for (i = 0; i < num_indices; i++) { |
239 | if (id == pin->ucGPIO_ID) { |
221 | if (id == pin->ucGPIO_ID) { |
240 | gpio.id = pin->ucGPIO_ID; |
222 | gpio.id = pin->ucGPIO_ID; |
241 | gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; |
223 | gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; |
242 | gpio.mask = (1 << pin->ucGpioPinBitShift); |
224 | gpio.mask = (1 << pin->ucGpioPinBitShift); |
243 | gpio.valid = true; |
225 | gpio.valid = true; |
- | 226 | break; |
|
- | 227 | } |
|
244 | break; |
228 | pin = (ATOM_GPIO_PIN_ASSIGNMENT *) |
245 | } |
229 | ((u8 *)pin + sizeof(ATOM_GPIO_PIN_ASSIGNMENT)); |
Line 246... | Line 230... | ||
246 | } |
230 | } |
247 | } |
231 | } |
Line 713... | Line 697... | ||
713 | ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; |
697 | ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; |
714 | ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = |
698 | ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = |
715 | (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) |
699 | (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) |
716 | (ctx->bios + data_offset + |
700 | (ctx->bios + data_offset + |
717 | le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); |
701 | le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); |
- | 702 | u8 *num_dst_objs = (u8 *) |
|
- | 703 | ((u8 *)router_src_dst_table + 1 + |
|
- | 704 | (router_src_dst_table->ucNumberOfSrc * 2)); |
|
- | 705 | u16 *dst_objs = (u16 *)(num_dst_objs + 1); |
|
718 | int enum_id; |
706 | int enum_id; |
Line 719... | Line 707... | ||
719 | 707 | ||
720 | router.router_id = router_obj_id; |
708 | router.router_id = router_obj_id; |
721 | for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; |
- | |
722 | enum_id++) { |
709 | for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) { |
723 | if (le16_to_cpu(path->usConnObjectId) == |
710 | if (le16_to_cpu(path->usConnObjectId) == |
724 | le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) |
711 | le16_to_cpu(dst_objs[enum_id])) |
725 | break; |
712 | break; |
Line 726... | Line 713... | ||
726 | } |
713 | } |
727 | 714 | ||
Line 1238... | Line 1225... | ||
1238 | 1225 | ||
1239 | if (ASIC_IS_DCE4(rdev)) { |
1226 | if (ASIC_IS_DCE4(rdev)) { |
1240 | rdev->clock.default_dispclk = |
1227 | rdev->clock.default_dispclk = |
1241 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); |
1228 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); |
1242 | if (rdev->clock.default_dispclk == 0) { |
1229 | if (rdev->clock.default_dispclk == 0) { |
- | 1230 | if (ASIC_IS_DCE6(rdev)) |
|
- | 1231 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ |
|
1243 | if (ASIC_IS_DCE5(rdev)) |
1232 | else if (ASIC_IS_DCE5(rdev)) |
1244 | rdev->clock.default_dispclk = 54000; /* 540 Mhz */ |
1233 | rdev->clock.default_dispclk = 54000; /* 540 Mhz */ |
1245 | else |
1234 | else |
1246 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ |
1235 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ |
- | 1236 | } |
|
- | 1237 | /* set a reasonable default for DP */ |
|
- | 1238 | if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk < 53900)) { |
|
- | 1239 | DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n", |
|
- | 1240 | rdev->clock.default_dispclk / 100); |
|
- | 1241 | rdev->clock.default_dispclk = 60000; |
|
1247 | } |
1242 | } |
1248 | rdev->clock.dp_extclk = |
1243 | rdev->clock.dp_extclk = |
- | 1244 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); |
|
1249 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); |
1245 | rdev->clock.current_dispclk = rdev->clock.default_dispclk; |
1250 | } |
1246 | } |
Line 1251... | Line 1247... | ||
1251 | *dcpll = *p1pll; |
1247 | *dcpll = *p1pll; |
1252 | 1248 | ||
Line 1267... | Line 1263... | ||
1267 | union igp_info { |
1263 | union igp_info { |
1268 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
1269 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
1270 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; |
1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; |
1271 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; |
1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; |
- | 1268 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8; |
|
1272 | }; |
1269 | }; |
Line 1273... | Line 1270... | ||
1273 | 1270 | ||
1274 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
1271 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
1275 | { |
1272 | { |
Line 1359... | Line 1356... | ||
1359 | { |
1356 | { |
1360 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1357 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1361 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); |
1358 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); |
1362 | uint16_t data_offset, size; |
1359 | uint16_t data_offset, size; |
1363 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
1360 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
- | 1361 | struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign; |
|
1364 | uint8_t frev, crev; |
1362 | uint8_t frev, crev; |
1365 | int i, num_indices; |
1363 | int i, num_indices; |
Line 1366... | Line 1364... | ||
1366 | 1364 | ||
1367 | memset(ss, 0, sizeof(struct radeon_atom_ss)); |
1365 | memset(ss, 0, sizeof(struct radeon_atom_ss)); |
Line 1370... | Line 1368... | ||
1370 | ss_info = |
1368 | ss_info = |
1371 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); |
1369 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); |
Line 1372... | Line 1370... | ||
1372 | 1370 | ||
1373 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1371 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1374 | sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); |
- | |
- | 1372 | sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); |
|
- | 1373 | ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) |
|
1375 | 1374 | ((u8 *)&ss_info->asSS_Info[0]); |
|
1376 | for (i = 0; i < num_indices; i++) { |
1375 | for (i = 0; i < num_indices; i++) { |
1377 | if (ss_info->asSS_Info[i].ucSS_Id == id) { |
1376 | if (ss_assign->ucSS_Id == id) { |
1378 | ss->percentage = |
1377 | ss->percentage = |
1379 | le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); |
1378 | le16_to_cpu(ss_assign->usSpreadSpectrumPercentage); |
1380 | ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; |
1379 | ss->type = ss_assign->ucSpreadSpectrumType; |
1381 | ss->step = ss_info->asSS_Info[i].ucSS_Step; |
1380 | ss->step = ss_assign->ucSS_Step; |
1382 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; |
1381 | ss->delay = ss_assign->ucSS_Delay; |
1383 | ss->range = ss_info->asSS_Info[i].ucSS_Range; |
1382 | ss->range = ss_assign->ucSS_Range; |
1384 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; |
1383 | ss->refdiv = ss_assign->ucRecommendedRef_Div; |
1385 | return true; |
1384 | return true; |
- | 1385 | } |
|
- | 1386 | ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) |
|
1386 | } |
1387 | ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT)); |
1387 | } |
1388 | } |
1388 | } |
1389 | } |
1389 | return false; |
1390 | return false; |
Line 1436... | Line 1437... | ||
1436 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); |
1437 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); |
1437 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); |
1438 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); |
1438 | break; |
1439 | break; |
1439 | } |
1440 | } |
1440 | break; |
1441 | break; |
- | 1442 | case 8: |
|
- | 1443 | switch (id) { |
|
- | 1444 | case ASIC_INTERNAL_SS_ON_TMDS: |
|
- | 1445 | percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage); |
|
- | 1446 | rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz); |
|
- | 1447 | break; |
|
- | 1448 | case ASIC_INTERNAL_SS_ON_HDMI: |
|
- | 1449 | percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage); |
|
- | 1450 | rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz); |
|
- | 1451 | break; |
|
- | 1452 | case ASIC_INTERNAL_SS_ON_LVDS: |
|
- | 1453 | percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage); |
|
- | 1454 | rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz); |
|
- | 1455 | break; |
|
- | 1456 | } |
|
- | 1457 | break; |
|
1441 | default: |
1458 | default: |
1442 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
1459 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
1443 | break; |
1460 | break; |
1444 | } |
1461 | } |
1445 | if (percentage) |
1462 | if (percentage) |
Line 1453... | Line 1470... | ||
1453 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; |
1470 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; |
1454 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; |
1471 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; |
1455 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; |
1472 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; |
1456 | }; |
1473 | }; |
Line -... | Line 1474... | ||
- | 1474 | ||
- | 1475 | union asic_ss_assignment { |
|
- | 1476 | struct _ATOM_ASIC_SS_ASSIGNMENT v1; |
|
- | 1477 | struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2; |
|
- | 1478 | struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3; |
|
- | 1479 | }; |
|
1457 | 1480 | ||
1458 | bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, |
1481 | bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, |
1459 | struct radeon_atom_ss *ss, |
1482 | struct radeon_atom_ss *ss, |
1460 | int id, u32 clock) |
1483 | int id, u32 clock) |
1461 | { |
1484 | { |
1462 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1485 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1463 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); |
1486 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); |
1464 | uint16_t data_offset, size; |
1487 | uint16_t data_offset, size; |
- | 1488 | union asic_ss_info *ss_info; |
|
1465 | union asic_ss_info *ss_info; |
1489 | union asic_ss_assignment *ss_assign; |
1466 | uint8_t frev, crev; |
1490 | uint8_t frev, crev; |
Line -... | Line 1491... | ||
- | 1491 | int i, num_indices; |
|
- | 1492 | ||
- | 1493 | if (id == ASIC_INTERNAL_MEMORY_SS) { |
|
- | 1494 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT)) |
|
- | 1495 | return false; |
|
- | 1496 | } |
|
- | 1497 | if (id == ASIC_INTERNAL_ENGINE_SS) { |
|
- | 1498 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT)) |
|
- | 1499 | return false; |
|
1467 | int i, num_indices; |
1500 | } |
1468 | 1501 | ||
1469 | memset(ss, 0, sizeof(struct radeon_atom_ss)); |
1502 | memset(ss, 0, sizeof(struct radeon_atom_ss)); |
Line 1470... | Line 1503... | ||
1470 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
1503 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
Line 1476... | Line 1509... | ||
1476 | switch (frev) { |
1509 | switch (frev) { |
1477 | case 1: |
1510 | case 1: |
1478 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1511 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1479 | sizeof(ATOM_ASIC_SS_ASSIGNMENT); |
1512 | sizeof(ATOM_ASIC_SS_ASSIGNMENT); |
Line -... | Line 1513... | ||
- | 1513 | ||
1480 | 1514 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]); |
|
1481 | for (i = 0; i < num_indices; i++) { |
1515 | for (i = 0; i < num_indices; i++) { |
1482 | if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && |
1516 | if ((ss_assign->v1.ucClockIndication == id) && |
1483 | (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { |
1517 | (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) { |
1484 | ss->percentage = |
1518 | ss->percentage = |
1485 | le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
1519 | le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage); |
1486 | ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
1520 | ss->type = ss_assign->v1.ucSpreadSpectrumMode; |
- | 1521 | ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz); |
|
1487 | ss->rate = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadRateInKhz); |
1522 | ss->percentage_divider = 100; |
1488 | return true; |
1523 | return true; |
- | 1524 | } |
|
- | 1525 | ss_assign = (union asic_ss_assignment *) |
|
1489 | } |
1526 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT)); |
1490 | } |
1527 | } |
1491 | break; |
1528 | break; |
1492 | case 2: |
1529 | case 2: |
1493 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1530 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
- | 1531 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); |
|
1494 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); |
1532 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]); |
1495 | for (i = 0; i < num_indices; i++) { |
1533 | for (i = 0; i < num_indices; i++) { |
1496 | if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && |
1534 | if ((ss_assign->v2.ucClockIndication == id) && |
1497 | (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { |
1535 | (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) { |
1498 | ss->percentage = |
1536 | ss->percentage = |
1499 | le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
1537 | le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage); |
1500 | ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
1538 | ss->type = ss_assign->v2.ucSpreadSpectrumMode; |
- | 1539 | ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz); |
|
- | 1540 | ss->percentage_divider = 100; |
|
- | 1541 | if ((crev == 2) && |
|
- | 1542 | ((id == ASIC_INTERNAL_ENGINE_SS) || |
|
- | 1543 | (id == ASIC_INTERNAL_MEMORY_SS))) |
|
1501 | ss->rate = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz); |
1544 | ss->rate /= 100; |
1502 | return true; |
1545 | return true; |
- | 1546 | } |
|
- | 1547 | ss_assign = (union asic_ss_assignment *) |
|
1503 | } |
1548 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2)); |
1504 | } |
1549 | } |
1505 | break; |
1550 | break; |
1506 | case 3: |
1551 | case 3: |
1507 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1552 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
- | 1553 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); |
|
1508 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); |
1554 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]); |
1509 | for (i = 0; i < num_indices; i++) { |
1555 | for (i = 0; i < num_indices; i++) { |
1510 | if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && |
1556 | if ((ss_assign->v3.ucClockIndication == id) && |
1511 | (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { |
1557 | (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) { |
1512 | ss->percentage = |
1558 | ss->percentage = |
1513 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
1559 | le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage); |
1514 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
1560 | ss->type = ss_assign->v3.ucSpreadSpectrumMode; |
- | 1561 | ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz); |
|
- | 1562 | if (ss_assign->v3.ucSpreadSpectrumMode & |
|
- | 1563 | SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK) |
|
- | 1564 | ss->percentage_divider = 1000; |
|
- | 1565 | else |
|
- | 1566 | ss->percentage_divider = 100; |
|
- | 1567 | if ((id == ASIC_INTERNAL_ENGINE_SS) || |
|
- | 1568 | (id == ASIC_INTERNAL_MEMORY_SS)) |
|
1515 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); |
1569 | ss->rate /= 100; |
1516 | if (rdev->flags & RADEON_IS_IGP) |
1570 | if (rdev->flags & RADEON_IS_IGP) |
1517 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); |
1571 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); |
1518 | return true; |
1572 | return true; |
- | 1573 | } |
|
- | 1574 | ss_assign = (union asic_ss_assignment *) |
|
1519 | } |
1575 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3)); |
1520 | } |
1576 | } |
1521 | break; |
1577 | break; |
1522 | default: |
1578 | default: |
1523 | DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev); |
1579 | DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev); |
Line 1649... | Line 1705... | ||
1649 | rdev->mode_info.bios_hardcoded_edid_size = edid_size; |
1705 | rdev->mode_info.bios_hardcoded_edid_size = edid_size; |
1650 | } else |
1706 | } else |
1651 | kfree(edid); |
1707 | kfree(edid); |
1652 | } |
1708 | } |
1653 | } |
1709 | } |
- | 1710 | record += fake_edid_record->ucFakeEDIDLength ? |
|
- | 1711 | fake_edid_record->ucFakeEDIDLength + 2 : |
|
1654 | record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); |
1712 | sizeof(ATOM_FAKE_EDID_PATCH_RECORD); |
1655 | break; |
1713 | break; |
1656 | case LCD_PANEL_RESOLUTION_RECORD_TYPE: |
1714 | case LCD_PANEL_RESOLUTION_RECORD_TYPE: |
1657 | panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; |
1715 | panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; |
1658 | lvds->native_mode.width_mm = panel_res_record->usHSize; |
1716 | lvds->native_mode.width_mm = panel_res_record->usHSize; |
1659 | lvds->native_mode.height_mm = panel_res_record->usVSize; |
1717 | lvds->native_mode.height_mm = panel_res_record->usVSize; |
Line 1747... | Line 1805... | ||
1747 | if (misc & ATOM_INTERLACE) |
1805 | if (misc & ATOM_INTERLACE) |
1748 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
1806 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
1749 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
1807 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
1750 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
1808 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
Line -... | Line 1809... | ||
- | 1809 | ||
1751 | 1810 | mode->crtc_clock = mode->clock = |
|
Line 1752... | Line 1811... | ||
1752 | mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; |
1811 | le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; |
1753 | 1812 | ||
1754 | if (index == 1) { |
1813 | if (index == 1) { |
1755 | /* PAL timings appear to have wrong values for totals */ |
1814 | /* PAL timings appear to have wrong values for totals */ |
Line 1790... | Line 1849... | ||
1790 | if (misc & ATOM_INTERLACE) |
1849 | if (misc & ATOM_INTERLACE) |
1791 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
1850 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
1792 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
1851 | if (misc & ATOM_DOUBLE_CLOCK_MODE) |
1793 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
1852 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
Line -... | Line 1853... | ||
- | 1853 | ||
1794 | 1854 | mode->crtc_clock = mode->clock = |
|
1795 | mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; |
1855 | le16_to_cpu(dtd_timings->usPixClk) * 10; |
1796 | break; |
1856 | break; |
1797 | } |
1857 | } |
1798 | return true; |
1858 | return true; |
Line 1901... | Line 1961... | ||
1901 | "NONE", |
1961 | "NONE", |
1902 | "lm63", |
1962 | "lm63", |
1903 | "adm1032", |
1963 | "adm1032", |
1904 | "adm1030", |
1964 | "adm1030", |
1905 | "max6649", |
1965 | "max6649", |
1906 | "lm64", |
1966 | "lm63", /* lm64 */ |
1907 | "f75375", |
1967 | "f75375", |
1908 | "asc7xxx", |
1968 | "asc7xxx", |
1909 | }; |
1969 | }; |
Line 1910... | Line 1970... | ||
1910 | 1970 | ||
1911 | static const char *pp_lib_thermal_controller_names[] = { |
1971 | static const char *pp_lib_thermal_controller_names[] = { |
1912 | "NONE", |
1972 | "NONE", |
1913 | "lm63", |
1973 | "lm63", |
1914 | "adm1032", |
1974 | "adm1032", |
1915 | "adm1030", |
1975 | "adm1030", |
1916 | "max6649", |
1976 | "max6649", |
1917 | "lm64", |
1977 | "lm63", /* lm64 */ |
1918 | "f75375", |
1978 | "f75375", |
1919 | "RV6xx", |
1979 | "RV6xx", |
1920 | "RV770", |
1980 | "RV770", |
1921 | "adt7473", |
1981 | "adt7473", |
Line 1925... | Line 1985... | ||
1925 | "emc2103", |
1985 | "emc2103", |
1926 | "Sumo", |
1986 | "Sumo", |
1927 | "Northern Islands", |
1987 | "Northern Islands", |
1928 | "Southern Islands", |
1988 | "Southern Islands", |
1929 | "lm96163", |
1989 | "lm96163", |
- | 1990 | "Sea Islands", |
|
1930 | }; |
1991 | }; |
Line 1931... | Line 1992... | ||
1931 | 1992 | ||
1932 | union power_info { |
1993 | union power_info { |
1933 | struct _ATOM_POWERPLAY_INFO info; |
1994 | struct _ATOM_POWERPLAY_INFO info; |
Line 1942... | Line 2003... | ||
1942 | struct _ATOM_PPLIB_R600_CLOCK_INFO r600; |
2003 | struct _ATOM_PPLIB_R600_CLOCK_INFO r600; |
1943 | struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; |
2004 | struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; |
1944 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; |
2005 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; |
1945 | struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; |
2006 | struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; |
1946 | struct _ATOM_PPLIB_SI_CLOCK_INFO si; |
2007 | struct _ATOM_PPLIB_SI_CLOCK_INFO si; |
- | 2008 | struct _ATOM_PPLIB_CI_CLOCK_INFO ci; |
|
1947 | }; |
2009 | }; |
Line 1948... | Line 2010... | ||
1948 | 2010 | ||
1949 | union pplib_power_state { |
2011 | union pplib_power_state { |
1950 | struct _ATOM_PPLIB_STATE v1; |
2012 | struct _ATOM_PPLIB_STATE v1; |
Line 2207... | Line 2269... | ||
2207 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) { |
2269 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) { |
2208 | DRM_INFO("Internal thermal controller %s fan control\n", |
2270 | DRM_INFO("Internal thermal controller %s fan control\n", |
2209 | (controller->ucFanParameters & |
2271 | (controller->ucFanParameters & |
2210 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2272 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2211 | rdev->pm.int_thermal_type = THERMAL_TYPE_SI; |
2273 | rdev->pm.int_thermal_type = THERMAL_TYPE_SI; |
- | 2274 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) { |
|
- | 2275 | DRM_INFO("Internal thermal controller %s fan control\n", |
|
- | 2276 | (controller->ucFanParameters & |
|
- | 2277 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
|
- | 2278 | rdev->pm.int_thermal_type = THERMAL_TYPE_CI; |
|
- | 2279 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) { |
|
- | 2280 | DRM_INFO("Internal thermal controller %s fan control\n", |
|
- | 2281 | (controller->ucFanParameters & |
|
- | 2282 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
|
- | 2283 | rdev->pm.int_thermal_type = THERMAL_TYPE_KV; |
|
2212 | } else if ((controller->ucType == |
2284 | } else if ((controller->ucType == |
2213 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || |
2285 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || |
2214 | (controller->ucType == |
2286 | (controller->ucType == |
2215 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || |
2287 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || |
2216 | (controller->ucType == |
2288 | (controller->ucType == |
Line 2239... | Line 2311... | ||
2239 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2311 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2240 | } |
2312 | } |
2241 | } |
2313 | } |
2242 | } |
2314 | } |
Line 2243... | Line 2315... | ||
2243 | 2315 | ||
2244 | static void radeon_atombios_get_default_voltages(struct radeon_device *rdev, |
2316 | void radeon_atombios_get_default_voltages(struct radeon_device *rdev, |
2245 | u16 *vddc, u16 *vddci) |
2317 | u16 *vddc, u16 *vddci, u16 *mvdd) |
2246 | { |
2318 | { |
2247 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2319 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2248 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2320 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2249 | u8 frev, crev; |
2321 | u8 frev, crev; |
2250 | u16 data_offset; |
2322 | u16 data_offset; |
Line 2251... | Line 2323... | ||
2251 | union firmware_info *firmware_info; |
2323 | union firmware_info *firmware_info; |
2252 | 2324 | ||
- | 2325 | *vddc = 0; |
|
Line 2253... | Line 2326... | ||
2253 | *vddc = 0; |
2326 | *vddci = 0; |
2254 | *vddci = 0; |
2327 | *mvdd = 0; |
2255 | 2328 | ||
2256 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2329 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2257 | &frev, &crev, &data_offset)) { |
2330 | &frev, &crev, &data_offset)) { |
2258 | firmware_info = |
2331 | firmware_info = |
2259 | (union firmware_info *)(mode_info->atom_context->bios + |
2332 | (union firmware_info *)(mode_info->atom_context->bios + |
2260 | data_offset); |
2333 | data_offset); |
- | 2334 | *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); |
|
- | 2335 | if ((frev == 2) && (crev >= 2)) { |
|
2261 | *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); |
2336 | *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); |
2262 | if ((frev == 2) && (crev >= 2)) |
2337 | *mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage); |
Line 2263... | Line 2338... | ||
2263 | *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); |
2338 | } |
2264 | } |
2339 | } |
2265 | } |
2340 | } |
2266 | 2341 | ||
2267 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
2342 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
2268 | int state_index, int mode_index, |
2343 | int state_index, int mode_index, |
2269 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) |
2344 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) |
2270 | { |
2345 | { |
Line 2271... | Line 2346... | ||
2271 | int j; |
2346 | int j; |
Line 2272... | Line 2347... | ||
2272 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2347 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2273 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2348 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2274 | u16 vddc, vddci; |
2349 | u16 vddc, vddci, mvdd; |
2275 | 2350 | ||
Line 2314... | Line 2389... | ||
2314 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
2389 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
2315 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
2390 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
2316 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; |
2391 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; |
2317 | rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; |
2392 | rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; |
2318 | } else { |
2393 | } else { |
- | 2394 | u16 max_vddci = 0; |
|
- | 2395 | ||
- | 2396 | if (ASIC_IS_DCE4(rdev)) |
|
- | 2397 | radeon_atom_get_max_voltage(rdev, |
|
- | 2398 | SET_VOLTAGE_TYPE_ASIC_VDDCI, |
|
- | 2399 | &max_vddci); |
|
2319 | /* patch the table values with the default slck/mclk from firmware info */ |
2400 | /* patch the table values with the default sclk/mclk from firmware info */ |
2320 | for (j = 0; j < mode_index; j++) { |
2401 | for (j = 0; j < mode_index; j++) { |
2321 | rdev->pm.power_state[state_index].clock_info[j].mclk = |
2402 | rdev->pm.power_state[state_index].clock_info[j].mclk = |
2322 | rdev->clock.default_mclk; |
2403 | rdev->clock.default_mclk; |
2323 | rdev->pm.power_state[state_index].clock_info[j].sclk = |
2404 | rdev->pm.power_state[state_index].clock_info[j].sclk = |
2324 | rdev->clock.default_sclk; |
2405 | rdev->clock.default_sclk; |
2325 | if (vddc) |
2406 | if (vddc) |
2326 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = |
2407 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = |
2327 | vddc; |
2408 | vddc; |
- | 2409 | if (max_vddci) |
|
- | 2410 | rdev->pm.power_state[state_index].clock_info[j].voltage.vddci = |
|
- | 2411 | max_vddci; |
|
2328 | } |
2412 | } |
2329 | } |
2413 | } |
2330 | } |
2414 | } |
2331 | } |
2415 | } |
Line 2345... | Line 2429... | ||
2345 | } else { |
2429 | } else { |
2346 | sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); |
2430 | sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); |
2347 | sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; |
2431 | sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; |
2348 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2432 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2349 | } |
2433 | } |
- | 2434 | } else if (rdev->family >= CHIP_BONAIRE) { |
|
- | 2435 | sclk = le16_to_cpu(clock_info->ci.usEngineClockLow); |
|
- | 2436 | sclk |= clock_info->ci.ucEngineClockHigh << 16; |
|
- | 2437 | mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow); |
|
- | 2438 | mclk |= clock_info->ci.ucMemoryClockHigh << 16; |
|
- | 2439 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; |
|
- | 2440 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
|
- | 2441 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
|
- | 2442 | VOLTAGE_NONE; |
|
2350 | } else if (rdev->family >= CHIP_TAHITI) { |
2443 | } else if (rdev->family >= CHIP_TAHITI) { |
2351 | sclk = le16_to_cpu(clock_info->si.usEngineClockLow); |
2444 | sclk = le16_to_cpu(clock_info->si.usEngineClockLow); |
2352 | sclk |= clock_info->si.ucEngineClockHigh << 16; |
2445 | sclk |= clock_info->si.ucEngineClockHigh << 16; |
2353 | mclk = le16_to_cpu(clock_info->si.usMemoryClockLow); |
2446 | mclk = le16_to_cpu(clock_info->si.usMemoryClockLow); |
2354 | mclk |= clock_info->si.ucMemoryClockHigh << 16; |
2447 | mclk |= clock_info->si.ucMemoryClockHigh << 16; |
Line 2390... | Line 2483... | ||
2390 | switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) { |
2483 | switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) { |
2391 | case ATOM_VIRTUAL_VOLTAGE_ID0: |
2484 | case ATOM_VIRTUAL_VOLTAGE_ID0: |
2392 | case ATOM_VIRTUAL_VOLTAGE_ID1: |
2485 | case ATOM_VIRTUAL_VOLTAGE_ID1: |
2393 | case ATOM_VIRTUAL_VOLTAGE_ID2: |
2486 | case ATOM_VIRTUAL_VOLTAGE_ID2: |
2394 | case ATOM_VIRTUAL_VOLTAGE_ID3: |
2487 | case ATOM_VIRTUAL_VOLTAGE_ID3: |
- | 2488 | case ATOM_VIRTUAL_VOLTAGE_ID4: |
|
- | 2489 | case ATOM_VIRTUAL_VOLTAGE_ID5: |
|
- | 2490 | case ATOM_VIRTUAL_VOLTAGE_ID6: |
|
- | 2491 | case ATOM_VIRTUAL_VOLTAGE_ID7: |
|
2395 | if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, |
2492 | if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, |
2396 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage, |
2493 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage, |
2397 | &vddc) == 0) |
2494 | &vddc) == 0) |
2398 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; |
2495 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; |
2399 | break; |
2496 | break; |
Line 2665... | Line 2762... | ||
2665 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1; |
2762 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS v1; |
2666 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2; |
2763 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 v2; |
2667 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3; |
2764 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3; |
2668 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4; |
2765 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4; |
2669 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5; |
2766 | struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5; |
- | 2767 | struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in; |
|
- | 2768 | struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out; |
|
2670 | }; |
2769 | }; |
Line 2671... | Line 2770... | ||
2671 | 2770 | ||
2672 | int radeon_atom_get_clock_dividers(struct radeon_device *rdev, |
2771 | int radeon_atom_get_clock_dividers(struct radeon_device *rdev, |
2673 | u8 clock_type, |
2772 | u8 clock_type, |
Line 2697... | Line 2796... | ||
2697 | dividers->fb_div = args.v1.ucFbDiv; |
2796 | dividers->fb_div = args.v1.ucFbDiv; |
2698 | dividers->enable_post_div = true; |
2797 | dividers->enable_post_div = true; |
2699 | break; |
2798 | break; |
2700 | case 2: |
2799 | case 2: |
2701 | case 3: |
2800 | case 3: |
- | 2801 | case 5: |
|
2702 | /* r6xx, r7xx, evergreen, ni */ |
2802 | /* r6xx, r7xx, evergreen, ni, si */ |
2703 | if (rdev->family <= CHIP_RV770) { |
2803 | if (rdev->family <= CHIP_RV770) { |
2704 | args.v2.ucAction = clock_type; |
2804 | args.v2.ucAction = clock_type; |
2705 | args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */ |
2805 | args.v2.ulClock = cpu_to_le32(clock); /* 10 khz */ |
Line 2706... | Line 2806... | ||
2706 | 2806 | ||
Line 2724... | Line 2824... | ||
2724 | dividers->post_div = args.v3.ucPostDiv; |
2824 | dividers->post_div = args.v3.ucPostDiv; |
2725 | dividers->enable_post_div = (args.v3.ucCntlFlag & |
2825 | dividers->enable_post_div = (args.v3.ucCntlFlag & |
2726 | ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false; |
2826 | ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false; |
2727 | dividers->enable_dithen = (args.v3.ucCntlFlag & |
2827 | dividers->enable_dithen = (args.v3.ucCntlFlag & |
2728 | ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true; |
2828 | ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true; |
2729 | dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); |
2829 | dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); |
2730 | dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac); |
2830 | dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac); |
2731 | dividers->ref_div = args.v3.ucRefDiv; |
2831 | dividers->ref_div = args.v3.ucRefDiv; |
2732 | dividers->vco_mode = (args.v3.ucCntlFlag & |
2832 | dividers->vco_mode = (args.v3.ucCntlFlag & |
2733 | ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0; |
2833 | ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0; |
2734 | } else { |
2834 | } else { |
- | 2835 | /* for SI we use ComputeMemoryClockParam for memory plls */ |
|
- | 2836 | if (rdev->family >= CHIP_TAHITI) |
|
- | 2837 | return -EINVAL; |
|
2735 | args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock); |
2838 | args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock); |
2736 | if (strobe_mode) |
2839 | if (strobe_mode) |
2737 | args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN; |
2840 | args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN; |
Line 2738... | Line 2841... | ||
2738 | 2841 | ||
Line 2755... | Line 2858... | ||
2755 | /* fusion */ |
2858 | /* fusion */ |
2756 | args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */ |
2859 | args.v4.ulClock = cpu_to_le32(clock); /* 10 khz */ |
Line 2757... | Line 2860... | ||
2757 | 2860 | ||
Line 2758... | Line 2861... | ||
2758 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
2861 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
2759 | 2862 | ||
2760 | dividers->post_div = args.v4.ucPostDiv; |
2863 | dividers->post_divider = dividers->post_div = args.v4.ucPostDiv; |
- | 2864 | dividers->real_clock = le32_to_cpu(args.v4.ulClock); |
|
- | 2865 | break; |
|
- | 2866 | case 6: |
|
- | 2867 | /* CI */ |
|
- | 2868 | /* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */ |
|
- | 2869 | args.v6_in.ulClock.ulComputeClockFlag = clock_type; |
|
- | 2870 | args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock); /* 10 khz */ |
|
- | 2871 | ||
- | 2872 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 2873 | ||
- | 2874 | dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv); |
|
- | 2875 | dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac); |
|
- | 2876 | dividers->ref_div = args.v6_out.ucPllRefDiv; |
|
- | 2877 | dividers->post_div = args.v6_out.ucPllPostDiv; |
|
- | 2878 | dividers->flags = args.v6_out.ucPllCntlFlag; |
|
- | 2879 | dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock); |
|
- | 2880 | dividers->post_divider = args.v6_out.ulClock.ucPostDiv; |
|
- | 2881 | break; |
|
- | 2882 | default: |
|
- | 2883 | return -EINVAL; |
|
- | 2884 | } |
|
- | 2885 | return 0; |
|
- | 2886 | } |
|
- | 2887 | ||
- | 2888 | int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev, |
|
- | 2889 | u32 clock, |
|
- | 2890 | bool strobe_mode, |
|
- | 2891 | struct atom_mpll_param *mpll_param) |
|
- | 2892 | { |
|
- | 2893 | COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args; |
|
- | 2894 | int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam); |
|
- | 2895 | u8 frev, crev; |
|
- | 2896 | ||
- | 2897 | memset(&args, 0, sizeof(args)); |
|
- | 2898 | memset(mpll_param, 0, sizeof(struct atom_mpll_param)); |
|
- | 2899 | ||
- | 2900 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
|
- | 2901 | return -EINVAL; |
|
- | 2902 | ||
- | 2903 | switch (frev) { |
|
- | 2904 | case 2: |
|
- | 2905 | switch (crev) { |
|
- | 2906 | case 1: |
|
- | 2907 | /* SI */ |
|
- | 2908 | args.ulClock = cpu_to_le32(clock); /* 10 khz */ |
|
- | 2909 | args.ucInputFlag = 0; |
|
- | 2910 | if (strobe_mode) |
|
- | 2911 | args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN; |
|
- | 2912 | ||
- | 2913 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 2914 | ||
- | 2915 | mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac); |
|
- | 2916 | mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv); |
|
- | 2917 | mpll_param->post_div = args.ucPostDiv; |
|
- | 2918 | mpll_param->dll_speed = args.ucDllSpeed; |
|
- | 2919 | mpll_param->bwcntl = args.ucBWCntl; |
|
- | 2920 | mpll_param->vco_mode = |
|
- | 2921 | (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK); |
|
- | 2922 | mpll_param->yclk_sel = |
|
- | 2923 | (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0; |
|
- | 2924 | mpll_param->qdr = |
|
- | 2925 | (args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0; |
|
- | 2926 | mpll_param->half_rate = |
|
- | 2927 | (args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0; |
|
- | 2928 | break; |
|
- | 2929 | default: |
|
- | 2930 | return -EINVAL; |
|
2761 | dividers->real_clock = le32_to_cpu(args.v4.ulClock); |
2931 | } |
2762 | break; |
2932 | break; |
2763 | default: |
2933 | default: |
2764 | return -EINVAL; |
2934 | return -EINVAL; |
2765 | } |
2935 | } |
Line 2817... | Line 2987... | ||
2817 | args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ |
2987 | args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ |
Line 2818... | Line 2988... | ||
2818 | 2988 | ||
2819 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
2989 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line -... | Line 2990... | ||
- | 2990 | } |
|
- | 2991 | ||
- | 2992 | void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev, |
|
- | 2993 | u32 eng_clock, u32 mem_clock) |
|
- | 2994 | { |
|
- | 2995 | SET_ENGINE_CLOCK_PS_ALLOCATION args; |
|
- | 2996 | int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings); |
|
- | 2997 | u32 tmp; |
|
- | 2998 | ||
- | 2999 | memset(&args, 0, sizeof(args)); |
|
- | 3000 | ||
- | 3001 | tmp = eng_clock & SET_CLOCK_FREQ_MASK; |
|
- | 3002 | tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24); |
|
- | 3003 | ||
- | 3004 | args.ulTargetEngineClock = cpu_to_le32(tmp); |
|
- | 3005 | if (mem_clock) |
|
- | 3006 | args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK); |
|
- | 3007 | ||
- | 3008 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3009 | } |
|
- | 3010 | ||
- | 3011 | void radeon_atom_update_memory_dll(struct radeon_device *rdev, |
|
- | 3012 | u32 mem_clock) |
|
- | 3013 | { |
|
- | 3014 | u32 args; |
|
- | 3015 | int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings); |
|
- | 3016 | ||
- | 3017 | args = cpu_to_le32(mem_clock); /* 10 khz */ |
|
- | 3018 | ||
- | 3019 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3020 | } |
|
- | 3021 | ||
- | 3022 | void radeon_atom_set_ac_timing(struct radeon_device *rdev, |
|
- | 3023 | u32 mem_clock) |
|
- | 3024 | { |
|
- | 3025 | SET_MEMORY_CLOCK_PS_ALLOCATION args; |
|
- | 3026 | int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings); |
|
- | 3027 | u32 tmp = mem_clock | (COMPUTE_MEMORY_PLL_PARAM << 24); |
|
- | 3028 | ||
- | 3029 | args.ulTargetMemoryClock = cpu_to_le32(tmp); /* 10 khz */ |
|
- | 3030 | ||
- | 3031 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
2820 | } |
3032 | } |
2821 | 3033 | ||
2822 | union set_voltage { |
3034 | union set_voltage { |
2823 | struct _SET_VOLTAGE_PS_ALLOCATION alloc; |
3035 | struct _SET_VOLTAGE_PS_ALLOCATION alloc; |
2824 | struct _SET_VOLTAGE_PARAMETERS v1; |
3036 | struct _SET_VOLTAGE_PARAMETERS v1; |
Line 2861... | Line 3073... | ||
2861 | } |
3073 | } |
Line 2862... | Line 3074... | ||
2862 | 3074 | ||
2863 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
3075 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line 2864... | Line 3076... | ||
2864 | } |
3076 | } |
2865 | 3077 | ||
2866 | static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, |
3078 | int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, |
2867 | u16 voltage_id, u16 *voltage) |
3079 | u16 voltage_id, u16 *voltage) |
2868 | { |
3080 | { |
2869 | union set_voltage args; |
3081 | union set_voltage args; |
Line 2900... | Line 3112... | ||
2900 | } |
3112 | } |
Line 2901... | Line 3113... | ||
2901 | 3113 | ||
2902 | return 0; |
3114 | return 0; |
Line -... | Line 3115... | ||
- | 3115 | } |
|
- | 3116 | ||
- | 3117 | int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev, |
|
- | 3118 | u16 *voltage, |
|
- | 3119 | u16 leakage_idx) |
|
- | 3120 | { |
|
- | 3121 | return radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage); |
|
- | 3122 | } |
|
- | 3123 | ||
- | 3124 | int radeon_atom_get_leakage_id_from_vbios(struct radeon_device *rdev, |
|
- | 3125 | u16 *leakage_id) |
|
- | 3126 | { |
|
- | 3127 | union set_voltage args; |
|
- | 3128 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); |
|
- | 3129 | u8 frev, crev; |
|
- | 3130 | ||
- | 3131 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
|
- | 3132 | return -EINVAL; |
|
- | 3133 | ||
- | 3134 | switch (crev) { |
|
- | 3135 | case 3: |
|
- | 3136 | case 4: |
|
- | 3137 | args.v3.ucVoltageType = 0; |
|
- | 3138 | args.v3.ucVoltageMode = ATOM_GET_LEAKAGE_ID; |
|
- | 3139 | args.v3.usVoltageLevel = 0; |
|
- | 3140 | ||
- | 3141 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3142 | ||
- | 3143 | *leakage_id = le16_to_cpu(args.v3.usVoltageLevel); |
|
- | 3144 | break; |
|
- | 3145 | default: |
|
- | 3146 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3147 | return -EINVAL; |
|
- | 3148 | } |
|
- | 3149 | ||
- | 3150 | return 0; |
|
- | 3151 | } |
|
- | 3152 | ||
- | 3153 | int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *rdev, |
|
- | 3154 | u16 *vddc, u16 *vddci, |
|
- | 3155 | u16 virtual_voltage_id, |
|
- | 3156 | u16 vbios_voltage_id) |
|
- | 3157 | { |
|
- | 3158 | int index = GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo); |
|
- | 3159 | u8 frev, crev; |
|
- | 3160 | u16 data_offset, size; |
|
- | 3161 | int i, j; |
|
- | 3162 | ATOM_ASIC_PROFILING_INFO_V2_1 *profile; |
|
- | 3163 | u16 *leakage_bin, *vddc_id_buf, *vddc_buf, *vddci_id_buf, *vddci_buf; |
|
- | 3164 | ||
- | 3165 | *vddc = 0; |
|
- | 3166 | *vddci = 0; |
|
- | 3167 | ||
- | 3168 | if (!atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3169 | &frev, &crev, &data_offset)) |
|
- | 3170 | return -EINVAL; |
|
- | 3171 | ||
- | 3172 | profile = (ATOM_ASIC_PROFILING_INFO_V2_1 *) |
|
- | 3173 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3174 | ||
- | 3175 | switch (frev) { |
|
- | 3176 | case 1: |
|
- | 3177 | return -EINVAL; |
|
- | 3178 | case 2: |
|
- | 3179 | switch (crev) { |
|
- | 3180 | case 1: |
|
- | 3181 | if (size < sizeof(ATOM_ASIC_PROFILING_INFO_V2_1)) |
|
- | 3182 | return -EINVAL; |
|
- | 3183 | leakage_bin = (u16 *) |
|
- | 3184 | (rdev->mode_info.atom_context->bios + data_offset + |
|
- | 3185 | le16_to_cpu(profile->usLeakageBinArrayOffset)); |
|
- | 3186 | vddc_id_buf = (u16 *) |
|
- | 3187 | (rdev->mode_info.atom_context->bios + data_offset + |
|
- | 3188 | le16_to_cpu(profile->usElbVDDC_IdArrayOffset)); |
|
- | 3189 | vddc_buf = (u16 *) |
|
- | 3190 | (rdev->mode_info.atom_context->bios + data_offset + |
|
- | 3191 | le16_to_cpu(profile->usElbVDDC_LevelArrayOffset)); |
|
- | 3192 | vddci_id_buf = (u16 *) |
|
- | 3193 | (rdev->mode_info.atom_context->bios + data_offset + |
|
- | 3194 | le16_to_cpu(profile->usElbVDDCI_IdArrayOffset)); |
|
- | 3195 | vddci_buf = (u16 *) |
|
- | 3196 | (rdev->mode_info.atom_context->bios + data_offset + |
|
- | 3197 | le16_to_cpu(profile->usElbVDDCI_LevelArrayOffset)); |
|
- | 3198 | ||
- | 3199 | if (profile->ucElbVDDC_Num > 0) { |
|
- | 3200 | for (i = 0; i < profile->ucElbVDDC_Num; i++) { |
|
- | 3201 | if (vddc_id_buf[i] == virtual_voltage_id) { |
|
- | 3202 | for (j = 0; j < profile->ucLeakageBinNum; j++) { |
|
- | 3203 | if (vbios_voltage_id <= leakage_bin[j]) { |
|
- | 3204 | *vddc = vddc_buf[j * profile->ucElbVDDC_Num + i]; |
|
- | 3205 | break; |
|
- | 3206 | } |
|
- | 3207 | } |
|
- | 3208 | break; |
|
- | 3209 | } |
|
- | 3210 | } |
|
- | 3211 | } |
|
- | 3212 | if (profile->ucElbVDDCI_Num > 0) { |
|
- | 3213 | for (i = 0; i < profile->ucElbVDDCI_Num; i++) { |
|
- | 3214 | if (vddci_id_buf[i] == virtual_voltage_id) { |
|
- | 3215 | for (j = 0; j < profile->ucLeakageBinNum; j++) { |
|
- | 3216 | if (vbios_voltage_id <= leakage_bin[j]) { |
|
- | 3217 | *vddci = vddci_buf[j * profile->ucElbVDDCI_Num + i]; |
|
- | 3218 | break; |
|
- | 3219 | } |
|
- | 3220 | } |
|
- | 3221 | break; |
|
- | 3222 | } |
|
- | 3223 | } |
|
- | 3224 | } |
|
- | 3225 | break; |
|
- | 3226 | default: |
|
- | 3227 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3228 | return -EINVAL; |
|
- | 3229 | } |
|
- | 3230 | break; |
|
- | 3231 | default: |
|
- | 3232 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3233 | return -EINVAL; |
|
- | 3234 | } |
|
- | 3235 | ||
- | 3236 | return 0; |
|
- | 3237 | } |
|
- | 3238 | ||
- | 3239 | union get_voltage_info { |
|
- | 3240 | struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in; |
|
- | 3241 | struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out; |
|
- | 3242 | }; |
|
- | 3243 | ||
- | 3244 | int radeon_atom_get_voltage_evv(struct radeon_device *rdev, |
|
- | 3245 | u16 virtual_voltage_id, |
|
- | 3246 | u16 *voltage) |
|
- | 3247 | { |
|
- | 3248 | int index = GetIndexIntoMasterTable(COMMAND, GetVoltageInfo); |
|
- | 3249 | u32 entry_id; |
|
- | 3250 | u32 count = rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; |
|
- | 3251 | union get_voltage_info args; |
|
- | 3252 | ||
- | 3253 | for (entry_id = 0; entry_id < count; entry_id++) { |
|
- | 3254 | if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].v == |
|
- | 3255 | virtual_voltage_id) |
|
- | 3256 | break; |
|
- | 3257 | } |
|
- | 3258 | ||
- | 3259 | if (entry_id >= count) |
|
- | 3260 | return -EINVAL; |
|
- | 3261 | ||
- | 3262 | args.in.ucVoltageType = VOLTAGE_TYPE_VDDC; |
|
- | 3263 | args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE; |
|
- | 3264 | args.in.ulSCLKFreq = |
|
- | 3265 | cpu_to_le32(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk); |
|
- | 3266 | ||
- | 3267 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3268 | ||
- | 3269 | *voltage = le16_to_cpu(args.evv_out.usVoltageLevel); |
|
- | 3270 | ||
- | 3271 | return 0; |
|
- | 3272 | } |
|
- | 3273 | ||
- | 3274 | int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev, |
|
- | 3275 | u16 voltage_level, u8 voltage_type, |
|
- | 3276 | u32 *gpio_value, u32 *gpio_mask) |
|
- | 3277 | { |
|
- | 3278 | union set_voltage args; |
|
- | 3279 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); |
|
- | 3280 | u8 frev, crev; |
|
- | 3281 | ||
- | 3282 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
|
- | 3283 | return -EINVAL; |
|
- | 3284 | ||
- | 3285 | switch (crev) { |
|
- | 3286 | case 1: |
|
- | 3287 | return -EINVAL; |
|
- | 3288 | case 2: |
|
- | 3289 | args.v2.ucVoltageType = voltage_type; |
|
- | 3290 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK; |
|
- | 3291 | args.v2.usVoltageLevel = cpu_to_le16(voltage_level); |
|
- | 3292 | ||
- | 3293 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3294 | ||
- | 3295 | *gpio_mask = le32_to_cpu(*(u32 *)&args.v2); |
|
- | 3296 | ||
- | 3297 | args.v2.ucVoltageType = voltage_type; |
|
- | 3298 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL; |
|
- | 3299 | args.v2.usVoltageLevel = cpu_to_le16(voltage_level); |
|
- | 3300 | ||
- | 3301 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 3302 | ||
- | 3303 | *gpio_value = le32_to_cpu(*(u32 *)&args.v2); |
|
- | 3304 | break; |
|
- | 3305 | default: |
|
- | 3306 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3307 | return -EINVAL; |
|
- | 3308 | } |
|
- | 3309 | ||
- | 3310 | return 0; |
|
- | 3311 | } |
|
- | 3312 | ||
- | 3313 | union voltage_object_info { |
|
- | 3314 | struct _ATOM_VOLTAGE_OBJECT_INFO v1; |
|
- | 3315 | struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2; |
|
- | 3316 | struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3; |
|
- | 3317 | }; |
|
- | 3318 | ||
- | 3319 | union voltage_object { |
|
- | 3320 | struct _ATOM_VOLTAGE_OBJECT v1; |
|
- | 3321 | struct _ATOM_VOLTAGE_OBJECT_V2 v2; |
|
- | 3322 | union _ATOM_VOLTAGE_OBJECT_V3 v3; |
|
- | 3323 | }; |
|
- | 3324 | ||
- | 3325 | static ATOM_VOLTAGE_OBJECT *atom_lookup_voltage_object_v1(ATOM_VOLTAGE_OBJECT_INFO *v1, |
|
- | 3326 | u8 voltage_type) |
|
- | 3327 | { |
|
- | 3328 | u32 size = le16_to_cpu(v1->sHeader.usStructureSize); |
|
- | 3329 | u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO, asVoltageObj[0]); |
|
- | 3330 | u8 *start = (u8 *)v1; |
|
- | 3331 | ||
- | 3332 | while (offset < size) { |
|
- | 3333 | ATOM_VOLTAGE_OBJECT *vo = (ATOM_VOLTAGE_OBJECT *)(start + offset); |
|
- | 3334 | if (vo->ucVoltageType == voltage_type) |
|
- | 3335 | return vo; |
|
- | 3336 | offset += offsetof(ATOM_VOLTAGE_OBJECT, asFormula.ucVIDAdjustEntries) + |
|
- | 3337 | vo->asFormula.ucNumOfVoltageEntries; |
|
- | 3338 | } |
|
- | 3339 | return NULL; |
|
- | 3340 | } |
|
- | 3341 | ||
- | 3342 | static ATOM_VOLTAGE_OBJECT_V2 *atom_lookup_voltage_object_v2(ATOM_VOLTAGE_OBJECT_INFO_V2 *v2, |
|
- | 3343 | u8 voltage_type) |
|
- | 3344 | { |
|
- | 3345 | u32 size = le16_to_cpu(v2->sHeader.usStructureSize); |
|
- | 3346 | u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V2, asVoltageObj[0]); |
|
- | 3347 | u8 *start = (u8*)v2; |
|
- | 3348 | ||
- | 3349 | while (offset < size) { |
|
- | 3350 | ATOM_VOLTAGE_OBJECT_V2 *vo = (ATOM_VOLTAGE_OBJECT_V2 *)(start + offset); |
|
- | 3351 | if (vo->ucVoltageType == voltage_type) |
|
- | 3352 | return vo; |
|
- | 3353 | offset += offsetof(ATOM_VOLTAGE_OBJECT_V2, asFormula.asVIDAdjustEntries) + |
|
- | 3354 | (vo->asFormula.ucNumOfVoltageEntries * sizeof(VOLTAGE_LUT_ENTRY)); |
|
- | 3355 | } |
|
- | 3356 | return NULL; |
|
- | 3357 | } |
|
- | 3358 | ||
- | 3359 | static ATOM_VOLTAGE_OBJECT_V3 *atom_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3, |
|
- | 3360 | u8 voltage_type, u8 voltage_mode) |
|
- | 3361 | { |
|
- | 3362 | u32 size = le16_to_cpu(v3->sHeader.usStructureSize); |
|
- | 3363 | u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]); |
|
- | 3364 | u8 *start = (u8*)v3; |
|
- | 3365 | ||
- | 3366 | while (offset < size) { |
|
- | 3367 | ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset); |
|
- | 3368 | if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) && |
|
- | 3369 | (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode)) |
|
- | 3370 | return vo; |
|
- | 3371 | offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize); |
|
- | 3372 | } |
|
- | 3373 | return NULL; |
|
- | 3374 | } |
|
- | 3375 | ||
- | 3376 | bool |
|
- | 3377 | radeon_atom_is_voltage_gpio(struct radeon_device *rdev, |
|
- | 3378 | u8 voltage_type, u8 voltage_mode) |
|
- | 3379 | { |
|
- | 3380 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3381 | u8 frev, crev; |
|
- | 3382 | u16 data_offset, size; |
|
- | 3383 | union voltage_object_info *voltage_info; |
|
- | 3384 | union voltage_object *voltage_object = NULL; |
|
- | 3385 | ||
- | 3386 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3387 | &frev, &crev, &data_offset)) { |
|
- | 3388 | voltage_info = (union voltage_object_info *) |
|
- | 3389 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3390 | ||
- | 3391 | switch (frev) { |
|
- | 3392 | case 1: |
|
- | 3393 | case 2: |
|
- | 3394 | switch (crev) { |
|
- | 3395 | case 1: |
|
- | 3396 | voltage_object = (union voltage_object *) |
|
- | 3397 | atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type); |
|
- | 3398 | if (voltage_object && |
|
- | 3399 | (voltage_object->v1.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO)) |
|
- | 3400 | return true; |
|
- | 3401 | break; |
|
- | 3402 | case 2: |
|
- | 3403 | voltage_object = (union voltage_object *) |
|
- | 3404 | atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type); |
|
- | 3405 | if (voltage_object && |
|
- | 3406 | (voltage_object->v2.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO)) |
|
- | 3407 | return true; |
|
- | 3408 | break; |
|
- | 3409 | default: |
|
- | 3410 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3411 | return false; |
|
- | 3412 | } |
|
- | 3413 | break; |
|
- | 3414 | case 3: |
|
- | 3415 | switch (crev) { |
|
- | 3416 | case 1: |
|
- | 3417 | if (atom_lookup_voltage_object_v3(&voltage_info->v3, |
|
- | 3418 | voltage_type, voltage_mode)) |
|
- | 3419 | return true; |
|
- | 3420 | break; |
|
- | 3421 | default: |
|
- | 3422 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3423 | return false; |
|
- | 3424 | } |
|
- | 3425 | break; |
|
- | 3426 | default: |
|
- | 3427 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3428 | return false; |
|
- | 3429 | } |
|
- | 3430 | ||
- | 3431 | } |
|
- | 3432 | return false; |
|
- | 3433 | } |
|
- | 3434 | ||
- | 3435 | int radeon_atom_get_svi2_info(struct radeon_device *rdev, |
|
- | 3436 | u8 voltage_type, |
|
- | 3437 | u8 *svd_gpio_id, u8 *svc_gpio_id) |
|
- | 3438 | { |
|
- | 3439 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3440 | u8 frev, crev; |
|
- | 3441 | u16 data_offset, size; |
|
- | 3442 | union voltage_object_info *voltage_info; |
|
- | 3443 | union voltage_object *voltage_object = NULL; |
|
- | 3444 | ||
- | 3445 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3446 | &frev, &crev, &data_offset)) { |
|
- | 3447 | voltage_info = (union voltage_object_info *) |
|
- | 3448 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3449 | ||
- | 3450 | switch (frev) { |
|
- | 3451 | case 3: |
|
- | 3452 | switch (crev) { |
|
- | 3453 | case 1: |
|
- | 3454 | voltage_object = (union voltage_object *) |
|
- | 3455 | atom_lookup_voltage_object_v3(&voltage_info->v3, |
|
- | 3456 | voltage_type, |
|
- | 3457 | VOLTAGE_OBJ_SVID2); |
|
- | 3458 | if (voltage_object) { |
|
- | 3459 | *svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId; |
|
- | 3460 | *svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId; |
|
- | 3461 | } else { |
|
- | 3462 | return -EINVAL; |
|
- | 3463 | } |
|
- | 3464 | break; |
|
- | 3465 | default: |
|
- | 3466 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3467 | return -EINVAL; |
|
- | 3468 | } |
|
- | 3469 | break; |
|
- | 3470 | default: |
|
- | 3471 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3472 | return -EINVAL; |
|
- | 3473 | } |
|
- | 3474 | ||
- | 3475 | } |
|
- | 3476 | return 0; |
|
- | 3477 | } |
|
- | 3478 | ||
- | 3479 | int radeon_atom_get_max_voltage(struct radeon_device *rdev, |
|
- | 3480 | u8 voltage_type, u16 *max_voltage) |
|
- | 3481 | { |
|
- | 3482 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3483 | u8 frev, crev; |
|
- | 3484 | u16 data_offset, size; |
|
- | 3485 | union voltage_object_info *voltage_info; |
|
- | 3486 | union voltage_object *voltage_object = NULL; |
|
- | 3487 | ||
- | 3488 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3489 | &frev, &crev, &data_offset)) { |
|
- | 3490 | voltage_info = (union voltage_object_info *) |
|
- | 3491 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3492 | ||
- | 3493 | switch (crev) { |
|
- | 3494 | case 1: |
|
- | 3495 | voltage_object = (union voltage_object *) |
|
- | 3496 | atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type); |
|
- | 3497 | if (voltage_object) { |
|
- | 3498 | ATOM_VOLTAGE_FORMULA *formula = |
|
- | 3499 | &voltage_object->v1.asFormula; |
|
- | 3500 | if (formula->ucFlag & 1) |
|
- | 3501 | *max_voltage = |
|
- | 3502 | le16_to_cpu(formula->usVoltageBaseLevel) + |
|
- | 3503 | formula->ucNumOfVoltageEntries / 2 * |
|
- | 3504 | le16_to_cpu(formula->usVoltageStep); |
|
- | 3505 | else |
|
- | 3506 | *max_voltage = |
|
- | 3507 | le16_to_cpu(formula->usVoltageBaseLevel) + |
|
- | 3508 | (formula->ucNumOfVoltageEntries - 1) * |
|
- | 3509 | le16_to_cpu(formula->usVoltageStep); |
|
- | 3510 | return 0; |
|
- | 3511 | } |
|
- | 3512 | break; |
|
- | 3513 | case 2: |
|
- | 3514 | voltage_object = (union voltage_object *) |
|
- | 3515 | atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type); |
|
- | 3516 | if (voltage_object) { |
|
- | 3517 | ATOM_VOLTAGE_FORMULA_V2 *formula = |
|
- | 3518 | &voltage_object->v2.asFormula; |
|
- | 3519 | if (formula->ucNumOfVoltageEntries) { |
|
- | 3520 | VOLTAGE_LUT_ENTRY *lut = (VOLTAGE_LUT_ENTRY *) |
|
- | 3521 | ((u8 *)&formula->asVIDAdjustEntries[0] + |
|
- | 3522 | (sizeof(VOLTAGE_LUT_ENTRY) * (formula->ucNumOfVoltageEntries - 1))); |
|
- | 3523 | *max_voltage = |
|
- | 3524 | le16_to_cpu(lut->usVoltageValue); |
|
- | 3525 | return 0; |
|
- | 3526 | } |
|
- | 3527 | } |
|
- | 3528 | break; |
|
- | 3529 | default: |
|
- | 3530 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3531 | return -EINVAL; |
|
- | 3532 | } |
|
- | 3533 | ||
- | 3534 | } |
|
- | 3535 | return -EINVAL; |
|
- | 3536 | } |
|
- | 3537 | ||
- | 3538 | int radeon_atom_get_min_voltage(struct radeon_device *rdev, |
|
- | 3539 | u8 voltage_type, u16 *min_voltage) |
|
- | 3540 | { |
|
- | 3541 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3542 | u8 frev, crev; |
|
- | 3543 | u16 data_offset, size; |
|
- | 3544 | union voltage_object_info *voltage_info; |
|
- | 3545 | union voltage_object *voltage_object = NULL; |
|
- | 3546 | ||
- | 3547 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3548 | &frev, &crev, &data_offset)) { |
|
- | 3549 | voltage_info = (union voltage_object_info *) |
|
- | 3550 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3551 | ||
- | 3552 | switch (crev) { |
|
- | 3553 | case 1: |
|
- | 3554 | voltage_object = (union voltage_object *) |
|
- | 3555 | atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type); |
|
- | 3556 | if (voltage_object) { |
|
- | 3557 | ATOM_VOLTAGE_FORMULA *formula = |
|
- | 3558 | &voltage_object->v1.asFormula; |
|
- | 3559 | *min_voltage = |
|
- | 3560 | le16_to_cpu(formula->usVoltageBaseLevel); |
|
- | 3561 | return 0; |
|
- | 3562 | } |
|
- | 3563 | break; |
|
- | 3564 | case 2: |
|
- | 3565 | voltage_object = (union voltage_object *) |
|
- | 3566 | atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type); |
|
- | 3567 | if (voltage_object) { |
|
- | 3568 | ATOM_VOLTAGE_FORMULA_V2 *formula = |
|
- | 3569 | &voltage_object->v2.asFormula; |
|
- | 3570 | if (formula->ucNumOfVoltageEntries) { |
|
- | 3571 | *min_voltage = |
|
- | 3572 | le16_to_cpu(formula->asVIDAdjustEntries[ |
|
- | 3573 | 0 |
|
- | 3574 | ].usVoltageValue); |
|
- | 3575 | return 0; |
|
- | 3576 | } |
|
- | 3577 | } |
|
- | 3578 | break; |
|
- | 3579 | default: |
|
- | 3580 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3581 | return -EINVAL; |
|
- | 3582 | } |
|
- | 3583 | ||
- | 3584 | } |
|
- | 3585 | return -EINVAL; |
|
- | 3586 | } |
|
- | 3587 | ||
- | 3588 | int radeon_atom_get_voltage_step(struct radeon_device *rdev, |
|
- | 3589 | u8 voltage_type, u16 *voltage_step) |
|
- | 3590 | { |
|
- | 3591 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3592 | u8 frev, crev; |
|
- | 3593 | u16 data_offset, size; |
|
- | 3594 | union voltage_object_info *voltage_info; |
|
- | 3595 | union voltage_object *voltage_object = NULL; |
|
- | 3596 | ||
- | 3597 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3598 | &frev, &crev, &data_offset)) { |
|
- | 3599 | voltage_info = (union voltage_object_info *) |
|
- | 3600 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3601 | ||
- | 3602 | switch (crev) { |
|
- | 3603 | case 1: |
|
- | 3604 | voltage_object = (union voltage_object *) |
|
- | 3605 | atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type); |
|
- | 3606 | if (voltage_object) { |
|
- | 3607 | ATOM_VOLTAGE_FORMULA *formula = |
|
- | 3608 | &voltage_object->v1.asFormula; |
|
- | 3609 | if (formula->ucFlag & 1) |
|
- | 3610 | *voltage_step = |
|
- | 3611 | (le16_to_cpu(formula->usVoltageStep) + 1) / 2; |
|
- | 3612 | else |
|
- | 3613 | *voltage_step = |
|
- | 3614 | le16_to_cpu(formula->usVoltageStep); |
|
- | 3615 | return 0; |
|
- | 3616 | } |
|
- | 3617 | break; |
|
- | 3618 | case 2: |
|
- | 3619 | return -EINVAL; |
|
- | 3620 | default: |
|
- | 3621 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3622 | return -EINVAL; |
|
- | 3623 | } |
|
- | 3624 | ||
- | 3625 | } |
|
- | 3626 | return -EINVAL; |
|
- | 3627 | } |
|
- | 3628 | ||
- | 3629 | int radeon_atom_round_to_true_voltage(struct radeon_device *rdev, |
|
- | 3630 | u8 voltage_type, |
|
- | 3631 | u16 nominal_voltage, |
|
- | 3632 | u16 *true_voltage) |
|
- | 3633 | { |
|
- | 3634 | u16 min_voltage, max_voltage, voltage_step; |
|
- | 3635 | ||
- | 3636 | if (radeon_atom_get_max_voltage(rdev, voltage_type, &max_voltage)) |
|
- | 3637 | return -EINVAL; |
|
- | 3638 | if (radeon_atom_get_min_voltage(rdev, voltage_type, &min_voltage)) |
|
- | 3639 | return -EINVAL; |
|
- | 3640 | if (radeon_atom_get_voltage_step(rdev, voltage_type, &voltage_step)) |
|
- | 3641 | return -EINVAL; |
|
- | 3642 | ||
- | 3643 | if (nominal_voltage <= min_voltage) |
|
- | 3644 | *true_voltage = min_voltage; |
|
- | 3645 | else if (nominal_voltage >= max_voltage) |
|
- | 3646 | *true_voltage = max_voltage; |
|
- | 3647 | else |
|
- | 3648 | *true_voltage = min_voltage + |
|
- | 3649 | ((nominal_voltage - min_voltage) / voltage_step) * |
|
- | 3650 | voltage_step; |
|
- | 3651 | ||
- | 3652 | return 0; |
|
- | 3653 | } |
|
- | 3654 | ||
- | 3655 | int radeon_atom_get_voltage_table(struct radeon_device *rdev, |
|
- | 3656 | u8 voltage_type, u8 voltage_mode, |
|
- | 3657 | struct atom_voltage_table *voltage_table) |
|
- | 3658 | { |
|
- | 3659 | int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo); |
|
- | 3660 | u8 frev, crev; |
|
- | 3661 | u16 data_offset, size; |
|
- | 3662 | int i, ret; |
|
- | 3663 | union voltage_object_info *voltage_info; |
|
- | 3664 | union voltage_object *voltage_object = NULL; |
|
- | 3665 | ||
- | 3666 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3667 | &frev, &crev, &data_offset)) { |
|
- | 3668 | voltage_info = (union voltage_object_info *) |
|
- | 3669 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3670 | ||
- | 3671 | switch (frev) { |
|
- | 3672 | case 1: |
|
- | 3673 | case 2: |
|
- | 3674 | switch (crev) { |
|
- | 3675 | case 1: |
|
- | 3676 | DRM_ERROR("old table version %d, %d\n", frev, crev); |
|
- | 3677 | return -EINVAL; |
|
- | 3678 | case 2: |
|
- | 3679 | voltage_object = (union voltage_object *) |
|
- | 3680 | atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type); |
|
- | 3681 | if (voltage_object) { |
|
- | 3682 | ATOM_VOLTAGE_FORMULA_V2 *formula = |
|
- | 3683 | &voltage_object->v2.asFormula; |
|
- | 3684 | VOLTAGE_LUT_ENTRY *lut; |
|
- | 3685 | if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES) |
|
- | 3686 | return -EINVAL; |
|
- | 3687 | lut = &formula->asVIDAdjustEntries[0]; |
|
- | 3688 | for (i = 0; i < formula->ucNumOfVoltageEntries; i++) { |
|
- | 3689 | voltage_table->entries[i].value = |
|
- | 3690 | le16_to_cpu(lut->usVoltageValue); |
|
- | 3691 | ret = radeon_atom_get_voltage_gpio_settings(rdev, |
|
- | 3692 | voltage_table->entries[i].value, |
|
- | 3693 | voltage_type, |
|
- | 3694 | &voltage_table->entries[i].smio_low, |
|
- | 3695 | &voltage_table->mask_low); |
|
- | 3696 | if (ret) |
|
- | 3697 | return ret; |
|
- | 3698 | lut = (VOLTAGE_LUT_ENTRY *) |
|
- | 3699 | ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY)); |
|
- | 3700 | } |
|
- | 3701 | voltage_table->count = formula->ucNumOfVoltageEntries; |
|
- | 3702 | return 0; |
|
- | 3703 | } |
|
- | 3704 | break; |
|
- | 3705 | default: |
|
- | 3706 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3707 | return -EINVAL; |
|
- | 3708 | } |
|
- | 3709 | break; |
|
- | 3710 | case 3: |
|
- | 3711 | switch (crev) { |
|
- | 3712 | case 1: |
|
- | 3713 | voltage_object = (union voltage_object *) |
|
- | 3714 | atom_lookup_voltage_object_v3(&voltage_info->v3, |
|
- | 3715 | voltage_type, voltage_mode); |
|
- | 3716 | if (voltage_object) { |
|
- | 3717 | ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio = |
|
- | 3718 | &voltage_object->v3.asGpioVoltageObj; |
|
- | 3719 | VOLTAGE_LUT_ENTRY_V2 *lut; |
|
- | 3720 | if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES) |
|
- | 3721 | return -EINVAL; |
|
- | 3722 | lut = &gpio->asVolGpioLut[0]; |
|
- | 3723 | for (i = 0; i < gpio->ucGpioEntryNum; i++) { |
|
- | 3724 | voltage_table->entries[i].value = |
|
- | 3725 | le16_to_cpu(lut->usVoltageValue); |
|
- | 3726 | voltage_table->entries[i].smio_low = |
|
- | 3727 | le32_to_cpu(lut->ulVoltageId); |
|
- | 3728 | lut = (VOLTAGE_LUT_ENTRY_V2 *) |
|
- | 3729 | ((u8 *)lut + sizeof(VOLTAGE_LUT_ENTRY_V2)); |
|
- | 3730 | } |
|
- | 3731 | voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal); |
|
- | 3732 | voltage_table->count = gpio->ucGpioEntryNum; |
|
- | 3733 | voltage_table->phase_delay = gpio->ucPhaseDelay; |
|
- | 3734 | return 0; |
|
- | 3735 | } |
|
- | 3736 | break; |
|
- | 3737 | default: |
|
- | 3738 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3739 | return -EINVAL; |
|
- | 3740 | } |
|
- | 3741 | break; |
|
- | 3742 | default: |
|
- | 3743 | DRM_ERROR("unknown voltage object table\n"); |
|
- | 3744 | return -EINVAL; |
|
- | 3745 | } |
|
- | 3746 | } |
|
- | 3747 | return -EINVAL; |
|
- | 3748 | } |
|
- | 3749 | ||
- | 3750 | union vram_info { |
|
- | 3751 | struct _ATOM_VRAM_INFO_V3 v1_3; |
|
- | 3752 | struct _ATOM_VRAM_INFO_V4 v1_4; |
|
- | 3753 | struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1; |
|
- | 3754 | }; |
|
- | 3755 | ||
- | 3756 | int radeon_atom_get_memory_info(struct radeon_device *rdev, |
|
- | 3757 | u8 module_index, struct atom_memory_info *mem_info) |
|
- | 3758 | { |
|
- | 3759 | int index = GetIndexIntoMasterTable(DATA, VRAM_Info); |
|
- | 3760 | u8 frev, crev, i; |
|
- | 3761 | u16 data_offset, size; |
|
- | 3762 | union vram_info *vram_info; |
|
- | 3763 | ||
- | 3764 | memset(mem_info, 0, sizeof(struct atom_memory_info)); |
|
- | 3765 | ||
- | 3766 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3767 | &frev, &crev, &data_offset)) { |
|
- | 3768 | vram_info = (union vram_info *) |
|
- | 3769 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3770 | switch (frev) { |
|
- | 3771 | case 1: |
|
- | 3772 | switch (crev) { |
|
- | 3773 | case 3: |
|
- | 3774 | /* r6xx */ |
|
- | 3775 | if (module_index < vram_info->v1_3.ucNumOfVRAMModule) { |
|
- | 3776 | ATOM_VRAM_MODULE_V3 *vram_module = |
|
- | 3777 | (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo; |
|
- | 3778 | ||
- | 3779 | for (i = 0; i < module_index; i++) { |
|
- | 3780 | if (le16_to_cpu(vram_module->usSize) == 0) |
|
- | 3781 | return -EINVAL; |
|
- | 3782 | vram_module = (ATOM_VRAM_MODULE_V3 *) |
|
- | 3783 | ((u8 *)vram_module + le16_to_cpu(vram_module->usSize)); |
|
- | 3784 | } |
|
- | 3785 | mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf; |
|
- | 3786 | mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0; |
|
- | 3787 | } else |
|
- | 3788 | return -EINVAL; |
|
- | 3789 | break; |
|
- | 3790 | case 4: |
|
- | 3791 | /* r7xx, evergreen */ |
|
- | 3792 | if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { |
|
- | 3793 | ATOM_VRAM_MODULE_V4 *vram_module = |
|
- | 3794 | (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; |
|
- | 3795 | ||
- | 3796 | for (i = 0; i < module_index; i++) { |
|
- | 3797 | if (le16_to_cpu(vram_module->usModuleSize) == 0) |
|
- | 3798 | return -EINVAL; |
|
- | 3799 | vram_module = (ATOM_VRAM_MODULE_V4 *) |
|
- | 3800 | ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); |
|
- | 3801 | } |
|
- | 3802 | mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; |
|
- | 3803 | mem_info->mem_type = vram_module->ucMemoryType & 0xf0; |
|
- | 3804 | } else |
|
- | 3805 | return -EINVAL; |
|
- | 3806 | break; |
|
- | 3807 | default: |
|
- | 3808 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3809 | return -EINVAL; |
|
- | 3810 | } |
|
- | 3811 | break; |
|
- | 3812 | case 2: |
|
- | 3813 | switch (crev) { |
|
- | 3814 | case 1: |
|
- | 3815 | /* ni */ |
|
- | 3816 | if (module_index < vram_info->v2_1.ucNumOfVRAMModule) { |
|
- | 3817 | ATOM_VRAM_MODULE_V7 *vram_module = |
|
- | 3818 | (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo; |
|
- | 3819 | ||
- | 3820 | for (i = 0; i < module_index; i++) { |
|
- | 3821 | if (le16_to_cpu(vram_module->usModuleSize) == 0) |
|
- | 3822 | return -EINVAL; |
|
- | 3823 | vram_module = (ATOM_VRAM_MODULE_V7 *) |
|
- | 3824 | ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); |
|
- | 3825 | } |
|
- | 3826 | mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; |
|
- | 3827 | mem_info->mem_type = vram_module->ucMemoryType & 0xf0; |
|
- | 3828 | } else |
|
- | 3829 | return -EINVAL; |
|
- | 3830 | break; |
|
- | 3831 | default: |
|
- | 3832 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3833 | return -EINVAL; |
|
- | 3834 | } |
|
- | 3835 | break; |
|
- | 3836 | default: |
|
- | 3837 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3838 | return -EINVAL; |
|
- | 3839 | } |
|
- | 3840 | return 0; |
|
- | 3841 | } |
|
- | 3842 | return -EINVAL; |
|
- | 3843 | } |
|
- | 3844 | ||
- | 3845 | int radeon_atom_get_mclk_range_table(struct radeon_device *rdev, |
|
- | 3846 | bool gddr5, u8 module_index, |
|
- | 3847 | struct atom_memory_clock_range_table *mclk_range_table) |
|
- | 3848 | { |
|
- | 3849 | int index = GetIndexIntoMasterTable(DATA, VRAM_Info); |
|
- | 3850 | u8 frev, crev, i; |
|
- | 3851 | u16 data_offset, size; |
|
- | 3852 | union vram_info *vram_info; |
|
- | 3853 | u32 mem_timing_size = gddr5 ? |
|
- | 3854 | sizeof(ATOM_MEMORY_TIMING_FORMAT_V2) : sizeof(ATOM_MEMORY_TIMING_FORMAT); |
|
- | 3855 | ||
- | 3856 | memset(mclk_range_table, 0, sizeof(struct atom_memory_clock_range_table)); |
|
- | 3857 | ||
- | 3858 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3859 | &frev, &crev, &data_offset)) { |
|
- | 3860 | vram_info = (union vram_info *) |
|
- | 3861 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3862 | switch (frev) { |
|
- | 3863 | case 1: |
|
- | 3864 | switch (crev) { |
|
- | 3865 | case 3: |
|
- | 3866 | DRM_ERROR("old table version %d, %d\n", frev, crev); |
|
- | 3867 | return -EINVAL; |
|
- | 3868 | case 4: |
|
- | 3869 | /* r7xx, evergreen */ |
|
- | 3870 | if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { |
|
- | 3871 | ATOM_VRAM_MODULE_V4 *vram_module = |
|
- | 3872 | (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; |
|
- | 3873 | ATOM_MEMORY_TIMING_FORMAT *format; |
|
- | 3874 | ||
- | 3875 | for (i = 0; i < module_index; i++) { |
|
- | 3876 | if (le16_to_cpu(vram_module->usModuleSize) == 0) |
|
- | 3877 | return -EINVAL; |
|
- | 3878 | vram_module = (ATOM_VRAM_MODULE_V4 *) |
|
- | 3879 | ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); |
|
- | 3880 | } |
|
- | 3881 | mclk_range_table->num_entries = (u8) |
|
- | 3882 | ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) / |
|
- | 3883 | mem_timing_size); |
|
- | 3884 | format = &vram_module->asMemTiming[0]; |
|
- | 3885 | for (i = 0; i < mclk_range_table->num_entries; i++) { |
|
- | 3886 | mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange); |
|
- | 3887 | format = (ATOM_MEMORY_TIMING_FORMAT *) |
|
- | 3888 | ((u8 *)format + mem_timing_size); |
|
- | 3889 | } |
|
- | 3890 | } else |
|
- | 3891 | return -EINVAL; |
|
- | 3892 | break; |
|
- | 3893 | default: |
|
- | 3894 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3895 | return -EINVAL; |
|
- | 3896 | } |
|
- | 3897 | break; |
|
- | 3898 | case 2: |
|
- | 3899 | DRM_ERROR("new table version %d, %d\n", frev, crev); |
|
- | 3900 | return -EINVAL; |
|
- | 3901 | default: |
|
- | 3902 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3903 | return -EINVAL; |
|
- | 3904 | } |
|
- | 3905 | return 0; |
|
- | 3906 | } |
|
- | 3907 | return -EINVAL; |
|
- | 3908 | } |
|
- | 3909 | ||
- | 3910 | #define MEM_ID_MASK 0xff000000 |
|
- | 3911 | #define MEM_ID_SHIFT 24 |
|
- | 3912 | #define CLOCK_RANGE_MASK 0x00ffffff |
|
- | 3913 | #define CLOCK_RANGE_SHIFT 0 |
|
- | 3914 | #define LOW_NIBBLE_MASK 0xf |
|
- | 3915 | #define DATA_EQU_PREV 0 |
|
- | 3916 | #define DATA_FROM_TABLE 4 |
|
- | 3917 | ||
- | 3918 | int radeon_atom_init_mc_reg_table(struct radeon_device *rdev, |
|
- | 3919 | u8 module_index, |
|
- | 3920 | struct atom_mc_reg_table *reg_table) |
|
- | 3921 | { |
|
- | 3922 | int index = GetIndexIntoMasterTable(DATA, VRAM_Info); |
|
- | 3923 | u8 frev, crev, num_entries, t_mem_id, num_ranges = 0; |
|
- | 3924 | u32 i = 0, j; |
|
- | 3925 | u16 data_offset, size; |
|
- | 3926 | union vram_info *vram_info; |
|
- | 3927 | ||
- | 3928 | memset(reg_table, 0, sizeof(struct atom_mc_reg_table)); |
|
- | 3929 | ||
- | 3930 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, |
|
- | 3931 | &frev, &crev, &data_offset)) { |
|
- | 3932 | vram_info = (union vram_info *) |
|
- | 3933 | (rdev->mode_info.atom_context->bios + data_offset); |
|
- | 3934 | switch (frev) { |
|
- | 3935 | case 1: |
|
- | 3936 | DRM_ERROR("old table version %d, %d\n", frev, crev); |
|
- | 3937 | return -EINVAL; |
|
- | 3938 | case 2: |
|
- | 3939 | switch (crev) { |
|
- | 3940 | case 1: |
|
- | 3941 | if (module_index < vram_info->v2_1.ucNumOfVRAMModule) { |
|
- | 3942 | ATOM_INIT_REG_BLOCK *reg_block = |
|
- | 3943 | (ATOM_INIT_REG_BLOCK *) |
|
- | 3944 | ((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset)); |
|
- | 3945 | ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data = |
|
- | 3946 | (ATOM_MEMORY_SETTING_DATA_BLOCK *) |
|
- | 3947 | ((u8 *)reg_block + (2 * sizeof(u16)) + |
|
- | 3948 | le16_to_cpu(reg_block->usRegIndexTblSize)); |
|
- | 3949 | ATOM_INIT_REG_INDEX_FORMAT *format = ®_block->asRegIndexBuf[0]; |
|
- | 3950 | num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) / |
|
- | 3951 | sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1; |
|
- | 3952 | if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE) |
|
- | 3953 | return -EINVAL; |
|
- | 3954 | while (i < num_entries) { |
|
- | 3955 | if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER) |
|
- | 3956 | break; |
|
- | 3957 | reg_table->mc_reg_address[i].s1 = |
|
- | 3958 | (u16)(le16_to_cpu(format->usRegIndex)); |
|
- | 3959 | reg_table->mc_reg_address[i].pre_reg_data = |
|
- | 3960 | (u8)(format->ucPreRegDataLength); |
|
- | 3961 | i++; |
|
- | 3962 | format = (ATOM_INIT_REG_INDEX_FORMAT *) |
|
- | 3963 | ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT)); |
|
- | 3964 | } |
|
- | 3965 | reg_table->last = i; |
|
- | 3966 | while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) && |
|
- | 3967 | (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) { |
|
- | 3968 | t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK) |
|
- | 3969 | >> MEM_ID_SHIFT); |
|
- | 3970 | if (module_index == t_mem_id) { |
|
- | 3971 | reg_table->mc_reg_table_entry[num_ranges].mclk_max = |
|
- | 3972 | (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK) |
|
- | 3973 | >> CLOCK_RANGE_SHIFT); |
|
- | 3974 | for (i = 0, j = 1; i < reg_table->last; i++) { |
|
- | 3975 | if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) { |
|
- | 3976 | reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = |
|
- | 3977 | (u32)le32_to_cpu(*((u32 *)reg_data + j)); |
|
- | 3978 | j++; |
|
- | 3979 | } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { |
|
- | 3980 | reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = |
|
- | 3981 | reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; |
|
- | 3982 | } |
|
- | 3983 | } |
|
- | 3984 | num_ranges++; |
|
- | 3985 | } |
|
- | 3986 | reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *) |
|
- | 3987 | ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize)); |
|
- | 3988 | } |
|
- | 3989 | if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) |
|
- | 3990 | return -EINVAL; |
|
- | 3991 | reg_table->num_entries = num_ranges; |
|
- | 3992 | } else |
|
- | 3993 | return -EINVAL; |
|
- | 3994 | break; |
|
- | 3995 | default: |
|
- | 3996 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 3997 | return -EINVAL; |
|
- | 3998 | } |
|
- | 3999 | break; |
|
- | 4000 | default: |
|
- | 4001 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
|
- | 4002 | return -EINVAL; |
|
- | 4003 | } |
|
- | 4004 | return 0; |
|
- | 4005 | } |
|
- | 4006 | return -EINVAL; |
|
2903 | } |
4007 | } |
2904 | 4008 | ||
2905 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) |
4009 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) |
2906 | { |
4010 | { |
Line 2919... | Line 4023... | ||
2919 | bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; |
4023 | bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; |
Line 2920... | Line 4024... | ||
2920 | 4024 | ||
2921 | /* tell the bios not to handle mode switching */ |
4025 | /* tell the bios not to handle mode switching */ |
Line -... | Line 4026... | ||
- | 4026 | bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; |
|
- | 4027 | ||
- | 4028 | /* clear the vbios dpms state */ |
|
- | 4029 | if (ASIC_IS_DCE4(rdev)) |
|
2922 | bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; |
4030 | bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE; |
2923 | 4031 | ||
2924 | if (rdev->family >= CHIP_R600) { |
4032 | if (rdev->family >= CHIP_R600) { |
2925 | WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); |
4033 | WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); |
2926 | WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); |
4034 | WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); |