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