Lines Matching +full:stm32 +full:- +full:dsi
1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/clk-provider.h>
28 /* DSI digital registers & bit definitions */
32 /* DSI wrapper registers & bit definitions */
35 #define WCFGR_DSIM BIT(0) /* DSI Mode */
39 #define WCR_DSIEN BIT(3) /* DSI ENable */
63 /* dsi color format coding according to the datasheet */
86 struct dw_mipi_dsi *dsi; member
94 static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) in dsi_write() argument
96 writel(val, dsi->base + reg); in dsi_write()
99 static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg) in dsi_read() argument
101 return readl(dsi->base + reg); in dsi_read()
104 static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) in dsi_set() argument
106 dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); in dsi_set()
109 static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) in dsi_clear() argument
111 dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); in dsi_clear()
114 static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg, in dsi_update_bits() argument
117 dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); in dsi_update_bits()
148 static int dsi_pll_get_params(struct dw_mipi_dsi_stm *dsi, in dsi_pll_get_params() argument
157 return -EINVAL; in dsi_pll_get_params()
159 fvco_min = dsi->lane_min_kbps * 2 * ODF_MAX; in dsi_pll_get_params()
160 fvco_max = dsi->lane_max_kbps * 2 * ODF_MIN; in dsi_pll_get_params()
185 delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) - in dsi_pll_get_params()
188 delta = -delta; in dsi_pll_get_params()
209 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(clk); in dw_mipi_dsi_clk_disable() local
213 /* Disable the DSI PLL */ in dw_mipi_dsi_clk_disable()
214 dsi_clear(dsi, DSI_WRPCR, WRPCR_PLLEN); in dw_mipi_dsi_clk_disable()
217 dsi_clear(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); in dw_mipi_dsi_clk_disable()
222 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(clk); in dw_mipi_dsi_clk_enable() local
229 dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); in dw_mipi_dsi_clk_enable()
230 ret = readl_poll_timeout_atomic(dsi->base + DSI_WISR, val, val & WISR_RRS, in dw_mipi_dsi_clk_enable()
235 /* Enable the DSI PLL & wait for its lock */ in dw_mipi_dsi_clk_enable()
236 dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); in dw_mipi_dsi_clk_enable()
237 ret = readl_poll_timeout_atomic(dsi->base + DSI_WISR, val, val & WISR_PLLLS, in dw_mipi_dsi_clk_enable()
247 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); in dw_mipi_dsi_clk_is_enabled() local
249 return dsi_read(dsi, DSI_WRPCR) & WRPCR_PLLEN; in dw_mipi_dsi_clk_is_enabled()
255 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); in dw_mipi_dsi_clk_recalc_rate() local
263 val = dsi_read(dsi, DSI_WRPCR); in dw_mipi_dsi_clk_recalc_rate()
280 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); in dw_mipi_dsi_clk_round_rate() local
293 ret = dsi_pll_get_params(dsi, pll_in_khz, rate / 1000, in dw_mipi_dsi_clk_round_rate()
307 struct dw_mipi_dsi_stm *dsi = clk_to_dw_mipi_dsi_stm(hw); in dw_mipi_dsi_clk_set_rate() local
321 ret = dsi_pll_get_params(dsi, pll_in_khz, rate / 1000, &idf, &ndiv, &odf); in dw_mipi_dsi_clk_set_rate()
329 dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, in dw_mipi_dsi_clk_set_rate()
330 (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); in dw_mipi_dsi_clk_set_rate()
332 /* Compute uix4 & set the bit period in high-speed mode */ in dw_mipi_dsi_clk_set_rate()
334 dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); in dw_mipi_dsi_clk_set_rate()
341 struct dw_mipi_dsi_stm *dsi = data; in dw_mipi_dsi_clk_unregister() local
345 of_clk_del_provider(dsi->dev->of_node); in dw_mipi_dsi_clk_unregister()
346 clk_hw_unregister(&dsi->txbyte_clk); in dw_mipi_dsi_clk_unregister()
365 static int dw_mipi_dsi_clk_register(struct dw_mipi_dsi_stm *dsi, in dw_mipi_dsi_clk_register() argument
368 struct device_node *node = dev->of_node; in dw_mipi_dsi_clk_register()
373 dsi->txbyte_clk.init = &cdata_init; in dw_mipi_dsi_clk_register()
375 ret = clk_hw_register(dev, &dsi->txbyte_clk); in dw_mipi_dsi_clk_register()
380 &dsi->txbyte_clk); in dw_mipi_dsi_clk_register()
382 clk_hw_unregister(&dsi->txbyte_clk); in dw_mipi_dsi_clk_register()
389 struct dw_mipi_dsi_stm *dsi = priv_data; in dw_mipi_dsi_phy_init() local
392 ret = clk_prepare_enable(dsi->txbyte_clk.clk); in dw_mipi_dsi_phy_init()
398 struct dw_mipi_dsi_stm *dsi = priv_data; in dw_mipi_dsi_phy_power_on() local
402 /* Enable the DSI wrapper */ in dw_mipi_dsi_phy_power_on()
403 dsi_set(dsi, DSI_WCR, WCR_DSIEN); in dw_mipi_dsi_phy_power_on()
408 struct dw_mipi_dsi_stm *dsi = priv_data; in dw_mipi_dsi_phy_power_off() local
412 clk_disable_unprepare(dsi->txbyte_clk.clk); in dw_mipi_dsi_phy_power_off()
414 /* Disable the DSI wrapper */ in dw_mipi_dsi_phy_power_off()
415 dsi_clear(dsi, DSI_WCR, WCR_DSIEN); in dw_mipi_dsi_phy_power_off()
423 struct dw_mipi_dsi_stm *dsi = priv_data; in dw_mipi_dsi_get_lane_mbps() local
427 pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); in dw_mipi_dsi_get_lane_mbps()
431 pll_out_khz = mode->clock * bpp / lanes; in dw_mipi_dsi_get_lane_mbps()
437 if (pll_out_khz > dsi->lane_max_kbps) { in dw_mipi_dsi_get_lane_mbps()
438 pll_out_khz = dsi->lane_max_kbps; in dw_mipi_dsi_get_lane_mbps()
441 if (pll_out_khz < dsi->lane_min_kbps) { in dw_mipi_dsi_get_lane_mbps()
442 pll_out_khz = dsi->lane_min_kbps; in dw_mipi_dsi_get_lane_mbps()
446 ret = clk_set_rate((dsi->txbyte_clk.clk), pll_out_khz * 1000); in dw_mipi_dsi_get_lane_mbps()
448 DRM_DEBUG_DRIVER("ERROR Could not set rate of %d to %s clk->name", in dw_mipi_dsi_get_lane_mbps()
449 pll_out_khz, clk_hw_get_name(&dsi->txbyte_clk)); in dw_mipi_dsi_get_lane_mbps()
452 dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM); in dw_mipi_dsi_get_lane_mbps()
455 dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX, in dw_mipi_dsi_get_lane_mbps()
479 timing->clk_hs2lp = DSI_PHY_DELAY(272, 136, lane_mbps); in dw_mipi_dsi_phy_get_timing()
480 timing->clk_lp2hs = DSI_PHY_DELAY(512, 40, lane_mbps); in dw_mipi_dsi_phy_get_timing()
481 timing->data_hs2lp = DSI_PHY_DELAY(192, 64, lane_mbps); in dw_mipi_dsi_phy_get_timing()
482 timing->data_lp2hs = DSI_PHY_DELAY(256, 32, lane_mbps); in dw_mipi_dsi_phy_get_timing()
494 struct dw_mipi_dsi_stm *dsi = priv_data; in dw_mipi_dsi_stm_mode_valid() local
503 pll_out_khz = mode->clock * bpp / lanes; in dw_mipi_dsi_stm_mode_valid()
505 if (pll_out_khz > dsi->lane_max_kbps) in dw_mipi_dsi_stm_mode_valid()
512 if (pll_out_khz < dsi->lane_min_kbps) in dw_mipi_dsi_stm_mode_valid()
520 pll_in_khz = clk_get_rate(dsi->pllref_clk) / 1000; in dw_mipi_dsi_stm_mode_valid()
521 ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, &idf, &ndiv, &odf); in dw_mipi_dsi_stm_mode_valid()
536 target_px_clock_hz = mode->clock * 1000; in dw_mipi_dsi_stm_mode_valid()
541 if (px_clock_hz < target_px_clock_hz - CLK_TOLERANCE_HZ || in dw_mipi_dsi_stm_mode_valid()
545 /* sync packets are codes as DSI short packets (4 bytes) */ in dw_mipi_dsi_stm_mode_valid()
548 hfp = mode->hsync_start - mode->hdisplay; in dw_mipi_dsi_stm_mode_valid()
549 hsync = mode->hsync_end - mode->hsync_start; in dw_mipi_dsi_stm_mode_valid()
550 hbp = mode->htotal - mode->hsync_end; in dw_mipi_dsi_stm_mode_valid()
560 hbp -= dsi_short_packet_size_px; in dw_mipi_dsi_stm_mode_valid()
563 hbp += hsync - dsi_short_packet_size_px; in dw_mipi_dsi_stm_mode_valid()
571 * In non-burst mode DSI has to enter in LP during HFP in dw_mipi_dsi_stm_mode_valid()
599 { .compatible = "st,stm32-dsi", .data = &dw_mipi_dsi_stm_plat_data, },
606 struct device *dev = &pdev->dev; in dw_mipi_dsi_stm_probe()
607 struct dw_mipi_dsi_stm *dsi; in dw_mipi_dsi_stm_probe() local
611 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); in dw_mipi_dsi_stm_probe()
612 if (!dsi) in dw_mipi_dsi_stm_probe()
613 return -ENOMEM; in dw_mipi_dsi_stm_probe()
615 dsi->base = devm_platform_ioremap_resource(pdev, 0); in dw_mipi_dsi_stm_probe()
616 if (IS_ERR(dsi->base)) { in dw_mipi_dsi_stm_probe()
617 ret = PTR_ERR(dsi->base); in dw_mipi_dsi_stm_probe()
618 DRM_ERROR("Unable to get dsi registers %d\n", ret); in dw_mipi_dsi_stm_probe()
622 dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi"); in dw_mipi_dsi_stm_probe()
623 if (IS_ERR(dsi->vdd_supply)) { in dw_mipi_dsi_stm_probe()
624 ret = PTR_ERR(dsi->vdd_supply); in dw_mipi_dsi_stm_probe()
629 ret = regulator_enable(dsi->vdd_supply); in dw_mipi_dsi_stm_probe()
635 dsi->pllref_clk = devm_clk_get(dev, "ref"); in dw_mipi_dsi_stm_probe()
636 if (IS_ERR(dsi->pllref_clk)) { in dw_mipi_dsi_stm_probe()
637 ret = PTR_ERR(dsi->pllref_clk); in dw_mipi_dsi_stm_probe()
642 ret = clk_prepare_enable(dsi->pllref_clk); in dw_mipi_dsi_stm_probe()
648 dsi->pclk = devm_clk_get(dev, "pclk"); in dw_mipi_dsi_stm_probe()
649 if (IS_ERR(dsi->pclk)) { in dw_mipi_dsi_stm_probe()
650 ret = PTR_ERR(dsi->pclk); in dw_mipi_dsi_stm_probe()
655 ret = clk_prepare_enable(dsi->pclk); in dw_mipi_dsi_stm_probe()
661 dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; in dw_mipi_dsi_stm_probe()
662 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_stm_probe()
664 if (dsi->hw_version != HWVER_130 && dsi->hw_version != HWVER_131) { in dw_mipi_dsi_stm_probe()
665 ret = -ENODEV; in dw_mipi_dsi_stm_probe()
666 DRM_ERROR("bad dsi hardware version\n"); in dw_mipi_dsi_stm_probe()
671 dsi->lane_min_kbps = LANE_MIN_KBPS; in dw_mipi_dsi_stm_probe()
672 dsi->lane_max_kbps = LANE_MAX_KBPS; in dw_mipi_dsi_stm_probe()
673 if (dsi->hw_version == HWVER_131) { in dw_mipi_dsi_stm_probe()
674 dsi->lane_min_kbps *= 2; in dw_mipi_dsi_stm_probe()
675 dsi->lane_max_kbps *= 2; in dw_mipi_dsi_stm_probe()
678 dsi->pdata = *pdata; in dw_mipi_dsi_stm_probe()
679 dsi->pdata.base = dsi->base; in dw_mipi_dsi_stm_probe()
680 dsi->pdata.priv_data = dsi; in dw_mipi_dsi_stm_probe()
682 dsi->pdata.max_data_lanes = 2; in dw_mipi_dsi_stm_probe()
683 dsi->pdata.phy_ops = &dw_mipi_dsi_stm_phy_ops; in dw_mipi_dsi_stm_probe()
685 platform_set_drvdata(pdev, dsi); in dw_mipi_dsi_stm_probe()
687 dsi->dsi = dw_mipi_dsi_probe(pdev, &dsi->pdata); in dw_mipi_dsi_stm_probe()
688 if (IS_ERR(dsi->dsi)) { in dw_mipi_dsi_stm_probe()
689 ret = PTR_ERR(dsi->dsi); in dw_mipi_dsi_stm_probe()
690 dev_err_probe(dev, ret, "Failed to initialize mipi dsi host\n"); in dw_mipi_dsi_stm_probe()
698 ret = clk_prepare_enable(dsi->pclk); in dw_mipi_dsi_stm_probe()
704 ret = dw_mipi_dsi_clk_register(dsi, dev); in dw_mipi_dsi_stm_probe()
706 DRM_ERROR("Failed to register DSI pixel clock: %d\n", ret); in dw_mipi_dsi_stm_probe()
707 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_stm_probe()
711 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_stm_probe()
716 clk_disable_unprepare(dsi->pllref_clk); in dw_mipi_dsi_stm_probe()
718 regulator_disable(dsi->vdd_supply); in dw_mipi_dsi_stm_probe()
725 struct dw_mipi_dsi_stm *dsi = platform_get_drvdata(pdev); in dw_mipi_dsi_stm_remove() local
727 dw_mipi_dsi_remove(dsi->dsi); in dw_mipi_dsi_stm_remove()
728 clk_disable_unprepare(dsi->pllref_clk); in dw_mipi_dsi_stm_remove()
729 dw_mipi_dsi_clk_unregister(dsi); in dw_mipi_dsi_stm_remove()
730 regulator_disable(dsi->vdd_supply); in dw_mipi_dsi_stm_remove()
735 struct dw_mipi_dsi_stm *dsi = dev_get_drvdata(dev); in dw_mipi_dsi_stm_suspend() local
739 clk_disable_unprepare(dsi->pllref_clk); in dw_mipi_dsi_stm_suspend()
740 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_stm_suspend()
741 regulator_disable(dsi->vdd_supply); in dw_mipi_dsi_stm_suspend()
748 struct dw_mipi_dsi_stm *dsi = dev_get_drvdata(dev); in dw_mipi_dsi_stm_resume() local
753 ret = regulator_enable(dsi->vdd_supply); in dw_mipi_dsi_stm_resume()
759 ret = clk_prepare_enable(dsi->pclk); in dw_mipi_dsi_stm_resume()
761 regulator_disable(dsi->vdd_supply); in dw_mipi_dsi_stm_resume()
766 ret = clk_prepare_enable(dsi->pllref_clk); in dw_mipi_dsi_stm_resume()
768 clk_disable_unprepare(dsi->pclk); in dw_mipi_dsi_stm_resume()
769 regulator_disable(dsi->vdd_supply); in dw_mipi_dsi_stm_resume()
789 .name = "stm32-display-dsi",
798 MODULE_DESCRIPTION("STMicroelectronics DW MIPI DSI host controller driver");