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