linux/drivers/video/omap2/dss/rfbi.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/video/omap2/dss/rfbi.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 "RFBI"
  24
  25#include <linux/kernel.h>
  26#include <linux/dma-mapping.h>
  27#include <linux/export.h>
  28#include <linux/vmalloc.h>
  29#include <linux/clk.h>
  30#include <linux/io.h>
  31#include <linux/delay.h>
  32#include <linux/kfifo.h>
  33#include <linux/ktime.h>
  34#include <linux/hrtimer.h>
  35#include <linux/seq_file.h>
  36#include <linux/semaphore.h>
  37#include <linux/platform_device.h>
  38#include <linux/pm_runtime.h>
  39
  40#include <video/omapdss.h>
  41#include "dss.h"
  42
  43struct rfbi_reg { u16 idx; };
  44
  45#define RFBI_REG(idx)           ((const struct rfbi_reg) { idx })
  46
  47#define RFBI_REVISION           RFBI_REG(0x0000)
  48#define RFBI_SYSCONFIG          RFBI_REG(0x0010)
  49#define RFBI_SYSSTATUS          RFBI_REG(0x0014)
  50#define RFBI_CONTROL            RFBI_REG(0x0040)
  51#define RFBI_PIXEL_CNT          RFBI_REG(0x0044)
  52#define RFBI_LINE_NUMBER        RFBI_REG(0x0048)
  53#define RFBI_CMD                RFBI_REG(0x004c)
  54#define RFBI_PARAM              RFBI_REG(0x0050)
  55#define RFBI_DATA               RFBI_REG(0x0054)
  56#define RFBI_READ               RFBI_REG(0x0058)
  57#define RFBI_STATUS             RFBI_REG(0x005c)
  58
  59#define RFBI_CONFIG(n)          RFBI_REG(0x0060 + (n)*0x18)
  60#define RFBI_ONOFF_TIME(n)      RFBI_REG(0x0064 + (n)*0x18)
  61#define RFBI_CYCLE_TIME(n)      RFBI_REG(0x0068 + (n)*0x18)
  62#define RFBI_DATA_CYCLE1(n)     RFBI_REG(0x006c + (n)*0x18)
  63#define RFBI_DATA_CYCLE2(n)     RFBI_REG(0x0070 + (n)*0x18)
  64#define RFBI_DATA_CYCLE3(n)     RFBI_REG(0x0074 + (n)*0x18)
  65
  66#define RFBI_VSYNC_WIDTH        RFBI_REG(0x0090)
  67#define RFBI_HSYNC_WIDTH        RFBI_REG(0x0094)
  68
  69#define REG_FLD_MOD(idx, val, start, end) \
  70        rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
  71
  72enum omap_rfbi_cycleformat {
  73        OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
  74        OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
  75        OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
  76        OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
  77};
  78
  79enum omap_rfbi_datatype {
  80        OMAP_DSS_RFBI_DATATYPE_12 = 0,
  81        OMAP_DSS_RFBI_DATATYPE_16 = 1,
  82        OMAP_DSS_RFBI_DATATYPE_18 = 2,
  83        OMAP_DSS_RFBI_DATATYPE_24 = 3,
  84};
  85
  86enum omap_rfbi_parallelmode {
  87        OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
  88        OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
  89        OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
  90        OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
  91};
  92
  93static int rfbi_convert_timings(struct rfbi_timings *t);
  94static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
  95
  96static struct {
  97        struct platform_device *pdev;
  98        void __iomem    *base;
  99
 100        unsigned long   l4_khz;
 101
 102        enum omap_rfbi_datatype datatype;
 103        enum omap_rfbi_parallelmode parallelmode;
 104
 105        enum omap_rfbi_te_mode te_mode;
 106        int te_enabled;
 107
 108        void (*framedone_callback)(void *data);
 109        void *framedone_callback_data;
 110
 111        struct omap_dss_device *dssdev[2];
 112
 113        struct semaphore bus_lock;
 114
 115        struct omap_video_timings timings;
 116        int pixel_size;
 117        int data_lines;
 118        struct rfbi_timings intf_timings;
 119
 120        struct omap_dss_output output;
 121} rfbi;
 122
 123static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
 124{
 125        __raw_writel(val, rfbi.base + idx.idx);
 126}
 127
 128static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
 129{
 130        return __raw_readl(rfbi.base + idx.idx);
 131}
 132
 133static int rfbi_runtime_get(void)
 134{
 135        int r;
 136
 137        DSSDBG("rfbi_runtime_get\n");
 138
 139        r = pm_runtime_get_sync(&rfbi.pdev->dev);
 140        WARN_ON(r < 0);
 141        return r < 0 ? r : 0;
 142}
 143
 144static void rfbi_runtime_put(void)
 145{
 146        int r;
 147
 148        DSSDBG("rfbi_runtime_put\n");
 149
 150        r = pm_runtime_put_sync(&rfbi.pdev->dev);
 151        WARN_ON(r < 0 && r != -ENOSYS);
 152}
 153
 154void rfbi_bus_lock(void)
 155{
 156        down(&rfbi.bus_lock);
 157}
 158EXPORT_SYMBOL(rfbi_bus_lock);
 159
 160void rfbi_bus_unlock(void)
 161{
 162        up(&rfbi.bus_lock);
 163}
 164EXPORT_SYMBOL(rfbi_bus_unlock);
 165
 166void omap_rfbi_write_command(const void *buf, u32 len)
 167{
 168        switch (rfbi.parallelmode) {
 169        case OMAP_DSS_RFBI_PARALLELMODE_8:
 170        {
 171                const u8 *b = buf;
 172                for (; len; len--)
 173                        rfbi_write_reg(RFBI_CMD, *b++);
 174                break;
 175        }
 176
 177        case OMAP_DSS_RFBI_PARALLELMODE_16:
 178        {
 179                const u16 *w = buf;
 180                BUG_ON(len & 1);
 181                for (; len; len -= 2)
 182                        rfbi_write_reg(RFBI_CMD, *w++);
 183                break;
 184        }
 185
 186        case OMAP_DSS_RFBI_PARALLELMODE_9:
 187        case OMAP_DSS_RFBI_PARALLELMODE_12:
 188        default:
 189                BUG();
 190        }
 191}
 192EXPORT_SYMBOL(omap_rfbi_write_command);
 193
 194void omap_rfbi_read_data(void *buf, u32 len)
 195{
 196        switch (rfbi.parallelmode) {
 197        case OMAP_DSS_RFBI_PARALLELMODE_8:
 198        {
 199                u8 *b = buf;
 200                for (; len; len--) {
 201                        rfbi_write_reg(RFBI_READ, 0);
 202                        *b++ = rfbi_read_reg(RFBI_READ);
 203                }
 204                break;
 205        }
 206
 207        case OMAP_DSS_RFBI_PARALLELMODE_16:
 208        {
 209                u16 *w = buf;
 210                BUG_ON(len & ~1);
 211                for (; len; len -= 2) {
 212                        rfbi_write_reg(RFBI_READ, 0);
 213                        *w++ = rfbi_read_reg(RFBI_READ);
 214                }
 215                break;
 216        }
 217
 218        case OMAP_DSS_RFBI_PARALLELMODE_9:
 219        case OMAP_DSS_RFBI_PARALLELMODE_12:
 220        default:
 221                BUG();
 222        }
 223}
 224EXPORT_SYMBOL(omap_rfbi_read_data);
 225
 226void omap_rfbi_write_data(const void *buf, u32 len)
 227{
 228        switch (rfbi.parallelmode) {
 229        case OMAP_DSS_RFBI_PARALLELMODE_8:
 230        {
 231                const u8 *b = buf;
 232                for (; len; len--)
 233                        rfbi_write_reg(RFBI_PARAM, *b++);
 234                break;
 235        }
 236
 237        case OMAP_DSS_RFBI_PARALLELMODE_16:
 238        {
 239                const u16 *w = buf;
 240                BUG_ON(len & 1);
 241                for (; len; len -= 2)
 242                        rfbi_write_reg(RFBI_PARAM, *w++);
 243                break;
 244        }
 245
 246        case OMAP_DSS_RFBI_PARALLELMODE_9:
 247        case OMAP_DSS_RFBI_PARALLELMODE_12:
 248        default:
 249                BUG();
 250
 251        }
 252}
 253EXPORT_SYMBOL(omap_rfbi_write_data);
 254
 255void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
 256                u16 x, u16 y,
 257                u16 w, u16 h)
 258{
 259        int start_offset = scr_width * y + x;
 260        int horiz_offset = scr_width - w;
 261        int i;
 262
 263        if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
 264           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
 265                const u16 __iomem *pd = buf;
 266                pd += start_offset;
 267
 268                for (; h; --h) {
 269                        for (i = 0; i < w; ++i) {
 270                                const u8 __iomem *b = (const u8 __iomem *)pd;
 271                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
 272                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
 273                                ++pd;
 274                        }
 275                        pd += horiz_offset;
 276                }
 277        } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
 278           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
 279                const u32 __iomem *pd = buf;
 280                pd += start_offset;
 281
 282                for (; h; --h) {
 283                        for (i = 0; i < w; ++i) {
 284                                const u8 __iomem *b = (const u8 __iomem *)pd;
 285                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
 286                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
 287                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
 288                                ++pd;
 289                        }
 290                        pd += horiz_offset;
 291                }
 292        } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
 293           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
 294                const u16 __iomem *pd = buf;
 295                pd += start_offset;
 296
 297                for (; h; --h) {
 298                        for (i = 0; i < w; ++i) {
 299                                rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
 300                                ++pd;
 301                        }
 302                        pd += horiz_offset;
 303                }
 304        } else {
 305                BUG();
 306        }
 307}
 308EXPORT_SYMBOL(omap_rfbi_write_pixels);
 309
 310static int rfbi_transfer_area(struct omap_dss_device *dssdev,
 311                void (*callback)(void *data), void *data)
 312{
 313        u32 l;
 314        int r;
 315        struct omap_overlay_manager *mgr = dssdev->output->manager;
 316        u16 width = rfbi.timings.x_res;
 317        u16 height = rfbi.timings.y_res;
 318
 319        /*BUG_ON(callback == 0);*/
 320        BUG_ON(rfbi.framedone_callback != NULL);
 321
 322        DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
 323
 324        dss_mgr_set_timings(mgr, &rfbi.timings);
 325
 326        r = dss_mgr_enable(mgr);
 327        if (r)
 328                return r;
 329
 330        rfbi.framedone_callback = callback;
 331        rfbi.framedone_callback_data = data;
 332
 333        rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
 334
 335        l = rfbi_read_reg(RFBI_CONTROL);
 336        l = FLD_MOD(l, 1, 0, 0); /* enable */
 337        if (!rfbi.te_enabled)
 338                l = FLD_MOD(l, 1, 4, 4); /* ITE */
 339
 340        rfbi_write_reg(RFBI_CONTROL, l);
 341
 342        return 0;
 343}
 344
 345static void framedone_callback(void *data)
 346{
 347        void (*callback)(void *data);
 348
 349        DSSDBG("FRAMEDONE\n");
 350
 351        REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
 352
 353        callback = rfbi.framedone_callback;
 354        rfbi.framedone_callback = NULL;
 355
 356        if (callback != NULL)
 357                callback(rfbi.framedone_callback_data);
 358}
 359
 360#if 1 /* VERBOSE */
 361static void rfbi_print_timings(void)
 362{
 363        u32 l;
 364        u32 time;
 365
 366        l = rfbi_read_reg(RFBI_CONFIG(0));
 367        time = 1000000000 / rfbi.l4_khz;
 368        if (l & (1 << 4))
 369                time *= 2;
 370
 371        DSSDBG("Tick time %u ps\n", time);
 372        l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
 373        DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
 374                "REONTIME %d, REOFFTIME %d\n",
 375                l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
 376                (l >> 20) & 0x0f, (l >> 24) & 0x3f);
 377
 378        l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
 379        DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
 380                "ACCESSTIME %d\n",
 381                (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
 382                (l >> 22) & 0x3f);
 383}
 384#else
 385static void rfbi_print_timings(void) {}
 386#endif
 387
 388
 389
 390
 391static u32 extif_clk_period;
 392
 393static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
 394{
 395        int bus_tick = extif_clk_period * div;
 396        return (ps + bus_tick - 1) / bus_tick * bus_tick;
 397}
 398
 399static int calc_reg_timing(struct rfbi_timings *t, int div)
 400{
 401        t->clk_div = div;
 402
 403        t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
 404
 405        t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
 406        t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
 407        t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
 408
 409        t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
 410        t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
 411        t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
 412
 413        t->access_time = round_to_extif_ticks(t->access_time, div);
 414        t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
 415        t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
 416
 417        DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
 418               t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
 419        DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
 420               t->we_on_time, t->we_off_time, t->re_cycle_time,
 421               t->we_cycle_time);
 422        DSSDBG("[reg]rdaccess %d cspulse %d\n",
 423               t->access_time, t->cs_pulse_width);
 424
 425        return rfbi_convert_timings(t);
 426}
 427
 428static int calc_extif_timings(struct rfbi_timings *t)
 429{
 430        u32 max_clk_div;
 431        int div;
 432
 433        rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
 434        for (div = 1; div <= max_clk_div; div++) {
 435                if (calc_reg_timing(t, div) == 0)
 436                        break;
 437        }
 438
 439        if (div <= max_clk_div)
 440                return 0;
 441
 442        DSSERR("can't setup timings\n");
 443        return -1;
 444}
 445
 446
 447static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
 448{
 449        int r;
 450
 451        if (!t->converted) {
 452                r = calc_extif_timings(t);
 453                if (r < 0)
 454                        DSSERR("Failed to calc timings\n");
 455        }
 456
 457        BUG_ON(!t->converted);
 458
 459        rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
 460        rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
 461
 462        /* TIMEGRANULARITY */
 463        REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
 464                    (t->tim[2] ? 1 : 0), 4, 4);
 465
 466        rfbi_print_timings();
 467}
 468
 469static int ps_to_rfbi_ticks(int time, int div)
 470{
 471        unsigned long tick_ps;
 472        int ret;
 473
 474        /* Calculate in picosecs to yield more exact results */
 475        tick_ps = 1000000000 / (rfbi.l4_khz) * div;
 476
 477        ret = (time + tick_ps - 1) / tick_ps;
 478
 479        return ret;
 480}
 481
 482static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
 483{
 484        *clk_period = 1000000000 / rfbi.l4_khz;
 485        *max_clk_div = 2;
 486}
 487
 488static int rfbi_convert_timings(struct rfbi_timings *t)
 489{
 490        u32 l;
 491        int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
 492        int actim, recyc, wecyc;
 493        int div = t->clk_div;
 494
 495        if (div <= 0 || div > 2)
 496                return -1;
 497
 498        /* Make sure that after conversion it still holds that:
 499         * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
 500         * csoff > cson, csoff >= max(weoff, reoff), actim > reon
 501         */
 502        weon = ps_to_rfbi_ticks(t->we_on_time, div);
 503        weoff = ps_to_rfbi_ticks(t->we_off_time, div);
 504        if (weoff <= weon)
 505                weoff = weon + 1;
 506        if (weon > 0x0f)
 507                return -1;
 508        if (weoff > 0x3f)
 509                return -1;
 510
 511        reon = ps_to_rfbi_ticks(t->re_on_time, div);
 512        reoff = ps_to_rfbi_ticks(t->re_off_time, div);
 513        if (reoff <= reon)
 514                reoff = reon + 1;
 515        if (reon > 0x0f)
 516                return -1;
 517        if (reoff > 0x3f)
 518                return -1;
 519
 520        cson = ps_to_rfbi_ticks(t->cs_on_time, div);
 521        csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
 522        if (csoff <= cson)
 523                csoff = cson + 1;
 524        if (csoff < max(weoff, reoff))
 525                csoff = max(weoff, reoff);
 526        if (cson > 0x0f)
 527                return -1;
 528        if (csoff > 0x3f)
 529                return -1;
 530
 531        l =  cson;
 532        l |= csoff << 4;
 533        l |= weon  << 10;
 534        l |= weoff << 14;
 535        l |= reon  << 20;
 536        l |= reoff << 24;
 537
 538        t->tim[0] = l;
 539
 540        actim = ps_to_rfbi_ticks(t->access_time, div);
 541        if (actim <= reon)
 542                actim = reon + 1;
 543        if (actim > 0x3f)
 544                return -1;
 545
 546        wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
 547        if (wecyc < weoff)
 548                wecyc = weoff;
 549        if (wecyc > 0x3f)
 550                return -1;
 551
 552        recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
 553        if (recyc < reoff)
 554                recyc = reoff;
 555        if (recyc > 0x3f)
 556                return -1;
 557
 558        cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
 559        if (cs_pulse > 0x3f)
 560                return -1;
 561
 562        l =  wecyc;
 563        l |= recyc    << 6;
 564        l |= cs_pulse << 12;
 565        l |= actim    << 22;
 566
 567        t->tim[1] = l;
 568
 569        t->tim[2] = div - 1;
 570
 571        t->converted = 1;
 572
 573        return 0;
 574}
 575
 576/* xxx FIX module selection missing */
 577int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
 578                             unsigned hs_pulse_time, unsigned vs_pulse_time,
 579                             int hs_pol_inv, int vs_pol_inv, int extif_div)
 580{
 581        int hs, vs;
 582        int min;
 583        u32 l;
 584
 585        hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
 586        vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
 587        if (hs < 2)
 588                return -EDOM;
 589        if (mode == OMAP_DSS_RFBI_TE_MODE_2)
 590                min = 2;
 591        else /* OMAP_DSS_RFBI_TE_MODE_1 */
 592                min = 4;
 593        if (vs < min)
 594                return -EDOM;
 595        if (vs == hs)
 596                return -EINVAL;
 597        rfbi.te_mode = mode;
 598        DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
 599                mode, hs, vs, hs_pol_inv, vs_pol_inv);
 600
 601        rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
 602        rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
 603
 604        l = rfbi_read_reg(RFBI_CONFIG(0));
 605        if (hs_pol_inv)
 606                l &= ~(1 << 21);
 607        else
 608                l |= 1 << 21;
 609        if (vs_pol_inv)
 610                l &= ~(1 << 20);
 611        else
 612                l |= 1 << 20;
 613
 614        return 0;
 615}
 616EXPORT_SYMBOL(omap_rfbi_setup_te);
 617
 618/* xxx FIX module selection missing */
 619int omap_rfbi_enable_te(bool enable, unsigned line)
 620{
 621        u32 l;
 622
 623        DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
 624        if (line > (1 << 11) - 1)
 625                return -EINVAL;
 626
 627        l = rfbi_read_reg(RFBI_CONFIG(0));
 628        l &= ~(0x3 << 2);
 629        if (enable) {
 630                rfbi.te_enabled = 1;
 631                l |= rfbi.te_mode << 2;
 632        } else
 633                rfbi.te_enabled = 0;
 634        rfbi_write_reg(RFBI_CONFIG(0), l);
 635        rfbi_write_reg(RFBI_LINE_NUMBER, line);
 636
 637        return 0;
 638}
 639EXPORT_SYMBOL(omap_rfbi_enable_te);
 640
 641static int rfbi_configure(int rfbi_module, int bpp, int lines)
 642{
 643        u32 l;
 644        int cycle1 = 0, cycle2 = 0, cycle3 = 0;
 645        enum omap_rfbi_cycleformat cycleformat;
 646        enum omap_rfbi_datatype datatype;
 647        enum omap_rfbi_parallelmode parallelmode;
 648
 649        switch (bpp) {
 650        case 12:
 651                datatype = OMAP_DSS_RFBI_DATATYPE_12;
 652                break;
 653        case 16:
 654                datatype = OMAP_DSS_RFBI_DATATYPE_16;
 655                break;
 656        case 18:
 657                datatype = OMAP_DSS_RFBI_DATATYPE_18;
 658                break;
 659        case 24:
 660                datatype = OMAP_DSS_RFBI_DATATYPE_24;
 661                break;
 662        default:
 663                BUG();
 664                return 1;
 665        }
 666        rfbi.datatype = datatype;
 667
 668        switch (lines) {
 669        case 8:
 670                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
 671                break;
 672        case 9:
 673                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
 674                break;
 675        case 12:
 676                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
 677                break;
 678        case 16:
 679                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
 680                break;
 681        default:
 682                BUG();
 683                return 1;
 684        }
 685        rfbi.parallelmode = parallelmode;
 686
 687        if ((bpp % lines) == 0) {
 688                switch (bpp / lines) {
 689                case 1:
 690                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
 691                        break;
 692                case 2:
 693                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
 694                        break;
 695                case 3:
 696                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
 697                        break;
 698                default:
 699                        BUG();
 700                        return 1;
 701                }
 702        } else if ((2 * bpp % lines) == 0) {
 703                if ((2 * bpp / lines) == 3)
 704                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
 705                else {
 706                        BUG();
 707                        return 1;
 708                }
 709        } else {
 710                BUG();
 711                return 1;
 712        }
 713
 714        switch (cycleformat) {
 715        case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
 716                cycle1 = lines;
 717                break;
 718
 719        case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
 720                cycle1 = lines;
 721                cycle2 = lines;
 722                break;
 723
 724        case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
 725                cycle1 = lines;
 726                cycle2 = lines;
 727                cycle3 = lines;
 728                break;
 729
 730        case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
 731                cycle1 = lines;
 732                cycle2 = (lines / 2) | ((lines / 2) << 16);
 733                cycle3 = (lines << 16);
 734                break;
 735        }
 736
 737        REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
 738
 739        l = 0;
 740        l |= FLD_VAL(parallelmode, 1, 0);
 741        l |= FLD_VAL(0, 3, 2);          /* TRIGGERMODE: ITE */
 742        l |= FLD_VAL(0, 4, 4);          /* TIMEGRANULARITY */
 743        l |= FLD_VAL(datatype, 6, 5);
 744        /* l |= FLD_VAL(2, 8, 7); */    /* L4FORMAT, 2pix/L4 */
 745        l |= FLD_VAL(0, 8, 7);  /* L4FORMAT, 1pix/L4 */
 746        l |= FLD_VAL(cycleformat, 10, 9);
 747        l |= FLD_VAL(0, 12, 11);        /* UNUSEDBITS */
 748        l |= FLD_VAL(0, 16, 16);        /* A0POLARITY */
 749        l |= FLD_VAL(0, 17, 17);        /* REPOLARITY */
 750        l |= FLD_VAL(0, 18, 18);        /* WEPOLARITY */
 751        l |= FLD_VAL(0, 19, 19);        /* CSPOLARITY */
 752        l |= FLD_VAL(1, 20, 20);        /* TE_VSYNC_POLARITY */
 753        l |= FLD_VAL(1, 21, 21);        /* HSYNCPOLARITY */
 754        rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
 755
 756        rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
 757        rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
 758        rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
 759
 760
 761        l = rfbi_read_reg(RFBI_CONTROL);
 762        l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
 763        l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
 764        rfbi_write_reg(RFBI_CONTROL, l);
 765
 766
 767        DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
 768               bpp, lines, cycle1, cycle2, cycle3);
 769
 770        return 0;
 771}
 772
 773int omap_rfbi_configure(struct omap_dss_device *dssdev)
 774{
 775        return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
 776                        rfbi.data_lines);
 777}
 778EXPORT_SYMBOL(omap_rfbi_configure);
 779
 780int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
 781                void *data)
 782{
 783        return rfbi_transfer_area(dssdev, callback, data);
 784}
 785EXPORT_SYMBOL(omap_rfbi_update);
 786
 787void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
 788{
 789        rfbi.timings.x_res = w;
 790        rfbi.timings.y_res = h;
 791}
 792EXPORT_SYMBOL(omapdss_rfbi_set_size);
 793
 794void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
 795{
 796        rfbi.pixel_size = pixel_size;
 797}
 798EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
 799
 800void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
 801{
 802        rfbi.data_lines = data_lines;
 803}
 804EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
 805
 806void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
 807                struct rfbi_timings *timings)
 808{
 809        rfbi.intf_timings = *timings;
 810}
 811EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings);
 812
 813static void rfbi_dump_regs(struct seq_file *s)
 814{
 815#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
 816
 817        if (rfbi_runtime_get())
 818                return;
 819
 820        DUMPREG(RFBI_REVISION);
 821        DUMPREG(RFBI_SYSCONFIG);
 822        DUMPREG(RFBI_SYSSTATUS);
 823        DUMPREG(RFBI_CONTROL);
 824        DUMPREG(RFBI_PIXEL_CNT);
 825        DUMPREG(RFBI_LINE_NUMBER);
 826        DUMPREG(RFBI_CMD);
 827        DUMPREG(RFBI_PARAM);
 828        DUMPREG(RFBI_DATA);
 829        DUMPREG(RFBI_READ);
 830        DUMPREG(RFBI_STATUS);
 831
 832        DUMPREG(RFBI_CONFIG(0));
 833        DUMPREG(RFBI_ONOFF_TIME(0));
 834        DUMPREG(RFBI_CYCLE_TIME(0));
 835        DUMPREG(RFBI_DATA_CYCLE1(0));
 836        DUMPREG(RFBI_DATA_CYCLE2(0));
 837        DUMPREG(RFBI_DATA_CYCLE3(0));
 838
 839        DUMPREG(RFBI_CONFIG(1));
 840        DUMPREG(RFBI_ONOFF_TIME(1));
 841        DUMPREG(RFBI_CYCLE_TIME(1));
 842        DUMPREG(RFBI_DATA_CYCLE1(1));
 843        DUMPREG(RFBI_DATA_CYCLE2(1));
 844        DUMPREG(RFBI_DATA_CYCLE3(1));
 845
 846        DUMPREG(RFBI_VSYNC_WIDTH);
 847        DUMPREG(RFBI_HSYNC_WIDTH);
 848
 849        rfbi_runtime_put();
 850#undef DUMPREG
 851}
 852
 853static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
 854{
 855        struct omap_overlay_manager *mgr = dssdev->output->manager;
 856        struct dss_lcd_mgr_config mgr_config;
 857
 858        mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
 859
 860        mgr_config.stallmode = true;
 861        /* Do we need fifohandcheck for RFBI? */
 862        mgr_config.fifohandcheck = false;
 863
 864        mgr_config.video_port_width = rfbi.pixel_size;
 865        mgr_config.lcden_sig_polarity = 0;
 866
 867        dss_mgr_set_lcd_config(mgr, &mgr_config);
 868
 869        /*
 870         * Set rfbi.timings with default values, the x_res and y_res fields
 871         * are expected to be already configured by the panel driver via
 872         * omapdss_rfbi_set_size()
 873         */
 874        rfbi.timings.hsw = 1;
 875        rfbi.timings.hfp = 1;
 876        rfbi.timings.hbp = 1;
 877        rfbi.timings.vsw = 1;
 878        rfbi.timings.vfp = 0;
 879        rfbi.timings.vbp = 0;
 880
 881        rfbi.timings.interlace = false;
 882        rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
 883        rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
 884        rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 885        rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
 886        rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 887
 888        dss_mgr_set_timings(mgr, &rfbi.timings);
 889}
 890
 891int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 892{
 893        struct omap_dss_output *out = dssdev->output;
 894        int r;
 895
 896        if (out == NULL || out->manager == NULL) {
 897                DSSERR("failed to enable display: no output/manager\n");
 898                return -ENODEV;
 899        }
 900
 901        r = rfbi_runtime_get();
 902        if (r)
 903                return r;
 904
 905        r = omap_dss_start_device(dssdev);
 906        if (r) {
 907                DSSERR("failed to start device\n");
 908                goto err0;
 909        }
 910
 911        r = dss_mgr_register_framedone_handler(out->manager,
 912                        framedone_callback, NULL);
 913        if (r) {
 914                DSSERR("can't get FRAMEDONE irq\n");
 915                goto err1;
 916        }
 917
 918        rfbi_config_lcd_manager(dssdev);
 919
 920        rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
 921                        rfbi.data_lines);
 922
 923        rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
 924
 925        return 0;
 926err1:
 927        omap_dss_stop_device(dssdev);
 928err0:
 929        rfbi_runtime_put();
 930        return r;
 931}
 932EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 933
 934void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
 935{
 936        struct omap_dss_output *out = dssdev->output;
 937
 938        dss_mgr_unregister_framedone_handler(out->manager,
 939                        framedone_callback, NULL);
 940        omap_dss_stop_device(dssdev);
 941
 942        rfbi_runtime_put();
 943}
 944EXPORT_SYMBOL(omapdss_rfbi_display_disable);
 945
 946static int rfbi_init_display(struct omap_dss_device *dssdev)
 947{
 948        rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
 949        return 0;
 950}
 951
 952static struct omap_dss_device *rfbi_find_dssdev(struct platform_device *pdev)
 953{
 954        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
 955        const char *def_disp_name = omapdss_get_default_display_name();
 956        struct omap_dss_device *def_dssdev;
 957        int i;
 958
 959        def_dssdev = NULL;
 960
 961        for (i = 0; i < pdata->num_devices; ++i) {
 962                struct omap_dss_device *dssdev = pdata->devices[i];
 963
 964                if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
 965                        continue;
 966
 967                if (def_dssdev == NULL)
 968                        def_dssdev = dssdev;
 969
 970                if (def_disp_name != NULL &&
 971                                strcmp(dssdev->name, def_disp_name) == 0) {
 972                        def_dssdev = dssdev;
 973                        break;
 974                }
 975        }
 976
 977        return def_dssdev;
 978}
 979
 980static int rfbi_probe_pdata(struct platform_device *rfbidev)
 981{
 982        struct omap_dss_device *plat_dssdev;
 983        struct omap_dss_device *dssdev;
 984        int r;
 985
 986        plat_dssdev = rfbi_find_dssdev(rfbidev);
 987
 988        if (!plat_dssdev)
 989                return 0;
 990
 991        dssdev = dss_alloc_and_init_device(&rfbidev->dev);
 992        if (!dssdev)
 993                return -ENOMEM;
 994
 995        dss_copy_device_pdata(dssdev, plat_dssdev);
 996
 997        r = rfbi_init_display(dssdev);
 998        if (r) {
 999                DSSERR("device %s init failed: %d\n", dssdev->name, r);
1000                dss_put_device(dssdev);
1001                return r;
1002        }
1003
1004        r = omapdss_output_set_device(&rfbi.output, dssdev);
1005        if (r) {
1006                DSSERR("failed to connect output to new device: %s\n",
1007                                dssdev->name);
1008                dss_put_device(dssdev);
1009                return r;
1010        }
1011
1012        r = dss_add_device(dssdev);
1013        if (r) {
1014                DSSERR("device %s register failed: %d\n", dssdev->name, r);
1015                omapdss_output_unset_device(&rfbi.output);
1016                dss_put_device(dssdev);
1017                return r;
1018        }
1019
1020        return 0;
1021}
1022
1023static void rfbi_init_output(struct platform_device *pdev)
1024{
1025        struct omap_dss_output *out = &rfbi.output;
1026
1027        out->pdev = pdev;
1028        out->id = OMAP_DSS_OUTPUT_DBI;
1029        out->type = OMAP_DISPLAY_TYPE_DBI;
1030        out->name = "rfbi.0";
1031        out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
1032
1033        dss_register_output(out);
1034}
1035
1036static void __exit rfbi_uninit_output(struct platform_device *pdev)
1037{
1038        struct omap_dss_output *out = &rfbi.output;
1039
1040        dss_unregister_output(out);
1041}
1042
1043/* RFBI HW IP initialisation */
1044static int omap_rfbihw_probe(struct platform_device *pdev)
1045{
1046        u32 rev;
1047        struct resource *rfbi_mem;
1048        struct clk *clk;
1049        int r;
1050
1051        rfbi.pdev = pdev;
1052
1053        sema_init(&rfbi.bus_lock, 1);
1054
1055        rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1056        if (!rfbi_mem) {
1057                DSSERR("can't get IORESOURCE_MEM RFBI\n");
1058                return -EINVAL;
1059        }
1060
1061        rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
1062                                 resource_size(rfbi_mem));
1063        if (!rfbi.base) {
1064                DSSERR("can't ioremap RFBI\n");
1065                return -ENOMEM;
1066        }
1067
1068        clk = clk_get(&pdev->dev, "ick");
1069        if (IS_ERR(clk)) {
1070                DSSERR("can't get ick\n");
1071                return PTR_ERR(clk);
1072        }
1073
1074        rfbi.l4_khz = clk_get_rate(clk) / 1000;
1075
1076        clk_put(clk);
1077
1078        pm_runtime_enable(&pdev->dev);
1079
1080        r = rfbi_runtime_get();
1081        if (r)
1082                goto err_runtime_get;
1083
1084        msleep(10);
1085
1086        rev = rfbi_read_reg(RFBI_REVISION);
1087        dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
1088               FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1089
1090        rfbi_runtime_put();
1091
1092        dss_debugfs_create_file("rfbi", rfbi_dump_regs);
1093
1094        rfbi_init_output(pdev);
1095
1096        r = rfbi_probe_pdata(pdev);
1097        if (r) {
1098                rfbi_uninit_output(pdev);
1099                pm_runtime_disable(&pdev->dev);
1100                return r;
1101        }
1102
1103        return 0;
1104
1105err_runtime_get:
1106        pm_runtime_disable(&pdev->dev);
1107        return r;
1108}
1109
1110static int __exit omap_rfbihw_remove(struct platform_device *pdev)
1111{
1112        dss_unregister_child_devices(&pdev->dev);
1113
1114        rfbi_uninit_output(pdev);
1115
1116        pm_runtime_disable(&pdev->dev);
1117
1118        return 0;
1119}
1120
1121static int rfbi_runtime_suspend(struct device *dev)
1122{
1123        dispc_runtime_put();
1124
1125        return 0;
1126}
1127
1128static int rfbi_runtime_resume(struct device *dev)
1129{
1130        int r;
1131
1132        r = dispc_runtime_get();
1133        if (r < 0)
1134                return r;
1135
1136        return 0;
1137}
1138
1139static const struct dev_pm_ops rfbi_pm_ops = {
1140        .runtime_suspend = rfbi_runtime_suspend,
1141        .runtime_resume = rfbi_runtime_resume,
1142};
1143
1144static struct platform_driver omap_rfbihw_driver = {
1145        .probe          = omap_rfbihw_probe,
1146        .remove         = __exit_p(omap_rfbihw_remove),
1147        .driver         = {
1148                .name   = "omapdss_rfbi",
1149                .owner  = THIS_MODULE,
1150                .pm     = &rfbi_pm_ops,
1151        },
1152};
1153
1154int __init rfbi_init_platform_driver(void)
1155{
1156        return platform_driver_register(&omap_rfbihw_driver);
1157}
1158
1159void __exit rfbi_uninit_platform_driver(void)
1160{
1161        platform_driver_unregister(&omap_rfbihw_driver);
1162}
1163