linux/drivers/video/omap2/displays-new/panel-dsi-cm.c
<<
>>
Prefs
   1/*
   2 * Generic DSI Command Mode panel driver
   3 *
   4 * Copyright (C) 2013 Texas Instruments
   5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 */
  11
  12/* #define DEBUG */
  13
  14#include <linux/backlight.h>
  15#include <linux/delay.h>
  16#include <linux/fb.h>
  17#include <linux/gpio.h>
  18#include <linux/interrupt.h>
  19#include <linux/jiffies.h>
  20#include <linux/module.h>
  21#include <linux/platform_device.h>
  22#include <linux/sched.h>
  23#include <linux/slab.h>
  24#include <linux/workqueue.h>
  25
  26#include <video/omapdss.h>
  27#include <video/omap-panel-data.h>
  28#include <video/mipi_display.h>
  29
  30/* DSI Virtual channel. Hardcoded for now. */
  31#define TCH 0
  32
  33#define DCS_READ_NUM_ERRORS     0x05
  34#define DCS_BRIGHTNESS          0x51
  35#define DCS_CTRL_DISPLAY        0x53
  36#define DCS_GET_ID1             0xda
  37#define DCS_GET_ID2             0xdb
  38#define DCS_GET_ID3             0xdc
  39
  40struct panel_drv_data {
  41        struct omap_dss_device dssdev;
  42        struct omap_dss_device *in;
  43
  44        struct omap_video_timings timings;
  45
  46        struct platform_device *pdev;
  47
  48        struct mutex lock;
  49
  50        struct backlight_device *bldev;
  51
  52        unsigned long   hw_guard_end;   /* next value of jiffies when we can
  53                                         * issue the next sleep in/out command
  54                                         */
  55        unsigned long   hw_guard_wait;  /* max guard time in jiffies */
  56
  57        /* panel HW configuration from DT or platform data */
  58        int reset_gpio;
  59        int ext_te_gpio;
  60
  61        bool use_dsi_backlight;
  62
  63        struct omap_dsi_pin_config pin_config;
  64
  65        /* runtime variables */
  66        bool enabled;
  67
  68        bool te_enabled;
  69
  70        atomic_t do_update;
  71        int channel;
  72
  73        struct delayed_work te_timeout_work;
  74
  75        bool intro_printed;
  76
  77        struct workqueue_struct *workqueue;
  78
  79        bool ulps_enabled;
  80        unsigned ulps_timeout;
  81        struct delayed_work ulps_work;
  82};
  83
  84#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
  85
  86static irqreturn_t dsicm_te_isr(int irq, void *data);
  87static void dsicm_te_timeout_work_callback(struct work_struct *work);
  88static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
  89
  90static int dsicm_panel_reset(struct panel_drv_data *ddata);
  91
  92static void dsicm_ulps_work(struct work_struct *work);
  93
  94static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
  95{
  96        ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
  97        ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
  98}
  99
 100static void hw_guard_wait(struct panel_drv_data *ddata)
 101{
 102        unsigned long wait = ddata->hw_guard_end - jiffies;
 103
 104        if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
 105                set_current_state(TASK_UNINTERRUPTIBLE);
 106                schedule_timeout(wait);
 107        }
 108}
 109
 110static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
 111{
 112        struct omap_dss_device *in = ddata->in;
 113        int r;
 114        u8 buf[1];
 115
 116        r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd, buf, 1);
 117
 118        if (r < 0)
 119                return r;
 120
 121        *data = buf[0];
 122
 123        return 0;
 124}
 125
 126static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
 127{
 128        struct omap_dss_device *in = ddata->in;
 129        return in->ops.dsi->dcs_write(in, ddata->channel, &dcs_cmd, 1);
 130}
 131
 132static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
 133{
 134        struct omap_dss_device *in = ddata->in;
 135        u8 buf[2] = { dcs_cmd, param };
 136
 137        return in->ops.dsi->dcs_write(in, ddata->channel, buf, 2);
 138}
 139
 140static int dsicm_sleep_in(struct panel_drv_data *ddata)
 141
 142{
 143        struct omap_dss_device *in = ddata->in;
 144        u8 cmd;
 145        int r;
 146
 147        hw_guard_wait(ddata);
 148
 149        cmd = MIPI_DCS_ENTER_SLEEP_MODE;
 150        r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, &cmd, 1);
 151        if (r)
 152                return r;
 153
 154        hw_guard_start(ddata, 120);
 155
 156        usleep_range(5000, 10000);
 157
 158        return 0;
 159}
 160
 161static int dsicm_sleep_out(struct panel_drv_data *ddata)
 162{
 163        int r;
 164
 165        hw_guard_wait(ddata);
 166
 167        r = dsicm_dcs_write_0(ddata, MIPI_DCS_EXIT_SLEEP_MODE);
 168        if (r)
 169                return r;
 170
 171        hw_guard_start(ddata, 120);
 172
 173        usleep_range(5000, 10000);
 174
 175        return 0;
 176}
 177
 178static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
 179{
 180        int r;
 181
 182        r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
 183        if (r)
 184                return r;
 185        r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
 186        if (r)
 187                return r;
 188        r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
 189        if (r)
 190                return r;
 191
 192        return 0;
 193}
 194
 195static int dsicm_set_update_window(struct panel_drv_data *ddata,
 196                u16 x, u16 y, u16 w, u16 h)
 197{
 198        struct omap_dss_device *in = ddata->in;
 199        int r;
 200        u16 x1 = x;
 201        u16 x2 = x + w - 1;
 202        u16 y1 = y;
 203        u16 y2 = y + h - 1;
 204
 205        u8 buf[5];
 206        buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
 207        buf[1] = (x1 >> 8) & 0xff;
 208        buf[2] = (x1 >> 0) & 0xff;
 209        buf[3] = (x2 >> 8) & 0xff;
 210        buf[4] = (x2 >> 0) & 0xff;
 211
 212        r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
 213        if (r)
 214                return r;
 215
 216        buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
 217        buf[1] = (y1 >> 8) & 0xff;
 218        buf[2] = (y1 >> 0) & 0xff;
 219        buf[3] = (y2 >> 8) & 0xff;
 220        buf[4] = (y2 >> 0) & 0xff;
 221
 222        r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
 223        if (r)
 224                return r;
 225
 226        in->ops.dsi->bta_sync(in, ddata->channel);
 227
 228        return r;
 229}
 230
 231static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
 232{
 233        if (ddata->ulps_timeout > 0)
 234                queue_delayed_work(ddata->workqueue, &ddata->ulps_work,
 235                                msecs_to_jiffies(ddata->ulps_timeout));
 236}
 237
 238static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata)
 239{
 240        cancel_delayed_work(&ddata->ulps_work);
 241}
 242
 243static int dsicm_enter_ulps(struct panel_drv_data *ddata)
 244{
 245        struct omap_dss_device *in = ddata->in;
 246        int r;
 247
 248        if (ddata->ulps_enabled)
 249                return 0;
 250
 251        dsicm_cancel_ulps_work(ddata);
 252
 253        r = _dsicm_enable_te(ddata, false);
 254        if (r)
 255                goto err;
 256
 257        if (gpio_is_valid(ddata->ext_te_gpio))
 258                disable_irq(gpio_to_irq(ddata->ext_te_gpio));
 259
 260        in->ops.dsi->disable(in, false, true);
 261
 262        ddata->ulps_enabled = true;
 263
 264        return 0;
 265
 266err:
 267        dev_err(&ddata->pdev->dev, "enter ULPS failed");
 268        dsicm_panel_reset(ddata);
 269
 270        ddata->ulps_enabled = false;
 271
 272        dsicm_queue_ulps_work(ddata);
 273
 274        return r;
 275}
 276
 277static int dsicm_exit_ulps(struct panel_drv_data *ddata)
 278{
 279        struct omap_dss_device *in = ddata->in;
 280        int r;
 281
 282        if (!ddata->ulps_enabled)
 283                return 0;
 284
 285        r = in->ops.dsi->enable(in);
 286        if (r) {
 287                dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
 288                goto err1;
 289        }
 290
 291        in->ops.dsi->enable_hs(in, ddata->channel, true);
 292
 293        r = _dsicm_enable_te(ddata, true);
 294        if (r) {
 295                dev_err(&ddata->pdev->dev, "failed to re-enable TE");
 296                goto err2;
 297        }
 298
 299        if (gpio_is_valid(ddata->ext_te_gpio))
 300                enable_irq(gpio_to_irq(ddata->ext_te_gpio));
 301
 302        dsicm_queue_ulps_work(ddata);
 303
 304        ddata->ulps_enabled = false;
 305
 306        return 0;
 307
 308err2:
 309        dev_err(&ddata->pdev->dev, "failed to exit ULPS");
 310
 311        r = dsicm_panel_reset(ddata);
 312        if (!r) {
 313                if (gpio_is_valid(ddata->ext_te_gpio))
 314                        enable_irq(gpio_to_irq(ddata->ext_te_gpio));
 315                ddata->ulps_enabled = false;
 316        }
 317err1:
 318        dsicm_queue_ulps_work(ddata);
 319
 320        return r;
 321}
 322
 323static int dsicm_wake_up(struct panel_drv_data *ddata)
 324{
 325        if (ddata->ulps_enabled)
 326                return dsicm_exit_ulps(ddata);
 327
 328        dsicm_cancel_ulps_work(ddata);
 329        dsicm_queue_ulps_work(ddata);
 330        return 0;
 331}
 332
 333static int dsicm_bl_update_status(struct backlight_device *dev)
 334{
 335        struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
 336        struct omap_dss_device *in = ddata->in;
 337        int r;
 338        int level;
 339
 340        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 341                        dev->props.power == FB_BLANK_UNBLANK)
 342                level = dev->props.brightness;
 343        else
 344                level = 0;
 345
 346        dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level);
 347
 348        mutex_lock(&ddata->lock);
 349
 350        if (ddata->enabled) {
 351                in->ops.dsi->bus_lock(in);
 352
 353                r = dsicm_wake_up(ddata);
 354                if (!r)
 355                        r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level);
 356
 357                in->ops.dsi->bus_unlock(in);
 358        } else {
 359                r = 0;
 360        }
 361
 362        mutex_unlock(&ddata->lock);
 363
 364        return r;
 365}
 366
 367static int dsicm_bl_get_intensity(struct backlight_device *dev)
 368{
 369        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 370                        dev->props.power == FB_BLANK_UNBLANK)
 371                return dev->props.brightness;
 372
 373        return 0;
 374}
 375
 376static const struct backlight_ops dsicm_bl_ops = {
 377        .get_brightness = dsicm_bl_get_intensity,
 378        .update_status  = dsicm_bl_update_status,
 379};
 380
 381static void dsicm_get_resolution(struct omap_dss_device *dssdev,
 382                u16 *xres, u16 *yres)
 383{
 384        *xres = dssdev->panel.timings.x_res;
 385        *yres = dssdev->panel.timings.y_res;
 386}
 387
 388static ssize_t dsicm_num_errors_show(struct device *dev,
 389                struct device_attribute *attr, char *buf)
 390{
 391        struct platform_device *pdev = to_platform_device(dev);
 392        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 393        struct omap_dss_device *in = ddata->in;
 394        u8 errors = 0;
 395        int r;
 396
 397        mutex_lock(&ddata->lock);
 398
 399        if (ddata->enabled) {
 400                in->ops.dsi->bus_lock(in);
 401
 402                r = dsicm_wake_up(ddata);
 403                if (!r)
 404                        r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
 405                                        &errors);
 406
 407                in->ops.dsi->bus_unlock(in);
 408        } else {
 409                r = -ENODEV;
 410        }
 411
 412        mutex_unlock(&ddata->lock);
 413
 414        if (r)
 415                return r;
 416
 417        return snprintf(buf, PAGE_SIZE, "%d\n", errors);
 418}
 419
 420static ssize_t dsicm_hw_revision_show(struct device *dev,
 421                struct device_attribute *attr, char *buf)
 422{
 423        struct platform_device *pdev = to_platform_device(dev);
 424        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 425        struct omap_dss_device *in = ddata->in;
 426        u8 id1, id2, id3;
 427        int r;
 428
 429        mutex_lock(&ddata->lock);
 430
 431        if (ddata->enabled) {
 432                in->ops.dsi->bus_lock(in);
 433
 434                r = dsicm_wake_up(ddata);
 435                if (!r)
 436                        r = dsicm_get_id(ddata, &id1, &id2, &id3);
 437
 438                in->ops.dsi->bus_unlock(in);
 439        } else {
 440                r = -ENODEV;
 441        }
 442
 443        mutex_unlock(&ddata->lock);
 444
 445        if (r)
 446                return r;
 447
 448        return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
 449}
 450
 451static ssize_t dsicm_store_ulps(struct device *dev,
 452                struct device_attribute *attr,
 453                const char *buf, size_t count)
 454{
 455        struct platform_device *pdev = to_platform_device(dev);
 456        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 457        struct omap_dss_device *in = ddata->in;
 458        unsigned long t;
 459        int r;
 460
 461        r = kstrtoul(buf, 0, &t);
 462        if (r)
 463                return r;
 464
 465        mutex_lock(&ddata->lock);
 466
 467        if (ddata->enabled) {
 468                in->ops.dsi->bus_lock(in);
 469
 470                if (t)
 471                        r = dsicm_enter_ulps(ddata);
 472                else
 473                        r = dsicm_wake_up(ddata);
 474
 475                in->ops.dsi->bus_unlock(in);
 476        }
 477
 478        mutex_unlock(&ddata->lock);
 479
 480        if (r)
 481                return r;
 482
 483        return count;
 484}
 485
 486static ssize_t dsicm_show_ulps(struct device *dev,
 487                struct device_attribute *attr,
 488                char *buf)
 489{
 490        struct platform_device *pdev = to_platform_device(dev);
 491        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 492        unsigned t;
 493
 494        mutex_lock(&ddata->lock);
 495        t = ddata->ulps_enabled;
 496        mutex_unlock(&ddata->lock);
 497
 498        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 499}
 500
 501static ssize_t dsicm_store_ulps_timeout(struct device *dev,
 502                struct device_attribute *attr,
 503                const char *buf, size_t count)
 504{
 505        struct platform_device *pdev = to_platform_device(dev);
 506        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 507        struct omap_dss_device *in = ddata->in;
 508        unsigned long t;
 509        int r;
 510
 511        r = kstrtoul(buf, 0, &t);
 512        if (r)
 513                return r;
 514
 515        mutex_lock(&ddata->lock);
 516        ddata->ulps_timeout = t;
 517
 518        if (ddata->enabled) {
 519                /* dsicm_wake_up will restart the timer */
 520                in->ops.dsi->bus_lock(in);
 521                r = dsicm_wake_up(ddata);
 522                in->ops.dsi->bus_unlock(in);
 523        }
 524
 525        mutex_unlock(&ddata->lock);
 526
 527        if (r)
 528                return r;
 529
 530        return count;
 531}
 532
 533static ssize_t dsicm_show_ulps_timeout(struct device *dev,
 534                struct device_attribute *attr,
 535                char *buf)
 536{
 537        struct platform_device *pdev = to_platform_device(dev);
 538        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 539        unsigned t;
 540
 541        mutex_lock(&ddata->lock);
 542        t = ddata->ulps_timeout;
 543        mutex_unlock(&ddata->lock);
 544
 545        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 546}
 547
 548static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
 549static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
 550static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
 551                dsicm_show_ulps, dsicm_store_ulps);
 552static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
 553                dsicm_show_ulps_timeout, dsicm_store_ulps_timeout);
 554
 555static struct attribute *dsicm_attrs[] = {
 556        &dev_attr_num_dsi_errors.attr,
 557        &dev_attr_hw_revision.attr,
 558        &dev_attr_ulps.attr,
 559        &dev_attr_ulps_timeout.attr,
 560        NULL,
 561};
 562
 563static struct attribute_group dsicm_attr_group = {
 564        .attrs = dsicm_attrs,
 565};
 566
 567static void dsicm_hw_reset(struct panel_drv_data *ddata)
 568{
 569        if (!gpio_is_valid(ddata->reset_gpio))
 570                return;
 571
 572        gpio_set_value(ddata->reset_gpio, 1);
 573        udelay(10);
 574        /* reset the panel */
 575        gpio_set_value(ddata->reset_gpio, 0);
 576        /* assert reset */
 577        udelay(10);
 578        gpio_set_value(ddata->reset_gpio, 1);
 579        /* wait after releasing reset */
 580        usleep_range(5000, 10000);
 581}
 582
 583static int dsicm_power_on(struct panel_drv_data *ddata)
 584{
 585        struct omap_dss_device *in = ddata->in;
 586        u8 id1, id2, id3;
 587        int r;
 588        struct omap_dss_dsi_config dsi_config = {
 589                .mode = OMAP_DSS_DSI_CMD_MODE,
 590                .pixel_format = OMAP_DSS_DSI_FMT_RGB888,
 591                .timings = &ddata->timings,
 592                .hs_clk_min = 150000000,
 593                .hs_clk_max = 300000000,
 594                .lp_clk_min = 7000000,
 595                .lp_clk_max = 10000000,
 596        };
 597
 598        r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
 599        if (r) {
 600                dev_err(&ddata->pdev->dev, "failed to configure DSI pins\n");
 601                goto err0;
 602        };
 603
 604        r = in->ops.dsi->set_config(in, &dsi_config);
 605        if (r) {
 606                dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
 607                goto err0;
 608        }
 609
 610        r = in->ops.dsi->enable(in);
 611        if (r) {
 612                dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
 613                goto err0;
 614        }
 615
 616        dsicm_hw_reset(ddata);
 617
 618        in->ops.dsi->enable_hs(in, ddata->channel, false);
 619
 620        r = dsicm_sleep_out(ddata);
 621        if (r)
 622                goto err;
 623
 624        r = dsicm_get_id(ddata, &id1, &id2, &id3);
 625        if (r)
 626                goto err;
 627
 628        r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, 0xff);
 629        if (r)
 630                goto err;
 631
 632        r = dsicm_dcs_write_1(ddata, DCS_CTRL_DISPLAY,
 633                        (1<<2) | (1<<5));       /* BL | BCTRL */
 634        if (r)
 635                goto err;
 636
 637        r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_PIXEL_FORMAT,
 638                MIPI_DCS_PIXEL_FMT_24BIT);
 639        if (r)
 640                goto err;
 641
 642        r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_ON);
 643        if (r)
 644                goto err;
 645
 646        r = _dsicm_enable_te(ddata, ddata->te_enabled);
 647        if (r)
 648                goto err;
 649
 650        r = in->ops.dsi->enable_video_output(in, ddata->channel);
 651        if (r)
 652                goto err;
 653
 654        ddata->enabled = 1;
 655
 656        if (!ddata->intro_printed) {
 657                dev_info(&ddata->pdev->dev, "panel revision %02x.%02x.%02x\n",
 658                        id1, id2, id3);
 659                ddata->intro_printed = true;
 660        }
 661
 662        in->ops.dsi->enable_hs(in, ddata->channel, true);
 663
 664        return 0;
 665err:
 666        dev_err(&ddata->pdev->dev, "error while enabling panel, issuing HW reset\n");
 667
 668        dsicm_hw_reset(ddata);
 669
 670        in->ops.dsi->disable(in, true, false);
 671err0:
 672        return r;
 673}
 674
 675static void dsicm_power_off(struct panel_drv_data *ddata)
 676{
 677        struct omap_dss_device *in = ddata->in;
 678        int r;
 679
 680        in->ops.dsi->disable_video_output(in, ddata->channel);
 681
 682        r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_OFF);
 683        if (!r)
 684                r = dsicm_sleep_in(ddata);
 685
 686        if (r) {
 687                dev_err(&ddata->pdev->dev,
 688                                "error disabling panel, issuing HW reset\n");
 689                dsicm_hw_reset(ddata);
 690        }
 691
 692        in->ops.dsi->disable(in, true, false);
 693
 694        ddata->enabled = 0;
 695}
 696
 697static int dsicm_panel_reset(struct panel_drv_data *ddata)
 698{
 699        dev_err(&ddata->pdev->dev, "performing LCD reset\n");
 700
 701        dsicm_power_off(ddata);
 702        dsicm_hw_reset(ddata);
 703        return dsicm_power_on(ddata);
 704}
 705
 706static int dsicm_connect(struct omap_dss_device *dssdev)
 707{
 708        struct panel_drv_data *ddata = to_panel_data(dssdev);
 709        struct omap_dss_device *in = ddata->in;
 710        struct device *dev = &ddata->pdev->dev;
 711        int r;
 712
 713        if (omapdss_device_is_connected(dssdev))
 714                return 0;
 715
 716        r = in->ops.dsi->connect(in, dssdev);
 717        if (r) {
 718                dev_err(dev, "Failed to connect to video source\n");
 719                return r;
 720        }
 721
 722        r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
 723        if (r) {
 724                dev_err(dev, "failed to get virtual channel\n");
 725                goto err_req_vc;
 726        }
 727
 728        r = in->ops.dsi->set_vc_id(ddata->in, ddata->channel, TCH);
 729        if (r) {
 730                dev_err(dev, "failed to set VC_ID\n");
 731                goto err_vc_id;
 732        }
 733
 734        return 0;
 735
 736err_vc_id:
 737        in->ops.dsi->release_vc(ddata->in, ddata->channel);
 738err_req_vc:
 739        in->ops.dsi->disconnect(in, dssdev);
 740        return r;
 741}
 742
 743static void dsicm_disconnect(struct omap_dss_device *dssdev)
 744{
 745        struct panel_drv_data *ddata = to_panel_data(dssdev);
 746        struct omap_dss_device *in = ddata->in;
 747
 748        if (!omapdss_device_is_connected(dssdev))
 749                return;
 750
 751        in->ops.dsi->release_vc(in, ddata->channel);
 752        in->ops.dsi->disconnect(in, dssdev);
 753}
 754
 755static int dsicm_enable(struct omap_dss_device *dssdev)
 756{
 757        struct panel_drv_data *ddata = to_panel_data(dssdev);
 758        struct omap_dss_device *in = ddata->in;
 759        int r;
 760
 761        dev_dbg(&ddata->pdev->dev, "enable\n");
 762
 763        mutex_lock(&ddata->lock);
 764
 765        if (!omapdss_device_is_connected(dssdev)) {
 766                r = -ENODEV;
 767                goto err;
 768        }
 769
 770        if (omapdss_device_is_enabled(dssdev)) {
 771                r = 0;
 772                goto err;
 773        }
 774
 775        in->ops.dsi->bus_lock(in);
 776
 777        r = dsicm_power_on(ddata);
 778
 779        in->ops.dsi->bus_unlock(in);
 780
 781        if (r)
 782                goto err;
 783
 784        dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 785
 786        mutex_unlock(&ddata->lock);
 787
 788        return 0;
 789err:
 790        dev_dbg(&ddata->pdev->dev, "enable failed\n");
 791        mutex_unlock(&ddata->lock);
 792        return r;
 793}
 794
 795static void dsicm_disable(struct omap_dss_device *dssdev)
 796{
 797        struct panel_drv_data *ddata = to_panel_data(dssdev);
 798        struct omap_dss_device *in = ddata->in;
 799        int r;
 800
 801        dev_dbg(&ddata->pdev->dev, "disable\n");
 802
 803        mutex_lock(&ddata->lock);
 804
 805        dsicm_cancel_ulps_work(ddata);
 806
 807        in->ops.dsi->bus_lock(in);
 808
 809        if (omapdss_device_is_enabled(dssdev)) {
 810                r = dsicm_wake_up(ddata);
 811                if (!r)
 812                        dsicm_power_off(ddata);
 813        }
 814
 815        in->ops.dsi->bus_unlock(in);
 816
 817        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 818
 819        mutex_unlock(&ddata->lock);
 820}
 821
 822static void dsicm_framedone_cb(int err, void *data)
 823{
 824        struct panel_drv_data *ddata = data;
 825        struct omap_dss_device *in = ddata->in;
 826
 827        dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
 828        in->ops.dsi->bus_unlock(ddata->in);
 829}
 830
 831static irqreturn_t dsicm_te_isr(int irq, void *data)
 832{
 833        struct panel_drv_data *ddata = data;
 834        struct omap_dss_device *in = ddata->in;
 835        int old;
 836        int r;
 837
 838        old = atomic_cmpxchg(&ddata->do_update, 1, 0);
 839
 840        if (old) {
 841                cancel_delayed_work(&ddata->te_timeout_work);
 842
 843                r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
 844                                ddata);
 845                if (r)
 846                        goto err;
 847        }
 848
 849        return IRQ_HANDLED;
 850err:
 851        dev_err(&ddata->pdev->dev, "start update failed\n");
 852        in->ops.dsi->bus_unlock(in);
 853        return IRQ_HANDLED;
 854}
 855
 856static void dsicm_te_timeout_work_callback(struct work_struct *work)
 857{
 858        struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
 859                                        te_timeout_work.work);
 860        struct omap_dss_device *in = ddata->in;
 861
 862        dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
 863
 864        atomic_set(&ddata->do_update, 0);
 865        in->ops.dsi->bus_unlock(in);
 866}
 867
 868static int dsicm_update(struct omap_dss_device *dssdev,
 869                                    u16 x, u16 y, u16 w, u16 h)
 870{
 871        struct panel_drv_data *ddata = to_panel_data(dssdev);
 872        struct omap_dss_device *in = ddata->in;
 873        int r;
 874
 875        dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
 876
 877        mutex_lock(&ddata->lock);
 878        in->ops.dsi->bus_lock(in);
 879
 880        r = dsicm_wake_up(ddata);
 881        if (r)
 882                goto err;
 883
 884        if (!ddata->enabled) {
 885                r = 0;
 886                goto err;
 887        }
 888
 889        /* XXX no need to send this every frame, but dsi break if not done */
 890        r = dsicm_set_update_window(ddata, 0, 0,
 891                        dssdev->panel.timings.x_res,
 892                        dssdev->panel.timings.y_res);
 893        if (r)
 894                goto err;
 895
 896        if (ddata->te_enabled && gpio_is_valid(ddata->ext_te_gpio)) {
 897                schedule_delayed_work(&ddata->te_timeout_work,
 898                                msecs_to_jiffies(250));
 899                atomic_set(&ddata->do_update, 1);
 900        } else {
 901                r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
 902                                ddata);
 903                if (r)
 904                        goto err;
 905        }
 906
 907        /* note: no bus_unlock here. unlock is in framedone_cb */
 908        mutex_unlock(&ddata->lock);
 909        return 0;
 910err:
 911        in->ops.dsi->bus_unlock(in);
 912        mutex_unlock(&ddata->lock);
 913        return r;
 914}
 915
 916static int dsicm_sync(struct omap_dss_device *dssdev)
 917{
 918        struct panel_drv_data *ddata = to_panel_data(dssdev);
 919        struct omap_dss_device *in = ddata->in;
 920
 921        dev_dbg(&ddata->pdev->dev, "sync\n");
 922
 923        mutex_lock(&ddata->lock);
 924        in->ops.dsi->bus_lock(in);
 925        in->ops.dsi->bus_unlock(in);
 926        mutex_unlock(&ddata->lock);
 927
 928        dev_dbg(&ddata->pdev->dev, "sync done\n");
 929
 930        return 0;
 931}
 932
 933static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
 934{
 935        struct omap_dss_device *in = ddata->in;
 936        int r;
 937
 938        if (enable)
 939                r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
 940        else
 941                r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
 942
 943        if (!gpio_is_valid(ddata->ext_te_gpio))
 944                in->ops.dsi->enable_te(in, enable);
 945
 946        /* possible panel bug */
 947        msleep(100);
 948
 949        return r;
 950}
 951
 952static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
 953{
 954        struct panel_drv_data *ddata = to_panel_data(dssdev);
 955        struct omap_dss_device *in = ddata->in;
 956        int r;
 957
 958        mutex_lock(&ddata->lock);
 959
 960        if (ddata->te_enabled == enable)
 961                goto end;
 962
 963        in->ops.dsi->bus_lock(in);
 964
 965        if (ddata->enabled) {
 966                r = dsicm_wake_up(ddata);
 967                if (r)
 968                        goto err;
 969
 970                r = _dsicm_enable_te(ddata, enable);
 971                if (r)
 972                        goto err;
 973        }
 974
 975        ddata->te_enabled = enable;
 976
 977        in->ops.dsi->bus_unlock(in);
 978end:
 979        mutex_unlock(&ddata->lock);
 980
 981        return 0;
 982err:
 983        in->ops.dsi->bus_unlock(in);
 984        mutex_unlock(&ddata->lock);
 985
 986        return r;
 987}
 988
 989static int dsicm_get_te(struct omap_dss_device *dssdev)
 990{
 991        struct panel_drv_data *ddata = to_panel_data(dssdev);
 992        int r;
 993
 994        mutex_lock(&ddata->lock);
 995        r = ddata->te_enabled;
 996        mutex_unlock(&ddata->lock);
 997
 998        return r;
 999}
