diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 435 |
1 files changed, 426 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4d8831548a5f..93783b15c81d 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -159,8 +159,15 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
159 | struct radeon_gpio_rec *gpio) | 159 | struct radeon_gpio_rec *gpio) |
160 | { | 160 | { |
161 | struct radeon_hpd hpd; | 161 | struct radeon_hpd hpd; |
162 | u32 reg; | ||
163 | |||
164 | if (ASIC_IS_DCE4(rdev)) | ||
165 | reg = EVERGREEN_DC_GPIO_HPD_A; | ||
166 | else | ||
167 | reg = AVIVO_DC_GPIO_HPD_A; | ||
168 | |||
162 | hpd.gpio = *gpio; | 169 | hpd.gpio = *gpio; |
163 | if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { | 170 | if (gpio->reg == reg) { |
164 | switch(gpio->mask) { | 171 | switch(gpio->mask) { |
165 | case (1 << 0): | 172 | case (1 << 0): |
166 | hpd.hpd = RADEON_HPD_1; | 173 | hpd.hpd = RADEON_HPD_1; |
@@ -574,6 +581,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
574 | ddc_bus.valid = false; | 581 | ddc_bus.valid = false; |
575 | } | 582 | } |
576 | 583 | ||
584 | /* needed for aux chan transactions */ | ||
585 | ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0; | ||
586 | |||
577 | conn_id = le16_to_cpu(path->usConnObjectId); | 587 | conn_id = le16_to_cpu(path->usConnObjectId); |
578 | 588 | ||
579 | if (!radeon_atom_apply_quirks | 589 | if (!radeon_atom_apply_quirks |
@@ -838,6 +848,7 @@ union firmware_info { | |||
838 | ATOM_FIRMWARE_INFO_V1_2 info_12; | 848 | ATOM_FIRMWARE_INFO_V1_2 info_12; |
839 | ATOM_FIRMWARE_INFO_V1_3 info_13; | 849 | ATOM_FIRMWARE_INFO_V1_3 info_13; |
840 | ATOM_FIRMWARE_INFO_V1_4 info_14; | 850 | ATOM_FIRMWARE_INFO_V1_4 info_14; |
851 | ATOM_FIRMWARE_INFO_V2_1 info_21; | ||
841 | }; | 852 | }; |
842 | 853 | ||
843 | bool radeon_atom_get_clock_info(struct drm_device *dev) | 854 | bool radeon_atom_get_clock_info(struct drm_device *dev) |
@@ -849,6 +860,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
849 | uint8_t frev, crev; | 860 | uint8_t frev, crev; |
850 | struct radeon_pll *p1pll = &rdev->clock.p1pll; | 861 | struct radeon_pll *p1pll = &rdev->clock.p1pll; |
851 | struct radeon_pll *p2pll = &rdev->clock.p2pll; | 862 | struct radeon_pll *p2pll = &rdev->clock.p2pll; |
863 | struct radeon_pll *dcpll = &rdev->clock.dcpll; | ||
852 | struct radeon_pll *spll = &rdev->clock.spll; | 864 | struct radeon_pll *spll = &rdev->clock.spll; |
853 | struct radeon_pll *mpll = &rdev->clock.mpll; | 865 | struct radeon_pll *mpll = &rdev->clock.mpll; |
854 | uint16_t data_offset; | 866 | uint16_t data_offset; |
@@ -951,8 +963,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
951 | rdev->clock.default_mclk = | 963 | rdev->clock.default_mclk = |
952 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); | 964 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); |
953 | 965 | ||
966 | if (ASIC_IS_DCE4(rdev)) { | ||
967 | rdev->clock.default_dispclk = | ||
968 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); | ||
969 | if (rdev->clock.default_dispclk == 0) | ||
970 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ | ||
971 | rdev->clock.dp_extclk = | ||
972 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); | ||
973 | } | ||
974 | *dcpll = *p1pll; | ||
975 | |||
954 | return true; | 976 | return true; |
955 | } | 977 | } |
978 | |||
956 | return false; | 979 | return false; |
957 | } | 980 | } |
958 | 981 | ||
@@ -1091,6 +1114,30 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | |||
1091 | return ss; | 1114 | return ss; |
1092 | } | 1115 | } |
1093 | 1116 | ||
1117 | static void radeon_atom_apply_lvds_quirks(struct drm_device *dev, | ||
1118 | struct radeon_encoder_atom_dig *lvds) | ||
1119 | { | ||
1120 | |||
1121 | /* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */ | ||
1122 | if ((dev->pdev->device == 0x95c4) && | ||
1123 | (dev->pdev->subsystem_vendor == 0x1179) && | ||
1124 | (dev->pdev->subsystem_device == 0xff50)) { | ||
1125 | if ((lvds->native_mode.hdisplay == 1280) && | ||
1126 | (lvds->native_mode.vdisplay == 800)) | ||
1127 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1128 | } | ||
1129 | |||
1130 | /* Dell Studio 15 laptop panel doesn't like new pll divider algo */ | ||
1131 | if ((dev->pdev->device == 0x95c4) && | ||
1132 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
1133 | (dev->pdev->subsystem_device == 0x029f)) { | ||
1134 | if ((lvds->native_mode.hdisplay == 1280) && | ||
1135 | (lvds->native_mode.vdisplay == 800)) | ||
1136 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1137 | } | ||
1138 | |||
1139 | } | ||
1140 | |||
1094 | union lvds_info { | 1141 | union lvds_info { |
1095 | struct _ATOM_LVDS_INFO info; | 1142 | struct _ATOM_LVDS_INFO info; |
1096 | struct _ATOM_LVDS_INFO_V12 info_12; | 1143 | struct _ATOM_LVDS_INFO_V12 info_12; |
@@ -1161,6 +1208,21 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1161 | 1208 | ||
1162 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); | 1209 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); |
1163 | 1210 | ||
1211 | if (ASIC_IS_AVIVO(rdev)) { | ||
1212 | if (radeon_new_pll == 0) | ||
1213 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1214 | else | ||
1215 | lvds->pll_algo = PLL_ALGO_NEW; | ||
1216 | } else { | ||
1217 | if (radeon_new_pll == 1) | ||
1218 | lvds->pll_algo = PLL_ALGO_NEW; | ||
1219 | else | ||
1220 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1221 | } | ||
1222 | |||
1223 | /* LVDS quirks */ | ||
1224 | radeon_atom_apply_lvds_quirks(dev, lvds); | ||
1225 | |||
1164 | encoder->native_mode = lvds->native_mode; | 1226 | encoder->native_mode = lvds->native_mode; |
1165 | } | 1227 | } |
1166 | return lvds; | 1228 | return lvds; |
@@ -1385,20 +1447,375 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1385 | return tv_dac; | 1447 | return tv_dac; |
1386 | } | 1448 | } |
1387 | 1449 | ||
1388 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) | 1450 | union power_info { |
1451 | struct _ATOM_POWERPLAY_INFO info; | ||
1452 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | ||
1453 | struct _ATOM_POWERPLAY_INFO_V3 info_3; | ||
1454 | struct _ATOM_PPLIB_POWERPLAYTABLE info_4; | ||
1455 | }; | ||
1456 | |||
1457 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | ||
1389 | { | 1458 | { |
1390 | DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; | 1459 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1391 | int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); | 1460 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
1461 | u16 data_offset; | ||
1462 | u8 frev, crev; | ||
1463 | u32 misc, misc2 = 0, sclk, mclk; | ||
1464 | union power_info *power_info; | ||
1465 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
1466 | struct _ATOM_PPLIB_STATE *power_state; | ||
1467 | int num_modes = 0, i, j; | ||
1468 | int state_index = 0, mode_index = 0; | ||
1392 | 1469 | ||
1393 | args.ucEnable = enable; | 1470 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); |
1394 | 1471 | ||
1395 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1472 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
1473 | |||
1474 | rdev->pm.default_power_state = NULL; | ||
1475 | |||
1476 | if (power_info) { | ||
1477 | if (frev < 4) { | ||
1478 | num_modes = power_info->info.ucNumOfPowerModeEntries; | ||
1479 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | ||
1480 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | ||
1481 | for (i = 0; i < num_modes; i++) { | ||
1482 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1483 | switch (frev) { | ||
1484 | case 1: | ||
1485 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1486 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1487 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | ||
1488 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1489 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | ||
1490 | /* skip invalid modes */ | ||
1491 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1492 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1493 | continue; | ||
1494 | /* skip overclock modes for now */ | ||
1495 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1496 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1497 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1498 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1499 | continue; | ||
1500 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1501 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | ||
1502 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | ||
1503 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1504 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1505 | VOLTAGE_GPIO; | ||
1506 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1507 | radeon_lookup_gpio(rdev, | ||
1508 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1509 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1510 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1511 | true; | ||
1512 | else | ||
1513 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1514 | false; | ||
1515 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1516 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1517 | VOLTAGE_VDDC; | ||
1518 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1519 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1520 | } | ||
1521 | /* order matters! */ | ||
1522 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1523 | rdev->pm.power_state[state_index].type = | ||
1524 | POWER_STATE_TYPE_POWERSAVE; | ||
1525 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1526 | rdev->pm.power_state[state_index].type = | ||
1527 | POWER_STATE_TYPE_BATTERY; | ||
1528 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1529 | rdev->pm.power_state[state_index].type = | ||
1530 | POWER_STATE_TYPE_BATTERY; | ||
1531 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1532 | rdev->pm.power_state[state_index].type = | ||
1533 | POWER_STATE_TYPE_BALANCED; | ||
1534 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1535 | rdev->pm.power_state[state_index].type = | ||
1536 | POWER_STATE_TYPE_PERFORMANCE; | ||
1537 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1538 | rdev->pm.power_state[state_index].type = | ||
1539 | POWER_STATE_TYPE_DEFAULT; | ||
1540 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1541 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1542 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1543 | } | ||
1544 | state_index++; | ||
1545 | break; | ||
1546 | case 2: | ||
1547 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1548 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1549 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | ||
1550 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1551 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); | ||
1552 | /* skip invalid modes */ | ||
1553 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1554 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1555 | continue; | ||
1556 | /* skip overclock modes for now */ | ||
1557 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1558 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1559 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1560 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1561 | continue; | ||
1562 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1563 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | ||
1564 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | ||
1565 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | ||
1566 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1567 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1568 | VOLTAGE_GPIO; | ||
1569 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1570 | radeon_lookup_gpio(rdev, | ||
1571 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1572 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1573 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1574 | true; | ||
1575 | else | ||
1576 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1577 | false; | ||
1578 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1579 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1580 | VOLTAGE_VDDC; | ||
1581 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1582 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1583 | } | ||
1584 | /* order matters! */ | ||
1585 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1586 | rdev->pm.power_state[state_index].type = | ||
1587 | POWER_STATE_TYPE_POWERSAVE; | ||
1588 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1589 | rdev->pm.power_state[state_index].type = | ||
1590 | POWER_STATE_TYPE_BATTERY; | ||
1591 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1592 | rdev->pm.power_state[state_index].type = | ||
1593 | POWER_STATE_TYPE_BATTERY; | ||
1594 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1595 | rdev->pm.power_state[state_index].type = | ||
1596 | POWER_STATE_TYPE_BALANCED; | ||
1597 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1598 | rdev->pm.power_state[state_index].type = | ||
1599 | POWER_STATE_TYPE_PERFORMANCE; | ||
1600 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1601 | rdev->pm.power_state[state_index].type = | ||
1602 | POWER_STATE_TYPE_BALANCED; | ||
1603 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1604 | rdev->pm.power_state[state_index].type = | ||
1605 | POWER_STATE_TYPE_DEFAULT; | ||
1606 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1607 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1608 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1609 | } | ||
1610 | state_index++; | ||
1611 | break; | ||
1612 | case 3: | ||
1613 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1614 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1615 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | ||
1616 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1617 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); | ||
1618 | /* skip invalid modes */ | ||
1619 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1620 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1621 | continue; | ||
1622 | /* skip overclock modes for now */ | ||
1623 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk > | ||
1624 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1625 | (rdev->pm.power_state[state_index].clock_info[0].sclk > | ||
1626 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1627 | continue; | ||
1628 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1629 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1630 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1631 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1632 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | ||
1633 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1634 | VOLTAGE_GPIO; | ||
1635 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1636 | radeon_lookup_gpio(rdev, | ||
1637 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1638 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1639 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1640 | true; | ||
1641 | else | ||
1642 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1643 | false; | ||
1644 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1645 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1646 | VOLTAGE_VDDC; | ||
1647 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1648 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1649 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1650 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1651 | true; | ||
1652 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
1653 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
1654 | } | ||
1655 | } | ||
1656 | /* order matters! */ | ||
1657 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1658 | rdev->pm.power_state[state_index].type = | ||
1659 | POWER_STATE_TYPE_POWERSAVE; | ||
1660 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1661 | rdev->pm.power_state[state_index].type = | ||
1662 | POWER_STATE_TYPE_BATTERY; | ||
1663 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1664 | rdev->pm.power_state[state_index].type = | ||
1665 | POWER_STATE_TYPE_BATTERY; | ||
1666 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1667 | rdev->pm.power_state[state_index].type = | ||
1668 | POWER_STATE_TYPE_BALANCED; | ||
1669 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) | ||
1670 | rdev->pm.power_state[state_index].type = | ||
1671 | POWER_STATE_TYPE_PERFORMANCE; | ||
1672 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1673 | rdev->pm.power_state[state_index].type = | ||
1674 | POWER_STATE_TYPE_BALANCED; | ||
1675 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1676 | rdev->pm.power_state[state_index].type = | ||
1677 | POWER_STATE_TYPE_DEFAULT; | ||
1678 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1679 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1680 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1681 | } | ||
1682 | state_index++; | ||
1683 | break; | ||
1684 | } | ||
1685 | } | ||
1686 | } else if (frev == 4) { | ||
1687 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | ||
1688 | mode_index = 0; | ||
1689 | power_state = (struct _ATOM_PPLIB_STATE *) | ||
1690 | (mode_info->atom_context->bios + | ||
1691 | data_offset + | ||
1692 | le16_to_cpu(power_info->info_4.usStateArrayOffset) + | ||
1693 | i * power_info->info_4.ucStateEntrySize); | ||
1694 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | ||
1695 | (mode_info->atom_context->bios + | ||
1696 | data_offset + | ||
1697 | le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + | ||
1698 | (power_state->ucNonClockStateIndex * | ||
1699 | power_info->info_4.ucNonClockSize)); | ||
1700 | for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { | ||
1701 | if (rdev->flags & RADEON_IS_IGP) { | ||
1702 | struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = | ||
1703 | (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) | ||
1704 | (mode_info->atom_context->bios + | ||
1705 | data_offset + | ||
1706 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | ||
1707 | (power_state->ucClockStateIndices[j] * | ||
1708 | power_info->info_4.ucClockInfoSize)); | ||
1709 | sclk = le16_to_cpu(clock_info->usLowEngineClockLow); | ||
1710 | sclk |= clock_info->ucLowEngineClockHigh << 16; | ||
1711 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
1712 | /* skip invalid modes */ | ||
1713 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | ||
1714 | continue; | ||
1715 | /* skip overclock modes for now */ | ||
1716 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > | ||
1717 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN) | ||
1718 | continue; | ||
1719 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
1720 | VOLTAGE_SW; | ||
1721 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
1722 | clock_info->usVDDC; | ||
1723 | mode_index++; | ||
1724 | } else { | ||
1725 | struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = | ||
1726 | (struct _ATOM_PPLIB_R600_CLOCK_INFO *) | ||
1727 | (mode_info->atom_context->bios + | ||
1728 | data_offset + | ||
1729 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | ||
1730 | (power_state->ucClockStateIndices[j] * | ||
1731 | power_info->info_4.ucClockInfoSize)); | ||
1732 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | ||
1733 | sclk |= clock_info->ucEngineClockHigh << 16; | ||
1734 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | ||
1735 | mclk |= clock_info->ucMemoryClockHigh << 16; | ||
1736 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | ||
1737 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | ||
1738 | /* skip invalid modes */ | ||
1739 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | ||
1740 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | ||
1741 | continue; | ||
1742 | /* skip overclock modes for now */ | ||
1743 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk > | ||
1744 | rdev->clock.default_mclk + RADEON_MODE_OVERCLOCK_MARGIN) || | ||
1745 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk > | ||
1746 | rdev->clock.default_sclk + RADEON_MODE_OVERCLOCK_MARGIN)) | ||
1747 | continue; | ||
1748 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | ||
1749 | VOLTAGE_SW; | ||
1750 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
1751 | clock_info->usVDDC; | ||
1752 | mode_index++; | ||
1753 | } | ||
1754 | } | ||
1755 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
1756 | if (mode_index) { | ||
1757 | misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | ||
1758 | misc2 = le16_to_cpu(non_clock_info->usClassification); | ||
1759 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = | ||
1760 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> | ||
1761 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; | ||
1762 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { | ||
1763 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: | ||
1764 | rdev->pm.power_state[state_index].type = | ||
1765 | POWER_STATE_TYPE_BATTERY; | ||
1766 | break; | ||
1767 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: | ||
1768 | rdev->pm.power_state[state_index].type = | ||
1769 | POWER_STATE_TYPE_BALANCED; | ||
1770 | break; | ||
1771 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: | ||
1772 | rdev->pm.power_state[state_index].type = | ||
1773 | POWER_STATE_TYPE_PERFORMANCE; | ||
1774 | break; | ||
1775 | } | ||
1776 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { | ||
1777 | rdev->pm.power_state[state_index].type = | ||
1778 | POWER_STATE_TYPE_DEFAULT; | ||
1779 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1780 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1781 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | ||
1782 | } | ||
1783 | state_index++; | ||
1784 | } | ||
1785 | } | ||
1786 | } | ||
1787 | } else { | ||
1788 | /* XXX figure out some good default low power mode for cards w/out power tables */ | ||
1789 | } | ||
1790 | |||
1791 | if (rdev->pm.default_power_state == NULL) { | ||
1792 | /* add the default mode */ | ||
1793 | rdev->pm.power_state[state_index].type = | ||
1794 | POWER_STATE_TYPE_DEFAULT; | ||
1795 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1796 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; | ||
1797 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; | ||
1798 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1799 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1800 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1801 | if (rdev->asic->get_pcie_lanes) | ||
1802 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = radeon_get_pcie_lanes(rdev); | ||
1803 | else | ||
1804 | rdev->pm.power_state[state_index].non_clock_info.pcie_lanes = 16; | ||
1805 | rdev->pm.default_power_state = &rdev->pm.power_state[state_index]; | ||
1806 | state_index++; | ||
1807 | } | ||
1808 | rdev->pm.num_power_states = state_index; | ||
1809 | |||
1810 | rdev->pm.current_power_state = rdev->pm.default_power_state; | ||
1811 | rdev->pm.current_clock_mode = | ||
1812 | rdev->pm.default_power_state->default_clock_mode; | ||
1396 | } | 1813 | } |
1397 | 1814 | ||
1398 | void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable) | 1815 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) |
1399 | { | 1816 | { |
1400 | ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args; | 1817 | DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; |
1401 | int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt); | 1818 | int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); |
1402 | 1819 | ||
1403 | args.ucEnable = enable; | 1820 | args.ucEnable = enable; |
1404 | 1821 | ||