diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 404e25d285ba..f79ee184ffd5 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1367,6 +1367,7 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, | |||
1367 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); | 1367 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); |
1368 | uint16_t data_offset, size; | 1368 | uint16_t data_offset, size; |
1369 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; | 1369 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
1370 | struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT *ss_assign; | ||
1370 | uint8_t frev, crev; | 1371 | uint8_t frev, crev; |
1371 | int i, num_indices; | 1372 | int i, num_indices; |
1372 | 1373 | ||
@@ -1378,18 +1379,21 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, | |||
1378 | 1379 | ||
1379 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | 1380 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1380 | sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); | 1381 | sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); |
1381 | 1382 | ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) | |
1383 | ((u8 *)&ss_info->asSS_Info[0]); | ||
1382 | for (i = 0; i < num_indices; i++) { | 1384 | for (i = 0; i < num_indices; i++) { |
1383 | if (ss_info->asSS_Info[i].ucSS_Id == id) { | 1385 | if (ss_assign->ucSS_Id == id) { |
1384 | ss->percentage = | 1386 | ss->percentage = |
1385 | le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); | 1387 | le16_to_cpu(ss_assign->usSpreadSpectrumPercentage); |
1386 | ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; | 1388 | ss->type = ss_assign->ucSpreadSpectrumType; |
1387 | ss->step = ss_info->asSS_Info[i].ucSS_Step; | 1389 | ss->step = ss_assign->ucSS_Step; |
1388 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; | 1390 | ss->delay = ss_assign->ucSS_Delay; |
1389 | ss->range = ss_info->asSS_Info[i].ucSS_Range; | 1391 | ss->range = ss_assign->ucSS_Range; |
1390 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; | 1392 | ss->refdiv = ss_assign->ucRecommendedRef_Div; |
1391 | return true; | 1393 | return true; |
1392 | } | 1394 | } |
1395 | ss_assign = (struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT*) | ||
1396 | ((u8 *)ss_assign + sizeof(struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT)); | ||
1393 | } | 1397 | } |
1394 | } | 1398 | } |
1395 | return false; | 1399 | return false; |
@@ -1477,6 +1481,12 @@ union asic_ss_info { | |||
1477 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; | 1481 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; |
1478 | }; | 1482 | }; |
1479 | 1483 | ||
1484 | union asic_ss_assignment { | ||
1485 | struct _ATOM_ASIC_SS_ASSIGNMENT v1; | ||
1486 | struct _ATOM_ASIC_SS_ASSIGNMENT_V2 v2; | ||
1487 | struct _ATOM_ASIC_SS_ASSIGNMENT_V3 v3; | ||
1488 | }; | ||
1489 | |||
1480 | bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | 1490 | bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, |
1481 | struct radeon_atom_ss *ss, | 1491 | struct radeon_atom_ss *ss, |
1482 | int id, u32 clock) | 1492 | int id, u32 clock) |
@@ -1485,6 +1495,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
1485 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | 1495 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); |
1486 | uint16_t data_offset, size; | 1496 | uint16_t data_offset, size; |
1487 | union asic_ss_info *ss_info; | 1497 | union asic_ss_info *ss_info; |
1498 | union asic_ss_assignment *ss_assign; | ||
1488 | uint8_t frev, crev; | 1499 | uint8_t frev, crev; |
1489 | int i, num_indices; | 1500 | int i, num_indices; |
1490 | 1501 | ||
@@ -1509,45 +1520,52 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
1509 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | 1520 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1510 | sizeof(ATOM_ASIC_SS_ASSIGNMENT); | 1521 | sizeof(ATOM_ASIC_SS_ASSIGNMENT); |
1511 | 1522 | ||
1523 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info.asSpreadSpectrum[0]); | ||
1512 | for (i = 0; i < num_indices; i++) { | 1524 | for (i = 0; i < num_indices; i++) { |
1513 | if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && | 1525 | if ((ss_assign->v1.ucClockIndication == id) && |
1514 | (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { | 1526 | (clock <= le32_to_cpu(ss_assign->v1.ulTargetClockRange))) { |
1515 | ss->percentage = | 1527 | ss->percentage = |
1516 | le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1528 | le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage); |
1517 | ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1529 | ss->type = ss_assign->v1.ucSpreadSpectrumMode; |
1518 | ss->rate = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadRateInKhz); | 1530 | ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz); |
1519 | return true; | 1531 | return true; |
1520 | } | 1532 | } |
1533 | ss_assign = (union asic_ss_assignment *) | ||
1534 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT)); | ||
1521 | } | 1535 | } |
1522 | break; | 1536 | break; |
1523 | case 2: | 1537 | case 2: |
1524 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | 1538 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1525 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); | 1539 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); |
1540 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_2.asSpreadSpectrum[0]); | ||
1526 | for (i = 0; i < num_indices; i++) { | 1541 | for (i = 0; i < num_indices; i++) { |
1527 | if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && | 1542 | if ((ss_assign->v2.ucClockIndication == id) && |
1528 | (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { | 1543 | (clock <= le32_to_cpu(ss_assign->v2.ulTargetClockRange))) { |
1529 | ss->percentage = | 1544 | ss->percentage = |
1530 | le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1545 | le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage); |
1531 | ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1546 | ss->type = ss_assign->v2.ucSpreadSpectrumMode; |
1532 | ss->rate = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz); | 1547 | ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz); |
1533 | if ((crev == 2) && | 1548 | if ((crev == 2) && |
1534 | ((id == ASIC_INTERNAL_ENGINE_SS) || | 1549 | ((id == ASIC_INTERNAL_ENGINE_SS) || |
1535 | (id == ASIC_INTERNAL_MEMORY_SS))) | 1550 | (id == ASIC_INTERNAL_MEMORY_SS))) |
1536 | ss->rate /= 100; | 1551 | ss->rate /= 100; |
1537 | return true; | 1552 | return true; |
1538 | } | 1553 | } |
1554 | ss_assign = (union asic_ss_assignment *) | ||
1555 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2)); | ||
1539 | } | 1556 | } |
1540 | break; | 1557 | break; |
1541 | case 3: | 1558 | case 3: |
1542 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / | 1559 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
1543 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); | 1560 | sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); |
1561 | ss_assign = (union asic_ss_assignment *)((u8 *)&ss_info->info_3.asSpreadSpectrum[0]); | ||
1544 | for (i = 0; i < num_indices; i++) { | 1562 | for (i = 0; i < num_indices; i++) { |
1545 | if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && | 1563 | if ((ss_assign->v3.ucClockIndication == id) && |
1546 | (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { | 1564 | (clock <= le32_to_cpu(ss_assign->v3.ulTargetClockRange))) { |
1547 | ss->percentage = | 1565 | ss->percentage = |
1548 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1566 | le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage); |
1549 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1567 | ss->type = ss_assign->v3.ucSpreadSpectrumMode; |
1550 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); | 1568 | ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz); |
1551 | if ((id == ASIC_INTERNAL_ENGINE_SS) || | 1569 | if ((id == ASIC_INTERNAL_ENGINE_SS) || |
1552 | (id == ASIC_INTERNAL_MEMORY_SS)) | 1570 | (id == ASIC_INTERNAL_MEMORY_SS)) |
1553 | ss->rate /= 100; | 1571 | ss->rate /= 100; |
@@ -1555,6 +1573,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
1555 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); | 1573 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); |
1556 | return true; | 1574 | return true; |
1557 | } | 1575 | } |
1576 | ss_assign = (union asic_ss_assignment *) | ||
1577 | ((u8 *)ss_assign + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3)); | ||
1558 | } | 1578 | } |
1559 | break; | 1579 | break; |
1560 | default: | 1580 | default: |