1000
1001static int dsicm_memory_read(struct omap_dss_device *dssdev,
1002                void *buf, size_t size,
1003                u16 x, u16 y, u16 w, u16 h)
1004{
1005        struct panel_drv_data *ddata = to_panel_data(dssdev);
1006        struct omap_dss_device *in = ddata->in;
1007        int r;
1008        int first = 1;
1009        int plen;
1010        unsigned buf_used = 0;
1011
1012        if (size < w * h * 3)
1013                return -ENOMEM;
1014
1015        mutex_lock(&ddata->lock);
1016
1017        if (!ddata->enabled) {
1018                r = -ENODEV;
1019                goto err1;
1020        }
1021
1022        size = min(w * h * 3,
1023                        dssdev->panel.timings.x_res *
1024                        dssdev->panel.timings.y_res * 3);
1025
1026        in->ops.dsi->bus_lock(in);
1027
1028        r = dsicm_wake_up(ddata);
1029        if (r)
1030                goto err2;
1031
1032        /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1033         * use short packets. plen 32 works, but bigger packets seem to cause
1034         * an error. */
1035        if (size % 2)
1036                plen = 1;
1037        else
1038                plen = 2;
1039
1040        dsicm_set_update_window(ddata, x, y, w, h);
1041
1042        r = in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, plen);
1043        if (r)
1044                goto err2;
1045
1046        while (buf_used < size) {
1047                u8 dcs_cmd = first ? 0x2e : 0x3e;
1048                first = 0;
1049
1050                r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd,
1051                                buf + buf_used, size - buf_used);
1052
1053                if (r < 0) {
1054                        dev_err(dssdev->dev, "read error\n");
1055                        goto err3;
1056                }
1057
1058                buf_used += r;
1059
1060                if (r < plen) {
1061                        dev_err(&ddata->pdev->dev, "short read\n");
1062                        break;
1063                }
1064
1065                if (signal_pending(current)) {
1066                        dev_err(&ddata->pdev->dev, "signal pending, "
1067                                        "aborting memory read\n");
1068                        r = -ERESTARTSYS;
1069                        goto err3;
1070                }
1071        }
1072
1073        r = buf_used;
1074
1075err3:
1076        in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1);
1077err2:
1078        in->ops.dsi->bus_unlock(in);
1079err1:
1080        mutex_unlock(&ddata->lock);
1081        return r;
1082}
1083
1084static void dsicm_ulps_work(struct work_struct *work)
1085{
1086        struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
1087                        ulps_work.work);
1088        struct omap_dss_device *dssdev = &ddata->dssdev;
1089        struct omap_dss_device *in = ddata->in;
1090
1091        mutex_lock(&ddata->lock);
1092
1093        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
1094                mutex_unlock(&ddata->lock);
1095                return;
1096        }
1097
1098        in->ops.dsi->bus_lock(in);
1099
1100        dsicm_enter_ulps(ddata);
1101
1102        in->ops.dsi->bus_unlock(in);
1103        mutex_unlock(&ddata->lock);
1104}
1105
1106static struct omap_dss_driver dsicm_ops = {
1107        .connect        = dsicm_connect,
1108        .disconnect     = dsicm_disconnect,
1109
1110        .enable         = dsicm_enable,
1111        .disable        = dsicm_disable,
1112
1113        .update         = dsicm_update,
1114        .sync           = dsicm_sync,
1115
1116        .get_resolution = dsicm_get_resolution,
1117        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1118
1119        .enable_te      = dsicm_enable_te,
1120        .get_te         = dsicm_get_te,
1121
1122        .memory_read    = dsicm_memory_read,
1123};
1124
1125static int dsicm_probe_pdata(struct platform_device *pdev)
1126{
1127        const struct panel_dsicm_platform_data *pdata;
1128        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
1129        struct omap_dss_device *dssdev, *in;
1130
1131        pdata = dev_get_platdata(&pdev->dev);
1132
1133        in = omap_dss_find_output(pdata->source);
1134        if (in == NULL) {
1135                dev_err(&pdev->dev, "failed to find video source\n");
1136                return -EPROBE_DEFER;
1137        }
1138        ddata->in = in;
1139
1140        ddata->reset_gpio = pdata->reset_gpio;
1141
1142        if (pdata->use_ext_te)
1143                ddata->ext_te_gpio = pdata->ext_te_gpio;
1144        else
1145                ddata->ext_te_gpio = -1;
1146
1147        ddata->ulps_timeout = pdata->ulps_timeout;
1148
1149        ddata->use_dsi_backlight = pdata->use_dsi_backlight;
1150
1151        ddata->pin_config = pdata->pin_config;
1152
1153        dssdev = &ddata->dssdev;
1154        dssdev->name = pdata->name;
1155
1156        return 0;
1157}
1158
1159static int dsicm_probe(struct platform_device *pdev)
1160{
1161        struct backlight_properties props;
1162        struct panel_drv_data *ddata;
1163        struct backlight_device *bldev = NULL;
1164        struct device *dev = &pdev->dev;
1165        struct omap_dss_device *dssdev;
1166        int r;
1167
1168        dev_dbg(dev, "probe\n");
1169
1170        ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
1171        if (!ddata)
1172                return -ENOMEM;
1173
1174        platform_set_drvdata(pdev, ddata);
1175        ddata->pdev = pdev;
1176
1177        if (dev_get_platdata(dev)) {
1178                r = dsicm_probe_pdata(pdev);
1179                if (r)
1180                        return r;
1181        } else {
1182                return -ENODEV;
1183        }
1184
1185        ddata->timings.x_res = 864;
1186        ddata->timings.y_res = 480;
1187        ddata->timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
1188
1189        dssdev = &ddata->dssdev;
1190        dssdev->dev = dev;
1191        dssdev->driver = &dsicm_ops;
1192        dssdev->panel.timings = ddata->timings;
1193        dssdev->type = OMAP_DISPLAY_TYPE_DSI;
1194        dssdev->owner = THIS_MODULE;
1195
1196        dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
1197        dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
1198                OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
1199
1200        r = omapdss_register_display(dssdev);
1201        if (r) {
1202                dev_err(dev, "Failed to register panel\n");
1203                goto err_reg;
1204        }
1205
1206        mutex_init(&ddata->lock);
1207
1208        atomic_set(&ddata->do_update, 0);
1209
1210        if (gpio_is_valid(ddata->reset_gpio)) {
1211                r = devm_gpio_request_one(dev, ddata->reset_gpio,
1212                                GPIOF_OUT_INIT_LOW, "taal rst");
1213                if (r) {
1214                        dev_err(dev, "failed to request reset gpio\n");
1215                        return r;
1216                }
1217        }
1218
1219        if (gpio_is_valid(ddata->ext_te_gpio)) {
1220                r = devm_gpio_request_one(dev, ddata->ext_te_gpio,
1221                                GPIOF_IN, "taal irq");
1222                if (r) {
1223                        dev_err(dev, "GPIO request failed\n");
1224                        return r;
1225                }
1226
1227                r = devm_request_irq(dev, gpio_to_irq(ddata->ext_te_gpio),
1228                                dsicm_te_isr,
1229                                IRQF_TRIGGER_RISING,
1230                                "taal vsync", ddata);
1231
1232                if (r) {
1233                        dev_err(dev, "IRQ request failed\n");
1234                        return r;
1235                }
1236
1237                INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
1238                                        dsicm_te_timeout_work_callback);
1239
1240                dev_dbg(dev, "Using GPIO TE\n");
1241        }
1242
1243        ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
1244        if (ddata->workqueue == NULL) {
1245                dev_err(dev, "can't create workqueue\n");
1246                return -ENOMEM;
1247        }
1248        INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
1249
1250        dsicm_hw_reset(ddata);
1251
1252        if (ddata->use_dsi_backlight) {
1253                memset(&props, 0, sizeof(struct backlight_properties));
1254                props.max_brightness = 255;
1255
1256                props.type = BACKLIGHT_RAW;
1257                bldev = backlight_device_register(dev_name(dev),
1258                                dev, ddata, &dsicm_bl_ops, &props);
1259                if (IS_ERR(bldev)) {
1260                        r = PTR_ERR(bldev);
1261                        goto err_bl;
1262                }
1263
1264                ddata->bldev = bldev;
1265
1266                bldev->props.fb_blank = FB_BLANK_UNBLANK;
1267                bldev->props.power = FB_BLANK_UNBLANK;
1268                bldev->props.brightness = 255;
1269
1270                dsicm_bl_update_status(bldev);
1271        }
1272
1273        r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
1274        if (r) {
1275                dev_err(dev, "failed to create sysfs files\n");
1276                goto err_sysfs_create;
1277        }
1278
1279        return 0;
1280
1281err_sysfs_create:
1282        if (bldev != NULL)
1283                backlight_device_unregister(bldev);
1284err_bl:
1285        destroy_workqueue(ddata->workqueue);
1286err_reg:
1287        return r;
1288}
1289
1290static int __exit dsicm_remove(struct platform_device *pdev)
1291{
1292        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
1293        struct omap_dss_device *dssdev = &ddata->dssdev;
1294        struct backlight_device *bldev;
1295
1296        dev_dbg(&pdev->dev, "remove\n");
1297
1298        omapdss_unregister_display(dssdev);
1299
1300        dsicm_disable(dssdev);
1301        dsicm_disconnect(dssdev);
1302
1303        sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
1304
1305        bldev = ddata->bldev;
1306        if (bldev != NULL) {
1307                bldev->props.power = FB_BLANK_POWERDOWN;
1308                dsicm_bl_update_status(bldev);
1309                backlight_device_unregister(bldev);
1310        }
1311
1312        omap_dss_put_device(ddata->in);
1313
1314        dsicm_cancel_ulps_work(ddata);
1315        destroy_workqueue(ddata->workqueue);
1316
1317        /* reset, to be sure that the panel is in a valid state */
1318        dsicm_hw_reset(ddata);
1319
1320        return 0;
1321}
1322
1323static struct platform_driver dsicm_driver = {
1324        .probe = dsicm_probe,
1325        .remove = __exit_p(dsicm_remove),
1326        .driver = {
1327                .name = "panel-dsi-cm",
1328                .owner = THIS_MODULE,
1329        },
1330};
1331
1332module_platform_driver(dsicm_driver);
1333
1334MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
1335MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
1336MODULE_LICENSE("GPL");
1337