Lines Matching +full:dp +full:- +full:connector
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017 - 2020 Xilinx, Inc.
8 * - Hyun Woo Kwon <hyun.kwon@xilinx.com>
9 * - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
25 #include <linux/media-bus-format.h>
40 MODULE_PARM_DESC(aux_timeout_ms, "DP aux timeout value in msec (default: 50)");
47 MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)");
242 * struct zynqmp_dp_link_config - Common link config between source and sink
252 * struct zynqmp_dp_mode - Configured mode of DisplayPort
266 * struct zynqmp_dp_config - Configuration of DisplayPort from DTS
267 * @misc0: misc0 configuration (per DP v1.2 spec)
268 * @misc1: misc1 configuration (per DP v1.2 spec)
278 * struct zynqmp_dp - Xilinx DisplayPort core
284 * @bridge: DRM bridge for the DP encoder
288 * @phy: PHY handles for DP lanes
293 * @dpcd: DP configuration data from currently connected sink device
327 static void zynqmp_dp_write(struct zynqmp_dp *dp, int offset, u32 val) in zynqmp_dp_write() argument
329 writel(val, dp->iomem + offset); in zynqmp_dp_write()
332 static u32 zynqmp_dp_read(struct zynqmp_dp *dp, int offset) in zynqmp_dp_read() argument
334 return readl(dp->iomem + offset); in zynqmp_dp_read()
337 static void zynqmp_dp_clr(struct zynqmp_dp *dp, int offset, u32 clr) in zynqmp_dp_clr() argument
339 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) & ~clr); in zynqmp_dp_clr()
342 static void zynqmp_dp_set(struct zynqmp_dp *dp, int offset, u32 set) in zynqmp_dp_set() argument
344 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) | set); in zynqmp_dp_set()
347 /* -----------------------------------------------------------------------------
353 static int zynqmp_dp_reset(struct zynqmp_dp *dp, bool assert) in zynqmp_dp_reset() argument
358 reset_control_assert(dp->reset); in zynqmp_dp_reset()
360 reset_control_deassert(dp->reset); in zynqmp_dp_reset()
365 bool status = !!reset_control_status(dp->reset); in zynqmp_dp_reset()
373 dev_err(dp->dev, "reset %s timeout\n", assert ? "assert" : "deassert"); in zynqmp_dp_reset()
374 return -ETIMEDOUT; in zynqmp_dp_reset()
378 * zynqmp_dp_phy_init - Initialize the phy
379 * @dp: DisplayPort IP core structure
386 static int zynqmp_dp_phy_init(struct zynqmp_dp *dp) in zynqmp_dp_phy_init() argument
391 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_init()
392 ret = phy_init(dp->phy[i]); in zynqmp_dp_phy_init()
394 dev_err(dp->dev, "failed to init phy lane %d\n", i); in zynqmp_dp_phy_init()
399 zynqmp_dp_clr(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_phy_init()
405 for (i = dp->num_lanes - 1; i >= 0; i--) { in zynqmp_dp_phy_init()
406 ret = phy_power_on(dp->phy[i]); in zynqmp_dp_phy_init()
408 dev_err(dp->dev, "failed to power on phy lane %d\n", i); in zynqmp_dp_phy_init()
417 * zynqmp_dp_phy_exit - Exit the phy
418 * @dp: DisplayPort IP core structure
422 static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp) in zynqmp_dp_phy_exit() argument
427 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
428 ret = phy_power_off(dp->phy[i]); in zynqmp_dp_phy_exit()
430 dev_err(dp->dev, "failed to power off phy(%d) %d\n", i, in zynqmp_dp_phy_exit()
434 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
435 ret = phy_exit(dp->phy[i]); in zynqmp_dp_phy_exit()
437 dev_err(dp->dev, "failed to exit phy(%d) %d\n", i, ret); in zynqmp_dp_phy_exit()
442 * zynqmp_dp_phy_probe - Probe the PHYs
443 * @dp: DisplayPort IP core structure
447 * found. The caller can check dp->num_lanes to check how many PHYs were found.
450 * * 0 - Success
451 * * -ENXIO - No PHY found
452 * * -EPROBE_DEFER - Probe deferral requested
453 * * Other negative value - PHY retrieval failure
455 static int zynqmp_dp_phy_probe(struct zynqmp_dp *dp) in zynqmp_dp_phy_probe() argument
463 snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i); in zynqmp_dp_phy_probe()
464 phy = devm_phy_get(dp->dev, phy_name); in zynqmp_dp_phy_probe()
468 case -ENODEV: in zynqmp_dp_phy_probe()
469 if (dp->num_lanes) in zynqmp_dp_phy_probe()
472 dev_err(dp->dev, "no PHY found\n"); in zynqmp_dp_phy_probe()
473 return -ENXIO; in zynqmp_dp_phy_probe()
475 case -EPROBE_DEFER: in zynqmp_dp_phy_probe()
476 return -EPROBE_DEFER; in zynqmp_dp_phy_probe()
479 dev_err(dp->dev, "failed to get PHY lane %u\n", in zynqmp_dp_phy_probe()
485 dp->phy[i] = phy; in zynqmp_dp_phy_probe()
486 dp->num_lanes++; in zynqmp_dp_phy_probe()
493 * zynqmp_dp_phy_ready - Check if PHY is ready
494 * @dp: DisplayPort IP core structure
499 * Return: 0 if PHY is ready, or -ENODEV if PHY is not ready.
501 static int zynqmp_dp_phy_ready(struct zynqmp_dp *dp) in zynqmp_dp_phy_ready() argument
505 ready = (1 << dp->num_lanes) - 1; in zynqmp_dp_phy_ready()
509 reg = zynqmp_dp_read(dp, ZYNQMP_DP_PHY_STATUS); in zynqmp_dp_phy_ready()
514 dev_err(dp->dev, "PHY isn't ready\n"); in zynqmp_dp_phy_ready()
515 return -ENODEV; in zynqmp_dp_phy_ready()
524 /* -----------------------------------------------------------------------------
529 * zynqmp_dp_max_rate - Calculate and return available max pixel clock
530 * @link_rate: link rate (Kilo-bytes / sec)
542 * zynqmp_dp_mode_configure - Configure the link values
543 * @dp: DisplayPort IP core structure
552 * Return: Current link rate code, or -EINVAL.
554 static int zynqmp_dp_mode_configure(struct zynqmp_dp *dp, int pclock, in zynqmp_dp_mode_configure() argument
557 int max_rate = dp->link_config.max_rate; in zynqmp_dp_mode_configure()
559 u8 max_lanes = dp->link_config.max_lanes; in zynqmp_dp_mode_configure()
561 u8 bpp = dp->config.bpp; in zynqmp_dp_mode_configure()
573 dev_err(dp->dev, "can't downshift. already lowest link rate\n"); in zynqmp_dp_mode_configure()
574 return -EINVAL; in zynqmp_dp_mode_configure()
588 dp->mode.bw_code = bw_code; in zynqmp_dp_mode_configure()
589 dp->mode.lane_cnt = lane_cnt; in zynqmp_dp_mode_configure()
590 dp->mode.pclock = pclock; in zynqmp_dp_mode_configure()
591 return dp->mode.bw_code; in zynqmp_dp_mode_configure()
595 dev_err(dp->dev, "failed to configure link values\n"); in zynqmp_dp_mode_configure()
597 return -EINVAL; in zynqmp_dp_mode_configure()
601 * zynqmp_dp_adjust_train - Adjust train values
602 * @dp: DisplayPort IP core structure
605 static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp, in zynqmp_dp_adjust_train() argument
608 u8 *train_set = dp->train_set; in zynqmp_dp_adjust_train()
611 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_adjust_train()
627 * zynqmp_dp_update_vs_emph - Update the training values
628 * @dp: DisplayPort IP core structure
636 static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp) in zynqmp_dp_update_vs_emph() argument
641 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->train_set, in zynqmp_dp_update_vs_emph()
642 dp->mode.lane_cnt); in zynqmp_dp_update_vs_emph()
646 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_update_vs_emph()
649 u8 train = dp->train_set[i]; in zynqmp_dp_update_vs_emph()
651 opts.dp.voltage[0] = (train & DP_TRAIN_VOLTAGE_SWING_MASK) in zynqmp_dp_update_vs_emph()
653 opts.dp.pre[0] = (train & DP_TRAIN_PRE_EMPHASIS_MASK) in zynqmp_dp_update_vs_emph()
656 phy_configure(dp->phy[i], &opts); in zynqmp_dp_update_vs_emph()
658 zynqmp_dp_write(dp, reg, 0x2); in zynqmp_dp_update_vs_emph()
665 * zynqmp_dp_link_train_cr - Train clock recovery
666 * @dp: DisplayPort IP core structure
671 static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp) in zynqmp_dp_link_train_cr() argument
674 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_cr()
680 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
682 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
693 ret = zynqmp_dp_update_vs_emph(dp); in zynqmp_dp_link_train_cr()
697 drm_dp_link_train_clock_recovery_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_cr()
698 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_cr()
707 if (!(dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED)) in zynqmp_dp_link_train_cr()
712 if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == vs) in zynqmp_dp_link_train_cr()
720 vs = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; in zynqmp_dp_link_train_cr()
721 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_cr()
725 return -EIO; in zynqmp_dp_link_train_cr()
731 * zynqmp_dp_link_train_ce - Train channel equalization
732 * @dp: DisplayPort IP core structure
737 static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp) in zynqmp_dp_link_train_ce() argument
740 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_ce()
745 if (dp->dpcd[DP_DPCD_REV] >= DP_V1_2 && in zynqmp_dp_link_train_ce()
746 dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) in zynqmp_dp_link_train_ce()
751 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, pat); in zynqmp_dp_link_train_ce()
752 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_ce()
758 ret = zynqmp_dp_update_vs_emph(dp); in zynqmp_dp_link_train_ce()
762 drm_dp_link_train_channel_eq_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_ce()
763 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_ce()
771 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_ce()
775 return -EIO; in zynqmp_dp_link_train_ce()
781 * zynqmp_dp_train - Train the link
782 * @dp: DisplayPort IP core structure
786 static int zynqmp_dp_train(struct zynqmp_dp *dp) in zynqmp_dp_train() argument
789 u8 bw_code = dp->mode.bw_code; in zynqmp_dp_train()
790 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_train()
795 zynqmp_dp_write(dp, ZYNQMP_DP_LANE_COUNT_SET, lane_cnt); in zynqmp_dp_train()
796 enhanced = drm_dp_enhanced_frame_cap(dp->dpcd); in zynqmp_dp_train()
798 zynqmp_dp_write(dp, ZYNQMP_DP_ENHANCED_FRAME_EN, 1); in zynqmp_dp_train()
802 if (dp->dpcd[3] & 0x1) { in zynqmp_dp_train()
803 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 1); in zynqmp_dp_train()
804 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, in zynqmp_dp_train()
807 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 0); in zynqmp_dp_train()
808 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, 0); in zynqmp_dp_train()
811 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, aux_lane_cnt); in zynqmp_dp_train()
813 dev_err(dp->dev, "failed to set lane count\n"); in zynqmp_dp_train()
817 ret = drm_dp_dpcd_writeb(&dp->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, in zynqmp_dp_train()
820 dev_err(dp->dev, "failed to set ANSI 8B/10B encoding\n"); in zynqmp_dp_train()
824 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LINK_BW_SET, bw_code); in zynqmp_dp_train()
826 dev_err(dp->dev, "failed to set DP bandwidth\n"); in zynqmp_dp_train()
830 zynqmp_dp_write(dp, ZYNQMP_DP_LINK_BW_SET, bw_code); in zynqmp_dp_train()
844 zynqmp_dp_write(dp, ZYNQMP_DP_PHY_CLOCK_SELECT, reg); in zynqmp_dp_train()
845 ret = zynqmp_dp_phy_ready(dp); in zynqmp_dp_train()
849 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 1); in zynqmp_dp_train()
850 memset(dp->train_set, 0, sizeof(dp->train_set)); in zynqmp_dp_train()
851 ret = zynqmp_dp_link_train_cr(dp); in zynqmp_dp_train()
855 ret = zynqmp_dp_link_train_ce(dp); in zynqmp_dp_train()
859 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
862 dev_err(dp->dev, "failed to disable training pattern\n"); in zynqmp_dp_train()
865 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
868 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 0); in zynqmp_dp_train()
874 * zynqmp_dp_train_loop - Downshift the link rate during training
875 * @dp: DisplayPort IP core structure
879 static void zynqmp_dp_train_loop(struct zynqmp_dp *dp) in zynqmp_dp_train_loop() argument
881 struct zynqmp_dp_mode *mode = &dp->mode; in zynqmp_dp_train_loop()
882 u8 bw = mode->bw_code; in zynqmp_dp_train_loop()
886 if (dp->status == connector_status_disconnected || in zynqmp_dp_train_loop()
887 !dp->enabled) in zynqmp_dp_train_loop()
890 ret = zynqmp_dp_train(dp); in zynqmp_dp_train_loop()
894 ret = zynqmp_dp_mode_configure(dp, mode->pclock, bw); in zynqmp_dp_train_loop()
902 dev_err(dp->dev, "failed to train the DP link\n"); in zynqmp_dp_train_loop()
905 /* -----------------------------------------------------------------------------
912 * zynqmp_dp_aux_cmd_submit - Submit aux command
913 * @dp: DisplayPort IP core structure
929 * -EBUSY when there is any request already being processed
930 * -ETIMEDOUT when receiving reply is timed out
931 * -EIO when received bytes are less than requested
933 static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr, in zynqmp_dp_aux_cmd_submit() argument
939 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
941 return -EBUSY; in zynqmp_dp_aux_cmd_submit()
943 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_ADDRESS, addr); in zynqmp_dp_aux_cmd_submit()
946 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_WRITE_FIFO, in zynqmp_dp_aux_cmd_submit()
953 reg |= (bytes - 1) << ZYNQMP_DP_AUX_COMMAND_BYTES_SHIFT; in zynqmp_dp_aux_cmd_submit()
954 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_COMMAND, reg); in zynqmp_dp_aux_cmd_submit()
958 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
964 return -ETIMEDOUT; in zynqmp_dp_aux_cmd_submit()
969 reg = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_CODE); in zynqmp_dp_aux_cmd_submit()
976 reg = zynqmp_dp_read(dp, ZYNQMP_DP_REPLY_DATA_COUNT); in zynqmp_dp_aux_cmd_submit()
978 return -EIO; in zynqmp_dp_aux_cmd_submit()
981 buf[i] = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_DATA); in zynqmp_dp_aux_cmd_submit()
990 struct zynqmp_dp *dp = container_of(aux, struct zynqmp_dp, aux); in zynqmp_dp_aux_transfer() local
999 ret = zynqmp_dp_aux_cmd_submit(dp, msg->request, msg->address, in zynqmp_dp_aux_transfer()
1000 msg->buffer, msg->size, in zynqmp_dp_aux_transfer()
1001 &msg->reply); in zynqmp_dp_aux_transfer()
1003 dev_vdbg(dp->dev, "aux %d retries\n", i); in zynqmp_dp_aux_transfer()
1004 return msg->size; in zynqmp_dp_aux_transfer()
1007 if (dp->status == connector_status_disconnected) { in zynqmp_dp_aux_transfer()
1008 dev_dbg(dp->dev, "no connected aux device\n"); in zynqmp_dp_aux_transfer()
1009 return -ENODEV; in zynqmp_dp_aux_transfer()
1015 dev_dbg(dp->dev, "failed to do aux transfer (%d)\n", ret); in zynqmp_dp_aux_transfer()
1021 * zynqmp_dp_aux_init - Initialize and register the DP AUX
1022 * @dp: DisplayPort IP core structure
1024 * Program the AUX clock divider and filter and register the DP AUX adapter.
1028 static int zynqmp_dp_aux_init(struct zynqmp_dp *dp) in zynqmp_dp_aux_init() argument
1040 rate = clk_get_rate(dp->dpsub->apb_clk); in zynqmp_dp_aux_init()
1043 dev_err(dp->dev, "aclk frequency too high\n"); in zynqmp_dp_aux_init()
1044 return -EINVAL; in zynqmp_dp_aux_init()
1047 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_CLK_DIVIDER, in zynqmp_dp_aux_init()
1051 dp->aux.name = "ZynqMP DP AUX"; in zynqmp_dp_aux_init()
1052 dp->aux.dev = dp->dev; in zynqmp_dp_aux_init()
1053 dp->aux.drm_dev = dp->bridge.dev; in zynqmp_dp_aux_init()
1054 dp->aux.transfer = zynqmp_dp_aux_transfer; in zynqmp_dp_aux_init()
1056 return drm_dp_aux_register(&dp->aux); in zynqmp_dp_aux_init()
1060 * zynqmp_dp_aux_cleanup - Cleanup the DP AUX
1061 * @dp: DisplayPort IP core structure
1063 * Unregister the DP AUX adapter.
1065 static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp) in zynqmp_dp_aux_cleanup() argument
1067 drm_dp_aux_unregister(&dp->aux); in zynqmp_dp_aux_cleanup()
1070 /* -----------------------------------------------------------------------------
1075 * zynqmp_dp_update_misc - Write the misc registers
1076 * @dp: DisplayPort IP core structure
1081 static void zynqmp_dp_update_misc(struct zynqmp_dp *dp) in zynqmp_dp_update_misc() argument
1083 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC0, dp->config.misc0); in zynqmp_dp_update_misc()
1084 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC1, dp->config.misc1); in zynqmp_dp_update_misc()
1088 * zynqmp_dp_set_format - Set the input format
1089 * @dp: DisplayPort IP core structure
1096 * Return: 0 on success, or -EINVAL.
1098 static int zynqmp_dp_set_format(struct zynqmp_dp *dp, in zynqmp_dp_set_format() argument
1103 struct zynqmp_dp_config *config = &dp->config; in zynqmp_dp_set_format()
1106 config->misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_MASK; in zynqmp_dp_set_format()
1107 config->misc1 &= ~ZYNQMP_DP_MAIN_STREAM_MISC1_Y_ONLY_EN; in zynqmp_dp_set_format()
1111 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_RGB; in zynqmp_dp_set_format()
1116 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_444; in zynqmp_dp_set_format()
1121 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_422; in zynqmp_dp_set_format()
1126 config->misc1 |= ZYNQMP_DP_MAIN_STREAM_MISC1_Y_ONLY_EN; in zynqmp_dp_set_format()
1131 dev_err(dp->dev, "Invalid colormetry in DT\n"); in zynqmp_dp_set_format()
1132 return -EINVAL; in zynqmp_dp_set_format()
1135 if (info && info->bpc && bpc > info->bpc) { in zynqmp_dp_set_format()
1136 dev_warn(dp->dev, in zynqmp_dp_set_format()
1138 bpc, info->bpc); in zynqmp_dp_set_format()
1139 bpc = info->bpc; in zynqmp_dp_set_format()
1142 config->misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_MASK; in zynqmp_dp_set_format()
1146 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_6; in zynqmp_dp_set_format()
1149 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8; in zynqmp_dp_set_format()
1152 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_10; in zynqmp_dp_set_format()
1155 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_12; in zynqmp_dp_set_format()
1158 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_16; in zynqmp_dp_set_format()
1161 dev_warn(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", in zynqmp_dp_set_format()
1163 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8; in zynqmp_dp_set_format()
1169 config->bpp = bpc * num_colors; in zynqmp_dp_set_format()
1175 * zynqmp_dp_encoder_mode_set_transfer_unit - Set the transfer unit values
1176 * @dp: DisplayPort IP core structure
1180 * Calculation is based on DP and IP core specification.
1183 zynqmp_dp_encoder_mode_set_transfer_unit(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_transfer_unit() argument
1190 zynqmp_dp_write(dp, ZYNQMP_DP_MSA_TRANSFER_UNIT_SIZE, tu); in zynqmp_dp_encoder_mode_set_transfer_unit()
1192 vid_kbytes = mode->clock * (dp->config.bpp / 8); in zynqmp_dp_encoder_mode_set_transfer_unit()
1193 bw = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_transfer_unit()
1194 avg_bytes_per_tu = vid_kbytes * tu / (dp->mode.lane_cnt * bw / 1000); in zynqmp_dp_encoder_mode_set_transfer_unit()
1195 zynqmp_dp_write(dp, ZYNQMP_DP_MIN_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1197 zynqmp_dp_write(dp, ZYNQMP_DP_FRAC_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1206 init_wait = tu - avg_bytes_per_tu / 1000; in zynqmp_dp_encoder_mode_set_transfer_unit()
1208 zynqmp_dp_write(dp, ZYNQMP_DP_INIT_WAIT, init_wait); in zynqmp_dp_encoder_mode_set_transfer_unit()
1212 * zynqmp_dp_encoder_mode_set_stream - Configure the main stream
1213 * @dp: DisplayPort IP core structure
1219 static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_stream() argument
1222 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_encoder_mode_set_stream()
1226 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HTOTAL, mode->htotal); in zynqmp_dp_encoder_mode_set_stream()
1227 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VTOTAL, mode->vtotal); in zynqmp_dp_encoder_mode_set_stream()
1228 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_POLARITY, in zynqmp_dp_encoder_mode_set_stream()
1229 (!!(mode->flags & DRM_MODE_FLAG_PVSYNC) << in zynqmp_dp_encoder_mode_set_stream()
1231 (!!(mode->flags & DRM_MODE_FLAG_PHSYNC) << in zynqmp_dp_encoder_mode_set_stream()
1233 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1234 mode->hsync_end - mode->hsync_start); in zynqmp_dp_encoder_mode_set_stream()
1235 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1236 mode->vsync_end - mode->vsync_start); in zynqmp_dp_encoder_mode_set_stream()
1237 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HRES, mode->hdisplay); in zynqmp_dp_encoder_mode_set_stream()
1238 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VRES, mode->vdisplay); in zynqmp_dp_encoder_mode_set_stream()
1239 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSTART, in zynqmp_dp_encoder_mode_set_stream()
1240 mode->htotal - mode->hsync_start); in zynqmp_dp_encoder_mode_set_stream()
1241 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSTART, in zynqmp_dp_encoder_mode_set_stream()
1242 mode->vtotal - mode->vsync_start); in zynqmp_dp_encoder_mode_set_stream()
1245 if (dp->config.misc0 & ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK) { in zynqmp_dp_encoder_mode_set_stream()
1246 reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_stream()
1247 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_N_VID, reg); in zynqmp_dp_encoder_mode_set_stream()
1248 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_M_VID, mode->clock); in zynqmp_dp_encoder_mode_set_stream()
1249 rate = zynqmp_dpsub_get_audio_clk_rate(dp->dpsub); in zynqmp_dp_encoder_mode_set_stream()
1251 dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512); in zynqmp_dp_encoder_mode_set_stream()
1252 zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, reg); in zynqmp_dp_encoder_mode_set_stream()
1253 zynqmp_dp_write(dp, ZYNQMP_DP_TX_M_AUD, rate / 1000); in zynqmp_dp_encoder_mode_set_stream()
1258 if (zynqmp_dpsub_audio_enabled(dp->dpsub)) in zynqmp_dp_encoder_mode_set_stream()
1259 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, 1); in zynqmp_dp_encoder_mode_set_stream()
1261 zynqmp_dp_write(dp, ZYNQMP_DP_USER_PIX_WIDTH, 1); in zynqmp_dp_encoder_mode_set_stream()
1264 wpl = (mode->hdisplay * dp->config.bpp + 15) / 16; in zynqmp_dp_encoder_mode_set_stream()
1265 reg = wpl + wpl % lane_cnt - lane_cnt; in zynqmp_dp_encoder_mode_set_stream()
1266 zynqmp_dp_write(dp, ZYNQMP_DP_USER_DATA_COUNT_PER_LANE, reg); in zynqmp_dp_encoder_mode_set_stream()
1269 /* -----------------------------------------------------------------------------
1274 * zynqmp_dp_disp_connected_live_layer - Return the first connected live layer
1275 * @dp: DisplayPort IP core structure
1281 zynqmp_dp_disp_connected_live_layer(struct zynqmp_dp *dp) in zynqmp_dp_disp_connected_live_layer() argument
1283 if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO)) in zynqmp_dp_disp_connected_live_layer()
1284 return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_VID]; in zynqmp_dp_disp_connected_live_layer()
1285 else if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX)) in zynqmp_dp_disp_connected_live_layer()
1286 return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX]; in zynqmp_dp_disp_connected_live_layer()
1291 static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp, in zynqmp_dp_disp_enable() argument
1298 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_disp_enable()
1302 bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state->base.state, in zynqmp_dp_disp_enable()
1303 old_bridge_state->bridge); in zynqmp_dp_disp_enable()
1307 bus_fmt = bridge_state->input_bus_cfg.format; in zynqmp_dp_disp_enable()
1311 if (layer == dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX]) in zynqmp_dp_disp_enable()
1312 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, true, 255); in zynqmp_dp_disp_enable()
1314 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, false, 0); in zynqmp_dp_disp_enable()
1316 zynqmp_disp_enable(dp->dpsub->disp); in zynqmp_dp_disp_enable()
1319 static void zynqmp_dp_disp_disable(struct zynqmp_dp *dp, in zynqmp_dp_disp_disable() argument
1324 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_disp_disable()
1328 zynqmp_disp_disable(dp->dpsub->disp); in zynqmp_dp_disp_disable()
1332 /* -----------------------------------------------------------------------------
1339 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_attach() local
1343 ret = zynqmp_dp_aux_init(dp); in zynqmp_dp_bridge_attach()
1345 dev_err(dp->dev, "failed to initialize DP aux\n"); in zynqmp_dp_bridge_attach()
1349 if (dp->next_bridge) { in zynqmp_dp_bridge_attach()
1350 ret = drm_bridge_attach(bridge->encoder, dp->next_bridge, in zynqmp_dp_bridge_attach()
1357 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_ALL); in zynqmp_dp_bridge_attach()
1362 zynqmp_dp_aux_cleanup(dp); in zynqmp_dp_bridge_attach()
1368 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_detach() local
1370 zynqmp_dp_aux_cleanup(dp); in zynqmp_dp_bridge_detach()
1378 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_mode_valid() local
1381 if (mode->clock > ZYNQMP_MAX_FREQ) { in zynqmp_dp_bridge_mode_valid()
1382 dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", in zynqmp_dp_bridge_mode_valid()
1383 mode->name); in zynqmp_dp_bridge_mode_valid()
1389 rate = zynqmp_dp_max_rate(dp->link_config.max_rate, in zynqmp_dp_bridge_mode_valid()
1390 dp->link_config.max_lanes, dp->config.bpp); in zynqmp_dp_bridge_mode_valid()
1391 if (mode->clock > rate) { in zynqmp_dp_bridge_mode_valid()
1392 dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", in zynqmp_dp_bridge_mode_valid()
1393 mode->name); in zynqmp_dp_bridge_mode_valid()
1404 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_enable() local
1405 struct drm_atomic_state *state = old_bridge_state->base.state; in zynqmp_dp_bridge_atomic_enable()
1409 struct drm_connector *connector; in zynqmp_dp_bridge_atomic_enable() local
1415 pm_runtime_get_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1417 zynqmp_dp_disp_enable(dp, old_bridge_state); in zynqmp_dp_bridge_atomic_enable()
1421 * dance to go from the bridge to the encoder, to the connector and to in zynqmp_dp_bridge_atomic_enable()
1424 connector = drm_atomic_get_new_connector_for_encoder(state, in zynqmp_dp_bridge_atomic_enable()
1425 bridge->encoder); in zynqmp_dp_bridge_atomic_enable()
1426 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc; in zynqmp_dp_bridge_atomic_enable()
1428 adjusted_mode = &crtc_state->adjusted_mode; in zynqmp_dp_bridge_atomic_enable()
1429 mode = &crtc_state->mode; in zynqmp_dp_bridge_atomic_enable()
1431 zynqmp_dp_set_format(dp, &connector->display_info, in zynqmp_dp_bridge_atomic_enable()
1435 rate = zynqmp_dp_max_rate(dp->link_config.max_rate, in zynqmp_dp_bridge_atomic_enable()
1436 dp->link_config.max_lanes, dp->config.bpp); in zynqmp_dp_bridge_atomic_enable()
1437 if (mode->clock > rate) { in zynqmp_dp_bridge_atomic_enable()
1438 dev_err(dp->dev, "mode %s has too high pixel rate\n", in zynqmp_dp_bridge_atomic_enable()
1439 mode->name); in zynqmp_dp_bridge_atomic_enable()
1444 ret = zynqmp_dp_mode_configure(dp, adjusted_mode->clock, 0); in zynqmp_dp_bridge_atomic_enable()
1446 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1450 zynqmp_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1451 zynqmp_dp_encoder_mode_set_stream(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1454 dp->enabled = true; in zynqmp_dp_bridge_atomic_enable()
1455 zynqmp_dp_update_misc(dp); in zynqmp_dp_bridge_atomic_enable()
1456 if (zynqmp_dpsub_audio_enabled(dp->dpsub)) in zynqmp_dp_bridge_atomic_enable()
1457 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1); in zynqmp_dp_bridge_atomic_enable()
1458 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0); in zynqmp_dp_bridge_atomic_enable()
1459 if (dp->status == connector_status_connected) { in zynqmp_dp_bridge_atomic_enable()
1461 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, in zynqmp_dp_bridge_atomic_enable()
1471 dev_dbg(dp->dev, "DP aux failed\n"); in zynqmp_dp_bridge_atomic_enable()
1473 zynqmp_dp_train_loop(dp); in zynqmp_dp_bridge_atomic_enable()
1474 zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, in zynqmp_dp_bridge_atomic_enable()
1476 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); in zynqmp_dp_bridge_atomic_enable()
1482 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_disable() local
1484 dp->enabled = false; in zynqmp_dp_bridge_atomic_disable()
1485 cancel_work(&dp->hpd_work); in zynqmp_dp_bridge_atomic_disable()
1486 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); in zynqmp_dp_bridge_atomic_disable()
1487 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in zynqmp_dp_bridge_atomic_disable()
1488 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_bridge_atomic_disable()
1490 if (zynqmp_dpsub_audio_enabled(dp->dpsub)) in zynqmp_dp_bridge_atomic_disable()
1491 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); in zynqmp_dp_bridge_atomic_disable()
1493 zynqmp_dp_disp_disable(dp, old_bridge_state); in zynqmp_dp_bridge_atomic_disable()
1495 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_disable()
1505 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_check() local
1506 struct drm_display_mode *mode = &crtc_state->mode; in zynqmp_dp_bridge_atomic_check()
1507 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; in zynqmp_dp_bridge_atomic_check()
1508 int diff = mode->htotal - mode->hsync_end; in zynqmp_dp_bridge_atomic_check()
1511 * ZynqMP DP requires horizontal backporch to be greater than 12. in zynqmp_dp_bridge_atomic_check()
1515 int vrefresh = (adjusted_mode->clock * 1000) / in zynqmp_dp_bridge_atomic_check()
1516 (adjusted_mode->vtotal * adjusted_mode->htotal); in zynqmp_dp_bridge_atomic_check()
1518 dev_dbg(dp->dev, "hbackporch adjusted: %d to %d", in zynqmp_dp_bridge_atomic_check()
1519 diff, ZYNQMP_DP_MIN_H_BACKPORCH - diff); in zynqmp_dp_bridge_atomic_check()
1520 diff = ZYNQMP_DP_MIN_H_BACKPORCH - diff; in zynqmp_dp_bridge_atomic_check()
1521 adjusted_mode->htotal += diff; in zynqmp_dp_bridge_atomic_check()
1522 adjusted_mode->clock = adjusted_mode->vtotal * in zynqmp_dp_bridge_atomic_check()
1523 adjusted_mode->htotal * vrefresh / 1000; in zynqmp_dp_bridge_atomic_check()
1531 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_detect() local
1532 struct zynqmp_dp_link_config *link_config = &dp->link_config; in zynqmp_dp_bridge_detect()
1541 state = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_bridge_detect()
1548 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd, in zynqmp_dp_bridge_detect()
1549 sizeof(dp->dpcd)); in zynqmp_dp_bridge_detect()
1551 dev_dbg(dp->dev, "DPCD read failed"); in zynqmp_dp_bridge_detect()
1555 link_config->max_rate = min_t(int, in zynqmp_dp_bridge_detect()
1556 drm_dp_max_link_rate(dp->dpcd), in zynqmp_dp_bridge_detect()
1558 link_config->max_lanes = min_t(u8, in zynqmp_dp_bridge_detect()
1559 drm_dp_max_lane_count(dp->dpcd), in zynqmp_dp_bridge_detect()
1560 dp->num_lanes); in zynqmp_dp_bridge_detect()
1562 dp->status = connector_status_connected; in zynqmp_dp_bridge_detect()
1567 dp->status = connector_status_disconnected; in zynqmp_dp_bridge_detect()
1572 struct drm_connector *connector) in zynqmp_dp_bridge_edid_read() argument
1574 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_edid_read() local
1576 return drm_edid_read_ddc(connector, &dp->aux.ddc); in zynqmp_dp_bridge_edid_read()
1598 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_get_input_bus_fmts() local
1601 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_bridge_get_input_bus_fmts()
1623 /* -----------------------------------------------------------------------------
1628 * zynqmp_dp_enable_vblank - Enable vblank
1629 * @dp: DisplayPort IP core structure
1633 void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_enable_vblank() argument
1635 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_enable_vblank()
1639 * zynqmp_dp_disable_vblank - Disable vblank
1640 * @dp: DisplayPort IP core structure
1644 void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_disable_vblank() argument
1646 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_disable_vblank()
1651 struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work); in zynqmp_dp_hpd_work_func() local
1654 status = zynqmp_dp_bridge_detect(&dp->bridge); in zynqmp_dp_hpd_work_func()
1655 drm_bridge_hpd_notify(&dp->bridge, status); in zynqmp_dp_hpd_work_func()
1660 struct zynqmp_dp *dp = (struct zynqmp_dp *)data; in zynqmp_dp_irq_handler() local
1663 status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS); in zynqmp_dp_irq_handler()
1665 zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); in zynqmp_dp_irq_handler()
1666 mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK); in zynqmp_dp_irq_handler()
1679 dev_dbg_ratelimited(dp->dev, "underflow interrupt\n"); in zynqmp_dp_irq_handler()
1681 dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); in zynqmp_dp_irq_handler()
1684 zynqmp_dpsub_drm_handle_vblank(dp->dpsub); in zynqmp_dp_irq_handler()
1687 schedule_work(&dp->hpd_work); in zynqmp_dp_irq_handler()
1693 ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, in zynqmp_dp_irq_handler()
1699 !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || in zynqmp_dp_irq_handler()
1700 !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { in zynqmp_dp_irq_handler()
1701 zynqmp_dp_train_loop(dp); in zynqmp_dp_irq_handler()
1709 /* -----------------------------------------------------------------------------
1715 struct platform_device *pdev = to_platform_device(dpsub->dev); in zynqmp_dp_probe()
1717 struct zynqmp_dp *dp; in zynqmp_dp_probe() local
1721 dp = kzalloc(sizeof(*dp), GFP_KERNEL); in zynqmp_dp_probe()
1722 if (!dp) in zynqmp_dp_probe()
1723 return -ENOMEM; in zynqmp_dp_probe()
1725 dp->dev = &pdev->dev; in zynqmp_dp_probe()
1726 dp->dpsub = dpsub; in zynqmp_dp_probe()
1727 dp->status = connector_status_disconnected; in zynqmp_dp_probe()
1729 INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); in zynqmp_dp_probe()
1732 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp"); in zynqmp_dp_probe()
1733 dp->iomem = devm_ioremap_resource(dp->dev, res); in zynqmp_dp_probe()
1734 if (IS_ERR(dp->iomem)) { in zynqmp_dp_probe()
1735 ret = PTR_ERR(dp->iomem); in zynqmp_dp_probe()
1739 dp->irq = platform_get_irq(pdev, 0); in zynqmp_dp_probe()
1740 if (dp->irq < 0) { in zynqmp_dp_probe()
1741 ret = dp->irq; in zynqmp_dp_probe()
1745 dp->reset = devm_reset_control_get(dp->dev, NULL); in zynqmp_dp_probe()
1746 if (IS_ERR(dp->reset)) { in zynqmp_dp_probe()
1747 if (PTR_ERR(dp->reset) != -EPROBE_DEFER) in zynqmp_dp_probe()
1748 dev_err(dp->dev, "failed to get reset: %ld\n", in zynqmp_dp_probe()
1749 PTR_ERR(dp->reset)); in zynqmp_dp_probe()
1750 ret = PTR_ERR(dp->reset); in zynqmp_dp_probe()
1754 ret = zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
1758 ret = zynqmp_dp_reset(dp, false); in zynqmp_dp_probe()
1762 ret = zynqmp_dp_phy_probe(dp); in zynqmp_dp_probe()
1767 bridge = &dp->bridge; in zynqmp_dp_probe()
1768 bridge->funcs = &zynqmp_dp_bridge_funcs; in zynqmp_dp_probe()
1769 bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID in zynqmp_dp_probe()
1771 bridge->type = DRM_MODE_CONNECTOR_DisplayPort; in zynqmp_dp_probe()
1772 bridge->of_node = dp->dev->of_node; in zynqmp_dp_probe()
1773 dpsub->bridge = bridge; in zynqmp_dp_probe()
1777 * not being connected for backward-compatibility with older DTs. in zynqmp_dp_probe()
1779 ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 5, 0, NULL, in zynqmp_dp_probe()
1780 &dp->next_bridge); in zynqmp_dp_probe()
1781 if (ret < 0 && ret != -ENODEV) in zynqmp_dp_probe()
1785 dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK; in zynqmp_dp_probe()
1786 zynqmp_dp_set_format(dp, NULL, ZYNQMP_DPSUB_FORMAT_RGB, 8); in zynqmp_dp_probe()
1788 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_probe()
1790 zynqmp_dp_set(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_probe()
1791 zynqmp_dp_write(dp, ZYNQMP_DP_FORCE_SCRAMBLER_RESET, 1); in zynqmp_dp_probe()
1792 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_probe()
1793 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_probe()
1795 ret = zynqmp_dp_phy_init(dp); in zynqmp_dp_probe()
1799 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1); in zynqmp_dp_probe()
1805 ret = devm_request_threaded_irq(dp->dev, dp->irq, NULL, in zynqmp_dp_probe()
1807 dev_name(dp->dev), dp); in zynqmp_dp_probe()
1811 dpsub->dp = dp; in zynqmp_dp_probe()
1813 dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n", in zynqmp_dp_probe()
1814 dp->num_lanes); in zynqmp_dp_probe()
1819 zynqmp_dp_phy_exit(dp); in zynqmp_dp_probe()
1821 zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
1823 kfree(dp); in zynqmp_dp_probe()
1829 struct zynqmp_dp *dp = dpsub->dp; in zynqmp_dp_remove() local
1831 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); in zynqmp_dp_remove()
1832 disable_irq(dp->irq); in zynqmp_dp_remove()
1834 cancel_work_sync(&dp->hpd_work); in zynqmp_dp_remove()
1836 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_remove()
1837 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_remove()
1839 zynqmp_dp_phy_exit(dp); in zynqmp_dp_remove()
1840 zynqmp_dp_reset(dp, true); in zynqmp_dp_remove()