Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2009 Nokia Corporation
0004  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
0005  */
0006 
0007 #define DSS_SUBSYS_NAME "SDI"
0008 
0009 #include <linux/delay.h>
0010 #include <linux/err.h>
0011 #include <linux/export.h>
0012 #include <linux/kernel.h>
0013 #include <linux/of.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/consumer.h>
0016 #include <linux/string.h>
0017 
0018 #include <drm/drm_bridge.h>
0019 
0020 #include "dss.h"
0021 #include "omapdss.h"
0022 
0023 struct sdi_device {
0024     struct platform_device *pdev;
0025     struct dss_device *dss;
0026 
0027     bool update_enabled;
0028     struct regulator *vdds_sdi_reg;
0029 
0030     struct dss_lcd_mgr_config mgr_config;
0031     unsigned long pixelclock;
0032     int datapairs;
0033 
0034     struct omap_dss_device output;
0035     struct drm_bridge bridge;
0036 };
0037 
0038 #define drm_bridge_to_sdi(bridge) \
0039     container_of(bridge, struct sdi_device, bridge)
0040 
0041 struct sdi_clk_calc_ctx {
0042     struct sdi_device *sdi;
0043     unsigned long pck_min, pck_max;
0044 
0045     unsigned long fck;
0046     struct dispc_clock_info dispc_cinfo;
0047 };
0048 
0049 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
0050         unsigned long pck, void *data)
0051 {
0052     struct sdi_clk_calc_ctx *ctx = data;
0053 
0054     ctx->dispc_cinfo.lck_div = lckd;
0055     ctx->dispc_cinfo.pck_div = pckd;
0056     ctx->dispc_cinfo.lck = lck;
0057     ctx->dispc_cinfo.pck = pck;
0058 
0059     return true;
0060 }
0061 
0062 static bool dpi_calc_dss_cb(unsigned long fck, void *data)
0063 {
0064     struct sdi_clk_calc_ctx *ctx = data;
0065 
0066     ctx->fck = fck;
0067 
0068     return dispc_div_calc(ctx->sdi->dss->dispc, fck,
0069                   ctx->pck_min, ctx->pck_max,
0070                   dpi_calc_dispc_cb, ctx);
0071 }
0072 
0073 static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
0074                   unsigned long *fck,
0075                   struct dispc_clock_info *dispc_cinfo)
0076 {
0077     int i;
0078     struct sdi_clk_calc_ctx ctx;
0079 
0080     /*
0081      * DSS fclk gives us very few possibilities, so finding a good pixel
0082      * clock may not be possible. We try multiple times to find the clock,
0083      * each time widening the pixel clock range we look for, up to
0084      * +/- 1MHz.
0085      */
0086 
0087     for (i = 0; i < 10; ++i) {
0088         bool ok;
0089 
0090         memset(&ctx, 0, sizeof(ctx));
0091 
0092         ctx.sdi = sdi;
0093 
0094         if (pclk > 1000 * i * i * i)
0095             ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
0096         else
0097             ctx.pck_min = 0;
0098         ctx.pck_max = pclk + 1000 * i * i * i;
0099 
0100         ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min,
0101                   dpi_calc_dss_cb, &ctx);
0102         if (ok) {
0103             *fck = ctx.fck;
0104             *dispc_cinfo = ctx.dispc_cinfo;
0105             return 0;
0106         }
0107     }
0108 
0109     return -EINVAL;
0110 }
0111 
0112 static void sdi_config_lcd_manager(struct sdi_device *sdi)
0113 {
0114     sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
0115 
0116     sdi->mgr_config.stallmode = false;
0117     sdi->mgr_config.fifohandcheck = false;
0118 
0119     sdi->mgr_config.video_port_width = 24;
0120     sdi->mgr_config.lcden_sig_polarity = 1;
0121 
0122     dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
0123 }
0124 
0125 /* -----------------------------------------------------------------------------
0126  * DRM Bridge Operations
0127  */
0128 
0129 static int sdi_bridge_attach(struct drm_bridge *bridge,
0130                  enum drm_bridge_attach_flags flags)
0131 {
0132     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0133 
0134     if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
0135         return -EINVAL;
0136 
0137     return drm_bridge_attach(bridge->encoder, sdi->output.next_bridge,
0138                  bridge, flags);
0139 }
0140 
0141 static enum drm_mode_status
0142 sdi_bridge_mode_valid(struct drm_bridge *bridge,
0143               const struct drm_display_info *info,
0144               const struct drm_display_mode *mode)
0145 {
0146     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0147     unsigned long pixelclock = mode->clock * 1000;
0148     struct dispc_clock_info dispc_cinfo;
0149     unsigned long fck;
0150     int ret;
0151 
0152     if (pixelclock == 0)
0153         return MODE_NOCLOCK;
0154 
0155     ret = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo);
0156     if (ret < 0)
0157         return MODE_CLOCK_RANGE;
0158 
0159     return MODE_OK;
0160 }
0161 
0162 static bool sdi_bridge_mode_fixup(struct drm_bridge *bridge,
0163                   const struct drm_display_mode *mode,
0164                   struct drm_display_mode *adjusted_mode)
0165 {
0166     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0167     unsigned long pixelclock = mode->clock * 1000;
0168     struct dispc_clock_info dispc_cinfo;
0169     unsigned long fck;
0170     unsigned long pck;
0171     int ret;
0172 
0173     ret = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo);
0174     if (ret < 0)
0175         return false;
0176 
0177     pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
0178 
0179     if (pck != pixelclock)
0180         dev_dbg(&sdi->pdev->dev,
0181             "pixel clock adjusted from %lu Hz to %lu Hz\n",
0182             pixelclock, pck);
0183 
0184     adjusted_mode->clock = pck / 1000;
0185 
0186     return true;
0187 }
0188 
0189 static void sdi_bridge_mode_set(struct drm_bridge *bridge,
0190                 const struct drm_display_mode *mode,
0191                 const struct drm_display_mode *adjusted_mode)
0192 {
0193     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0194 
0195     sdi->pixelclock = adjusted_mode->clock * 1000;
0196 }
0197 
0198 static void sdi_bridge_enable(struct drm_bridge *bridge)
0199 {
0200     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0201     struct dispc_clock_info dispc_cinfo;
0202     unsigned long fck;
0203     int r;
0204 
0205     r = regulator_enable(sdi->vdds_sdi_reg);
0206     if (r)
0207         return;
0208 
0209     r = dispc_runtime_get(sdi->dss->dispc);
0210     if (r)
0211         goto err_get_dispc;
0212 
0213     r = sdi_calc_clock_div(sdi, sdi->pixelclock, &fck, &dispc_cinfo);
0214     if (r)
0215         goto err_calc_clock_div;
0216 
0217     sdi->mgr_config.clock_info = dispc_cinfo;
0218 
0219     r = dss_set_fck_rate(sdi->dss, fck);
0220     if (r)
0221         goto err_set_dss_clock_div;
0222 
0223     sdi_config_lcd_manager(sdi);
0224 
0225     /*
0226      * LCLK and PCLK divisors are located in shadow registers, and we
0227      * normally write them to DISPC registers when enabling the output.
0228      * However, SDI uses pck-free as source clock for its PLL, and pck-free
0229      * is affected by the divisors. And as we need the PLL before enabling
0230      * the output, we need to write the divisors early.
0231      *
0232      * It seems just writing to the DISPC register is enough, and we don't
0233      * need to care about the shadow register mechanism for pck-free. The
0234      * exact reason for this is unknown.
0235      */
0236     dispc_mgr_set_clock_div(sdi->dss->dispc, sdi->output.dispc_channel,
0237                 &sdi->mgr_config.clock_info);
0238 
0239     dss_sdi_init(sdi->dss, sdi->datapairs);
0240     r = dss_sdi_enable(sdi->dss);
0241     if (r)
0242         goto err_sdi_enable;
0243     mdelay(2);
0244 
0245     r = dss_mgr_enable(&sdi->output);
0246     if (r)
0247         goto err_mgr_enable;
0248 
0249     return;
0250 
0251 err_mgr_enable:
0252     dss_sdi_disable(sdi->dss);
0253 err_sdi_enable:
0254 err_set_dss_clock_div:
0255 err_calc_clock_div:
0256     dispc_runtime_put(sdi->dss->dispc);
0257 err_get_dispc:
0258     regulator_disable(sdi->vdds_sdi_reg);
0259 }
0260 
0261 static void sdi_bridge_disable(struct drm_bridge *bridge)
0262 {
0263     struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
0264 
0265     dss_mgr_disable(&sdi->output);
0266 
0267     dss_sdi_disable(sdi->dss);
0268 
0269     dispc_runtime_put(sdi->dss->dispc);
0270 
0271     regulator_disable(sdi->vdds_sdi_reg);
0272 }
0273 
0274 static const struct drm_bridge_funcs sdi_bridge_funcs = {
0275     .attach = sdi_bridge_attach,
0276     .mode_valid = sdi_bridge_mode_valid,
0277     .mode_fixup = sdi_bridge_mode_fixup,
0278     .mode_set = sdi_bridge_mode_set,
0279     .enable = sdi_bridge_enable,
0280     .disable = sdi_bridge_disable,
0281 };
0282 
0283 static void sdi_bridge_init(struct sdi_device *sdi)
0284 {
0285     sdi->bridge.funcs = &sdi_bridge_funcs;
0286     sdi->bridge.of_node = sdi->pdev->dev.of_node;
0287     sdi->bridge.type = DRM_MODE_CONNECTOR_LVDS;
0288 
0289     drm_bridge_add(&sdi->bridge);
0290 }
0291 
0292 static void sdi_bridge_cleanup(struct sdi_device *sdi)
0293 {
0294     drm_bridge_remove(&sdi->bridge);
0295 }
0296 
0297 /* -----------------------------------------------------------------------------
0298  * Initialisation and Cleanup
0299  */
0300 
0301 static int sdi_init_output(struct sdi_device *sdi)
0302 {
0303     struct omap_dss_device *out = &sdi->output;
0304     int r;
0305 
0306     sdi_bridge_init(sdi);
0307 
0308     out->dev = &sdi->pdev->dev;
0309     out->id = OMAP_DSS_OUTPUT_SDI;
0310     out->type = OMAP_DISPLAY_TYPE_SDI;
0311     out->name = "sdi.0";
0312     out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
0313     /* We have SDI only on OMAP3, where it's on port 1 */
0314     out->of_port = 1;
0315     out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE /* 15.5.9.1.2 */
0316                | DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE;
0317 
0318     r = omapdss_device_init_output(out, &sdi->bridge);
0319     if (r < 0) {
0320         sdi_bridge_cleanup(sdi);
0321         return r;
0322     }
0323 
0324     omapdss_device_register(out);
0325 
0326     return 0;
0327 }
0328 
0329 static void sdi_uninit_output(struct sdi_device *sdi)
0330 {
0331     omapdss_device_unregister(&sdi->output);
0332     omapdss_device_cleanup_output(&sdi->output);
0333 
0334     sdi_bridge_cleanup(sdi);
0335 }
0336 
0337 int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
0338           struct device_node *port)
0339 {
0340     struct sdi_device *sdi;
0341     struct device_node *ep;
0342     u32 datapairs;
0343     int r;
0344 
0345     sdi = kzalloc(sizeof(*sdi), GFP_KERNEL);
0346     if (!sdi)
0347         return -ENOMEM;
0348 
0349     ep = of_get_next_child(port, NULL);
0350     if (!ep) {
0351         r = 0;
0352         goto err_free;
0353     }
0354 
0355     r = of_property_read_u32(ep, "datapairs", &datapairs);
0356     of_node_put(ep);
0357     if (r) {
0358         DSSERR("failed to parse datapairs\n");
0359         goto err_free;
0360     }
0361 
0362     sdi->datapairs = datapairs;
0363     sdi->dss = dss;
0364 
0365     sdi->pdev = pdev;
0366     port->data = sdi;
0367 
0368     sdi->vdds_sdi_reg = devm_regulator_get(&pdev->dev, "vdds_sdi");
0369     if (IS_ERR(sdi->vdds_sdi_reg)) {
0370         r = PTR_ERR(sdi->vdds_sdi_reg);
0371         if (r != -EPROBE_DEFER)
0372             DSSERR("can't get VDDS_SDI regulator\n");
0373         goto err_free;
0374     }
0375 
0376     r = sdi_init_output(sdi);
0377     if (r)
0378         goto err_free;
0379 
0380     return 0;
0381 
0382 err_free:
0383     kfree(sdi);
0384 
0385     return r;
0386 }
0387 
0388 void sdi_uninit_port(struct device_node *port)
0389 {
0390     struct sdi_device *sdi = port->data;
0391 
0392     if (!sdi)
0393         return;
0394 
0395     sdi_uninit_output(sdi);
0396     kfree(sdi);
0397 }