panel-dsi-cm.c (27586B)
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 38struct 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 82static irqreturn_t dsicm_te_isr(int irq, void *data); 83static void dsicm_te_timeout_work_callback(struct work_struct *work); 84static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable); 85 86static int dsicm_panel_reset(struct panel_drv_data *ddata); 87 88static void dsicm_ulps_work(struct work_struct *work); 89 90static 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 96static 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 106static 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 122static 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 128static 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 136static 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 157static 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 174static 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 191static 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 227static 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 234static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata) 235{ 236 cancel_delayed_work(&ddata->ulps_work); 237} 238 239static 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 262err: 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 273static 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 304err2: 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 } 313err1: 314 dsicm_queue_ulps_work(ddata); 315 316 return r; 317} 318 319static 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 329static 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 363static 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 372static const struct backlight_ops dsicm_bl_ops = { 373 .get_brightness = dsicm_bl_get_intensity, 374 .update_status = dsicm_bl_update_status, 375}; 376 377static 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 384static 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 sysfs_emit(buf, "%d\n", errors); 413} 414 415static 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 sysfs_emit(buf, "%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 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 479static 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 sysfs_emit(buf, "%u\n", t); 491} 492 493static 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 524static 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 sysfs_emit(buf, "%u\n", t); 536} 537 538static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL); 539static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL); 540static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR, 541 dsicm_show_ulps, dsicm_store_ulps); 542static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR, 543 dsicm_show_ulps_timeout, dsicm_store_ulps_timeout); 544 545static 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 553static const struct attribute_group dsicm_attr_group = { 554 .attrs = dsicm_attrs, 555}; 556 557static 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 573static 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; 658err: 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); 664err0: 665 return r; 666} 667 668static 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 690static 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 699static 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 729err_vc_id: 730 in->ops.dsi->release_vc(ddata->in, ddata->channel); 731err_req_vc: 732 in->ops.dsi->disconnect(in, dssdev); 733 return r; 734} 735 736static 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 748static 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; 782err: 783 dev_dbg(&ddata->pdev->dev, "enable failed\n"); 784 mutex_unlock(&ddata->lock); 785 return r; 786} 787 788static 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 815static 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 824static 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; 843err: 844 dev_err(&ddata->pdev->dev, "start update failed\n"); 845 in->ops.dsi->bus_unlock(in); 846 return IRQ_HANDLED; 847} 848 849static 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 861static 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; 903err: 904 in->ops.dsi->bus_unlock(in); 905 mutex_unlock(&ddata->lock); 906 return r; 907} 908 909static 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 926static 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 945static 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); 971end: 972 mutex_unlock(&ddata->lock); 973 974 return 0; 975err: 976 in->ops.dsi->bus_unlock(in); 977 mutex_unlock(&ddata->lock); 978 979 return r; 980} 981 982static 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 994static 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 1068err3: 1069 in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1); 1070err2: 1071 in->ops.dsi->bus_unlock(in); 1072err1: 1073 mutex_unlock(&ddata->lock); 1074 return r; 1075} 1076 1077static 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 1099static 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 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 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 1269err_sysfs_create: 1270 if (bldev != NULL) 1271 backlight_device_unregister(bldev); 1272err_reg: 1273 return r; 1274} 1275 1276static 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 1308static const struct of_device_id dsicm_of_match[] = { 1309 { .compatible = "omapdss,panel-dsi-cm", }, 1310 {}, 1311}; 1312 1313MODULE_DEVICE_TABLE(of, dsicm_of_match); 1314 1315static 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 1325module_platform_driver(dsicm_driver); 1326 1327MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); 1328MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver"); 1329MODULE_LICENSE("GPL");