root/drivers/gpu/drm/omapdrm/dss/dpi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dpi_get_data_from_dssdev
  2. dpi_get_clk_src_dra7xx
  3. dpi_get_clk_src
  4. dpi_calc_dispc_cb
  5. dpi_calc_hsdiv_cb
  6. dpi_calc_pll_cb
  7. dpi_calc_dss_cb
  8. dpi_pll_clk_calc
  9. dpi_dss_clk_calc
  10. dpi_set_pll_clk
  11. dpi_set_dispc_clk
  12. dpi_set_mode
  13. dpi_config_lcd_manager
  14. dpi_display_enable
  15. dpi_display_disable
  16. dpi_set_timings
  17. dpi_check_timings
  18. dpi_verify_pll
  19. dpi_init_pll
  20. dpi_get_channel
  21. dpi_connect
  22. dpi_disconnect
  23. dpi_init_output_port
  24. dpi_uninit_output_port
  25. dpi_init_regulator
  26. dpi_init_port
  27. dpi_uninit_port

   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  * Some code and ideas taken from drivers/video/omap/ driver
   7  * by Imre Deak.
   8  */
   9 
  10 #define DSS_SUBSYS_NAME "DPI"
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/delay.h>
  14 #include <linux/export.h>
  15 #include <linux/err.h>
  16 #include <linux/errno.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/regulator/consumer.h>
  19 #include <linux/string.h>
  20 #include <linux/of.h>
  21 #include <linux/clk.h>
  22 #include <linux/sys_soc.h>
  23 
  24 #include "omapdss.h"
  25 #include "dss.h"
  26 
  27 struct dpi_data {
  28         struct platform_device *pdev;
  29         enum dss_model dss_model;
  30         struct dss_device *dss;
  31         unsigned int id;
  32 
  33         struct regulator *vdds_dsi_reg;
  34         enum dss_clk_source clk_src;
  35         struct dss_pll *pll;
  36 
  37         struct mutex lock;
  38 
  39         struct dss_lcd_mgr_config mgr_config;
  40         unsigned long pixelclock;
  41         int data_lines;
  42 
  43         struct omap_dss_device output;
  44 };
  45 
  46 static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
  47 {
  48         return container_of(dssdev, struct dpi_data, output);
  49 }
  50 
  51 static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
  52                                                   enum omap_channel channel)
  53 {
  54         /*
  55          * Possible clock sources:
  56          * LCD1: FCK/PLL1_1/HDMI_PLL
  57          * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3)
  58          * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1)
  59          */
  60 
  61         switch (channel) {
  62         case OMAP_DSS_CHANNEL_LCD:
  63         {
  64                 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1))
  65                         return DSS_CLK_SRC_PLL1_1;
  66                 break;
  67         }
  68         case OMAP_DSS_CHANNEL_LCD2:
  69         {
  70                 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
  71                         return DSS_CLK_SRC_PLL1_3;
  72                 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3))
  73                         return DSS_CLK_SRC_PLL2_3;
  74                 break;
  75         }
  76         case OMAP_DSS_CHANNEL_LCD3:
  77         {
  78                 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1))
  79                         return DSS_CLK_SRC_PLL2_1;
  80                 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
  81                         return DSS_CLK_SRC_PLL1_3;
  82                 break;
  83         }
  84         default:
  85                 break;
  86         }
  87 
  88         return DSS_CLK_SRC_FCK;
  89 }
  90 
  91 static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
  92 {
  93         enum omap_channel channel = dpi->output.dispc_channel;
  94 
  95         /*
  96          * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
  97          * would also be used for DISPC fclk. Meaning, when the DPI output is
  98          * disabled, DISPC clock will be disabled, and TV out will stop.
  99          */
 100         switch (dpi->dss_model) {
 101         case DSS_MODEL_OMAP2:
 102         case DSS_MODEL_OMAP3:
 103                 return DSS_CLK_SRC_FCK;
 104 
 105         case DSS_MODEL_OMAP4:
 106                 switch (channel) {
 107                 case OMAP_DSS_CHANNEL_LCD:
 108                         return DSS_CLK_SRC_PLL1_1;
 109                 case OMAP_DSS_CHANNEL_LCD2:
 110                         return DSS_CLK_SRC_PLL2_1;
 111                 default:
 112                         return DSS_CLK_SRC_FCK;
 113                 }
 114 
 115         case DSS_MODEL_OMAP5:
 116                 switch (channel) {
 117                 case OMAP_DSS_CHANNEL_LCD:
 118                         return DSS_CLK_SRC_PLL1_1;
 119                 case OMAP_DSS_CHANNEL_LCD3:
 120                         return DSS_CLK_SRC_PLL2_1;
 121                 case OMAP_DSS_CHANNEL_LCD2:
 122                 default:
 123                         return DSS_CLK_SRC_FCK;
 124                 }
 125 
 126         case DSS_MODEL_DRA7:
 127                 return dpi_get_clk_src_dra7xx(dpi, channel);
 128 
 129         default:
 130                 return DSS_CLK_SRC_FCK;
 131         }
 132 }
 133 
 134 struct dpi_clk_calc_ctx {
 135         struct dpi_data *dpi;
 136         unsigned int clkout_idx;
 137 
 138         /* inputs */
 139 
 140         unsigned long pck_min, pck_max;
 141 
 142         /* outputs */
 143 
 144         struct dss_pll_clock_info pll_cinfo;
 145         unsigned long fck;
 146         struct dispc_clock_info dispc_cinfo;
 147 };
 148 
 149 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
 150                 unsigned long pck, void *data)
 151 {
 152         struct dpi_clk_calc_ctx *ctx = data;
 153 
 154         /*
 155          * Odd dividers give us uneven duty cycle, causing problem when level
 156          * shifted. So skip all odd dividers when the pixel clock is on the
 157          * higher side.
 158          */
 159         if (ctx->pck_min >= 100000000) {
 160                 if (lckd > 1 && lckd % 2 != 0)
 161                         return false;
 162 
 163                 if (pckd > 1 && pckd % 2 != 0)
 164                         return false;
 165         }
 166 
 167         ctx->dispc_cinfo.lck_div = lckd;
 168         ctx->dispc_cinfo.pck_div = pckd;
 169         ctx->dispc_cinfo.lck = lck;
 170         ctx->dispc_cinfo.pck = pck;
 171 
 172         return true;
 173 }
 174 
 175 
 176 static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
 177                 void *data)
 178 {
 179         struct dpi_clk_calc_ctx *ctx = data;
 180 
 181         ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
 182         ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
 183 
 184         return dispc_div_calc(ctx->dpi->dss->dispc, dispc,
 185                               ctx->pck_min, ctx->pck_max,
 186                               dpi_calc_dispc_cb, ctx);
 187 }
 188 
 189 
 190 static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
 191                 unsigned long clkdco,
 192                 void *data)
 193 {
 194         struct dpi_clk_calc_ctx *ctx = data;
 195 
 196         ctx->pll_cinfo.n = n;
 197         ctx->pll_cinfo.m = m;
 198         ctx->pll_cinfo.fint = fint;
 199         ctx->pll_cinfo.clkdco = clkdco;
 200 
 201         return dss_pll_hsdiv_calc_a(ctx->dpi->pll, clkdco,
 202                 ctx->pck_min, dss_get_max_fck_rate(ctx->dpi->dss),
 203                 dpi_calc_hsdiv_cb, ctx);
 204 }
 205 
 206 static bool dpi_calc_dss_cb(unsigned long fck, void *data)
 207 {
 208         struct dpi_clk_calc_ctx *ctx = data;
 209 
 210         ctx->fck = fck;
 211 
 212         return dispc_div_calc(ctx->dpi->dss->dispc, fck,
 213                               ctx->pck_min, ctx->pck_max,
 214                               dpi_calc_dispc_cb, ctx);
 215 }
 216 
 217 static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
 218                 struct dpi_clk_calc_ctx *ctx)
 219 {
 220         unsigned long clkin;
 221 
 222         memset(ctx, 0, sizeof(*ctx));
 223         ctx->dpi = dpi;
 224         ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
 225 
 226         clkin = clk_get_rate(dpi->pll->clkin);
 227 
 228         if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
 229                 unsigned long pll_min, pll_max;
 230 
 231                 ctx->pck_min = pck - 1000;
 232                 ctx->pck_max = pck + 1000;
 233 
 234                 pll_min = 0;
 235                 pll_max = 0;
 236 
 237                 return dss_pll_calc_a(ctx->dpi->pll, clkin,
 238                                 pll_min, pll_max,
 239                                 dpi_calc_pll_cb, ctx);
 240         } else { /* DSS_PLL_TYPE_B */
 241                 dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
 242 
 243                 ctx->dispc_cinfo.lck_div = 1;
 244                 ctx->dispc_cinfo.pck_div = 1;
 245                 ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
 246                 ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
 247 
 248                 return true;
 249         }
 250 }
 251 
 252 static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck,
 253                              struct dpi_clk_calc_ctx *ctx)
 254 {
 255         int i;
 256 
 257         /*
 258          * DSS fck gives us very few possibilities, so finding a good pixel
 259          * clock may not be possible. We try multiple times to find the clock,
 260          * each time widening the pixel clock range we look for, up to
 261          * +/- ~15MHz.
 262          */
 263 
 264         for (i = 0; i < 25; ++i) {
 265                 bool ok;
 266 
 267                 memset(ctx, 0, sizeof(*ctx));
 268                 ctx->dpi = dpi;
 269                 if (pck > 1000 * i * i * i)
 270                         ctx->pck_min = max(pck - 1000 * i * i * i, 0lu);
 271                 else
 272                         ctx->pck_min = 0;
 273                 ctx->pck_max = pck + 1000 * i * i * i;
 274 
 275                 ok = dss_div_calc(dpi->dss, pck, ctx->pck_min,
 276                                   dpi_calc_dss_cb, ctx);
 277                 if (ok)
 278                         return ok;
 279         }
 280 
 281         return false;
 282 }
 283 
 284 
 285 
 286 static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
 287                 unsigned long pck_req, unsigned long *fck, int *lck_div,
 288                 int *pck_div)
 289 {
 290         struct dpi_clk_calc_ctx ctx;
 291         int r;
 292         bool ok;
 293 
 294         ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
 295         if (!ok)
 296                 return -EINVAL;
 297 
 298         r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
 299         if (r)
 300                 return r;
 301 
 302         dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src);
 303 
 304         dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 305 
 306         *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
 307         *lck_div = ctx.dispc_cinfo.lck_div;
 308         *pck_div = ctx.dispc_cinfo.pck_div;
 309 
 310         return 0;
 311 }
 312 
 313 static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
 314                 unsigned long *fck, int *lck_div, int *pck_div)
 315 {
 316         struct dpi_clk_calc_ctx ctx;
 317         int r;
 318         bool ok;
 319 
 320         ok = dpi_dss_clk_calc(dpi, pck_req, &ctx);
 321         if (!ok)
 322                 return -EINVAL;
 323 
 324         r = dss_set_fck_rate(dpi->dss, ctx.fck);
 325         if (r)
 326                 return r;
 327 
 328         dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 329 
 330         *fck = ctx.fck;
 331         *lck_div = ctx.dispc_cinfo.lck_div;
 332         *pck_div = ctx.dispc_cinfo.pck_div;
 333 
 334         return 0;
 335 }
 336 
 337 static int dpi_set_mode(struct dpi_data *dpi)
 338 {
 339         int lck_div = 0, pck_div = 0;
 340         unsigned long fck = 0;
 341         int r = 0;
 342 
 343         if (dpi->pll)
 344                 r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
 345                                     dpi->pixelclock, &fck, &lck_div, &pck_div);
 346         else
 347                 r = dpi_set_dispc_clk(dpi, dpi->pixelclock, &fck,
 348                                 &lck_div, &pck_div);
 349         if (r)
 350                 return r;
 351 
 352         return 0;
 353 }
 354 
 355 static void dpi_config_lcd_manager(struct dpi_data *dpi)
 356 {
 357         dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 358 
 359         dpi->mgr_config.stallmode = false;
 360         dpi->mgr_config.fifohandcheck = false;
 361 
 362         dpi->mgr_config.video_port_width = dpi->data_lines;
 363 
 364         dpi->mgr_config.lcden_sig_polarity = 0;
 365 
 366         dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
 367 }
 368 
 369 static void dpi_display_enable(struct omap_dss_device *dssdev)
 370 {
 371         struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 372         struct omap_dss_device *out = &dpi->output;
 373         int r;
 374 
 375         mutex_lock(&dpi->lock);
 376 
 377         if (dpi->vdds_dsi_reg) {
 378                 r = regulator_enable(dpi->vdds_dsi_reg);
 379                 if (r)
 380                         goto err_reg_enable;
 381         }
 382 
 383         r = dispc_runtime_get(dpi->dss->dispc);
 384         if (r)
 385                 goto err_get_dispc;
 386 
 387         r = dss_dpi_select_source(dpi->dss, dpi->id, out->dispc_channel);
 388         if (r)
 389                 goto err_src_sel;
 390 
 391         if (dpi->pll) {
 392                 r = dss_pll_enable(dpi->pll);
 393                 if (r)
 394                         goto err_pll_init;
 395         }
 396 
 397         r = dpi_set_mode(dpi);
 398         if (r)
 399                 goto err_set_mode;
 400 
 401         dpi_config_lcd_manager(dpi);
 402 
 403         mdelay(2);
 404 
 405         r = dss_mgr_enable(&dpi->output);
 406         if (r)
 407                 goto err_mgr_enable;
 408 
 409         mutex_unlock(&dpi->lock);
 410 
 411         return;
 412 
 413 err_mgr_enable:
 414 err_set_mode:
 415         if (dpi->pll)
 416                 dss_pll_disable(dpi->pll);
 417 err_pll_init:
 418 err_src_sel:
 419         dispc_runtime_put(dpi->dss->dispc);
 420 err_get_dispc:
 421         if (dpi->vdds_dsi_reg)
 422                 regulator_disable(dpi->vdds_dsi_reg);
 423 err_reg_enable:
 424         mutex_unlock(&dpi->lock);
 425 }
 426 
 427 static void dpi_display_disable(struct omap_dss_device *dssdev)
 428 {
 429         struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 430 
 431         mutex_lock(&dpi->lock);
 432 
 433         dss_mgr_disable(&dpi->output);
 434 
 435         if (dpi->pll) {
 436                 dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
 437                                           DSS_CLK_SRC_FCK);
 438                 dss_pll_disable(dpi->pll);
 439         }
 440 
 441         dispc_runtime_put(dpi->dss->dispc);
 442 
 443         if (dpi->vdds_dsi_reg)
 444                 regulator_disable(dpi->vdds_dsi_reg);
 445 
 446         mutex_unlock(&dpi->lock);
 447 }
 448 
 449 static void dpi_set_timings(struct omap_dss_device *dssdev,
 450                             const struct drm_display_mode *mode)
 451 {
 452         struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 453 
 454         DSSDBG("dpi_set_timings\n");
 455 
 456         mutex_lock(&dpi->lock);
 457 
 458         dpi->pixelclock = mode->clock * 1000;
 459 
 460         mutex_unlock(&dpi->lock);
 461 }
 462 
 463 static int dpi_check_timings(struct omap_dss_device *dssdev,
 464                              struct drm_display_mode *mode)
 465 {
 466         struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 467         int lck_div, pck_div;
 468         unsigned long fck;
 469         unsigned long pck;
 470         struct dpi_clk_calc_ctx ctx;
 471         bool ok;
 472 
 473         if (mode->hdisplay % 8 != 0)
 474                 return -EINVAL;
 475 
 476         if (mode->clock == 0)
 477                 return -EINVAL;
 478 
 479         if (dpi->pll) {
 480                 ok = dpi_pll_clk_calc(dpi, mode->clock * 1000, &ctx);
 481                 if (!ok)
 482                         return -EINVAL;
 483 
 484                 fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
 485         } else {
 486                 ok = dpi_dss_clk_calc(dpi, mode->clock * 1000, &ctx);
 487                 if (!ok)
 488                         return -EINVAL;
 489 
 490                 fck = ctx.fck;
 491         }
 492 
 493         lck_div = ctx.dispc_cinfo.lck_div;
 494         pck_div = ctx.dispc_cinfo.pck_div;
 495 
 496         pck = fck / lck_div / pck_div;
 497 
 498         mode->clock = pck / 1000;
 499 
 500         return 0;
 501 }
 502 
 503 static int dpi_verify_pll(struct dss_pll *pll)
 504 {
 505         int r;
 506 
 507         /* do initial setup with the PLL to see if it is operational */
 508 
 509         r = dss_pll_enable(pll);
 510         if (r)
 511                 return r;
 512 
 513         dss_pll_disable(pll);
 514 
 515         return 0;
 516 }
 517 
 518 static void dpi_init_pll(struct dpi_data *dpi)
 519 {
 520         struct dss_pll *pll;
 521 
 522         if (dpi->pll)
 523                 return;
 524 
 525         dpi->clk_src = dpi_get_clk_src(dpi);
 526 
 527         pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
 528         if (!pll)
 529                 return;
 530 
 531         if (dpi_verify_pll(pll)) {
 532                 DSSWARN("PLL not operational\n");
 533                 return;
 534         }
 535 
 536         dpi->pll = pll;
 537 }
 538 
 539 /*
 540  * Return a hardcoded channel for the DPI output. This should work for
 541  * current use cases, but this can be later expanded to either resolve
 542  * the channel in some more dynamic manner, or get the channel as a user
 543  * parameter.
 544  */
 545 static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
 546 {
 547         switch (dpi->dss_model) {
 548         case DSS_MODEL_OMAP2:
 549         case DSS_MODEL_OMAP3:
 550                 return OMAP_DSS_CHANNEL_LCD;
 551 
 552         case DSS_MODEL_DRA7:
 553                 switch (dpi->id) {
 554                 case 2:
 555                         return OMAP_DSS_CHANNEL_LCD3;
 556                 case 1:
 557                         return OMAP_DSS_CHANNEL_LCD2;
 558                 case 0:
 559                 default:
 560                         return OMAP_DSS_CHANNEL_LCD;
 561                 }
 562 
 563         case DSS_MODEL_OMAP4:
 564                 return OMAP_DSS_CHANNEL_LCD2;
 565 
 566         case DSS_MODEL_OMAP5:
 567                 return OMAP_DSS_CHANNEL_LCD3;
 568 
 569         default:
 570                 DSSWARN("unsupported DSS version\n");
 571                 return OMAP_DSS_CHANNEL_LCD;
 572         }
 573 }
 574 
 575 static int dpi_connect(struct omap_dss_device *src,
 576                        struct omap_dss_device *dst)
 577 {
 578         struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
 579 
 580         dpi_init_pll(dpi);
 581 
 582         return omapdss_device_connect(dst->dss, dst, dst->next);
 583 }
 584 
 585 static void dpi_disconnect(struct omap_dss_device *src,
 586                            struct omap_dss_device *dst)
 587 {
 588         omapdss_device_disconnect(dst, dst->next);
 589 }
 590 
 591 static const struct omap_dss_device_ops dpi_ops = {
 592         .connect = dpi_connect,
 593         .disconnect = dpi_disconnect,
 594 
 595         .enable = dpi_display_enable,
 596         .disable = dpi_display_disable,
 597 
 598         .check_timings = dpi_check_timings,
 599         .set_timings = dpi_set_timings,
 600 };
 601 
 602 static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
 603 {
 604         struct omap_dss_device *out = &dpi->output;
 605         u32 port_num = 0;
 606         int r;
 607 
 608         of_property_read_u32(port, "reg", &port_num);
 609         dpi->id = port_num <= 2 ? port_num : 0;
 610 
 611         switch (port_num) {
 612         case 2:
 613                 out->name = "dpi.2";
 614                 break;
 615         case 1:
 616                 out->name = "dpi.1";
 617                 break;
 618         case 0:
 619         default:
 620                 out->name = "dpi.0";
 621                 break;
 622         }
 623 
 624         out->dev = &dpi->pdev->dev;
 625         out->id = OMAP_DSS_OUTPUT_DPI;
 626         out->type = OMAP_DISPLAY_TYPE_DPI;
 627         out->dispc_channel = dpi_get_channel(dpi);
 628         out->of_ports = BIT(port_num);
 629         out->ops = &dpi_ops;
 630         out->owner = THIS_MODULE;
 631 
 632         r = omapdss_device_init_output(out);
 633         if (r < 0)
 634                 return r;
 635 
 636         omapdss_device_register(out);
 637 
 638         return 0;
 639 }
 640 
 641 static void dpi_uninit_output_port(struct device_node *port)
 642 {
 643         struct dpi_data *dpi = port->data;
 644         struct omap_dss_device *out = &dpi->output;
 645 
 646         omapdss_device_unregister(out);
 647         omapdss_device_cleanup_output(out);
 648 }
 649 
 650 static const struct soc_device_attribute dpi_soc_devices[] = {
 651         { .machine = "OMAP3[456]*" },
 652         { .machine = "[AD]M37*" },
 653         { /* sentinel */ }
 654 };
 655 
 656 static int dpi_init_regulator(struct dpi_data *dpi)
 657 {
 658         struct regulator *vdds_dsi;
 659 
 660         /*
 661          * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
 662          * DM37xx only.
 663          */
 664         if (!soc_device_match(dpi_soc_devices))
 665                 return 0;
 666 
 667         vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
 668         if (IS_ERR(vdds_dsi)) {
 669                 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
 670                         DSSERR("can't get VDDS_DSI regulator\n");
 671                 return PTR_ERR(vdds_dsi);
 672         }
 673 
 674         dpi->vdds_dsi_reg = vdds_dsi;
 675 
 676         return 0;
 677 }
 678 
 679 int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
 680                   struct device_node *port, enum dss_model dss_model)
 681 {
 682         struct dpi_data *dpi;
 683         struct device_node *ep;
 684         u32 datalines;
 685         int r;
 686 
 687         dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
 688         if (!dpi)
 689                 return -ENOMEM;
 690 
 691         ep = of_get_next_child(port, NULL);
 692         if (!ep)
 693                 return 0;
 694 
 695         r = of_property_read_u32(ep, "data-lines", &datalines);
 696         of_node_put(ep);
 697         if (r) {
 698                 DSSERR("failed to parse datalines\n");
 699                 return r;
 700         }
 701 
 702         dpi->data_lines = datalines;
 703 
 704         dpi->pdev = pdev;
 705         dpi->dss_model = dss_model;
 706         dpi->dss = dss;
 707         port->data = dpi;
 708 
 709         mutex_init(&dpi->lock);
 710 
 711         r = dpi_init_regulator(dpi);
 712         if (r)
 713                 return r;
 714 
 715         return dpi_init_output_port(dpi, port);
 716 }
 717 
 718 void dpi_uninit_port(struct device_node *port)
 719 {
 720         struct dpi_data *dpi = port->data;
 721 
 722         if (!dpi)
 723                 return;
 724 
 725         dpi_uninit_output_port(port);
 726 }

/* [<][>][^][v][top][bottom][index][help] */