Lines Matching +full:dp +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Author: Chris Zhong <zyw@rock-chips.com>
12 #include <linux/phy/phy.h>
16 #include <sound/hdmi-codec.h>
25 #include "cdn-dp-core.h"
26 #include "cdn-dp-reg.h"
55 { .compatible = "rockchip,rk3399-cdn-dp",
62 static int cdn_dp_grf_write(struct cdn_dp_device *dp, in cdn_dp_grf_write() argument
67 ret = clk_prepare_enable(dp->grf_clk); in cdn_dp_grf_write()
69 DRM_DEV_ERROR(dp->dev, "Failed to prepare_enable grf clock\n"); in cdn_dp_grf_write()
73 ret = regmap_write(dp->grf, reg, val); in cdn_dp_grf_write()
75 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); in cdn_dp_grf_write()
79 clk_disable_unprepare(dp->grf_clk); in cdn_dp_grf_write()
84 static int cdn_dp_clk_enable(struct cdn_dp_device *dp) in cdn_dp_clk_enable() argument
89 ret = clk_prepare_enable(dp->pclk); in cdn_dp_clk_enable()
91 DRM_DEV_ERROR(dp->dev, "cannot enable dp pclk %d\n", ret); in cdn_dp_clk_enable()
95 ret = clk_prepare_enable(dp->core_clk); in cdn_dp_clk_enable()
97 DRM_DEV_ERROR(dp->dev, "cannot enable core_clk %d\n", ret); in cdn_dp_clk_enable()
101 ret = pm_runtime_get_sync(dp->dev); in cdn_dp_clk_enable()
103 DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret); in cdn_dp_clk_enable()
107 reset_control_assert(dp->core_rst); in cdn_dp_clk_enable()
108 reset_control_assert(dp->dptx_rst); in cdn_dp_clk_enable()
109 reset_control_assert(dp->apb_rst); in cdn_dp_clk_enable()
110 reset_control_deassert(dp->core_rst); in cdn_dp_clk_enable()
111 reset_control_deassert(dp->dptx_rst); in cdn_dp_clk_enable()
112 reset_control_deassert(dp->apb_rst); in cdn_dp_clk_enable()
114 rate = clk_get_rate(dp->core_clk); in cdn_dp_clk_enable()
116 DRM_DEV_ERROR(dp->dev, "get clk rate failed\n"); in cdn_dp_clk_enable()
117 ret = -EINVAL; in cdn_dp_clk_enable()
121 cdn_dp_set_fw_clk(dp, rate); in cdn_dp_clk_enable()
122 cdn_dp_clock_reset(dp); in cdn_dp_clk_enable()
127 pm_runtime_put(dp->dev); in cdn_dp_clk_enable()
129 clk_disable_unprepare(dp->core_clk); in cdn_dp_clk_enable()
131 clk_disable_unprepare(dp->pclk); in cdn_dp_clk_enable()
136 static void cdn_dp_clk_disable(struct cdn_dp_device *dp) in cdn_dp_clk_disable() argument
138 pm_runtime_put_sync(dp->dev); in cdn_dp_clk_disable()
139 clk_disable_unprepare(dp->pclk); in cdn_dp_clk_disable()
140 clk_disable_unprepare(dp->core_clk); in cdn_dp_clk_disable()
145 struct extcon_dev *edev = port->extcon; in cdn_dp_get_port_lanes()
165 static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count) in cdn_dp_get_sink_count() argument
171 ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, &value, 1); in cdn_dp_get_sink_count()
179 static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp) in cdn_dp_connected_port() argument
184 for (i = 0; i < dp->ports; i++) { in cdn_dp_connected_port()
185 port = dp->port[i]; in cdn_dp_connected_port()
193 static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp) in cdn_dp_check_sink_connection() argument
199 if (dp->active_port < 0 || dp->active_port >= dp->ports) { in cdn_dp_check_sink_connection()
200 DRM_DEV_ERROR(dp->dev, "active_port is wrong!\n"); in cdn_dp_check_sink_connection()
204 port = dp->port[dp->active_port]; in cdn_dp_check_sink_connection()
213 if (!extcon_get_state(port->extcon, EXTCON_DISP_DP)) in cdn_dp_check_sink_connection()
216 if (!cdn_dp_get_sink_count(dp, &sink_count)) in cdn_dp_check_sink_connection()
222 DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n"); in cdn_dp_check_sink_connection()
229 struct cdn_dp_device *dp = connector_to_dp(connector); in cdn_dp_connector_detect() local
232 mutex_lock(&dp->lock); in cdn_dp_connector_detect()
233 if (dp->connected) in cdn_dp_connector_detect()
235 mutex_unlock(&dp->lock); in cdn_dp_connector_detect()
257 struct cdn_dp_device *dp = connector_to_dp(connector); in cdn_dp_connector_get_modes() local
261 mutex_lock(&dp->lock); in cdn_dp_connector_get_modes()
262 edid = dp->edid; in cdn_dp_connector_get_modes()
264 DRM_DEV_DEBUG_KMS(dp->dev, "got edid: width[%d] x height[%d]\n", in cdn_dp_connector_get_modes()
265 edid->width_cm, edid->height_cm); in cdn_dp_connector_get_modes()
267 dp->sink_has_audio = drm_detect_monitor_audio(edid); in cdn_dp_connector_get_modes()
273 mutex_unlock(&dp->lock); in cdn_dp_connector_get_modes()
281 struct cdn_dp_device *dp = connector_to_dp(connector); in cdn_dp_connector_mode_valid() local
282 struct drm_display_info *display_info = &dp->connector.display_info; in cdn_dp_connector_mode_valid()
286 /* If DP is disconnected, every mode is invalid */ in cdn_dp_connector_mode_valid()
287 if (!dp->connected) in cdn_dp_connector_mode_valid()
290 switch (display_info->bpc) { in cdn_dp_connector_mode_valid()
302 requested = mode->clock * bpc * 3 / 1000; in cdn_dp_connector_mode_valid()
304 source_max = dp->lanes; in cdn_dp_connector_mode_valid()
305 sink_max = drm_dp_max_lane_count(dp->dpcd); in cdn_dp_connector_mode_valid()
309 sink_max = drm_dp_max_link_rate(dp->dpcd); in cdn_dp_connector_mode_valid()
318 DRM_DEV_DEBUG_KMS(dp->dev, in cdn_dp_connector_mode_valid()
320 requested, actual, mode->clock); in cdn_dp_connector_mode_valid()
332 static int cdn_dp_firmware_init(struct cdn_dp_device *dp) in cdn_dp_firmware_init() argument
336 const struct firmware *fw = dp->fw; in cdn_dp_firmware_init()
339 hdr = (struct cdn_firmware_header *)fw->data; in cdn_dp_firmware_init()
340 if (fw->size != le32_to_cpu(hdr->size_bytes)) { in cdn_dp_firmware_init()
341 DRM_DEV_ERROR(dp->dev, "firmware is invalid\n"); in cdn_dp_firmware_init()
342 return -EINVAL; in cdn_dp_firmware_init()
345 iram_data = (const u32 *)(fw->data + hdr->header_size); in cdn_dp_firmware_init()
346 dram_data = (const u32 *)(fw->data + hdr->header_size + hdr->iram_size); in cdn_dp_firmware_init()
348 ret = cdn_dp_load_firmware(dp, iram_data, hdr->iram_size, in cdn_dp_firmware_init()
349 dram_data, hdr->dram_size); in cdn_dp_firmware_init()
353 ret = cdn_dp_set_firmware_active(dp, true); in cdn_dp_firmware_init()
355 DRM_DEV_ERROR(dp->dev, "active ucpu failed: %d\n", ret); in cdn_dp_firmware_init()
359 return cdn_dp_event_config(dp); in cdn_dp_firmware_init()
362 static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp) in cdn_dp_get_sink_capability() argument
366 if (!cdn_dp_check_sink_connection(dp)) in cdn_dp_get_sink_capability()
367 return -ENODEV; in cdn_dp_get_sink_capability()
369 ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd, in cdn_dp_get_sink_capability()
372 DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret); in cdn_dp_get_sink_capability()
376 kfree(dp->edid); in cdn_dp_get_sink_capability()
377 dp->edid = drm_do_get_edid(&dp->connector, in cdn_dp_get_sink_capability()
378 cdn_dp_get_edid_block, dp); in cdn_dp_get_sink_capability()
382 static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port) in cdn_dp_enable_phy() argument
387 if (!port->phy_enabled) { in cdn_dp_enable_phy()
388 ret = phy_power_on(port->phy); in cdn_dp_enable_phy()
390 DRM_DEV_ERROR(dp->dev, "phy power on failed: %d\n", in cdn_dp_enable_phy()
394 port->phy_enabled = true; in cdn_dp_enable_phy()
397 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26, in cdn_dp_enable_phy()
400 DRM_DEV_ERROR(dp->dev, "Failed to write HPD_SEL %d\n", ret); in cdn_dp_enable_phy()
404 ret = cdn_dp_get_hpd_status(dp); in cdn_dp_enable_phy()
407 DRM_DEV_ERROR(dp->dev, "hpd does not exist\n"); in cdn_dp_enable_phy()
411 ret = extcon_get_property(port->extcon, EXTCON_DISP_DP, in cdn_dp_enable_phy()
414 DRM_DEV_ERROR(dp->dev, "get property failed\n"); in cdn_dp_enable_phy()
418 port->lanes = cdn_dp_get_port_lanes(port); in cdn_dp_enable_phy()
419 ret = cdn_dp_set_host_cap(dp, port->lanes, property.intval); in cdn_dp_enable_phy()
421 DRM_DEV_ERROR(dp->dev, "set host capabilities failed: %d\n", in cdn_dp_enable_phy()
426 dp->active_port = port->id; in cdn_dp_enable_phy()
430 if (phy_power_off(port->phy)) in cdn_dp_enable_phy()
431 DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret); in cdn_dp_enable_phy()
433 port->phy_enabled = false; in cdn_dp_enable_phy()
436 cdn_dp_grf_write(dp, GRF_SOC_CON26, in cdn_dp_enable_phy()
441 static int cdn_dp_disable_phy(struct cdn_dp_device *dp, in cdn_dp_disable_phy() argument
446 if (port->phy_enabled) { in cdn_dp_disable_phy()
447 ret = phy_power_off(port->phy); in cdn_dp_disable_phy()
449 DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret); in cdn_dp_disable_phy()
454 port->phy_enabled = false; in cdn_dp_disable_phy()
455 port->lanes = 0; in cdn_dp_disable_phy()
456 dp->active_port = -1; in cdn_dp_disable_phy()
460 static int cdn_dp_disable(struct cdn_dp_device *dp) in cdn_dp_disable() argument
464 if (!dp->active) in cdn_dp_disable()
467 for (i = 0; i < dp->ports; i++) in cdn_dp_disable()
468 cdn_dp_disable_phy(dp, dp->port[i]); in cdn_dp_disable()
470 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26, in cdn_dp_disable()
473 DRM_DEV_ERROR(dp->dev, "Failed to clear hpd sel %d\n", in cdn_dp_disable()
478 cdn_dp_set_firmware_active(dp, false); in cdn_dp_disable()
479 cdn_dp_clk_disable(dp); in cdn_dp_disable()
480 dp->active = false; in cdn_dp_disable()
481 dp->max_lanes = 0; in cdn_dp_disable()
482 dp->max_rate = 0; in cdn_dp_disable()
483 if (!dp->connected) { in cdn_dp_disable()
484 kfree(dp->edid); in cdn_dp_disable()
485 dp->edid = NULL; in cdn_dp_disable()
491 static int cdn_dp_enable(struct cdn_dp_device *dp) in cdn_dp_enable() argument
496 port = cdn_dp_connected_port(dp); in cdn_dp_enable()
498 DRM_DEV_ERROR(dp->dev, in cdn_dp_enable()
500 return -ENODEV; in cdn_dp_enable()
503 if (dp->active) in cdn_dp_enable()
506 ret = cdn_dp_clk_enable(dp); in cdn_dp_enable()
510 ret = cdn_dp_firmware_init(dp); in cdn_dp_enable()
512 DRM_DEV_ERROR(dp->dev, "firmware init failed: %d", ret); in cdn_dp_enable()
517 for (i = port->id; i < dp->ports; i++) { in cdn_dp_enable()
518 port = dp->port[i]; in cdn_dp_enable()
521 ret = cdn_dp_enable_phy(dp, port); in cdn_dp_enable()
525 ret = cdn_dp_get_sink_capability(dp); in cdn_dp_enable()
527 cdn_dp_disable_phy(dp, port); in cdn_dp_enable()
529 dp->active = true; in cdn_dp_enable()
530 dp->lanes = port->lanes; in cdn_dp_enable()
537 cdn_dp_clk_disable(dp); in cdn_dp_enable()
545 struct cdn_dp_device *dp = encoder_to_dp(encoder); in cdn_dp_encoder_mode_set() local
546 struct drm_display_info *display_info = &dp->connector.display_info; in cdn_dp_encoder_mode_set()
547 struct video_info *video = &dp->video_info; in cdn_dp_encoder_mode_set()
549 switch (display_info->bpc) { in cdn_dp_encoder_mode_set()
551 video->color_depth = 10; in cdn_dp_encoder_mode_set()
554 video->color_depth = 6; in cdn_dp_encoder_mode_set()
557 video->color_depth = 8; in cdn_dp_encoder_mode_set()
561 video->color_fmt = PXL_RGB; in cdn_dp_encoder_mode_set()
562 video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); in cdn_dp_encoder_mode_set()
563 video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); in cdn_dp_encoder_mode_set()
565 memcpy(&dp->mode, adjusted, sizeof(*mode)); in cdn_dp_encoder_mode_set()
568 static bool cdn_dp_check_link_status(struct cdn_dp_device *dp) in cdn_dp_check_link_status() argument
571 struct cdn_dp_port *port = cdn_dp_connected_port(dp); in cdn_dp_check_link_status()
572 u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd); in cdn_dp_check_link_status()
574 if (!port || !dp->max_rate || !dp->max_lanes) in cdn_dp_check_link_status()
577 if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status, in cdn_dp_check_link_status()
584 return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes)); in cdn_dp_check_link_status()
589 struct cdn_dp_device *dp = encoder_to_dp(encoder); in cdn_dp_encoder_enable() local
592 ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); in cdn_dp_encoder_enable()
594 DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret); in cdn_dp_encoder_enable()
598 DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n", in cdn_dp_encoder_enable()
605 ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val); in cdn_dp_encoder_enable()
609 mutex_lock(&dp->lock); in cdn_dp_encoder_enable()
611 ret = cdn_dp_enable(dp); in cdn_dp_encoder_enable()
613 DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n", in cdn_dp_encoder_enable()
617 if (!cdn_dp_check_link_status(dp)) { in cdn_dp_encoder_enable()
618 ret = cdn_dp_train_link(dp); in cdn_dp_encoder_enable()
620 DRM_DEV_ERROR(dp->dev, "Failed link train %d\n", ret); in cdn_dp_encoder_enable()
625 ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE); in cdn_dp_encoder_enable()
627 DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret); in cdn_dp_encoder_enable()
631 ret = cdn_dp_config_video(dp); in cdn_dp_encoder_enable()
633 DRM_DEV_ERROR(dp->dev, "Failed to config video %d\n", ret); in cdn_dp_encoder_enable()
637 ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID); in cdn_dp_encoder_enable()
639 DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret); in cdn_dp_encoder_enable()
643 mutex_unlock(&dp->lock); in cdn_dp_encoder_enable()
648 struct cdn_dp_device *dp = encoder_to_dp(encoder); in cdn_dp_encoder_disable() local
651 mutex_lock(&dp->lock); in cdn_dp_encoder_disable()
652 if (dp->active) { in cdn_dp_encoder_disable()
653 ret = cdn_dp_disable(dp); in cdn_dp_encoder_disable()
655 DRM_DEV_ERROR(dp->dev, "Failed to disable encoder %d\n", in cdn_dp_encoder_disable()
659 mutex_unlock(&dp->lock); in cdn_dp_encoder_disable()
662 * In the following 2 cases, we need to run the event_work to re-enable in cdn_dp_encoder_disable()
663 * the DP: in cdn_dp_encoder_disable()
665 * device from a port, the DP will be disabled here, at this case, in cdn_dp_encoder_disable()
666 * run the event_work to re-open DP for the other port. in cdn_dp_encoder_disable()
667 * 2. If re-training or re-config failed, the DP will be disabled here. in cdn_dp_encoder_disable()
668 * run the event_work to re-connect it. in cdn_dp_encoder_disable()
670 if (!dp->connected && cdn_dp_connected_port(dp)) in cdn_dp_encoder_disable()
671 schedule_work(&dp->event_work); in cdn_dp_encoder_disable()
680 s->output_mode = ROCKCHIP_OUT_MODE_AAAA; in cdn_dp_encoder_atomic_check()
681 s->output_type = DRM_MODE_CONNECTOR_DisplayPort; in cdn_dp_encoder_atomic_check()
693 static int cdn_dp_parse_dt(struct cdn_dp_device *dp) in cdn_dp_parse_dt() argument
695 struct device *dev = dp->dev; in cdn_dp_parse_dt()
696 struct device_node *np = dev->of_node; in cdn_dp_parse_dt()
700 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); in cdn_dp_parse_dt()
701 if (IS_ERR(dp->grf)) { in cdn_dp_parse_dt()
702 DRM_DEV_ERROR(dev, "cdn-dp needs rockchip,grf property\n"); in cdn_dp_parse_dt()
703 return PTR_ERR(dp->grf); in cdn_dp_parse_dt()
707 dp->regs = devm_ioremap_resource(dev, res); in cdn_dp_parse_dt()
708 if (IS_ERR(dp->regs)) { in cdn_dp_parse_dt()
710 return PTR_ERR(dp->regs); in cdn_dp_parse_dt()
713 dp->core_clk = devm_clk_get(dev, "core-clk"); in cdn_dp_parse_dt()
714 if (IS_ERR(dp->core_clk)) { in cdn_dp_parse_dt()
716 return PTR_ERR(dp->core_clk); in cdn_dp_parse_dt()
719 dp->pclk = devm_clk_get(dev, "pclk"); in cdn_dp_parse_dt()
720 if (IS_ERR(dp->pclk)) { in cdn_dp_parse_dt()
722 return PTR_ERR(dp->pclk); in cdn_dp_parse_dt()
725 dp->spdif_clk = devm_clk_get(dev, "spdif"); in cdn_dp_parse_dt()
726 if (IS_ERR(dp->spdif_clk)) { in cdn_dp_parse_dt()
728 return PTR_ERR(dp->spdif_clk); in cdn_dp_parse_dt()
731 dp->grf_clk = devm_clk_get(dev, "grf"); in cdn_dp_parse_dt()
732 if (IS_ERR(dp->grf_clk)) { in cdn_dp_parse_dt()
734 return PTR_ERR(dp->grf_clk); in cdn_dp_parse_dt()
737 dp->spdif_rst = devm_reset_control_get(dev, "spdif"); in cdn_dp_parse_dt()
738 if (IS_ERR(dp->spdif_rst)) { in cdn_dp_parse_dt()
740 return PTR_ERR(dp->spdif_rst); in cdn_dp_parse_dt()
743 dp->dptx_rst = devm_reset_control_get(dev, "dptx"); in cdn_dp_parse_dt()
744 if (IS_ERR(dp->dptx_rst)) { in cdn_dp_parse_dt()
746 return PTR_ERR(dp->dptx_rst); in cdn_dp_parse_dt()
749 dp->core_rst = devm_reset_control_get(dev, "core"); in cdn_dp_parse_dt()
750 if (IS_ERR(dp->core_rst)) { in cdn_dp_parse_dt()
752 return PTR_ERR(dp->core_rst); in cdn_dp_parse_dt()
755 dp->apb_rst = devm_reset_control_get(dev, "apb"); in cdn_dp_parse_dt()
756 if (IS_ERR(dp->apb_rst)) { in cdn_dp_parse_dt()
758 return PTR_ERR(dp->apb_rst); in cdn_dp_parse_dt()
768 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_audio_hw_params() local
770 .sample_width = params->sample_width, in cdn_dp_audio_hw_params()
771 .sample_rate = params->sample_rate, in cdn_dp_audio_hw_params()
772 .channels = params->channels, in cdn_dp_audio_hw_params()
776 mutex_lock(&dp->lock); in cdn_dp_audio_hw_params()
777 if (!dp->active) { in cdn_dp_audio_hw_params()
778 ret = -ENODEV; in cdn_dp_audio_hw_params()
782 switch (daifmt->fmt) { in cdn_dp_audio_hw_params()
790 DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt); in cdn_dp_audio_hw_params()
791 ret = -EINVAL; in cdn_dp_audio_hw_params()
795 ret = cdn_dp_audio_config(dp, &audio); in cdn_dp_audio_hw_params()
797 dp->audio_info = audio; in cdn_dp_audio_hw_params()
800 mutex_unlock(&dp->lock); in cdn_dp_audio_hw_params()
806 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_audio_shutdown() local
809 mutex_lock(&dp->lock); in cdn_dp_audio_shutdown()
810 if (!dp->active) in cdn_dp_audio_shutdown()
813 ret = cdn_dp_audio_stop(dp, &dp->audio_info); in cdn_dp_audio_shutdown()
815 dp->audio_info.format = AFMT_UNUSED; in cdn_dp_audio_shutdown()
817 mutex_unlock(&dp->lock); in cdn_dp_audio_shutdown()
823 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_audio_mute_stream() local
826 mutex_lock(&dp->lock); in cdn_dp_audio_mute_stream()
827 if (!dp->active) { in cdn_dp_audio_mute_stream()
828 ret = -ENODEV; in cdn_dp_audio_mute_stream()
832 ret = cdn_dp_audio_mute(dp, enable); in cdn_dp_audio_mute_stream()
835 mutex_unlock(&dp->lock); in cdn_dp_audio_mute_stream()
842 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_audio_get_eld() local
844 memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len)); in cdn_dp_audio_get_eld()
857 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp, in cdn_dp_audio_codec_init() argument
867 dp->audio_pdev = platform_device_register_data( in cdn_dp_audio_codec_init()
871 return PTR_ERR_OR_ZERO(dp->audio_pdev); in cdn_dp_audio_codec_init()
874 static int cdn_dp_request_firmware(struct cdn_dp_device *dp) in cdn_dp_request_firmware() argument
880 WARN_ON(!mutex_is_locked(&dp->lock)); in cdn_dp_request_firmware()
882 if (dp->fw_loaded) in cdn_dp_request_firmware()
886 mutex_unlock(&dp->lock); in cdn_dp_request_firmware()
889 ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev); in cdn_dp_request_firmware()
890 if (ret == -ENOENT) { in cdn_dp_request_firmware()
895 DRM_DEV_ERROR(dp->dev, in cdn_dp_request_firmware()
900 dp->fw_loaded = true; in cdn_dp_request_firmware()
905 DRM_DEV_ERROR(dp->dev, "Timed out trying to load firmware\n"); in cdn_dp_request_firmware()
906 ret = -ETIMEDOUT; in cdn_dp_request_firmware()
908 mutex_lock(&dp->lock); in cdn_dp_request_firmware()
914 struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, in cdn_dp_pd_event_work() local
916 struct drm_connector *connector = &dp->connector; in cdn_dp_pd_event_work()
921 mutex_lock(&dp->lock); in cdn_dp_pd_event_work()
923 if (dp->suspended) in cdn_dp_pd_event_work()
926 ret = cdn_dp_request_firmware(dp); in cdn_dp_pd_event_work()
930 dp->connected = true; in cdn_dp_pd_event_work()
933 if (!cdn_dp_connected_port(dp)) { in cdn_dp_pd_event_work()
934 DRM_DEV_INFO(dp->dev, "Not connected. Disabling cdn\n"); in cdn_dp_pd_event_work()
935 dp->connected = false; in cdn_dp_pd_event_work()
938 } else if (!dp->active) { in cdn_dp_pd_event_work()
939 DRM_DEV_INFO(dp->dev, "Connected, not enabled. Enabling cdn\n"); in cdn_dp_pd_event_work()
940 ret = cdn_dp_enable(dp); in cdn_dp_pd_event_work()
942 DRM_DEV_ERROR(dp->dev, "Enable dp failed %d\n", ret); in cdn_dp_pd_event_work()
943 dp->connected = false; in cdn_dp_pd_event_work()
947 } else if (!cdn_dp_check_sink_connection(dp)) { in cdn_dp_pd_event_work()
948 DRM_DEV_INFO(dp->dev, "Connected without sink. Assert hpd\n"); in cdn_dp_pd_event_work()
949 dp->connected = false; in cdn_dp_pd_event_work()
951 /* Enabled and connected with a sink, re-train if requested */ in cdn_dp_pd_event_work()
952 } else if (!cdn_dp_check_link_status(dp)) { in cdn_dp_pd_event_work()
953 unsigned int rate = dp->max_rate; in cdn_dp_pd_event_work()
954 unsigned int lanes = dp->max_lanes; in cdn_dp_pd_event_work()
955 struct drm_display_mode *mode = &dp->mode; in cdn_dp_pd_event_work()
957 DRM_DEV_INFO(dp->dev, "Connected with sink. Re-train link\n"); in cdn_dp_pd_event_work()
958 ret = cdn_dp_train_link(dp); in cdn_dp_pd_event_work()
960 dp->connected = false; in cdn_dp_pd_event_work()
961 DRM_DEV_ERROR(dp->dev, "Train link failed %d\n", ret); in cdn_dp_pd_event_work()
966 if (mode->clock && in cdn_dp_pd_event_work()
967 (rate != dp->max_rate || lanes != dp->max_lanes)) { in cdn_dp_pd_event_work()
968 ret = cdn_dp_config_video(dp); in cdn_dp_pd_event_work()
970 dp->connected = false; in cdn_dp_pd_event_work()
971 DRM_DEV_ERROR(dp->dev, in cdn_dp_pd_event_work()
979 mutex_unlock(&dp->lock); in cdn_dp_pd_event_work()
981 old_status = connector->status; in cdn_dp_pd_event_work()
982 connector->status = connector->funcs->detect(connector, false); in cdn_dp_pd_event_work()
983 if (old_status != connector->status) in cdn_dp_pd_event_work()
984 drm_kms_helper_hotplug_event(dp->drm_dev); in cdn_dp_pd_event_work()
992 struct cdn_dp_device *dp = port->dp; in cdn_dp_pd_event() local
997 * to turn on the block/phy, so use a worker instead. in cdn_dp_pd_event()
999 schedule_work(&dp->event_work); in cdn_dp_pd_event()
1006 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_bind() local
1013 ret = cdn_dp_parse_dt(dp); in cdn_dp_bind()
1017 dp->drm_dev = drm_dev; in cdn_dp_bind()
1018 dp->connected = false; in cdn_dp_bind()
1019 dp->active = false; in cdn_dp_bind()
1020 dp->active_port = -1; in cdn_dp_bind()
1021 dp->fw_loaded = false; in cdn_dp_bind()
1023 INIT_WORK(&dp->event_work, cdn_dp_pd_event_work); in cdn_dp_bind()
1025 encoder = &dp->encoder; in cdn_dp_bind()
1027 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, in cdn_dp_bind()
1028 dev->of_node); in cdn_dp_bind()
1029 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); in cdn_dp_bind()
1040 connector = &dp->connector; in cdn_dp_bind()
1041 connector->polled = DRM_CONNECTOR_POLL_HPD; in cdn_dp_bind()
1042 connector->dpms = DRM_MODE_DPMS_OFF; in cdn_dp_bind()
1060 for (i = 0; i < dp->ports; i++) { in cdn_dp_bind()
1061 port = dp->port[i]; in cdn_dp_bind()
1063 port->event_nb.notifier_call = cdn_dp_pd_event; in cdn_dp_bind()
1064 ret = devm_extcon_register_notifier(dp->dev, port->extcon, in cdn_dp_bind()
1066 &port->event_nb); in cdn_dp_bind()
1076 schedule_work(&dp->event_work); in cdn_dp_bind()
1089 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_unbind() local
1090 struct drm_encoder *encoder = &dp->encoder; in cdn_dp_unbind()
1091 struct drm_connector *connector = &dp->connector; in cdn_dp_unbind()
1093 cancel_work_sync(&dp->event_work); in cdn_dp_unbind()
1095 encoder->funcs->destroy(encoder); in cdn_dp_unbind()
1096 connector->funcs->destroy(connector); in cdn_dp_unbind()
1099 if (dp->fw_loaded) in cdn_dp_unbind()
1100 release_firmware(dp->fw); in cdn_dp_unbind()
1101 kfree(dp->edid); in cdn_dp_unbind()
1102 dp->edid = NULL; in cdn_dp_unbind()
1112 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_suspend() local
1115 mutex_lock(&dp->lock); in cdn_dp_suspend()
1116 if (dp->active) in cdn_dp_suspend()
1117 ret = cdn_dp_disable(dp); in cdn_dp_suspend()
1118 dp->suspended = true; in cdn_dp_suspend()
1119 mutex_unlock(&dp->lock); in cdn_dp_suspend()
1126 struct cdn_dp_device *dp = dev_get_drvdata(dev); in cdn_dp_resume() local
1128 mutex_lock(&dp->lock); in cdn_dp_resume()
1129 dp->suspended = false; in cdn_dp_resume()
1130 if (dp->fw_loaded) in cdn_dp_resume()
1131 schedule_work(&dp->event_work); in cdn_dp_resume()
1132 mutex_unlock(&dp->lock); in cdn_dp_resume()
1139 struct device *dev = &pdev->dev; in cdn_dp_probe()
1143 struct cdn_dp_device *dp; in cdn_dp_probe() local
1145 struct phy *phy; in cdn_dp_probe() local
1148 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); in cdn_dp_probe()
1149 if (!dp) in cdn_dp_probe()
1150 return -ENOMEM; in cdn_dp_probe()
1151 dp->dev = dev; in cdn_dp_probe()
1153 match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node); in cdn_dp_probe()
1154 dp_data = (struct cdn_dp_data *)match->data; in cdn_dp_probe()
1156 for (i = 0; i < dp_data->max_phy; i++) { in cdn_dp_probe()
1158 phy = devm_of_phy_get_by_index(dev, dev->of_node, i); in cdn_dp_probe()
1160 if (PTR_ERR(extcon) == -EPROBE_DEFER || in cdn_dp_probe()
1161 PTR_ERR(phy) == -EPROBE_DEFER) in cdn_dp_probe()
1162 return -EPROBE_DEFER; in cdn_dp_probe()
1164 if (IS_ERR(extcon) || IS_ERR(phy)) in cdn_dp_probe()
1169 return -ENOMEM; in cdn_dp_probe()
1171 port->extcon = extcon; in cdn_dp_probe()
1172 port->phy = phy; in cdn_dp_probe()
1173 port->dp = dp; in cdn_dp_probe()
1174 port->id = i; in cdn_dp_probe()
1175 dp->port[dp->ports++] = port; in cdn_dp_probe()
1178 if (!dp->ports) { in cdn_dp_probe()
1179 DRM_DEV_ERROR(dev, "missing extcon or phy\n"); in cdn_dp_probe()
1180 return -EINVAL; in cdn_dp_probe()
1183 mutex_init(&dp->lock); in cdn_dp_probe()
1184 dev_set_drvdata(dev, dp); in cdn_dp_probe()
1186 cdn_dp_audio_codec_init(dp, dev); in cdn_dp_probe()
1193 struct cdn_dp_device *dp = platform_get_drvdata(pdev); in cdn_dp_remove() local
1195 platform_device_unregister(dp->audio_pdev); in cdn_dp_remove()
1196 cdn_dp_suspend(dp->dev); in cdn_dp_remove()
1197 component_del(&pdev->dev, &cdn_dp_component_ops); in cdn_dp_remove()
1204 struct cdn_dp_device *dp = platform_get_drvdata(pdev); in cdn_dp_shutdown() local
1206 cdn_dp_suspend(dp->dev); in cdn_dp_shutdown()
1219 .name = "cdn-dp",