root/drivers/video/fbdev/omap2/omapfb/dss/dss.c

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

DEFINITIONS

This source file includes following definitions.
  1. omapdss_is_initialized
  2. dss_write_reg
  3. dss_read_reg
  4. dss_save_context
  5. dss_restore_context
  6. dss_ctrl_pll_enable
  7. dss_ctrl_pll_set_control_mux
  8. dss_sdi_init
  9. dss_sdi_enable
  10. dss_sdi_disable
  11. dss_get_generic_clk_source_name
  12. dss_dump_clocks
  13. dss_dump_regs
  14. dss_select_dispc_clk_source
  15. dss_select_dsi_clk_source
  16. dss_select_lcd_clk_source
  17. dss_get_dispc_clk_source
  18. dss_get_dsi_clk_source
  19. dss_get_lcd_clk_source
  20. dss_div_calc
  21. dss_set_fck_rate
  22. dss_get_dispc_clk_rate
  23. dss_setup_default_clock
  24. dss_set_venc_output
  25. dss_set_dac_pwrdn_bgz
  26. dss_select_hdmi_venc_clk_source
  27. dss_get_hdmi_venc_clk_source
  28. dss_dpi_select_source_omap2_omap3
  29. dss_dpi_select_source_omap4
  30. dss_dpi_select_source_omap5
  31. dss_dpi_select_source_dra7xx
  32. dss_dpi_select_source
  33. dss_get_clocks
  34. dss_put_clocks
  35. dss_runtime_get
  36. dss_runtime_put
  37. dss_debug_dump_clocks
  38. dss_get_features
  39. dss_init_ports
  40. dss_uninit_ports
  41. dss_video_pll_probe
  42. dss_bind
  43. dss_unbind
  44. dss_component_compare
  45. dss_add_child_component
  46. dss_probe
  47. dss_remove
  48. dss_runtime_suspend
  49. dss_runtime_resume
  50. dss_init_platform_driver
  51. dss_uninit_platform_driver

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/video/omap2/dss/dss.c
   4  *
   5  * Copyright (C) 2009 Nokia Corporation
   6  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
   7  *
   8  * Some code and ideas taken from drivers/video/omap/ driver
   9  * by Imre Deak.
  10  */
  11 
  12 #define DSS_SUBSYS_NAME "DSS"
  13 
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 #include <linux/io.h>
  17 #include <linux/export.h>
  18 #include <linux/err.h>
  19 #include <linux/delay.h>
  20 #include <linux/seq_file.h>
  21 #include <linux/clk.h>
  22 #include <linux/platform_device.h>
  23 #include <linux/pm_runtime.h>
  24 #include <linux/gfp.h>
  25 #include <linux/sizes.h>
  26 #include <linux/mfd/syscon.h>
  27 #include <linux/regmap.h>
  28 #include <linux/of.h>
  29 #include <linux/regulator/consumer.h>
  30 #include <linux/suspend.h>
  31 #include <linux/component.h>
  32 #include <linux/pinctrl/consumer.h>
  33 
  34 #include <video/omapfb_dss.h>
  35 
  36 #include "dss.h"
  37 #include "dss_features.h"
  38 
  39 #define DSS_SZ_REGS                     SZ_512
  40 
  41 struct dss_reg {
  42         u16 idx;
  43 };
  44 
  45 #define DSS_REG(idx)                    ((const struct dss_reg) { idx })
  46 
  47 #define DSS_REVISION                    DSS_REG(0x0000)
  48 #define DSS_SYSCONFIG                   DSS_REG(0x0010)
  49 #define DSS_SYSSTATUS                   DSS_REG(0x0014)
  50 #define DSS_CONTROL                     DSS_REG(0x0040)
  51 #define DSS_SDI_CONTROL                 DSS_REG(0x0044)
  52 #define DSS_PLL_CONTROL                 DSS_REG(0x0048)
  53 #define DSS_SDI_STATUS                  DSS_REG(0x005C)
  54 
  55 #define REG_GET(idx, start, end) \
  56         FLD_GET(dss_read_reg(idx), start, end)
  57 
  58 #define REG_FLD_MOD(idx, val, start, end) \
  59         dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
  60 
  61 struct dss_features {
  62         u8 fck_div_max;
  63         u8 dss_fck_multiplier;
  64         const char *parent_clk_name;
  65         const enum omap_display_type *ports;
  66         int num_ports;
  67         int (*dpi_select_source)(int port, enum omap_channel channel);
  68 };
  69 
  70 static struct {
  71         struct platform_device *pdev;
  72         void __iomem    *base;
  73         struct regmap   *syscon_pll_ctrl;
  74         u32             syscon_pll_ctrl_offset;
  75 
  76         struct clk      *parent_clk;
  77         struct clk      *dss_clk;
  78         unsigned long   dss_clk_rate;
  79 
  80         unsigned long   cache_req_pck;
  81         unsigned long   cache_prate;
  82         struct dispc_clock_info cache_dispc_cinfo;
  83 
  84         enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
  85         enum omap_dss_clk_source dispc_clk_source;
  86         enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
  87 
  88         bool            ctx_valid;
  89         u32             ctx[DSS_SZ_REGS / sizeof(u32)];
  90 
  91         const struct dss_features *feat;
  92 
  93         struct dss_pll  *video1_pll;
  94         struct dss_pll  *video2_pll;
  95 } dss;
  96 
  97 static const char * const dss_generic_clk_source_names[] = {
  98         [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "DSI_PLL_HSDIV_DISPC",
  99         [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "DSI_PLL_HSDIV_DSI",
 100         [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
 101         [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
 102         [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]   = "DSI_PLL2_HSDIV_DSI",
 103 };
 104 
 105 static bool dss_initialized;
 106 
 107 bool omapdss_is_initialized(void)
 108 {
 109         return dss_initialized;
 110 }
 111 EXPORT_SYMBOL(omapdss_is_initialized);
 112 
 113 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
 114 {
 115         __raw_writel(val, dss.base + idx.idx);
 116 }
 117 
 118 static inline u32 dss_read_reg(const struct dss_reg idx)
 119 {
 120         return __raw_readl(dss.base + idx.idx);
 121 }
 122 
 123 #define SR(reg) \
 124         dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
 125 #define RR(reg) \
 126         dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
 127 
 128 static void dss_save_context(void)
 129 {
 130         DSSDBG("dss_save_context\n");
 131 
 132         SR(CONTROL);
 133 
 134         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
 135                         OMAP_DISPLAY_TYPE_SDI) {
 136                 SR(SDI_CONTROL);
 137                 SR(PLL_CONTROL);
 138         }
 139 
 140         dss.ctx_valid = true;
 141 
 142         DSSDBG("context saved\n");
 143 }
 144 
 145 static void dss_restore_context(void)
 146 {
 147         DSSDBG("dss_restore_context\n");
 148 
 149         if (!dss.ctx_valid)
 150                 return;
 151 
 152         RR(CONTROL);
 153 
 154         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
 155                         OMAP_DISPLAY_TYPE_SDI) {
 156                 RR(SDI_CONTROL);
 157                 RR(PLL_CONTROL);
 158         }
 159 
 160         DSSDBG("context restored\n");
 161 }
 162 
 163 #undef SR
 164 #undef RR
 165 
 166 void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
 167 {
 168         unsigned shift;
 169         unsigned val;
 170 
 171         if (!dss.syscon_pll_ctrl)
 172                 return;
 173 
 174         val = !enable;
 175 
 176         switch (pll_id) {
 177         case DSS_PLL_VIDEO1:
 178                 shift = 0;
 179                 break;
 180         case DSS_PLL_VIDEO2:
 181                 shift = 1;
 182                 break;
 183         case DSS_PLL_HDMI:
 184                 shift = 2;
 185                 break;
 186         default:
 187                 DSSERR("illegal DSS PLL ID %d\n", pll_id);
 188                 return;
 189         }
 190 
 191         regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
 192                 1 << shift, val << shift);
 193 }
 194 
 195 void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
 196         enum omap_channel channel)
 197 {
 198         unsigned shift, val;
 199 
 200         if (!dss.syscon_pll_ctrl)
 201                 return;
 202 
 203         switch (channel) {
 204         case OMAP_DSS_CHANNEL_LCD:
 205                 shift = 3;
 206 
 207                 switch (pll_id) {
 208                 case DSS_PLL_VIDEO1:
 209                         val = 0; break;
 210                 case DSS_PLL_HDMI:
 211                         val = 1; break;
 212                 default:
 213                         DSSERR("error in PLL mux config for LCD\n");
 214                         return;
 215                 }
 216 
 217                 break;
 218         case OMAP_DSS_CHANNEL_LCD2:
 219                 shift = 5;
 220 
 221                 switch (pll_id) {
 222                 case DSS_PLL_VIDEO1:
 223                         val = 0; break;
 224                 case DSS_PLL_VIDEO2:
 225                         val = 1; break;
 226                 case DSS_PLL_HDMI:
 227                         val = 2; break;
 228                 default:
 229                         DSSERR("error in PLL mux config for LCD2\n");
 230                         return;
 231                 }
 232 
 233                 break;
 234         case OMAP_DSS_CHANNEL_LCD3:
 235                 shift = 7;
 236 
 237                 switch (pll_id) {
 238                 case DSS_PLL_VIDEO1:
 239                         val = 1; break;
 240                 case DSS_PLL_VIDEO2:
 241                         val = 0; break;
 242                 case DSS_PLL_HDMI:
 243                         val = 2; break;
 244                 default:
 245                         DSSERR("error in PLL mux config for LCD3\n");
 246                         return;
 247                 }
 248 
 249                 break;
 250         default:
 251                 DSSERR("error in PLL mux config\n");
 252                 return;
 253         }
 254 
 255         regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
 256                 0x3 << shift, val << shift);
 257 }
 258 
 259 void dss_sdi_init(int datapairs)
 260 {
 261         u32 l;
 262 
 263         BUG_ON(datapairs > 3 || datapairs < 1);
 264 
 265         l = dss_read_reg(DSS_SDI_CONTROL);
 266         l = FLD_MOD(l, 0xf, 19, 15);            /* SDI_PDIV */
 267         l = FLD_MOD(l, datapairs-1, 3, 2);      /* SDI_PRSEL */
 268         l = FLD_MOD(l, 2, 1, 0);                /* SDI_BWSEL */
 269         dss_write_reg(DSS_SDI_CONTROL, l);
 270 
 271         l = dss_read_reg(DSS_PLL_CONTROL);
 272         l = FLD_MOD(l, 0x7, 25, 22);    /* SDI_PLL_FREQSEL */
 273         l = FLD_MOD(l, 0xb, 16, 11);    /* SDI_PLL_REGN */
 274         l = FLD_MOD(l, 0xb4, 10, 1);    /* SDI_PLL_REGM */
 275         dss_write_reg(DSS_PLL_CONTROL, l);
 276 }
 277 
 278 int dss_sdi_enable(void)
 279 {
 280         unsigned long timeout;
 281 
 282         dispc_pck_free_enable(1);
 283 
 284         /* Reset SDI PLL */
 285         REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
 286         udelay(1);      /* wait 2x PCLK */
 287 
 288         /* Lock SDI PLL */
 289         REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
 290 
 291         /* Waiting for PLL lock request to complete */
 292         timeout = jiffies + msecs_to_jiffies(500);
 293         while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
 294                 if (time_after_eq(jiffies, timeout)) {
 295                         DSSERR("PLL lock request timed out\n");
 296                         goto err1;
 297                 }
 298         }
 299 
 300         /* Clearing PLL_GO bit */
 301         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
 302 
 303         /* Waiting for PLL to lock */
 304         timeout = jiffies + msecs_to_jiffies(500);
 305         while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
 306                 if (time_after_eq(jiffies, timeout)) {
 307                         DSSERR("PLL lock timed out\n");
 308                         goto err1;
 309                 }
 310         }
 311 
 312         dispc_lcd_enable_signal(1);
 313 
 314         /* Waiting for SDI reset to complete */
 315         timeout = jiffies + msecs_to_jiffies(500);
 316         while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
 317                 if (time_after_eq(jiffies, timeout)) {
 318                         DSSERR("SDI reset timed out\n");
 319                         goto err2;
 320                 }
 321         }
 322 
 323         return 0;
 324 
 325  err2:
 326         dispc_lcd_enable_signal(0);
 327  err1:
 328         /* Reset SDI PLL */
 329         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
 330 
 331         dispc_pck_free_enable(0);
 332 
 333         return -ETIMEDOUT;
 334 }
 335 
 336 void dss_sdi_disable(void)
 337 {
 338         dispc_lcd_enable_signal(0);
 339 
 340         dispc_pck_free_enable(0);
 341 
 342         /* Reset SDI PLL */
 343         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
 344 }
 345 
 346 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
 347 {
 348         return dss_generic_clk_source_names[clk_src];
 349 }
 350 
 351 void dss_dump_clocks(struct seq_file *s)
 352 {
 353         const char *fclk_name, *fclk_real_name;
 354         unsigned long fclk_rate;
 355 
 356         if (dss_runtime_get())
 357                 return;
 358 
 359         seq_printf(s, "- DSS -\n");
 360 
 361         fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
 362         fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
 363         fclk_rate = clk_get_rate(dss.dss_clk);
 364 
 365         seq_printf(s, "%s (%s) = %lu\n",
 366                         fclk_name, fclk_real_name,
 367                         fclk_rate);
 368 
 369         dss_runtime_put();
 370 }
 371 
 372 static void dss_dump_regs(struct seq_file *s)
 373 {
 374 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
 375 
 376         if (dss_runtime_get())
 377                 return;
 378 
 379         DUMPREG(DSS_REVISION);
 380         DUMPREG(DSS_SYSCONFIG);
 381         DUMPREG(DSS_SYSSTATUS);
 382         DUMPREG(DSS_CONTROL);
 383 
 384         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
 385                         OMAP_DISPLAY_TYPE_SDI) {
 386                 DUMPREG(DSS_SDI_CONTROL);
 387                 DUMPREG(DSS_PLL_CONTROL);
 388                 DUMPREG(DSS_SDI_STATUS);
 389         }
 390 
 391         dss_runtime_put();
 392 #undef DUMPREG
 393 }
 394 
 395 static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 396 {
 397         int b;
 398         u8 start, end;
 399 
 400         switch (clk_src) {
 401         case OMAP_DSS_CLK_SRC_FCK:
 402                 b = 0;
 403                 break;
 404         case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
 405                 b = 1;
 406                 break;
 407         case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
 408                 b = 2;
 409                 break;
 410         default:
 411                 BUG();
 412                 return;
 413         }
 414 
 415         dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
 416 
 417         REG_FLD_MOD(DSS_CONTROL, b, start, end);        /* DISPC_CLK_SWITCH */
 418 
 419         dss.dispc_clk_source = clk_src;
 420 }
 421 
 422 void dss_select_dsi_clk_source(int dsi_module,
 423                 enum omap_dss_clk_source clk_src)
 424 {
 425         int b, pos;
 426 
 427         switch (clk_src) {
 428         case OMAP_DSS_CLK_SRC_FCK:
 429                 b = 0;
 430                 break;
 431         case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
 432                 BUG_ON(dsi_module != 0);
 433                 b = 1;
 434                 break;
 435         case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
 436                 BUG_ON(dsi_module != 1);
 437                 b = 1;
 438                 break;
 439         default:
 440                 BUG();
 441                 return;
 442         }
 443 
 444         pos = dsi_module == 0 ? 1 : 10;
 445         REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* DSIx_CLK_SWITCH */
 446 
 447         dss.dsi_clk_source[dsi_module] = clk_src;
 448 }
 449 
 450 void dss_select_lcd_clk_source(enum omap_channel channel,
 451                 enum omap_dss_clk_source clk_src)
 452 {
 453         int b, ix, pos;
 454 
 455         if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
 456                 dss_select_dispc_clk_source(clk_src);
 457                 return;
 458         }
 459 
 460         switch (clk_src) {
 461         case OMAP_DSS_CLK_SRC_FCK:
 462                 b = 0;
 463                 break;
 464         case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
 465                 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
 466                 b = 1;
 467                 break;
 468         case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
 469                 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
 470                        channel != OMAP_DSS_CHANNEL_LCD3);
 471                 b = 1;
 472                 break;
 473         default:
 474                 BUG();
 475                 return;
 476         }
 477 
 478         pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
 479              (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
 480         REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* LCDx_CLK_SWITCH */
 481 
 482         ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
 483             (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
 484         dss.lcd_clk_source[ix] = clk_src;
 485 }
 486 
 487 enum omap_dss_clk_source dss_get_dispc_clk_source(void)
 488 {
 489         return dss.dispc_clk_source;
 490 }
 491 
 492 enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
 493 {
 494         return dss.dsi_clk_source[dsi_module];
 495 }
 496 
 497 enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 498 {
 499         if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
 500                 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
 501                         (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
 502                 return dss.lcd_clk_source[ix];
 503         } else {
 504                 /* LCD_CLK source is the same as DISPC_FCLK source for
 505                  * OMAP2 and OMAP3 */
 506                 return dss.dispc_clk_source;
 507         }
 508 }
 509 
 510 bool dss_div_calc(unsigned long pck, unsigned long fck_min,
 511                 dss_div_calc_func func, void *data)
 512 {
 513         int fckd, fckd_start, fckd_stop;
 514         unsigned long fck;
 515         unsigned long fck_hw_max;
 516         unsigned long fckd_hw_max;
 517         unsigned long prate;
 518         unsigned m;
 519 
 520         fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 521 
 522         if (dss.parent_clk == NULL) {
 523                 unsigned pckd;
 524 
 525                 pckd = fck_hw_max / pck;
 526 
 527                 fck = pck * pckd;
 528 
 529                 fck = clk_round_rate(dss.dss_clk, fck);
 530 
 531                 return func(fck, data);
 532         }
 533 
 534         fckd_hw_max = dss.feat->fck_div_max;
 535 
 536         m = dss.feat->dss_fck_multiplier;
 537         prate = clk_get_rate(dss.parent_clk);
 538 
 539         fck_min = fck_min ? fck_min : 1;
 540 
 541         fckd_start = min(prate * m / fck_min, fckd_hw_max);
 542         fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
 543 
 544         for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
 545                 fck = DIV_ROUND_UP(prate, fckd) * m;
 546 
 547                 if (func(fck, data))
 548                         return true;
 549         }
 550 
 551         return false;
 552 }
 553 
 554 int dss_set_fck_rate(unsigned long rate)
 555 {
 556         int r;
 557 
 558         DSSDBG("set fck to %lu\n", rate);
 559 
 560         r = clk_set_rate(dss.dss_clk, rate);
 561         if (r)
 562                 return r;
 563 
 564         dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
 565 
 566         WARN_ONCE(dss.dss_clk_rate != rate,
 567                         "clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
 568                         rate);
 569 
 570         return 0;
 571 }
 572 
 573 unsigned long dss_get_dispc_clk_rate(void)
 574 {
 575         return dss.dss_clk_rate;
 576 }
 577 
 578 static int dss_setup_default_clock(void)
 579 {
 580         unsigned long max_dss_fck, prate;
 581         unsigned long fck;
 582         unsigned fck_div;
 583         int r;
 584 
 585         max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 586 
 587         if (dss.parent_clk == NULL) {
 588                 fck = clk_round_rate(dss.dss_clk, max_dss_fck);
 589         } else {
 590                 prate = clk_get_rate(dss.parent_clk);
 591 
 592                 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
 593                                 max_dss_fck);
 594                 fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
 595         }
 596 
 597         r = dss_set_fck_rate(fck);
 598         if (r)
 599                 return r;
 600 
 601         return 0;
 602 }
 603 
 604 void dss_set_venc_output(enum omap_dss_venc_type type)
 605 {
 606         int l = 0;
 607 
 608         if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
 609                 l = 0;
 610         else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
 611                 l = 1;
 612         else
 613                 BUG();
 614 
 615         /* venc out selection. 0 = comp, 1 = svideo */
 616         REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
 617 }
 618 
 619 void dss_set_dac_pwrdn_bgz(bool enable)
 620 {
 621         REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
 622 }
 623 
 624 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
 625 {
 626         enum omap_display_type dp;
 627         dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
 628 
 629         /* Complain about invalid selections */
 630         WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
 631         WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
 632 
 633         /* Select only if we have options */
 634         if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
 635                 REG_FLD_MOD(DSS_CONTROL, src, 15, 15);  /* VENC_HDMI_SWITCH */
 636 }
 637 
 638 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
 639 {
 640         enum omap_display_type displays;
 641 
 642         displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
 643         if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
 644                 return DSS_VENC_TV_CLK;
 645 
 646         if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
 647                 return DSS_HDMI_M_PCLK;
 648 
 649         return REG_GET(DSS_CONTROL, 15, 15);
 650 }
 651 
 652 static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
 653 {
 654         if (channel != OMAP_DSS_CHANNEL_LCD)
 655                 return -EINVAL;
 656 
 657         return 0;
 658 }
 659 
 660 static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
 661 {
 662         int val;
 663 
 664         switch (channel) {
 665         case OMAP_DSS_CHANNEL_LCD2:
 666                 val = 0;
 667                 break;
 668         case OMAP_DSS_CHANNEL_DIGIT:
 669                 val = 1;
 670                 break;
 671         default:
 672                 return -EINVAL;
 673         }
 674 
 675         REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
 676 
 677         return 0;
 678 }
 679 
 680 static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
 681 {
 682         int val;
 683 
 684         switch (channel) {
 685         case OMAP_DSS_CHANNEL_LCD:
 686                 val = 1;
 687                 break;
 688         case OMAP_DSS_CHANNEL_LCD2:
 689                 val = 2;
 690                 break;
 691         case OMAP_DSS_CHANNEL_LCD3:
 692                 val = 3;
 693                 break;
 694         case OMAP_DSS_CHANNEL_DIGIT:
 695                 val = 0;
 696                 break;
 697         default:
 698                 return -EINVAL;
 699         }
 700 
 701         REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
 702 
 703         return 0;
 704 }
 705 
 706 static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
 707 {
 708         switch (port) {
 709         case 0:
 710                 return dss_dpi_select_source_omap5(port, channel);
 711         case 1:
 712                 if (channel != OMAP_DSS_CHANNEL_LCD2)
 713                         return -EINVAL;
 714                 break;
 715         case 2:
 716                 if (channel != OMAP_DSS_CHANNEL_LCD3)
 717                         return -EINVAL;
 718                 break;
 719         default:
 720                 return -EINVAL;
 721         }
 722 
 723         return 0;
 724 }
 725 
 726 int dss_dpi_select_source(int port, enum omap_channel channel)
 727 {
 728         return dss.feat->dpi_select_source(port, channel);
 729 }
 730 
 731 static int dss_get_clocks(void)
 732 {
 733         struct clk *clk;
 734 
 735         clk = devm_clk_get(&dss.pdev->dev, "fck");
 736         if (IS_ERR(clk)) {
 737                 DSSERR("can't get clock fck\n");
 738                 return PTR_ERR(clk);
 739         }
 740 
 741         dss.dss_clk = clk;
 742 
 743         if (dss.feat->parent_clk_name) {
 744                 clk = clk_get(NULL, dss.feat->parent_clk_name);
 745                 if (IS_ERR(clk)) {
 746                         DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
 747                         return PTR_ERR(clk);
 748                 }
 749         } else {
 750                 clk = NULL;
 751         }
 752 
 753         dss.parent_clk = clk;
 754 
 755         return 0;
 756 }
 757 
 758 static void dss_put_clocks(void)
 759 {
 760         if (dss.parent_clk)
 761                 clk_put(dss.parent_clk);
 762 }
 763 
 764 int dss_runtime_get(void)
 765 {
 766         int r;
 767 
 768         DSSDBG("dss_runtime_get\n");
 769 
 770         r = pm_runtime_get_sync(&dss.pdev->dev);
 771         WARN_ON(r < 0);
 772         return r < 0 ? r : 0;
 773 }
 774 
 775 void dss_runtime_put(void)
 776 {
 777         int r;
 778 
 779         DSSDBG("dss_runtime_put\n");
 780 
 781         r = pm_runtime_put_sync(&dss.pdev->dev);
 782         WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
 783 }
 784 
 785 /* DEBUGFS */
 786 #if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS)
 787 void dss_debug_dump_clocks(struct seq_file *s)
 788 {
 789         dss_dump_clocks(s);
 790         dispc_dump_clocks(s);
 791 #ifdef CONFIG_FB_OMAP2_DSS_DSI
 792         dsi_dump_clocks(s);
 793 #endif
 794 }
 795 #endif
 796 
 797 
 798 static const enum omap_display_type omap2plus_ports[] = {
 799         OMAP_DISPLAY_TYPE_DPI,
 800 };
 801 
 802 static const enum omap_display_type omap34xx_ports[] = {
 803         OMAP_DISPLAY_TYPE_DPI,
 804         OMAP_DISPLAY_TYPE_SDI,
 805 };
 806 
 807 static const enum omap_display_type dra7xx_ports[] = {
 808         OMAP_DISPLAY_TYPE_DPI,
 809         OMAP_DISPLAY_TYPE_DPI,
 810         OMAP_DISPLAY_TYPE_DPI,
 811 };
 812 
 813 static const struct dss_features omap24xx_dss_feats = {
 814         /*
 815          * fck div max is really 16, but the divider range has gaps. The range
 816          * from 1 to 6 has no gaps, so let's use that as a max.
 817          */
 818         .fck_div_max            =       6,
 819         .dss_fck_multiplier     =       2,
 820         .parent_clk_name        =       "core_ck",
 821         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
 822         .ports                  =       omap2plus_ports,
 823         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
 824 };
 825 
 826 static const struct dss_features omap34xx_dss_feats = {
 827         .fck_div_max            =       16,
 828         .dss_fck_multiplier     =       2,
 829         .parent_clk_name        =       "dpll4_ck",
 830         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
 831         .ports                  =       omap34xx_ports,
 832         .num_ports              =       ARRAY_SIZE(omap34xx_ports),
 833 };
 834 
 835 static const struct dss_features omap3630_dss_feats = {
 836         .fck_div_max            =       32,
 837         .dss_fck_multiplier     =       1,
 838         .parent_clk_name        =       "dpll4_ck",
 839         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
 840         .ports                  =       omap2plus_ports,
 841         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
 842 };
 843 
 844 static const struct dss_features omap44xx_dss_feats = {
 845         .fck_div_max            =       32,
 846         .dss_fck_multiplier     =       1,
 847         .parent_clk_name        =       "dpll_per_x2_ck",
 848         .dpi_select_source      =       &dss_dpi_select_source_omap4,
 849         .ports                  =       omap2plus_ports,
 850         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
 851 };
 852 
 853 static const struct dss_features omap54xx_dss_feats = {
 854         .fck_div_max            =       64,
 855         .dss_fck_multiplier     =       1,
 856         .parent_clk_name        =       "dpll_per_x2_ck",
 857         .dpi_select_source      =       &dss_dpi_select_source_omap5,
 858         .ports                  =       omap2plus_ports,
 859         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
 860 };
 861 
 862 static const struct dss_features am43xx_dss_feats = {
 863         .fck_div_max            =       0,
 864         .dss_fck_multiplier     =       0,
 865         .parent_clk_name        =       NULL,
 866         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
 867         .ports                  =       omap2plus_ports,
 868         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
 869 };
 870 
 871 static const struct dss_features dra7xx_dss_feats = {
 872         .fck_div_max            =       64,
 873         .dss_fck_multiplier     =       1,
 874         .parent_clk_name        =       "dpll_per_x2_ck",
 875         .dpi_select_source      =       &dss_dpi_select_source_dra7xx,
 876         .ports                  =       dra7xx_ports,
 877         .num_ports              =       ARRAY_SIZE(dra7xx_ports),
 878 };
 879 
 880 static const struct dss_features *dss_get_features(void)
 881 {
 882         switch (omapdss_get_version()) {
 883         case OMAPDSS_VER_OMAP24xx:
 884                 return &omap24xx_dss_feats;
 885 
 886         case OMAPDSS_VER_OMAP34xx_ES1:
 887         case OMAPDSS_VER_OMAP34xx_ES3:
 888         case OMAPDSS_VER_AM35xx:
 889                 return &omap34xx_dss_feats;
 890 
 891         case OMAPDSS_VER_OMAP3630:
 892                 return &omap3630_dss_feats;
 893 
 894         case OMAPDSS_VER_OMAP4430_ES1:
 895         case OMAPDSS_VER_OMAP4430_ES2:
 896         case OMAPDSS_VER_OMAP4:
 897                 return &omap44xx_dss_feats;
 898 
 899         case OMAPDSS_VER_OMAP5:
 900                 return &omap54xx_dss_feats;
 901 
 902         case OMAPDSS_VER_AM43xx:
 903                 return &am43xx_dss_feats;
 904 
 905         case OMAPDSS_VER_DRA7xx:
 906                 return &dra7xx_dss_feats;
 907 
 908         default:
 909                 return NULL;
 910         }
 911 }
 912 
 913 static void dss_uninit_ports(struct platform_device *pdev);
 914 
 915 static int dss_init_ports(struct platform_device *pdev)
 916 {
 917         struct device_node *parent = pdev->dev.of_node;
 918         struct device_node *port;
 919         int r, ret = 0;
 920 
 921         if (parent == NULL)
 922                 return 0;
 923 
 924         port = omapdss_of_get_next_port(parent, NULL);
 925         if (!port)
 926                 return 0;
 927 
 928         if (dss.feat->num_ports == 0)
 929                 return 0;
 930 
 931         do {
 932                 enum omap_display_type port_type;
 933                 u32 reg;
 934 
 935                 r = of_property_read_u32(port, "reg", &reg);
 936                 if (r)
 937                         reg = 0;
 938 
 939                 if (reg >= dss.feat->num_ports)
 940                         continue;
 941 
 942                 port_type = dss.feat->ports[reg];
 943 
 944                 switch (port_type) {
 945                 case OMAP_DISPLAY_TYPE_DPI:
 946                         ret = dpi_init_port(pdev, port);
 947                         break;
 948                 case OMAP_DISPLAY_TYPE_SDI:
 949                         ret = sdi_init_port(pdev, port);
 950                         break;
 951                 default:
 952                         break;
 953                 }
 954         } while (!ret &&
 955                  (port = omapdss_of_get_next_port(parent, port)) != NULL);
 956 
 957         if (ret)
 958                 dss_uninit_ports(pdev);
 959 
 960         return ret;
 961 }
 962 
 963 static void dss_uninit_ports(struct platform_device *pdev)
 964 {
 965         struct device_node *parent = pdev->dev.of_node;
 966         struct device_node *port;
 967 
 968         if (parent == NULL)
 969                 return;
 970 
 971         port = omapdss_of_get_next_port(parent, NULL);
 972         if (!port)
 973                 return;
 974 
 975         if (dss.feat->num_ports == 0)
 976                 return;
 977 
 978         do {
 979                 enum omap_display_type port_type;
 980                 u32 reg;
 981                 int r;
 982 
 983                 r = of_property_read_u32(port, "reg", &reg);
 984                 if (r)
 985                         reg = 0;
 986 
 987                 if (reg >= dss.feat->num_ports)
 988                         continue;
 989 
 990                 port_type = dss.feat->ports[reg];
 991 
 992                 switch (port_type) {
 993                 case OMAP_DISPLAY_TYPE_DPI:
 994                         dpi_uninit_port(port);
 995                         break;
 996                 case OMAP_DISPLAY_TYPE_SDI:
 997                         sdi_uninit_port(port);
 998                         break;
 999                 default:
1000                         break;
1001                 }
1002         } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1003 }
1004 
1005 static int dss_video_pll_probe(struct platform_device *pdev)
1006 {
1007         struct device_node *np = pdev->dev.of_node;
1008         struct regulator *pll_regulator;
1009         int r;
1010 
1011         if (!np)
1012                 return 0;
1013 
1014         if (of_property_read_bool(np, "syscon-pll-ctrl")) {
1015                 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1016                         "syscon-pll-ctrl");
1017                 if (IS_ERR(dss.syscon_pll_ctrl)) {
1018                         dev_err(&pdev->dev,
1019                                 "failed to get syscon-pll-ctrl regmap\n");
1020                         return PTR_ERR(dss.syscon_pll_ctrl);
1021                 }
1022 
1023                 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1024                                 &dss.syscon_pll_ctrl_offset)) {
1025                         dev_err(&pdev->dev,
1026                                 "failed to get syscon-pll-ctrl offset\n");
1027                         return -EINVAL;
1028                 }
1029         }
1030 
1031         pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1032         if (IS_ERR(pll_regulator)) {
1033                 r = PTR_ERR(pll_regulator);
1034 
1035                 switch (r) {
1036                 case -ENOENT:
1037                         pll_regulator = NULL;
1038                         break;
1039 
1040                 case -EPROBE_DEFER:
1041                         return -EPROBE_DEFER;
1042 
1043                 default:
1044                         DSSERR("can't get DPLL VDDA regulator\n");
1045                         return r;
1046                 }
1047         }
1048 
1049         if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1050                 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1051                 if (IS_ERR(dss.video1_pll))
1052                         return PTR_ERR(dss.video1_pll);
1053         }
1054 
1055         if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1056                 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1057                 if (IS_ERR(dss.video2_pll)) {
1058                         dss_video_pll_uninit(dss.video1_pll);
1059                         return PTR_ERR(dss.video2_pll);
1060                 }
1061         }
1062 
1063         return 0;
1064 }
1065 
1066 /* DSS HW IP initialisation */
1067 static int dss_bind(struct device *dev)
1068 {
1069         struct platform_device *pdev = to_platform_device(dev);
1070         struct resource *dss_mem;
1071         u32 rev;
1072         int r;
1073 
1074         dss.pdev = pdev;
1075 
1076         dss.feat = dss_get_features();
1077         if (!dss.feat)
1078                 return -ENODEV;
1079 
1080         dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
1081         if (!dss_mem) {
1082                 DSSERR("can't get IORESOURCE_MEM DSS\n");
1083                 return -EINVAL;
1084         }
1085 
1086         dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
1087                                 resource_size(dss_mem));
1088         if (!dss.base) {
1089                 DSSERR("can't ioremap DSS\n");
1090                 return -ENOMEM;
1091         }
1092 
1093         r = dss_get_clocks();
1094         if (r)
1095                 return r;
1096 
1097         r = dss_setup_default_clock();
1098         if (r)
1099                 goto err_setup_clocks;
1100 
1101         r = dss_video_pll_probe(pdev);
1102         if (r)
1103                 goto err_pll_init;
1104 
1105         r = dss_init_ports(pdev);
1106         if (r)
1107                 goto err_init_ports;
1108 
1109         pm_runtime_enable(&pdev->dev);
1110 
1111         r = dss_runtime_get();
1112         if (r)
1113                 goto err_runtime_get;
1114 
1115         dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
1116 
1117         /* Select DPLL */
1118         REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1119 
1120         dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
1121 
1122 #ifdef CONFIG_FB_OMAP2_DSS_VENC
1123         REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);      /* venc dac demen */
1124         REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);      /* venc clock 4x enable */
1125         REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);      /* venc clock mode = normal */
1126 #endif
1127         dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1128         dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1129         dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
1130         dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1131         dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1132 
1133         rev = dss_read_reg(DSS_REVISION);
1134         printk(KERN_INFO "OMAP DSS rev %d.%d\n",
1135                         FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1136 
1137         dss_runtime_put();
1138 
1139         r = component_bind_all(&pdev->dev, NULL);
1140         if (r)
1141                 goto err_component;
1142 
1143         dss_debugfs_create_file("dss", dss_dump_regs);
1144 
1145         pm_set_vt_switch(0);
1146 
1147         dss_initialized = true;
1148 
1149         return 0;
1150 
1151 err_component:
1152 err_runtime_get:
1153         pm_runtime_disable(&pdev->dev);
1154         dss_uninit_ports(pdev);
1155 err_init_ports:
1156         if (dss.video1_pll)
1157                 dss_video_pll_uninit(dss.video1_pll);
1158 
1159         if (dss.video2_pll)
1160                 dss_video_pll_uninit(dss.video2_pll);
1161 err_pll_init:
1162 err_setup_clocks:
1163         dss_put_clocks();
1164         return r;
1165 }
1166 
1167 static void dss_unbind(struct device *dev)
1168 {
1169         struct platform_device *pdev = to_platform_device(dev);
1170 
1171         dss_initialized = false;
1172 
1173         component_unbind_all(&pdev->dev, NULL);
1174 
1175         if (dss.video1_pll)
1176                 dss_video_pll_uninit(dss.video1_pll);
1177 
1178         if (dss.video2_pll)
1179                 dss_video_pll_uninit(dss.video2_pll);
1180 
1181         dss_uninit_ports(pdev);
1182 
1183         pm_runtime_disable(&pdev->dev);
1184 
1185         dss_put_clocks();
1186 }
1187 
1188 static const struct component_master_ops dss_component_ops = {
1189         .bind = dss_bind,
1190         .unbind = dss_unbind,
1191 };
1192 
1193 static int dss_component_compare(struct device *dev, void *data)
1194 {
1195         struct device *child = data;
1196         return dev == child;
1197 }
1198 
1199 static int dss_add_child_component(struct device *dev, void *data)
1200 {
1201         struct component_match **match = data;
1202 
1203         /*
1204          * HACK
1205          * We don't have a working driver for rfbi, so skip it here always.
1206          * Otherwise dss will never get probed successfully, as it will wait
1207          * for rfbi to get probed.
1208          */
1209         if (strstr(dev_name(dev), "rfbi"))
1210                 return 0;
1211 
1212         component_match_add(dev->parent, match, dss_component_compare, dev);
1213 
1214         return 0;
1215 }
1216 
1217 static int dss_probe(struct platform_device *pdev)
1218 {
1219         struct component_match *match = NULL;
1220         int r;
1221 
1222         /* add all the child devices as components */
1223         device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1224 
1225         r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1226         if (r)
1227                 return r;
1228 
1229         return 0;
1230 }
1231 
1232 static int dss_remove(struct platform_device *pdev)
1233 {
1234         component_master_del(&pdev->dev, &dss_component_ops);
1235         return 0;
1236 }
1237 
1238 static int dss_runtime_suspend(struct device *dev)
1239 {
1240         dss_save_context();
1241         dss_set_min_bus_tput(dev, 0);
1242 
1243         pinctrl_pm_select_sleep_state(dev);
1244 
1245         return 0;
1246 }
1247 
1248 static int dss_runtime_resume(struct device *dev)
1249 {
1250         int r;
1251 
1252         pinctrl_pm_select_default_state(dev);
1253 
1254         /*
1255          * Set an arbitrarily high tput request to ensure OPP100.
1256          * What we should really do is to make a request to stay in OPP100,
1257          * without any tput requirements, but that is not currently possible
1258          * via the PM layer.
1259          */
1260 
1261         r = dss_set_min_bus_tput(dev, 1000000000);
1262         if (r)
1263                 return r;
1264 
1265         dss_restore_context();
1266         return 0;
1267 }
1268 
1269 static const struct dev_pm_ops dss_pm_ops = {
1270         .runtime_suspend = dss_runtime_suspend,
1271         .runtime_resume = dss_runtime_resume,
1272 };
1273 
1274 static const struct of_device_id dss_of_match[] = {
1275         { .compatible = "ti,omap2-dss", },
1276         { .compatible = "ti,omap3-dss", },
1277         { .compatible = "ti,omap4-dss", },
1278         { .compatible = "ti,omap5-dss", },
1279         { .compatible = "ti,dra7-dss", },
1280         {},
1281 };
1282 
1283 MODULE_DEVICE_TABLE(of, dss_of_match);
1284 
1285 static struct platform_driver omap_dsshw_driver = {
1286         .probe          = dss_probe,
1287         .remove         = dss_remove,
1288         .driver         = {
1289                 .name   = "omapdss_dss",
1290                 .pm     = &dss_pm_ops,
1291                 .of_match_table = dss_of_match,
1292                 .suppress_bind_attrs = true,
1293         },
1294 };
1295 
1296 int __init dss_init_platform_driver(void)
1297 {
1298         return platform_driver_register(&omap_dsshw_driver);
1299 }
1300 
1301 void dss_uninit_platform_driver(void)
1302 {
1303         platform_driver_unregister(&omap_dsshw_driver);
1304 }

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