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