aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2014-03-17 23:48:16 -0400
committerChristian König <christian.koenig@amd.com>2014-03-25 08:13:17 -0400
commit6f50e0758795e21919d0d45e3c9ff441f6139575 (patch)
tree1471a456e042380a981865ddd6969555149a62b7
parent2953da1589477c9aec85431339d28a8303d47945 (diff)
drm/radeon/atom: rework encoder enable/disable sequence
This more closely matches what the vbios does and also adds a quirk for travis lvds displays and powers down the sink on DP displays which saves some power and may fix display issues in some cases. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Christian König <christian.koenig@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c82
1 files changed, 34 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 607dc14d195e..e6eb5097597f 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1633,10 +1633,16 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
1633 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1633 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
1634 struct radeon_connector *radeon_connector = NULL; 1634 struct radeon_connector *radeon_connector = NULL;
1635 struct radeon_connector_atom_dig *radeon_dig_connector = NULL; 1635 struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
1636 bool travis_quirk = false;
1636 1637
1637 if (connector) { 1638 if (connector) {
1638 radeon_connector = to_radeon_connector(connector); 1639 radeon_connector = to_radeon_connector(connector);
1639 radeon_dig_connector = radeon_connector->con_priv; 1640 radeon_dig_connector = radeon_connector->con_priv;
1641 if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
1642 ENCODER_OBJECT_ID_TRAVIS) &&
1643 (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
1644 !ASIC_IS_DCE5(rdev))
1645 travis_quirk = true;
1640 } 1646 }
1641 1647
1642 switch (mode) { 1648 switch (mode) {
@@ -1657,17 +1663,13 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
1657 atombios_external_encoder_setup(encoder, ext_encoder, 1663 atombios_external_encoder_setup(encoder, ext_encoder,
1658 EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); 1664 EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
1659 } 1665 }
1660 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1661 } else if (ASIC_IS_DCE4(rdev)) { 1666 } else if (ASIC_IS_DCE4(rdev)) {
1662 /* setup and enable the encoder */ 1667 /* setup and enable the encoder */
1663 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); 1668 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
1664 /* enable the transmitter */
1665 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1666 } else { 1669 } else {
1667 /* setup and enable the encoder and transmitter */ 1670 /* setup and enable the encoder and transmitter */
1668 atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); 1671 atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
1669 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); 1672 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
1670 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1671 } 1673 }
1672 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { 1674 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
1673 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1675 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
@@ -1675,68 +1677,56 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
1675 ATOM_TRANSMITTER_ACTION_POWER_ON); 1677 ATOM_TRANSMITTER_ACTION_POWER_ON);
1676 radeon_dig_connector->edp_on = true; 1678 radeon_dig_connector->edp_on = true;
1677 } 1679 }
1680 }
1681 /* enable the transmitter */
1682 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1683 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
1684 /* DP_SET_POWER_D0 is set in radeon_dp_link_train */
1678 radeon_dp_link_train(encoder, connector); 1685 radeon_dp_link_train(encoder, connector);
1679 if (ASIC_IS_DCE4(rdev)) 1686 if (ASIC_IS_DCE4(rdev))
1680 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); 1687 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
1681 } 1688 }
1682 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1689 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
1683 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); 1690 atombios_dig_transmitter_setup(encoder,
1691 ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
1692 if (ext_encoder)
1693 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
1684 break; 1694 break;
1685 case DRM_MODE_DPMS_STANDBY: 1695 case DRM_MODE_DPMS_STANDBY:
1686 case DRM_MODE_DPMS_SUSPEND: 1696 case DRM_MODE_DPMS_SUSPEND:
1687 case DRM_MODE_DPMS_OFF: 1697 case DRM_MODE_DPMS_OFF:
1688 if (ASIC_IS_DCE4(rdev)) { 1698 if (ASIC_IS_DCE4(rdev)) {
1699 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector)
1700 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
1701 }
1702 if (ext_encoder)
1703 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
1704 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
1705 atombios_dig_transmitter_setup(encoder,
1706 ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
1707
1708 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) &&
1709 connector && !travis_quirk)
1710 radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3);
1711 if (ASIC_IS_DCE4(rdev)) {
1689 /* disable the transmitter */ 1712 /* disable the transmitter */
1690 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); 1713 atombios_dig_transmitter_setup(encoder,
1714 ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
1691 } else { 1715 } else {
1692 /* disable the encoder and transmitter */ 1716 /* disable the encoder and transmitter */
1693 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); 1717 atombios_dig_transmitter_setup(encoder,
1718 ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
1694 atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); 1719 atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
1695 } 1720 }
1696 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { 1721 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
1697 if (ASIC_IS_DCE4(rdev)) 1722 if (travis_quirk)
1698 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); 1723 radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3);
1699 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1724 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1700 atombios_set_edp_panel_power(connector, 1725 atombios_set_edp_panel_power(connector,
1701 ATOM_TRANSMITTER_ACTION_POWER_OFF); 1726 ATOM_TRANSMITTER_ACTION_POWER_OFF);
1702 radeon_dig_connector->edp_on = false; 1727 radeon_dig_connector->edp_on = false;
1703 } 1728 }
1704 } 1729 }
1705 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
1706 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
1707 break;
1708 }
1709}
1710
1711static void
1712radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder,
1713 struct drm_encoder *ext_encoder,
1714 int mode)
1715{
1716 struct drm_device *dev = encoder->dev;
1717 struct radeon_device *rdev = dev->dev_private;
1718
1719 switch (mode) {
1720 case DRM_MODE_DPMS_ON:
1721 default:
1722 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) {
1723 atombios_external_encoder_setup(encoder, ext_encoder,
1724 EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
1725 atombios_external_encoder_setup(encoder, ext_encoder,
1726 EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
1727 } else
1728 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
1729 break;
1730 case DRM_MODE_DPMS_STANDBY:
1731 case DRM_MODE_DPMS_SUSPEND:
1732 case DRM_MODE_DPMS_OFF:
1733 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) {
1734 atombios_external_encoder_setup(encoder, ext_encoder,
1735 EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
1736 atombios_external_encoder_setup(encoder, ext_encoder,
1737 EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
1738 } else
1739 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
1740 break; 1730 break;
1741 } 1731 }
1742} 1732}
@@ -1747,7 +1737,6 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1747 struct drm_device *dev = encoder->dev; 1737 struct drm_device *dev = encoder->dev;
1748 struct radeon_device *rdev = dev->dev_private; 1738 struct radeon_device *rdev = dev->dev_private;
1749 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1739 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1750 struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
1751 1740
1752 DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", 1741 DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
1753 radeon_encoder->encoder_id, mode, radeon_encoder->devices, 1742 radeon_encoder->encoder_id, mode, radeon_encoder->devices,
@@ -1807,9 +1796,6 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1807 return; 1796 return;
1808 } 1797 }
1809 1798
1810 if (ext_encoder)
1811 radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode);
1812
1813 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1799 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
1814 1800
1815} 1801}