Rev 5271 | Rev 6661 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5271 | Rev 6104 | ||
---|---|---|---|
Line 25... | Line 25... | ||
25 | */ |
25 | */ |
26 | #include |
26 | #include |
27 | #include |
27 | #include |
28 | #include |
28 | #include |
29 | #include "radeon.h" |
29 | #include "radeon.h" |
- | 30 | #include "radeon_audio.h" |
|
30 | #include "atom.h" |
31 | #include "atom.h" |
31 | #include |
32 | #include |
Line 32... | Line 33... | ||
32 | 33 | ||
Line 234... | Line 235... | ||
234 | bd->props.brightness = RADEON_MAX_BL_LEVEL; |
235 | bd->props.brightness = RADEON_MAX_BL_LEVEL; |
235 | bd->props.power = FB_BLANK_UNBLANK; |
236 | bd->props.power = FB_BLANK_UNBLANK; |
236 | backlight_update_status(bd); |
237 | backlight_update_status(bd); |
Line 237... | Line 238... | ||
237 | 238 | ||
- | 239 | DRM_INFO("radeon atom DIG backlight initialized\n"); |
|
Line 238... | Line 240... | ||
238 | DRM_INFO("radeon atom DIG backlight initialized\n"); |
240 | rdev->mode_info.bl_encoder = radeon_encoder; |
Line 239... | Line 241... | ||
239 | 241 | ||
240 | return; |
242 | return; |
Line 307... | Line 309... | ||
307 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) |
309 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) |
308 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
310 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
309 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
311 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
Line 310... | Line 312... | ||
310 | 312 | ||
311 | /* get the native mode for scaling */ |
313 | /* get the native mode for scaling */ |
312 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT|ATOM_DEVICE_DFP_SUPPORT)) { |
314 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { |
313 | radeon_panel_mode_fixup(encoder, adjusted_mode); |
315 | radeon_panel_mode_fixup(encoder, adjusted_mode); |
314 | } else if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { |
316 | } else if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { |
315 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
317 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
316 | if (tv_dac) { |
318 | if (tv_dac) { |
Line 662... | Line 664... | ||
662 | } |
664 | } |
Line 663... | Line 665... | ||
663 | 665 | ||
664 | int |
666 | int |
665 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
667 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
- | 668 | { |
|
- | 669 | struct drm_device *dev = encoder->dev; |
|
666 | { |
670 | struct radeon_device *rdev = dev->dev_private; |
667 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
671 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
668 | struct drm_connector *connector; |
672 | struct drm_connector *connector; |
669 | struct radeon_connector *radeon_connector; |
673 | struct radeon_connector *radeon_connector; |
- | 674 | struct radeon_connector_atom_dig *dig_connector; |
|
Line -... | Line 675... | ||
- | 675 | struct radeon_encoder_atom_dig *dig_enc; |
|
- | 676 | ||
- | 677 | if (radeon_encoder_is_digital(encoder)) { |
|
- | 678 | dig_enc = radeon_encoder->enc_priv; |
|
- | 679 | if (dig_enc->active_mst_links) |
|
- | 680 | return ATOM_ENCODER_MODE_DP_MST; |
|
- | 681 | } |
|
670 | struct radeon_connector_atom_dig *dig_connector; |
682 | if (radeon_encoder->is_mst_encoder || radeon_encoder->offset) |
671 | 683 | return ATOM_ENCODER_MODE_DP_MST; |
|
672 | /* dp bridges are always DP */ |
684 | /* dp bridges are always DP */ |
Line 673... | Line 685... | ||
673 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) |
685 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) |
Line 726... | Line 738... | ||
726 | break; |
738 | break; |
727 | case DRM_MODE_CONNECTOR_DisplayPort: |
739 | case DRM_MODE_CONNECTOR_DisplayPort: |
728 | dig_connector = radeon_connector->con_priv; |
740 | dig_connector = radeon_connector->con_priv; |
729 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
741 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
730 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
742 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
- | 743 | if (radeon_audio != 0 && |
|
- | 744 | drm_detect_monitor_audio(radeon_connector_edid(connector)) && |
|
- | 745 | ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) |
|
- | 746 | return ATOM_ENCODER_MODE_DP_AUDIO; |
|
731 | return ATOM_ENCODER_MODE_DP; |
747 | return ATOM_ENCODER_MODE_DP; |
732 | } else if (radeon_audio != 0) { |
748 | } else if (radeon_audio != 0) { |
733 | if (radeon_connector->audio == RADEON_AUDIO_ENABLE) |
749 | if (radeon_connector->audio == RADEON_AUDIO_ENABLE) |
734 | return ATOM_ENCODER_MODE_HDMI; |
750 | return ATOM_ENCODER_MODE_HDMI; |
735 | else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && |
751 | else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && |
Line 740... | Line 756... | ||
740 | } else { |
756 | } else { |
741 | return ATOM_ENCODER_MODE_DVI; |
757 | return ATOM_ENCODER_MODE_DVI; |
742 | } |
758 | } |
743 | break; |
759 | break; |
744 | case DRM_MODE_CONNECTOR_eDP: |
760 | case DRM_MODE_CONNECTOR_eDP: |
- | 761 | if (radeon_audio != 0 && |
|
- | 762 | drm_detect_monitor_audio(radeon_connector_edid(connector)) && |
|
- | 763 | ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) |
|
- | 764 | return ATOM_ENCODER_MODE_DP_AUDIO; |
|
745 | return ATOM_ENCODER_MODE_DP; |
765 | return ATOM_ENCODER_MODE_DP; |
746 | case DRM_MODE_CONNECTOR_DVIA: |
766 | case DRM_MODE_CONNECTOR_DVIA: |
747 | case DRM_MODE_CONNECTOR_VGA: |
767 | case DRM_MODE_CONNECTOR_VGA: |
748 | return ATOM_ENCODER_MODE_CRT; |
768 | return ATOM_ENCODER_MODE_CRT; |
749 | break; |
769 | break; |
Line 810... | Line 830... | ||
810 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; |
830 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; |
811 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; |
831 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; |
812 | }; |
832 | }; |
Line 813... | Line 833... | ||
813 | 833 | ||
814 | void |
834 | void |
815 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) |
835 | atombios_dig_encoder_setup2(struct drm_encoder *encoder, int action, int panel_mode, int enc_override) |
816 | { |
836 | { |
817 | struct drm_device *dev = encoder->dev; |
837 | struct drm_device *dev = encoder->dev; |
818 | struct radeon_device *rdev = dev->dev_private; |
838 | struct radeon_device *rdev = dev->dev_private; |
819 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
839 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
Line 907... | Line 927... | ||
907 | else |
927 | else |
908 | args.v3.ucLaneNum = 4; |
928 | args.v3.ucLaneNum = 4; |
Line 909... | Line 929... | ||
909 | 929 | ||
910 | if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000)) |
930 | if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000)) |
- | 931 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; |
|
- | 932 | if (enc_override != -1) |
|
- | 933 | args.v3.acConfig.ucDigSel = enc_override; |
|
911 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; |
934 | else |
912 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
935 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
913 | args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder); |
936 | args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder); |
914 | break; |
937 | break; |
915 | case 4: |
938 | case 4: |
Line 935... | Line 958... | ||
935 | else if (dp_clock == 270000) |
958 | else if (dp_clock == 270000) |
936 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; |
959 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; |
937 | else |
960 | else |
938 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ; |
961 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ; |
939 | } |
962 | } |
- | 963 | ||
- | 964 | if (enc_override != -1) |
|
- | 965 | args.v4.acConfig.ucDigSel = enc_override; |
|
- | 966 | else |
|
940 | args.v4.acConfig.ucDigSel = dig->dig_encoder; |
967 | args.v4.acConfig.ucDigSel = dig->dig_encoder; |
941 | args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder); |
968 | args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder); |
942 | if (hpd_id == RADEON_HPD_NONE) |
969 | if (hpd_id == RADEON_HPD_NONE) |
943 | args.v4.ucHPD_ID = 0; |
970 | args.v4.ucHPD_ID = 0; |
944 | else |
971 | else |
Line 956... | Line 983... | ||
956 | 983 | ||
Line 957... | Line 984... | ||
957 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
984 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line -... | Line 985... | ||
- | 985 | ||
- | 986 | } |
|
- | 987 | ||
- | 988 | void |
|
- | 989 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) |
|
- | 990 | { |
|
958 | 991 | atombios_dig_encoder_setup2(encoder, action, panel_mode, -1); |
|
959 | } |
992 | } |
960 | 993 | ||
961 | union dig_transmitter_control { |
994 | union dig_transmitter_control { |
962 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
995 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
963 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
996 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
964 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; |
997 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; |
Line 965... | Line 998... | ||
965 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; |
998 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; |
966 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5; |
999 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5; |
967 | }; |
1000 | }; |
968 | 1001 | ||
969 | void |
1002 | void |
970 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
1003 | atombios_dig_transmitter_setup2(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set, int fe) |
971 | { |
1004 | { |
Line 1315... | Line 1348... | ||
1315 | } |
1348 | } |
1316 | if (hpd_id == RADEON_HPD_NONE) |
1349 | if (hpd_id == RADEON_HPD_NONE) |
1317 | args.v5.asConfig.ucHPDSel = 0; |
1350 | args.v5.asConfig.ucHPDSel = 0; |
1318 | else |
1351 | else |
1319 | args.v5.asConfig.ucHPDSel = hpd_id + 1; |
1352 | args.v5.asConfig.ucHPDSel = hpd_id + 1; |
1320 | args.v5.ucDigEncoderSel = 1 << dig_encoder; |
1353 | args.v5.ucDigEncoderSel = (fe != -1) ? (1 << fe) : (1 << dig_encoder); |
1321 | args.v5.ucDPLaneSet = lane_set; |
1354 | args.v5.ucDPLaneSet = lane_set; |
1322 | break; |
1355 | break; |
1323 | default: |
1356 | default: |
1324 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
1357 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
1325 | break; |
1358 | break; |
Line 1331... | Line 1364... | ||
1331 | } |
1364 | } |
Line 1332... | Line 1365... | ||
1332 | 1365 | ||
1333 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1366 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
Line -... | Line 1367... | ||
- | 1367 | } |
|
- | 1368 | ||
- | 1369 | void |
|
- | 1370 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
|
- | 1371 | { |
|
- | 1372 | atombios_dig_transmitter_setup2(encoder, action, lane_num, lane_set, -1); |
|
1334 | } |
1373 | } |
1335 | 1374 | ||
1336 | bool |
1375 | bool |
1337 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) |
1376 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) |
1338 | { |
1377 | { |
Line 1584... | Line 1623... | ||
1584 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1623 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1585 | WREG32(RADEON_BIOS_3_SCRATCH, reg); |
1624 | WREG32(RADEON_BIOS_3_SCRATCH, reg); |
1586 | } else |
1625 | } else |
1587 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1626 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1588 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
1627 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
- | 1628 | if (rdev->mode_info.bl_encoder) { |
|
- | 1629 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
|
- | 1630 | ||
- | 1631 | atombios_set_backlight_level(radeon_encoder, dig->backlight_level); |
|
- | 1632 | } else { |
|
1589 | args.ucAction = ATOM_LCD_BLON; |
1633 | args.ucAction = ATOM_LCD_BLON; |
1590 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1634 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1591 | } |
1635 | } |
- | 1636 | } |
|
1592 | break; |
1637 | break; |
1593 | case DRM_MODE_DPMS_STANDBY: |
1638 | case DRM_MODE_DPMS_STANDBY: |
1594 | case DRM_MODE_DPMS_SUSPEND: |
1639 | case DRM_MODE_DPMS_SUSPEND: |
1595 | case DRM_MODE_DPMS_OFF: |
1640 | case DRM_MODE_DPMS_OFF: |
1596 | args.ucAction = ATOM_DISABLE; |
1641 | args.ucAction = ATOM_DISABLE; |
Line 1665... | Line 1710... | ||
1665 | /* DP_SET_POWER_D0 is set in radeon_dp_link_train */ |
1710 | /* DP_SET_POWER_D0 is set in radeon_dp_link_train */ |
1666 | radeon_dp_link_train(encoder, connector); |
1711 | radeon_dp_link_train(encoder, connector); |
1667 | if (ASIC_IS_DCE4(rdev)) |
1712 | if (ASIC_IS_DCE4(rdev)) |
1668 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); |
1713 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); |
1669 | } |
1714 | } |
1670 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
1715 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
- | 1716 | if (rdev->mode_info.bl_encoder) |
|
- | 1717 | atombios_set_backlight_level(radeon_encoder, dig->backlight_level); |
|
- | 1718 | else |
|
1671 | atombios_dig_transmitter_setup(encoder, |
1719 | atombios_dig_transmitter_setup(encoder, |
1672 | ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); |
1720 | ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); |
- | 1721 | } |
|
1673 | if (ext_encoder) |
1722 | if (ext_encoder) |
1674 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); |
1723 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); |
1675 | break; |
1724 | break; |
1676 | case DRM_MODE_DPMS_STANDBY: |
1725 | case DRM_MODE_DPMS_STANDBY: |
1677 | case DRM_MODE_DPMS_SUSPEND: |
1726 | case DRM_MODE_DPMS_SUSPEND: |
1678 | case DRM_MODE_DPMS_OFF: |
1727 | case DRM_MODE_DPMS_OFF: |
- | 1728 | ||
- | 1729 | /* don't power off encoders with active MST links */ |
|
- | 1730 | if (dig->active_mst_links) |
|
- | 1731 | return; |
|
- | 1732 | ||
1679 | if (ASIC_IS_DCE4(rdev)) { |
1733 | if (ASIC_IS_DCE4(rdev)) { |
1680 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) |
1734 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) |
1681 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
1735 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
1682 | } |
1736 | } |
1683 | if (ext_encoder) |
1737 | if (ext_encoder) |
Line 1716... | Line 1770... | ||
1716 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) |
1770 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) |
1717 | { |
1771 | { |
1718 | struct drm_device *dev = encoder->dev; |
1772 | struct drm_device *dev = encoder->dev; |
1719 | struct radeon_device *rdev = dev->dev_private; |
1773 | struct radeon_device *rdev = dev->dev_private; |
1720 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1774 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
- | 1775 | int encoder_mode = atombios_get_encoder_mode(encoder); |
|
Line 1721... | Line 1776... | ||
1721 | 1776 | ||
1722 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
1777 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
1723 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
1778 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
- | 1779 | radeon_encoder->active_device); |
|
- | 1780 | ||
- | 1781 | if ((radeon_audio != 0) && |
|
- | 1782 | ((encoder_mode == ATOM_ENCODER_MODE_HDMI) || |
|
- | 1783 | ENCODER_MODE_IS_DP(encoder_mode))) |
|
- | 1784 | radeon_audio_dpms(encoder, mode); |
|
1724 | radeon_encoder->active_device); |
1785 | |
1725 | switch (radeon_encoder->encoder_id) { |
1786 | switch (radeon_encoder->encoder_id) { |
1726 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: |
1787 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: |
1727 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
1788 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
1728 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
1789 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
Line 1933... | Line 1994... | ||
1933 | 1994 | ||
1934 | /* update scratch regs with new routing */ |
1995 | /* update scratch regs with new routing */ |
1935 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
1996 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
Line -... | Line 1997... | ||
- | 1997 | } |
|
- | 1998 | ||
- | 1999 | void |
|
- | 2000 | atombios_set_mst_encoder_crtc_source(struct drm_encoder *encoder, int fe) |
|
- | 2001 | { |
|
- | 2002 | struct drm_device *dev = encoder->dev; |
|
- | 2003 | struct radeon_device *rdev = dev->dev_private; |
|
- | 2004 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
|
- | 2005 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); |
|
- | 2006 | uint8_t frev, crev; |
|
- | 2007 | union crtc_source_param args; |
|
- | 2008 | ||
- | 2009 | memset(&args, 0, sizeof(args)); |
|
- | 2010 | ||
- | 2011 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
|
- | 2012 | return; |
|
- | 2013 | ||
- | 2014 | if (frev != 1 && crev != 2) |
|
- | 2015 | DRM_ERROR("Unknown table for MST %d, %d\n", frev, crev); |
|
- | 2016 | ||
- | 2017 | args.v2.ucCRTC = radeon_crtc->crtc_id; |
|
- | 2018 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_DP_MST; |
|
- | 2019 | ||
- | 2020 | switch (fe) { |
|
- | 2021 | case 0: |
|
- | 2022 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
|
- | 2023 | break; |
|
- | 2024 | case 1: |
|
- | 2025 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
|
- | 2026 | break; |
|
- | 2027 | case 2: |
|
- | 2028 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; |
|
- | 2029 | break; |
|
- | 2030 | case 3: |
|
- | 2031 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; |
|
- | 2032 | break; |
|
- | 2033 | case 4: |
|
- | 2034 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; |
|
- | 2035 | break; |
|
- | 2036 | case 5: |
|
- | 2037 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; |
|
- | 2038 | break; |
|
- | 2039 | case 6: |
|
- | 2040 | args.v2.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID; |
|
- | 2041 | break; |
|
- | 2042 | } |
|
- | 2043 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
1936 | } |
2044 | } |
1937 | 2045 | ||
1938 | static void |
2046 | static void |
1939 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, |
2047 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, |
1940 | struct drm_display_mode *mode) |
2048 | struct drm_display_mode *mode) |
Line 1981... | Line 2089... | ||
1981 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
2089 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
1982 | } |
2090 | } |
1983 | } |
2091 | } |
1984 | } |
2092 | } |
Line -... | Line 2093... | ||
- | 2093 | ||
- | 2094 | void radeon_atom_release_dig_encoder(struct radeon_device *rdev, int enc_idx) |
|
- | 2095 | { |
|
- | 2096 | if (enc_idx < 0) |
|
- | 2097 | return; |
|
- | 2098 | rdev->mode_info.active_encoders &= ~(1 << enc_idx); |
|
- | 2099 | } |
|
1985 | 2100 | ||
1986 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) |
2101 | int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder, int fe_idx) |
1987 | { |
2102 | { |
1988 | struct drm_device *dev = encoder->dev; |
2103 | struct drm_device *dev = encoder->dev; |
1989 | struct radeon_device *rdev = dev->dev_private; |
2104 | struct radeon_device *rdev = dev->dev_private; |
1990 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
2105 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1991 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
2106 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1992 | struct drm_encoder *test_encoder; |
2107 | struct drm_encoder *test_encoder; |
1993 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
2108 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | 2109 | uint32_t dig_enc_in_use = 0; |
|
Line -... | Line 2110... | ||
- | 2110 | int enc_idx = -1; |
|
- | 2111 | ||
- | 2112 | if (fe_idx >= 0) { |
|
- | 2113 | enc_idx = fe_idx; |
|
1994 | uint32_t dig_enc_in_use = 0; |
2114 | goto assigned; |
1995 | 2115 | } |
|
1996 | if (ASIC_IS_DCE6(rdev)) { |
2116 | if (ASIC_IS_DCE6(rdev)) { |
1997 | /* DCE6 */ |
2117 | /* DCE6 */ |
1998 | switch (radeon_encoder->encoder_id) { |
2118 | switch (radeon_encoder->encoder_id) { |
1999 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
2119 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
2000 | if (dig->linkb) |
2120 | if (dig->linkb) |
2001 | return 1; |
2121 | enc_idx = 1; |
2002 | else |
2122 | else |
2003 | return 0; |
2123 | enc_idx = 0; |
2004 | break; |
2124 | break; |
2005 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2125 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2006 | if (dig->linkb) |
2126 | if (dig->linkb) |
2007 | return 3; |
2127 | enc_idx = 3; |
2008 | else |
2128 | else |
2009 | return 2; |
2129 | enc_idx = 2; |
2010 | break; |
2130 | break; |
2011 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2131 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2012 | if (dig->linkb) |
2132 | if (dig->linkb) |
2013 | return 5; |
2133 | enc_idx = 5; |
2014 | else |
2134 | else |
2015 | return 4; |
2135 | enc_idx = 4; |
2016 | break; |
2136 | break; |
2017 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
2137 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
2018 | return 6; |
2138 | enc_idx = 6; |
- | 2139 | break; |
|
2019 | break; |
2140 | } |
2020 | } |
2141 | goto assigned; |
2021 | } else if (ASIC_IS_DCE4(rdev)) { |
2142 | } else if (ASIC_IS_DCE4(rdev)) { |
2022 | /* DCE4/5 */ |
2143 | /* DCE4/5 */ |
2023 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { |
2144 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { |
2024 | /* ontario follows DCE4 */ |
2145 | /* ontario follows DCE4 */ |
2025 | if (rdev->family == CHIP_PALM) { |
2146 | if (rdev->family == CHIP_PALM) { |
2026 | if (dig->linkb) |
2147 | if (dig->linkb) |
2027 | return 1; |
2148 | enc_idx = 1; |
2028 | else |
2149 | else |
2029 | return 0; |
2150 | enc_idx = 0; |
2030 | } else |
2151 | } else |
2031 | /* llano follows DCE3.2 */ |
2152 | /* llano follows DCE3.2 */ |
2032 | return radeon_crtc->crtc_id; |
2153 | enc_idx = radeon_crtc->crtc_id; |
2033 | } else { |
2154 | } else { |
2034 | switch (radeon_encoder->encoder_id) { |
2155 | switch (radeon_encoder->encoder_id) { |
2035 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
2156 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
2036 | if (dig->linkb) |
2157 | if (dig->linkb) |
2037 | return 1; |
2158 | enc_idx = 1; |
2038 | else |
2159 | else |
2039 | return 0; |
2160 | enc_idx = 0; |
2040 | break; |
2161 | break; |
2041 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2162 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2042 | if (dig->linkb) |
2163 | if (dig->linkb) |
2043 | return 3; |
2164 | enc_idx = 3; |
2044 | else |
2165 | else |
2045 | return 2; |
2166 | enc_idx = 2; |
2046 | break; |
2167 | break; |
2047 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2168 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2048 | if (dig->linkb) |
2169 | if (dig->linkb) |
2049 | return 5; |
2170 | enc_idx = 5; |
2050 | else |
2171 | else |
2051 | return 4; |
2172 | enc_idx = 4; |
2052 | break; |
2173 | break; |
- | 2174 | } |
|
2053 | } |
2175 | } |
Line 2054... | Line 2176... | ||
2054 | } |
2176 | goto assigned; |
2055 | } |
2177 | } |
2056 | 2178 | ||
- | 2179 | /* on DCE32 and encoder can driver any block so just crtc id */ |
|
2057 | /* on DCE32 and encoder can driver any block so just crtc id */ |
2180 | if (ASIC_IS_DCE32(rdev)) { |
Line 2058... | Line 2181... | ||
2058 | if (ASIC_IS_DCE32(rdev)) { |
2181 | enc_idx = radeon_crtc->crtc_id; |
2059 | return radeon_crtc->crtc_id; |
2182 | goto assigned; |
2060 | } |
2183 | } |
Line 2082... | Line 2205... | ||
2082 | return 1; |
2205 | return 1; |
2083 | } |
2206 | } |
2084 | if (!(dig_enc_in_use & 1)) |
2207 | if (!(dig_enc_in_use & 1)) |
2085 | return 0; |
2208 | return 0; |
2086 | return 1; |
2209 | return 1; |
- | 2210 | ||
- | 2211 | assigned: |
|
- | 2212 | if (enc_idx == -1) { |
|
- | 2213 | DRM_ERROR("Got encoder index incorrect - returning 0\n"); |
|
- | 2214 | return 0; |
|
- | 2215 | } |
|
- | 2216 | if (rdev->mode_info.active_encoders & (1 << enc_idx)) { |
|
- | 2217 | DRM_ERROR("chosen encoder in use %d\n", enc_idx); |
|
- | 2218 | } |
|
- | 2219 | rdev->mode_info.active_encoders |= (1 << enc_idx); |
|
- | 2220 | return enc_idx; |
|
2087 | } |
2221 | } |
Line 2088... | Line 2222... | ||
2088 | 2222 | ||
2089 | /* This only needs to be called once at startup */ |
2223 | /* This only needs to be called once at startup */ |
2090 | void |
2224 | void |
Line 2121... | Line 2255... | ||
2121 | struct drm_display_mode *adjusted_mode) |
2255 | struct drm_display_mode *adjusted_mode) |
2122 | { |
2256 | { |
2123 | struct drm_device *dev = encoder->dev; |
2257 | struct drm_device *dev = encoder->dev; |
2124 | struct radeon_device *rdev = dev->dev_private; |
2258 | struct radeon_device *rdev = dev->dev_private; |
2125 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
2259 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
- | 2260 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
|
- | 2261 | int encoder_mode; |
|
Line 2126... | Line 2262... | ||
2126 | 2262 | ||
Line 2127... | Line 2263... | ||
2127 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
2263 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
2128 | 2264 | ||
Line 2169... | Line 2305... | ||
2169 | break; |
2305 | break; |
2170 | } |
2306 | } |
Line 2171... | Line 2307... | ||
2171 | 2307 | ||
Line 2172... | Line 2308... | ||
2172 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
2308 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
2173 | 2309 | ||
2174 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
2310 | encoder_mode = atombios_get_encoder_mode(encoder); |
2175 | if (rdev->asic->display.hdmi_enable) |
2311 | if (connector && (radeon_audio != 0) && |
2176 | radeon_hdmi_enable(rdev, encoder, true); |
2312 | ((encoder_mode == ATOM_ENCODER_MODE_HDMI) || |
2177 | if (rdev->asic->display.hdmi_setmode) |
- | |
2178 | radeon_hdmi_setmode(rdev, encoder, adjusted_mode); |
2313 | ENCODER_MODE_IS_DP(encoder_mode))) |
Line 2179... | Line 2314... | ||
2179 | } |
2314 | radeon_audio_mode_set(encoder, adjusted_mode); |
2180 | } |
2315 | } |
2181 | 2316 | ||
Line 2338... | Line 2473... | ||
2338 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || |
2473 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || |
2339 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
2474 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
2340 | ENCODER_OBJECT_ID_NONE)) { |
2475 | ENCODER_OBJECT_ID_NONE)) { |
2341 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
2476 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
2342 | if (dig) { |
2477 | if (dig) { |
- | 2478 | if (dig->dig_encoder >= 0) |
|
- | 2479 | radeon_atom_release_dig_encoder(rdev, dig->dig_encoder); |
|
2343 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); |
2480 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder, -1); |
2344 | if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) { |
2481 | if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) { |
2345 | if (rdev->family >= CHIP_R600) |
2482 | if (rdev->family >= CHIP_R600) |
2346 | dig->afmt = rdev->mode_info.afmt[dig->dig_encoder]; |
2483 | dig->afmt = rdev->mode_info.afmt[dig->dig_encoder]; |
2347 | else |
2484 | else |
2348 | /* RS600/690/740 have only 1 afmt block */ |
2485 | /* RS600/690/740 have only 1 afmt block */ |
Line 2444... | Line 2581... | ||
2444 | if (radeon_encoder_is_digital(encoder)) { |
2581 | if (radeon_encoder_is_digital(encoder)) { |
2445 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
2582 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
2446 | if (rdev->asic->display.hdmi_enable) |
2583 | if (rdev->asic->display.hdmi_enable) |
2447 | radeon_hdmi_enable(rdev, encoder, false); |
2584 | radeon_hdmi_enable(rdev, encoder, false); |
2448 | } |
2585 | } |
- | 2586 | if (atombios_get_encoder_mode(encoder) != ATOM_ENCODER_MODE_DP_MST) { |
|
2449 | dig = radeon_encoder->enc_priv; |
2587 | dig = radeon_encoder->enc_priv; |
- | 2588 | radeon_atom_release_dig_encoder(rdev, dig->dig_encoder); |
|
2450 | dig->dig_encoder = -1; |
2589 | dig->dig_encoder = -1; |
- | 2590 | radeon_encoder->active_device = 0; |
|
2451 | } |
2591 | } |
- | 2592 | } else |
|
2452 | radeon_encoder->active_device = 0; |
2593 | radeon_encoder->active_device = 0; |
2453 | } |
2594 | } |
Line 2454... | Line 2595... | ||
2454 | 2595 | ||
2455 | /* these are handled by the primary encoders */ |
2596 | /* these are handled by the primary encoders */ |