Lines Matching +full:dp +full:- +full:aux +full:- +full:bus

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017 - 2020 Xilinx, Inc.
8 * - Hyun Woo Kwon <[email protected]>
9 * - Laurent Pinchart <[email protected]>
27 #include <linux/media-bus-format.h>
42 MODULE_PARM_DESC(aux_timeout_ms, "DP aux timeout value in msec (default: 50)");
49 MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)");
100 /* AUX channel interface registers */
249 * struct zynqmp_dp_link_config - Common link config between source and sink
259 * struct zynqmp_dp_mode - Configured mode of DisplayPort
273 * struct zynqmp_dp_config - Configuration of DisplayPort from DTS
274 * @misc0: misc0 configuration (per DP v1.2 spec)
275 * @misc1: misc1 configuration (per DP v1.2 spec)
285 * enum test_pattern - Test patterns for test testing
289 * @TEST_80BIT_CUSTOM: A custom 80-bit pattern
311 [TEST_SYMBOL_ERROR] = "symbol-error",
313 [TEST_80BIT_CUSTOM] = "80bit-custom",
318 * struct zynqmp_dp_test - Configuration for test mode
338 * struct zynqmp_dp_train_set_priv - Private data for train_set debugfs files
339 * @dp: DisplayPort IP core structure
343 struct zynqmp_dp *dp; member
348 * struct zynqmp_dp - Xilinx DisplayPort core
353 * @lock: Mutex protecting this struct and register access (but not AUX)
355 * @bridge: DRM bridge for the DP encoder
359 * @aux: aux channel
360 * @aux_done: Completed when we get an AUX reply or timeout
361 * @ignore_aux_errors: If set, AUX errors are suppressed
362 * @phy: PHY handles for DP lanes
369 * @dpcd: DP configuration data from currently connected sink device
376 * registers. It does not cover @aux or @ignore_aux_errors. It is not strictly
381 struct drm_dp_aux aux; member
416 static void zynqmp_dp_write(struct zynqmp_dp *dp, int offset, u32 val) in zynqmp_dp_write() argument
418 writel(val, dp->iomem + offset); in zynqmp_dp_write()
421 static u32 zynqmp_dp_read(struct zynqmp_dp *dp, int offset) in zynqmp_dp_read() argument
423 return readl(dp->iomem + offset); in zynqmp_dp_read()
426 static void zynqmp_dp_clr(struct zynqmp_dp *dp, int offset, u32 clr) in zynqmp_dp_clr() argument
428 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) & ~clr); in zynqmp_dp_clr()
431 static void zynqmp_dp_set(struct zynqmp_dp *dp, int offset, u32 set) in zynqmp_dp_set() argument
433 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) | set); in zynqmp_dp_set()
436 /* -----------------------------------------------------------------------------
442 static int zynqmp_dp_reset(struct zynqmp_dp *dp, bool assert) in zynqmp_dp_reset() argument
447 reset_control_assert(dp->reset); in zynqmp_dp_reset()
449 reset_control_deassert(dp->reset); in zynqmp_dp_reset()
454 bool status = !!reset_control_status(dp->reset); in zynqmp_dp_reset()
462 dev_err(dp->dev, "reset %s timeout\n", assert ? "assert" : "deassert"); in zynqmp_dp_reset()
463 return -ETIMEDOUT; in zynqmp_dp_reset()
467 * zynqmp_dp_phy_init - Initialize the phy
468 * @dp: DisplayPort IP core structure
475 static int zynqmp_dp_phy_init(struct zynqmp_dp *dp) in zynqmp_dp_phy_init() argument
480 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_init()
481 ret = phy_init(dp->phy[i]); in zynqmp_dp_phy_init()
483 dev_err(dp->dev, "failed to init phy lane %d\n", i); in zynqmp_dp_phy_init()
488 zynqmp_dp_clr(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_phy_init()
494 for (i = dp->num_lanes - 1; i >= 0; i--) { in zynqmp_dp_phy_init()
495 ret = phy_power_on(dp->phy[i]); in zynqmp_dp_phy_init()
497 dev_err(dp->dev, "failed to power on phy lane %d\n", i); in zynqmp_dp_phy_init()
506 * zynqmp_dp_phy_exit - Exit the phy
507 * @dp: DisplayPort IP core structure
511 static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp) in zynqmp_dp_phy_exit() argument
516 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
517 ret = phy_power_off(dp->phy[i]); in zynqmp_dp_phy_exit()
519 dev_err(dp->dev, "failed to power off phy(%d) %d\n", i, in zynqmp_dp_phy_exit()
523 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
524 ret = phy_exit(dp->phy[i]); in zynqmp_dp_phy_exit()
526 dev_err(dp->dev, "failed to exit phy(%d) %d\n", i, ret); in zynqmp_dp_phy_exit()
531 * zynqmp_dp_phy_probe - Probe the PHYs
532 * @dp: DisplayPort IP core structure
536 * found. The caller can check dp->num_lanes to check how many PHYs were found.
539 * * 0 - Success
540 * * -ENXIO - No PHY found
541 * * -EPROBE_DEFER - Probe deferral requested
542 * * Other negative value - PHY retrieval failure
544 static int zynqmp_dp_phy_probe(struct zynqmp_dp *dp) in zynqmp_dp_phy_probe() argument
552 snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i); in zynqmp_dp_phy_probe()
553 phy = devm_phy_get(dp->dev, phy_name); in zynqmp_dp_phy_probe()
557 case -ENODEV: in zynqmp_dp_phy_probe()
558 if (dp->num_lanes) in zynqmp_dp_phy_probe()
561 dev_err(dp->dev, "no PHY found\n"); in zynqmp_dp_phy_probe()
562 return -ENXIO; in zynqmp_dp_phy_probe()
564 case -EPROBE_DEFER: in zynqmp_dp_phy_probe()
565 return -EPROBE_DEFER; in zynqmp_dp_phy_probe()
568 dev_err(dp->dev, "failed to get PHY lane %u\n", in zynqmp_dp_phy_probe()
574 dp->phy[i] = phy; in zynqmp_dp_phy_probe()
575 dp->num_lanes++; in zynqmp_dp_phy_probe()
582 * zynqmp_dp_phy_ready - Check if PHY is ready
583 * @dp: DisplayPort IP core structure
588 * Return: 0 if PHY is ready, or -ENODEV if PHY is not ready.
590 static int zynqmp_dp_phy_ready(struct zynqmp_dp *dp) in zynqmp_dp_phy_ready() argument
594 ready = (1 << dp->num_lanes) - 1; in zynqmp_dp_phy_ready()
598 reg = zynqmp_dp_read(dp, ZYNQMP_DP_PHY_STATUS); in zynqmp_dp_phy_ready()
603 dev_err(dp->dev, "PHY isn't ready\n"); in zynqmp_dp_phy_ready()
604 return -ENODEV; in zynqmp_dp_phy_ready()
613 /* -----------------------------------------------------------------------------
618 * zynqmp_dp_max_rate - Calculate and return available max pixel clock
619 * @link_rate: link rate (Kilo-bytes / sec)
631 * zynqmp_dp_mode_configure - Configure the link values
632 * @dp: DisplayPort IP core structure
641 * Return: Current link rate code, or -EINVAL.
643 static int zynqmp_dp_mode_configure(struct zynqmp_dp *dp, int pclock, in zynqmp_dp_mode_configure() argument
646 int max_rate = dp->link_config.max_rate; in zynqmp_dp_mode_configure()
648 u8 max_lanes = dp->link_config.max_lanes; in zynqmp_dp_mode_configure()
650 u8 bpp = dp->config.bpp; in zynqmp_dp_mode_configure()
662 dev_err(dp->dev, "can't downshift. already lowest link rate\n"); in zynqmp_dp_mode_configure()
663 return -EINVAL; in zynqmp_dp_mode_configure()
677 dp->mode.bw_code = bw_code; in zynqmp_dp_mode_configure()
678 dp->mode.lane_cnt = lane_cnt; in zynqmp_dp_mode_configure()
679 dp->mode.pclock = pclock; in zynqmp_dp_mode_configure()
680 return dp->mode.bw_code; in zynqmp_dp_mode_configure()
684 dev_err(dp->dev, "failed to configure link values\n"); in zynqmp_dp_mode_configure()
686 return -EINVAL; in zynqmp_dp_mode_configure()
690 * zynqmp_dp_adjust_train - Adjust train values
691 * @dp: DisplayPort IP core structure
694 static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp, in zynqmp_dp_adjust_train() argument
697 u8 *train_set = dp->train_set; in zynqmp_dp_adjust_train()
700 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_adjust_train()
716 * zynqmp_dp_update_vs_emph - Update the training values
717 * @dp: DisplayPort IP core structure
726 static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp, u8 *train_set) in zynqmp_dp_update_vs_emph() argument
731 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set, in zynqmp_dp_update_vs_emph()
732 dp->mode.lane_cnt); in zynqmp_dp_update_vs_emph()
736 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_update_vs_emph()
741 opts.dp.voltage[0] = (train & DP_TRAIN_VOLTAGE_SWING_MASK) in zynqmp_dp_update_vs_emph()
743 opts.dp.pre[0] = (train & DP_TRAIN_PRE_EMPHASIS_MASK) in zynqmp_dp_update_vs_emph()
746 phy_configure(dp->phy[i], &opts); in zynqmp_dp_update_vs_emph()
748 zynqmp_dp_write(dp, reg, 0x2); in zynqmp_dp_update_vs_emph()
755 * zynqmp_dp_link_train_cr - Train clock recovery
756 * @dp: DisplayPort IP core structure
761 static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp) in zynqmp_dp_link_train_cr() argument
764 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_cr()
770 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
772 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
783 ret = zynqmp_dp_update_vs_emph(dp, dp->train_set); in zynqmp_dp_link_train_cr()
787 drm_dp_link_train_clock_recovery_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_cr()
788 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_cr()
797 if (!(dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED)) in zynqmp_dp_link_train_cr()
802 if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == vs) in zynqmp_dp_link_train_cr()
810 vs = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; in zynqmp_dp_link_train_cr()
811 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_cr()
815 return -EIO; in zynqmp_dp_link_train_cr()
821 * zynqmp_dp_link_train_ce - Train channel equalization
822 * @dp: DisplayPort IP core structure
827 static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp) in zynqmp_dp_link_train_ce() argument
830 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_ce()
835 if (dp->dpcd[DP_DPCD_REV] >= DP_V1_2 && in zynqmp_dp_link_train_ce()
836 dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) in zynqmp_dp_link_train_ce()
841 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, pat); in zynqmp_dp_link_train_ce()
842 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_ce()
848 ret = zynqmp_dp_update_vs_emph(dp, dp->train_set); in zynqmp_dp_link_train_ce()
852 drm_dp_link_train_channel_eq_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_ce()
853 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_ce()
861 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_ce()
865 return -EIO; in zynqmp_dp_link_train_ce()
871 * zynqmp_dp_setup() - Set up major link parameters
872 * @dp: DisplayPort IP core structure
876 * @downspread: Enable spread-spectrum clocking
878 * Return: 0 on success, or -errno on failure
880 static int zynqmp_dp_setup(struct zynqmp_dp *dp, u8 bw_code, u8 lane_cnt, in zynqmp_dp_setup() argument
887 zynqmp_dp_write(dp, ZYNQMP_DP_LANE_COUNT_SET, lane_cnt); in zynqmp_dp_setup()
889 zynqmp_dp_write(dp, ZYNQMP_DP_ENHANCED_FRAME_EN, 1); in zynqmp_dp_setup()
894 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 1); in zynqmp_dp_setup()
895 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, in zynqmp_dp_setup()
898 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 0); in zynqmp_dp_setup()
899 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, 0); in zynqmp_dp_setup()
902 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, aux_lane_cnt); in zynqmp_dp_setup()
904 dev_err(dp->dev, "failed to set lane count\n"); in zynqmp_dp_setup()
908 ret = drm_dp_dpcd_writeb(&dp->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, in zynqmp_dp_setup()
911 dev_err(dp->dev, "failed to set ANSI 8B/10B encoding\n"); in zynqmp_dp_setup()
915 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LINK_BW_SET, bw_code); in zynqmp_dp_setup()
917 dev_err(dp->dev, "failed to set DP bandwidth\n"); in zynqmp_dp_setup()
921 zynqmp_dp_write(dp, ZYNQMP_DP_LINK_BW_SET, bw_code); in zynqmp_dp_setup()
935 zynqmp_dp_write(dp, ZYNQMP_DP_PHY_CLOCK_SELECT, reg); in zynqmp_dp_setup()
936 return zynqmp_dp_phy_ready(dp); in zynqmp_dp_setup()
940 * zynqmp_dp_train - Train the link
941 * @dp: DisplayPort IP core structure
945 static int zynqmp_dp_train(struct zynqmp_dp *dp) in zynqmp_dp_train() argument
949 ret = zynqmp_dp_setup(dp, dp->mode.bw_code, dp->mode.lane_cnt, in zynqmp_dp_train()
950 drm_dp_enhanced_frame_cap(dp->dpcd), in zynqmp_dp_train()
951 dp->dpcd[DP_MAX_DOWNSPREAD] & in zynqmp_dp_train()
956 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 1); in zynqmp_dp_train()
957 memset(dp->train_set, 0, sizeof(dp->train_set)); in zynqmp_dp_train()
958 ret = zynqmp_dp_link_train_cr(dp); in zynqmp_dp_train()
962 ret = zynqmp_dp_link_train_ce(dp); in zynqmp_dp_train()
966 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
969 dev_err(dp->dev, "failed to disable training pattern\n"); in zynqmp_dp_train()
972 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
975 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 0); in zynqmp_dp_train()
981 * zynqmp_dp_train_loop - Downshift the link rate during training
982 * @dp: DisplayPort IP core structure
986 static void zynqmp_dp_train_loop(struct zynqmp_dp *dp) in zynqmp_dp_train_loop() argument
988 struct zynqmp_dp_mode *mode = &dp->mode; in zynqmp_dp_train_loop()
989 u8 bw = mode->bw_code; in zynqmp_dp_train_loop()
993 if (dp->status == connector_status_disconnected || in zynqmp_dp_train_loop()
994 !dp->enabled) in zynqmp_dp_train_loop()
997 ret = zynqmp_dp_train(dp); in zynqmp_dp_train_loop()
1001 ret = zynqmp_dp_mode_configure(dp, mode->pclock, bw); in zynqmp_dp_train_loop()
1009 dev_err(dp->dev, "failed to train the DP link\n"); in zynqmp_dp_train_loop()
1012 /* -----------------------------------------------------------------------------
1013 * DisplayPort AUX
1019 * zynqmp_dp_aux_cmd_submit - Submit aux command
1020 * @dp: DisplayPort IP core structure
1021 * @cmd: aux command
1022 * @addr: aux address
1027 * Submit an aux command. All aux related commands, native or i2c aux
1036 * -EBUSY when there is any request already being processed
1037 * -ETIMEDOUT when receiving reply is timed out
1038 * -EIO when received bytes are less than requested
1040 static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr, in zynqmp_dp_aux_cmd_submit() argument
1047 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
1049 return -EBUSY; in zynqmp_dp_aux_cmd_submit()
1051 reinit_completion(&dp->aux_done); in zynqmp_dp_aux_cmd_submit()
1053 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_ADDRESS, addr); in zynqmp_dp_aux_cmd_submit()
1056 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_WRITE_FIFO, in zynqmp_dp_aux_cmd_submit()
1063 reg |= (bytes - 1) << ZYNQMP_DP_AUX_COMMAND_BYTES_SHIFT; in zynqmp_dp_aux_cmd_submit()
1064 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_COMMAND, reg); in zynqmp_dp_aux_cmd_submit()
1067 time_left = wait_for_completion_timeout(&dp->aux_done, in zynqmp_dp_aux_cmd_submit()
1070 return -ETIMEDOUT; in zynqmp_dp_aux_cmd_submit()
1072 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
1074 return -ETIMEDOUT; in zynqmp_dp_aux_cmd_submit()
1076 reg = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_CODE); in zynqmp_dp_aux_cmd_submit()
1083 reg = zynqmp_dp_read(dp, ZYNQMP_DP_REPLY_DATA_COUNT); in zynqmp_dp_aux_cmd_submit()
1085 return -EIO; in zynqmp_dp_aux_cmd_submit()
1088 buf[i] = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_DATA); in zynqmp_dp_aux_cmd_submit()
1095 zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) in zynqmp_dp_aux_transfer() argument
1097 struct zynqmp_dp *dp = container_of(aux, struct zynqmp_dp, aux); in zynqmp_dp_aux_transfer() local
1101 /* Number of loops = timeout in msec / aux delay (400 usec) */ in zynqmp_dp_aux_transfer()
1106 ret = zynqmp_dp_aux_cmd_submit(dp, msg->request, msg->address, in zynqmp_dp_aux_transfer()
1107 msg->buffer, msg->size, in zynqmp_dp_aux_transfer()
1108 &msg->reply); in zynqmp_dp_aux_transfer()
1110 dev_vdbg(dp->dev, "aux %d retries\n", i); in zynqmp_dp_aux_transfer()
1111 return msg->size; in zynqmp_dp_aux_transfer()
1114 if (dp->status == connector_status_disconnected) { in zynqmp_dp_aux_transfer()
1115 dev_dbg(dp->dev, "no connected aux device\n"); in zynqmp_dp_aux_transfer()
1116 if (dp->ignore_aux_errors) in zynqmp_dp_aux_transfer()
1118 return -ENODEV; in zynqmp_dp_aux_transfer()
1124 dev_dbg(dp->dev, "failed to do aux transfer (%d)\n", ret); in zynqmp_dp_aux_transfer()
1126 if (!dp->ignore_aux_errors) in zynqmp_dp_aux_transfer()
1130 msg->reply = DP_AUX_NATIVE_REPLY_ACK; in zynqmp_dp_aux_transfer()
1131 memset(msg->buffer, 0, msg->size); in zynqmp_dp_aux_transfer()
1132 return msg->size; in zynqmp_dp_aux_transfer()
1136 * zynqmp_dp_aux_init - Initialize and register the DP AUX
1137 * @dp: DisplayPort IP core structure
1139 * Program the AUX clock divider and filter and register the DP AUX adapter.
1143 static int zynqmp_dp_aux_init(struct zynqmp_dp *dp) in zynqmp_dp_aux_init() argument
1150 * corresponding to the AUX pulse. Allowable values are 8, 16, 24, 32, in zynqmp_dp_aux_init()
1151 * 40 and 48. The AUX pulse width must be between 0.4µs and 0.6µs, in zynqmp_dp_aux_init()
1155 rate = clk_get_rate(dp->dpsub->apb_clk); in zynqmp_dp_aux_init()
1158 dev_err(dp->dev, "aclk frequency too high\n"); in zynqmp_dp_aux_init()
1159 return -EINVAL; in zynqmp_dp_aux_init()
1162 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_CLK_DIVIDER, in zynqmp_dp_aux_init()
1166 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_REPLY_RECEIVED | in zynqmp_dp_aux_init()
1169 dp->aux.name = "ZynqMP DP AUX"; in zynqmp_dp_aux_init()
1170 dp->aux.dev = dp->dev; in zynqmp_dp_aux_init()
1171 dp->aux.drm_dev = dp->bridge.dev; in zynqmp_dp_aux_init()
1172 dp->aux.transfer = zynqmp_dp_aux_transfer; in zynqmp_dp_aux_init()
1174 return drm_dp_aux_register(&dp->aux); in zynqmp_dp_aux_init()
1178 * zynqmp_dp_aux_cleanup - Cleanup the DP AUX
1179 * @dp: DisplayPort IP core structure
1181 * Unregister the DP AUX adapter.
1183 static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp) in zynqmp_dp_aux_cleanup() argument
1185 drm_dp_aux_unregister(&dp->aux); in zynqmp_dp_aux_cleanup()
1187 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_REPLY_RECEIVED | in zynqmp_dp_aux_cleanup()
1191 /* -----------------------------------------------------------------------------
1196 * zynqmp_dp_update_misc - Write the misc registers
1197 * @dp: DisplayPort IP core structure
1202 static void zynqmp_dp_update_misc(struct zynqmp_dp *dp) in zynqmp_dp_update_misc() argument
1204 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC0, dp->config.misc0); in zynqmp_dp_update_misc()
1205 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC1, dp->config.misc1); in zynqmp_dp_update_misc()
1209 * zynqmp_dp_set_format - Set the input format
1210 * @dp: DisplayPort IP core structure
1217 * Return: 0 on success, or -EINVAL.
1219 static int zynqmp_dp_set_format(struct zynqmp_dp *dp, in zynqmp_dp_set_format() argument
1224 struct zynqmp_dp_config *config = &dp->config; in zynqmp_dp_set_format()
1227 config->misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_MASK; in zynqmp_dp_set_format()
1228 config->misc1 &= ~ZYNQMP_DP_MAIN_STREAM_MISC1_Y_ONLY_EN; in zynqmp_dp_set_format()
1232 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_RGB; in zynqmp_dp_set_format()
1237 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_444; in zynqmp_dp_set_format()
1242 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_422; in zynqmp_dp_set_format()
1247 config->misc1 |= ZYNQMP_DP_MAIN_STREAM_MISC1_Y_ONLY_EN; in zynqmp_dp_set_format()
1252 dev_err(dp->dev, "Invalid colormetry in DT\n"); in zynqmp_dp_set_format()
1253 return -EINVAL; in zynqmp_dp_set_format()
1256 if (info && info->bpc && bpc > info->bpc) { in zynqmp_dp_set_format()
1257 dev_warn(dp->dev, in zynqmp_dp_set_format()
1259 bpc, info->bpc); in zynqmp_dp_set_format()
1260 bpc = info->bpc; in zynqmp_dp_set_format()
1263 config->misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_MASK; in zynqmp_dp_set_format()
1267 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_6; in zynqmp_dp_set_format()
1270 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8; in zynqmp_dp_set_format()
1273 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_10; in zynqmp_dp_set_format()
1276 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_12; in zynqmp_dp_set_format()
1279 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_16; in zynqmp_dp_set_format()
1282 dev_warn(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", in zynqmp_dp_set_format()
1284 config->misc0 |= ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8; in zynqmp_dp_set_format()
1290 config->bpp = bpc * num_colors; in zynqmp_dp_set_format()
1296 * zynqmp_dp_encoder_mode_set_transfer_unit - Set the transfer unit values
1297 * @dp: DisplayPort IP core structure
1301 * Calculation is based on DP and IP core specification.
1304 zynqmp_dp_encoder_mode_set_transfer_unit(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_transfer_unit() argument
1311 zynqmp_dp_write(dp, ZYNQMP_DP_MSA_TRANSFER_UNIT_SIZE, tu); in zynqmp_dp_encoder_mode_set_transfer_unit()
1313 vid_kbytes = mode->clock * (dp->config.bpp / 8); in zynqmp_dp_encoder_mode_set_transfer_unit()
1314 bw = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_transfer_unit()
1315 avg_bytes_per_tu = vid_kbytes * tu / (dp->mode.lane_cnt * bw / 1000); in zynqmp_dp_encoder_mode_set_transfer_unit()
1316 zynqmp_dp_write(dp, ZYNQMP_DP_MIN_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1318 zynqmp_dp_write(dp, ZYNQMP_DP_FRAC_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1327 init_wait = tu - avg_bytes_per_tu / 1000; in zynqmp_dp_encoder_mode_set_transfer_unit()
1329 zynqmp_dp_write(dp, ZYNQMP_DP_INIT_WAIT, init_wait); in zynqmp_dp_encoder_mode_set_transfer_unit()
1333 * zynqmp_dp_encoder_mode_set_stream - Configure the main stream
1334 * @dp: DisplayPort IP core structure
1340 static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_stream() argument
1343 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_encoder_mode_set_stream()
1346 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HTOTAL, mode->htotal); in zynqmp_dp_encoder_mode_set_stream()
1347 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VTOTAL, mode->vtotal); in zynqmp_dp_encoder_mode_set_stream()
1348 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_POLARITY, in zynqmp_dp_encoder_mode_set_stream()
1349 (!!(mode->flags & DRM_MODE_FLAG_PVSYNC) << in zynqmp_dp_encoder_mode_set_stream()
1351 (!!(mode->flags & DRM_MODE_FLAG_PHSYNC) << in zynqmp_dp_encoder_mode_set_stream()
1353 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1354 mode->hsync_end - mode->hsync_start); in zynqmp_dp_encoder_mode_set_stream()
1355 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1356 mode->vsync_end - mode->vsync_start); in zynqmp_dp_encoder_mode_set_stream()
1357 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HRES, mode->hdisplay); in zynqmp_dp_encoder_mode_set_stream()
1358 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VRES, mode->vdisplay); in zynqmp_dp_encoder_mode_set_stream()
1359 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSTART, in zynqmp_dp_encoder_mode_set_stream()
1360 mode->htotal - mode->hsync_start); in zynqmp_dp_encoder_mode_set_stream()
1361 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSTART, in zynqmp_dp_encoder_mode_set_stream()
1362 mode->vtotal - mode->vsync_start); in zynqmp_dp_encoder_mode_set_stream()
1365 if (dp->config.misc0 & ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK) { in zynqmp_dp_encoder_mode_set_stream()
1366 reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_stream()
1367 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_N_VID, reg); in zynqmp_dp_encoder_mode_set_stream()
1368 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_M_VID, mode->clock); in zynqmp_dp_encoder_mode_set_stream()
1371 zynqmp_dp_write(dp, ZYNQMP_DP_USER_PIX_WIDTH, 1); in zynqmp_dp_encoder_mode_set_stream()
1374 wpl = (mode->hdisplay * dp->config.bpp + 15) / 16; in zynqmp_dp_encoder_mode_set_stream()
1375 reg = wpl + wpl % lane_cnt - lane_cnt; in zynqmp_dp_encoder_mode_set_stream()
1376 zynqmp_dp_write(dp, ZYNQMP_DP_USER_DATA_COUNT_PER_LANE, reg); in zynqmp_dp_encoder_mode_set_stream()
1379 /* -----------------------------------------------------------------------------
1383 void zynqmp_dp_audio_set_channels(struct zynqmp_dp *dp, in zynqmp_dp_audio_set_channels() argument
1386 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, num_channels - 1); in zynqmp_dp_audio_set_channels()
1389 void zynqmp_dp_audio_enable(struct zynqmp_dp *dp) in zynqmp_dp_audio_enable() argument
1391 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1); in zynqmp_dp_audio_enable()
1394 void zynqmp_dp_audio_disable(struct zynqmp_dp *dp) in zynqmp_dp_audio_disable() argument
1396 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); in zynqmp_dp_audio_disable()
1399 void zynqmp_dp_audio_write_n_m(struct zynqmp_dp *dp) in zynqmp_dp_audio_write_n_m() argument
1404 if (!(dp->config.misc0 & ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK)) in zynqmp_dp_audio_write_n_m()
1407 link_rate = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_audio_write_n_m()
1409 rate = clk_get_rate(dp->dpsub->aud_clk); in zynqmp_dp_audio_write_n_m()
1411 dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512); in zynqmp_dp_audio_write_n_m()
1413 zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, link_rate); in zynqmp_dp_audio_write_n_m()
1414 zynqmp_dp_write(dp, ZYNQMP_DP_TX_M_AUD, rate / 1000); in zynqmp_dp_audio_write_n_m()
1417 /* -----------------------------------------------------------------------------
1422 * zynqmp_dp_disp_connected_live_layer - Return the first connected live layer
1423 * @dp: DisplayPort IP core structure
1429 zynqmp_dp_disp_connected_live_layer(struct zynqmp_dp *dp) in zynqmp_dp_disp_connected_live_layer() argument
1431 if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO)) in zynqmp_dp_disp_connected_live_layer()
1432 return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_VID]; in zynqmp_dp_disp_connected_live_layer()
1433 else if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX)) in zynqmp_dp_disp_connected_live_layer()
1434 return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX]; in zynqmp_dp_disp_connected_live_layer()
1439 static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp, in zynqmp_dp_disp_enable() argument
1446 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_disp_enable()
1450 bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state->base.state, in zynqmp_dp_disp_enable()
1451 old_bridge_state->bridge); in zynqmp_dp_disp_enable()
1455 bus_fmt = bridge_state->input_bus_cfg.format; in zynqmp_dp_disp_enable()
1459 if (layer == dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX]) in zynqmp_dp_disp_enable()
1460 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, true, 255); in zynqmp_dp_disp_enable()
1462 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, false, 0); in zynqmp_dp_disp_enable()
1464 zynqmp_disp_enable(dp->dpsub->disp); in zynqmp_dp_disp_enable()
1467 static void zynqmp_dp_disp_disable(struct zynqmp_dp *dp, in zynqmp_dp_disp_disable() argument
1472 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_disp_disable()
1476 zynqmp_disp_disable(dp->dpsub->disp); in zynqmp_dp_disp_disable()
1480 /* -----------------------------------------------------------------------------
1487 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_attach() local
1490 /* Initialize and register the AUX adapter. */ in zynqmp_dp_bridge_attach()
1491 ret = zynqmp_dp_aux_init(dp); in zynqmp_dp_bridge_attach()
1493 dev_err(dp->dev, "failed to initialize DP aux\n"); in zynqmp_dp_bridge_attach()
1497 if (dp->next_bridge) { in zynqmp_dp_bridge_attach()
1498 ret = drm_bridge_attach(bridge->encoder, dp->next_bridge, in zynqmp_dp_bridge_attach()
1505 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_ALL); in zynqmp_dp_bridge_attach()
1510 zynqmp_dp_aux_cleanup(dp); in zynqmp_dp_bridge_attach()
1516 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_detach() local
1518 zynqmp_dp_aux_cleanup(dp); in zynqmp_dp_bridge_detach()
1526 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_mode_valid() local
1529 if (mode->clock > ZYNQMP_MAX_FREQ) { in zynqmp_dp_bridge_mode_valid()
1530 dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", in zynqmp_dp_bridge_mode_valid()
1531 mode->name); in zynqmp_dp_bridge_mode_valid()
1537 mutex_lock(&dp->lock); in zynqmp_dp_bridge_mode_valid()
1538 rate = zynqmp_dp_max_rate(dp->link_config.max_rate, in zynqmp_dp_bridge_mode_valid()
1539 dp->link_config.max_lanes, dp->config.bpp); in zynqmp_dp_bridge_mode_valid()
1540 mutex_unlock(&dp->lock); in zynqmp_dp_bridge_mode_valid()
1541 if (mode->clock > rate) { in zynqmp_dp_bridge_mode_valid()
1542 dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", in zynqmp_dp_bridge_mode_valid()
1543 mode->name); in zynqmp_dp_bridge_mode_valid()
1554 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_enable() local
1555 struct drm_atomic_state *state = old_bridge_state->base.state; in zynqmp_dp_bridge_atomic_enable()
1565 pm_runtime_get_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1567 guard(mutex)(&dp->lock); in zynqmp_dp_bridge_atomic_enable()
1568 zynqmp_dp_disp_enable(dp, old_bridge_state); in zynqmp_dp_bridge_atomic_enable()
1576 bridge->encoder); in zynqmp_dp_bridge_atomic_enable()
1577 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc; in zynqmp_dp_bridge_atomic_enable()
1579 adjusted_mode = &crtc_state->adjusted_mode; in zynqmp_dp_bridge_atomic_enable()
1580 mode = &crtc_state->mode; in zynqmp_dp_bridge_atomic_enable()
1582 zynqmp_dp_set_format(dp, &connector->display_info, in zynqmp_dp_bridge_atomic_enable()
1586 rate = zynqmp_dp_max_rate(dp->link_config.max_rate, in zynqmp_dp_bridge_atomic_enable()
1587 dp->link_config.max_lanes, dp->config.bpp); in zynqmp_dp_bridge_atomic_enable()
1588 if (mode->clock > rate) { in zynqmp_dp_bridge_atomic_enable()
1589 dev_err(dp->dev, "mode %s has too high pixel rate\n", in zynqmp_dp_bridge_atomic_enable()
1590 mode->name); in zynqmp_dp_bridge_atomic_enable()
1595 ret = zynqmp_dp_mode_configure(dp, adjusted_mode->clock, 0); in zynqmp_dp_bridge_atomic_enable()
1597 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1601 zynqmp_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1602 zynqmp_dp_encoder_mode_set_stream(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1605 dp->enabled = true; in zynqmp_dp_bridge_atomic_enable()
1606 zynqmp_dp_update_misc(dp); in zynqmp_dp_bridge_atomic_enable()
1608 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0); in zynqmp_dp_bridge_atomic_enable()
1609 if (dp->status == connector_status_connected) { in zynqmp_dp_bridge_atomic_enable()
1611 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, in zynqmp_dp_bridge_atomic_enable()
1621 dev_dbg(dp->dev, "DP aux failed\n"); in zynqmp_dp_bridge_atomic_enable()
1623 zynqmp_dp_train_loop(dp); in zynqmp_dp_bridge_atomic_enable()
1624 zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, in zynqmp_dp_bridge_atomic_enable()
1626 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); in zynqmp_dp_bridge_atomic_enable()
1632 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_disable() local
1634 mutex_lock(&dp->lock); in zynqmp_dp_bridge_atomic_disable()
1635 dp->enabled = false; in zynqmp_dp_bridge_atomic_disable()
1636 cancel_work(&dp->hpd_work); in zynqmp_dp_bridge_atomic_disable()
1637 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); in zynqmp_dp_bridge_atomic_disable()
1638 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in zynqmp_dp_bridge_atomic_disable()
1639 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_bridge_atomic_disable()
1642 zynqmp_dp_disp_disable(dp, old_bridge_state); in zynqmp_dp_bridge_atomic_disable()
1643 mutex_unlock(&dp->lock); in zynqmp_dp_bridge_atomic_disable()
1645 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_disable()
1655 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_check() local
1656 struct drm_display_mode *mode = &crtc_state->mode; in zynqmp_dp_bridge_atomic_check()
1657 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; in zynqmp_dp_bridge_atomic_check()
1658 int diff = mode->htotal - mode->hsync_end; in zynqmp_dp_bridge_atomic_check()
1661 * ZynqMP DP requires horizontal backporch to be greater than 12. in zynqmp_dp_bridge_atomic_check()
1665 int vrefresh = (adjusted_mode->clock * 1000) / in zynqmp_dp_bridge_atomic_check()
1666 (adjusted_mode->vtotal * adjusted_mode->htotal); in zynqmp_dp_bridge_atomic_check()
1668 dev_dbg(dp->dev, "hbackporch adjusted: %d to %d", in zynqmp_dp_bridge_atomic_check()
1669 diff, ZYNQMP_DP_MIN_H_BACKPORCH - diff); in zynqmp_dp_bridge_atomic_check()
1670 diff = ZYNQMP_DP_MIN_H_BACKPORCH - diff; in zynqmp_dp_bridge_atomic_check()
1671 adjusted_mode->htotal += diff; in zynqmp_dp_bridge_atomic_check()
1672 adjusted_mode->clock = adjusted_mode->vtotal * in zynqmp_dp_bridge_atomic_check()
1673 adjusted_mode->htotal * vrefresh / 1000; in zynqmp_dp_bridge_atomic_check()
1679 static enum drm_connector_status __zynqmp_dp_bridge_detect(struct zynqmp_dp *dp) in __zynqmp_dp_bridge_detect() argument
1681 struct zynqmp_dp_link_config *link_config = &dp->link_config; in __zynqmp_dp_bridge_detect()
1685 lockdep_assert_held(&dp->lock); in __zynqmp_dp_bridge_detect()
1692 state = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in __zynqmp_dp_bridge_detect()
1699 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd, in __zynqmp_dp_bridge_detect()
1700 sizeof(dp->dpcd)); in __zynqmp_dp_bridge_detect()
1702 dev_dbg(dp->dev, "DPCD read failed"); in __zynqmp_dp_bridge_detect()
1706 link_config->max_rate = min_t(int, in __zynqmp_dp_bridge_detect()
1707 drm_dp_max_link_rate(dp->dpcd), in __zynqmp_dp_bridge_detect()
1709 link_config->max_lanes = min_t(u8, in __zynqmp_dp_bridge_detect()
1710 drm_dp_max_lane_count(dp->dpcd), in __zynqmp_dp_bridge_detect()
1711 dp->num_lanes); in __zynqmp_dp_bridge_detect()
1713 dp->status = connector_status_connected; in __zynqmp_dp_bridge_detect()
1718 dp->status = connector_status_disconnected; in __zynqmp_dp_bridge_detect()
1724 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_detect() local
1727 mutex_lock(&dp->lock); in zynqmp_dp_bridge_detect()
1728 ret = __zynqmp_dp_bridge_detect(dp); in zynqmp_dp_bridge_detect()
1729 mutex_unlock(&dp->lock); in zynqmp_dp_bridge_detect()
1737 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_edid_read() local
1739 return drm_edid_read_ddc(connector, &dp->aux.ddc); in zynqmp_dp_bridge_edid_read()
1761 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_get_input_bus_fmts() local
1764 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_bridge_get_input_bus_fmts()
1771 /* -----------------------------------------------------------------------------
1776 * zynqmp_dp_set_test_pattern() - Configure the link for a test pattern
1777 * @dp: DisplayPort IP core structure
1783 static int zynqmp_dp_set_test_pattern(struct zynqmp_dp *dp, in zynqmp_dp_set_test_pattern() argument
1817 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_1, in zynqmp_dp_set_test_pattern()
1819 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_2, in zynqmp_dp_set_test_pattern()
1821 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_3, in zynqmp_dp_set_test_pattern()
1835 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, !scramble); in zynqmp_dp_set_test_pattern()
1836 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, train_pattern); in zynqmp_dp_set_test_pattern()
1837 zynqmp_dp_write(dp, ZYNQMP_DP_LINK_QUAL_PATTERN_SET, link_pattern); in zynqmp_dp_set_test_pattern()
1838 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMIT_PRBS7, pattern == TEST_PRBS7); in zynqmp_dp_set_test_pattern()
1845 if (dp->dpcd[DP_DPCD_REV] < 0x12) { in zynqmp_dp_set_test_pattern()
1847 dev_warn(dp->dev, in zynqmp_dp_set_test_pattern()
1856 ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_QUAL_LANE0_SET, in zynqmp_dp_set_test_pattern()
1862 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, dpcd_train); in zynqmp_dp_set_test_pattern()
1866 static int zynqmp_dp_test_setup(struct zynqmp_dp *dp) in zynqmp_dp_test_setup() argument
1868 return zynqmp_dp_setup(dp, dp->test.bw_code, dp->test.link_cnt, in zynqmp_dp_test_setup()
1869 dp->test.enhanced, dp->test.downspread); in zynqmp_dp_test_setup()
1875 struct dentry *dentry = file->f_path.dentry; in zynqmp_dp_pattern_read()
1876 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_pattern_read() local
1884 mutex_lock(&dp->lock); in zynqmp_dp_pattern_read()
1886 test_pattern_str[dp->test.pattern]); in zynqmp_dp_pattern_read()
1887 mutex_unlock(&dp->lock); in zynqmp_dp_pattern_read()
1897 struct dentry *dentry = file->f_path.dentry; in zynqmp_dp_pattern_write()
1898 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_pattern_write() local
1907 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, in zynqmp_dp_pattern_write()
1915 ret = -EINVAL; in zynqmp_dp_pattern_write()
1919 mutex_lock(&dp->lock); in zynqmp_dp_pattern_write()
1920 dp->test.pattern = pattern; in zynqmp_dp_pattern_write()
1921 if (dp->test.active) in zynqmp_dp_pattern_write()
1922 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_pattern_write()
1923 dp->test.custom) ?: ret; in zynqmp_dp_pattern_write()
1924 mutex_unlock(&dp->lock); in zynqmp_dp_pattern_write()
1940 struct zynqmp_dp *dp = data; in zynqmp_dp_enhanced_get() local
1942 mutex_lock(&dp->lock); in zynqmp_dp_enhanced_get()
1943 *val = dp->test.enhanced; in zynqmp_dp_enhanced_get()
1944 mutex_unlock(&dp->lock); in zynqmp_dp_enhanced_get()
1950 struct zynqmp_dp *dp = data; in zynqmp_dp_enhanced_set() local
1953 mutex_lock(&dp->lock); in zynqmp_dp_enhanced_set()
1954 dp->test.enhanced = val; in zynqmp_dp_enhanced_set()
1955 if (dp->test.active) in zynqmp_dp_enhanced_set()
1956 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_enhanced_set()
1957 mutex_unlock(&dp->lock); in zynqmp_dp_enhanced_set()
1967 struct zynqmp_dp *dp = data; in zynqmp_dp_downspread_get() local
1969 mutex_lock(&dp->lock); in zynqmp_dp_downspread_get()
1970 *val = dp->test.downspread; in zynqmp_dp_downspread_get()
1971 mutex_unlock(&dp->lock); in zynqmp_dp_downspread_get()
1977 struct zynqmp_dp *dp = data; in zynqmp_dp_downspread_set() local
1980 mutex_lock(&dp->lock); in zynqmp_dp_downspread_set()
1981 dp->test.downspread = val; in zynqmp_dp_downspread_set()
1982 if (dp->test.active) in zynqmp_dp_downspread_set()
1983 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_downspread_set()
1984 mutex_unlock(&dp->lock); in zynqmp_dp_downspread_set()
1994 struct zynqmp_dp *dp = data; in zynqmp_dp_active_get() local
1996 mutex_lock(&dp->lock); in zynqmp_dp_active_get()
1997 *val = dp->test.active; in zynqmp_dp_active_get()
1998 mutex_unlock(&dp->lock); in zynqmp_dp_active_get()
2004 struct zynqmp_dp *dp = data; in zynqmp_dp_active_set() local
2007 mutex_lock(&dp->lock); in zynqmp_dp_active_set()
2010 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_active_set()
2015 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_active_set()
2016 dp->test.custom); in zynqmp_dp_active_set()
2020 ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_active_set()
2024 dp->test.active = true; in zynqmp_dp_active_set()
2028 dp->test.active = false; in zynqmp_dp_active_set()
2029 err = zynqmp_dp_set_test_pattern(dp, TEST_VIDEO, NULL); in zynqmp_dp_active_set()
2031 dev_warn(dp->dev, "could not clear test pattern: %d\n", in zynqmp_dp_active_set()
2033 zynqmp_dp_train_loop(dp); in zynqmp_dp_active_set()
2036 mutex_unlock(&dp->lock); in zynqmp_dp_active_set()
2047 struct dentry *dentry = file->f_path.dentry; in zynqmp_dp_custom_read()
2048 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_custom_read() local
2055 mutex_lock(&dp->lock); in zynqmp_dp_custom_read()
2056 ret = simple_read_from_buffer(user_buf, count, ppos, &dp->test.custom, in zynqmp_dp_custom_read()
2057 sizeof(dp->test.custom)); in zynqmp_dp_custom_read()
2058 mutex_unlock(&dp->lock); in zynqmp_dp_custom_read()
2068 struct dentry *dentry = file->f_path.dentry; in zynqmp_dp_custom_write()
2069 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_custom_write() local
2071 char buf[sizeof(dp->test.custom)]; in zynqmp_dp_custom_write()
2081 mutex_lock(&dp->lock); in zynqmp_dp_custom_write()
2082 memcpy(dp->test.custom, buf, ret); in zynqmp_dp_custom_write()
2083 if (dp->test.active) in zynqmp_dp_custom_write()
2084 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_custom_write()
2085 dp->test.custom) ?: ret; in zynqmp_dp_custom_write()
2086 mutex_unlock(&dp->lock); in zynqmp_dp_custom_write()
2103 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_swing_get() local
2105 mutex_lock(&dp->lock); in zynqmp_dp_swing_get()
2106 *val = dp->test.train_set[priv->lane] & DP_TRAIN_VOLTAGE_SWING_MASK; in zynqmp_dp_swing_get()
2107 mutex_unlock(&dp->lock); in zynqmp_dp_swing_get()
2114 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_swing_set() local
2115 u8 *train_set = &dp->test.train_set[priv->lane]; in zynqmp_dp_swing_set()
2119 return -EINVAL; in zynqmp_dp_swing_set()
2121 mutex_lock(&dp->lock); in zynqmp_dp_swing_set()
2128 if (dp->test.active) in zynqmp_dp_swing_set()
2129 ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_swing_set()
2130 mutex_unlock(&dp->lock); in zynqmp_dp_swing_set()
2141 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_preemphasis_get() local
2143 mutex_lock(&dp->lock); in zynqmp_dp_preemphasis_get()
2145 dp->test.train_set[priv->lane]); in zynqmp_dp_preemphasis_get()
2146 mutex_unlock(&dp->lock); in zynqmp_dp_preemphasis_get()
2153 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_preemphasis_set() local
2154 u8 *train_set = &dp->test.train_set[priv->lane]; in zynqmp_dp_preemphasis_set()
2158 return -EINVAL; in zynqmp_dp_preemphasis_set()
2160 mutex_lock(&dp->lock); in zynqmp_dp_preemphasis_set()
2167 if (dp->test.active) in zynqmp_dp_preemphasis_set()
2168 ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_preemphasis_set()
2169 mutex_unlock(&dp->lock); in zynqmp_dp_preemphasis_set()
2179 struct zynqmp_dp *dp = data; in zynqmp_dp_lanes_get() local
2181 mutex_lock(&dp->lock); in zynqmp_dp_lanes_get()
2182 *val = dp->test.link_cnt; in zynqmp_dp_lanes_get()
2183 mutex_unlock(&dp->lock); in zynqmp_dp_lanes_get()
2189 struct zynqmp_dp *dp = data; in zynqmp_dp_lanes_set() local
2193 return -EINVAL; in zynqmp_dp_lanes_set()
2195 mutex_lock(&dp->lock); in zynqmp_dp_lanes_set()
2196 if (val > dp->num_lanes) { in zynqmp_dp_lanes_set()
2197 ret = -EINVAL; in zynqmp_dp_lanes_set()
2199 dp->test.link_cnt = val; in zynqmp_dp_lanes_set()
2200 if (dp->test.active) in zynqmp_dp_lanes_set()
2201 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_lanes_set()
2203 mutex_unlock(&dp->lock); in zynqmp_dp_lanes_set()
2213 struct zynqmp_dp *dp = data; in zynqmp_dp_rate_get() local
2215 mutex_lock(&dp->lock); in zynqmp_dp_rate_get()
2216 *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL; in zynqmp_dp_rate_get()
2217 mutex_unlock(&dp->lock); in zynqmp_dp_rate_get()
2223 struct zynqmp_dp *dp = data; in zynqmp_dp_rate_set() local
2229 return -EINVAL; in zynqmp_dp_rate_set()
2234 return -EINVAL; in zynqmp_dp_rate_set()
2238 return -EINVAL; in zynqmp_dp_rate_set()
2240 mutex_lock(&dp->lock); in zynqmp_dp_rate_set()
2241 dp->test.bw_code = bw_code; in zynqmp_dp_rate_set()
2242 if (dp->test.active) in zynqmp_dp_rate_set()
2243 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_rate_set()
2244 mutex_unlock(&dp->lock); in zynqmp_dp_rate_set()
2254 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_aux_errors_get() local
2256 mutex_lock(&dp->aux.hw_mutex); in zynqmp_dp_ignore_aux_errors_get()
2257 *val = dp->ignore_aux_errors; in zynqmp_dp_ignore_aux_errors_get()
2258 mutex_unlock(&dp->aux.hw_mutex); in zynqmp_dp_ignore_aux_errors_get()
2264 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_aux_errors_set() local
2267 return -EINVAL; in zynqmp_dp_ignore_aux_errors_set()
2269 mutex_lock(&dp->aux.hw_mutex); in zynqmp_dp_ignore_aux_errors_set()
2270 dp->ignore_aux_errors = val; in zynqmp_dp_ignore_aux_errors_set()
2271 mutex_unlock(&dp->aux.hw_mutex); in zynqmp_dp_ignore_aux_errors_set()
2281 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_hpd_get() local
2283 mutex_lock(&dp->lock); in zynqmp_dp_ignore_hpd_get()
2284 *val = dp->ignore_hpd; in zynqmp_dp_ignore_hpd_get()
2285 mutex_unlock(&dp->lock); in zynqmp_dp_ignore_hpd_get()
2291 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_hpd_set() local
2294 return -EINVAL; in zynqmp_dp_ignore_hpd_set()
2296 mutex_lock(&dp->lock); in zynqmp_dp_ignore_hpd_set()
2297 dp->ignore_hpd = val; in zynqmp_dp_ignore_hpd_set()
2298 mutex_unlock(&dp->lock); in zynqmp_dp_ignore_hpd_set()
2308 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_debugfs_init() local
2312 dp->test.bw_code = DP_LINK_BW_5_4; in zynqmp_dp_bridge_debugfs_init()
2313 dp->test.link_cnt = dp->num_lanes; in zynqmp_dp_bridge_debugfs_init()
2317 debugfs_create_file(#name, 0600, test, dp, &fops_zynqmp_dp_##name) in zynqmp_dp_bridge_debugfs_init()
2328 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_bridge_debugfs_init()
2332 dp->debugfs_train_set[i].dp = dp; in zynqmp_dp_bridge_debugfs_init()
2333 dp->debugfs_train_set[i].lane = i; in zynqmp_dp_bridge_debugfs_init()
2337 &dp->debugfs_train_set[i], in zynqmp_dp_bridge_debugfs_init()
2342 &dp->debugfs_train_set[i], in zynqmp_dp_bridge_debugfs_init()
2363 /* -----------------------------------------------------------------------------
2368 * zynqmp_dp_enable_vblank - Enable vblank
2369 * @dp: DisplayPort IP core structure
2373 void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_enable_vblank() argument
2375 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_enable_vblank()
2379 * zynqmp_dp_disable_vblank - Disable vblank
2380 * @dp: DisplayPort IP core structure
2384 void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_disable_vblank() argument
2386 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_disable_vblank()
2391 struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work); in zynqmp_dp_hpd_work_func() local
2394 mutex_lock(&dp->lock); in zynqmp_dp_hpd_work_func()
2395 if (dp->ignore_hpd) { in zynqmp_dp_hpd_work_func()
2396 mutex_unlock(&dp->lock); in zynqmp_dp_hpd_work_func()
2400 status = __zynqmp_dp_bridge_detect(dp); in zynqmp_dp_hpd_work_func()
2401 mutex_unlock(&dp->lock); in zynqmp_dp_hpd_work_func()
2403 drm_bridge_hpd_notify(&dp->bridge, status); in zynqmp_dp_hpd_work_func()
2408 struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, in zynqmp_dp_hpd_irq_work_func() local
2413 mutex_lock(&dp->lock); in zynqmp_dp_hpd_irq_work_func()
2414 if (dp->ignore_hpd) { in zynqmp_dp_hpd_irq_work_func()
2415 mutex_unlock(&dp->lock); in zynqmp_dp_hpd_irq_work_func()
2419 err = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, in zynqmp_dp_hpd_irq_work_func()
2422 dev_dbg_ratelimited(dp->dev, in zynqmp_dp_hpd_irq_work_func()
2426 !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || in zynqmp_dp_hpd_irq_work_func()
2427 !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { in zynqmp_dp_hpd_irq_work_func()
2428 zynqmp_dp_train_loop(dp); in zynqmp_dp_hpd_irq_work_func()
2431 mutex_unlock(&dp->lock); in zynqmp_dp_hpd_irq_work_func()
2436 struct zynqmp_dp *dp = (struct zynqmp_dp *)data; in zynqmp_dp_irq_handler() local
2439 status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS); in zynqmp_dp_irq_handler()
2441 zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); in zynqmp_dp_irq_handler()
2442 mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK); in zynqmp_dp_irq_handler()
2455 dev_dbg_ratelimited(dp->dev, "underflow interrupt\n"); in zynqmp_dp_irq_handler()
2457 dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); in zynqmp_dp_irq_handler()
2460 zynqmp_dpsub_drm_handle_vblank(dp->dpsub); in zynqmp_dp_irq_handler()
2463 schedule_work(&dp->hpd_work); in zynqmp_dp_irq_handler()
2466 schedule_work(&dp->hpd_irq_work); in zynqmp_dp_irq_handler()
2469 complete(&dp->aux_done); in zynqmp_dp_irq_handler()
2472 complete(&dp->aux_done); in zynqmp_dp_irq_handler()
2477 /* -----------------------------------------------------------------------------
2483 struct platform_device *pdev = to_platform_device(dpsub->dev); in zynqmp_dp_probe()
2485 struct zynqmp_dp *dp; in zynqmp_dp_probe() local
2489 dp = kzalloc(sizeof(*dp), GFP_KERNEL); in zynqmp_dp_probe()
2490 if (!dp) in zynqmp_dp_probe()
2491 return -ENOMEM; in zynqmp_dp_probe()
2493 dp->dev = &pdev->dev; in zynqmp_dp_probe()
2494 dp->dpsub = dpsub; in zynqmp_dp_probe()
2495 dp->status = connector_status_disconnected; in zynqmp_dp_probe()
2496 mutex_init(&dp->lock); in zynqmp_dp_probe()
2497 init_completion(&dp->aux_done); in zynqmp_dp_probe()
2499 INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); in zynqmp_dp_probe()
2500 INIT_WORK(&dp->hpd_irq_work, zynqmp_dp_hpd_irq_work_func); in zynqmp_dp_probe()
2503 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp"); in zynqmp_dp_probe()
2504 dp->iomem = devm_ioremap_resource(dp->dev, res); in zynqmp_dp_probe()
2505 if (IS_ERR(dp->iomem)) { in zynqmp_dp_probe()
2506 ret = PTR_ERR(dp->iomem); in zynqmp_dp_probe()
2510 dp->irq = platform_get_irq(pdev, 0); in zynqmp_dp_probe()
2511 if (dp->irq < 0) { in zynqmp_dp_probe()
2512 ret = dp->irq; in zynqmp_dp_probe()
2516 dp->reset = devm_reset_control_get(dp->dev, NULL); in zynqmp_dp_probe()
2517 if (IS_ERR(dp->reset)) { in zynqmp_dp_probe()
2518 if (PTR_ERR(dp->reset) != -EPROBE_DEFER) in zynqmp_dp_probe()
2519 dev_err(dp->dev, "failed to get reset: %ld\n", in zynqmp_dp_probe()
2520 PTR_ERR(dp->reset)); in zynqmp_dp_probe()
2521 ret = PTR_ERR(dp->reset); in zynqmp_dp_probe()
2525 ret = zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
2529 ret = zynqmp_dp_reset(dp, false); in zynqmp_dp_probe()
2533 ret = zynqmp_dp_phy_probe(dp); in zynqmp_dp_probe()
2538 bridge = &dp->bridge; in zynqmp_dp_probe()
2539 bridge->funcs = &zynqmp_dp_bridge_funcs; in zynqmp_dp_probe()
2540 bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID in zynqmp_dp_probe()
2542 bridge->type = DRM_MODE_CONNECTOR_DisplayPort; in zynqmp_dp_probe()
2543 bridge->of_node = dp->dev->of_node; in zynqmp_dp_probe()
2544 dpsub->bridge = bridge; in zynqmp_dp_probe()
2548 * not being connected for backward-compatibility with older DTs. in zynqmp_dp_probe()
2550 ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 5, 0, NULL, in zynqmp_dp_probe()
2551 &dp->next_bridge); in zynqmp_dp_probe()
2552 if (ret < 0 && ret != -ENODEV) in zynqmp_dp_probe()
2556 dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK; in zynqmp_dp_probe()
2557 zynqmp_dp_set_format(dp, NULL, ZYNQMP_DPSUB_FORMAT_RGB, 8); in zynqmp_dp_probe()
2559 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_probe()
2561 zynqmp_dp_set(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_probe()
2562 zynqmp_dp_write(dp, ZYNQMP_DP_FORCE_SCRAMBLER_RESET, 1); in zynqmp_dp_probe()
2563 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_probe()
2564 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_probe()
2566 ret = zynqmp_dp_phy_init(dp); in zynqmp_dp_probe()
2570 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1); in zynqmp_dp_probe()
2576 ret = devm_request_irq(dp->dev, dp->irq, zynqmp_dp_irq_handler, in zynqmp_dp_probe()
2577 IRQF_SHARED, dev_name(dp->dev), dp); in zynqmp_dp_probe()
2581 dpsub->dp = dp; in zynqmp_dp_probe()
2583 dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n", in zynqmp_dp_probe()
2584 dp->num_lanes); in zynqmp_dp_probe()
2589 zynqmp_dp_phy_exit(dp); in zynqmp_dp_probe()
2591 zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
2593 kfree(dp); in zynqmp_dp_probe()
2599 struct zynqmp_dp *dp = dpsub->dp; in zynqmp_dp_remove() local
2601 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); in zynqmp_dp_remove()
2602 devm_free_irq(dp->dev, dp->irq, dp); in zynqmp_dp_remove()
2604 cancel_work_sync(&dp->hpd_irq_work); in zynqmp_dp_remove()
2605 cancel_work_sync(&dp->hpd_work); in zynqmp_dp_remove()
2607 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_remove()
2608 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_remove()
2610 zynqmp_dp_phy_exit(dp); in zynqmp_dp_remove()
2611 zynqmp_dp_reset(dp, true); in zynqmp_dp_remove()
2612 mutex_destroy(&dp->lock); in zynqmp_dp_remove()