Lines Matching +full:dp +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0
7 * Author: Wyon Bi <bivvy.bi@rock-chips.com>
8 * Zhang Yubing <yubing.zhang@rock-chips.com>
26 #include <linux/extcon-provider.h>
34 #include <linux/phy/phy.h>
39 #include <sound/hdmi-codec.h>
350 struct phy *phy; member
495 static int dw_dp_hdcp_init_keys(struct dw_dp *dp) in dw_dp_hdcp_init_keys() argument
503 regmap_read(dp->regmap, DPTX_HDCPREG_RMLSTS, &val); in dw_dp_hdcp_init_keys()
505 dev_info(dp->dev, "dpk keys already write\n"); in dw_dp_hdcp_init_keys()
511 dev_info(dp->dev, "HDCP: read size %d\n", size); in dw_dp_hdcp_init_keys()
512 return -EINVAL; in dw_dp_hdcp_init_keys()
515 base = sip_hdcp_request_share_memory(dp->id ? DP_TX1 : DP_TX0); in dw_dp_hdcp_init_keys()
517 return -ENOMEM; in dw_dp_hdcp_init_keys()
521 res = sip_hdcp_config(HDCP_FUNC_KEY_LOAD, dp->id ? DP_TX1 : DP_TX0, 0); in dw_dp_hdcp_init_keys()
523 dev_err(dp->dev, "load hdcp key failed\n"); in dw_dp_hdcp_init_keys()
524 return -EBUSY; in dw_dp_hdcp_init_keys()
530 static int dw_dp_hdcp_rng_init(struct dw_dp *dp) in dw_dp_hdcp_rng_init() argument
534 regmap_write(dp->regmap, DPTX_HDCPREG_ANCONF, OANBYPASS); in dw_dp_hdcp_rng_init()
536 regmap_write(dp->regmap, DPTX_HDCPREG_AN0, random_val); in dw_dp_hdcp_rng_init()
538 regmap_write(dp->regmap, DPTX_HDCPREG_AN1, random_val); in dw_dp_hdcp_rng_init()
543 static int dw_dp_hw_hdcp_init(struct dw_dp *dp) in dw_dp_hw_hdcp_init() argument
545 regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, HDCP_MODULE_RESET, in dw_dp_hw_hdcp_init()
548 regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, HDCP_MODULE_RESET, in dw_dp_hw_hdcp_init()
551 regmap_update_bits(dp->regmap, DPTX_GENERAL_INTERRUPT_ENABLE, in dw_dp_hw_hdcp_init()
557 static bool dw_dp_hdcp2_capable(struct dw_dp *dp) in dw_dp_hdcp2_capable() argument
562 ret = drm_dp_dpcd_read(&dp->aux, DP_HDCP_2_2_REG_RX_CAPS_OFFSET, in dw_dp_hdcp2_capable()
565 dev_err(dp->dev, "get hdcp2 capable failed:%d\n", ret); in dw_dp_hdcp2_capable()
576 static int _dw_dp_hdcp2_disable(struct dw_dp *dp) in _dw_dp_hdcp2_disable() argument
578 struct dw_dp_hdcp *hdcp = &dp->hdcp; in _dw_dp_hdcp2_disable()
580 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, ENABLE_HDCP, 0); in _dw_dp_hdcp2_disable()
581 clk_disable_unprepare(dp->hdcp_clk); in _dw_dp_hdcp2_disable()
583 hdcp->status = HDCP_TX_NONE; in _dw_dp_hdcp2_disable()
585 dp->hdcp.hdcp2_encrypted = false; in _dw_dp_hdcp2_disable()
590 static int dw_dp_hdcp2_auth_check(struct dw_dp *dp) in dw_dp_hdcp2_auth_check() argument
595 ret = regmap_read_poll_timeout(dp->regmap, DPTX_HDCPOBS, val, in dw_dp_hdcp2_auth_check()
598 dev_err(dp->dev, "wait HDCP2 controller booted timeout\n"); in dw_dp_hdcp2_auth_check()
602 ret = regmap_read_poll_timeout(dp->regmap, DPTX_HDCPOBS, val, in dw_dp_hdcp2_auth_check()
607 dev_err(dp->dev, "sink not support HDCP2\n"); in dw_dp_hdcp2_auth_check()
611 ret = regmap_read_poll_timeout(dp->regmap, DPTX_HDCPOBS, val, in dw_dp_hdcp2_auth_check()
615 dev_err(dp->dev, "wait hdcp22 controller auth timeout\n"); in dw_dp_hdcp2_auth_check()
619 dp->hdcp.hdcp2_encrypted = true; in dw_dp_hdcp2_auth_check()
621 dev_info(dp->dev, "HDCP2 authentication succeed\n"); in dw_dp_hdcp2_auth_check()
626 static int _dw_dp_hdcp2_enable(struct dw_dp *dp) in _dw_dp_hdcp2_enable() argument
628 struct dw_dp_hdcp *hdcp = &dp->hdcp; in _dw_dp_hdcp2_enable()
630 hdcp->status = HDCP_TX_2; in _dw_dp_hdcp2_enable()
632 clk_prepare_enable(dp->hdcp_clk); in _dw_dp_hdcp2_enable()
634 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, ENABLE_HDCP, ENABLE_HDCP); in _dw_dp_hdcp2_enable()
636 return dw_dp_hdcp2_auth_check(dp); in _dw_dp_hdcp2_enable()
639 static bool dw_dp_hdcp_capable(struct dw_dp *dp) in dw_dp_hdcp_capable() argument
644 ret = drm_dp_dpcd_readb(&dp->aux, DP_AUX_HDCP_BCAPS, &bcaps); in dw_dp_hdcp_capable()
646 dev_err(dp->dev, "get hdcp capable failed:%d\n", ret); in dw_dp_hdcp_capable()
653 static int _dw_dp_hdcp_disable(struct dw_dp *dp) in _dw_dp_hdcp_disable() argument
655 struct dw_dp_hdcp *hdcp = &dp->hdcp; in _dw_dp_hdcp_disable()
657 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, ENABLE_HDCP | ENABLE_HDCP_13, 0); in _dw_dp_hdcp_disable()
659 hdcp->status = HDCP_TX_NONE; in _dw_dp_hdcp_disable()
661 dp->hdcp.hdcp_encrypted = false; in _dw_dp_hdcp_disable()
666 static int dw_dp_hdcp_auth_check(struct dw_dp *dp) in dw_dp_hdcp_auth_check() argument
671 ret = regmap_read_poll_timeout(dp->regmap, DPTX_HDCPAPIINTSTAT, val, in dw_dp_hdcp_auth_check()
675 dev_err(dp->dev, " HDCP authentication process failed\n"); in dw_dp_hdcp_auth_check()
676 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, HDCP_FAILED); in dw_dp_hdcp_auth_check()
680 dev_err(dp->dev, "Aux received nack response continuously for 7 times\n"); in dw_dp_hdcp_auth_check()
681 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, AUXRESPNACK7TIMES); in dw_dp_hdcp_auth_check()
685 dev_err(dp->dev, "Aux did not receive a response and timedout\n"); in dw_dp_hdcp_auth_check()
686 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, AUXRESPTIMEOUT); in dw_dp_hdcp_auth_check()
690 dev_err(dp->dev, "Aux received defer response continuously for 7 times\n"); in dw_dp_hdcp_auth_check()
691 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, AUXRESPDEFER7TIMES); in dw_dp_hdcp_auth_check()
694 dev_err(dp->dev, "HDCP authentication timeout\n"); in dw_dp_hdcp_auth_check()
696 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, HDCP_ENGAGED); in dw_dp_hdcp_auth_check()
697 dp->hdcp.hdcp_encrypted = true; in dw_dp_hdcp_auth_check()
698 dev_info(dp->dev, "HDCP authentication succeed\n"); in dw_dp_hdcp_auth_check()
704 static int _dw_dp_hdcp_enable(struct dw_dp *dp) in _dw_dp_hdcp_enable() argument
708 struct dw_dp_hdcp *hdcp = &dp->hdcp; in _dw_dp_hdcp_enable()
710 hdcp->status = HDCP_TX_1; in _dw_dp_hdcp_enable()
712 dw_dp_hdcp_rng_init(dp); in _dw_dp_hdcp_enable()
714 ret = dw_dp_hdcp_init_keys(dp); in _dw_dp_hdcp_enable()
718 ret = drm_dp_dpcd_readb(&dp->aux, DP_DPCD_REV, &rev); in _dw_dp_hdcp_enable()
723 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, DPCD12PLUS, DPCD12PLUS); in _dw_dp_hdcp_enable()
725 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, ENABLE_HDCP | ENABLE_HDCP_13, in _dw_dp_hdcp_enable()
728 return dw_dp_hdcp_auth_check(dp); in _dw_dp_hdcp_enable()
733 static int dw_dp_hdcp_enable(struct dw_dp *dp, u8 content_type) in dw_dp_hdcp_enable() argument
735 int ret = -EINVAL; in dw_dp_hdcp_enable()
737 dp->hdcp.check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; in dw_dp_hdcp_enable()
738 mutex_lock(&dp->hdcp.mutex); in dw_dp_hdcp_enable()
739 sip_hdcp_config(HDCP_FUNC_ENCRYPT_MODE, dp->id ? DP_TX1 : DP_TX0, 0x0); in dw_dp_hdcp_enable()
740 dw_dp_hw_hdcp_init(dp); in dw_dp_hdcp_enable()
741 if (dw_dp_hdcp2_capable(dp)) { in dw_dp_hdcp_enable()
742 ret = _dw_dp_hdcp2_enable(dp); in dw_dp_hdcp_enable()
744 dp->hdcp.check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS; in dw_dp_hdcp_enable()
746 _dw_dp_hdcp2_disable(dp); in dw_dp_hdcp_enable()
749 if (ret && dw_dp_hdcp_capable(dp) && content_type != DRM_MODE_HDCP_CONTENT_TYPE1) { in dw_dp_hdcp_enable()
750 ret = _dw_dp_hdcp_enable(dp); in dw_dp_hdcp_enable()
752 dp->hdcp.check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; in dw_dp_hdcp_enable()
754 _dw_dp_hdcp_disable(dp); in dw_dp_hdcp_enable()
760 dp->hdcp.hdcp_content_type = content_type; in dw_dp_hdcp_enable()
761 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED; in dw_dp_hdcp_enable()
762 schedule_work(&dp->hdcp.prop_work); in dw_dp_hdcp_enable()
763 schedule_delayed_work(&dp->hdcp.check_work, dp->hdcp.check_link_interval); in dw_dp_hdcp_enable()
766 mutex_unlock(&dp->hdcp.mutex); in dw_dp_hdcp_enable()
770 static int dw_dp_hdcp_disable(struct dw_dp *dp) in dw_dp_hdcp_disable() argument
774 mutex_lock(&dp->hdcp.mutex); in dw_dp_hdcp_disable()
775 if (dp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { in dw_dp_hdcp_disable()
776 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED; in dw_dp_hdcp_disable()
777 sip_hdcp_config(HDCP_FUNC_ENCRYPT_MODE, dp->id ? DP_TX1 : DP_TX0, 0x1); in dw_dp_hdcp_disable()
778 ret = _dw_dp_hdcp_disable(dp); in dw_dp_hdcp_disable()
780 mutex_unlock(&dp->hdcp.mutex); in dw_dp_hdcp_disable()
781 cancel_delayed_work_sync(&dp->hdcp.check_work); in dw_dp_hdcp_disable()
786 static int _dw_dp_hdcp_check_link(struct dw_dp *dp) in _dw_dp_hdcp_check_link() argument
791 ret = drm_dp_dpcd_readb(&dp->aux, DP_AUX_HDCP_BSTATUS, &bstatus); in _dw_dp_hdcp_check_link()
796 return -EINVAL; in _dw_dp_hdcp_check_link()
801 static int dw_dp_hdcp_check_link(struct dw_dp *dp) in dw_dp_hdcp_check_link() argument
805 mutex_lock(&dp->hdcp.mutex); in dw_dp_hdcp_check_link()
807 if (dp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) in dw_dp_hdcp_check_link()
810 ret = _dw_dp_hdcp_check_link(dp); in dw_dp_hdcp_check_link()
814 dev_info(dp->dev, "HDCP link failed, retrying authentication\n"); in dw_dp_hdcp_check_link()
816 if (dp->hdcp.status == HDCP_TX_2) { in dw_dp_hdcp_check_link()
817 ret = _dw_dp_hdcp2_disable(dp); in dw_dp_hdcp_check_link()
819 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_check_link()
820 schedule_work(&dp->hdcp.prop_work); in dw_dp_hdcp_check_link()
824 ret = _dw_dp_hdcp2_enable(dp); in dw_dp_hdcp_check_link()
826 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_check_link()
827 schedule_work(&dp->hdcp.prop_work); in dw_dp_hdcp_check_link()
829 } else if (dp->hdcp.status == HDCP_TX_1) { in dw_dp_hdcp_check_link()
830 ret = _dw_dp_hdcp_disable(dp); in dw_dp_hdcp_check_link()
832 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_check_link()
833 schedule_work(&dp->hdcp.prop_work); in dw_dp_hdcp_check_link()
837 ret = _dw_dp_hdcp_enable(dp); in dw_dp_hdcp_check_link()
839 dp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_check_link()
840 schedule_work(&dp->hdcp.prop_work); in dw_dp_hdcp_check_link()
845 mutex_unlock(&dp->hdcp.mutex); in dw_dp_hdcp_check_link()
854 struct dw_dp *dp = in dw_dp_hdcp_check_work() local
857 if (!dw_dp_hdcp_check_link(dp)) in dw_dp_hdcp_check_work()
858 schedule_delayed_work(&hdcp->check_work, in dw_dp_hdcp_check_work()
859 hdcp->check_link_interval); in dw_dp_hdcp_check_work()
866 struct dw_dp *dp = in dp_dp_hdcp_prop_work() local
868 struct drm_device *dev = dp->connector.dev; in dp_dp_hdcp_prop_work()
870 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); in dp_dp_hdcp_prop_work()
871 mutex_lock(&dp->hdcp.mutex); in dp_dp_hdcp_prop_work()
872 if (dp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) in dp_dp_hdcp_prop_work()
873 drm_hdcp_update_content_protection(&dp->connector, dp->hdcp.value); in dp_dp_hdcp_prop_work()
874 mutex_unlock(&dp->hdcp.mutex); in dp_dp_hdcp_prop_work()
875 drm_modeset_unlock(&dev->mode_config.connection_mutex); in dp_dp_hdcp_prop_work()
878 static void dw_dp_hdcp_init(struct dw_dp *dp) in dw_dp_hdcp_init() argument
880 INIT_DELAYED_WORK(&dp->hdcp.check_work, dw_dp_hdcp_check_work); in dw_dp_hdcp_init()
881 INIT_WORK(&dp->hdcp.prop_work, dp_dp_hdcp_prop_work); in dw_dp_hdcp_init()
882 mutex_init(&dp->hdcp.mutex); in dw_dp_hdcp_init()
885 static void dw_dp_handle_hdcp_event(struct dw_dp *dp) in dw_dp_handle_hdcp_event() argument
889 mutex_lock(&dp->irq_lock); in dw_dp_handle_hdcp_event()
891 regmap_read(dp->regmap, DPTX_HDCPAPIINTSTAT, &value); in dw_dp_handle_hdcp_event()
894 dev_info(dp->dev, "A change in HDCP22 GPIO Output status\n"); in dw_dp_handle_hdcp_event()
895 regmap_write(dp->regmap, DPTX_HDCPAPIINTCLR, HDCP22_GPIOINT); in dw_dp_handle_hdcp_event()
898 mutex_unlock(&dp->irq_lock); in dw_dp_handle_hdcp_event()
948 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_match_by_id() local
951 return dp->id == *id; in dw_dp_match_by_id()
966 static void dw_dp_phy_set_pattern(struct dw_dp *dp, u32 pattern) in dw_dp_phy_set_pattern() argument
968 regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, TPS_SEL, in dw_dp_phy_set_pattern()
972 static void dw_dp_phy_xmit_enable(struct dw_dp *dp, u32 lanes) in dw_dp_phy_xmit_enable() argument
980 xmit_enable = GENMASK(lanes - 1, 0); in dw_dp_phy_xmit_enable()
988 regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, XMIT_ENABLE, in dw_dp_phy_xmit_enable()
992 static bool dw_dp_bandwidth_ok(struct dw_dp *dp, in dw_dp_bandwidth_ok() argument
998 req_bw = mode->clock * bpp / 8; in dw_dp_bandwidth_ok()
1006 static bool dw_dp_detect(struct dw_dp *dp) in dw_dp_detect() argument
1010 if (dp->hpd_gpio) in dw_dp_detect()
1011 return gpiod_get_value_cansleep(dp->hpd_gpio); in dw_dp_detect()
1013 regmap_read(dp->regmap, DPTX_HPD_STATUS, &value); in dw_dp_detect()
1021 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_connector_detect() local
1023 if (dp->right && drm_bridge_detect(&dp->right->bridge) != connector_status_connected) in dw_dp_connector_detect()
1026 return drm_bridge_detect(&dp->bridge); in dw_dp_connector_detect()
1031 if (audio->plugged_cb && audio->codec_dev) in dw_dp_audio_handle_plugged_change()
1032 audio->plugged_cb(audio->codec_dev, plugged); in dw_dp_audio_handle_plugged_change()
1037 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_connector_force() local
1039 if (connector->status == connector_status_connected) { in dw_dp_connector_force()
1040 extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true); in dw_dp_connector_force()
1041 dw_dp_audio_handle_plugged_change(&dp->audio, true); in dw_dp_connector_force()
1043 extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false); in dw_dp_connector_force()
1044 dw_dp_audio_handle_plugged_change(&dp->audio, false); in dw_dp_connector_force()
1050 struct dw_dp_state *dp_state = connector_to_dp_state(connector->state); in dw_dp_atomic_connector_reset()
1052 if (connector->state) { in dw_dp_atomic_connector_reset()
1053 __drm_atomic_helper_connector_destroy_state(connector->state); in dw_dp_atomic_connector_reset()
1061 __drm_atomic_helper_connector_reset(connector, &dp_state->state); in dw_dp_atomic_connector_reset()
1062 dp_state->bpc = 0; in dw_dp_atomic_connector_reset()
1063 dp_state->color_format = RK_IF_FORMAT_RGB; in dw_dp_atomic_connector_reset()
1071 if (WARN_ON(!connector->state)) in dw_dp_atomic_connector_duplicate_state()
1074 old_cstate = connector_to_dp_state(connector->state); in dw_dp_atomic_connector_duplicate_state()
1079 __drm_atomic_helper_connector_duplicate_state(connector, &cstate->state); in dw_dp_atomic_connector_duplicate_state()
1080 cstate->bpc = old_cstate->bpc; in dw_dp_atomic_connector_duplicate_state()
1081 cstate->color_format = old_cstate->color_format; in dw_dp_atomic_connector_duplicate_state()
1083 return &cstate->state; in dw_dp_atomic_connector_duplicate_state()
1091 __drm_atomic_helper_connector_destroy_state(&cstate->state); in dw_dp_atomic_connector_destroy_state()
1100 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_atomic_connector_get_property() local
1102 struct drm_display_info *info = &connector->display_info; in dw_dp_atomic_connector_get_property()
1104 if (property == dp->color_depth_property) { in dw_dp_atomic_connector_get_property()
1105 *val = dp_state->bpc; in dw_dp_atomic_connector_get_property()
1107 } else if (property == dp->color_format_property) { in dw_dp_atomic_connector_get_property()
1108 *val = dp_state->color_format; in dw_dp_atomic_connector_get_property()
1110 } else if (property == dp->color_depth_capacity) { in dw_dp_atomic_connector_get_property()
1112 switch (info->bpc) { in dw_dp_atomic_connector_get_property()
1130 } else if (property == dp->color_format_capacity) { in dw_dp_atomic_connector_get_property()
1131 *val = info->color_formats; in dw_dp_atomic_connector_get_property()
1133 } else if (property == dp->hdcp_state_property) { in dw_dp_atomic_connector_get_property()
1134 if (dp->hdcp.hdcp2_encrypted) in dw_dp_atomic_connector_get_property()
1136 else if (dp->hdcp.hdcp_encrypted) in dw_dp_atomic_connector_get_property()
1143 dev_err(dp->dev, "Unknown property [PROP:%d:%s]\n", in dw_dp_atomic_connector_get_property()
1144 property->base.id, property->name); in dw_dp_atomic_connector_get_property()
1154 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_atomic_connector_set_property() local
1157 if (property == dp->color_depth_property) { in dw_dp_atomic_connector_set_property()
1158 dp_state->bpc = val; in dw_dp_atomic_connector_set_property()
1160 } else if (property == dp->color_format_property) { in dw_dp_atomic_connector_set_property()
1161 dp_state->color_format = val; in dw_dp_atomic_connector_set_property()
1163 } else if (property == dp->color_depth_capacity) { in dw_dp_atomic_connector_set_property()
1165 } else if (property == dp->color_format_capacity) { in dw_dp_atomic_connector_set_property()
1167 } else if (property == dp->hdcp_state_property) { in dw_dp_atomic_connector_set_property()
1171 dev_err(dp->dev, "Unknown property [PROP:%d:%s]\n", in dw_dp_atomic_connector_set_property()
1172 property->base.id, property->name); in dw_dp_atomic_connector_set_property()
1174 return -EINVAL; in dw_dp_atomic_connector_set_property()
1191 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_update_hdr_property() local
1192 struct drm_device *dev = connector->dev; in dw_dp_update_hdr_property()
1194 &connector->hdr_sink_metadata.hdmi_type1; in dw_dp_update_hdr_property()
1198 ret = drm_property_replace_global_blob(dev, &dp->hdr_panel_blob_ptr, size, metadata, in dw_dp_update_hdr_property()
1199 &connector->base, dp->hdr_panel_metadata_property); in dw_dp_update_hdr_property()
1206 struct dw_dp *dp = connector_to_dp(connector); in dw_dp_connector_get_modes() local
1207 struct drm_display_info *di = &connector->display_info; in dw_dp_connector_get_modes()
1211 if (dp->right && dp->right->next_bridge) { in dw_dp_connector_get_modes()
1212 struct drm_bridge *bridge = dp->right->next_bridge; in dw_dp_connector_get_modes()
1214 if (bridge->ops & DRM_BRIDGE_OP_MODES) { in dw_dp_connector_get_modes()
1220 if (dp->next_bridge) in dw_dp_connector_get_modes()
1221 num_modes = drm_bridge_get_modes(dp->next_bridge, connector); in dw_dp_connector_get_modes()
1223 if (dp->panel) in dw_dp_connector_get_modes()
1224 num_modes = drm_panel_get_modes(dp->panel, connector); in dw_dp_connector_get_modes()
1227 edid = drm_bridge_get_edid(&dp->bridge, connector); in dw_dp_connector_get_modes()
1236 if (!di->color_formats) in dw_dp_connector_get_modes()
1237 di->color_formats = DRM_COLOR_FORMAT_RGB444; in dw_dp_connector_get_modes()
1239 if (!di->bpc) in dw_dp_connector_get_modes()
1240 di->bpc = 8; in dw_dp_connector_get_modes()
1242 if (num_modes > 0 && dp->split_mode) { in dw_dp_connector_get_modes()
1245 di->width_mm *= 2; in dw_dp_connector_get_modes()
1247 list_for_each_entry(mode, &connector->probed_modes, head) in dw_dp_connector_get_modes()
1263 old_cp = old_state->content_protection; in dw_dp_hdcp_atomic_check()
1264 new_cp = new_state->content_protection; in dw_dp_hdcp_atomic_check()
1266 if (old_state->hdcp_content_type != new_state->hdcp_content_type && in dw_dp_hdcp_atomic_check()
1268 new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_atomic_check()
1272 if (!new_state->crtc) { in dw_dp_hdcp_atomic_check()
1274 new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; in dw_dp_hdcp_atomic_check()
1284 crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc); in dw_dp_hdcp_atomic_check()
1285 crtc_state->mode_changed = true; in dw_dp_hdcp_atomic_check()
1293 struct drm_property_blob *old_blob = old_state->hdr_output_metadata; in dw_dp_hdr_metadata_equal()
1294 struct drm_property_blob *new_blob = new_state->hdr_output_metadata; in dw_dp_hdr_metadata_equal()
1299 if (old_blob->length != new_blob->length) in dw_dp_hdr_metadata_equal()
1302 return !memcmp(old_blob->data, new_blob->data, old_blob->length); in dw_dp_hdr_metadata_equal()
1316 struct dw_dp *dp = connector_to_dp(conn); in dw_dp_connector_atomic_check() local
1325 if (!new_state->crtc) in dw_dp_connector_atomic_check()
1328 crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc); in dw_dp_connector_atomic_check()
1331 crtc_state->mode_changed = true; in dw_dp_connector_atomic_check()
1333 if ((dp_new_state->bpc != 0) && (dp_new_state->bpc != 6) && (dp_new_state->bpc != 8) && in dw_dp_connector_atomic_check()
1334 (dp_new_state->bpc != 10)) { in dw_dp_connector_atomic_check()
1335 dev_err(dp->dev, "set invalid bpc:%d\n", dp_new_state->bpc); in dw_dp_connector_atomic_check()
1336 return -EINVAL; in dw_dp_connector_atomic_check()
1339 if ((dp_new_state->color_format < RK_IF_FORMAT_RGB) || in dw_dp_connector_atomic_check()
1340 (dp_new_state->color_format > RK_IF_FORMAT_YCBCR420)) { in dw_dp_connector_atomic_check()
1341 dev_err(dp->dev, "set invalid color format:%d\n", dp_new_state->color_format); in dw_dp_connector_atomic_check()
1342 return -EINVAL; in dw_dp_connector_atomic_check()
1345 if ((dp_old_state->bpc != dp_new_state->bpc) || in dw_dp_connector_atomic_check()
1346 (dp_old_state->color_format != dp_new_state->color_format)) { in dw_dp_connector_atomic_check()
1347 if ((dp_old_state->bpc == 0) && (dp_new_state->bpc == 0)) in dw_dp_connector_atomic_check()
1348 dev_info(dp->dev, "still auto set color mode\n"); in dw_dp_connector_atomic_check()
1350 crtc_state->mode_changed = true; in dw_dp_connector_atomic_check()
1363 caps->enhanced_framing = false; in dw_dp_link_caps_reset()
1364 caps->tps3_supported = false; in dw_dp_link_caps_reset()
1365 caps->tps4_supported = false; in dw_dp_link_caps_reset()
1366 caps->fast_training = false; in dw_dp_link_caps_reset()
1367 caps->channel_coding = false; in dw_dp_link_caps_reset()
1372 link->vsc_sdp_extension_for_colorimetry_supported = 0; in dw_dp_link_reset()
1373 link->sink_count = 0; in dw_dp_link_reset()
1374 link->revision = 0; in dw_dp_link_reset()
1376 dw_dp_link_caps_reset(&link->caps); in dw_dp_link_reset()
1377 memset(link->dpcd, 0, sizeof(link->dpcd)); in dw_dp_link_reset()
1379 link->rate = 0; in dw_dp_link_reset()
1380 link->lanes = 0; in dw_dp_link_reset()
1383 static int dw_dp_link_power_up(struct dw_dp *dp) in dw_dp_link_power_up() argument
1385 struct dw_dp_link *link = &dp->link; in dw_dp_link_power_up()
1389 if (link->revision < 0x11) in dw_dp_link_power_up()
1392 ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value); in dw_dp_link_power_up()
1399 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); in dw_dp_link_power_up()
1408 static int dw_dp_link_power_down(struct dw_dp *dp) in dw_dp_link_power_down() argument
1410 struct dw_dp_link *link = &dp->link; in dw_dp_link_power_down()
1414 if (link->revision < 0x11) in dw_dp_link_power_down()
1417 ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value); in dw_dp_link_power_down()
1424 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); in dw_dp_link_power_down()
1439 static int dw_dp_link_probe(struct dw_dp *dp) in dw_dp_link_probe() argument
1441 struct dw_dp_link *link = &dp->link; in dw_dp_link_probe()
1447 ret = drm_dp_read_dpcd_caps(&dp->aux, link->dpcd); in dw_dp_link_probe()
1451 drm_dp_read_desc(&dp->aux, &link->desc, drm_dp_is_branch(link->dpcd)); in dw_dp_link_probe()
1453 if (dw_dp_has_sink_count(link->dpcd, &link->desc)) { in dw_dp_link_probe()
1454 ret = drm_dp_read_sink_count(&dp->aux); in dw_dp_link_probe()
1458 link->sink_count = ret; in dw_dp_link_probe()
1461 if (!link->sink_count) in dw_dp_link_probe()
1462 return -ENODEV; in dw_dp_link_probe()
1465 ret = drm_dp_dpcd_readb(&dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST, in dw_dp_link_probe()
1470 link->vsc_sdp_extension_for_colorimetry_supported = in dw_dp_link_probe()
1473 link->revision = link->dpcd[DP_DPCD_REV]; in dw_dp_link_probe()
1474 link->rate = min_t(u32, min(dp->max_link_rate, dp->phy->attrs.max_link_rate * 100), in dw_dp_link_probe()
1475 drm_dp_max_link_rate(link->dpcd)); in dw_dp_link_probe()
1476 link->lanes = min_t(u8, phy_get_bus_width(dp->phy), in dw_dp_link_probe()
1477 drm_dp_max_lane_count(link->dpcd)); in dw_dp_link_probe()
1479 link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(link->dpcd); in dw_dp_link_probe()
1480 link->caps.tps3_supported = drm_dp_tps3_supported(link->dpcd); in dw_dp_link_probe()
1481 link->caps.tps4_supported = drm_dp_tps4_supported(link->dpcd); in dw_dp_link_probe()
1482 link->caps.fast_training = drm_dp_fast_training_cap(link->dpcd); in dw_dp_link_probe()
1483 link->caps.channel_coding = drm_dp_channel_coding_supported(link->dpcd); in dw_dp_link_probe()
1484 link->caps.ssc = !!(link->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); in dw_dp_link_probe()
1489 static int dw_dp_phy_update_vs_emph(struct dw_dp *dp, unsigned int rate, unsigned int lanes, in dw_dp_phy_update_vs_emph() argument
1497 vs = train_set->voltage_swing; in dw_dp_phy_update_vs_emph()
1498 pe = train_set->pre_emphasis; in dw_dp_phy_update_vs_emph()
1501 phy_cfg.dp.voltage[i] = vs[i]; in dw_dp_phy_update_vs_emph()
1502 phy_cfg.dp.pre[i] = pe[i]; in dw_dp_phy_update_vs_emph()
1505 phy_cfg.dp.lanes = lanes; in dw_dp_phy_update_vs_emph()
1506 phy_cfg.dp.link_rate = rate / 100; in dw_dp_phy_update_vs_emph()
1507 phy_cfg.dp.set_lanes = false; in dw_dp_phy_update_vs_emph()
1508 phy_cfg.dp.set_rate = false; in dw_dp_phy_update_vs_emph()
1509 phy_cfg.dp.set_voltages = true; in dw_dp_phy_update_vs_emph()
1511 ret = phy_configure(dp->phy, &phy_cfg); in dw_dp_phy_update_vs_emph()
1518 if (train_set->voltage_max_reached[i]) in dw_dp_phy_update_vs_emph()
1520 if (train_set->pre_max_reached[i]) in dw_dp_phy_update_vs_emph()
1524 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, buf, lanes); in dw_dp_phy_update_vs_emph()
1531 static int dw_dp_link_train_update_vs_emph(struct dw_dp *dp) in dw_dp_link_train_update_vs_emph() argument
1533 struct dw_dp_link *link = &dp->link; in dw_dp_link_train_update_vs_emph()
1534 struct drm_dp_link_train_set *request = &link->train.request; in dw_dp_link_train_update_vs_emph()
1536 return dw_dp_phy_update_vs_emph(dp, dp->link.rate, dp->link.lanes, request); in dw_dp_link_train_update_vs_emph()
1539 static int dw_dp_phy_configure(struct dw_dp *dp, unsigned int rate, in dw_dp_phy_configure() argument
1545 /* Move PHY to P3 */ in dw_dp_phy_configure()
1546 regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_POWERDOWN, in dw_dp_phy_configure()
1549 phy_cfg.dp.lanes = lanes; in dw_dp_phy_configure()
1550 phy_cfg.dp.link_rate = rate / 100; in dw_dp_phy_configure()
1551 phy_cfg.dp.ssc = ssc; in dw_dp_phy_configure()
1552 phy_cfg.dp.set_lanes = true; in dw_dp_phy_configure()
1553 phy_cfg.dp.set_rate = true; in dw_dp_phy_configure()
1554 phy_cfg.dp.set_voltages = false; in dw_dp_phy_configure()
1555 ret = phy_configure(dp->phy, &phy_cfg); in dw_dp_phy_configure()
1559 regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_LANES, in dw_dp_phy_configure()
1562 /* Move PHY to P0 */ in dw_dp_phy_configure()
1563 regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_POWERDOWN, in dw_dp_phy_configure()
1566 dw_dp_phy_xmit_enable(dp, lanes); in dw_dp_phy_configure()
1571 static int dw_dp_link_configure(struct dw_dp *dp) in dw_dp_link_configure() argument
1573 struct dw_dp_link *link = &dp->link; in dw_dp_link_configure()
1577 ret = dw_dp_phy_configure(dp, link->rate, link->lanes, link->caps.ssc); in dw_dp_link_configure()
1580 buf[0] = drm_dp_link_rate_to_bw_code(link->rate); in dw_dp_link_configure()
1581 buf[1] = link->lanes; in dw_dp_link_configure()
1583 if (link->caps.enhanced_framing) { in dw_dp_link_configure()
1585 regmap_update_bits(dp->regmap, DPTX_CCTL, ENHANCE_FRAMING_EN, in dw_dp_link_configure()
1588 regmap_update_bits(dp->regmap, DPTX_CCTL, ENHANCE_FRAMING_EN, in dw_dp_link_configure()
1592 ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); in dw_dp_link_configure()
1596 buf[0] = link->caps.ssc ? DP_SPREAD_AMP_0_5 : 0; in dw_dp_link_configure()
1597 buf[1] = link->caps.channel_coding ? DP_SET_ANSI_8B10B : 0; in dw_dp_link_configure()
1599 ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, in dw_dp_link_configure()
1609 struct drm_dp_link_train_set *request = &train->request; in dw_dp_link_train_init()
1610 struct drm_dp_link_train_set *adjust = &train->adjust; in dw_dp_link_train_init()
1614 request->voltage_swing[i] = 0; in dw_dp_link_train_init()
1615 adjust->voltage_swing[i] = 0; in dw_dp_link_train_init()
1617 request->pre_emphasis[i] = 0; in dw_dp_link_train_init()
1618 adjust->pre_emphasis[i] = 0; in dw_dp_link_train_init()
1620 request->voltage_max_reached[i] = false; in dw_dp_link_train_init()
1621 adjust->voltage_max_reached[i] = false; in dw_dp_link_train_init()
1623 request->pre_max_reached[i] = false; in dw_dp_link_train_init()
1624 adjust->pre_max_reached[i] = false; in dw_dp_link_train_init()
1627 train->clock_recovered = false; in dw_dp_link_train_init()
1628 train->channel_equalized = false; in dw_dp_link_train_init()
1633 return train->clock_recovered && train->channel_equalized; in dw_dp_link_train_valid()
1636 static int dw_dp_link_train_set_pattern(struct dw_dp *dp, u32 pattern) in dw_dp_link_train_set_pattern() argument
1644 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_link_train_set_pattern()
1647 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_link_train_set_pattern()
1653 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_NONE); in dw_dp_link_train_set_pattern()
1656 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_1); in dw_dp_link_train_set_pattern()
1659 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_2); in dw_dp_link_train_set_pattern()
1662 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_3); in dw_dp_link_train_set_pattern()
1665 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_4); in dw_dp_link_train_set_pattern()
1668 return -EINVAL; in dw_dp_link_train_set_pattern()
1671 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in dw_dp_link_train_set_pattern()
1697 struct drm_dp_link_train_set *adjust = &link->train.adjust; in dw_dp_link_get_adjustments()
1702 for (i = 0; i < link->lanes; i++) { in dw_dp_link_get_adjustments()
1706 adjust->pre_emphasis[i] = DP_TRAIN_PRE_EMPH_LEVEL_3 >> in dw_dp_link_get_adjustments()
1708 adjust->pre_max_reached[i] = true; in dw_dp_link_get_adjustments()
1710 adjust->pre_emphasis[i] = p >> DP_TRAIN_PRE_EMPHASIS_SHIFT; in dw_dp_link_get_adjustments()
1711 adjust->pre_max_reached[i] = false; in dw_dp_link_get_adjustments()
1715 adjust->voltage_swing[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 >> in dw_dp_link_get_adjustments()
1717 adjust->voltage_max_reached[i] = true; in dw_dp_link_get_adjustments()
1719 adjust->voltage_swing[i] = v >> DP_TRAIN_VOLTAGE_SWING_SHIFT; in dw_dp_link_get_adjustments()
1720 adjust->voltage_max_reached[i] = false; in dw_dp_link_get_adjustments()
1727 struct drm_dp_link_train_set *request = &train->request; in dw_dp_link_train_adjust()
1728 struct drm_dp_link_train_set *adjust = &train->adjust; in dw_dp_link_train_adjust()
1732 if (request->voltage_swing[i] != adjust->voltage_swing[i]) in dw_dp_link_train_adjust()
1733 request->voltage_swing[i] = adjust->voltage_swing[i]; in dw_dp_link_train_adjust()
1734 if (request->voltage_max_reached[i] != adjust->voltage_max_reached[i]) in dw_dp_link_train_adjust()
1735 request->voltage_max_reached[i] = adjust->voltage_max_reached[i]; in dw_dp_link_train_adjust()
1739 if (request->pre_emphasis[i] != adjust->pre_emphasis[i]) in dw_dp_link_train_adjust()
1740 request->pre_emphasis[i] = adjust->pre_emphasis[i]; in dw_dp_link_train_adjust()
1741 if (request->pre_max_reached[i] != adjust->pre_max_reached[i]) in dw_dp_link_train_adjust()
1742 request->pre_max_reached[i] = adjust->pre_max_reached[i]; in dw_dp_link_train_adjust()
1746 static int dw_dp_link_clock_recovery(struct dw_dp *dp) in dw_dp_link_clock_recovery() argument
1748 struct dw_dp_link *link = &dp->link; in dw_dp_link_clock_recovery()
1753 ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1); in dw_dp_link_clock_recovery()
1758 ret = dw_dp_link_train_update_vs_emph(dp); in dw_dp_link_clock_recovery()
1762 drm_dp_link_train_clock_recovery_delay(link->dpcd); in dw_dp_link_clock_recovery()
1764 ret = drm_dp_dpcd_read_link_status(&dp->aux, status); in dw_dp_link_clock_recovery()
1766 dev_err(dp->dev, "failed to read link status: %d\n", ret); in dw_dp_link_clock_recovery()
1770 if (drm_dp_clock_recovery_ok(status, link->lanes)) { in dw_dp_link_clock_recovery()
1771 link->train.clock_recovered = true; in dw_dp_link_clock_recovery()
1777 if (link->train.request.voltage_swing[0] == in dw_dp_link_clock_recovery()
1778 link->train.adjust.voltage_swing[0]) in dw_dp_link_clock_recovery()
1786 dw_dp_link_train_adjust(&link->train); in dw_dp_link_clock_recovery()
1792 static int dw_dp_link_channel_equalization(struct dw_dp *dp) in dw_dp_link_channel_equalization() argument
1794 struct dw_dp_link *link = &dp->link; in dw_dp_link_channel_equalization()
1799 if (link->caps.tps4_supported) in dw_dp_link_channel_equalization()
1801 else if (link->caps.tps3_supported) in dw_dp_link_channel_equalization()
1805 ret = dw_dp_link_train_set_pattern(dp, pattern); in dw_dp_link_channel_equalization()
1810 ret = dw_dp_link_train_update_vs_emph(dp); in dw_dp_link_channel_equalization()
1814 drm_dp_link_train_channel_eq_delay(link->dpcd); in dw_dp_link_channel_equalization()
1816 ret = drm_dp_dpcd_read_link_status(&dp->aux, status); in dw_dp_link_channel_equalization()
1820 if (!drm_dp_clock_recovery_ok(status, link->lanes)) { in dw_dp_link_channel_equalization()
1821 dev_err(dp->dev, "clock recovery lost while equalizing channel\n"); in dw_dp_link_channel_equalization()
1822 link->train.clock_recovered = false; in dw_dp_link_channel_equalization()
1826 if (drm_dp_channel_eq_ok(status, link->lanes)) { in dw_dp_link_channel_equalization()
1827 link->train.channel_equalized = true; in dw_dp_link_channel_equalization()
1832 dw_dp_link_train_adjust(&link->train); in dw_dp_link_channel_equalization()
1838 static int dw_dp_link_downgrade(struct dw_dp *dp) in dw_dp_link_downgrade() argument
1840 struct dw_dp_link *link = &dp->link; in dw_dp_link_downgrade()
1841 struct dw_dp_video *video = &dp->video; in dw_dp_link_downgrade()
1843 switch (link->rate) { in dw_dp_link_downgrade()
1845 return -EINVAL; in dw_dp_link_downgrade()
1847 link->rate = 162000; in dw_dp_link_downgrade()
1850 link->rate = 270000; in dw_dp_link_downgrade()
1853 link->rate = 540000; in dw_dp_link_downgrade()
1857 if (!dw_dp_bandwidth_ok(dp, &video->mode, video->bpp, link->lanes, in dw_dp_link_downgrade()
1858 link->rate)) in dw_dp_link_downgrade()
1859 return -E2BIG; in dw_dp_link_downgrade()
1864 static int dw_dp_link_train_full(struct dw_dp *dp) in dw_dp_link_train_full() argument
1866 struct dw_dp_link *link = &dp->link; in dw_dp_link_train_full()
1870 dw_dp_link_train_init(&link->train); in dw_dp_link_train_full()
1872 dev_info(dp->dev, "full-training link: %u lane%s at %u MHz\n", in dw_dp_link_train_full()
1873 link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100); in dw_dp_link_train_full()
1875 ret = dw_dp_link_configure(dp); in dw_dp_link_train_full()
1877 dev_err(dp->dev, "failed to configure DP link: %d\n", ret); in dw_dp_link_train_full()
1881 ret = dw_dp_link_clock_recovery(dp); in dw_dp_link_train_full()
1883 dev_err(dp->dev, "clock recovery failed: %d\n", ret); in dw_dp_link_train_full()
1887 if (!link->train.clock_recovered) { in dw_dp_link_train_full()
1888 dev_err(dp->dev, "clock recovery failed, downgrading link\n"); in dw_dp_link_train_full()
1890 ret = dw_dp_link_downgrade(dp); in dw_dp_link_train_full()
1897 dev_info(dp->dev, "clock recovery succeeded\n"); in dw_dp_link_train_full()
1899 ret = dw_dp_link_channel_equalization(dp); in dw_dp_link_train_full()
1901 dev_err(dp->dev, "channel equalization failed: %d\n", ret); in dw_dp_link_train_full()
1905 if (!link->train.channel_equalized) { in dw_dp_link_train_full()
1906 dev_err(dp->dev, "channel equalization failed, downgrading link\n"); in dw_dp_link_train_full()
1908 ret = dw_dp_link_downgrade(dp); in dw_dp_link_train_full()
1915 dev_info(dp->dev, "channel equalization succeeded\n"); in dw_dp_link_train_full()
1918 dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); in dw_dp_link_train_full()
1922 static int dw_dp_link_train_fast(struct dw_dp *dp) in dw_dp_link_train_fast() argument
1924 struct dw_dp_link *link = &dp->link; in dw_dp_link_train_fast()
1928 dw_dp_link_train_init(&link->train); in dw_dp_link_train_fast()
1930 dev_info(dp->dev, "fast-training link: %u lane%s at %u MHz\n", in dw_dp_link_train_fast()
1931 link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100); in dw_dp_link_train_fast()
1933 ret = dw_dp_link_configure(dp); in dw_dp_link_train_fast()
1935 dev_err(dp->dev, "failed to configure DP link: %d\n", ret); in dw_dp_link_train_fast()
1939 ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1); in dw_dp_link_train_fast()
1945 if (link->caps.tps4_supported) in dw_dp_link_train_fast()
1947 else if (link->caps.tps3_supported) in dw_dp_link_train_fast()
1951 ret = dw_dp_link_train_set_pattern(dp, pattern); in dw_dp_link_train_fast()
1957 ret = drm_dp_dpcd_read_link_status(&dp->aux, status); in dw_dp_link_train_fast()
1959 dev_err(dp->dev, "failed to read link status: %d\n", ret); in dw_dp_link_train_fast()
1963 if (!drm_dp_clock_recovery_ok(status, link->lanes)) { in dw_dp_link_train_fast()
1964 dev_err(dp->dev, "clock recovery failed\n"); in dw_dp_link_train_fast()
1965 ret = -EIO; in dw_dp_link_train_fast()
1969 if (!drm_dp_channel_eq_ok(status, link->lanes)) { in dw_dp_link_train_fast()
1970 dev_err(dp->dev, "channel equalization failed\n"); in dw_dp_link_train_fast()
1971 ret = -EIO; in dw_dp_link_train_fast()
1976 dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); in dw_dp_link_train_fast()
1980 static int dw_dp_link_train(struct dw_dp *dp) in dw_dp_link_train() argument
1982 struct dw_dp_link *link = &dp->link; in dw_dp_link_train()
1985 if (link->caps.fast_training) { in dw_dp_link_train()
1986 if (dw_dp_link_train_valid(&link->train)) { in dw_dp_link_train()
1987 ret = dw_dp_link_train_fast(dp); in dw_dp_link_train()
1989 dev_err(dp->dev, in dw_dp_link_train()
1996 ret = dw_dp_link_train_full(dp); in dw_dp_link_train()
1998 dev_err(dp->dev, "full link training failed: %d\n", ret); in dw_dp_link_train()
2005 static int dw_dp_send_sdp(struct dw_dp *dp, struct dw_dp_sdp *sdp) in dw_dp_send_sdp() argument
2007 const u8 *payload = sdp->db; in dw_dp_send_sdp()
2011 nr = find_first_zero_bit(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); in dw_dp_send_sdp()
2013 set_bit(nr, dp->sdp_reg_bank); in dw_dp_send_sdp()
2015 return -EBUSY; in dw_dp_send_sdp()
2020 regmap_write(dp->regmap, reg, get_unaligned_le32(&sdp->header)); in dw_dp_send_sdp()
2024 regmap_write(dp->regmap, reg + i * 4, in dw_dp_send_sdp()
2027 if (sdp->flags & DPTX_SDP_VERTICAL_INTERVAL) in dw_dp_send_sdp()
2028 regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL, in dw_dp_send_sdp()
2032 if (sdp->flags & DPTX_SDP_HORIZONTAL_INTERVAL) in dw_dp_send_sdp()
2033 regmap_update_bits(dp->regmap, DPTX_SDP_HORIZONTAL_CTRL, in dw_dp_send_sdp()
2043 sdp->header.HB0 = 0; in dw_dp_vsc_sdp_pack()
2044 sdp->header.HB1 = DP_SDP_VSC; in dw_dp_vsc_sdp_pack()
2045 sdp->header.HB2 = vsc->revision; in dw_dp_vsc_sdp_pack()
2046 sdp->header.HB3 = vsc->length; in dw_dp_vsc_sdp_pack()
2048 sdp->db[16] = (vsc->pixelformat & 0xf) << 4; in dw_dp_vsc_sdp_pack()
2049 sdp->db[16] |= vsc->colorimetry & 0xf; in dw_dp_vsc_sdp_pack()
2051 switch (vsc->bpc) { in dw_dp_vsc_sdp_pack()
2053 sdp->db[17] = 0x1; in dw_dp_vsc_sdp_pack()
2056 sdp->db[17] = 0x2; in dw_dp_vsc_sdp_pack()
2059 sdp->db[17] = 0x3; in dw_dp_vsc_sdp_pack()
2062 sdp->db[17] = 0x4; in dw_dp_vsc_sdp_pack()
2069 if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) in dw_dp_vsc_sdp_pack()
2070 sdp->db[17] |= 0x80; in dw_dp_vsc_sdp_pack()
2072 sdp->db[18] = vsc->content_type & 0x7; in dw_dp_vsc_sdp_pack()
2074 sdp->flags |= DPTX_SDP_VERTICAL_INTERVAL; in dw_dp_vsc_sdp_pack()
2077 static int dw_dp_send_vsc_sdp(struct dw_dp *dp) in dw_dp_send_vsc_sdp() argument
2079 struct dw_dp_video *video = &dp->video; in dw_dp_send_vsc_sdp()
2086 switch (video->color_format) { in dw_dp_send_vsc_sdp()
2102 if (video->color_format == DRM_COLOR_FORMAT_RGB444) { in dw_dp_send_vsc_sdp()
2103 if (dw_dp_is_hdr_eotf(dp->eotf_type)) in dw_dp_send_vsc_sdp()
2109 if (dw_dp_is_hdr_eotf(dp->eotf_type)) in dw_dp_send_vsc_sdp()
2116 vsc.bpc = video->bpc; in dw_dp_send_vsc_sdp()
2121 return dw_dp_send_sdp(dp, &sdp); in dw_dp_send_vsc_sdp()
2124 static ssize_t dw_dp_hdr_metadata_infoframe_sdp_pack(struct dw_dp *dp, in dw_dp_hdr_metadata_infoframe_sdp_pack() argument
2136 dev_err(dp->dev, "buffer size is smaller than hdr metadata infoframe\n"); in dw_dp_hdr_metadata_infoframe_sdp_pack()
2137 return -ENOSPC; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2141 dev_err(dp->dev, "wrong static hdr metadata size\n"); in dw_dp_hdr_metadata_infoframe_sdp_pack()
2142 return -ENOSPC; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2145 sdp->header.HB0 = 0; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2146 sdp->header.HB1 = drm_infoframe->type; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2147 sdp->header.HB2 = 0x1D; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2148 sdp->header.HB3 = (0x13 << 2); in dw_dp_hdr_metadata_infoframe_sdp_pack()
2149 sdp->db[0] = drm_infoframe->version; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2150 sdp->db[1] = drm_infoframe->length; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2152 memcpy(&sdp->db[2], &buf[HDMI_INFOFRAME_HEADER_SIZE], in dw_dp_hdr_metadata_infoframe_sdp_pack()
2155 sdp->flags |= DPTX_SDP_VERTICAL_INTERVAL; in dw_dp_hdr_metadata_infoframe_sdp_pack()
2160 static int dw_dp_send_hdr_metadata_infoframe_sdp(struct dw_dp *dp) in dw_dp_send_hdr_metadata_infoframe_sdp() argument
2167 conn_state = dp->connector.state; in dw_dp_send_hdr_metadata_infoframe_sdp()
2171 dev_err(dp->dev, "couldn't set HDR metadata in infoframe\n"); in dw_dp_send_hdr_metadata_infoframe_sdp()
2175 dw_dp_hdr_metadata_infoframe_sdp_pack(dp, &drm_infoframe, &sdp); in dw_dp_send_hdr_metadata_infoframe_sdp()
2177 return dw_dp_send_sdp(dp, &sdp); in dw_dp_send_hdr_metadata_infoframe_sdp()
2180 static int dw_dp_video_set_pixel_mode(struct dw_dp *dp, u8 pixel_mode) in dw_dp_video_set_pixel_mode() argument
2188 return -EINVAL; in dw_dp_video_set_pixel_mode()
2191 regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, PIXEL_MODE_SELECT, in dw_dp_video_set_pixel_mode()
2197 static bool dw_dp_video_need_vsc_sdp(struct dw_dp *dp) in dw_dp_video_need_vsc_sdp() argument
2199 struct dw_dp_link *link = &dp->link; in dw_dp_video_need_vsc_sdp()
2200 struct dw_dp_video *video = &dp->video; in dw_dp_video_need_vsc_sdp()
2202 if (!link->vsc_sdp_extension_for_colorimetry_supported) in dw_dp_video_need_vsc_sdp()
2205 if (video->color_format == DRM_COLOR_FORMAT_YCRCB420) in dw_dp_video_need_vsc_sdp()
2208 if (dw_dp_is_hdr_eotf(dp->eotf_type)) in dw_dp_video_need_vsc_sdp()
2214 static int dw_dp_video_set_msa(struct dw_dp *dp, u8 color_format, u8 bpc, in dw_dp_video_set_msa() argument
2219 if (dw_dp_video_need_vsc_sdp(dp)) in dw_dp_video_set_msa()
2235 return -EINVAL; in dw_dp_video_set_msa()
2255 return -EINVAL; in dw_dp_video_set_msa()
2258 regmap_write(dp->regmap, DPTX_VIDEO_MSA1, in dw_dp_video_set_msa()
2260 regmap_write(dp->regmap, DPTX_VIDEO_MSA2, FIELD_PREP(MISC0, misc)); in dw_dp_video_set_msa()
2261 regmap_write(dp->regmap, DPTX_VIDEO_MSA3, FIELD_PREP(MISC1, misc >> 8)); in dw_dp_video_set_msa()
2266 static void dw_dp_video_disable(struct dw_dp *dp) in dw_dp_video_disable() argument
2268 regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE, in dw_dp_video_disable()
2272 static int dw_dp_video_enable(struct dw_dp *dp) in dw_dp_video_enable() argument
2274 struct dw_dp_video *video = &dp->video; in dw_dp_video_enable()
2275 struct dw_dp_link *link = &dp->link; in dw_dp_video_enable()
2276 struct drm_display_mode *mode = &video->mode; in dw_dp_video_enable()
2277 u8 color_format = video->color_format; in dw_dp_video_enable()
2278 u8 bpc = video->bpc; in dw_dp_video_enable()
2279 u8 pixel_mode = video->pixel_mode; in dw_dp_video_enable()
2280 u8 bpp = video->bpp, init_threshold, vic; in dw_dp_video_enable()
2283 u32 vstart = mode->vtotal - mode->vsync_start; in dw_dp_video_enable()
2284 u32 hstart = mode->htotal - mode->hsync_start; in dw_dp_video_enable()
2291 ret = dw_dp_video_set_pixel_mode(dp, pixel_mode); in dw_dp_video_enable()
2295 ret = dw_dp_video_set_msa(dp, color_format, bpc, vstart, hstart); in dw_dp_video_enable()
2299 regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_MAPPING, in dw_dp_video_enable()
2300 FIELD_PREP(VIDEO_MAPPING, video->video_mapping)); in dw_dp_video_enable()
2304 if (mode->flags & DRM_MODE_FLAG_PHSYNC) in dw_dp_video_enable()
2306 if (mode->flags & DRM_MODE_FLAG_PVSYNC) in dw_dp_video_enable()
2308 regmap_write(dp->regmap, DPTX_VINPUT_POLARITY_CTRL, value); in dw_dp_video_enable()
2311 hactive = mode->hdisplay; in dw_dp_video_enable()
2312 hblank = mode->htotal - mode->hdisplay; in dw_dp_video_enable()
2314 if (mode->flags & DRM_MODE_FLAG_INTERLACE) in dw_dp_video_enable()
2325 regmap_write(dp->regmap, DPTX_VIDEO_CONFIG1, value); in dw_dp_video_enable()
2328 vblank = mode->vtotal - mode->vdisplay; in dw_dp_video_enable()
2329 vactive = mode->vdisplay; in dw_dp_video_enable()
2330 regmap_write(dp->regmap, DPTX_VIDEO_CONFIG2, in dw_dp_video_enable()
2334 h_sync_width = mode->hsync_end - mode->hsync_start; in dw_dp_video_enable()
2335 h_front_porch = mode->hsync_start - mode->hdisplay; in dw_dp_video_enable()
2336 regmap_write(dp->regmap, DPTX_VIDEO_CONFIG3, in dw_dp_video_enable()
2341 v_sync_width = mode->vsync_end - mode->vsync_start; in dw_dp_video_enable()
2342 v_front_porch = mode->vsync_start - mode->vdisplay; in dw_dp_video_enable()
2343 regmap_write(dp->regmap, DPTX_VIDEO_CONFIG4, in dw_dp_video_enable()
2348 peak_stream_bandwidth = mode->clock * bpp / 8; in dw_dp_video_enable()
2349 link_bandwidth = (link->rate / 1000) * link->lanes; in dw_dp_video_enable()
2352 average_bytes_per_tu_frac = ts / 100 - average_bytes_per_tu * 10; in dw_dp_video_enable()
2367 t1 = (4 * 1000 / 9) * link->lanes; in dw_dp_video_enable()
2371 t1 = (1000 / 2) * link->lanes; in dw_dp_video_enable()
2374 t1 = (1000 / 3) * link->lanes; in dw_dp_video_enable()
2376 t1 = (3000 / 16) * link->lanes; in dw_dp_video_enable()
2381 t1 = (2000 / 5) * link->lanes; in dw_dp_video_enable()
2383 t1 = (4000 / 15) * link->lanes; in dw_dp_video_enable()
2388 t1 = (1000 / 6) * link->lanes; in dw_dp_video_enable()
2390 t1 = (1000 / 3) * link->lanes; in dw_dp_video_enable()
2392 t1 = (2000 / 9) * link->lanes; in dw_dp_video_enable()
2398 t1 = (1000 / 6) * link->lanes; in dw_dp_video_enable()
2400 t1 = (1000 / 4) * link->lanes; in dw_dp_video_enable()
2403 return -EINVAL; in dw_dp_video_enable()
2407 t2 = (link->rate / 4) * 1000 / (mode->clock / 2); in dw_dp_video_enable()
2409 t2 = (link->rate / 4) * 1000 / mode->clock; in dw_dp_video_enable()
2420 regmap_write(dp->regmap, DPTX_VIDEO_CONFIG5, in dw_dp_video_enable()
2427 hblank_interval = hblank * (link->rate / 4) / mode->clock; in dw_dp_video_enable()
2428 regmap_write(dp->regmap, DPTX_VIDEO_HBLANK_INTERVAL, in dw_dp_video_enable()
2433 regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE, in dw_dp_video_enable()
2436 if (dw_dp_video_need_vsc_sdp(dp)) in dw_dp_video_enable()
2437 dw_dp_send_vsc_sdp(dp); in dw_dp_video_enable()
2439 if (dw_dp_is_hdr_eotf(dp->eotf_type)) in dw_dp_video_enable()
2440 dw_dp_send_hdr_metadata_infoframe_sdp(dp); in dw_dp_video_enable()
2447 struct dw_dp *dp = arg; in dw_dp_hpd_irq_handler() local
2448 bool hpd = dw_dp_detect(dp); in dw_dp_hpd_irq_handler()
2450 mutex_lock(&dp->irq_lock); in dw_dp_hpd_irq_handler()
2452 dp->hotplug.long_hpd = true; in dw_dp_hpd_irq_handler()
2454 if (dp->hotplug.status && !hpd) { in dw_dp_hpd_irq_handler()
2457 hpd = dw_dp_detect(dp); in dw_dp_hpd_irq_handler()
2459 dp->hotplug.long_hpd = false; in dw_dp_hpd_irq_handler()
2462 dp->hotplug.status = hpd; in dw_dp_hpd_irq_handler()
2464 mutex_unlock(&dp->irq_lock); in dw_dp_hpd_irq_handler()
2466 schedule_work(&dp->hpd_work); in dw_dp_hpd_irq_handler()
2471 static void dw_dp_hpd_init(struct dw_dp *dp) in dw_dp_hpd_init() argument
2473 dp->hotplug.status = dw_dp_detect(dp); in dw_dp_hpd_init()
2475 if (dp->hpd_gpio || dp->force_hpd) { in dw_dp_hpd_init()
2476 regmap_update_bits(dp->regmap, DPTX_CCTL, FORCE_HPD, in dw_dp_hpd_init()
2482 regmap_update_bits(dp->regmap, DPTX_HPD_INTERRUPT_ENABLE, in dw_dp_hpd_init()
2488 /* Enable all top-level interrupts */ in dw_dp_hpd_init()
2489 regmap_update_bits(dp->regmap, DPTX_GENERAL_INTERRUPT_ENABLE, in dw_dp_hpd_init()
2493 static void dw_dp_aux_init(struct dw_dp *dp) in dw_dp_aux_init() argument
2495 regmap_update_bits(dp->regmap, DPTX_GENERAL_INTERRUPT_ENABLE, in dw_dp_aux_init()
2500 static void dw_dp_init(struct dw_dp *dp) in dw_dp_init() argument
2502 regmap_update_bits(dp->regmap, DPTX_CCTL, DEFAULT_FAST_LINK_TRAIN_EN, in dw_dp_init()
2505 dw_dp_hpd_init(dp); in dw_dp_init()
2506 dw_dp_aux_init(dp); in dw_dp_init()
2516 struct dw_dp *dp = encoder_to_dp(encoder); in dw_dp_encoder_disable() local
2517 struct drm_crtc *crtc = encoder->crtc; in dw_dp_encoder_disable()
2518 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state); in dw_dp_encoder_disable()
2520 if (!crtc->state->active_changed) in dw_dp_encoder_disable()
2523 if (dp->split_mode) in dw_dp_encoder_disable()
2524 s->output_if &= ~(VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1); in dw_dp_encoder_disable()
2526 s->output_if &= ~(dp->id ? VOP_OUTPUT_IF_DP1 : VOP_OUTPUT_IF_DP0); in dw_dp_encoder_disable()
2529 static void dw_dp_mode_fixup(struct dw_dp *dp, struct drm_display_mode *adjusted_mode) in dw_dp_mode_fixup() argument
2534 if (dp->split_mode) { in dw_dp_mode_fixup()
2539 if (adjusted_mode->hsync_end - adjusted_mode->hsync_start < min_hsync) { in dw_dp_mode_fixup()
2540 adjusted_mode->hsync_end = adjusted_mode->hsync_start + min_hsync; in dw_dp_mode_fixup()
2541 dev_warn(dp->dev, "hsync is too narrow, fixup to min hsync:%d\n", min_hsync); in dw_dp_mode_fixup()
2543 if (adjusted_mode->htotal - adjusted_mode->hsync_end < min_hbp) { in dw_dp_mode_fixup()
2544 adjusted_mode->htotal = adjusted_mode->hsync_end + min_hbp; in dw_dp_mode_fixup()
2545 dev_warn(dp->dev, "hbp is too narrow, fixup to min hbp:%d\n", min_hbp); in dw_dp_mode_fixup()
2551 if (conn_state->hdr_output_metadata) { in dw_dp_get_eotf()
2553 (struct hdr_output_metadata *)conn_state->hdr_output_metadata->data; in dw_dp_get_eotf()
2555 return hdr_metadata->hdmi_metadata_type1.eotf; in dw_dp_get_eotf()
2565 struct dw_dp *dp = encoder_to_dp(encoder); in dw_dp_encoder_atomic_check() local
2566 struct dw_dp_video *video = &dp->video; in dw_dp_encoder_atomic_check()
2568 struct drm_display_info *di = &conn_state->connector->display_info; in dw_dp_encoder_atomic_check()
2570 dp->eotf_type = dw_dp_get_eotf(conn_state); in dw_dp_encoder_atomic_check()
2571 switch (video->color_format) { in dw_dp_encoder_atomic_check()
2573 s->output_mode = ROCKCHIP_OUT_MODE_YUV420; in dw_dp_encoder_atomic_check()
2576 s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY; in dw_dp_encoder_atomic_check()
2581 s->output_mode = ROCKCHIP_OUT_MODE_AAAA; in dw_dp_encoder_atomic_check()
2585 if (dp->split_mode) { in dw_dp_encoder_atomic_check()
2586 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; in dw_dp_encoder_atomic_check()
2587 s->output_flags |= dp->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0; in dw_dp_encoder_atomic_check()
2588 s->output_if |= VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1; in dw_dp_encoder_atomic_check()
2590 s->output_if |= dp->id ? VOP_OUTPUT_IF_DP1 : VOP_OUTPUT_IF_DP0; in dw_dp_encoder_atomic_check()
2593 s->output_type = DRM_MODE_CONNECTOR_DisplayPort; in dw_dp_encoder_atomic_check()
2594 s->bus_format = video->bus_format; in dw_dp_encoder_atomic_check()
2595 s->bus_flags = di->bus_flags; in dw_dp_encoder_atomic_check()
2596 s->tv_state = &conn_state->tv; in dw_dp_encoder_atomic_check()
2597 s->eotf = dp->eotf_type; in dw_dp_encoder_atomic_check()
2598 if (dw_dp_is_hdr_eotf(s->eotf)) in dw_dp_encoder_atomic_check()
2599 s->color_space = V4L2_COLORSPACE_BT2020; in dw_dp_encoder_atomic_check()
2601 s->color_space = V4L2_COLORSPACE_DEFAULT; in dw_dp_encoder_atomic_check()
2603 dw_dp_mode_fixup(dp, &crtc_state->adjusted_mode); in dw_dp_encoder_atomic_check()
2611 struct drm_crtc *crtc = encoder->crtc; in dw_dp_encoder_mode_valid()
2612 struct drm_device *dev = encoder->dev; in dw_dp_encoder_mode_valid()
2620 s = to_rockchip_crtc_state(crtc->state); in dw_dp_encoder_mode_valid()
2621 s->output_type = DRM_MODE_CONNECTOR_DisplayPort; in dw_dp_encoder_mode_valid()
2635 static int dw_dp_aux_write_data(struct dw_dp *dp, const u8 *buffer, size_t size) in dw_dp_aux_write_data() argument
2640 size_t num = min_t(size_t, size - i * 4, 4); in dw_dp_aux_write_data()
2646 regmap_write(dp->regmap, DPTX_AUX_DATA0 + i * 4, value); in dw_dp_aux_write_data()
2652 static int dw_dp_aux_read_data(struct dw_dp *dp, u8 *buffer, size_t size) in dw_dp_aux_read_data() argument
2657 size_t num = min_t(size_t, size - i * 4, 4); in dw_dp_aux_read_data()
2660 regmap_read(dp->regmap, DPTX_AUX_DATA0 + i * 4, &value); in dw_dp_aux_read_data()
2672 struct dw_dp *dp = container_of(aux, struct dw_dp, aux); in dw_dp_aux_transfer() local
2677 if (WARN_ON(msg->size > 16)) in dw_dp_aux_transfer()
2678 return -E2BIG; in dw_dp_aux_transfer()
2680 switch (msg->request & ~DP_AUX_I2C_MOT) { in dw_dp_aux_transfer()
2684 ret = dw_dp_aux_write_data(dp, msg->buffer, msg->size); in dw_dp_aux_transfer()
2692 return -EINVAL; in dw_dp_aux_transfer()
2695 if (msg->size > 0) in dw_dp_aux_transfer()
2696 value = FIELD_PREP(AUX_LEN_REQ, msg->size - 1); in dw_dp_aux_transfer()
2699 value |= FIELD_PREP(AUX_CMD_TYPE, msg->request); in dw_dp_aux_transfer()
2700 value |= FIELD_PREP(AUX_ADDR, msg->address); in dw_dp_aux_transfer()
2701 regmap_write(dp->regmap, DPTX_AUX_CMD, value); in dw_dp_aux_transfer()
2703 status = wait_for_completion_timeout(&dp->complete, timeout); in dw_dp_aux_transfer()
2705 dev_dbg(dp->dev, "timeout waiting for AUX reply\n"); in dw_dp_aux_transfer()
2706 return -ETIMEDOUT; in dw_dp_aux_transfer()
2709 regmap_read(dp->regmap, DPTX_AUX_STATUS, &value); in dw_dp_aux_transfer()
2711 return -ETIMEDOUT; in dw_dp_aux_transfer()
2713 msg->reply = FIELD_GET(AUX_STATUS, value); in dw_dp_aux_transfer()
2715 if (msg->size > 0 && msg->reply == DP_AUX_NATIVE_REPLY_ACK) { in dw_dp_aux_transfer()
2716 if (msg->request & DP_AUX_I2C_READ) { in dw_dp_aux_transfer()
2717 size_t count = FIELD_GET(AUX_BYTES_READ, value) - 1; in dw_dp_aux_transfer()
2719 if (count != msg->size) in dw_dp_aux_transfer()
2720 return -EBUSY; in dw_dp_aux_transfer()
2722 ret = dw_dp_aux_read_data(dp, msg->buffer, count); in dw_dp_aux_transfer()
2736 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_mode_valid() local
2737 struct dw_dp_link *link = &dp->link; in dw_dp_bridge_mode_valid()
2743 if (dp->split_mode) in dw_dp_bridge_mode_valid()
2746 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB420 && in dw_dp_bridge_mode_valid()
2747 link->vsc_sdp_extension_for_colorimetry_supported && in dw_dp_bridge_mode_valid()
2750 else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) in dw_dp_bridge_mode_valid()
2752 else if (info->color_formats & DRM_COLOR_FORMAT_RGB444) in dw_dp_bridge_mode_valid()
2757 if (!link->vsc_sdp_extension_for_colorimetry_supported && in dw_dp_bridge_mode_valid()
2761 if (!dw_dp_bandwidth_ok(dp, &m, min_bpp, link->lanes, link->rate)) in dw_dp_bridge_mode_valid()
2767 static void _dw_dp_loader_protect(struct dw_dp *dp, bool on) in _dw_dp_loader_protect() argument
2769 struct dw_dp_link *link = &dp->link; in _dw_dp_loader_protect()
2770 struct drm_connector *conn = &dp->connector; in _dw_dp_loader_protect()
2771 struct drm_display_info *di = &conn->display_info; in _dw_dp_loader_protect()
2776 di->color_formats = DRM_COLOR_FORMAT_RGB444; in _dw_dp_loader_protect()
2777 di->bpc = 8; in _dw_dp_loader_protect()
2779 regmap_read(dp->regmap, DPTX_PHYIF_CTRL, &value); in _dw_dp_loader_protect()
2782 link->lanes = 4; in _dw_dp_loader_protect()
2785 link->lanes = 2; in _dw_dp_loader_protect()
2790 link->lanes = 1; in _dw_dp_loader_protect()
2796 link->rate = 810000; in _dw_dp_loader_protect()
2799 link->rate = 540000; in _dw_dp_loader_protect()
2802 link->rate = 270000; in _dw_dp_loader_protect()
2807 link->rate = 162000; in _dw_dp_loader_protect()
2811 phy_power_on(dp->phy); in _dw_dp_loader_protect()
2813 phy_power_off(dp->phy); in _dw_dp_loader_protect()
2819 struct dw_dp *dp = encoder_to_dp(encoder); in dw_dp_loader_protect() local
2821 _dw_dp_loader_protect(dp, on); in dw_dp_loader_protect()
2822 if (dp->right) in dw_dp_loader_protect()
2823 _dw_dp_loader_protect(dp->right, on); in dw_dp_loader_protect()
2828 static int dw_dp_connector_init(struct dw_dp *dp) in dw_dp_connector_init() argument
2830 struct drm_connector *connector = &dp->connector; in dw_dp_connector_init()
2831 struct drm_bridge *bridge = &dp->bridge; in dw_dp_connector_init()
2833 struct drm_device *dev = bridge->dev; in dw_dp_connector_init()
2836 connector->polled = DRM_CONNECTOR_POLL_HPD; in dw_dp_connector_init()
2837 if (dp->next_bridge && dp->next_bridge->ops & DRM_BRIDGE_OP_DETECT) in dw_dp_connector_init()
2838 connector->polled = DRM_CONNECTOR_POLL_CONNECT | in dw_dp_connector_init()
2840 connector->ycbcr_420_allowed = true; in dw_dp_connector_init()
2842 ret = drm_connector_init(bridge->dev, connector, in dw_dp_connector_init()
2846 DRM_DEV_ERROR(dp->dev, "Failed to initialize connector\n"); in dw_dp_connector_init()
2853 drm_connector_attach_encoder(connector, bridge->encoder); in dw_dp_connector_init()
2855 prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_DEPTH, in dw_dp_connector_init()
2859 DRM_DEV_ERROR(dp->dev, "create color depth prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2860 return -ENOMEM; in dw_dp_connector_init()
2862 dp->color_depth_property = prop; in dw_dp_connector_init()
2863 drm_object_attach_property(&connector->base, prop, 0); in dw_dp_connector_init()
2865 prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT, in dw_dp_connector_init()
2869 DRM_DEV_ERROR(dp->dev, "create color format prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2870 return -ENOMEM; in dw_dp_connector_init()
2872 dp->color_format_property = prop; in dw_dp_connector_init()
2873 drm_object_attach_property(&connector->base, prop, 0); in dw_dp_connector_init()
2875 prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_COLOR_DEPTH_CAPS, in dw_dp_connector_init()
2878 DRM_DEV_ERROR(dp->dev, "create color depth caps prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2879 return -ENOMEM; in dw_dp_connector_init()
2881 dp->color_depth_capacity = prop; in dw_dp_connector_init()
2882 drm_object_attach_property(&connector->base, prop, 0); in dw_dp_connector_init()
2884 prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT_CAPS, in dw_dp_connector_init()
2887 DRM_DEV_ERROR(dp->dev, "create color format caps prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2888 return -ENOMEM; in dw_dp_connector_init()
2890 dp->color_format_capacity = prop; in dw_dp_connector_init()
2891 drm_object_attach_property(&connector->base, prop, 0); in dw_dp_connector_init()
2893 ret = drm_connector_attach_content_protection_property(&dp->connector, true); in dw_dp_connector_init()
2895 dev_err(dp->dev, "failed to attach content protection: %d\n", ret); in dw_dp_connector_init()
2899 prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_ENCRYPTED, in dw_dp_connector_init()
2902 dev_err(dp->dev, "create hdcp encrypted prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2903 return -ENOMEM; in dw_dp_connector_init()
2905 dp->hdcp_state_property = prop; in dw_dp_connector_init()
2906 drm_object_attach_property(&connector->base, prop, RK_IF_HDCP_ENCRYPTED_NONE); in dw_dp_connector_init()
2908 prop = drm_property_create(connector->dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE, in dw_dp_connector_init()
2911 DRM_DEV_ERROR(dp->dev, "create hdr metedata prop for dp%d failed\n", dp->id); in dw_dp_connector_init()
2912 return -ENOMEM; in dw_dp_connector_init()
2914 dp->hdr_panel_metadata_property = prop; in dw_dp_connector_init()
2915 drm_object_attach_property(&connector->base, prop, 0); in dw_dp_connector_init()
2916 drm_object_attach_property(&connector->base, in dw_dp_connector_init()
2917 dev->mode_config.hdr_output_metadata_property, in dw_dp_connector_init()
2926 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_attach() local
2931 if (!bridge->encoder) { in dw_dp_bridge_attach()
2932 DRM_DEV_ERROR(dp->dev, "Parent encoder object not found"); in dw_dp_bridge_attach()
2933 return -ENODEV; in dw_dp_bridge_attach()
2936 ret = drm_of_find_panel_or_bridge(bridge->of_node, 1, -1, &dp->panel, in dw_dp_bridge_attach()
2937 &dp->next_bridge); in dw_dp_bridge_attach()
2938 if (ret < 0 && ret != -ENODEV) in dw_dp_bridge_attach()
2941 if (dp->next_bridge) { in dw_dp_bridge_attach()
2942 struct drm_bridge *next_bridge = dp->next_bridge; in dw_dp_bridge_attach()
2944 ret = drm_bridge_attach(bridge->encoder, next_bridge, bridge, in dw_dp_bridge_attach()
2945 next_bridge->ops & DRM_BRIDGE_OP_MODES ? in dw_dp_bridge_attach()
2948 DRM_DEV_ERROR(dp->dev, "failed to attach next bridge: %d\n", ret); in dw_dp_bridge_attach()
2952 skip_connector = !(next_bridge->ops & DRM_BRIDGE_OP_MODES); in dw_dp_bridge_attach()
2959 ret = dw_dp_connector_init(dp); in dw_dp_bridge_attach()
2961 DRM_DEV_ERROR(dp->dev, "failed to create connector\n"); in dw_dp_bridge_attach()
2965 connector = &dp->connector; in dw_dp_bridge_attach()
2968 &bridge->dev->mode_config.connector_list; in dw_dp_bridge_attach()
2972 bridge->encoder)) in dw_dp_bridge_attach()
2976 dp->sub_dev.connector = connector; in dw_dp_bridge_attach()
2977 dp->sub_dev.of_node = dp->dev->of_node; in dw_dp_bridge_attach()
2978 dp->sub_dev.loader_protect = dw_dp_loader_protect; in dw_dp_bridge_attach()
2979 rockchip_drm_register_sub_dev(&dp->sub_dev); in dw_dp_bridge_attach()
2986 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_detach() local
2988 drm_connector_cleanup(&dp->connector); in dw_dp_bridge_detach()
2994 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_pre_enable() local
2995 struct dw_dp_video *video = &dp->video; in dw_dp_bridge_atomic_pre_enable()
2996 struct drm_crtc_state *crtc_state = bridge->encoder->crtc->state; in dw_dp_bridge_atomic_pre_enable()
2997 struct drm_display_mode *m = &video->mode; in dw_dp_bridge_atomic_pre_enable()
2999 drm_mode_copy(m, &crtc_state->adjusted_mode); in dw_dp_bridge_atomic_pre_enable()
3001 if (dp->split_mode) in dw_dp_bridge_atomic_pre_enable()
3004 if (dp->panel) in dw_dp_bridge_atomic_pre_enable()
3005 drm_panel_prepare(dp->panel); in dw_dp_bridge_atomic_pre_enable()
3012 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_post_disable() local
3014 if (dp->panel) in dw_dp_bridge_atomic_post_disable()
3015 drm_panel_unprepare(dp->panel); in dw_dp_bridge_atomic_post_disable()
3018 static bool dw_dp_needs_link_retrain(struct dw_dp *dp) in dw_dp_needs_link_retrain() argument
3020 struct dw_dp_link *link = &dp->link; in dw_dp_needs_link_retrain()
3023 if (!dw_dp_link_train_valid(&link->train)) in dw_dp_needs_link_retrain()
3026 if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) < 0) in dw_dp_needs_link_retrain()
3030 return !drm_dp_channel_eq_ok(link_status, dp->link.lanes); in dw_dp_needs_link_retrain()
3033 static void dw_dp_link_disable(struct dw_dp *dp) in dw_dp_link_disable() argument
3035 struct dw_dp_link *link = &dp->link; in dw_dp_link_disable()
3037 if (dw_dp_detect(dp)) in dw_dp_link_disable()
3038 dw_dp_link_power_down(dp); in dw_dp_link_disable()
3040 dw_dp_phy_xmit_enable(dp, 0); in dw_dp_link_disable()
3042 phy_power_off(dp->phy); in dw_dp_link_disable()
3044 link->train.clock_recovered = false; in dw_dp_link_disable()
3045 link->train.channel_equalized = false; in dw_dp_link_disable()
3048 static int dw_dp_link_enable(struct dw_dp *dp) in dw_dp_link_enable() argument
3052 ret = phy_power_on(dp->phy); in dw_dp_link_enable()
3056 ret = dw_dp_link_power_up(dp); in dw_dp_link_enable()
3060 ret = dw_dp_link_train(dp); in dw_dp_link_enable()
3062 dev_err(dp->dev, "link training failed: %d\n", ret); in dw_dp_link_enable()
3072 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_enable() local
3073 struct drm_atomic_state *state = old_state->base.state; in dw_dp_bridge_atomic_enable()
3078 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); in dw_dp_bridge_atomic_enable()
3080 dev_err(dp->dev, "failed to get connector\n"); in dw_dp_bridge_atomic_enable()
3086 dev_err(dp->dev, "failed to get connector state\n"); in dw_dp_bridge_atomic_enable()
3090 set_bit(0, dp->sdp_reg_bank); in dw_dp_bridge_atomic_enable()
3092 ret = dw_dp_link_enable(dp); in dw_dp_bridge_atomic_enable()
3094 dev_err(dp->dev, "failed to enable link: %d\n", ret); in dw_dp_bridge_atomic_enable()
3098 if (conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) in dw_dp_bridge_atomic_enable()
3099 dw_dp_hdcp_enable(dp, conn_state->hdcp_content_type); in dw_dp_bridge_atomic_enable()
3101 ret = dw_dp_video_enable(dp); in dw_dp_bridge_atomic_enable()
3103 dev_err(dp->dev, "failed to enable video: %d\n", ret); in dw_dp_bridge_atomic_enable()
3107 if (dp->panel) in dw_dp_bridge_atomic_enable()
3108 drm_panel_enable(dp->panel); in dw_dp_bridge_atomic_enable()
3110 extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true); in dw_dp_bridge_atomic_enable()
3111 dw_dp_audio_handle_plugged_change(&dp->audio, true); in dw_dp_bridge_atomic_enable()
3114 static void dw_dp_reset(struct dw_dp *dp) in dw_dp_reset() argument
3118 disable_irq(dp->irq); in dw_dp_reset()
3119 regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET, in dw_dp_reset()
3122 regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET, in dw_dp_reset()
3125 dw_dp_init(dp); in dw_dp_reset()
3126 if (!dp->hpd_gpio) { in dw_dp_reset()
3127 regmap_read_poll_timeout(dp->regmap, DPTX_HPD_STATUS, val, in dw_dp_reset()
3129 regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_PLUG); in dw_dp_reset()
3131 enable_irq(dp->irq); in dw_dp_reset()
3137 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_disable() local
3139 if (dp->panel) in dw_dp_bridge_atomic_disable()
3140 drm_panel_disable(dp->panel); in dw_dp_bridge_atomic_disable()
3142 dw_dp_hdcp_disable(dp); in dw_dp_bridge_atomic_disable()
3143 dw_dp_video_disable(dp); in dw_dp_bridge_atomic_disable()
3144 dw_dp_link_disable(dp); in dw_dp_bridge_atomic_disable()
3145 bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); in dw_dp_bridge_atomic_disable()
3146 dw_dp_reset(dp); in dw_dp_bridge_atomic_disable()
3148 extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false); in dw_dp_bridge_atomic_disable()
3149 dw_dp_audio_handle_plugged_change(&dp->audio, false); in dw_dp_bridge_atomic_disable()
3152 static bool dw_dp_detect_dpcd(struct dw_dp *dp) in dw_dp_detect_dpcd() argument
3157 ret = phy_power_on(dp->phy); in dw_dp_detect_dpcd()
3161 ret = drm_dp_dpcd_readb(&dp->aux, DP_DPCD_REV, &value); in dw_dp_detect_dpcd()
3163 dev_err(dp->dev, "aux failed to read dpcd: %d\n", ret); in dw_dp_detect_dpcd()
3167 ret = dw_dp_link_probe(dp); in dw_dp_detect_dpcd()
3169 dev_err(dp->dev, "failed to probe DP link: %d\n", ret); in dw_dp_detect_dpcd()
3173 phy_power_off(dp->phy); in dw_dp_detect_dpcd()
3178 phy_power_off(dp->phy); in dw_dp_detect_dpcd()
3185 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_detect() local
3188 if (dp->panel) in dw_dp_bridge_detect()
3189 drm_panel_prepare(dp->panel); in dw_dp_bridge_detect()
3191 if (!dw_dp_detect(dp)) { in dw_dp_bridge_detect()
3196 if (!dw_dp_detect_dpcd(dp)) { in dw_dp_bridge_detect()
3201 if (dp->next_bridge) { in dw_dp_bridge_detect()
3202 struct drm_bridge *next_bridge = dp->next_bridge; in dw_dp_bridge_detect()
3204 if (next_bridge->ops & DRM_BRIDGE_OP_DETECT) in dw_dp_bridge_detect()
3215 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_get_edid() local
3219 ret = phy_power_on(dp->phy); in dw_dp_bridge_get_edid()
3223 edid = drm_get_edid(connector, &dp->aux.ddc); in dw_dp_bridge_get_edid()
3225 phy_power_off(dp->phy); in dw_dp_bridge_get_edid()
3236 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_get_output_bus_fmts() local
3238 struct dw_dp_link *link = &dp->link; in dw_dp_bridge_atomic_get_output_bus_fmts()
3239 struct drm_display_info *di = &conn_state->connector->display_info; in dw_dp_bridge_atomic_get_output_bus_fmts()
3240 struct drm_display_mode mode = crtc_state->mode; in dw_dp_bridge_atomic_get_output_bus_fmts()
3244 if (dp->split_mode) in dw_dp_bridge_atomic_get_output_bus_fmts()
3247 if (dp->panel) { in dw_dp_bridge_atomic_get_output_bus_fmts()
3254 if (di->num_bus_formats && di->bus_formats) in dw_dp_bridge_atomic_get_output_bus_fmts()
3255 output_fmts[0] = di->bus_formats[0]; in dw_dp_bridge_atomic_get_output_bus_fmts()
3272 if (fmt->bpc > conn_state->max_bpc) in dw_dp_bridge_atomic_get_output_bus_fmts()
3275 if (!(di->color_formats & fmt->color_format)) in dw_dp_bridge_atomic_get_output_bus_fmts()
3278 if (fmt->color_format == DRM_COLOR_FORMAT_YCRCB420 && in dw_dp_bridge_atomic_get_output_bus_fmts()
3279 !link->vsc_sdp_extension_for_colorimetry_supported) in dw_dp_bridge_atomic_get_output_bus_fmts()
3283 fmt->color_format != DRM_COLOR_FORMAT_YCRCB420) in dw_dp_bridge_atomic_get_output_bus_fmts()
3286 if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate)) in dw_dp_bridge_atomic_get_output_bus_fmts()
3289 if (dp_state->bpc != 0) { in dw_dp_bridge_atomic_get_output_bus_fmts()
3290 if ((fmt->bpc != dp_state->bpc) || in dw_dp_bridge_atomic_get_output_bus_fmts()
3291 (fmt->color_format != BIT(dp_state->color_format))) in dw_dp_bridge_atomic_get_output_bus_fmts()
3295 if (dw_dp_is_hdr_eotf(dp->eotf_type) && fmt->bpc < 10) in dw_dp_bridge_atomic_get_output_bus_fmts()
3298 output_fmts[j++] = fmt->bus_format; in dw_dp_bridge_atomic_get_output_bus_fmts()
3311 struct dw_dp *dp = bridge_to_dp(bridge); in dw_dp_bridge_atomic_check() local
3312 struct dw_dp_video *video = &dp->video; in dw_dp_bridge_atomic_check()
3314 dw_dp_get_output_format(bridge_state->output_bus_cfg.format); in dw_dp_bridge_atomic_check()
3316 dev_dbg(dp->dev, "input format 0x%04x, output format 0x%04x\n", in dw_dp_bridge_atomic_check()
3317 bridge_state->input_bus_cfg.format, in dw_dp_bridge_atomic_check()
3318 bridge_state->output_bus_cfg.format); in dw_dp_bridge_atomic_check()
3320 video->video_mapping = fmt->video_mapping; in dw_dp_bridge_atomic_check()
3321 video->color_format = fmt->color_format; in dw_dp_bridge_atomic_check()
3322 video->bus_format = fmt->bus_format; in dw_dp_bridge_atomic_check()
3323 video->bpc = fmt->bpc; in dw_dp_bridge_atomic_check()
3324 video->bpp = fmt->bpp; in dw_dp_bridge_atomic_check()
3347 static int dw_dp_link_retrain(struct dw_dp *dp) in dw_dp_link_retrain() argument
3349 struct drm_device *dev = dp->bridge.dev; in dw_dp_link_retrain()
3353 if (!dw_dp_needs_link_retrain(dp)) in dw_dp_link_retrain()
3356 dev_dbg(dp->dev, "Retraining link\n"); in dw_dp_link_retrain()
3360 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); in dw_dp_link_retrain()
3361 if (ret != -EDEADLK) in dw_dp_link_retrain()
3367 ret = dw_dp_link_train(dp); in dw_dp_link_retrain()
3374 static u8 dw_dp_autotest_phy_pattern(struct dw_dp *dp) in dw_dp_autotest_phy_pattern() argument
3376 struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest; in dw_dp_autotest_phy_pattern()
3378 if (drm_dp_get_phy_test_pattern(&dp->aux, data)) { in dw_dp_autotest_phy_pattern()
3379 dev_err(dp->dev, "DP Phy Test pattern AUX read failure\n"); in dw_dp_autotest_phy_pattern()
3384 dp->compliance.test_active = true; in dw_dp_autotest_phy_pattern()
3389 static void dw_dp_handle_test_request(struct dw_dp *dp) in dw_dp_handle_test_request() argument
3395 status = drm_dp_dpcd_readb(&dp->aux, DP_TEST_REQUEST, &request); in dw_dp_handle_test_request()
3397 dev_err(dp->dev, "Could not read test request from sink\n"); in dw_dp_handle_test_request()
3403 dev_dbg(dp->dev, "PHY_PATTERN test requested\n"); in dw_dp_handle_test_request()
3404 response = dw_dp_autotest_phy_pattern(dp); in dw_dp_handle_test_request()
3407 dev_warn(dp->dev, "Invalid test request '%02x'\n", request); in dw_dp_handle_test_request()
3412 dp->compliance.test_type = request; in dw_dp_handle_test_request()
3415 status = drm_dp_dpcd_writeb(&dp->aux, DP_TEST_RESPONSE, response); in dw_dp_handle_test_request()
3417 dev_warn(dp->dev, "Could not write test response to sink\n"); in dw_dp_handle_test_request()
3420 static void dw_dp_hdcp_handle_cp_irq(struct dw_dp *dp) in dw_dp_hdcp_handle_cp_irq() argument
3422 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, CP_IRQ, CP_IRQ); in dw_dp_hdcp_handle_cp_irq()
3424 regmap_update_bits(dp->regmap, DPTX_HDCPCFG, CP_IRQ, 0); in dw_dp_hdcp_handle_cp_irq()
3427 static void dw_dp_check_service_irq(struct dw_dp *dp) in dw_dp_check_service_irq() argument
3429 struct dw_dp_link *link = &dp->link; in dw_dp_check_service_irq()
3432 if (link->dpcd[DP_DPCD_REV] < 0x11) in dw_dp_check_service_irq()
3435 if (drm_dp_dpcd_readb(&dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, &val) != 1 || !val) in dw_dp_check_service_irq()
3438 drm_dp_dpcd_writeb(&dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val); in dw_dp_check_service_irq()
3441 dw_dp_handle_test_request(dp); in dw_dp_check_service_irq()
3444 dw_dp_hdcp_handle_cp_irq(dp); in dw_dp_check_service_irq()
3447 dev_info(dp->dev, "Sink specific irq unhandled\n"); in dw_dp_check_service_irq()
3450 static void dw_dp_phy_pattern_update(struct dw_dp *dp) in dw_dp_phy_pattern_update() argument
3452 struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest; in dw_dp_phy_pattern_update()
3454 switch (data->phy_pattern) { in dw_dp_phy_pattern_update()
3456 dev_dbg(dp->dev, "Disable Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3457 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3459 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_NONE); in dw_dp_phy_pattern_update()
3462 dev_dbg(dp->dev, "Set D10.2 Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3463 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3465 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_1); in dw_dp_phy_pattern_update()
3468 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3470 dev_dbg(dp->dev, "Set Error Count Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3471 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_SERM); in dw_dp_phy_pattern_update()
3474 dev_dbg(dp->dev, "Set PRBS7 Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3475 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3477 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_PBRS7); in dw_dp_phy_pattern_update()
3480 dev_dbg(dp->dev, "Set 80Bit Custom Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3481 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3483 regmap_write(dp->regmap, DPTX_CUSTOMPAT0, 0x3e0f83e0); in dw_dp_phy_pattern_update()
3484 regmap_write(dp->regmap, DPTX_CUSTOMPAT1, 0x3e0f83e0); in dw_dp_phy_pattern_update()
3485 regmap_write(dp->regmap, DPTX_CUSTOMPAT2, 0x000f83e0); in dw_dp_phy_pattern_update()
3486 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_CUSTOM_80BIT); in dw_dp_phy_pattern_update()
3489 dev_dbg(dp->dev, "Set HBR2 compliance Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3490 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3492 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_CP2520_1); in dw_dp_phy_pattern_update()
3495 dev_dbg(dp->dev, "Set TPS4 Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3496 regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS, in dw_dp_phy_pattern_update()
3498 dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_4); in dw_dp_phy_pattern_update()
3501 WARN(1, "Invalid Phy Test Pattern\n"); in dw_dp_phy_pattern_update()
3505 static void dw_dp_process_phy_request(struct dw_dp *dp) in dw_dp_process_phy_request() argument
3507 struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest; in dw_dp_process_phy_request()
3511 ret = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE); in dw_dp_process_phy_request()
3513 dev_err(dp->dev, "failed to get link status\n"); in dw_dp_process_phy_request()
3517 ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread); in dw_dp_process_phy_request()
3519 dev_err(dp->dev, "failed to get spread\n"); in dw_dp_process_phy_request()
3523 dw_dp_phy_configure(dp, data->link_rate, data->num_lanes, in dw_dp_process_phy_request()
3525 dw_dp_link_get_adjustments(&dp->link, link_status); in dw_dp_process_phy_request()
3526 dw_dp_phy_update_vs_emph(dp, data->link_rate, data->num_lanes, &dp->link.train.adjust); in dw_dp_process_phy_request()
3527 dw_dp_phy_pattern_update(dp); in dw_dp_process_phy_request()
3528 drm_dp_set_phy_test_pattern(&dp->aux, data, link_status[DP_DPCD_REV]); in dw_dp_process_phy_request()
3530 dev_dbg(dp->dev, "phy test rate:%d, lane count:%d, ssc:%d, vs:%d, pe: %d\n", in dw_dp_process_phy_request()
3531 data->link_rate, data->num_lanes, spread, dp->link.train.adjust.voltage_swing[0], in dw_dp_process_phy_request()
3532 dp->link.train.adjust.pre_emphasis[0]); in dw_dp_process_phy_request()
3535 static void dw_dp_phy_test(struct dw_dp *dp) in dw_dp_phy_test() argument
3537 struct drm_device *dev = dp->bridge.dev; in dw_dp_phy_test()
3544 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); in dw_dp_phy_test()
3545 if (ret != -EDEADLK) in dw_dp_phy_test()
3551 dw_dp_process_phy_request(dp); in dw_dp_phy_test()
3556 static bool dw_dp_hpd_short_pulse(struct dw_dp *dp) in dw_dp_hpd_short_pulse() argument
3558 memset(&dp->compliance, 0, sizeof(dp->compliance)); in dw_dp_hpd_short_pulse()
3560 dw_dp_check_service_irq(dp); in dw_dp_hpd_short_pulse()
3562 if (dw_dp_needs_link_retrain(dp)) in dw_dp_hpd_short_pulse()
3565 switch (dp->compliance.test_type) { in dw_dp_hpd_short_pulse()
3569 dev_warn(dp->dev, "test_type%lu is not support\n", dp->compliance.test_type); in dw_dp_hpd_short_pulse()
3578 struct dw_dp *dp = container_of(work, struct dw_dp, hpd_work); in dw_dp_hpd_work() local
3582 mutex_lock(&dp->irq_lock); in dw_dp_hpd_work()
3583 long_hpd = dp->hotplug.long_hpd; in dw_dp_hpd_work()
3584 mutex_unlock(&dp->irq_lock); in dw_dp_hpd_work()
3586 dev_dbg(dp->dev, "got hpd irq - %s\n", long_hpd ? "long" : "short"); in dw_dp_hpd_work()
3589 if (dw_dp_hpd_short_pulse(dp)) in dw_dp_hpd_work()
3592 if (dp->compliance.test_active && in dw_dp_hpd_work()
3593 dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { in dw_dp_hpd_work()
3594 dw_dp_phy_test(dp); in dw_dp_hpd_work()
3595 /* just do the PHY test and nothing else */ in dw_dp_hpd_work()
3599 ret = dw_dp_link_retrain(dp); in dw_dp_hpd_work()
3601 dev_warn(dp->dev, "Retrain link failed\n"); in dw_dp_hpd_work()
3603 drm_helper_hpd_irq_event(dp->bridge.dev); in dw_dp_hpd_work()
3607 static void dw_dp_handle_hpd_event(struct dw_dp *dp) in dw_dp_handle_hpd_event() argument
3611 mutex_lock(&dp->irq_lock); in dw_dp_handle_hpd_event()
3613 regmap_read(dp->regmap, DPTX_HPD_STATUS, &value); in dw_dp_handle_hpd_event()
3616 dev_dbg(dp->dev, "IRQ from the HPD\n"); in dw_dp_handle_hpd_event()
3617 dp->hotplug.long_hpd = false; in dw_dp_handle_hpd_event()
3618 regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_IRQ); in dw_dp_handle_hpd_event()
3622 dev_dbg(dp->dev, "Hot plug detected\n"); in dw_dp_handle_hpd_event()
3623 dp->hotplug.long_hpd = true; in dw_dp_handle_hpd_event()
3624 regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_PLUG); in dw_dp_handle_hpd_event()
3628 dev_dbg(dp->dev, "Unplug detected\n"); in dw_dp_handle_hpd_event()
3629 dp->hotplug.long_hpd = true; in dw_dp_handle_hpd_event()
3630 regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_UNPLUG); in dw_dp_handle_hpd_event()
3633 mutex_unlock(&dp->irq_lock); in dw_dp_handle_hpd_event()
3635 schedule_work(&dp->hpd_work); in dw_dp_handle_hpd_event()
3640 struct dw_dp *dp = data; in dw_dp_irq_handler() local
3643 regmap_read(dp->regmap, DPTX_GENERAL_INTERRUPT, &value); in dw_dp_irq_handler()
3648 dw_dp_handle_hpd_event(dp); in dw_dp_irq_handler()
3651 regmap_write(dp->regmap, DPTX_GENERAL_INTERRUPT, in dw_dp_irq_handler()
3653 complete(&dp->complete); in dw_dp_irq_handler()
3657 dw_dp_handle_hdcp_event(dp); in dw_dp_irq_handler()
3666 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_audio_hw_params() local
3667 struct dw_dp_audio *audio = &dp->audio; in dw_dp_audio_hw_params()
3670 audio->channels = params->cea.channels; in dw_dp_audio_hw_params()
3672 switch (params->cea.channels) { in dw_dp_audio_hw_params()
3686 dev_err(dp->dev, "invalid channels %d\n", params->cea.channels); in dw_dp_audio_hw_params()
3687 return -EINVAL; in dw_dp_audio_hw_params()
3690 switch (daifmt->fmt) { in dw_dp_audio_hw_params()
3693 audio->format = AFMT_SPDIF; in dw_dp_audio_hw_params()
3697 audio->format = AFMT_I2S; in dw_dp_audio_hw_params()
3700 dev_err(dp->dev, "invalid daifmt %d\n", daifmt->fmt); in dw_dp_audio_hw_params()
3701 return -EINVAL; in dw_dp_audio_hw_params()
3704 clk_prepare_enable(dp->spdif_clk); in dw_dp_audio_hw_params()
3705 clk_prepare_enable(dp->i2s_clk); in dw_dp_audio_hw_params()
3707 regmap_update_bits(dp->regmap, DPTX_AUD_CONFIG1, in dw_dp_audio_hw_params()
3712 FIELD_PREP(AUDIO_DATA_WIDTH, params->sample_width) | in dw_dp_audio_hw_params()
3717 if (audio->format == AFMT_I2S) in dw_dp_audio_hw_params()
3718 clk_disable_unprepare(dp->spdif_clk); in dw_dp_audio_hw_params()
3719 else if (audio->format == AFMT_SPDIF) in dw_dp_audio_hw_params()
3720 clk_disable_unprepare(dp->i2s_clk); in dw_dp_audio_hw_params()
3725 static int dw_dp_audio_infoframe_send(struct dw_dp *dp) in dw_dp_audio_infoframe_send() argument
3727 struct dw_dp_audio *audio = &dp->audio; in dw_dp_audio_infoframe_send()
3746 frame.channels = audio->channels; in dw_dp_audio_infoframe_send()
3752 regmap_write(dp->regmap, DPTX_SDP_REGISTER_BANK, in dw_dp_audio_infoframe_send()
3756 size_t num = min_t(size_t, size - i * 4, 4); in dw_dp_audio_infoframe_send()
3762 regmap_write(dp->regmap, DPTX_SDP_REGISTER_BANK + 4 * i, value); in dw_dp_audio_infoframe_send()
3765 regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL, in dw_dp_audio_infoframe_send()
3773 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_audio_startup() local
3775 regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL, in dw_dp_audio_startup()
3779 regmap_update_bits(dp->regmap, DPTX_SDP_HORIZONTAL_CTRL, in dw_dp_audio_startup()
3783 return dw_dp_audio_infoframe_send(dp); in dw_dp_audio_startup()
3788 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_audio_shutdown() local
3789 struct dw_dp_audio *audio = &dp->audio; in dw_dp_audio_shutdown()
3791 regmap_update_bits(dp->regmap, DPTX_AUD_CONFIG1, AUDIO_DATA_IN_EN, in dw_dp_audio_shutdown()
3794 if (audio->format == AFMT_SPDIF) in dw_dp_audio_shutdown()
3795 clk_disable_unprepare(dp->spdif_clk); in dw_dp_audio_shutdown()
3796 else if (audio->format == AFMT_I2S) in dw_dp_audio_shutdown()
3797 clk_disable_unprepare(dp->i2s_clk); in dw_dp_audio_shutdown()
3799 audio->format = AFMT_UNUSED; in dw_dp_audio_shutdown()
3806 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_audio_hook_plugged_cb() local
3807 struct dw_dp_audio *audio = &dp->audio; in dw_dp_audio_hook_plugged_cb()
3809 audio->plugged_cb = fn; in dw_dp_audio_hook_plugged_cb()
3810 audio->codec_dev = codec_dev; in dw_dp_audio_hook_plugged_cb()
3811 dw_dp_audio_handle_plugged_change(audio, dw_dp_detect(dp)); in dw_dp_audio_hook_plugged_cb()
3818 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_audio_get_eld() local
3819 struct drm_connector *connector = &dp->connector; in dw_dp_audio_get_eld()
3821 memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); in dw_dp_audio_get_eld()
3834 static int dw_dp_register_audio_driver(struct dw_dp *dp) in dw_dp_register_audio_driver() argument
3836 struct dw_dp_audio *audio = &dp->audio; in dw_dp_register_audio_driver()
3844 audio->format = AFMT_UNUSED; in dw_dp_register_audio_driver()
3845 audio->pdev = platform_device_register_data(dp->dev, in dw_dp_register_audio_driver()
3851 return PTR_ERR_OR_ZERO(audio->pdev); in dw_dp_register_audio_driver()
3856 struct dw_dp *dp = data; in dw_dp_unregister_audio_driver() local
3857 struct dw_dp_audio *audio = &dp->audio; in dw_dp_unregister_audio_driver()
3859 if (audio->pdev) { in dw_dp_unregister_audio_driver()
3860 platform_device_unregister(audio->pdev); in dw_dp_unregister_audio_driver()
3861 audio->pdev = NULL; in dw_dp_unregister_audio_driver()
3867 struct dw_dp *dp = data; in dw_dp_aux_unregister() local
3869 drm_dp_aux_unregister(&dp->aux); in dw_dp_aux_unregister()
3874 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_bind() local
3876 struct drm_encoder *encoder = &dp->encoder; in dw_dp_bind()
3877 struct drm_bridge *bridge = &dp->bridge; in dw_dp_bind()
3880 if (!dp->left) { in dw_dp_bind()
3884 encoder->possible_crtcs = in dw_dp_bind()
3885 rockchip_drm_of_find_possible_crtcs(drm_dev, dev->of_node); in dw_dp_bind()
3894 if (dp->right) { in dw_dp_bind()
3895 struct dw_dp *secondary = dp->right; in dw_dp_bind()
3897 list_last_entry(&encoder->bridge_chain, in dw_dp_bind()
3900 ret = drm_bridge_attach(encoder, &secondary->bridge, last_bridge, in dw_dp_bind()
3906 pm_runtime_enable(dp->dev); in dw_dp_bind()
3907 pm_runtime_get_sync(dp->dev); in dw_dp_bind()
3909 enable_irq(dp->irq); in dw_dp_bind()
3910 if (dp->hpd_gpio) in dw_dp_bind()
3911 enable_irq(dp->hpd_irq); in dw_dp_bind()
3918 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_unbind() local
3920 if (dp->hpd_gpio) in dw_dp_unbind()
3921 disable_irq(dp->hpd_irq); in dw_dp_unbind()
3922 disable_irq(dp->irq); in dw_dp_unbind()
3924 pm_runtime_put(dp->dev); in dw_dp_unbind()
3925 pm_runtime_disable(dp->dev); in dw_dp_unbind()
3927 drm_encoder_cleanup(&dp->encoder); in dw_dp_unbind()
3963 static u32 dw_dp_parse_link_frequencies(struct dw_dp *dp) in dw_dp_parse_link_frequencies() argument
3965 struct device_node *node = dp->dev->of_node; in dw_dp_parse_link_frequencies()
3974 cnt = of_property_count_u64_elems(endpoint, "link-frequencies"); in dw_dp_parse_link_frequencies()
3976 of_property_read_u64_index(endpoint, "link-frequencies", in dw_dp_parse_link_frequencies()
3977 cnt - 1, &frequency); in dw_dp_parse_link_frequencies()
3992 dev_err(dp->dev, "invalid link frequency value: %llu\n", frequency); in dw_dp_parse_link_frequencies()
3999 static int dw_dp_parse_dt(struct dw_dp *dp) in dw_dp_parse_dt() argument
4001 dp->force_hpd = device_property_read_bool(dp->dev, "force-hpd"); in dw_dp_parse_dt()
4003 dp->max_link_rate = dw_dp_parse_link_frequencies(dp); in dw_dp_parse_dt()
4004 if (!dp->max_link_rate) in dw_dp_parse_dt()
4005 dp->max_link_rate = 810000; in dw_dp_parse_dt()
4012 struct device *dev = &pdev->dev; in dw_dp_probe()
4013 struct dw_dp *dp; in dw_dp_probe() local
4017 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); in dw_dp_probe()
4018 if (!dp) in dw_dp_probe()
4019 return -ENOMEM; in dw_dp_probe()
4021 id = of_alias_get_id(dev->of_node, "dp"); in dw_dp_probe()
4025 dp->id = id; in dw_dp_probe()
4026 dp->dev = dev; in dw_dp_probe()
4027 dp->video.pixel_mode = DPTX_MP_QUAD_PIXEL; in dw_dp_probe()
4029 ret = dw_dp_parse_dt(dp); in dw_dp_probe()
4033 mutex_init(&dp->irq_lock); in dw_dp_probe()
4034 INIT_WORK(&dp->hpd_work, dw_dp_hpd_work); in dw_dp_probe()
4035 init_completion(&dp->complete); in dw_dp_probe()
4041 dp->regmap = devm_regmap_init_mmio(dev, base, &dw_dp_regmap_config); in dw_dp_probe()
4042 if (IS_ERR(dp->regmap)) in dw_dp_probe()
4043 return dev_err_probe(dev, PTR_ERR(dp->regmap), in dw_dp_probe()
4046 dp->phy = devm_of_phy_get(dev, dev->of_node, NULL); in dw_dp_probe()
4047 if (IS_ERR(dp->phy)) in dw_dp_probe()
4048 return dev_err_probe(dev, PTR_ERR(dp->phy), in dw_dp_probe()
4049 "failed to get phy\n"); in dw_dp_probe()
4051 dp->apb_clk = devm_clk_get(dev, "apb"); in dw_dp_probe()
4052 if (IS_ERR(dp->apb_clk)) in dw_dp_probe()
4053 return dev_err_probe(dev, PTR_ERR(dp->apb_clk), in dw_dp_probe()
4056 dp->aux_clk = devm_clk_get(dev, "aux"); in dw_dp_probe()
4057 if (IS_ERR(dp->aux_clk)) in dw_dp_probe()
4058 return dev_err_probe(dev, PTR_ERR(dp->aux_clk), in dw_dp_probe()
4061 dp->i2s_clk = devm_clk_get(dev, "i2s"); in dw_dp_probe()
4062 if (IS_ERR(dp->i2s_clk)) in dw_dp_probe()
4063 return dev_err_probe(dev, PTR_ERR(dp->i2s_clk), in dw_dp_probe()
4066 dp->spdif_clk = devm_clk_get(dev, "spdif"); in dw_dp_probe()
4067 if (IS_ERR(dp->spdif_clk)) in dw_dp_probe()
4068 return dev_err_probe(dev, PTR_ERR(dp->spdif_clk), in dw_dp_probe()
4071 dp->hclk = devm_clk_get_optional(dev, "hclk"); in dw_dp_probe()
4072 if (IS_ERR(dp->hclk)) in dw_dp_probe()
4073 return dev_err_probe(dev, PTR_ERR(dp->hclk), in dw_dp_probe()
4076 dp->hdcp_clk = devm_clk_get(dev, "hdcp"); in dw_dp_probe()
4077 if (IS_ERR(dp->hdcp_clk)) in dw_dp_probe()
4078 return dev_err_probe(dev, PTR_ERR(dp->hdcp_clk), in dw_dp_probe()
4081 dp->rstc = devm_reset_control_get(dev, NULL); in dw_dp_probe()
4082 if (IS_ERR(dp->rstc)) in dw_dp_probe()
4083 return dev_err_probe(dev, PTR_ERR(dp->rstc), in dw_dp_probe()
4086 dp->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); in dw_dp_probe()
4087 if (IS_ERR(dp->hpd_gpio)) in dw_dp_probe()
4088 return dev_err_probe(dev, PTR_ERR(dp->hpd_gpio), in dw_dp_probe()
4090 if (dp->hpd_gpio) { in dw_dp_probe()
4091 dp->hpd_irq = gpiod_to_irq(dp->hpd_gpio); in dw_dp_probe()
4092 if (dp->hpd_irq < 0) in dw_dp_probe()
4093 return dev_err_probe(dev, dp->hpd_irq, in dw_dp_probe()
4096 irq_set_status_flags(dp->hpd_irq, IRQ_NOAUTOEN); in dw_dp_probe()
4097 ret = devm_request_threaded_irq(dev, dp->hpd_irq, NULL, in dw_dp_probe()
4101 IRQF_ONESHOT, "dw-dp-hpd", dp); in dw_dp_probe()
4108 dp->irq = platform_get_irq(pdev, 0); in dw_dp_probe()
4109 if (dp->irq < 0) in dw_dp_probe()
4110 return dp->irq; in dw_dp_probe()
4112 irq_set_status_flags(dp->irq, IRQ_NOAUTOEN); in dw_dp_probe()
4113 ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq_handler, in dw_dp_probe()
4114 IRQF_ONESHOT, dev_name(dev), dp); in dw_dp_probe()
4120 dp->extcon = devm_extcon_dev_allocate(dev, dw_dp_cable); in dw_dp_probe()
4121 if (IS_ERR(dp->extcon)) in dw_dp_probe()
4122 return dev_err_probe(dev, PTR_ERR(dp->extcon), in dw_dp_probe()
4125 ret = devm_extcon_dev_register(dev, dp->extcon); in dw_dp_probe()
4130 ret = dw_dp_register_audio_driver(dp); in dw_dp_probe()
4134 ret = devm_add_action_or_reset(dev, dw_dp_unregister_audio_driver, dp); in dw_dp_probe()
4138 dp->aux.dev = dev; in dw_dp_probe()
4139 dp->aux.name = dev_name(dev); in dw_dp_probe()
4140 dp->aux.transfer = dw_dp_aux_transfer; in dw_dp_probe()
4141 ret = drm_dp_aux_register(&dp->aux); in dw_dp_probe()
4145 ret = devm_add_action_or_reset(dev, dw_dp_aux_unregister, dp); in dw_dp_probe()
4149 dp->bridge.of_node = dev->of_node; in dw_dp_probe()
4150 dp->bridge.funcs = &dw_dp_bridge_funcs; in dw_dp_probe()
4151 dp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | in dw_dp_probe()
4153 dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; in dw_dp_probe()
4155 platform_set_drvdata(pdev, dp); in dw_dp_probe()
4157 if (device_property_read_bool(dev, "split-mode")) { in dw_dp_probe()
4158 struct dw_dp *secondary = dw_dp_find_by_id(dev->driver, !dp->id); in dw_dp_probe()
4161 return -EPROBE_DEFER; in dw_dp_probe()
4163 dp->right = secondary; in dw_dp_probe()
4164 dp->split_mode = true; in dw_dp_probe()
4165 secondary->left = dp; in dw_dp_probe()
4166 secondary->split_mode = true; in dw_dp_probe()
4169 dw_dp_hdcp_init(dp); in dw_dp_probe()
4176 struct dw_dp *dp = platform_get_drvdata(pdev); in dw_dp_remove() local
4178 component_del(dp->dev, &dw_dp_component_ops); in dw_dp_remove()
4179 cancel_work_sync(&dp->hpd_work); in dw_dp_remove()
4186 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_runtime_suspend() local
4188 clk_disable_unprepare(dp->aux_clk); in dw_dp_runtime_suspend()
4189 clk_disable_unprepare(dp->apb_clk); in dw_dp_runtime_suspend()
4190 clk_disable_unprepare(dp->hclk); in dw_dp_runtime_suspend()
4197 struct dw_dp *dp = dev_get_drvdata(dev); in dw_dp_runtime_resume() local
4199 clk_prepare_enable(dp->hclk); in dw_dp_runtime_resume()
4200 clk_prepare_enable(dp->apb_clk); in dw_dp_runtime_resume()
4201 clk_prepare_enable(dp->aux_clk); in dw_dp_runtime_resume()
4203 dw_dp_init(dp); in dw_dp_runtime_resume()
4215 { .compatible = "rockchip,rk3588-dp", },
4224 .name = "dw-dp",