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