Lines Matching full:dp
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)");
274 * @misc0: misc0 configuration (per DP v1.2 spec)
275 * @misc1: misc1 configuration (per DP v1.2 spec)
339 * @dp: DisplayPort IP core structure
343 struct zynqmp_dp *dp; member
355 * @bridge: DRM bridge for the DP encoder
362 * @phy: PHY handles for DP lanes
369 * @dpcd: DP configuration data from currently connected sink device
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()
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()
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()
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()
532 * @dp: DisplayPort IP core structure
536 * found. The caller can check dp->num_lanes to check how many PHYs were found.
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()
558 if (dp->num_lanes) in zynqmp_dp_phy_probe()
561 dev_err(dp->dev, "no PHY found\n"); 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()
583 * @dp: DisplayPort IP core structure
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()
632 * @dp: DisplayPort IP core structure
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()
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()
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()
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()
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()
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()
872 * @dp: DisplayPort IP core structure
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()
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()
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()
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()
1020 * @dp: DisplayPort IP core structure
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()
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()
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()
1072 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); 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()
1088 buf[i] = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_DATA); in zynqmp_dp_aux_cmd_submit()
1097 struct zynqmp_dp *dp = container_of(aux, struct zynqmp_dp, aux); in zynqmp_dp_aux_transfer() local
1106 ret = zynqmp_dp_aux_cmd_submit(dp, msg->request, msg->address, in zynqmp_dp_aux_transfer()
1110 dev_vdbg(dp->dev, "aux %d retries\n", i); 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()
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()
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
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()
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()
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()
1210 * @dp: DisplayPort IP core structure
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()
1252 dev_err(dp->dev, "Invalid colormetry in DT\n"); in zynqmp_dp_set_format()
1257 dev_warn(dp->dev, in zynqmp_dp_set_format()
1282 dev_warn(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", in zynqmp_dp_set_format()
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()
1329 zynqmp_dp_write(dp, ZYNQMP_DP_INIT_WAIT, init_wait); in zynqmp_dp_encoder_mode_set_transfer_unit()
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()
1353 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1355 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSWIDTH, 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()
1361 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSTART, 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()
1376 zynqmp_dp_write(dp, ZYNQMP_DP_USER_DATA_COUNT_PER_LANE, reg); in zynqmp_dp_encoder_mode_set_stream()
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()
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(state, &dp->bridge); in zynqmp_dp_disp_enable()
1458 if (layer == dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX]) in zynqmp_dp_disp_enable()
1459 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, true, 255); in zynqmp_dp_disp_enable()
1461 zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, false, 0); in zynqmp_dp_disp_enable()
1463 zynqmp_disp_enable(dp->dpsub->disp); in zynqmp_dp_disp_enable()
1466 static void zynqmp_dp_disp_disable(struct zynqmp_dp *dp, in zynqmp_dp_disp_disable() argument
1471 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_disp_disable()
1475 zynqmp_disp_disable(dp->dpsub->disp); in zynqmp_dp_disp_disable()
1487 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_attach() local
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(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
1530 dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", in zynqmp_dp_bridge_mode_valid()
1537 scoped_guard(mutex, &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, in zynqmp_dp_bridge_mode_valid()
1540 dp->config.bpp); 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()
1554 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_enable() local
1564 pm_runtime_get_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1566 guard(mutex)(&dp->lock); in zynqmp_dp_bridge_atomic_enable()
1567 zynqmp_dp_disp_enable(dp, state); in zynqmp_dp_bridge_atomic_enable()
1581 zynqmp_dp_set_format(dp, &connector->display_info, in zynqmp_dp_bridge_atomic_enable()
1585 rate = zynqmp_dp_max_rate(dp->link_config.max_rate, in zynqmp_dp_bridge_atomic_enable()
1586 dp->link_config.max_lanes, dp->config.bpp); in zynqmp_dp_bridge_atomic_enable()
1588 dev_err(dp->dev, "mode %s has too high pixel rate\n", in zynqmp_dp_bridge_atomic_enable()
1594 ret = zynqmp_dp_mode_configure(dp, adjusted_mode->clock, 0); in zynqmp_dp_bridge_atomic_enable()
1596 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_enable()
1600 zynqmp_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1601 zynqmp_dp_encoder_mode_set_stream(dp, adjusted_mode); in zynqmp_dp_bridge_atomic_enable()
1604 dp->enabled = true; in zynqmp_dp_bridge_atomic_enable()
1605 zynqmp_dp_update_misc(dp); in zynqmp_dp_bridge_atomic_enable()
1607 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0); in zynqmp_dp_bridge_atomic_enable()
1608 if (dp->status == connector_status_connected) { in zynqmp_dp_bridge_atomic_enable()
1610 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, in zynqmp_dp_bridge_atomic_enable()
1620 dev_dbg(dp->dev, "DP aux failed\n"); in zynqmp_dp_bridge_atomic_enable()
1622 zynqmp_dp_train_loop(dp); in zynqmp_dp_bridge_atomic_enable()
1623 zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, in zynqmp_dp_bridge_atomic_enable()
1625 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); in zynqmp_dp_bridge_atomic_enable()
1633 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_disable() local
1635 mutex_lock(&dp->lock); in zynqmp_dp_bridge_atomic_disable()
1636 dp->enabled = false; in zynqmp_dp_bridge_atomic_disable()
1637 cancel_work(&dp->hpd_work); in zynqmp_dp_bridge_atomic_disable()
1638 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); in zynqmp_dp_bridge_atomic_disable()
1639 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in zynqmp_dp_bridge_atomic_disable()
1640 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_bridge_atomic_disable()
1643 zynqmp_dp_disp_disable(dp, old_bridge_state); in zynqmp_dp_bridge_atomic_disable()
1644 mutex_unlock(&dp->lock); in zynqmp_dp_bridge_atomic_disable()
1646 pm_runtime_put_sync(dp->dev); in zynqmp_dp_bridge_atomic_disable()
1656 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_atomic_check() local
1662 * ZynqMP DP requires horizontal backporch to be greater than 12. in zynqmp_dp_bridge_atomic_check()
1669 dev_dbg(dp->dev, "hbackporch adjusted: %d to %d", in zynqmp_dp_bridge_atomic_check()
1680 static enum drm_connector_status __zynqmp_dp_bridge_detect(struct zynqmp_dp *dp) in __zynqmp_dp_bridge_detect() argument
1682 struct zynqmp_dp_link_config *link_config = &dp->link_config; in __zynqmp_dp_bridge_detect()
1686 lockdep_assert_held(&dp->lock); in __zynqmp_dp_bridge_detect()
1693 state = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in __zynqmp_dp_bridge_detect()
1700 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd, in __zynqmp_dp_bridge_detect()
1701 sizeof(dp->dpcd)); in __zynqmp_dp_bridge_detect()
1703 dev_dbg(dp->dev, "DPCD read failed"); in __zynqmp_dp_bridge_detect()
1708 drm_dp_max_link_rate(dp->dpcd), in __zynqmp_dp_bridge_detect()
1711 drm_dp_max_lane_count(dp->dpcd), in __zynqmp_dp_bridge_detect()
1712 dp->num_lanes); in __zynqmp_dp_bridge_detect()
1714 dp->status = connector_status_connected; in __zynqmp_dp_bridge_detect()
1719 dp->status = connector_status_disconnected; in __zynqmp_dp_bridge_detect()
1726 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_detect() local
1728 guard(mutex)(&dp->lock); in zynqmp_dp_bridge_detect()
1729 return __zynqmp_dp_bridge_detect(dp); in zynqmp_dp_bridge_detect()
1735 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_edid_read() local
1737 return drm_edid_read_ddc(connector, &dp->aux.ddc); in zynqmp_dp_bridge_edid_read()
1759 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_get_input_bus_fmts() local
1762 layer = zynqmp_dp_disp_connected_live_layer(dp); in zynqmp_dp_bridge_get_input_bus_fmts()
1775 * @dp: DisplayPort IP core structure
1781 static int zynqmp_dp_set_test_pattern(struct zynqmp_dp *dp, in zynqmp_dp_set_test_pattern() argument
1815 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_1, in zynqmp_dp_set_test_pattern()
1817 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_2, in zynqmp_dp_set_test_pattern()
1819 zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_3, in zynqmp_dp_set_test_pattern()
1833 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, !scramble); in zynqmp_dp_set_test_pattern()
1834 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, train_pattern); in zynqmp_dp_set_test_pattern()
1835 zynqmp_dp_write(dp, ZYNQMP_DP_LINK_QUAL_PATTERN_SET, link_pattern); in zynqmp_dp_set_test_pattern()
1836 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMIT_PRBS7, pattern == TEST_PRBS7); in zynqmp_dp_set_test_pattern()
1843 if (dp->dpcd[DP_DPCD_REV] < 0x12) { in zynqmp_dp_set_test_pattern()
1845 dev_warn(dp->dev, in zynqmp_dp_set_test_pattern()
1854 ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_QUAL_LANE0_SET, in zynqmp_dp_set_test_pattern()
1860 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, dpcd_train); in zynqmp_dp_set_test_pattern()
1864 static int zynqmp_dp_test_setup(struct zynqmp_dp *dp) in zynqmp_dp_test_setup() argument
1866 return zynqmp_dp_setup(dp, dp->test.bw_code, dp->test.link_cnt, in zynqmp_dp_test_setup()
1867 dp->test.enhanced, dp->test.downspread); in zynqmp_dp_test_setup()
1873 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_pattern_read() local
1877 scoped_guard(mutex, &dp->lock) in zynqmp_dp_pattern_read()
1879 test_pattern_str[dp->test.pattern]); in zynqmp_dp_pattern_read()
1888 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_pattern_write() local
1903 mutex_lock(&dp->lock); in zynqmp_dp_pattern_write()
1904 dp->test.pattern = pattern; in zynqmp_dp_pattern_write()
1905 if (dp->test.active) in zynqmp_dp_pattern_write()
1906 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_pattern_write()
1907 dp->test.custom) ?: ret; in zynqmp_dp_pattern_write()
1908 mutex_unlock(&dp->lock); in zynqmp_dp_pattern_write()
1922 struct zynqmp_dp *dp = data; in zynqmp_dp_enhanced_get() local
1924 guard(mutex)(&dp->lock); in zynqmp_dp_enhanced_get()
1925 *val = dp->test.enhanced; in zynqmp_dp_enhanced_get()
1931 struct zynqmp_dp *dp = data; in zynqmp_dp_enhanced_set() local
1933 guard(mutex)(&dp->lock); in zynqmp_dp_enhanced_set()
1934 dp->test.enhanced = val; in zynqmp_dp_enhanced_set()
1935 return dp->test.active ? zynqmp_dp_test_setup(dp) : 0; in zynqmp_dp_enhanced_set()
1943 struct zynqmp_dp *dp = data; in zynqmp_dp_downspread_get() local
1945 guard(mutex)(&dp->lock); in zynqmp_dp_downspread_get()
1946 *val = dp->test.downspread; in zynqmp_dp_downspread_get()
1952 struct zynqmp_dp *dp = data; in zynqmp_dp_downspread_set() local
1954 guard(mutex)(&dp->lock); in zynqmp_dp_downspread_set()
1955 dp->test.downspread = val; in zynqmp_dp_downspread_set()
1957 return dp->test.active ? zynqmp_dp_test_setup(dp) : 0; in zynqmp_dp_downspread_set()
1965 struct zynqmp_dp *dp = data; in zynqmp_dp_active_get() local
1967 guard(mutex)(&dp->lock); in zynqmp_dp_active_get()
1968 *val = dp->test.active; in zynqmp_dp_active_get()
1974 struct zynqmp_dp *dp = data; in zynqmp_dp_active_set() local
1977 guard(mutex)(&dp->lock); in zynqmp_dp_active_set()
1980 ret = zynqmp_dp_test_setup(dp); in zynqmp_dp_active_set()
1985 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_active_set()
1986 dp->test.custom); in zynqmp_dp_active_set()
1990 ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_active_set()
1994 dp->test.active = true; in zynqmp_dp_active_set()
1998 dp->test.active = false; in zynqmp_dp_active_set()
1999 err = zynqmp_dp_set_test_pattern(dp, TEST_VIDEO, NULL); in zynqmp_dp_active_set()
2001 dev_warn(dp->dev, "could not clear test pattern: %d\n", in zynqmp_dp_active_set()
2003 zynqmp_dp_train_loop(dp); in zynqmp_dp_active_set()
2015 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_custom_read() local
2018 mutex_lock(&dp->lock); in zynqmp_dp_custom_read()
2019 ret = simple_read_from_buffer(user_buf, count, ppos, &dp->test.custom, in zynqmp_dp_custom_read()
2020 sizeof(dp->test.custom)); in zynqmp_dp_custom_read()
2021 mutex_unlock(&dp->lock); in zynqmp_dp_custom_read()
2029 struct zynqmp_dp *dp = file->private_data; in zynqmp_dp_custom_write() local
2031 char buf[sizeof(dp->test.custom)]; in zynqmp_dp_custom_write()
2037 mutex_lock(&dp->lock); in zynqmp_dp_custom_write()
2038 memcpy(dp->test.custom, buf, ret); in zynqmp_dp_custom_write()
2039 if (dp->test.active) in zynqmp_dp_custom_write()
2040 ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, in zynqmp_dp_custom_write()
2041 dp->test.custom) ?: ret; in zynqmp_dp_custom_write()
2042 mutex_unlock(&dp->lock); in zynqmp_dp_custom_write()
2056 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_swing_get() local
2058 guard(mutex)(&dp->lock); in zynqmp_dp_swing_get()
2059 *val = dp->test.train_set[priv->lane] & DP_TRAIN_VOLTAGE_SWING_MASK; in zynqmp_dp_swing_get()
2066 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_swing_set() local
2067 u8 *train_set = &dp->test.train_set[priv->lane]; in zynqmp_dp_swing_set()
2072 guard(mutex)(&dp->lock); in zynqmp_dp_swing_set()
2079 if (dp->test.active) in zynqmp_dp_swing_set()
2080 return zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_swing_set()
2091 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_preemphasis_get() local
2093 guard(mutex)(&dp->lock); in zynqmp_dp_preemphasis_get()
2095 dp->test.train_set[priv->lane]); in zynqmp_dp_preemphasis_get()
2102 struct zynqmp_dp *dp = priv->dp; in zynqmp_dp_preemphasis_set() local
2103 u8 *train_set = &dp->test.train_set[priv->lane]; in zynqmp_dp_preemphasis_set()
2108 guard(mutex)(&dp->lock); in zynqmp_dp_preemphasis_set()
2115 if (dp->test.active) in zynqmp_dp_preemphasis_set()
2116 return zynqmp_dp_update_vs_emph(dp, dp->test.train_set); in zynqmp_dp_preemphasis_set()
2126 struct zynqmp_dp *dp = data; in zynqmp_dp_lanes_get() local
2128 guard(mutex)(&dp->lock); in zynqmp_dp_lanes_get()
2129 *val = dp->test.link_cnt; in zynqmp_dp_lanes_get()
2135 struct zynqmp_dp *dp = data; in zynqmp_dp_lanes_set() local
2140 guard(mutex)(&dp->lock); in zynqmp_dp_lanes_set()
2141 if (val > dp->num_lanes) in zynqmp_dp_lanes_set()
2144 dp->test.link_cnt = val; in zynqmp_dp_lanes_set()
2145 return dp->test.active ? zynqmp_dp_test_setup(dp) : 0; in zynqmp_dp_lanes_set()
2153 struct zynqmp_dp *dp = data; in zynqmp_dp_rate_get() local
2155 guard(mutex)(&dp->lock); in zynqmp_dp_rate_get()
2156 *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000ULL; in zynqmp_dp_rate_get()
2162 struct zynqmp_dp *dp = data; in zynqmp_dp_rate_set() local
2178 guard(mutex)(&dp->lock); in zynqmp_dp_rate_set()
2179 dp->test.bw_code = bw_code; in zynqmp_dp_rate_set()
2180 return dp->test.active ? zynqmp_dp_test_setup(dp) : 0; in zynqmp_dp_rate_set()
2188 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_aux_errors_get() local
2190 guard(mutex)(&dp->lock); in zynqmp_dp_ignore_aux_errors_get()
2191 *val = dp->ignore_aux_errors; in zynqmp_dp_ignore_aux_errors_get()
2197 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_aux_errors_set() local
2202 guard(mutex)(&dp->lock); in zynqmp_dp_ignore_aux_errors_set()
2203 dp->ignore_aux_errors = val; in zynqmp_dp_ignore_aux_errors_set()
2213 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_hpd_get() local
2215 guard(mutex)(&dp->lock); in zynqmp_dp_ignore_hpd_get()
2216 *val = dp->ignore_hpd; in zynqmp_dp_ignore_hpd_get()
2222 struct zynqmp_dp *dp = data; in zynqmp_dp_ignore_hpd_set() local
2227 guard(mutex)(&dp->lock); in zynqmp_dp_ignore_hpd_set()
2228 dp->ignore_hpd = val; in zynqmp_dp_ignore_hpd_set()
2238 struct zynqmp_dp *dp = bridge_to_dp(bridge); in zynqmp_dp_bridge_debugfs_init() local
2242 dp->test.bw_code = DP_LINK_BW_5_4; in zynqmp_dp_bridge_debugfs_init()
2243 dp->test.link_cnt = dp->num_lanes; in zynqmp_dp_bridge_debugfs_init()
2247 debugfs_create_file(#name, 0600, test, dp, &fops_zynqmp_dp_##name) in zynqmp_dp_bridge_debugfs_init()
2258 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_bridge_debugfs_init()
2262 dp->debugfs_train_set[i].dp = dp; in zynqmp_dp_bridge_debugfs_init()
2263 dp->debugfs_train_set[i].lane = i; in zynqmp_dp_bridge_debugfs_init()
2267 &dp->debugfs_train_set[i], in zynqmp_dp_bridge_debugfs_init()
2272 &dp->debugfs_train_set[i], in zynqmp_dp_bridge_debugfs_init()
2299 * @dp: DisplayPort IP core structure
2303 void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_enable_vblank() argument
2305 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_enable_vblank()
2310 * @dp: DisplayPort IP core structure
2314 void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_disable_vblank() argument
2316 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_disable_vblank()
2321 struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work); in zynqmp_dp_hpd_work_func() local
2324 scoped_guard(mutex, &dp->lock) { in zynqmp_dp_hpd_work_func()
2325 if (dp->ignore_hpd) in zynqmp_dp_hpd_work_func()
2328 status = __zynqmp_dp_bridge_detect(dp); in zynqmp_dp_hpd_work_func()
2331 drm_bridge_hpd_notify(&dp->bridge, status); in zynqmp_dp_hpd_work_func()
2336 struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, in zynqmp_dp_hpd_irq_work_func() local
2341 guard(mutex)(&dp->lock); in zynqmp_dp_hpd_irq_work_func()
2342 if (dp->ignore_hpd) in zynqmp_dp_hpd_irq_work_func()
2345 err = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, in zynqmp_dp_hpd_irq_work_func()
2348 dev_dbg_ratelimited(dp->dev, in zynqmp_dp_hpd_irq_work_func()
2352 !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || in zynqmp_dp_hpd_irq_work_func()
2353 !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { in zynqmp_dp_hpd_irq_work_func()
2354 zynqmp_dp_train_loop(dp); in zynqmp_dp_hpd_irq_work_func()
2361 struct zynqmp_dp *dp = (struct zynqmp_dp *)data; in zynqmp_dp_irq_handler() local
2364 status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS); in zynqmp_dp_irq_handler()
2366 zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); in zynqmp_dp_irq_handler()
2367 mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK); in zynqmp_dp_irq_handler()
2380 dev_dbg_ratelimited(dp->dev, "underflow interrupt\n"); in zynqmp_dp_irq_handler()
2382 dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); in zynqmp_dp_irq_handler()
2385 zynqmp_dpsub_drm_handle_vblank(dp->dpsub); in zynqmp_dp_irq_handler()
2388 schedule_work(&dp->hpd_work); in zynqmp_dp_irq_handler()
2391 schedule_work(&dp->hpd_irq_work); in zynqmp_dp_irq_handler()
2394 complete(&dp->aux_done); in zynqmp_dp_irq_handler()
2397 complete(&dp->aux_done); in zynqmp_dp_irq_handler()
2410 struct zynqmp_dp *dp; in zynqmp_dp_probe() local
2413 dp = devm_drm_bridge_alloc(&pdev->dev, struct zynqmp_dp, bridge, &zynqmp_dp_bridge_funcs); in zynqmp_dp_probe()
2414 if (IS_ERR(dp)) in zynqmp_dp_probe()
2415 return PTR_ERR(dp); in zynqmp_dp_probe()
2417 dp->dev = &pdev->dev; in zynqmp_dp_probe()
2418 dp->dpsub = dpsub; in zynqmp_dp_probe()
2419 dp->status = connector_status_disconnected; in zynqmp_dp_probe()
2420 mutex_init(&dp->lock); in zynqmp_dp_probe()
2421 init_completion(&dp->aux_done); in zynqmp_dp_probe()
2423 INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); in zynqmp_dp_probe()
2424 INIT_WORK(&dp->hpd_irq_work, zynqmp_dp_hpd_irq_work_func); in zynqmp_dp_probe()
2427 dp->iomem = devm_platform_ioremap_resource_byname(pdev, "dp"); in zynqmp_dp_probe()
2428 if (IS_ERR(dp->iomem)) in zynqmp_dp_probe()
2429 return PTR_ERR(dp->iomem); in zynqmp_dp_probe()
2431 dp->irq = platform_get_irq(pdev, 0); in zynqmp_dp_probe()
2432 if (dp->irq < 0) in zynqmp_dp_probe()
2433 return dp->irq; in zynqmp_dp_probe()
2435 dp->reset = devm_reset_control_get(dp->dev, NULL); in zynqmp_dp_probe()
2436 if (IS_ERR(dp->reset)) in zynqmp_dp_probe()
2437 return dev_err_probe(dp->dev, PTR_ERR(dp->reset), in zynqmp_dp_probe()
2440 ret = zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
2444 ret = zynqmp_dp_reset(dp, false); in zynqmp_dp_probe()
2448 ret = zynqmp_dp_phy_probe(dp); in zynqmp_dp_probe()
2453 bridge = &dp->bridge; in zynqmp_dp_probe()
2457 bridge->of_node = dp->dev->of_node; in zynqmp_dp_probe()
2464 ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 5, 0, NULL, in zynqmp_dp_probe()
2465 &dp->next_bridge); in zynqmp_dp_probe()
2470 dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK; in zynqmp_dp_probe()
2471 zynqmp_dp_set_format(dp, NULL, ZYNQMP_DPSUB_FORMAT_RGB, 8); in zynqmp_dp_probe()
2473 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_probe()
2475 zynqmp_dp_set(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_probe()
2476 zynqmp_dp_write(dp, ZYNQMP_DP_FORCE_SCRAMBLER_RESET, 1); in zynqmp_dp_probe()
2477 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_probe()
2478 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_probe()
2480 ret = zynqmp_dp_phy_init(dp); in zynqmp_dp_probe()
2484 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1); in zynqmp_dp_probe()
2490 ret = devm_request_irq(dp->dev, dp->irq, zynqmp_dp_irq_handler, in zynqmp_dp_probe()
2491 IRQF_SHARED, dev_name(dp->dev), dp); in zynqmp_dp_probe()
2495 dpsub->dp = dp; in zynqmp_dp_probe()
2497 dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n", in zynqmp_dp_probe()
2498 dp->num_lanes); in zynqmp_dp_probe()
2503 zynqmp_dp_phy_exit(dp); in zynqmp_dp_probe()
2505 zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
2511 struct zynqmp_dp *dp = dpsub->dp; in zynqmp_dp_remove() local
2513 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); in zynqmp_dp_remove()
2514 devm_free_irq(dp->dev, dp->irq, dp); in zynqmp_dp_remove()
2516 cancel_work_sync(&dp->hpd_irq_work); in zynqmp_dp_remove()
2517 cancel_work_sync(&dp->hpd_work); in zynqmp_dp_remove()
2519 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_remove()
2520 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_remove()
2522 zynqmp_dp_phy_exit(dp); in zynqmp_dp_remove()
2523 zynqmp_dp_reset(dp, true); in zynqmp_dp_remove()
2524 mutex_destroy(&dp->lock); in zynqmp_dp_remove()