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