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