1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2009 Nokia Corporation 4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 5 */ 6 7 #define DSS_SUBSYS_NAME "SDI" 8 9 #include <linux/kernel.h> 10 #include <linux/delay.h> 11 #include <linux/err.h> 12 #include <linux/regulator/consumer.h> 13 #include <linux/export.h> 14 #include <linux/platform_device.h> 15 #include <linux/string.h> 16 #include <linux/of.h> 17 18 #include "omapdss.h" 19 #include "dss.h" 20 21 struct sdi_device { 22 struct platform_device *pdev; 23 struct dss_device *dss; 24 25 bool update_enabled; 26 struct regulator *vdds_sdi_reg; 27 28 struct dss_lcd_mgr_config mgr_config; 29 unsigned long pixelclock; 30 int datapairs; 31 32 struct omap_dss_device output; 33 }; 34 35 #define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output) 36 37 struct sdi_clk_calc_ctx { 38 struct sdi_device *sdi; 39 unsigned long pck_min, pck_max; 40 41 unsigned long fck; 42 struct dispc_clock_info dispc_cinfo; 43 }; 44 45 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 46 unsigned long pck, void *data) 47 { 48 struct sdi_clk_calc_ctx *ctx = data; 49 50 ctx->dispc_cinfo.lck_div = lckd; 51 ctx->dispc_cinfo.pck_div = pckd; 52 ctx->dispc_cinfo.lck = lck; 53 ctx->dispc_cinfo.pck = pck; 54 55 return true; 56 } 57 58 static bool dpi_calc_dss_cb(unsigned long fck, void *data) 59 { 60 struct sdi_clk_calc_ctx *ctx = data; 61 62 ctx->fck = fck; 63 64 return dispc_div_calc(ctx->sdi->dss->dispc, fck, 65 ctx->pck_min, ctx->pck_max, 66 dpi_calc_dispc_cb, ctx); 67 } 68 69 static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk, 70 unsigned long *fck, 71 struct dispc_clock_info *dispc_cinfo) 72 { 73 int i; 74 struct sdi_clk_calc_ctx ctx; 75 76 /* 77 * DSS fclk gives us very few possibilities, so finding a good pixel 78 * clock may not be possible. We try multiple times to find the clock, 79 * each time widening the pixel clock range we look for, up to 80 * +/- 1MHz. 81 */ 82 83 for (i = 0; i < 10; ++i) { 84 bool ok; 85 86 memset(&ctx, 0, sizeof(ctx)); 87 88 ctx.sdi = sdi; 89 90 if (pclk > 1000 * i * i * i) 91 ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu); 92 else 93 ctx.pck_min = 0; 94 ctx.pck_max = pclk + 1000 * i * i * i; 95 96 ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min, 97 dpi_calc_dss_cb, &ctx); 98 if (ok) { 99 *fck = ctx.fck; 100 *dispc_cinfo = ctx.dispc_cinfo; 101 return 0; 102 } 103 } 104 105 return -EINVAL; 106 } 107 108 static void sdi_config_lcd_manager(struct sdi_device *sdi) 109 { 110 sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 111 112 sdi->mgr_config.stallmode = false; 113 sdi->mgr_config.fifohandcheck = false; 114 115 sdi->mgr_config.video_port_width = 24; 116 sdi->mgr_config.lcden_sig_polarity = 1; 117 118 dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config); 119 } 120 121 static void sdi_display_enable(struct omap_dss_device *dssdev) 122 { 123 struct sdi_device *sdi = dssdev_to_sdi(dssdev); 124 struct dispc_clock_info dispc_cinfo; 125 unsigned long fck; 126 int r; 127 128 r = regulator_enable(sdi->vdds_sdi_reg); 129 if (r) 130 return; 131 132 r = dispc_runtime_get(sdi->dss->dispc); 133 if (r) 134 goto err_get_dispc; 135 136 r = sdi_calc_clock_div(sdi, sdi->pixelclock, &fck, &dispc_cinfo); 137 if (r) 138 goto err_calc_clock_div; 139 140 sdi->mgr_config.clock_info = dispc_cinfo; 141 142 r = dss_set_fck_rate(sdi->dss, fck); 143 if (r) 144 goto err_set_dss_clock_div; 145 146 sdi_config_lcd_manager(sdi); 147 148 /* 149 * LCLK and PCLK divisors are located in shadow registers, and we 150 * normally write them to DISPC registers when enabling the output. 151 * However, SDI uses pck-free as source clock for its PLL, and pck-free 152 * is affected by the divisors. And as we need the PLL before enabling 153 * the output, we need to write the divisors early. 154 * 155 * It seems just writing to the DISPC register is enough, and we don't 156 * need to care about the shadow register mechanism for pck-free. The 157 * exact reason for this is unknown. 158 */ 159 dispc_mgr_set_clock_div(sdi->dss->dispc, sdi->output.dispc_channel, 160 &sdi->mgr_config.clock_info); 161 162 dss_sdi_init(sdi->dss, sdi->datapairs); 163 r = dss_sdi_enable(sdi->dss); 164 if (r) 165 goto err_sdi_enable; 166 mdelay(2); 167 168 r = dss_mgr_enable(&sdi->output); 169 if (r) 170 goto err_mgr_enable; 171 172 return; 173 174 err_mgr_enable: 175 dss_sdi_disable(sdi->dss); 176 err_sdi_enable: 177 err_set_dss_clock_div: 178 err_calc_clock_div: 179 dispc_runtime_put(sdi->dss->dispc); 180 err_get_dispc: 181 regulator_disable(sdi->vdds_sdi_reg); 182 } 183 184 static void sdi_display_disable(struct omap_dss_device *dssdev) 185 { 186 struct sdi_device *sdi = dssdev_to_sdi(dssdev); 187 188 dss_mgr_disable(&sdi->output); 189 190 dss_sdi_disable(sdi->dss); 191 192 dispc_runtime_put(sdi->dss->dispc); 193 194 regulator_disable(sdi->vdds_sdi_reg); 195 } 196 197 static void sdi_set_timings(struct omap_dss_device *dssdev, 198 const struct drm_display_mode *mode) 199 { 200 struct sdi_device *sdi = dssdev_to_sdi(dssdev); 201 202 sdi->pixelclock = mode->clock * 1000; 203 } 204 205 static int sdi_check_timings(struct omap_dss_device *dssdev, 206 struct drm_display_mode *mode) 207 { 208 struct sdi_device *sdi = dssdev_to_sdi(dssdev); 209 struct dispc_clock_info dispc_cinfo; 210 unsigned long pixelclock = mode->clock * 1000; 211 unsigned long fck; 212 unsigned long pck; 213 int r; 214 215 if (pixelclock == 0) 216 return -EINVAL; 217 218 r = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo); 219 if (r) 220 return r; 221 222 pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; 223 224 if (pck != pixelclock) { 225 DSSWARN("Pixel clock adjusted from %lu Hz to %lu Hz\n", 226 pixelclock, pck); 227 228 mode->clock = pck / 1000; 229 } 230 231 return 0; 232 } 233 234 static int sdi_connect(struct omap_dss_device *src, 235 struct omap_dss_device *dst) 236 { 237 return omapdss_device_connect(dst->dss, dst, dst->next); 238 } 239 240 static void sdi_disconnect(struct omap_dss_device *src, 241 struct omap_dss_device *dst) 242 { 243 omapdss_device_disconnect(dst, dst->next); 244 } 245 246 static const struct omap_dss_device_ops sdi_ops = { 247 .connect = sdi_connect, 248 .disconnect = sdi_disconnect, 249 250 .enable = sdi_display_enable, 251 .disable = sdi_display_disable, 252 253 .check_timings = sdi_check_timings, 254 .set_timings = sdi_set_timings, 255 }; 256 257 static int sdi_init_output(struct sdi_device *sdi) 258 { 259 struct omap_dss_device *out = &sdi->output; 260 int r; 261 262 out->dev = &sdi->pdev->dev; 263 out->id = OMAP_DSS_OUTPUT_SDI; 264 out->type = OMAP_DISPLAY_TYPE_SDI; 265 out->name = "sdi.0"; 266 out->dispc_channel = OMAP_DSS_CHANNEL_LCD; 267 /* We have SDI only on OMAP3, where it's on port 1 */ 268 out->of_ports = BIT(1); 269 out->ops = &sdi_ops; 270 out->owner = THIS_MODULE; 271 out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE /* 15.5.9.1.2 */ 272 | DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE; 273 274 r = omapdss_device_init_output(out); 275 if (r < 0) 276 return r; 277 278 omapdss_device_register(out); 279 280 return 0; 281 } 282 283 static void sdi_uninit_output(struct sdi_device *sdi) 284 { 285 omapdss_device_unregister(&sdi->output); 286 omapdss_device_cleanup_output(&sdi->output); 287 } 288 289 int sdi_init_port(struct dss_device *dss, struct platform_device *pdev, 290 struct device_node *port) 291 { 292 struct sdi_device *sdi; 293 struct device_node *ep; 294 u32 datapairs; 295 int r; 296 297 sdi = kzalloc(sizeof(*sdi), GFP_KERNEL); 298 if (!sdi) 299 return -ENOMEM; 300 301 ep = of_get_next_child(port, NULL); 302 if (!ep) { 303 r = 0; 304 goto err_free; 305 } 306 307 r = of_property_read_u32(ep, "datapairs", &datapairs); 308 of_node_put(ep); 309 if (r) { 310 DSSERR("failed to parse datapairs\n"); 311 goto err_free; 312 } 313 314 sdi->datapairs = datapairs; 315 sdi->dss = dss; 316 317 sdi->pdev = pdev; 318 port->data = sdi; 319 320 sdi->vdds_sdi_reg = devm_regulator_get(&pdev->dev, "vdds_sdi"); 321 if (IS_ERR(sdi->vdds_sdi_reg)) { 322 r = PTR_ERR(sdi->vdds_sdi_reg); 323 if (r != -EPROBE_DEFER) 324 DSSERR("can't get VDDS_SDI regulator\n"); 325 goto err_free; 326 } 327 328 r = sdi_init_output(sdi); 329 if (r) 330 goto err_free; 331 332 return 0; 333 334 err_free: 335 kfree(sdi); 336 337 return r; 338 } 339 340 void sdi_uninit_port(struct device_node *port) 341 { 342 struct sdi_device *sdi = port->data; 343 344 if (!sdi) 345 return; 346 347 sdi_uninit_output(sdi); 348 kfree(sdi); 349 } 350