Lines Matching +full:slave +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0+
8 * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs.
193 #define N_LANES(n) (((n) - 1) & 0x3)
266 struct dw_mipi_dsi *master; /* dual-dsi master ptr */
267 struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */ member
273 * Check if either a link to a master or slave is present
277 return dsi->slave || dsi->master; in dw_mipi_is_dual_mode()
284 static void dw_mipi_dsi_wait_for_two_frames(const struct drm_display_mode *mode) in dw_mipi_dsi_wait_for_two_frames() argument
288 refresh = drm_mode_vrefresh(mode); in dw_mipi_dsi_wait_for_two_frames()
305 writel(val, dsi->base + reg); in dsi_write()
310 return readl(dsi->base + reg); in dsi_read()
331 dsi->panel_bridge = bridge; in dw_mipi_dsi_panel_or_bridge()
333 if (!dsi->panel_bridge) in dw_mipi_dsi_panel_or_bridge()
334 return -EPROBE_DEFER; in dw_mipi_dsi_panel_or_bridge()
343 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; in dw_mipi_dsi_host_attach()
346 if (device->lanes > dsi->plat_data->max_data_lanes) { in dw_mipi_dsi_host_attach()
347 dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", in dw_mipi_dsi_host_attach()
348 device->lanes); in dw_mipi_dsi_host_attach()
349 return -EINVAL; in dw_mipi_dsi_host_attach()
352 dsi->lanes = device->lanes; in dw_mipi_dsi_host_attach()
353 dsi->channel = device->channel; in dw_mipi_dsi_host_attach()
354 dsi->format = device->format; in dw_mipi_dsi_host_attach()
355 dsi->mode_flags = device->mode_flags; in dw_mipi_dsi_host_attach()
357 if (!dsi->device_found) { in dw_mipi_dsi_host_attach()
358 ret = dw_mipi_dsi_panel_or_bridge(dsi, host->dev->of_node); in dw_mipi_dsi_host_attach()
362 dsi->device_found = true; in dw_mipi_dsi_host_attach()
365 if (pdata->host_ops && pdata->host_ops->attach) { in dw_mipi_dsi_host_attach()
366 ret = pdata->host_ops->attach(pdata->priv_data, device); in dw_mipi_dsi_host_attach()
378 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; in dw_mipi_dsi_host_detach()
381 if (pdata->host_ops && pdata->host_ops->detach) { in dw_mipi_dsi_host_detach()
382 ret = pdata->host_ops->detach(pdata->priv_data, device); in dw_mipi_dsi_host_detach()
387 drm_of_panel_bridge_remove(host->dev->of_node, 1, 0); in dw_mipi_dsi_host_detach()
389 drm_bridge_remove(&dsi->bridge); in dw_mipi_dsi_host_detach()
397 bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM; in dw_mipi_message_config()
409 if (msg->flags & MIPI_DSI_MSG_REQ_ACK) in dw_mipi_message_config()
429 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_gen_pkt_hdr_write()
433 dev_err(dsi->dev, "failed to get available command FIFO\n"); in dw_mipi_dsi_gen_pkt_hdr_write()
440 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_gen_pkt_hdr_write()
444 dev_err(dsi->dev, "failed to write command FIFO\n"); in dw_mipi_dsi_gen_pkt_hdr_write()
454 const u8 *tx_buf = packet->payload; in dw_mipi_dsi_write()
455 int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret; in dw_mipi_dsi_write()
469 len -= pld_data_bytes; in dw_mipi_dsi_write()
472 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_write()
476 dev_err(dsi->dev, in dw_mipi_dsi_write()
483 memcpy(&word, packet->header, sizeof(packet->header)); in dw_mipi_dsi_write()
490 int i, j, ret, len = msg->rx_len; in dw_mipi_dsi_read()
491 u8 *buf = msg->rx_buf; in dw_mipi_dsi_read()
495 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_read()
499 dev_err(dsi->dev, "Timeout during read operation\n"); in dw_mipi_dsi_read()
505 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_read()
509 dev_err(dsi->dev, "Read payload FIFO is empty\n"); in dw_mipi_dsi_read()
530 dev_err(dsi->dev, "failed to create packet: %d\n", ret); in dw_mipi_dsi_host_transfer()
535 if (dsi->slave) in dw_mipi_dsi_host_transfer()
536 dw_mipi_message_config(dsi->slave, msg); in dw_mipi_dsi_host_transfer()
541 if (dsi->slave) { in dw_mipi_dsi_host_transfer()
542 ret = dw_mipi_dsi_write(dsi->slave, &packet); in dw_mipi_dsi_host_transfer()
547 if (msg->rx_buf && msg->rx_len) { in dw_mipi_dsi_host_transfer()
551 nb_bytes = msg->rx_len; in dw_mipi_dsi_host_transfer()
571 * enabling low power is panel-dependent, we should use the in dw_mipi_dsi_video_mode_config()
576 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) in dw_mipi_dsi_video_mode_config()
578 else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in dw_mipi_dsi_video_mode_config()
584 if (dsi->vpg_defs.vpg) { in dw_mipi_dsi_video_mode_config()
586 val |= dsi->vpg_defs.vpg_horizontal ? in dw_mipi_dsi_video_mode_config()
588 val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0; in dw_mipi_dsi_video_mode_config()
610 if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) in dw_mipi_dsi_set_mode()
625 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; in dw_mipi_dsi_init()
634 if (phy_ops->get_esc_clk_rate) { in dw_mipi_dsi_init()
635 ret = phy_ops->get_esc_clk_rate(dsi->plat_data->priv_data, in dw_mipi_dsi_init()
648 esc_clk_division = (dsi->lane_mbps >> 3) / esc_rate + 1; in dw_mipi_dsi_init()
662 const struct drm_display_mode *mode) in dw_mipi_dsi_dpi_config() argument
666 switch (dsi->format) { in dw_mipi_dsi_dpi_config()
681 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in dw_mipi_dsi_dpi_config()
683 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in dw_mipi_dsi_dpi_config()
686 dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); in dw_mipi_dsi_dpi_config()
697 const struct drm_display_mode *mode) in dw_mipi_dsi_video_packet_config() argument
701 * only burst mode is supported here. For non-burst video modes, in dw_mipi_dsi_video_packet_config()
704 * non-burst video modes, see dw_mipi_dsi_video_mode_config()... in dw_mipi_dsi_video_packet_config()
709 VID_PKT_SIZE(mode->hdisplay / 2) : in dw_mipi_dsi_video_packet_config()
710 VID_PKT_SIZE(mode->hdisplay)); in dw_mipi_dsi_video_packet_config()
723 * the Bus-Turn-Around Timeout Counter should be computed in dw_mipi_dsi_command_mode_config()
732 const struct drm_display_mode *mode, in dw_mipi_dsi_get_hcomponent_lbcc() argument
737 lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; in dw_mipi_dsi_get_hcomponent_lbcc()
739 frac = lbcc % mode->clock; in dw_mipi_dsi_get_hcomponent_lbcc()
740 lbcc = lbcc / mode->clock; in dw_mipi_dsi_get_hcomponent_lbcc()
748 const struct drm_display_mode *mode) in dw_mipi_dsi_line_timer_config() argument
752 htotal = mode->htotal; in dw_mipi_dsi_line_timer_config()
753 hsa = mode->hsync_end - mode->hsync_start; in dw_mipi_dsi_line_timer_config()
754 hbp = mode->htotal - mode->hsync_end; in dw_mipi_dsi_line_timer_config()
760 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal); in dw_mipi_dsi_line_timer_config()
763 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa); in dw_mipi_dsi_line_timer_config()
766 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp); in dw_mipi_dsi_line_timer_config()
771 const struct drm_display_mode *mode) in dw_mipi_dsi_vertical_timing_config() argument
775 vactive = mode->vdisplay; in dw_mipi_dsi_vertical_timing_config()
776 vsa = mode->vsync_end - mode->vsync_start; in dw_mipi_dsi_vertical_timing_config()
777 vfp = mode->vsync_start - mode->vdisplay; in dw_mipi_dsi_vertical_timing_config()
778 vbp = mode->vtotal - mode->vsync_end; in dw_mipi_dsi_vertical_timing_config()
788 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; in dw_mipi_dsi_dphy_timing_config()
793 ret = phy_ops->get_timing(dsi->plat_data->priv_data, in dw_mipi_dsi_dphy_timing_config()
794 dsi->lane_mbps, &timing); in dw_mipi_dsi_dphy_timing_config()
796 DRM_DEV_ERROR(dsi->dev, "Retrieving phy timings failed\n"); in dw_mipi_dsi_dphy_timing_config()
801 * blankings and to the automatic clock lane control mode... in dw_mipi_dsi_dphy_timing_config()
833 N_LANES(dsi->lanes)); in dw_mipi_dsi_dphy_interface_config()
854 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, in dw_mipi_dsi_dphy_enable()
859 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, in dw_mipi_dsi_dphy_enable()
877 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; in dw_mipi_dsi_bridge_post_disable()
880 * Switch to command mode before panel-bridge post_disable & in dw_mipi_dsi_bridge_post_disable()
882 * Note: panel-bridge disable & panel disable has been called in dw_mipi_dsi_bridge_post_disable()
888 * TODO Only way found to call panel-bridge post_disable & in dw_mipi_dsi_bridge_post_disable()
893 if (dsi->panel_bridge->funcs->post_disable) in dw_mipi_dsi_bridge_post_disable()
894 dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge); in dw_mipi_dsi_bridge_post_disable()
896 if (phy_ops->power_off) in dw_mipi_dsi_bridge_post_disable()
897 phy_ops->power_off(dsi->plat_data->priv_data); in dw_mipi_dsi_bridge_post_disable()
899 if (dsi->slave) { in dw_mipi_dsi_bridge_post_disable()
900 dw_mipi_dsi_disable(dsi->slave); in dw_mipi_dsi_bridge_post_disable()
901 clk_disable_unprepare(dsi->slave->pclk); in dw_mipi_dsi_bridge_post_disable()
902 pm_runtime_put(dsi->slave->dev); in dw_mipi_dsi_bridge_post_disable()
906 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_bridge_post_disable()
907 pm_runtime_put(dsi->dev); in dw_mipi_dsi_bridge_post_disable()
912 /* this instance is the slave, so add the master's lanes */ in dw_mipi_dsi_get_lanes()
913 if (dsi->master) in dw_mipi_dsi_get_lanes()
914 return dsi->master->lanes + dsi->lanes; in dw_mipi_dsi_get_lanes()
916 /* this instance is the master, so add the slave's lanes */ in dw_mipi_dsi_get_lanes()
917 if (dsi->slave) in dw_mipi_dsi_get_lanes()
918 return dsi->lanes + dsi->slave->lanes; in dw_mipi_dsi_get_lanes()
920 /* single-dsi, so no other instance to consider */ in dw_mipi_dsi_get_lanes()
921 return dsi->lanes; in dw_mipi_dsi_get_lanes()
927 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; in dw_mipi_dsi_mode_set()
928 void *priv_data = dsi->plat_data->priv_data; in dw_mipi_dsi_mode_set()
932 clk_prepare_enable(dsi->pclk); in dw_mipi_dsi_mode_set()
934 ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags, in dw_mipi_dsi_mode_set()
935 lanes, dsi->format, &dsi->lane_mbps); in dw_mipi_dsi_mode_set()
939 pm_runtime_get_sync(dsi->dev); in dw_mipi_dsi_mode_set()
955 ret = phy_ops->init(priv_data); in dw_mipi_dsi_mode_set()
963 /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */ in dw_mipi_dsi_mode_set()
966 if (phy_ops->power_on) in dw_mipi_dsi_mode_set()
967 phy_ops->power_on(dsi->plat_data->priv_data); in dw_mipi_dsi_mode_set()
971 const struct drm_display_mode *mode, in dw_mipi_dsi_bridge_mode_set() argument
977 if (dsi->slave) in dw_mipi_dsi_bridge_mode_set()
978 dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode); in dw_mipi_dsi_bridge_mode_set()
985 /* Switch to video mode for panel-bridge enable & panel enable */ in dw_mipi_dsi_bridge_enable()
987 if (dsi->slave) in dw_mipi_dsi_bridge_enable()
988 dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO); in dw_mipi_dsi_bridge_enable()
994 const struct drm_display_mode *mode) in dw_mipi_dsi_bridge_mode_valid() argument
997 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; in dw_mipi_dsi_bridge_mode_valid()
1000 if (pdata->mode_valid) in dw_mipi_dsi_bridge_mode_valid()
1001 mode_status = pdata->mode_valid(pdata->priv_data, mode); in dw_mipi_dsi_bridge_mode_valid()
1011 if (!bridge->encoder) { in dw_mipi_dsi_bridge_attach()
1013 return -ENODEV; in dw_mipi_dsi_bridge_attach()
1017 bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI; in dw_mipi_dsi_bridge_attach()
1019 if (!dsi->device_found) { in dw_mipi_dsi_bridge_attach()
1022 ret = dw_mipi_dsi_panel_or_bridge(dsi, dsi->dev->of_node); in dw_mipi_dsi_bridge_attach()
1026 dsi->device_found = true; in dw_mipi_dsi_bridge_attach()
1029 /* Attach the panel-bridge to the dsi bridge */ in dw_mipi_dsi_bridge_attach()
1030 return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge, in dw_mipi_dsi_bridge_attach()
1051 return -ENODEV; in dw_mipi_dsi_debugfs_write()
1053 dsi = vpg->dsi; in dw_mipi_dsi_debugfs_write()
1055 *vpg->reg = (bool)val; in dw_mipi_dsi_debugfs_write()
1059 if (*vpg->reg) in dw_mipi_dsi_debugfs_write()
1060 mode_cfg |= vpg->mask; in dw_mipi_dsi_debugfs_write()
1062 mode_cfg &= ~vpg->mask; in dw_mipi_dsi_debugfs_write()
1074 return -ENODEV; in dw_mipi_dsi_debugfs_show()
1076 *val = *vpg->reg; in dw_mipi_dsi_debugfs_show()
1094 dsi->debugfs_vpg = kmemdup(debugfs, sizeof(debugfs), GFP_KERNEL); in debugfs_create_files()
1095 if (!dsi->debugfs_vpg) in debugfs_create_files()
1099 debugfs_create_file(dsi->debugfs_vpg[i].name, 0644, in debugfs_create_files()
1100 dsi->debugfs, &dsi->debugfs_vpg[i], in debugfs_create_files()
1106 dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL); in dw_mipi_dsi_debugfs_init()
1107 if (IS_ERR(dsi->debugfs)) { in dw_mipi_dsi_debugfs_init()
1108 dev_err(dsi->dev, "failed to create debugfs root\n"); in dw_mipi_dsi_debugfs_init()
1117 debugfs_remove_recursive(dsi->debugfs); in dw_mipi_dsi_debugfs_remove()
1118 kfree(dsi->debugfs_vpg); in dw_mipi_dsi_debugfs_remove()
1132 struct device *dev = &pdev->dev; in __dw_mipi_dsi_probe()
1139 return ERR_PTR(-ENOMEM); in __dw_mipi_dsi_probe()
1141 dsi->dev = dev; in __dw_mipi_dsi_probe()
1142 dsi->plat_data = plat_data; in __dw_mipi_dsi_probe()
1144 if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps || in __dw_mipi_dsi_probe()
1145 !plat_data->phy_ops->get_timing) { in __dw_mipi_dsi_probe()
1147 return ERR_PTR(-ENODEV); in __dw_mipi_dsi_probe()
1150 if (!plat_data->base) { in __dw_mipi_dsi_probe()
1151 dsi->base = devm_platform_ioremap_resource(pdev, 0); in __dw_mipi_dsi_probe()
1152 if (IS_ERR(dsi->base)) in __dw_mipi_dsi_probe()
1153 return ERR_PTR(-ENODEV); in __dw_mipi_dsi_probe()
1156 dsi->base = plat_data->base; in __dw_mipi_dsi_probe()
1159 dsi->pclk = devm_clk_get(dev, "pclk"); in __dw_mipi_dsi_probe()
1160 if (IS_ERR(dsi->pclk)) { in __dw_mipi_dsi_probe()
1161 ret = PTR_ERR(dsi->pclk); in __dw_mipi_dsi_probe()
1174 if (ret != -EPROBE_DEFER) in __dw_mipi_dsi_probe()
1181 ret = clk_prepare_enable(dsi->pclk); in __dw_mipi_dsi_probe()
1191 clk_disable_unprepare(dsi->pclk); in __dw_mipi_dsi_probe()
1197 dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; in __dw_mipi_dsi_probe()
1198 dsi->dsi_host.dev = dev; in __dw_mipi_dsi_probe()
1199 ret = mipi_dsi_host_register(&dsi->dsi_host); in __dw_mipi_dsi_probe()
1206 dsi->bridge.driver_private = dsi; in __dw_mipi_dsi_probe()
1207 dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; in __dw_mipi_dsi_probe()
1209 dsi->bridge.of_node = pdev->dev.of_node; in __dw_mipi_dsi_probe()
1211 drm_bridge_add(&dsi->bridge); in __dw_mipi_dsi_probe()
1218 mipi_dsi_host_unregister(&dsi->dsi_host); in __dw_mipi_dsi_remove()
1220 pm_runtime_disable(dsi->dev); in __dw_mipi_dsi_remove()
1224 void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave) in dw_mipi_dsi_set_slave() argument
1227 dsi->slave = slave; in dw_mipi_dsi_set_slave()
1228 dsi->slave->master = dsi; in dw_mipi_dsi_set_slave()
1231 dsi->slave->lanes = dsi->lanes; in dw_mipi_dsi_set_slave()
1232 dsi->slave->channel = dsi->channel; in dw_mipi_dsi_set_slave()
1233 dsi->slave->format = dsi->format; in dw_mipi_dsi_set_slave()
1234 dsi->slave->mode_flags = dsi->mode_flags; in dw_mipi_dsi_set_slave()
1260 return drm_bridge_attach(encoder, &dsi->bridge, NULL, 0); in dw_mipi_dsi_bind()
1269 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
1273 MODULE_ALIAS("platform:dw-mipi-dsi");