1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) STMicroelectronics SA 2017 4 * 5 * Authors: Philippe Cornu <philippe.cornu@st.com> 6 * Yannick Fertre <yannick.fertre@st.com> 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/iopoll.h> 11 #include <linux/module.h> 12 #include <drm/drmP.h> 13 #include <drm/drm_mipi_dsi.h> 14 #include <drm/bridge/dw_mipi_dsi.h> 15 #include <video/mipi_display.h> 16 17 #define HWVER_130 0x31333000 /* IP version 1.30 */ 18 #define HWVER_131 0x31333100 /* IP version 1.31 */ 19 20 /* DSI digital registers & bit definitions */ 21 #define DSI_VERSION 0x00 22 #define VERSION GENMASK(31, 8) 23 24 /* DSI wrapper registers & bit definitions */ 25 /* Note: registers are named as in the Reference Manual */ 26 #define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ 27 #define WCFGR_DSIM BIT(0) /* DSI Mode */ 28 #define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */ 29 30 #define DSI_WCR 0x0404 /* Wrapper Control Reg */ 31 #define WCR_DSIEN BIT(3) /* DSI ENable */ 32 33 #define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */ 34 #define WISR_PLLLS BIT(8) /* PLL Lock Status */ 35 #define WISR_RRS BIT(12) /* Regulator Ready Status */ 36 37 #define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */ 38 #define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */ 39 #define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */ 40 41 #define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */ 42 #define WRPCR_PLLEN BIT(0) /* PLL ENable */ 43 #define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */ 44 #define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */ 45 #define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */ 46 #define WRPCR_REGEN BIT(24) /* REGulator ENable */ 47 #define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */ 48 #define IDF_MIN 1 49 #define IDF_MAX 7 50 #define NDIV_MIN 10 51 #define NDIV_MAX 125 52 #define ODF_MIN 1 53 #define ODF_MAX 8 54 55 /* dsi color format coding according to the datasheet */ 56 enum dsi_color { 57 DSI_RGB565_CONF1, 58 DSI_RGB565_CONF2, 59 DSI_RGB565_CONF3, 60 DSI_RGB666_CONF1, 61 DSI_RGB666_CONF2, 62 DSI_RGB888, 63 }; 64 65 #define LANE_MIN_KBPS 31250 66 #define LANE_MAX_KBPS 500000 67 68 /* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */ 69 #define SLEEP_US 1000 70 #define TIMEOUT_US 200000 71 72 struct dw_mipi_dsi_stm { 73 void __iomem *base; 74 struct clk *pllref_clk; 75 struct dw_mipi_dsi *dsi; 76 u32 hw_version; 77 int lane_min_kbps; 78 int lane_max_kbps; 79 }; 80 81 static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) 82 { 83 writel(val, dsi->base + reg); 84 } 85 86 static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg) 87 { 88 return readl(dsi->base + reg); 89 } 90 91 static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) 92 { 93 dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); 94 } 95 96 static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) 97 { 98 dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); 99 } 100 101 static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg, 102 u32 mask, u32 val) 103 { 104 dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); 105 } 106 107 static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt) 108 { 109 switch (fmt) { 110 case MIPI_DSI_FMT_RGB888: 111 return DSI_RGB888; 112 case MIPI_DSI_FMT_RGB666: 113 return DSI_RGB666_CONF2; 114 case MIPI_DSI_FMT_RGB666_PACKED: 115 return DSI_RGB666_CONF1; 116 case MIPI_DSI_FMT_RGB565: 117 return DSI_RGB565_CONF1; 118 default: 119 DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n"); 120 } 121 return DSI_RGB888; 122 } 123 124 static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf) 125 { 126 int divisor = idf * odf; 127 128 /* prevent from division by 0 */ 129 if (!divisor) 130 return 0; 131 132 return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor); 133 } 134 135 static int dsi_pll_get_params(struct dw_mipi_dsi_stm *dsi, 136 int clkin_khz, int clkout_khz, 137 int *idf, int *ndiv, int *odf) 138 { 139 int i, o, n, n_min, n_max; 140 int fvco_min, fvco_max, delta, best_delta; /* all in khz */ 141 142 /* Early checks preventing division by 0 & odd results */ 143 if (clkin_khz <= 0 || clkout_khz <= 0) 144 return -EINVAL; 145 146 fvco_min = dsi->lane_min_kbps * 2 * ODF_MAX; 147 fvco_max = dsi->lane_max_kbps * 2 * ODF_MIN; 148 149 best_delta = 1000000; /* big started value (1000000khz) */ 150 151 for (i = IDF_MIN; i <= IDF_MAX; i++) { 152 /* Compute ndiv range according to Fvco */ 153 n_min = ((fvco_min * i) / (2 * clkin_khz)) + 1; 154 n_max = (fvco_max * i) / (2 * clkin_khz); 155 156 /* No need to continue idf loop if we reach ndiv max */ 157 if (n_min >= NDIV_MAX) 158 break; 159 160 /* Clamp ndiv to valid values */ 161 if (n_min < NDIV_MIN) 162 n_min = NDIV_MIN; 163 if (n_max > NDIV_MAX) 164 n_max = NDIV_MAX; 165 166 for (o = ODF_MIN; o <= ODF_MAX; o *= 2) { 167 n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz); 168 /* Check ndiv according to vco range */ 169 if (n < n_min || n > n_max) 170 continue; 171 /* Check if new delta is better & saves parameters */ 172 delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) - 173 clkout_khz; 174 if (delta < 0) 175 delta = -delta; 176 if (delta < best_delta) { 177 *idf = i; 178 *ndiv = n; 179 *odf = o; 180 best_delta = delta; 181 } 182 /* fast return in case of "perfect result" */ 183 if (!delta) 184 return 0; 185 } 186 } 187 188 return 0; 189 } 190 191 static int dw_mipi_dsi_phy_init(void *priv_data) 192 { 193 struct dw_mipi_dsi_stm *dsi = priv_data; 194 u32 val; 195 int ret; 196 197 /* Enable the regulator */ 198 dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); 199 ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, 200 SLEEP_US, TIMEOUT_US); 201 if (ret) 202 DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n"); 203 204 /* Enable the DSI PLL & wait for its lock */ 205 dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); 206 ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, 207 SLEEP_US, TIMEOUT_US); 208 if (ret) 209 DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n"); 210 211 /* Enable the DSI wrapper */ 212 dsi_set(dsi, DSI_WCR, WCR_DSIEN); 213 214 return 0; 215 } 216 217 static int 218 dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode, 219 unsigned long mode_flags, u32 lanes, u32 format, 220 unsigned int *lane_mbps) 221 { 222 struct dw_mipi_dsi_stm *dsi = priv_data; 223 unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz; 224 int ret, bpp; 225 u32 val; 226 227 /* Update lane capabilities according to hw version */ 228 dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; 229 dsi->lane_min_kbps = LANE_MIN_KBPS; 230 dsi->lane_max_kbps = LANE_MAX_KBPS; 231 if (dsi->hw_version == HWVER_131) { 232 dsi->lane_min_kbps *= 2; 233 dsi->lane_max_kbps *= 2; 234 } 235 236 pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); 237 238 /* Compute requested pll out */ 239 bpp = mipi_dsi_pixel_format_to_bpp(format); 240 pll_out_khz = mode->clock * bpp / lanes; 241 /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ 242 pll_out_khz = (pll_out_khz * 12) / 10; 243 if (pll_out_khz > dsi->lane_max_kbps) { 244 pll_out_khz = dsi->lane_max_kbps; 245 DRM_WARN("Warning max phy mbps is used\n"); 246 } 247 if (pll_out_khz < dsi->lane_min_kbps) { 248 pll_out_khz = dsi->lane_min_kbps; 249 DRM_WARN("Warning min phy mbps is used\n"); 250 } 251 252 /* Compute best pll parameters */ 253 idf = 0; 254 ndiv = 0; 255 odf = 0; 256 ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, 257 &idf, &ndiv, &odf); 258 if (ret) 259 DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); 260 261 /* Get the adjusted pll out value */ 262 pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); 263 264 /* Set the PLL division factors */ 265 dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, 266 (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); 267 268 /* Compute uix4 & set the bit period in high-speed mode */ 269 val = 4000000 / pll_out_khz; 270 dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); 271 272 /* Select video mode by resetting DSIM bit */ 273 dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM); 274 275 /* Select the color coding */ 276 dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX, 277 dsi_color_from_mipi(format) << 1); 278 279 *lane_mbps = pll_out_khz / 1000; 280 281 DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", 282 pll_in_khz, pll_out_khz, *lane_mbps); 283 284 return 0; 285 } 286 287 static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { 288 .init = dw_mipi_dsi_phy_init, 289 .get_lane_mbps = dw_mipi_dsi_get_lane_mbps, 290 }; 291 292 static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = { 293 .max_data_lanes = 2, 294 .phy_ops = &dw_mipi_dsi_stm_phy_ops, 295 }; 296 297 static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = { 298 { .compatible = "st,stm32-dsi", .data = &dw_mipi_dsi_stm_plat_data, }, 299 { }, 300 }; 301 MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids); 302 303 static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) 304 { 305 struct device *dev = &pdev->dev; 306 struct dw_mipi_dsi_stm *dsi; 307 struct resource *res; 308 int ret; 309 310 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); 311 if (!dsi) 312 return -ENOMEM; 313 314 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 315 dsi->base = devm_ioremap_resource(dev, res); 316 if (IS_ERR(dsi->base)) { 317 DRM_ERROR("Unable to get dsi registers\n"); 318 return PTR_ERR(dsi->base); 319 } 320 321 dsi->pllref_clk = devm_clk_get(dev, "ref"); 322 if (IS_ERR(dsi->pllref_clk)) { 323 ret = PTR_ERR(dsi->pllref_clk); 324 dev_err(dev, "Unable to get pll reference clock: %d\n", ret); 325 return ret; 326 } 327 328 ret = clk_prepare_enable(dsi->pllref_clk); 329 if (ret) { 330 dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__); 331 return ret; 332 } 333 334 dw_mipi_dsi_stm_plat_data.base = dsi->base; 335 dw_mipi_dsi_stm_plat_data.priv_data = dsi; 336 337 platform_set_drvdata(pdev, dsi); 338 339 dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data); 340 if (IS_ERR(dsi->dsi)) { 341 DRM_ERROR("Failed to initialize mipi dsi host\n"); 342 clk_disable_unprepare(dsi->pllref_clk); 343 return PTR_ERR(dsi->dsi); 344 } 345 346 return 0; 347 } 348 349 static int dw_mipi_dsi_stm_remove(struct platform_device *pdev) 350 { 351 struct dw_mipi_dsi_stm *dsi = platform_get_drvdata(pdev); 352 353 clk_disable_unprepare(dsi->pllref_clk); 354 dw_mipi_dsi_remove(dsi->dsi); 355 356 return 0; 357 } 358 359 static struct platform_driver dw_mipi_dsi_stm_driver = { 360 .probe = dw_mipi_dsi_stm_probe, 361 .remove = dw_mipi_dsi_stm_remove, 362 .driver = { 363 .of_match_table = dw_mipi_dsi_stm_dt_ids, 364 .name = "stm32-display-dsi", 365 }, 366 }; 367 368 module_platform_driver(dw_mipi_dsi_stm_driver); 369 370 MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>"); 371 MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>"); 372 MODULE_DESCRIPTION("STMicroelectronics DW MIPI DSI host controller driver"); 373 MODULE_LICENSE("GPL v2"); 374