aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_atombios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index d33fb4174b13..adf900e368ac 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1393,6 +1393,305 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
1393 return tv_dac; 1393 return tv_dac;
1394} 1394}
1395 1395
1396union power_info {
1397 struct _ATOM_POWERPLAY_INFO info;
1398 struct _ATOM_POWERPLAY_INFO_V2 info_2;
1399 struct _ATOM_POWERPLAY_INFO_V3 info_3;
1400 struct _ATOM_PPLIB_POWERPLAYTABLE info_4;
1401};
1402
1403void radeon_atombios_get_power_modes(struct radeon_device *rdev)
1404{
1405 struct radeon_mode_info *mode_info = &rdev->mode_info;
1406 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
1407 u16 data_offset;
1408 u8 frev, crev;
1409 u32 misc, misc2 = 0, sclk, mclk;
1410 union power_info *power_info;
1411 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
1412 struct _ATOM_PPLIB_STATE *power_state;
1413 int num_modes = 0, i, j;
1414 int state_index = 0, mode_index = 0;
1415
1416 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
1417
1418 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1419
1420 rdev->pm.default_power_state = NULL;
1421 rdev->pm.current_power_state = NULL;
1422
1423 if (power_info) {
1424 if (frev < 4) {
1425 num_modes = power_info->info.ucNumOfPowerModeEntries;
1426 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
1427 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
1428 for (i = 0; i < num_modes; i++) {
1429 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
1430 switch (frev) {
1431 case 1:
1432 rdev->pm.power_state[state_index].num_clock_modes = 1;
1433 rdev->pm.power_state[state_index].clock_info[0].mclk =
1434 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
1435 rdev->pm.power_state[state_index].clock_info[0].sclk =
1436 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock);
1437 /* skip invalid modes */
1438 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
1439 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
1440 continue;
1441 /* skip overclock modes for now */
1442 if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
1443 rdev->clock.default_mclk) ||
1444 (rdev->pm.power_state[state_index].clock_info[0].sclk >
1445 rdev->clock.default_sclk))
1446 continue;
1447 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
1448 power_info->info.asPowerPlayInfo[i].ucNumPciELanes;
1449 misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo);
1450 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
1451 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1452 VOLTAGE_GPIO;
1453 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
1454 radeon_lookup_gpio(rdev,
1455 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);
1456 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
1457 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1458 true;
1459 else
1460 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1461 false;
1462 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
1463 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1464 VOLTAGE_VDDC;
1465 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
1466 power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
1467 }
1468 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
1469 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
1470 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
1471 rdev->pm.power_state[state_index].default_clock_mode =
1472 &rdev->pm.power_state[state_index].clock_info[0];
1473 rdev->pm.power_state[state_index].current_clock_mode =
1474 &rdev->pm.power_state[state_index].clock_info[0];
1475 }
1476 state_index++;
1477 break;
1478 case 2:
1479 rdev->pm.power_state[state_index].num_clock_modes = 1;
1480 rdev->pm.power_state[state_index].clock_info[0].mclk =
1481 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
1482 rdev->pm.power_state[state_index].clock_info[0].sclk =
1483 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock);
1484 /* skip invalid modes */
1485 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
1486 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
1487 continue;
1488 /* skip overclock modes for now */
1489 if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
1490 rdev->clock.default_mclk) ||
1491 (rdev->pm.power_state[state_index].clock_info[0].sclk >
1492 rdev->clock.default_sclk))
1493 continue;
1494 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
1495 power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes;
1496 misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo);
1497 misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2);
1498 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
1499 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1500 VOLTAGE_GPIO;
1501 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
1502 radeon_lookup_gpio(rdev,
1503 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);
1504 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
1505 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1506 true;
1507 else
1508 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1509 false;
1510 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
1511 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1512 VOLTAGE_VDDC;
1513 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
1514 power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
1515 }
1516 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
1517 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
1518 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
1519 rdev->pm.power_state[state_index].default_clock_mode =
1520 &rdev->pm.power_state[state_index].clock_info[0];
1521 rdev->pm.power_state[state_index].current_clock_mode =
1522 &rdev->pm.power_state[state_index].clock_info[0];
1523 }
1524 state_index++;
1525 break;
1526 case 3:
1527 rdev->pm.power_state[state_index].num_clock_modes = 1;
1528 rdev->pm.power_state[state_index].clock_info[0].mclk =
1529 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
1530 rdev->pm.power_state[state_index].clock_info[0].sclk =
1531 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock);
1532 /* skip invalid modes */
1533 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
1534 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
1535 continue;
1536 /* skip overclock modes for now */
1537 if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
1538 rdev->clock.default_mclk) ||
1539 (rdev->pm.power_state[state_index].clock_info[0].sclk >
1540 rdev->clock.default_sclk))
1541 continue;
1542 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
1543 power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes;
1544 misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo);
1545 misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2);
1546 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
1547 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1548 VOLTAGE_GPIO;
1549 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
1550 radeon_lookup_gpio(rdev,
1551 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);
1552 if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
1553 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1554 true;
1555 else
1556 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
1557 false;
1558 } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) {
1559 rdev->pm.power_state[state_index].clock_info[0].voltage.type =
1560 VOLTAGE_VDDC;
1561 rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id =
1562 power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex;
1563 if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) {
1564 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled =
1565 true;
1566 rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id =
1567 power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex;
1568 }
1569 }
1570 if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
1571 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
1572 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
1573 rdev->pm.power_state[state_index].default_clock_mode =
1574 &rdev->pm.power_state[state_index].clock_info[0];
1575 rdev->pm.power_state[state_index].current_clock_mode =
1576 &rdev->pm.power_state[state_index].clock_info[0];
1577 }
1578 state_index++;
1579 break;
1580 }
1581 }
1582 } else if (frev == 4) {
1583 for (i = 0; i < power_info->info_4.ucNumStates; i++) {
1584 mode_index = 0;
1585 power_state = (struct _ATOM_PPLIB_STATE *)
1586 (mode_info->atom_context->bios +
1587 data_offset +
1588 le16_to_cpu(power_info->info_4.usStateArrayOffset) +
1589 i * power_info->info_4.ucStateEntrySize);
1590 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
1591 (mode_info->atom_context->bios +
1592 data_offset +
1593 le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) +
1594 (power_state->ucNonClockStateIndex *
1595 power_info->info_4.ucNonClockSize));
1596 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
1597 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
1598 ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >>
1599 ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
1600 for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) {
1601 if (rdev->flags & RADEON_IS_IGP) {
1602 struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info =
1603 (struct _ATOM_PPLIB_RS780_CLOCK_INFO *)
1604 (mode_info->atom_context->bios +
1605 data_offset +
1606 le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
1607 (power_state->ucClockStateIndices[j] *
1608 power_info->info_4.ucClockInfoSize));
1609 sclk = le16_to_cpu(clock_info->usLowEngineClockLow);
1610 sclk |= clock_info->ucLowEngineClockHigh << 16;
1611 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
1612 /* skip invalid modes */
1613 if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
1614 continue;
1615 /* skip overclock modes for now */
1616 if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk >
1617 rdev->clock.default_sclk)
1618 continue;
1619 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
1620 VOLTAGE_SW;
1621 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
1622 clock_info->usVDDC;
1623 mode_index++;
1624 } else {
1625 struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info =
1626 (struct _ATOM_PPLIB_R600_CLOCK_INFO *)
1627 (mode_info->atom_context->bios +
1628 data_offset +
1629 le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
1630 (power_state->ucClockStateIndices[j] *
1631 power_info->info_4.ucClockInfoSize));
1632 sclk = le16_to_cpu(clock_info->usEngineClockLow);
1633 sclk |= clock_info->ucEngineClockHigh << 16;
1634 mclk = le16_to_cpu(clock_info->usMemoryClockLow);
1635 mclk |= clock_info->ucMemoryClockHigh << 16;
1636 rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
1637 rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
1638 /* skip invalid modes */
1639 if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
1640 (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
1641 continue;
1642 /* skip overclock modes for now */
1643 if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk >
1644 rdev->clock.default_mclk) ||
1645 (rdev->pm.power_state[state_index].clock_info[mode_index].sclk >
1646 rdev->clock.default_sclk))
1647 continue;
1648 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
1649 VOLTAGE_SW;
1650 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
1651 clock_info->usVDDC;
1652 mode_index++;
1653 }
1654 }
1655 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
1656 if (mode_index) {
1657 misc2 = le16_to_cpu(non_clock_info->usClassification);
1658 if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) {
1659 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
1660 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
1661 rdev->pm.power_state[state_index].default_clock_mode =
1662 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
1663 rdev->pm.power_state[state_index].current_clock_mode =
1664 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
1665 }
1666 state_index++;
1667 }
1668 }
1669 }
1670 } else {
1671 /* XXX figure out some good default low power mode for cards w/out power tables */
1672 }
1673
1674 if (rdev->pm.default_power_state == NULL) {
1675 /* add the default mode */
1676 rdev->pm.power_state[state_index].num_clock_modes = 1;
1677 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
1678 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
1679 rdev->pm.power_state[state_index].default_clock_mode =
1680 &rdev->pm.power_state[state_index].clock_info[0];
1681 rdev->pm.power_state[state_index].current_clock_mode =
1682 &rdev->pm.power_state[state_index].clock_info[0];
1683 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
1684 if (rdev->asic->get_pcie_lanes)
1685 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev);
1686 else
1687 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16;
1688 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
1689 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
1690 state_index++;
1691 }
1692 rdev->pm.num_power_states = state_index;
1693}
1694
1396void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) 1695void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
1397{ 1696{
1398 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; 1697 DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;