root/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hw_guard_start
  2. hw_guard_wait
  3. dsicm_dcs_read_1
  4. dsicm_dcs_write_0
  5. dsicm_dcs_write_1
  6. dsicm_sleep_in
  7. dsicm_sleep_out
  8. dsicm_get_id
  9. dsicm_set_update_window
  10. dsicm_queue_ulps_work
  11. dsicm_cancel_ulps_work
  12. dsicm_enter_ulps
  13. dsicm_exit_ulps
  14. dsicm_wake_up
  15. dsicm_bl_update_status
  16. dsicm_bl_get_intensity
  17. dsicm_get_resolution
  18. dsicm_num_errors_show
  19. dsicm_hw_revision_show
  20. dsicm_store_ulps
  21. dsicm_show_ulps
  22. dsicm_store_ulps_timeout
  23. dsicm_show_ulps_timeout
  24. dsicm_hw_reset
  25. dsicm_power_on
  26. dsicm_power_off
  27. dsicm_panel_reset
  28. dsicm_connect
  29. dsicm_disconnect
  30. dsicm_enable
  31. dsicm_disable
  32. dsicm_framedone_cb
  33. dsicm_te_isr
  34. dsicm_te_timeout_work_callback
  35. dsicm_update
  36. dsicm_sync
  37. _dsicm_enable_te
  38. dsicm_enable_te
  39. dsicm_get_te
  40. dsicm_memory_read
  41. dsicm_ulps_work
  42. dsicm_probe_of
  43. dsicm_probe
  44. dsicm_remove

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

/* [<][>][^][v][top][bottom][index][help] */