aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-12-28 13:58:44 -0500
committerDave Airlie <airlied@redhat.com>2010-02-08 18:32:27 -0500
commit56278a8edacee9ae9e3bc9d8c8e2d37e9969f3eb (patch)
tree2aea5e4707e5caffb30abacc78230bd6f7295c32 /drivers/gpu/drm
parentc836a4126768cd76af9ee33b3c11f57695d5fda6 (diff)
drm/radeon/kms: pull power mode info from bios tables (v3)
The general idea is to validate the current hw state against the set of power states and select a power state based on that. This patch just pulls the power states from the bios and prints the information. It is not currently hooked up in the actual power management code. Hooking it up will require reworking the the current power state selection code and will be handled in a future patch. Additionally, we'd need to decide on some default lower power states for cards without power tables. v2 - increment state_index after checking for default state v3 - fix typo in pm init on pre-atom cards, handle pre-atom cards without x86 bioses Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h61
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c299
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c108
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c38
4 files changed, 506 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index df21edcbae16..d73d37d5effd 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -150,6 +150,8 @@ struct radeon_clock {
150 */ 150 */
151int radeon_pm_init(struct radeon_device *rdev); 151int radeon_pm_init(struct radeon_device *rdev);
152void radeon_pm_compute_clocks(struct radeon_device *rdev); 152void radeon_pm_compute_clocks(struct radeon_device *rdev);
153void radeon_combios_get_power_modes(struct radeon_device *rdev);
154void radeon_atombios_get_power_modes(struct radeon_device *rdev);
153 155
154/* 156/*
155 * Fences. 157 * Fences.
@@ -583,6 +585,59 @@ enum radeon_pm_action {
583 PM_ACTION_DOWNCLOCK, 585 PM_ACTION_DOWNCLOCK,
584 PM_ACTION_UPCLOCK 586 PM_ACTION_UPCLOCK
585}; 587};
588
589enum radeon_voltage_type {
590 VOLTAGE_NONE = 0,
591 VOLTAGE_GPIO,
592 VOLTAGE_VDDC,
593 VOLTAGE_SW
594};
595
596struct radeon_voltage {
597 enum radeon_voltage_type type;
598 /* gpio voltage */
599 struct radeon_gpio_rec gpio;
600 u32 delay; /* delay in usec from voltage drop to sclk change */
601 bool active_high; /* voltage drop is active when bit is high */
602 /* VDDC voltage */
603 u8 vddc_id; /* index into vddc voltage table */
604 u8 vddci_id; /* index into vddci voltage table */
605 bool vddci_enabled;
606 /* r6xx+ sw */
607 u32 voltage;
608};
609
610struct radeon_pm_non_clock_info {
611 /* pcie lanes */
612 int pcie_lanes;
613 /* standardized non-clock flags */
614 u32 flags;
615};
616
617struct radeon_pm_clock_info {
618 /* memory clock */
619 u32 mclk;
620 /* engine clock */
621 u32 sclk;
622 /* voltage info */
623 struct radeon_voltage voltage;
624 /* standardized clock flags - not sure we'll need these */
625 u32 flags;
626};
627
628struct radeon_power_state {
629 /* XXX: use a define for num clock modes */
630 struct radeon_pm_clock_info clock_info[8];
631 /* number of valid clock modes in this power state */
632 int num_clock_modes;
633 /* currently selected clock mode */
634 struct radeon_pm_clock_info *current_clock_mode;
635 struct radeon_pm_clock_info *default_clock_mode;
636 /* non clock info about this state */
637 struct radeon_pm_non_clock_info non_clock_info;
638 bool voltage_drop_active;
639};
640
586struct radeon_pm { 641struct radeon_pm {
587 struct mutex mutex; 642 struct mutex mutex;
588 struct work_struct reclock_work; 643 struct work_struct reclock_work;
@@ -609,6 +664,12 @@ struct radeon_pm {
609 fixed20_12 core_bandwidth; 664 fixed20_12 core_bandwidth;
610 fixed20_12 sclk; 665 fixed20_12 sclk;
611 fixed20_12 needed_bandwidth; 666 fixed20_12 needed_bandwidth;
667 /* XXX: use a define for num power modes */
668 struct radeon_power_state power_state[8];
669 /* number of valid power states */
670 int num_power_states;
671 struct radeon_power_state *current_power_state;
672 struct radeon_power_state *default_power_state;
612}; 673};
613 674
614 675
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;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 257ce1774e40..eac2174abc5b 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2374,6 +2374,114 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
2374 return true; 2374 return true;
2375} 2375}
2376 2376
2377void radeon_combios_get_power_modes(struct radeon_device *rdev)
2378{
2379 struct drm_device *dev = rdev->ddev;
2380 u16 offset, misc, misc2 = 0;
2381 u8 rev, blocks, tmp;
2382 int state_index = 0;
2383
2384 rdev->pm.default_power_state = NULL;
2385 rdev->pm.current_power_state = NULL;
2386
2387 /* XXX mac/sparc cards */
2388 if (rdev->bios == NULL)
2389 goto default_mode;
2390
2391 if (rdev->flags & RADEON_IS_MOBILITY) {
2392 offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
2393 if (offset) {
2394 rev = RBIOS8(offset);
2395 blocks = RBIOS8(offset + 0x2);
2396 /* power mode 0 tends to be the only valid one */
2397 rdev->pm.power_state[state_index].num_clock_modes = 1;
2398 rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
2399 rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
2400 if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
2401 (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
2402 goto default_mode;
2403 /* skip overclock modes for now */
2404 if ((rdev->pm.power_state[state_index].clock_info[0].mclk >
2405 rdev->clock.default_mclk) ||
2406 (rdev->pm.power_state[state_index].clock_info[0].sclk >
2407 rdev->clock.default_sclk))
2408 goto default_mode;
2409 misc = RBIOS16(offset + 0x5 + 0x0);
2410 if (rev > 4)
2411 misc2 = RBIOS16(offset + 0x5 + 0xe);
2412 if (misc & 0x4) {
2413 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
2414 if (misc & 0x8)
2415 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2416 true;
2417 else
2418 rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
2419 false;
2420 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
2421 if (rev < 6) {
2422 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
2423 RBIOS16(offset + 0x5 + 0xb) * 4;
2424 tmp = RBIOS8(offset + 0x5 + 0xd);
2425 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
2426 } else {
2427 u8 entries = RBIOS8(offset + 0x5 + 0xb);
2428 u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
2429 if (entries && voltage_table_offset) {
2430 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
2431 RBIOS16(voltage_table_offset) * 4;
2432 tmp = RBIOS8(voltage_table_offset + 0x2);
2433 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
2434 } else
2435 rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
2436 }
2437 switch ((misc2 & 0x700) >> 8) {
2438 case 0:
2439 default:
2440 rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
2441 break;
2442 case 1:
2443 rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
2444 break;
2445 case 2:
2446 rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
2447 break;
2448 case 3:
2449 rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
2450 break;
2451 case 4:
2452 rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
2453 break;
2454 }
2455 } else
2456 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2457 if (rev > 6)
2458 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes =
2459 RBIOS8(offset + 0x5 + 0x10);
2460 state_index++;
2461 } else {
2462 /* XXX figure out some good default low power mode for mobility cards w/out power tables */
2463 }
2464 } else {
2465 /* XXX figure out some good default low power mode for desktop cards */
2466 }
2467
2468default_mode:
2469 /* add the default mode */
2470 rdev->pm.power_state[state_index].num_clock_modes = 1;
2471 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2472 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2473 rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
2474 rdev->pm.power_state[state_index].current_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
2475 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2476 if (rdev->asic->get_pcie_lanes)
2477 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev);
2478 else
2479 rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16;
2480 rdev->pm.default_power_state = &rdev->pm.power_state[state_index];
2481 rdev->pm.current_power_state = &rdev->pm.power_state[state_index];
2482 rdev->pm.num_power_states = state_index + 1;
2483}
2484
2377void radeon_external_tmds_setup(struct drm_encoder *encoder) 2485void radeon_external_tmds_setup(struct drm_encoder *encoder)
2378{ 2486{
2379 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 2487 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index a9c61f435c06..6eb0e0b3264b 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -18,6 +18,7 @@
18 * OTHER DEALINGS IN THE SOFTWARE. 18 * OTHER DEALINGS IN THE SOFTWARE.
19 * 19 *
20 * Authors: Rafał Miłecki <zajec5@gmail.com> 20 * Authors: Rafał Miłecki <zajec5@gmail.com>
21 * Alex Deucher <alexdeucher@gmail.com>
21 */ 22 */
22#include "drmP.h" 23#include "drmP.h"
23#include "radeon.h" 24#include "radeon.h"
@@ -39,6 +40,35 @@ static const char *pm_state_names[4] = {
39 "PM_STATE_ACTIVE" 40 "PM_STATE_ACTIVE"
40}; 41};
41 42
43static void radeon_print_power_mode_info(struct radeon_device *rdev)
44{
45 int i, j;
46 bool is_default;
47
48 DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states);
49 for (i = 0; i < rdev->pm.num_power_states; i++) {
50 if (rdev->pm.default_power_state == &rdev->pm.power_state[i])
51 is_default = true;
52 else
53 is_default = false;
54 DRM_INFO("State %d %s\n", i, is_default ? "(default)" : "");
55 if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
56 DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].non_clock_info.pcie_lanes);
57 DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
58 for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
59 if (rdev->flags & RADEON_IS_IGP)
60 DRM_INFO("\t\t%d engine: %d\n",
61 j,
62 rdev->pm.power_state[i].clock_info[j].sclk * 10);
63 else
64 DRM_INFO("\t\t%d engine/memory: %d/%d\n",
65 j,
66 rdev->pm.power_state[i].clock_info[j].sclk * 10,
67 rdev->pm.power_state[i].clock_info[j].mclk * 10);
68 }
69 }
70}
71
42int radeon_pm_init(struct radeon_device *rdev) 72int radeon_pm_init(struct radeon_device *rdev)
43{ 73{
44 rdev->pm.state = PM_STATE_DISABLED; 74 rdev->pm.state = PM_STATE_DISABLED;
@@ -46,6 +76,14 @@ int radeon_pm_init(struct radeon_device *rdev)
46 rdev->pm.downclocked = false; 76 rdev->pm.downclocked = false;
47 rdev->pm.vblank_callback = false; 77 rdev->pm.vblank_callback = false;
48 78
79 if (rdev->bios) {
80 if (rdev->is_atom_bios)
81 radeon_atombios_get_power_modes(rdev);
82 else
83 radeon_combios_get_power_modes(rdev);
84 radeon_print_power_mode_info(rdev);
85 }
86
49 radeon_pm_check_limits(rdev); 87 radeon_pm_check_limits(rdev);
50 88
51 if (radeon_debugfs_pm_init(rdev)) { 89 if (radeon_debugfs_pm_init(rdev)) {