Lines Matching +full:zynqmp +full:- +full:dpsub +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
3 * ZynqMP DisplayPort Driver
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>
61 #define ZYNQMP_DP_SOFTWARE_RESET_STREAM2 BIT(1)
98 #define ZYNQMP_DP_CORE_ID_DIRECTION GENMASK(1)
111 #define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REQUEST BIT(1)
118 #define ZYNQMP_DP_AUX_REPLY_CODE_AUX_DEFER BIT(1)
130 #define ZYNQMP_DP_INT_HPD_EVENT BIT(1)
155 #define ZYNQMP_DP_MAIN_STREAM_POLARITY_VSYNC_SHIFT 1
164 #define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_RGB (0 << 1)
165 #define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_422 (5 << 1)
166 #define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_444 (6 << 1)
167 #define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_MASK (7 << 1)
171 #define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8 (1 << 5)
191 #define ZYNQMP_DP_PHY_RESET_GTTX_RESET BIT(1)
212 #define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_1 BIT(1)
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
285 * enum test_pattern - Test patterns for test testing
288 * @TEST_PRBS7: Output of the PRBS7 (x^7 + x^6 + 1) polynomial
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
348 * struct zynqmp_dp - Xilinx DisplayPort core
350 * @dpsub: Display subsystem
390 struct zynqmp_dpsub *dpsub; member
418 writel(val, dp->iomem + offset); in zynqmp_dp_write()
423 return readl(dp->iomem + offset); in zynqmp_dp_read()
436 /* -----------------------------------------------------------------------------
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
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()
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
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
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
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
585 * Check if PHY is ready. If PHY is not ready, wait 1ms to check for 100 times.
588 * Return: 0 if PHY is ready, or -ENODEV if PHY is not ready.
594 ready = (1 << dp->num_lanes) - 1; in zynqmp_dp_phy_ready()
596 /* Wait for 100 * 1ms. This should be enough time for PHY to be ready */ 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
641 * Return: Current link rate code, or -EINVAL.
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()
670 for (lane_cnt = 1; lane_cnt <= max_lanes; lane_cnt <<= 1) { 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
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
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()
746 phy_configure(dp->phy[i], &opts); in zynqmp_dp_update_vs_emph()
755 * zynqmp_dp_link_train_cr - Train clock recovery
764 u8 lane_cnt = dp->mode.lane_cnt; 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()
815 return -EIO; in zynqmp_dp_link_train_cr()
821 * zynqmp_dp_link_train_ce - Train channel equalization
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()
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()
865 return -EIO; in zynqmp_dp_link_train_ce()
871 * zynqmp_dp_setup() - Set up major link parameters
876 * @downspread: Enable spread-spectrum clocking
878 * Return: 0 on success, or -errno on failure
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()
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()
940 * zynqmp_dp_train - Train the link
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()
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()
981 * zynqmp_dp_train_loop - Downshift the link rate during training
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()
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 /* -----------------------------------------------------------------------------
1019 * zynqmp_dp_aux_cmd_submit - Submit aux command
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
1049 return -EBUSY; in zynqmp_dp_aux_cmd_submit()
1051 reinit_completion(&dp->aux_done); in zynqmp_dp_aux_cmd_submit()
1063 reg |= (bytes - 1) << ZYNQMP_DP_AUX_COMMAND_BYTES_SHIFT; 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()
1074 return -ETIMEDOUT; in zynqmp_dp_aux_cmd_submit()
1085 return -EIO; in zynqmp_dp_aux_cmd_submit()
1103 iter = iter ? iter : 1; 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
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()
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
1185 drm_dp_aux_unregister(&dp->aux); in zynqmp_dp_aux_cleanup()
1191 /* -----------------------------------------------------------------------------
1196 * zynqmp_dp_update_misc - Write the misc registers
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
1217 * Return: 0 on success, or -EINVAL.
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()
1248 num_colors = 1; 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
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()
1327 init_wait = tu - avg_bytes_per_tu / 1000; in zynqmp_dp_encoder_mode_set_transfer_unit()
1333 * zynqmp_dp_encoder_mode_set_stream - Configure the main stream
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()
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()
1354 mode->hsync_end - mode->hsync_start); 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()
1360 mode->htotal - mode->hsync_start); 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()
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()
1379 /* -----------------------------------------------------------------------------
1386 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, num_channels - 1); in zynqmp_dp_audio_set_channels()
1391 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1); in zynqmp_dp_audio_enable()
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()
1417 /* -----------------------------------------------------------------------------
1422 * zynqmp_dp_disp_connected_live_layer - Return the first connected live layer
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()
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()
1476 zynqmp_disp_disable(dp->dpsub->disp); in zynqmp_dp_disp_disable()
1480 /* -----------------------------------------------------------------------------
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()
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()
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()
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()
1605 dp->enabled = true; 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()
1613 if (ret == 1) in zynqmp_dp_bridge_atomic_enable()
1620 if (ret != 1) in zynqmp_dp_bridge_atomic_enable()
1621 dev_dbg(dp->dev, "DP aux failed\n"); in zynqmp_dp_bridge_atomic_enable()
1626 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); in zynqmp_dp_bridge_atomic_enable()
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()
1638 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3); 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()
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()
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()
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()
1727 mutex_lock(&dp->lock); in zynqmp_dp_bridge_detect()
1729 mutex_unlock(&dp->lock); in zynqmp_dp_bridge_detect()
1739 return drm_edid_read_ddc(connector, &dp->aux.ddc); in zynqmp_dp_bridge_edid_read()
1771 /* -----------------------------------------------------------------------------
1776 * zynqmp_dp_set_test_pattern() - Configure the link for a test pattern
1796 train_pattern = 1; in zynqmp_dp_set_test_pattern()
1818 (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); in zynqmp_dp_set_test_pattern()
1829 WARN_ON_ONCE(1); 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()
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()
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()
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()
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()
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()
1957 mutex_unlock(&dp->lock); in zynqmp_dp_enhanced_set()
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()
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()
1984 mutex_unlock(&dp->lock); in zynqmp_dp_downspread_set()
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()
2007 mutex_lock(&dp->lock); 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()
2031 dev_warn(dp->dev, "could not clear test pattern: %d\n", 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()
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()
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()
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()
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()
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()
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()
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()
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()
2203 mutex_unlock(&dp->lock); in zynqmp_dp_lanes_set()
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()
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()
2244 mutex_unlock(&dp->lock); in zynqmp_dp_rate_set()
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()
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()
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()
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()
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()
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
2379 * zynqmp_dp_disable_vblank - Disable vblank
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()
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()
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()
2431 mutex_unlock(&dp->lock); in zynqmp_dp_hpd_irq_work_func()
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 /* -----------------------------------------------------------------------------
2481 int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) in zynqmp_dp_probe() argument
2483 struct platform_device *pdev = to_platform_device(dpsub->dev); 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()
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()
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()
2562 zynqmp_dp_write(dp, ZYNQMP_DP_FORCE_SCRAMBLER_RESET, 1); 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()
2597 void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) in zynqmp_dp_remove() argument
2599 struct zynqmp_dp *dp = dpsub->dp; 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()
2612 mutex_destroy(&dp->lock); in zynqmp_dp_remove()