diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2014-03-17 23:48:16 -0400 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-03-25 08:13:17 -0400 |
commit | 6f50e0758795e21919d0d45e3c9ff441f6139575 (patch) | |
tree | 1471a456e042380a981865ddd6969555149a62b7 | |
parent | 2953da1589477c9aec85431339d28a8303d47945 (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.c | 82 |
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 | |||
1711 | static void | ||
1712 | radeon_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 | } |