Lines Matching full:dsi
7 * This generic Synopsys DesignWare MIPI DSI host driver is based on the
8 * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs.
259 static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val) in dsi_write() argument
261 writel(val, dsi->base + reg); in dsi_write()
264 static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg) in dsi_read() argument
266 return readl(dsi->base + reg); in dsi_read()
272 struct dw_mipi_dsi *dsi = host_to_dsi(host); in dw_mipi_dsi_host_attach() local
277 if (device->lanes > dsi->plat_data->max_data_lanes) { in dw_mipi_dsi_host_attach()
278 dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", in dw_mipi_dsi_host_attach()
283 dsi->lanes = device->lanes; in dw_mipi_dsi_host_attach()
284 dsi->channel = device->channel; in dw_mipi_dsi_host_attach()
285 dsi->format = device->format; in dw_mipi_dsi_host_attach()
286 dsi->mode_flags = device->mode_flags; in dw_mipi_dsi_host_attach()
299 dsi->panel_bridge = bridge; in dw_mipi_dsi_host_attach()
301 drm_bridge_add(&dsi->bridge); in dw_mipi_dsi_host_attach()
309 struct dw_mipi_dsi *dsi = host_to_dsi(host); in dw_mipi_dsi_host_detach() local
313 drm_bridge_remove(&dsi->bridge); in dw_mipi_dsi_host_detach()
318 static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, in dw_mipi_message_config() argument
329 dsi_write(dsi, DSI_CMD_MODE_CFG, val); in dw_mipi_message_config()
332 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) in dw_mipi_dsi_gen_pkt_hdr_write() argument
337 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_gen_pkt_hdr_write()
341 dev_err(dsi->dev, "failed to get available command FIFO\n"); in dw_mipi_dsi_gen_pkt_hdr_write()
345 dsi_write(dsi, DSI_GEN_HDR, hdr_val); in dw_mipi_dsi_gen_pkt_hdr_write()
348 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_gen_pkt_hdr_write()
352 dev_err(dsi->dev, "failed to write command FIFO\n"); in dw_mipi_dsi_gen_pkt_hdr_write()
359 static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_write() argument
371 dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word)); in dw_mipi_dsi_write()
375 dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word)); in dw_mipi_dsi_write()
380 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_write()
384 dev_err(dsi->dev, in dw_mipi_dsi_write()
392 return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word)); in dw_mipi_dsi_write()
395 static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_read() argument
403 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_read()
407 dev_err(dsi->dev, "Timeout during read operation\n"); in dw_mipi_dsi_read()
413 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, in dw_mipi_dsi_read()
417 dev_err(dsi->dev, "Read payload FIFO is empty\n"); in dw_mipi_dsi_read()
421 val = dsi_read(dsi, DSI_GEN_PLD_DATA); in dw_mipi_dsi_read()
432 struct dw_mipi_dsi *dsi = host_to_dsi(host); in dw_mipi_dsi_host_transfer() local
438 dev_err(dsi->dev, "failed to create packet: %d\n", ret); in dw_mipi_dsi_host_transfer()
442 dw_mipi_message_config(dsi, msg); in dw_mipi_dsi_host_transfer()
444 ret = dw_mipi_dsi_write(dsi, &packet); in dw_mipi_dsi_host_transfer()
449 ret = dw_mipi_dsi_read(dsi, msg); in dw_mipi_dsi_host_transfer()
466 static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_video_mode_config() argument
477 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) in dw_mipi_dsi_video_mode_config()
479 else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in dw_mipi_dsi_video_mode_config()
484 dsi_write(dsi, DSI_VID_MODE_CFG, val); in dw_mipi_dsi_video_mode_config()
487 static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_set_mode() argument
492 dsi_write(dsi, DSI_PWR_UP, RESET); in dw_mipi_dsi_set_mode()
495 dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE); in dw_mipi_dsi_set_mode()
496 dw_mipi_dsi_video_mode_config(dsi); in dw_mipi_dsi_set_mode()
498 dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); in dw_mipi_dsi_set_mode()
502 if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) in dw_mipi_dsi_set_mode()
504 dsi_write(dsi, DSI_LPCLK_CTRL, val); in dw_mipi_dsi_set_mode()
506 dsi_write(dsi, DSI_PWR_UP, POWERUP); in dw_mipi_dsi_set_mode()
509 static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_disable() argument
511 dsi_write(dsi, DSI_PWR_UP, RESET); in dw_mipi_dsi_disable()
512 dsi_write(dsi, DSI_PHY_RSTZ, PHY_RSTZ); in dw_mipi_dsi_disable()
515 static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_init() argument
525 u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1; in dw_mipi_dsi_init()
527 dsi_write(dsi, DSI_PWR_UP, RESET); in dw_mipi_dsi_init()
534 dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | in dw_mipi_dsi_init()
538 static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_dpi_config() argument
543 switch (dsi->format) { in dw_mipi_dsi_dpi_config()
563 dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); in dw_mipi_dsi_dpi_config()
564 dsi_write(dsi, DSI_DPI_COLOR_CODING, color); in dw_mipi_dsi_dpi_config()
565 dsi_write(dsi, DSI_DPI_CFG_POL, val); in dw_mipi_dsi_dpi_config()
572 dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4) in dw_mipi_dsi_dpi_config()
576 static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_packet_handler_config() argument
578 dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN); in dw_mipi_dsi_packet_handler_config()
581 static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_video_packet_config() argument
591 dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay)); in dw_mipi_dsi_video_packet_config()
594 static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_command_mode_config() argument
601 dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); in dw_mipi_dsi_command_mode_config()
607 dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00); in dw_mipi_dsi_command_mode_config()
608 dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); in dw_mipi_dsi_command_mode_config()
612 static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_get_hcomponent_lbcc() argument
618 lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; in dw_mipi_dsi_get_hcomponent_lbcc()
628 static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_line_timer_config() argument
641 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal); in dw_mipi_dsi_line_timer_config()
642 dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc); in dw_mipi_dsi_line_timer_config()
644 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa); in dw_mipi_dsi_line_timer_config()
645 dsi_write(dsi, DSI_VID_HSA_TIME, lbcc); in dw_mipi_dsi_line_timer_config()
647 lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp); in dw_mipi_dsi_line_timer_config()
648 dsi_write(dsi, DSI_VID_HBP_TIME, lbcc); in dw_mipi_dsi_line_timer_config()
651 static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi, in dw_mipi_dsi_vertical_timing_config() argument
661 dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive); in dw_mipi_dsi_vertical_timing_config()
662 dsi_write(dsi, DSI_VID_VSA_LINES, vsa); in dw_mipi_dsi_vertical_timing_config()
663 dsi_write(dsi, DSI_VID_VFP_LINES, vfp); in dw_mipi_dsi_vertical_timing_config()
664 dsi_write(dsi, DSI_VID_VBP_LINES, vbp); in dw_mipi_dsi_vertical_timing_config()
667 static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_dphy_timing_config() argument
679 hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; in dw_mipi_dsi_dphy_timing_config()
682 dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) | in dw_mipi_dsi_dphy_timing_config()
684 dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000)); in dw_mipi_dsi_dphy_timing_config()
686 dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) | in dw_mipi_dsi_dphy_timing_config()
690 dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40) in dw_mipi_dsi_dphy_timing_config()
694 static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_dphy_interface_config() argument
698 * stop wait time should be the maximum between host dsi in dw_mipi_dsi_dphy_interface_config()
701 dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) | in dw_mipi_dsi_dphy_interface_config()
702 N_LANES(dsi->lanes)); in dw_mipi_dsi_dphy_interface_config()
705 static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_dphy_init() argument
708 dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK in dw_mipi_dsi_dphy_init()
710 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); in dw_mipi_dsi_dphy_init()
711 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR); in dw_mipi_dsi_dphy_init()
712 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); in dw_mipi_dsi_dphy_init()
715 static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_dphy_enable() argument
720 dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK | in dw_mipi_dsi_dphy_enable()
723 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, in dw_mipi_dsi_dphy_enable()
728 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, in dw_mipi_dsi_dphy_enable()
735 static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_clear_err() argument
737 dsi_read(dsi, DSI_INT_ST0); in dw_mipi_dsi_clear_err()
738 dsi_read(dsi, DSI_INT_ST1); in dw_mipi_dsi_clear_err()
739 dsi_write(dsi, DSI_INT_MSK0, 0); in dw_mipi_dsi_clear_err()
740 dsi_write(dsi, DSI_INT_MSK1, 0); in dw_mipi_dsi_clear_err()
745 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); in dw_mipi_dsi_bridge_post_disable() local
753 dw_mipi_dsi_set_mode(dsi, 0); in dw_mipi_dsi_bridge_post_disable()
757 * panel unprepare before the dsi "final" disable... in dw_mipi_dsi_bridge_post_disable()
761 dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge); in dw_mipi_dsi_bridge_post_disable()
763 dw_mipi_dsi_disable(dsi); in dw_mipi_dsi_bridge_post_disable()
764 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_bridge_post_disable()
765 pm_runtime_put(dsi->dev); in dw_mipi_dsi_bridge_post_disable()
772 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); in dw_mipi_dsi_bridge_mode_set() local
773 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; in dw_mipi_dsi_bridge_mode_set()
774 void *priv_data = dsi->plat_data->priv_data; in dw_mipi_dsi_bridge_mode_set()
777 clk_prepare_enable(dsi->pclk); in dw_mipi_dsi_bridge_mode_set()
779 ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags, in dw_mipi_dsi_bridge_mode_set()
780 dsi->lanes, dsi->format, &dsi->lane_mbps); in dw_mipi_dsi_bridge_mode_set()
784 pm_runtime_get_sync(dsi->dev); in dw_mipi_dsi_bridge_mode_set()
785 dw_mipi_dsi_init(dsi); in dw_mipi_dsi_bridge_mode_set()
786 dw_mipi_dsi_dpi_config(dsi, adjusted_mode); in dw_mipi_dsi_bridge_mode_set()
787 dw_mipi_dsi_packet_handler_config(dsi); in dw_mipi_dsi_bridge_mode_set()
788 dw_mipi_dsi_video_mode_config(dsi); in dw_mipi_dsi_bridge_mode_set()
789 dw_mipi_dsi_video_packet_config(dsi, adjusted_mode); in dw_mipi_dsi_bridge_mode_set()
790 dw_mipi_dsi_command_mode_config(dsi); in dw_mipi_dsi_bridge_mode_set()
791 dw_mipi_dsi_line_timer_config(dsi, adjusted_mode); in dw_mipi_dsi_bridge_mode_set()
792 dw_mipi_dsi_vertical_timing_config(dsi, adjusted_mode); in dw_mipi_dsi_bridge_mode_set()
794 dw_mipi_dsi_dphy_init(dsi); in dw_mipi_dsi_bridge_mode_set()
795 dw_mipi_dsi_dphy_timing_config(dsi); in dw_mipi_dsi_bridge_mode_set()
796 dw_mipi_dsi_dphy_interface_config(dsi); in dw_mipi_dsi_bridge_mode_set()
798 dw_mipi_dsi_clear_err(dsi); in dw_mipi_dsi_bridge_mode_set()
804 dw_mipi_dsi_dphy_enable(dsi); in dw_mipi_dsi_bridge_mode_set()
809 dw_mipi_dsi_set_mode(dsi, 0); in dw_mipi_dsi_bridge_mode_set()
814 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); in dw_mipi_dsi_bridge_enable() local
817 dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); in dw_mipi_dsi_bridge_enable()
824 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); in dw_mipi_dsi_bridge_mode_valid() local
825 const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; in dw_mipi_dsi_bridge_mode_valid()
836 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); in dw_mipi_dsi_bridge_attach() local
846 /* Attach the panel-bridge to the dsi bridge */ in dw_mipi_dsi_bridge_attach()
847 return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge); in dw_mipi_dsi_bridge_attach()
864 struct dw_mipi_dsi *dsi; in __dw_mipi_dsi_probe() local
868 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); in __dw_mipi_dsi_probe()
869 if (!dsi) in __dw_mipi_dsi_probe()
872 dsi->dev = dev; in __dw_mipi_dsi_probe()
873 dsi->plat_data = plat_data; in __dw_mipi_dsi_probe()
885 dsi->base = devm_ioremap_resource(dev, res); in __dw_mipi_dsi_probe()
886 if (IS_ERR(dsi->base)) in __dw_mipi_dsi_probe()
890 dsi->base = plat_data->base; in __dw_mipi_dsi_probe()
893 dsi->pclk = devm_clk_get(dev, "pclk"); in __dw_mipi_dsi_probe()
894 if (IS_ERR(dsi->pclk)) { in __dw_mipi_dsi_probe()
895 ret = PTR_ERR(dsi->pclk); in __dw_mipi_dsi_probe()
915 ret = clk_prepare_enable(dsi->pclk); in __dw_mipi_dsi_probe()
925 clk_disable_unprepare(dsi->pclk); in __dw_mipi_dsi_probe()
930 dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; in __dw_mipi_dsi_probe()
931 dsi->dsi_host.dev = dev; in __dw_mipi_dsi_probe()
932 ret = mipi_dsi_host_register(&dsi->dsi_host); in __dw_mipi_dsi_probe()
938 dsi->bridge.driver_private = dsi; in __dw_mipi_dsi_probe()
939 dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs; in __dw_mipi_dsi_probe()
941 dsi->bridge.of_node = pdev->dev.of_node; in __dw_mipi_dsi_probe()
944 return dsi; in __dw_mipi_dsi_probe()
947 static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) in __dw_mipi_dsi_remove() argument
949 pm_runtime_disable(dsi->dev); in __dw_mipi_dsi_remove()
963 void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_remove() argument
965 mipi_dsi_host_unregister(&dsi->dsi_host); in dw_mipi_dsi_remove()
967 __dw_mipi_dsi_remove(dsi); in dw_mipi_dsi_remove()
978 struct dw_mipi_dsi *dsi; in dw_mipi_dsi_bind() local
981 dsi = __dw_mipi_dsi_probe(pdev, plat_data); in dw_mipi_dsi_bind()
982 if (IS_ERR(dsi)) in dw_mipi_dsi_bind()
983 return dsi; in dw_mipi_dsi_bind()
985 ret = drm_bridge_attach(encoder, &dsi->bridge, NULL); in dw_mipi_dsi_bind()
987 dw_mipi_dsi_remove(dsi); in dw_mipi_dsi_bind()
992 return dsi; in dw_mipi_dsi_bind()
996 void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi) in dw_mipi_dsi_unbind() argument
998 __dw_mipi_dsi_remove(dsi); in dw_mipi_dsi_unbind()
1004 MODULE_DESCRIPTION("DW MIPI DSI host controller driver");
1006 MODULE_ALIAS("platform:dw-mipi-dsi");