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/omapfb_dss.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 void dss_uninit_ports(struct platform_device *pdev);
 945
 946static int dss_init_ports(struct platform_device *pdev)
 947{
 948        struct device_node *parent = pdev->dev.of_node;
 949        struct device_node *port;
 950        int r, ret = 0;
 951
 952        if (parent == NULL)
 953                return 0;
 954
 955        port = omapdss_of_get_next_port(parent, NULL);
 956        if (!port)
 957                return 0;
 958
 959        if (dss.feat->num_ports == 0)
 960                return 0;
 961
 962        do {
 963                enum omap_display_type port_type;
 964                u32 reg;
 965
 966                r = of_property_read_u32(port, "reg", &reg);
 967                if (r)
 968                        reg = 0;
 969
 970                if (reg >= dss.feat->num_ports)
 971                        continue;
 972
 973                port_type = dss.feat->ports[reg];
 974
 975                switch (port_type) {
 976                case OMAP_DISPLAY_TYPE_DPI:
 977                        ret = dpi_init_port(pdev, port);
 978                        break;
 979                case OMAP_DISPLAY_TYPE_SDI:
 980                        ret = sdi_init_port(pdev, port);
 981                        break;
 982                default:
 983                        break;
 984                }
 985        } while (!ret &&
 986                 (port = omapdss_of_get_next_port(parent, port)) != NULL);
 987
 988        if (ret)
 989                dss_uninit_ports(pdev);
 990
 991        return ret;
 992}
 993
 994static void dss_uninit_ports(struct platform_device *pdev)
 995{
 996        struct device_node *parent = pdev->dev.of_node;
 997        struct device_node *port;
 998
 999        if (parent == NULL)
1000                return;
1001
1002        port = omapdss_of_get_next_port(parent, NULL);
1003        if (!port)
1004                return;
1005
1006        if (dss.feat->num_ports == 0)
1007                return;
1008
1009        do {
1010                enum omap_display_type port_type;
1011                u32 reg;
1012                int r;
1013
1014                r = of_property_read_u32(port, "reg", &reg);
1015                if (r)
1016                        reg = 0;
1017
1018                if (reg >= dss.feat->num_ports)
1019                        continue;
1020
1021                port_type = dss.feat->ports[reg];
1022
1023                switch (port_type) {
1024                case OMAP_DISPLAY_TYPE_DPI:
1025                        dpi_uninit_port(port);
1026                        break;
1027                case OMAP_DISPLAY_TYPE_SDI:
1028                        sdi_uninit_port(port);
1029                        break;
1030                default:
1031                        break;
1032                }
1033        } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1034}
1035
1036static int dss_video_pll_probe(struct platform_device *pdev)
1037{
1038        struct device_node *np = pdev->dev.of_node;
1039        struct regulator *pll_regulator;
1040        int r;
1041
1042        if (!np)
1043                return 0;
1044
1045        if (of_property_read_bool(np, "syscon-pll-ctrl")) {
1046                dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1047                        "syscon-pll-ctrl");
1048                if (IS_ERR(dss.syscon_pll_ctrl)) {
1049                        dev_err(&pdev->dev,
1050                                "failed to get syscon-pll-ctrl regmap\n");
1051                        return PTR_ERR(dss.syscon_pll_ctrl);
1052                }
1053
1054                if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1055                                &dss.syscon_pll_ctrl_offset)) {
1056                        dev_err(&pdev->dev,
1057                                "failed to get syscon-pll-ctrl offset\n");
1058                        return -EINVAL;
1059                }
1060        }
1061
1062        pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1063        if (IS_ERR(pll_regulator)) {
1064                r = PTR_ERR(pll_regulator);
1065
1066                switch (r) {
1067                case -ENOENT:
1068                        pll_regulator = NULL;
1069                        break;
1070
1071                case -EPROBE_DEFER:
1072                        return -EPROBE_DEFER;
1073
1074                default:
1075                        DSSERR("can't get DPLL VDDA regulator\n");
1076                        return r;
1077                }
1078        }
1079
1080        if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1081                dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1082                if (IS_ERR(dss.video1_pll))
1083                        return PTR_ERR(dss.video1_pll);
1084        }
1085
1086        if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1087                dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1088                if (IS_ERR(dss.video2_pll)) {
1089                        dss_video_pll_uninit(dss.video1_pll);
1090                        return PTR_ERR(dss.video2_pll);
1091                }
1092        }
1093
1094        return 0;
1095}
1096
1097/* DSS HW IP initialisation */
1098static int dss_bind(struct device *dev)
1099{
1100        struct platform_device *pdev = to_platform_device(dev);
1101        struct resource *dss_mem;
1102        u32 rev;
1103        int r;
1104
1105        dss.pdev = pdev;
1106
1107        r = dss_init_features(dss.pdev);
1108        if (r)
1109                return r;
1110
1111        dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
1112        if (!dss_mem) {
1113                DSSERR("can't get IORESOURCE_MEM DSS\n");
1114                return -EINVAL;
1115        }
1116
1117        dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
1118                                resource_size(dss_mem));
1119        if (!dss.base) {
1120                DSSERR("can't ioremap DSS\n");
1121                return -ENOMEM;
1122        }
1123
1124        r = dss_get_clocks();
1125        if (r)
1126                return r;
1127
1128        r = dss_setup_default_clock();
1129        if (r)
1130                goto err_setup_clocks;
1131
1132        r = dss_video_pll_probe(pdev);
1133        if (r)
1134                goto err_pll_init;
1135
1136        r = dss_init_ports(pdev);
1137        if (r)
1138                goto err_init_ports;
1139
1140        pm_runtime_enable(&pdev->dev);
1141
1142        r = dss_runtime_get();
1143        if (r)
1144                goto err_runtime_get;
1145
1146        dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
1147
1148        /* Select DPLL */
1149        REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1150
1151        dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
1152
1153#ifdef CONFIG_FB_OMAP2_DSS_VENC
1154        REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);      /* venc dac demen */
1155        REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);      /* venc clock 4x enable */
1156        REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);      /* venc clock mode = normal */
1157#endif
1158        dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1159        dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1160        dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
1161        dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1162        dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1163
1164        rev = dss_read_reg(DSS_REVISION);
1165        printk(KERN_INFO "OMAP DSS rev %d.%d\n",
1166                        FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1167
1168        dss_runtime_put();
1169
1170        r = component_bind_all(&pdev->dev, NULL);
1171        if (r)
1172                goto err_component;
1173
1174        dss_debugfs_create_file("dss", dss_dump_regs);
1175
1176        pm_set_vt_switch(0);
1177
1178        dss_initialized = true;
1179
1180        return 0;
1181
1182err_component:
1183err_runtime_get:
1184        pm_runtime_disable(&pdev->dev);
1185        dss_uninit_ports(pdev);
1186err_init_ports:
1187        if (dss.video1_pll)
1188                dss_video_pll_uninit(dss.video1_pll);
1189
1190        if (dss.video2_pll)
1191                dss_video_pll_uninit(dss.video2_pll);
1192err_pll_init:
1193err_setup_clocks:
1194        dss_put_clocks();
1195        return r;
1196}
1197
1198static void dss_unbind(struct device *dev)
1199{
1200        struct platform_device *pdev = to_platform_device(dev);
1201
1202        dss_initialized = false;
1203
1204        component_unbind_all(&pdev->dev, NULL);
1205
1206        if (dss.video1_pll)
1207                dss_video_pll_uninit(dss.video1_pll);
1208
1209        if (dss.video2_pll)
1210                dss_video_pll_uninit(dss.video2_pll);
1211
1212        dss_uninit_ports(pdev);
1213
1214        pm_runtime_disable(&pdev->dev);
1215
1216        dss_put_clocks();
1217}
1218
1219static const struct component_master_ops dss_component_ops = {
1220        .bind = dss_bind,
1221        .unbind = dss_unbind,
1222};
1223
1224static int dss_component_compare(struct device *dev, void *data)
1225{
1226        struct device *child = data;
1227        return dev == child;
1228}
1229
1230static int dss_add_child_component(struct device *dev, void *data)
1231{
1232        struct component_match **match = data;
1233
1234        /*
1235         * HACK
1236         * We don't have a working driver for rfbi, so skip it here always.
1237         * Otherwise dss will never get probed successfully, as it will wait
1238         * for rfbi to get probed.
1239         */
1240        if (strstr(dev_name(dev), "rfbi"))
1241                return 0;
1242
1243        component_match_add(dev->parent, match, dss_component_compare, dev);
1244
1245        return 0;
1246}
1247
1248static int dss_probe(struct platform_device *pdev)
1249{
1250        struct component_match *match = NULL;
1251        int r;
1252
1253        /* add all the child devices as components */
1254        device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1255
1256        r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1257        if (r)
1258                return r;
1259
1260        return 0;
1261}
1262
1263static int dss_remove(struct platform_device *pdev)
1264{
1265        component_master_del(&pdev->dev, &dss_component_ops);
1266        return 0;
1267}
1268
1269static int dss_runtime_suspend(struct device *dev)
1270{
1271        dss_save_context();
1272        dss_set_min_bus_tput(dev, 0);
1273
1274        pinctrl_pm_select_sleep_state(dev);
1275
1276        return 0;
1277}
1278
1279static int dss_runtime_resume(struct device *dev)
1280{
1281        int r;
1282
1283        pinctrl_pm_select_default_state(dev);
1284
1285        /*
1286         * Set an arbitrarily high tput request to ensure OPP100.
1287         * What we should really do is to make a request to stay in OPP100,
1288         * without any tput requirements, but that is not currently possible
1289         * via the PM layer.
1290         */
1291
1292        r = dss_set_min_bus_tput(dev, 1000000000);
1293        if (r)
1294                return r;
1295
1296        dss_restore_context();
1297        return 0;
1298}
1299
1300static const struct dev_pm_ops dss_pm_ops = {
1301        .runtime_suspend = dss_runtime_suspend,
1302        .runtime_resume = dss_runtime_resume,
1303};
1304
1305static const struct of_device_id dss_of_match[] = {
1306        { .compatible = "ti,omap2-dss", },
1307        { .compatible = "ti,omap3-dss", },
1308        { .compatible = "ti,omap4-dss", },
1309        { .compatible = "ti,omap5-dss", },
1310        { .compatible = "ti,dra7-dss", },
1311        {},
1312};
1313
1314MODULE_DEVICE_TABLE(of, dss_of_match);
1315
1316static struct platform_driver omap_dsshw_driver = {
1317        .probe          = dss_probe,
1318        .remove         = dss_remove,
1319        .driver         = {
1320                .name   = "omapdss_dss",
1321                .pm     = &dss_pm_ops,
1322                .of_match_table = dss_of_match,
1323                .suppress_bind_attrs = true,
1324        },
1325};
1326
1327int __init dss_init_platform_driver(void)
1328{
1329        return platform_driver_register(&omap_dsshw_driver);
1330}
1331
1332void dss_uninit_platform_driver(void)
1333{
1334        platform_driver_unregister(&omap_dsshw_driver);
1335}
1336