Lines Matching +full:dsi +full:- +full:lanes

1 // SPDX-License-Identifier: GPL-2.0-only
3 * DesignWare MIPI DSI Host Controller v1.02 driver
6 * Copyright (c) 2014-2016 HiSilicon Limited.
91 u32 lanes; member
98 struct dw_dsi dsi; member
152 phy->pll_vco_750M = dphy_range_info[i].pll_vco_750M; in dsi_calc_phy_rate()
153 phy->hstx_ckg_sel = dphy_range_info[i].hstx_ckg_sel; in dsi_calc_phy_rate()
155 if (phy->hstx_ckg_sel <= 7 && in dsi_calc_phy_rate()
156 phy->hstx_ckg_sel >= 4) in dsi_calc_phy_rate()
157 q_pll = 0x10 >> (7 - phy->hstx_ckg_sel); in dsi_calc_phy_rate()
191 phy->pll_fbd_p = 0; in dsi_calc_phy_rate()
192 phy->pll_pre_div1p = 1; in dsi_calc_phy_rate()
194 phy->pll_fbd_p = n_pll; in dsi_calc_phy_rate()
195 phy->pll_pre_div1p = 0; in dsi_calc_phy_rate()
198 if (phy->pll_fbd_2p <= 7 && phy->pll_fbd_2p >= 4) in dsi_calc_phy_rate()
199 r_pll = 0x10 >> (7 - phy->pll_fbd_2p); in dsi_calc_phy_rate()
202 phy->pll_pre_p = 0; in dsi_calc_phy_rate()
203 phy->pll_fbd_s = 0; in dsi_calc_phy_rate()
204 phy->pll_fbd_div1f = 0; in dsi_calc_phy_rate()
205 phy->pll_fbd_div5f = 1; in dsi_calc_phy_rate()
207 phy->pll_pre_p = m_pll / (2 * r_pll); in dsi_calc_phy_rate()
208 phy->pll_fbd_s = 0; in dsi_calc_phy_rate()
209 phy->pll_fbd_div1f = 1; in dsi_calc_phy_rate()
210 phy->pll_fbd_div5f = 0; in dsi_calc_phy_rate()
213 phy->pll_pre_p = in dsi_calc_phy_rate()
214 (m_pll / (2 * r_pll)) / 2 - 1; in dsi_calc_phy_rate()
215 phy->pll_fbd_s = in dsi_calc_phy_rate()
218 phy->pll_pre_p = in dsi_calc_phy_rate()
220 phy->pll_fbd_s = in dsi_calc_phy_rate()
223 phy->pll_fbd_div1f = 0; in dsi_calc_phy_rate()
224 phy->pll_fbd_div5f = 0; in dsi_calc_phy_rate()
226 phy->pll_pre_p = 0; in dsi_calc_phy_rate()
227 phy->pll_fbd_s = 0; in dsi_calc_phy_rate()
228 phy->pll_fbd_div1f = 0; in dsi_calc_phy_rate()
229 phy->pll_fbd_div5f = 1; in dsi_calc_phy_rate()
259 phy->clk_t_lpx = ROUND(50, 8 * ui); in dsi_get_phy_params()
260 phy->clk_t_hs_prepare = ROUND(133, 16 * ui) - 1; in dsi_get_phy_params()
262 phy->clk_t_hs_zero = ROUND(262, 8 * ui); in dsi_get_phy_params()
263 phy->clk_t_hs_trial = 2 * (ROUND(60, 8 * ui) - 1); in dsi_get_phy_params()
264 phy->clk_t_wakeup = ROUND(1000000, (ref_clk_ps / 1000) - 1); in dsi_get_phy_params()
265 if (phy->clk_t_wakeup > 0xff) in dsi_get_phy_params()
266 phy->clk_t_wakeup = 0xff; in dsi_get_phy_params()
267 phy->data_t_wakeup = phy->clk_t_wakeup; in dsi_get_phy_params()
268 phy->data_t_lpx = phy->clk_t_lpx; in dsi_get_phy_params()
269 phy->data_t_hs_prepare = ROUND(125 + 10 * ui, 16 * ui) - 1; in dsi_get_phy_params()
270 phy->data_t_hs_zero = ROUND(105 + 6 * ui, 8 * ui); in dsi_get_phy_params()
271 phy->data_t_hs_trial = 2 * (ROUND(60 + 4 * ui, 8 * ui) - 1); in dsi_get_phy_params()
272 phy->data_t_ta_go = 3; in dsi_get_phy_params()
273 phy->data_t_ta_get = 4; in dsi_get_phy_params()
275 phy->pll_enbwt = 1; in dsi_get_phy_params()
276 phy->clklp2hs_time = ROUND(407, 8 * ui) + 12; in dsi_get_phy_params()
277 phy->clkhs2lp_time = ROUND(105 + 12 * ui, 8 * ui); in dsi_get_phy_params()
278 phy->lp2hs_time = ROUND(240 + 12 * ui, 8 * ui) + 1; in dsi_get_phy_params()
279 phy->hs2lp_time = phy->clkhs2lp_time; in dsi_get_phy_params()
280 phy->clk_to_data_delay = 1 + phy->clklp2hs_time; in dsi_get_phy_params()
281 phy->data_to_clk_delay = ROUND(60 + 52 * ui, 8 * ui) + in dsi_get_phy_params()
282 phy->clkhs2lp_time; in dsi_get_phy_params()
284 phy->lane_byte_clk_kHz = phy_rate_kHz / 8; in dsi_get_phy_params()
285 phy->clk_division = in dsi_get_phy_params()
286 DIV_ROUND_UP(phy->lane_byte_clk_kHz, MAX_TX_ESC_CLK); in dsi_get_phy_params()
309 * dsi phy reg write function
332 u32 lanes) in dsi_set_phy_timer() argument
339 val = (lanes - 1) | (PHY_STOP_WAIT_TIME << 8); in dsi_set_phy_timer()
345 val = readl(base + CLKMGR_CFG) | phy->clk_division; in dsi_set_phy_timer()
351 dw_update_bits(base + PHY_TMR_CFG, 24, MASK(8), phy->hs2lp_time); in dsi_set_phy_timer()
352 dw_update_bits(base + PHY_TMR_CFG, 16, MASK(8), phy->lp2hs_time); in dsi_set_phy_timer()
354 phy->clkhs2lp_time); in dsi_set_phy_timer()
356 phy->clklp2hs_time); in dsi_set_phy_timer()
358 phy->data_to_clk_delay); in dsi_set_phy_timer()
360 phy->clk_to_data_delay); in dsi_set_phy_timer()
365 u32 lanes) in dsi_set_mipi_phy() argument
372 dsi_set_phy_timer(base, phy, lanes); in dsi_set_mipi_phy()
383 * Clock lane timing control setting: TLPX, THS-PREPARE, in dsi_set_mipi_phy()
384 * THS-ZERO, THS-TRAIL, TWAKEUP. in dsi_set_mipi_phy()
386 dsi_phy_tst_set(base, CLK_TLPX, phy->clk_t_lpx); in dsi_set_mipi_phy()
387 dsi_phy_tst_set(base, CLK_THS_PREPARE, phy->clk_t_hs_prepare); in dsi_set_mipi_phy()
388 dsi_phy_tst_set(base, CLK_THS_ZERO, phy->clk_t_hs_zero); in dsi_set_mipi_phy()
389 dsi_phy_tst_set(base, CLK_THS_TRAIL, phy->clk_t_hs_trial); in dsi_set_mipi_phy()
390 dsi_phy_tst_set(base, CLK_TWAKEUP, phy->clk_t_wakeup); in dsi_set_mipi_phy()
393 * Data lane timing control setting: TLPX, THS-PREPARE, in dsi_set_mipi_phy()
394 * THS-ZERO, THS-TRAIL, TTA-GO, TTA-GET, TWAKEUP. in dsi_set_mipi_phy()
396 for (i = 0; i < lanes; i++) { in dsi_set_mipi_phy()
397 dsi_phy_tst_set(base, DATA_TLPX(i), phy->data_t_lpx); in dsi_set_mipi_phy()
399 phy->data_t_hs_prepare); in dsi_set_mipi_phy()
400 dsi_phy_tst_set(base, DATA_THS_ZERO(i), phy->data_t_hs_zero); in dsi_set_mipi_phy()
401 dsi_phy_tst_set(base, DATA_THS_TRAIL(i), phy->data_t_hs_trial); in dsi_set_mipi_phy()
402 dsi_phy_tst_set(base, DATA_TTA_GO(i), phy->data_t_ta_go); in dsi_set_mipi_phy()
403 dsi_phy_tst_set(base, DATA_TTA_GET(i), phy->data_t_ta_get); in dsi_set_mipi_phy()
404 dsi_phy_tst_set(base, DATA_TWAKEUP(i), phy->data_t_wakeup); in dsi_set_mipi_phy()
411 dsi_phy_tst_set(base, PHY_CFG_I, phy->hstx_ckg_sel); in dsi_set_mipi_phy()
412 val = (phy->pll_fbd_div5f << 5) + (phy->pll_fbd_div1f << 4) + in dsi_set_mipi_phy()
413 (phy->pll_fbd_2p << 1) + phy->pll_enbwt; in dsi_set_mipi_phy()
415 dsi_phy_tst_set(base, PHY_CFG_PLL_II, phy->pll_fbd_p); in dsi_set_mipi_phy()
416 dsi_phy_tst_set(base, PHY_CFG_PLL_III, phy->pll_fbd_s); in dsi_set_mipi_phy()
417 val = (phy->pll_pre_div1p << 7) + phy->pll_pre_p; in dsi_set_mipi_phy()
419 val = (5 << 5) + (phy->pll_vco_750M << 4) + (phy->pll_lpf_rs << 2) + in dsi_set_mipi_phy()
420 phy->pll_lpf_cs; in dsi_set_mipi_phy()
440 delay_count--; in dsi_set_mipi_phy()
464 val = (mode->flags & DRM_MODE_FLAG_NHSYNC ? 1 : 0) << 2; in dsi_set_mode_timing()
465 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC ? 1 : 0) << 1; in dsi_set_mode_timing()
469 * The DSI IP accepts vertical timing using lines as normal, in dsi_set_mode_timing()
470 * but horizontal timing is a mixture of pixel-clocks for the in dsi_set_mode_timing()
471 * active region and byte-lane clocks for the blanking-related in dsi_set_mode_timing()
472 * timings. hfp is specified as the total hline_time in byte- in dsi_set_mode_timing()
475 pixel_clk_kHz = mode->clock; in dsi_set_mode_timing()
476 htot = mode->htotal; in dsi_set_mode_timing()
477 vtot = mode->vtotal; in dsi_set_mode_timing()
478 hfp = mode->hsync_start - mode->hdisplay; in dsi_set_mode_timing()
479 hbp = mode->htotal - mode->hsync_end; in dsi_set_mode_timing()
480 hsw = mode->hsync_end - mode->hsync_start; in dsi_set_mode_timing()
481 vfp = mode->vsync_start - mode->vdisplay; in dsi_set_mode_timing()
482 vbp = mode->vtotal - mode->vsync_end; in dsi_set_mode_timing()
483 vsw = mode->vsync_end - mode->vsync_start; in dsi_set_mode_timing()
494 /* all specified in byte-lane clocks */ in dsi_set_mode_timing()
502 writel(mode->vdisplay, base + VID_VACTIVE_LINES); in dsi_set_mode_timing()
503 writel(mode->hdisplay, base + VID_PKT_SIZE); in dsi_set_mode_timing()
537 static void dsi_mipi_init(struct dw_dsi *dsi) in dsi_mipi_init() argument
539 struct dsi_hw_ctx *ctx = dsi->ctx; in dsi_mipi_init()
540 struct mipi_phy_params *phy = &dsi->phy; in dsi_mipi_init()
541 struct drm_display_mode *mode = &dsi->cur_mode; in dsi_mipi_init()
542 u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); in dsi_mipi_init()
543 void __iomem *base = ctx->base; in dsi_mipi_init()
549 dphy_req_kHz = mode->clock * bpp / dsi->lanes; in dsi_mipi_init()
555 /* set dsi phy params */ in dsi_mipi_init()
556 dsi_set_mipi_phy(base, phy, dsi->lanes); in dsi_mipi_init()
558 /* set dsi mode timing */ in dsi_mipi_init()
559 dsi_set_mode_timing(base, phy->lane_byte_clk_kHz, mode, dsi->format); in dsi_mipi_init()
561 /* set dsi video mode */ in dsi_mipi_init()
562 dsi_set_video_mode(base, dsi->mode_flags); in dsi_mipi_init()
564 /* dsi wake up */ in dsi_mipi_init()
567 DRM_DEBUG_DRIVER("lanes=%d, pixel_clk=%d kHz, bytes_freq=%d kHz\n", in dsi_mipi_init()
568 dsi->lanes, mode->clock, phy->lane_byte_clk_kHz); in dsi_mipi_init()
573 struct dw_dsi *dsi = encoder_to_dsi(encoder); in dsi_encoder_disable() local
574 struct dsi_hw_ctx *ctx = dsi->ctx; in dsi_encoder_disable()
575 void __iomem *base = ctx->base; in dsi_encoder_disable()
577 if (!dsi->enable) in dsi_encoder_disable()
583 clk_disable_unprepare(ctx->pclk); in dsi_encoder_disable()
585 dsi->enable = false; in dsi_encoder_disable()
590 struct dw_dsi *dsi = encoder_to_dsi(encoder); in dsi_encoder_enable() local
591 struct dsi_hw_ctx *ctx = dsi->ctx; in dsi_encoder_enable()
594 if (dsi->enable) in dsi_encoder_enable()
597 ret = clk_prepare_enable(ctx->pclk); in dsi_encoder_enable()
603 dsi_mipi_init(dsi); in dsi_encoder_enable()
605 dsi->enable = true; in dsi_encoder_enable()
612 struct dw_dsi *dsi = encoder_to_dsi(encoder); in dsi_encoder_phy_mode_valid() local
614 u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); in dsi_encoder_phy_mode_valid()
619 req_kHz = mode->clock * bpp / dsi->lanes; in dsi_encoder_phy_mode_valid()
623 DRM_DEBUG_DRIVER("Checking mode %ix%i-%i@%i clock: %i...", in dsi_encoder_phy_mode_valid()
624 mode->hdisplay, mode->vdisplay, bpp, in dsi_encoder_phy_mode_valid()
625 drm_mode_vrefresh(mode), mode->clock); in dsi_encoder_phy_mode_valid()
631 if (mode->clock/dsi->lanes == lane_byte_clk_kHz/3) { in dsi_encoder_phy_mode_valid()
655 drm_for_each_crtc(crtc, encoder->dev) { in dsi_encoder_mode_valid()
662 crtc_funcs = crtc->helper_private; in dsi_encoder_mode_valid()
663 if (crtc_funcs && crtc_funcs->mode_fixup) in dsi_encoder_mode_valid()
664 if (!crtc_funcs->mode_fixup(crtc, mode, &adj_mode)) in dsi_encoder_mode_valid()
678 struct dw_dsi *dsi = encoder_to_dsi(encoder); in dsi_encoder_mode_set() local
680 drm_mode_copy(&dsi->cur_mode, adj_mode); in dsi_encoder_mode_set()
704 u32 crtc_mask = drm_of_find_possible_crtcs(drm_dev, dev->of_node); in dw_drm_encoder_init()
708 return -EINVAL; in dw_drm_encoder_init()
711 encoder->possible_crtcs = crtc_mask; in dw_drm_encoder_init()
714 DRM_ERROR("failed to init dsi encoder\n"); in dw_drm_encoder_init()
727 struct dw_dsi *dsi = host_to_dsi(host); in dsi_host_attach() local
728 struct device *dev = host->dev; in dsi_host_attach()
731 if (mdsi->lanes < 1 || mdsi->lanes > 4) { in dsi_host_attach()
732 DRM_ERROR("dsi device params invalid\n"); in dsi_host_attach()
733 return -EINVAL; in dsi_host_attach()
736 dsi->lanes = mdsi->lanes; in dsi_host_attach()
737 dsi->format = mdsi->format; in dsi_host_attach()
738 dsi->mode_flags = mdsi->mode_flags; in dsi_host_attach()
750 struct device *dev = host->dev; in dsi_host_detach()
762 static int dsi_host_init(struct device *dev, struct dw_dsi *dsi) in dsi_host_init() argument
764 struct mipi_dsi_host *host = &dsi->host; in dsi_host_init()
767 host->dev = dev; in dsi_host_init()
768 host->ops = &dsi_host_ops; in dsi_host_init()
771 DRM_ERROR("failed to register dsi host\n"); in dsi_host_init()
778 static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi) in dsi_bridge_init() argument
780 struct drm_encoder *encoder = &dsi->encoder; in dsi_bridge_init()
782 struct device_node *np = dsi->dev->of_node; in dsi_bridge_init()
786 * Get the endpoint node. In our case, dsi has one output port1 in dsi_bridge_init()
793 /* associate the bridge to dsi encoder */ in dsi_bridge_init()
800 struct dw_dsi *dsi = &ddata->dsi; in dsi_bind() local
804 ret = dw_drm_encoder_init(dev, drm_dev, &dsi->encoder); in dsi_bind()
808 ret = dsi_bridge_init(drm_dev, dsi); in dsi_bind()
825 static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi) in dsi_parse_dt() argument
827 struct dsi_hw_ctx *ctx = dsi->ctx; in dsi_parse_dt()
830 ctx->pclk = devm_clk_get(&pdev->dev, "pclk"); in dsi_parse_dt()
831 if (IS_ERR(ctx->pclk)) { in dsi_parse_dt()
833 return PTR_ERR(ctx->pclk); in dsi_parse_dt()
837 ctx->base = devm_ioremap_resource(&pdev->dev, res); in dsi_parse_dt()
838 if (IS_ERR(ctx->base)) { in dsi_parse_dt()
839 DRM_ERROR("failed to remap dsi io region\n"); in dsi_parse_dt()
840 return PTR_ERR(ctx->base); in dsi_parse_dt()
849 struct dw_dsi *dsi; in dsi_probe() local
853 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in dsi_probe()
855 DRM_ERROR("failed to allocate dsi data.\n"); in dsi_probe()
856 return -ENOMEM; in dsi_probe()
858 dsi = &data->dsi; in dsi_probe()
859 ctx = &data->ctx; in dsi_probe()
860 dsi->ctx = ctx; in dsi_probe()
861 dsi->dev = &pdev->dev; in dsi_probe()
863 ret = dsi_parse_dt(pdev, dsi); in dsi_probe()
869 ret = dsi_host_init(&pdev->dev, dsi); in dsi_probe()
879 struct dw_dsi *dsi = &data->dsi; in dsi_remove() local
881 mipi_dsi_host_unregister(&dsi->host); in dsi_remove()
885 {.compatible = "hisilicon,hi6220-dsi"},
894 .name = "dw-dsi",
904 MODULE_DESCRIPTION("DesignWare MIPI DSI Host Controller v1.02 driver");