Lines Matching full:dp
41 MODULE_PARM_DESC(aux_timeout_ms, "DP aux timeout value in msec (default: 50)");
48 MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)");
268 * @misc0: misc0 configuration (per DP v1.2 spec)
269 * @misc1: misc1 configuration (per DP v1.2 spec)
290 * @phy: PHY handles for DP lanes
295 * @dpcd: DP configuration data from currently connected sink device
334 static void zynqmp_dp_write(struct zynqmp_dp *dp, int offset, u32 val) in zynqmp_dp_write() argument
336 writel(val, dp->iomem + offset); in zynqmp_dp_write()
339 static u32 zynqmp_dp_read(struct zynqmp_dp *dp, int offset) in zynqmp_dp_read() argument
341 return readl(dp->iomem + offset); in zynqmp_dp_read()
344 static void zynqmp_dp_clr(struct zynqmp_dp *dp, int offset, u32 clr) in zynqmp_dp_clr() argument
346 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) & ~clr); in zynqmp_dp_clr()
349 static void zynqmp_dp_set(struct zynqmp_dp *dp, int offset, u32 set) in zynqmp_dp_set() argument
351 zynqmp_dp_write(dp, offset, zynqmp_dp_read(dp, offset) | set); in zynqmp_dp_set()
360 static int zynqmp_dp_reset(struct zynqmp_dp *dp, bool assert) in zynqmp_dp_reset() argument
365 reset_control_assert(dp->reset); in zynqmp_dp_reset()
367 reset_control_deassert(dp->reset); in zynqmp_dp_reset()
372 bool status = !!reset_control_status(dp->reset); in zynqmp_dp_reset()
380 dev_err(dp->dev, "reset %s timeout\n", assert ? "assert" : "deassert"); in zynqmp_dp_reset()
386 * @dp: DisplayPort IP core structure
393 static int zynqmp_dp_phy_init(struct zynqmp_dp *dp) in zynqmp_dp_phy_init() argument
398 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_init()
399 ret = phy_init(dp->phy[i]); in zynqmp_dp_phy_init()
401 dev_err(dp->dev, "failed to init phy lane %d\n", i); in zynqmp_dp_phy_init()
406 zynqmp_dp_clr(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_phy_init()
412 for (i = dp->num_lanes - 1; i >= 0; i--) { in zynqmp_dp_phy_init()
413 ret = phy_power_on(dp->phy[i]); in zynqmp_dp_phy_init()
415 dev_err(dp->dev, "failed to power on phy lane %d\n", i); in zynqmp_dp_phy_init()
425 * @dp: DisplayPort IP core structure
429 static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp) in zynqmp_dp_phy_exit() argument
434 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
435 ret = phy_power_off(dp->phy[i]); in zynqmp_dp_phy_exit()
437 dev_err(dp->dev, "failed to power off phy(%d) %d\n", i, in zynqmp_dp_phy_exit()
441 for (i = 0; i < dp->num_lanes; i++) { in zynqmp_dp_phy_exit()
442 ret = phy_exit(dp->phy[i]); in zynqmp_dp_phy_exit()
444 dev_err(dp->dev, "failed to exit phy(%d) %d\n", i, ret); in zynqmp_dp_phy_exit()
450 * @dp: DisplayPort IP core structure
454 * found. The caller can check dp->num_lanes to check how many PHYs were found.
462 static int zynqmp_dp_phy_probe(struct zynqmp_dp *dp) in zynqmp_dp_phy_probe() argument
470 snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i); in zynqmp_dp_phy_probe()
471 phy = devm_phy_get(dp->dev, phy_name); in zynqmp_dp_phy_probe()
476 if (dp->num_lanes) in zynqmp_dp_phy_probe()
479 dev_err(dp->dev, "no PHY found\n"); in zynqmp_dp_phy_probe()
486 dev_err(dp->dev, "failed to get PHY lane %u\n", in zynqmp_dp_phy_probe()
492 dp->phy[i] = phy; in zynqmp_dp_phy_probe()
493 dp->num_lanes++; in zynqmp_dp_phy_probe()
501 * @dp: DisplayPort IP core structure
508 static int zynqmp_dp_phy_ready(struct zynqmp_dp *dp) in zynqmp_dp_phy_ready() argument
512 ready = (1 << dp->num_lanes) - 1; in zynqmp_dp_phy_ready()
516 reg = zynqmp_dp_read(dp, ZYNQMP_DP_PHY_STATUS); in zynqmp_dp_phy_ready()
521 dev_err(dp->dev, "PHY isn't ready\n"); in zynqmp_dp_phy_ready()
550 * @dp: DisplayPort IP core structure
561 static int zynqmp_dp_mode_configure(struct zynqmp_dp *dp, int pclock, in zynqmp_dp_mode_configure() argument
564 int max_rate = dp->link_config.max_rate; in zynqmp_dp_mode_configure()
566 u8 max_lanes = dp->link_config.max_lanes; in zynqmp_dp_mode_configure()
568 u8 bpp = dp->config.bpp; in zynqmp_dp_mode_configure()
580 dev_err(dp->dev, "can't downshift. already lowest link rate\n"); in zynqmp_dp_mode_configure()
595 dp->mode.bw_code = bw_code; in zynqmp_dp_mode_configure()
596 dp->mode.lane_cnt = lane_cnt; in zynqmp_dp_mode_configure()
597 dp->mode.pclock = pclock; in zynqmp_dp_mode_configure()
598 return dp->mode.bw_code; in zynqmp_dp_mode_configure()
602 dev_err(dp->dev, "failed to configure link values\n"); in zynqmp_dp_mode_configure()
609 * @dp: DisplayPort IP core structure
612 static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp, in zynqmp_dp_adjust_train() argument
615 u8 *train_set = dp->train_set; in zynqmp_dp_adjust_train()
619 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_adjust_train()
636 for (i = 0; i < dp->mode.lane_cnt; i++) in zynqmp_dp_adjust_train()
642 * @dp: DisplayPort IP core structure
650 static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp) in zynqmp_dp_update_vs_emph() argument
655 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->train_set, in zynqmp_dp_update_vs_emph()
656 dp->mode.lane_cnt); in zynqmp_dp_update_vs_emph()
660 for (i = 0; i < dp->mode.lane_cnt; i++) { in zynqmp_dp_update_vs_emph()
663 u8 train = dp->train_set[i]; in zynqmp_dp_update_vs_emph()
665 opts.dp.voltage[0] = (train & DP_TRAIN_VOLTAGE_SWING_MASK) in zynqmp_dp_update_vs_emph()
667 opts.dp.pre[0] = (train & DP_TRAIN_PRE_EMPHASIS_MASK) in zynqmp_dp_update_vs_emph()
670 phy_configure(dp->phy[i], &opts); in zynqmp_dp_update_vs_emph()
672 zynqmp_dp_write(dp, reg, 0x2); in zynqmp_dp_update_vs_emph()
680 * @dp: DisplayPort IP core structure
685 static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp) in zynqmp_dp_link_train_cr() argument
688 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_cr()
694 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
696 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_cr()
707 ret = zynqmp_dp_update_vs_emph(dp); in zynqmp_dp_link_train_cr()
711 drm_dp_link_train_clock_recovery_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_cr()
712 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_cr()
721 if (!(dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED)) in zynqmp_dp_link_train_cr()
726 if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == vs) in zynqmp_dp_link_train_cr()
734 vs = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; in zynqmp_dp_link_train_cr()
735 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_cr()
746 * @dp: DisplayPort IP core structure
751 static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp) in zynqmp_dp_link_train_ce() argument
754 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_link_train_ce()
759 if (dp->dpcd[DP_DPCD_REV] >= DP_V1_2 && in zynqmp_dp_link_train_ce()
760 dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) in zynqmp_dp_link_train_ce()
765 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, pat); in zynqmp_dp_link_train_ce()
766 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_link_train_ce()
772 ret = zynqmp_dp_update_vs_emph(dp); in zynqmp_dp_link_train_ce()
776 drm_dp_link_train_channel_eq_delay(&dp->aux, dp->dpcd); in zynqmp_dp_link_train_ce()
777 ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); in zynqmp_dp_link_train_ce()
785 zynqmp_dp_adjust_train(dp, link_status); in zynqmp_dp_link_train_ce()
796 * @dp: DisplayPort IP core structure
800 static int zynqmp_dp_train(struct zynqmp_dp *dp) in zynqmp_dp_train() argument
803 u8 bw_code = dp->mode.bw_code; in zynqmp_dp_train()
804 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_train()
809 zynqmp_dp_write(dp, ZYNQMP_DP_LANE_COUNT_SET, lane_cnt); in zynqmp_dp_train()
810 enhanced = drm_dp_enhanced_frame_cap(dp->dpcd); in zynqmp_dp_train()
812 zynqmp_dp_write(dp, ZYNQMP_DP_ENHANCED_FRAME_EN, 1); in zynqmp_dp_train()
816 if (dp->dpcd[3] & 0x1) { in zynqmp_dp_train()
817 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 1); in zynqmp_dp_train()
818 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, in zynqmp_dp_train()
821 zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 0); in zynqmp_dp_train()
822 drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, 0); in zynqmp_dp_train()
825 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, aux_lane_cnt); in zynqmp_dp_train()
827 dev_err(dp->dev, "failed to set lane count\n"); in zynqmp_dp_train()
831 ret = drm_dp_dpcd_writeb(&dp->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, in zynqmp_dp_train()
834 dev_err(dp->dev, "failed to set ANSI 8B/10B encoding\n"); in zynqmp_dp_train()
838 ret = drm_dp_dpcd_writeb(&dp->aux, DP_LINK_BW_SET, bw_code); in zynqmp_dp_train()
840 dev_err(dp->dev, "failed to set DP bandwidth\n"); in zynqmp_dp_train()
844 zynqmp_dp_write(dp, ZYNQMP_DP_LINK_BW_SET, bw_code); in zynqmp_dp_train()
858 zynqmp_dp_write(dp, ZYNQMP_DP_PHY_CLOCK_SELECT, reg); in zynqmp_dp_train()
859 ret = zynqmp_dp_phy_ready(dp); in zynqmp_dp_train()
863 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 1); in zynqmp_dp_train()
864 memset(dp->train_set, 0, sizeof(dp->train_set)); in zynqmp_dp_train()
865 ret = zynqmp_dp_link_train_cr(dp); in zynqmp_dp_train()
869 ret = zynqmp_dp_link_train_ce(dp); in zynqmp_dp_train()
873 ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
876 dev_err(dp->dev, "failed to disable training pattern\n"); in zynqmp_dp_train()
879 zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, in zynqmp_dp_train()
882 zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 0); in zynqmp_dp_train()
889 * @dp: DisplayPort IP core structure
893 static void zynqmp_dp_train_loop(struct zynqmp_dp *dp) in zynqmp_dp_train_loop() argument
895 struct zynqmp_dp_mode *mode = &dp->mode; in zynqmp_dp_train_loop()
900 if (dp->status == connector_status_disconnected || in zynqmp_dp_train_loop()
901 !dp->enabled) in zynqmp_dp_train_loop()
904 ret = zynqmp_dp_train(dp); in zynqmp_dp_train_loop()
908 ret = zynqmp_dp_mode_configure(dp, mode->pclock, bw); in zynqmp_dp_train_loop()
916 dev_err(dp->dev, "failed to train the DP link\n"); in zynqmp_dp_train_loop()
927 * @dp: DisplayPort IP core structure
947 static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr, in zynqmp_dp_aux_cmd_submit() argument
953 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
957 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_ADDRESS, addr); in zynqmp_dp_aux_cmd_submit()
960 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_WRITE_FIFO, in zynqmp_dp_aux_cmd_submit()
968 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_COMMAND, reg); in zynqmp_dp_aux_cmd_submit()
972 reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_aux_cmd_submit()
983 reg = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_CODE); in zynqmp_dp_aux_cmd_submit()
990 reg = zynqmp_dp_read(dp, ZYNQMP_DP_REPLY_DATA_COUNT); in zynqmp_dp_aux_cmd_submit()
995 buf[i] = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_DATA); in zynqmp_dp_aux_cmd_submit()
1004 struct zynqmp_dp *dp = container_of(aux, struct zynqmp_dp, aux); in zynqmp_dp_aux_transfer() local
1013 ret = zynqmp_dp_aux_cmd_submit(dp, msg->request, msg->address, in zynqmp_dp_aux_transfer()
1017 dev_dbg(dp->dev, "aux %d retries\n", i); in zynqmp_dp_aux_transfer()
1021 if (dp->status == connector_status_disconnected) { in zynqmp_dp_aux_transfer()
1022 dev_dbg(dp->dev, "no connected aux device\n"); in zynqmp_dp_aux_transfer()
1029 dev_dbg(dp->dev, "failed to do aux transfer (%d)\n", ret); in zynqmp_dp_aux_transfer()
1035 * zynqmp_dp_aux_init - Initialize and register the DP AUX
1036 * @dp: DisplayPort IP core structure
1038 * Program the AUX clock divider and filter and register the DP AUX adapter.
1042 static int zynqmp_dp_aux_init(struct zynqmp_dp *dp) in zynqmp_dp_aux_init() argument
1054 rate = clk_get_rate(dp->dpsub->apb_clk); in zynqmp_dp_aux_init()
1057 dev_err(dp->dev, "aclk frequency too high\n"); in zynqmp_dp_aux_init()
1061 zynqmp_dp_write(dp, ZYNQMP_DP_AUX_CLK_DIVIDER, in zynqmp_dp_aux_init()
1065 dp->aux.name = "ZynqMP DP AUX"; in zynqmp_dp_aux_init()
1066 dp->aux.dev = dp->dev; in zynqmp_dp_aux_init()
1067 dp->aux.drm_dev = dp->drm; in zynqmp_dp_aux_init()
1068 dp->aux.transfer = zynqmp_dp_aux_transfer; in zynqmp_dp_aux_init()
1070 return drm_dp_aux_register(&dp->aux); in zynqmp_dp_aux_init()
1074 * zynqmp_dp_aux_cleanup - Cleanup the DP AUX
1075 * @dp: DisplayPort IP core structure
1077 * Unregister the DP AUX adapter.
1079 static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp) in zynqmp_dp_aux_cleanup() argument
1081 drm_dp_aux_unregister(&dp->aux); in zynqmp_dp_aux_cleanup()
1090 * @dp: DisplayPort IP core structure
1095 static void zynqmp_dp_update_misc(struct zynqmp_dp *dp) in zynqmp_dp_update_misc() argument
1097 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC0, dp->config.misc0); in zynqmp_dp_update_misc()
1098 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_MISC1, dp->config.misc1); in zynqmp_dp_update_misc()
1103 * @dp: DisplayPort IP core structure
1111 static int zynqmp_dp_set_format(struct zynqmp_dp *dp, in zynqmp_dp_set_format() argument
1116 struct zynqmp_dp_config *config = &dp->config; in zynqmp_dp_set_format()
1144 dev_err(dp->dev, "Invalid colormetry in DT\n"); in zynqmp_dp_set_format()
1148 display = &dp->connector.display_info; in zynqmp_dp_set_format()
1150 dev_warn(dp->dev, in zynqmp_dp_set_format()
1175 dev_warn(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", in zynqmp_dp_set_format()
1190 * @dp: DisplayPort IP core structure
1194 * Calculation is based on DP and IP core specification.
1197 zynqmp_dp_encoder_mode_set_transfer_unit(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_transfer_unit() argument
1204 zynqmp_dp_write(dp, ZYNQMP_DP_MSA_TRANSFER_UNIT_SIZE, tu); in zynqmp_dp_encoder_mode_set_transfer_unit()
1206 vid_kbytes = mode->clock * (dp->config.bpp / 8); in zynqmp_dp_encoder_mode_set_transfer_unit()
1207 bw = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_transfer_unit()
1208 avg_bytes_per_tu = vid_kbytes * tu / (dp->mode.lane_cnt * bw / 1000); in zynqmp_dp_encoder_mode_set_transfer_unit()
1209 zynqmp_dp_write(dp, ZYNQMP_DP_MIN_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1211 zynqmp_dp_write(dp, ZYNQMP_DP_FRAC_BYTES_PER_TU, in zynqmp_dp_encoder_mode_set_transfer_unit()
1222 zynqmp_dp_write(dp, ZYNQMP_DP_INIT_WAIT, init_wait); in zynqmp_dp_encoder_mode_set_transfer_unit()
1227 * @dp: DisplayPort IP core structure
1233 static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp, in zynqmp_dp_encoder_mode_set_stream() argument
1236 u8 lane_cnt = dp->mode.lane_cnt; in zynqmp_dp_encoder_mode_set_stream()
1240 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HTOTAL, mode->htotal); in zynqmp_dp_encoder_mode_set_stream()
1241 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VTOTAL, mode->vtotal); in zynqmp_dp_encoder_mode_set_stream()
1242 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_POLARITY, in zynqmp_dp_encoder_mode_set_stream()
1247 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1249 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSWIDTH, in zynqmp_dp_encoder_mode_set_stream()
1251 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HRES, mode->hdisplay); in zynqmp_dp_encoder_mode_set_stream()
1252 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VRES, mode->vdisplay); in zynqmp_dp_encoder_mode_set_stream()
1253 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_HSTART, in zynqmp_dp_encoder_mode_set_stream()
1255 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_VSTART, in zynqmp_dp_encoder_mode_set_stream()
1259 if (dp->config.misc0 & ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK) { in zynqmp_dp_encoder_mode_set_stream()
1260 reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); in zynqmp_dp_encoder_mode_set_stream()
1261 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_N_VID, reg); in zynqmp_dp_encoder_mode_set_stream()
1262 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_M_VID, mode->clock); in zynqmp_dp_encoder_mode_set_stream()
1263 rate = zynqmp_disp_get_audio_clk_rate(dp->dpsub->disp); in zynqmp_dp_encoder_mode_set_stream()
1265 dev_dbg(dp->dev, "Audio rate: %d\n", rate / 512); in zynqmp_dp_encoder_mode_set_stream()
1266 zynqmp_dp_write(dp, ZYNQMP_DP_TX_N_AUD, reg); in zynqmp_dp_encoder_mode_set_stream()
1267 zynqmp_dp_write(dp, ZYNQMP_DP_TX_M_AUD, rate / 1000); in zynqmp_dp_encoder_mode_set_stream()
1272 if (zynqmp_disp_audio_enabled(dp->dpsub->disp)) in zynqmp_dp_encoder_mode_set_stream()
1273 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CHANNELS, 1); in zynqmp_dp_encoder_mode_set_stream()
1275 zynqmp_dp_write(dp, ZYNQMP_DP_USER_PIX_WIDTH, 1); in zynqmp_dp_encoder_mode_set_stream()
1278 wpl = (mode->hdisplay * dp->config.bpp + 15) / 16; in zynqmp_dp_encoder_mode_set_stream()
1280 zynqmp_dp_write(dp, ZYNQMP_DP_USER_DATA_COUNT_PER_LANE, reg); in zynqmp_dp_encoder_mode_set_stream()
1290 struct zynqmp_dp *dp = connector_to_dp(connector); in zynqmp_dp_connector_detect() local
1291 struct zynqmp_dp_link_config *link_config = &dp->link_config; in zynqmp_dp_connector_detect()
1300 state = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); in zynqmp_dp_connector_detect()
1307 ret = drm_dp_dpcd_read(&dp->aux, 0x0, dp->dpcd, in zynqmp_dp_connector_detect()
1308 sizeof(dp->dpcd)); in zynqmp_dp_connector_detect()
1310 dev_dbg(dp->dev, "DPCD read failed"); in zynqmp_dp_connector_detect()
1315 drm_dp_max_link_rate(dp->dpcd), in zynqmp_dp_connector_detect()
1318 drm_dp_max_lane_count(dp->dpcd), in zynqmp_dp_connector_detect()
1319 dp->num_lanes); in zynqmp_dp_connector_detect()
1321 dp->status = connector_status_connected; in zynqmp_dp_connector_detect()
1326 dp->status = connector_status_disconnected; in zynqmp_dp_connector_detect()
1332 struct zynqmp_dp *dp = connector_to_dp(connector); in zynqmp_dp_connector_get_modes() local
1336 edid = drm_get_edid(connector, &dp->aux.ddc); in zynqmp_dp_connector_get_modes()
1350 struct zynqmp_dp *dp = connector_to_dp(connector); in zynqmp_dp_connector_best_encoder() local
1352 return &dp->encoder; in zynqmp_dp_connector_best_encoder()
1358 struct zynqmp_dp *dp = connector_to_dp(connector); in zynqmp_dp_connector_mode_valid() local
1359 u8 max_lanes = dp->link_config.max_lanes; in zynqmp_dp_connector_mode_valid()
1360 u8 bpp = dp->config.bpp; in zynqmp_dp_connector_mode_valid()
1361 int max_rate = dp->link_config.max_rate; in zynqmp_dp_connector_mode_valid()
1365 dev_dbg(dp->dev, "filtered the mode, %s,for high pixel rate\n", in zynqmp_dp_connector_mode_valid()
1374 dev_dbg(dp->dev, "filtered the mode, %s,for high pixel rate\n", in zynqmp_dp_connector_mode_valid()
1405 struct zynqmp_dp *dp = encoder_to_dp(encoder); in zynqmp_dp_encoder_enable() local
1409 pm_runtime_get_sync(dp->dev); in zynqmp_dp_encoder_enable()
1410 dp->enabled = true; in zynqmp_dp_encoder_enable()
1411 zynqmp_dp_update_misc(dp); in zynqmp_dp_encoder_enable()
1412 if (zynqmp_disp_audio_enabled(dp->dpsub->disp)) in zynqmp_dp_encoder_enable()
1413 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 1); in zynqmp_dp_encoder_enable()
1414 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, 0); in zynqmp_dp_encoder_enable()
1415 if (dp->status == connector_status_connected) { in zynqmp_dp_encoder_enable()
1417 ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, in zynqmp_dp_encoder_enable()
1427 dev_dbg(dp->dev, "DP aux failed\n"); in zynqmp_dp_encoder_enable()
1429 zynqmp_dp_train_loop(dp); in zynqmp_dp_encoder_enable()
1430 zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, in zynqmp_dp_encoder_enable()
1432 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); in zynqmp_dp_encoder_enable()
1437 struct zynqmp_dp *dp = encoder_to_dp(encoder); in zynqmp_dp_encoder_disable() local
1439 dp->enabled = false; in zynqmp_dp_encoder_disable()
1440 cancel_delayed_work(&dp->hpd_work); in zynqmp_dp_encoder_disable()
1441 zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); in zynqmp_dp_encoder_disable()
1442 drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in zynqmp_dp_encoder_disable()
1443 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_encoder_disable()
1445 if (zynqmp_disp_audio_enabled(dp->dpsub->disp)) in zynqmp_dp_encoder_disable()
1446 zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); in zynqmp_dp_encoder_disable()
1447 pm_runtime_put_sync(dp->dev); in zynqmp_dp_encoder_disable()
1455 struct zynqmp_dp *dp = encoder_to_dp(encoder); in zynqmp_dp_encoder_atomic_mode_set() local
1458 u8 max_lanes = dp->link_config.max_lanes; in zynqmp_dp_encoder_atomic_mode_set()
1459 u8 bpp = dp->config.bpp; in zynqmp_dp_encoder_atomic_mode_set()
1460 int rate, max_rate = dp->link_config.max_rate; in zynqmp_dp_encoder_atomic_mode_set()
1463 zynqmp_dp_set_format(dp, ZYNQMP_DPSUB_FORMAT_RGB, 8); in zynqmp_dp_encoder_atomic_mode_set()
1468 dev_err(dp->dev, "the mode, %s,has too high pixel rate\n", in zynqmp_dp_encoder_atomic_mode_set()
1473 ret = zynqmp_dp_mode_configure(dp, adjusted_mode->clock, 0); in zynqmp_dp_encoder_atomic_mode_set()
1477 zynqmp_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode); in zynqmp_dp_encoder_atomic_mode_set()
1478 zynqmp_dp_encoder_mode_set_stream(dp, adjusted_mode); in zynqmp_dp_encoder_atomic_mode_set()
1493 * ZynqMP DP requires horizontal backporch to be greater than 12. in zynqmp_dp_encoder_atomic_check()
1524 * @dp: DisplayPort IP core structure
1528 void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_enable_vblank() argument
1530 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_enable_vblank()
1535 * @dp: DisplayPort IP core structure
1539 void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp) in zynqmp_dp_disable_vblank() argument
1541 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_VBLANK_START); in zynqmp_dp_disable_vblank()
1546 struct zynqmp_dp *dp; in zynqmp_dp_hpd_work_func() local
1548 dp = container_of(work, struct zynqmp_dp, hpd_work.work); in zynqmp_dp_hpd_work_func()
1550 if (dp->drm) in zynqmp_dp_hpd_work_func()
1551 drm_helper_hpd_irq_event(dp->drm); in zynqmp_dp_hpd_work_func()
1556 struct zynqmp_dp *dp = (struct zynqmp_dp *)data; in zynqmp_dp_irq_handler() local
1559 status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS); in zynqmp_dp_irq_handler()
1560 mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK); in zynqmp_dp_irq_handler()
1566 dev_dbg_ratelimited(dp->dev, "underflow interrupt\n"); in zynqmp_dp_irq_handler()
1568 dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); in zynqmp_dp_irq_handler()
1570 zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); in zynqmp_dp_irq_handler()
1573 zynqmp_disp_handle_vblank(dp->dpsub->disp); in zynqmp_dp_irq_handler()
1576 schedule_delayed_work(&dp->hpd_work, 0); in zynqmp_dp_irq_handler()
1582 ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, in zynqmp_dp_irq_handler()
1588 !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || in zynqmp_dp_irq_handler()
1589 !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { in zynqmp_dp_irq_handler()
1590 zynqmp_dp_train_loop(dp); in zynqmp_dp_irq_handler()
1604 struct zynqmp_dp *dp = dpsub->dp; in zynqmp_dp_drm_init() local
1605 struct drm_encoder *encoder = &dp->encoder; in zynqmp_dp_drm_init()
1606 struct drm_connector *connector = &dp->connector; in zynqmp_dp_drm_init()
1609 dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK; in zynqmp_dp_drm_init()
1610 zynqmp_dp_set_format(dp, ZYNQMP_DPSUB_FORMAT_RGB, 8); in zynqmp_dp_drm_init()
1614 drm_simple_encoder_init(dp->drm, encoder, DRM_MODE_ENCODER_TMDS); in zynqmp_dp_drm_init()
1622 dev_err(dp->dev, "failed to create the DRM connector\n"); in zynqmp_dp_drm_init()
1631 ret = zynqmp_dp_aux_init(dp); in zynqmp_dp_drm_init()
1633 dev_err(dp->dev, "failed to initialize DP aux\n"); in zynqmp_dp_drm_init()
1638 zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_ALL); in zynqmp_dp_drm_init()
1646 struct zynqmp_dp *dp; in zynqmp_dp_probe() local
1650 dp = drmm_kzalloc(drm, sizeof(*dp), GFP_KERNEL); in zynqmp_dp_probe()
1651 if (!dp) in zynqmp_dp_probe()
1654 dp->dev = &pdev->dev; in zynqmp_dp_probe()
1655 dp->dpsub = dpsub; in zynqmp_dp_probe()
1656 dp->status = connector_status_disconnected; in zynqmp_dp_probe()
1657 dp->drm = drm; in zynqmp_dp_probe()
1659 INIT_DELAYED_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); in zynqmp_dp_probe()
1661 dpsub->dp = dp; in zynqmp_dp_probe()
1664 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp"); in zynqmp_dp_probe()
1665 dp->iomem = devm_ioremap_resource(dp->dev, res); in zynqmp_dp_probe()
1666 if (IS_ERR(dp->iomem)) in zynqmp_dp_probe()
1667 return PTR_ERR(dp->iomem); in zynqmp_dp_probe()
1669 dp->irq = platform_get_irq(pdev, 0); in zynqmp_dp_probe()
1670 if (dp->irq < 0) in zynqmp_dp_probe()
1671 return dp->irq; in zynqmp_dp_probe()
1673 dp->reset = devm_reset_control_get(dp->dev, NULL); in zynqmp_dp_probe()
1674 if (IS_ERR(dp->reset)) { in zynqmp_dp_probe()
1675 if (PTR_ERR(dp->reset) != -EPROBE_DEFER) in zynqmp_dp_probe()
1676 dev_err(dp->dev, "failed to get reset: %ld\n", in zynqmp_dp_probe()
1677 PTR_ERR(dp->reset)); in zynqmp_dp_probe()
1678 return PTR_ERR(dp->reset); in zynqmp_dp_probe()
1681 ret = zynqmp_dp_reset(dp, false); in zynqmp_dp_probe()
1685 ret = zynqmp_dp_phy_probe(dp); in zynqmp_dp_probe()
1690 zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN, in zynqmp_dp_probe()
1692 zynqmp_dp_set(dp, ZYNQMP_DP_PHY_RESET, ZYNQMP_DP_PHY_RESET_ALL_RESET); in zynqmp_dp_probe()
1693 zynqmp_dp_write(dp, ZYNQMP_DP_FORCE_SCRAMBLER_RESET, 1); in zynqmp_dp_probe()
1694 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_probe()
1695 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_probe()
1697 ret = zynqmp_dp_phy_init(dp); in zynqmp_dp_probe()
1701 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 1); in zynqmp_dp_probe()
1707 ret = devm_request_threaded_irq(dp->dev, dp->irq, NULL, in zynqmp_dp_probe()
1709 dev_name(dp->dev), dp); in zynqmp_dp_probe()
1713 dev_dbg(dp->dev, "ZynqMP DisplayPort Tx probed with %u lanes\n", in zynqmp_dp_probe()
1714 dp->num_lanes); in zynqmp_dp_probe()
1719 zynqmp_dp_phy_exit(dp); in zynqmp_dp_probe()
1721 zynqmp_dp_reset(dp, true); in zynqmp_dp_probe()
1728 struct zynqmp_dp *dp = dpsub->dp; in zynqmp_dp_remove() local
1730 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); in zynqmp_dp_remove()
1731 disable_irq(dp->irq); in zynqmp_dp_remove()
1733 cancel_delayed_work_sync(&dp->hpd_work); in zynqmp_dp_remove()
1734 zynqmp_dp_aux_cleanup(dp); in zynqmp_dp_remove()
1736 zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); in zynqmp_dp_remove()
1737 zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff); in zynqmp_dp_remove()
1739 zynqmp_dp_phy_exit(dp); in zynqmp_dp_remove()
1740 zynqmp_dp_reset(dp, true); in zynqmp_dp_remove()