Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
panel-taal.c
Go to the documentation of this file.
1 /*
2  * Taal DSI command mode panel
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Author: Tomi Valkeinen <[email protected]>
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  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /*#define DEBUG*/
21 
22 #include <linux/module.h>
23 #include <linux/delay.h>
24 #include <linux/err.h>
25 #include <linux/jiffies.h>
26 #include <linux/sched.h>
27 #include <linux/backlight.h>
28 #include <linux/fb.h>
29 #include <linux/interrupt.h>
30 #include <linux/gpio.h>
31 #include <linux/workqueue.h>
32 #include <linux/slab.h>
33 #include <linux/mutex.h>
34 
35 #include <video/omapdss.h>
37 #include <video/mipi_display.h>
38 
39 /* DSI Virtual channel. Hardcoded for now. */
40 #define TCH 0
41 
42 #define DCS_READ_NUM_ERRORS 0x05
43 #define DCS_BRIGHTNESS 0x51
44 #define DCS_CTRL_DISPLAY 0x53
45 #define DCS_WRITE_CABC 0x55
46 #define DCS_READ_CABC 0x56
47 #define DCS_GET_ID1 0xda
48 #define DCS_GET_ID2 0xdb
49 #define DCS_GET_ID3 0xdc
50 
51 static irqreturn_t taal_te_isr(int irq, void *data);
52 static void taal_te_timeout_work_callback(struct work_struct *work);
53 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
54 
55 static int taal_panel_reset(struct omap_dss_device *dssdev);
56 
67 struct panel_config {
68  const char *name;
69  int type;
70 
72 
73  struct {
74  unsigned int sleep_in;
75  unsigned int sleep_out;
76  unsigned int hw_reset;
77  unsigned int enable_te;
78  } sleep;
79 
80  struct {
81  unsigned int high;
82  unsigned int low;
84 
85 };
86 
87 enum {
89 };
90 
91 static struct panel_config panel_configs[] = {
92  {
93  .name = "taal",
94  .type = PANEL_TAAL,
95  .timings = {
96  .x_res = 864,
97  .y_res = 480,
98  },
99  .sleep = {
100  .sleep_in = 5,
101  .sleep_out = 5,
102  .hw_reset = 5,
103  .enable_te = 100, /* possible panel bug */
104  },
105  .reset_sequence = {
106  .high = 10,
107  .low = 10,
108  },
109  },
110 };
111 
112 struct taal_data {
113  struct mutex lock;
114 
116 
117  unsigned long hw_guard_end; /* next value of jiffies when we can
118  * issue the next sleep in/out command
119  */
120  unsigned long hw_guard_wait; /* max guard time in jiffies */
121 
123 
124  /* panel specific HW info */
126 
127  /* panel HW configuration from DT or platform data */
130 
132 
134 
135  /* runtime variables */
136  bool enabled;
138  bool mirror;
139 
141 
143  int channel;
144 
146 
148  unsigned cabc_mode;
149 
151 
153 
155  unsigned esd_interval;
156 
158  unsigned ulps_timeout;
160 };
161 
162 static void taal_esd_work(struct work_struct *work);
163 static void taal_ulps_work(struct work_struct *work);
164 
165 static void hw_guard_start(struct taal_data *td, int guard_msec)
166 {
167  td->hw_guard_wait = msecs_to_jiffies(guard_msec);
168  td->hw_guard_end = jiffies + td->hw_guard_wait;
169 }
170 
171 static void hw_guard_wait(struct taal_data *td)
172 {
173  unsigned long wait = td->hw_guard_end - jiffies;
174 
175  if ((long)wait > 0 && wait <= td->hw_guard_wait) {
177  schedule_timeout(wait);
178  }
179 }
180 
181 static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
182 {
183  int r;
184  u8 buf[1];
185 
186  r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
187 
188  if (r < 0)
189  return r;
190 
191  *data = buf[0];
192 
193  return 0;
194 }
195 
196 static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
197 {
198  return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
199 }
200 
201 static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
202 {
203  u8 buf[2];
204  buf[0] = dcs_cmd;
205  buf[1] = param;
206  return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
207 }
208 
209 static int taal_sleep_in(struct taal_data *td)
210 
211 {
212  u8 cmd;
213  int r;
214 
215  hw_guard_wait(td);
216 
218  r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
219  if (r)
220  return r;
221 
222  hw_guard_start(td, 120);
223 
224  if (td->panel_config->sleep.sleep_in)
225  msleep(td->panel_config->sleep.sleep_in);
226 
227  return 0;
228 }
229 
230 static int taal_sleep_out(struct taal_data *td)
231 {
232  int r;
233 
234  hw_guard_wait(td);
235 
236  r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
237  if (r)
238  return r;
239 
240  hw_guard_start(td, 120);
241 
242  if (td->panel_config->sleep.sleep_out)
243  msleep(td->panel_config->sleep.sleep_out);
244 
245  return 0;
246 }
247 
248 static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
249 {
250  int r;
251 
252  r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
253  if (r)
254  return r;
255  r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
256  if (r)
257  return r;
258  r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
259  if (r)
260  return r;
261 
262  return 0;
263 }
264 
265 static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
266 {
267  int r;
268  u8 mode;
269  int b5, b6, b7;
270 
271  r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
272  if (r)
273  return r;
274 
275  switch (rotate) {
276  default:
277  case 0:
278  b7 = 0;
279  b6 = 0;
280  b5 = 0;
281  break;
282  case 1:
283  b7 = 0;
284  b6 = 1;
285  b5 = 1;
286  break;
287  case 2:
288  b7 = 1;
289  b6 = 1;
290  b5 = 0;
291  break;
292  case 3:
293  b7 = 1;
294  b6 = 0;
295  b5 = 1;
296  break;
297  }
298 
299  if (mirror)
300  b6 = !b6;
301 
302  mode &= ~((1<<7) | (1<<6) | (1<<5));
303  mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
304 
305  return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
306 }
307 
308 static int taal_set_update_window(struct taal_data *td,
309  u16 x, u16 y, u16 w, u16 h)
310 {
311  int r;
312  u16 x1 = x;
313  u16 x2 = x + w - 1;
314  u16 y1 = y;
315  u16 y2 = y + h - 1;
316 
317  u8 buf[5];
319  buf[1] = (x1 >> 8) & 0xff;
320  buf[2] = (x1 >> 0) & 0xff;
321  buf[3] = (x2 >> 8) & 0xff;
322  buf[4] = (x2 >> 0) & 0xff;
323 
324  r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
325  if (r)
326  return r;
327 
328  buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
329  buf[1] = (y1 >> 8) & 0xff;
330  buf[2] = (y1 >> 0) & 0xff;
331  buf[3] = (y2 >> 8) & 0xff;
332  buf[4] = (y2 >> 0) & 0xff;
333 
334  r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
335  if (r)
336  return r;
337 
339 
340  return r;
341 }
342 
343 static void taal_queue_esd_work(struct omap_dss_device *dssdev)
344 {
345  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
346 
347  if (td->esd_interval > 0)
350 }
351 
352 static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
353 {
354  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
355 
357 }
358 
359 static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
360 {
361  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
362 
363  if (td->ulps_timeout > 0)
366 }
367 
368 static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
369 {
370  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
371 
373 }
374 
375 static int taal_enter_ulps(struct omap_dss_device *dssdev)
376 {
377  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
378  int r;
379 
380  if (td->ulps_enabled)
381  return 0;
382 
383  taal_cancel_ulps_work(dssdev);
384 
385  r = _taal_enable_te(dssdev, false);
386  if (r)
387  goto err;
388 
389  if (gpio_is_valid(td->ext_te_gpio))
391 
392  omapdss_dsi_display_disable(dssdev, false, true);
393 
394  td->ulps_enabled = true;
395 
396  return 0;
397 
398 err:
399  dev_err(&dssdev->dev, "enter ULPS failed");
400  taal_panel_reset(dssdev);
401 
402  td->ulps_enabled = false;
403 
404  taal_queue_ulps_work(dssdev);
405 
406  return r;
407 }
408 
409 static int taal_exit_ulps(struct omap_dss_device *dssdev)
410 {
411  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
412  int r;
413 
414  if (!td->ulps_enabled)
415  return 0;
416 
417  r = omapdss_dsi_display_enable(dssdev);
418  if (r) {
419  dev_err(&dssdev->dev, "failed to enable DSI\n");
420  goto err1;
421  }
422 
423  omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
424 
425  r = _taal_enable_te(dssdev, true);
426  if (r) {
427  dev_err(&dssdev->dev, "failed to re-enable TE");
428  goto err2;
429  }
430 
431  if (gpio_is_valid(td->ext_te_gpio))
433 
434  taal_queue_ulps_work(dssdev);
435 
436  td->ulps_enabled = false;
437 
438  return 0;
439 
440 err2:
441  dev_err(&dssdev->dev, "failed to exit ULPS");
442 
443  r = taal_panel_reset(dssdev);
444  if (!r) {
445  if (gpio_is_valid(td->ext_te_gpio))
447  td->ulps_enabled = false;
448  }
449 err1:
450  taal_queue_ulps_work(dssdev);
451 
452  return r;
453 }
454 
455 static int taal_wake_up(struct omap_dss_device *dssdev)
456 {
457  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
458 
459  if (td->ulps_enabled)
460  return taal_exit_ulps(dssdev);
461 
462  taal_cancel_ulps_work(dssdev);
463  taal_queue_ulps_work(dssdev);
464  return 0;
465 }
466 
467 static int taal_bl_update_status(struct backlight_device *dev)
468 {
469  struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
470  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
471  int r;
472  int level;
473 
474  if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
475  dev->props.power == FB_BLANK_UNBLANK)
476  level = dev->props.brightness;
477  else
478  level = 0;
479 
480  dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
481 
482  mutex_lock(&td->lock);
483 
484  if (td->enabled) {
485  dsi_bus_lock(dssdev);
486 
487  r = taal_wake_up(dssdev);
488  if (!r)
489  r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
490 
491  dsi_bus_unlock(dssdev);
492  } else {
493  r = 0;
494  }
495 
496  mutex_unlock(&td->lock);
497 
498  return r;
499 }
500 
501 static int taal_bl_get_intensity(struct backlight_device *dev)
502 {
503  if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
504  dev->props.power == FB_BLANK_UNBLANK)
505  return dev->props.brightness;
506 
507  return 0;
508 }
509 
510 static const struct backlight_ops taal_bl_ops = {
511  .get_brightness = taal_bl_get_intensity,
512  .update_status = taal_bl_update_status,
513 };
514 
515 static void taal_get_resolution(struct omap_dss_device *dssdev,
516  u16 *xres, u16 *yres)
517 {
518  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
519 
520  if (td->rotate == 0 || td->rotate == 2) {
521  *xres = dssdev->panel.timings.x_res;
522  *yres = dssdev->panel.timings.y_res;
523  } else {
524  *yres = dssdev->panel.timings.x_res;
525  *xres = dssdev->panel.timings.y_res;
526  }
527 }
528 
529 static ssize_t taal_num_errors_show(struct device *dev,
530  struct device_attribute *attr, char *buf)
531 {
532  struct omap_dss_device *dssdev = to_dss_device(dev);
533  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
534  u8 errors = 0;
535  int r;
536 
537  mutex_lock(&td->lock);
538 
539  if (td->enabled) {
540  dsi_bus_lock(dssdev);
541 
542  r = taal_wake_up(dssdev);
543  if (!r)
544  r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
545 
546  dsi_bus_unlock(dssdev);
547  } else {
548  r = -ENODEV;
549  }
550 
551  mutex_unlock(&td->lock);
552 
553  if (r)
554  return r;
555 
556  return snprintf(buf, PAGE_SIZE, "%d\n", errors);
557 }
558 
559 static ssize_t taal_hw_revision_show(struct device *dev,
560  struct device_attribute *attr, char *buf)
561 {
562  struct omap_dss_device *dssdev = to_dss_device(dev);
563  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
564  u8 id1, id2, id3;
565  int r;
566 
567  mutex_lock(&td->lock);
568 
569  if (td->enabled) {
570  dsi_bus_lock(dssdev);
571 
572  r = taal_wake_up(dssdev);
573  if (!r)
574  r = taal_get_id(td, &id1, &id2, &id3);
575 
576  dsi_bus_unlock(dssdev);
577  } else {
578  r = -ENODEV;
579  }
580 
581  mutex_unlock(&td->lock);
582 
583  if (r)
584  return r;
585 
586  return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
587 }
588 
589 static const char *cabc_modes[] = {
590  "off", /* used also always when CABC is not supported */
591  "ui",
592  "still-image",
593  "moving-image",
594 };
595 
596 static ssize_t show_cabc_mode(struct device *dev,
597  struct device_attribute *attr,
598  char *buf)
599 {
600  struct omap_dss_device *dssdev = to_dss_device(dev);
601  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
602  const char *mode_str;
603  int mode;
604  int len;
605 
606  mode = td->cabc_mode;
607 
608  mode_str = "unknown";
609  if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
610  mode_str = cabc_modes[mode];
611  len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
612 
613  return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
614 }
615 
616 static ssize_t store_cabc_mode(struct device *dev,
617  struct device_attribute *attr,
618  const char *buf, size_t count)
619 {
620  struct omap_dss_device *dssdev = to_dss_device(dev);
621  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
622  int i;
623  int r;
624 
625  for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
626  if (sysfs_streq(cabc_modes[i], buf))
627  break;
628  }
629 
630  if (i == ARRAY_SIZE(cabc_modes))
631  return -EINVAL;
632 
633  mutex_lock(&td->lock);
634 
635  if (td->enabled) {
636  dsi_bus_lock(dssdev);
637 
638  if (!td->cabc_broken) {
639  r = taal_wake_up(dssdev);
640  if (r)
641  goto err;
642 
643  r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
644  if (r)
645  goto err;
646  }
647 
648  dsi_bus_unlock(dssdev);
649  }
650 
651  td->cabc_mode = i;
652 
653  mutex_unlock(&td->lock);
654 
655  return count;
656 err:
657  dsi_bus_unlock(dssdev);
658  mutex_unlock(&td->lock);
659  return r;
660 }
661 
662 static ssize_t show_cabc_available_modes(struct device *dev,
663  struct device_attribute *attr,
664  char *buf)
665 {
666  int len;
667  int i;
668 
669  for (i = 0, len = 0;
670  len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
671  len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
672  i ? " " : "", cabc_modes[i],
673  i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
674 
675  return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
676 }
677 
678 static ssize_t taal_store_esd_interval(struct device *dev,
679  struct device_attribute *attr,
680  const char *buf, size_t count)
681 {
682  struct omap_dss_device *dssdev = to_dss_device(dev);
683  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
684 
685  unsigned long t;
686  int r;
687 
688  r = strict_strtoul(buf, 10, &t);
689  if (r)
690  return r;
691 
692  mutex_lock(&td->lock);
693  taal_cancel_esd_work(dssdev);
694  td->esd_interval = t;
695  if (td->enabled)
696  taal_queue_esd_work(dssdev);
697  mutex_unlock(&td->lock);
698 
699  return count;
700 }
701 
702 static ssize_t taal_show_esd_interval(struct device *dev,
703  struct device_attribute *attr,
704  char *buf)
705 {
706  struct omap_dss_device *dssdev = to_dss_device(dev);
707  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
708  unsigned t;
709 
710  mutex_lock(&td->lock);
711  t = td->esd_interval;
712  mutex_unlock(&td->lock);
713 
714  return snprintf(buf, PAGE_SIZE, "%u\n", t);
715 }
716 
717 static ssize_t taal_store_ulps(struct device *dev,
718  struct device_attribute *attr,
719  const char *buf, size_t count)
720 {
721  struct omap_dss_device *dssdev = to_dss_device(dev);
722  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
723  unsigned long t;
724  int r;
725 
726  r = strict_strtoul(buf, 10, &t);
727  if (r)
728  return r;
729 
730  mutex_lock(&td->lock);
731 
732  if (td->enabled) {
733  dsi_bus_lock(dssdev);
734 
735  if (t)
736  r = taal_enter_ulps(dssdev);
737  else
738  r = taal_wake_up(dssdev);
739 
740  dsi_bus_unlock(dssdev);
741  }
742 
743  mutex_unlock(&td->lock);
744 
745  if (r)
746  return r;
747 
748  return count;
749 }
750 
751 static ssize_t taal_show_ulps(struct device *dev,
752  struct device_attribute *attr,
753  char *buf)
754 {
755  struct omap_dss_device *dssdev = to_dss_device(dev);
756  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
757  unsigned t;
758 
759  mutex_lock(&td->lock);
760  t = td->ulps_enabled;
761  mutex_unlock(&td->lock);
762 
763  return snprintf(buf, PAGE_SIZE, "%u\n", t);
764 }
765 
766 static ssize_t taal_store_ulps_timeout(struct device *dev,
767  struct device_attribute *attr,
768  const char *buf, size_t count)
769 {
770  struct omap_dss_device *dssdev = to_dss_device(dev);
771  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
772  unsigned long t;
773  int r;
774 
775  r = strict_strtoul(buf, 10, &t);
776  if (r)
777  return r;
778 
779  mutex_lock(&td->lock);
780  td->ulps_timeout = t;
781 
782  if (td->enabled) {
783  /* taal_wake_up will restart the timer */
784  dsi_bus_lock(dssdev);
785  r = taal_wake_up(dssdev);
786  dsi_bus_unlock(dssdev);
787  }
788 
789  mutex_unlock(&td->lock);
790 
791  if (r)
792  return r;
793 
794  return count;
795 }
796 
797 static ssize_t taal_show_ulps_timeout(struct device *dev,
798  struct device_attribute *attr,
799  char *buf)
800 {
801  struct omap_dss_device *dssdev = to_dss_device(dev);
802  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
803  unsigned t;
804 
805  mutex_lock(&td->lock);
806  t = td->ulps_timeout;
807  mutex_unlock(&td->lock);
808 
809  return snprintf(buf, PAGE_SIZE, "%u\n", t);
810 }
811 
812 static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
813 static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
815  show_cabc_mode, store_cabc_mode);
816 static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
817  show_cabc_available_modes, NULL);
819  taal_show_esd_interval, taal_store_esd_interval);
820 static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
821  taal_show_ulps, taal_store_ulps);
823  taal_show_ulps_timeout, taal_store_ulps_timeout);
824 
825 static struct attribute *taal_attrs[] = {
826  &dev_attr_num_dsi_errors.attr,
827  &dev_attr_hw_revision.attr,
828  &dev_attr_cabc_mode.attr,
829  &dev_attr_cabc_available_modes.attr,
830  &dev_attr_esd_interval.attr,
831  &dev_attr_ulps.attr,
832  &dev_attr_ulps_timeout.attr,
833  NULL,
834 };
835 
836 static struct attribute_group taal_attr_group = {
837  .attrs = taal_attrs,
838 };
839 
840 static void taal_hw_reset(struct omap_dss_device *dssdev)
841 {
842  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
843 
844  if (!gpio_is_valid(td->reset_gpio))
845  return;
846 
847  gpio_set_value(td->reset_gpio, 1);
848  if (td->panel_config->reset_sequence.high)
849  udelay(td->panel_config->reset_sequence.high);
850  /* reset the panel */
851  gpio_set_value(td->reset_gpio, 0);
852  /* assert reset */
853  if (td->panel_config->reset_sequence.low)
854  udelay(td->panel_config->reset_sequence.low);
855  gpio_set_value(td->reset_gpio, 1);
856  /* wait after releasing reset */
857  if (td->panel_config->sleep.hw_reset)
858  msleep(td->panel_config->sleep.hw_reset);
859 }
860 
861 static void taal_probe_pdata(struct taal_data *td,
862  const struct nokia_dsi_panel_data *pdata)
863 {
864  td->reset_gpio = pdata->reset_gpio;
865 
866  if (pdata->use_ext_te)
867  td->ext_te_gpio = pdata->ext_te_gpio;
868  else
869  td->ext_te_gpio = -1;
870 
871  td->esd_interval = pdata->esd_interval;
872  td->ulps_timeout = pdata->ulps_timeout;
873 
875 
876  td->pin_config = pdata->pin_config;
877 }
878 
879 static int taal_probe(struct omap_dss_device *dssdev)
880 {
881  struct backlight_properties props;
882  struct taal_data *td;
883  struct backlight_device *bldev = NULL;
884  int r, i;
885  const char *panel_name;
886 
887  dev_dbg(&dssdev->dev, "probe\n");
888 
889  td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
890  if (!td)
891  return -ENOMEM;
892 
893  dev_set_drvdata(&dssdev->dev, td);
894  td->dssdev = dssdev;
895 
896  if (dssdev->data) {
897  const struct nokia_dsi_panel_data *pdata = dssdev->data;
898 
899  taal_probe_pdata(td, pdata);
900 
901  panel_name = pdata->name;
902  } else {
903  return -ENODEV;
904  }
905 
906  if (panel_name == NULL)
907  return -EINVAL;
908 
909  for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
910  if (strcmp(panel_name, panel_configs[i].name) == 0) {
911  td->panel_config = &panel_configs[i];
912  break;
913  }
914  }
915 
916  if (!td->panel_config)
917  return -EINVAL;
918 
919  dssdev->panel.timings = td->panel_config->timings;
920  dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
923 
924  mutex_init(&td->lock);
925 
926  atomic_set(&td->do_update, 0);
927 
928  if (gpio_is_valid(td->reset_gpio)) {
929  r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
930  GPIOF_OUT_INIT_LOW, "taal rst");
931  if (r) {
932  dev_err(&dssdev->dev, "failed to request reset gpio\n");
933  return r;
934  }
935  }
936 
937  if (gpio_is_valid(td->ext_te_gpio)) {
938  r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
939  GPIOF_IN, "taal irq");
940  if (r) {
941  dev_err(&dssdev->dev, "GPIO request failed\n");
942  return r;
943  }
944 
945  r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
946  taal_te_isr,
948  "taal vsync", dssdev);
949 
950  if (r) {
951  dev_err(&dssdev->dev, "IRQ request failed\n");
952  return r;
953  }
954 
956  taal_te_timeout_work_callback);
957 
958  dev_dbg(&dssdev->dev, "Using GPIO TE\n");
959  }
960 
961  td->workqueue = create_singlethread_workqueue("taal_esd");
962  if (td->workqueue == NULL) {
963  dev_err(&dssdev->dev, "can't create ESD workqueue\n");
964  return -ENOMEM;
965  }
966  INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
967  INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
968 
969  taal_hw_reset(dssdev);
970 
971  if (td->use_dsi_backlight) {
972  memset(&props, 0, sizeof(struct backlight_properties));
973  props.max_brightness = 255;
974 
975  props.type = BACKLIGHT_RAW;
976  bldev = backlight_device_register(dev_name(&dssdev->dev),
977  &dssdev->dev, dssdev, &taal_bl_ops, &props);
978  if (IS_ERR(bldev)) {
979  r = PTR_ERR(bldev);
980  goto err_bl;
981  }
982 
983  td->bldev = bldev;
984 
985  bldev->props.fb_blank = FB_BLANK_UNBLANK;
986  bldev->props.power = FB_BLANK_UNBLANK;
987  bldev->props.brightness = 255;
988 
989  taal_bl_update_status(bldev);
990  }
991 
992  r = omap_dsi_request_vc(dssdev, &td->channel);
993  if (r) {
994  dev_err(&dssdev->dev, "failed to get virtual channel\n");
995  goto err_req_vc;
996  }
997 
998  r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
999  if (r) {
1000  dev_err(&dssdev->dev, "failed to set VC_ID\n");
1001  goto err_vc_id;
1002  }
1003 
1004  r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
1005  if (r) {
1006  dev_err(&dssdev->dev, "failed to create sysfs files\n");
1007  goto err_vc_id;
1008  }
1009 
1010  return 0;
1011 
1012 err_vc_id:
1013  omap_dsi_release_vc(dssdev, td->channel);
1014 err_req_vc:
1015  if (bldev != NULL)
1017 err_bl:
1019  return r;
1020 }
1021 
1022 static void __exit taal_remove(struct omap_dss_device *dssdev)
1023 {
1024  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1025  struct backlight_device *bldev;
1026 
1027  dev_dbg(&dssdev->dev, "remove\n");
1028 
1029  sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
1030  omap_dsi_release_vc(dssdev, td->channel);
1031 
1032  bldev = td->bldev;
1033  if (bldev != NULL) {
1034  bldev->props.power = FB_BLANK_POWERDOWN;
1035  taal_bl_update_status(bldev);
1037  }
1038 
1039  taal_cancel_ulps_work(dssdev);
1040  taal_cancel_esd_work(dssdev);
1042 
1043  /* reset, to be sure that the panel is in a valid state */
1044  taal_hw_reset(dssdev);
1045 }
1046 
1047 static int taal_power_on(struct omap_dss_device *dssdev)
1048 {
1049  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1050  u8 id1, id2, id3;
1051  int r;
1052 
1053  r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
1054  if (r) {
1055  dev_err(&dssdev->dev, "failed to configure DSI pins\n");
1056  goto err0;
1057  };
1058 
1059  omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
1060  dssdev->panel.timings.y_res);
1063 
1064  r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
1065  if (r) {
1066  dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
1067  goto err0;
1068  }
1069 
1070  r = omapdss_dsi_display_enable(dssdev);
1071  if (r) {
1072  dev_err(&dssdev->dev, "failed to enable DSI\n");
1073  goto err0;
1074  }
1075 
1076  taal_hw_reset(dssdev);
1077 
1078  omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
1079 
1080  r = taal_sleep_out(td);
1081  if (r)
1082  goto err;
1083 
1084  r = taal_get_id(td, &id1, &id2, &id3);
1085  if (r)
1086  goto err;
1087 
1088  /* on early Taal revisions CABC is broken */
1089  if (td->panel_config->type == PANEL_TAAL &&
1090  (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
1091  td->cabc_broken = true;
1092 
1093  r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
1094  if (r)
1095  goto err;
1096 
1097  r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
1098  (1<<2) | (1<<5)); /* BL | BCTRL */
1099  if (r)
1100  goto err;
1101 
1102  r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
1104  if (r)
1105  goto err;
1106 
1107  r = taal_set_addr_mode(td, td->rotate, td->mirror);
1108  if (r)
1109  goto err;
1110 
1111  if (!td->cabc_broken) {
1112  r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
1113  if (r)
1114  goto err;
1115  }
1116 
1117  r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
1118  if (r)
1119  goto err;
1120 
1121  r = _taal_enable_te(dssdev, td->te_enabled);
1122  if (r)
1123  goto err;
1124 
1125  r = dsi_enable_video_output(dssdev, td->channel);
1126  if (r)
1127  goto err;
1128 
1129  td->enabled = 1;
1130 
1131  if (!td->intro_printed) {
1132  dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
1133  td->panel_config->name, id1, id2, id3);
1134  if (td->cabc_broken)
1135  dev_info(&dssdev->dev,
1136  "old Taal version, CABC disabled\n");
1137  td->intro_printed = true;
1138  }
1139 
1140  omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
1141 
1142  return 0;
1143 err:
1144  dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
1145 
1146  taal_hw_reset(dssdev);
1147 
1148  omapdss_dsi_display_disable(dssdev, true, false);
1149 err0:
1150  return r;
1151 }
1152 
1153 static void taal_power_off(struct omap_dss_device *dssdev)
1154 {
1155  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1156  int r;
1157 
1158  dsi_disable_video_output(dssdev, td->channel);
1159 
1160  r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
1161  if (!r)
1162  r = taal_sleep_in(td);
1163 
1164  if (r) {
1165  dev_err(&dssdev->dev,
1166  "error disabling panel, issuing HW reset\n");
1167  taal_hw_reset(dssdev);
1168  }
1169 
1170  omapdss_dsi_display_disable(dssdev, true, false);
1171 
1172  td->enabled = 0;
1173 }
1174 
1175 static int taal_panel_reset(struct omap_dss_device *dssdev)
1176 {
1177  dev_err(&dssdev->dev, "performing LCD reset\n");
1178 
1179  taal_power_off(dssdev);
1180  taal_hw_reset(dssdev);
1181  return taal_power_on(dssdev);
1182 }
1183 
1184 static int taal_enable(struct omap_dss_device *dssdev)
1185 {
1186  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1187  int r;
1188 
1189  dev_dbg(&dssdev->dev, "enable\n");
1190 
1191  mutex_lock(&td->lock);
1192 
1193  if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
1194  r = -EINVAL;
1195  goto err;
1196  }
1197 
1198  dsi_bus_lock(dssdev);
1199 
1200  r = taal_power_on(dssdev);
1201 
1202  dsi_bus_unlock(dssdev);
1203 
1204  if (r)
1205  goto err;
1206 
1207  taal_queue_esd_work(dssdev);
1208 
1209  dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1210 
1211  mutex_unlock(&td->lock);
1212 
1213  return 0;
1214 err:
1215  dev_dbg(&dssdev->dev, "enable failed\n");
1216  mutex_unlock(&td->lock);
1217  return r;
1218 }
1219 
1220 static void taal_disable(struct omap_dss_device *dssdev)
1221 {
1222  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1223 
1224  dev_dbg(&dssdev->dev, "disable\n");
1225 
1226  mutex_lock(&td->lock);
1227 
1228  taal_cancel_ulps_work(dssdev);
1229  taal_cancel_esd_work(dssdev);
1230 
1231  dsi_bus_lock(dssdev);
1232 
1233  if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
1234  int r;
1235 
1236  r = taal_wake_up(dssdev);
1237  if (!r)
1238  taal_power_off(dssdev);
1239  }
1240 
1241  dsi_bus_unlock(dssdev);
1242 
1243  dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1244 
1245  mutex_unlock(&td->lock);
1246 }
1247 
1248 static int taal_suspend(struct omap_dss_device *dssdev)
1249 {
1250  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1251  int r;
1252 
1253  dev_dbg(&dssdev->dev, "suspend\n");
1254 
1255  mutex_lock(&td->lock);
1256 
1257  if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
1258  r = -EINVAL;
1259  goto err;
1260  }
1261 
1262  taal_cancel_ulps_work(dssdev);
1263  taal_cancel_esd_work(dssdev);
1264 
1265  dsi_bus_lock(dssdev);
1266 
1267  r = taal_wake_up(dssdev);
1268  if (!r)
1269  taal_power_off(dssdev);
1270 
1271  dsi_bus_unlock(dssdev);
1272 
1274 
1275  mutex_unlock(&td->lock);
1276 
1277  return 0;
1278 err:
1279  mutex_unlock(&td->lock);
1280  return r;
1281 }
1282 
1283 static int taal_resume(struct omap_dss_device *dssdev)
1284 {
1285  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1286  int r;
1287 
1288  dev_dbg(&dssdev->dev, "resume\n");
1289 
1290  mutex_lock(&td->lock);
1291 
1292  if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
1293  r = -EINVAL;
1294  goto err;
1295  }
1296 
1297  dsi_bus_lock(dssdev);
1298 
1299  r = taal_power_on(dssdev);
1300 
1301  dsi_bus_unlock(dssdev);
1302 
1303  if (r) {
1304  dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1305  } else {
1306  dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1307  taal_queue_esd_work(dssdev);
1308  }
1309 
1310  mutex_unlock(&td->lock);
1311 
1312  return r;
1313 err:
1314  mutex_unlock(&td->lock);
1315  return r;
1316 }
1317 
1318 static void taal_framedone_cb(int err, void *data)
1319 {
1320  struct omap_dss_device *dssdev = data;
1321  dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
1322  dsi_bus_unlock(dssdev);
1323 }
1324 
1325 static irqreturn_t taal_te_isr(int irq, void *data)
1326 {
1327  struct omap_dss_device *dssdev = data;
1328  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1329  int old;
1330  int r;
1331 
1332  old = atomic_cmpxchg(&td->do_update, 1, 0);
1333 
1334  if (old) {
1336 
1337  r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
1338  dssdev);
1339  if (r)
1340  goto err;
1341  }
1342 
1343  return IRQ_HANDLED;
1344 err:
1345  dev_err(&dssdev->dev, "start update failed\n");
1346  dsi_bus_unlock(dssdev);
1347  return IRQ_HANDLED;
1348 }
1349 
1350 static void taal_te_timeout_work_callback(struct work_struct *work)
1351 {
1352  struct taal_data *td = container_of(work, struct taal_data,
1353  te_timeout_work.work);
1354  struct omap_dss_device *dssdev = td->dssdev;
1355 
1356  dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1357 
1358  atomic_set(&td->do_update, 0);
1359  dsi_bus_unlock(dssdev);
1360 }
1361 
1362 static int taal_update(struct omap_dss_device *dssdev,
1363  u16 x, u16 y, u16 w, u16 h)
1364 {
1365  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1366  int r;
1367 
1368  dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1369 
1370  mutex_lock(&td->lock);
1371  dsi_bus_lock(dssdev);
1372 
1373  r = taal_wake_up(dssdev);
1374  if (r)
1375  goto err;
1376 
1377  if (!td->enabled) {
1378  r = 0;
1379  goto err;
1380  }
1381 
1382  /* XXX no need to send this every frame, but dsi break if not done */
1383  r = taal_set_update_window(td, 0, 0,
1384  td->panel_config->timings.x_res,
1385  td->panel_config->timings.y_res);
1386  if (r)
1387  goto err;
1388 
1389  if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1391  msecs_to_jiffies(250));
1392  atomic_set(&td->do_update, 1);
1393  } else {
1394  r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
1395  dssdev);
1396  if (r)
1397  goto err;
1398  }
1399 
1400  /* note: no bus_unlock here. unlock is in framedone_cb */
1401  mutex_unlock(&td->lock);
1402  return 0;
1403 err:
1404  dsi_bus_unlock(dssdev);
1405  mutex_unlock(&td->lock);
1406  return r;
1407 }
1408 
1409 static int taal_sync(struct omap_dss_device *dssdev)
1410 {
1411  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1412 
1413  dev_dbg(&dssdev->dev, "sync\n");
1414 
1415  mutex_lock(&td->lock);
1416  dsi_bus_lock(dssdev);
1417  dsi_bus_unlock(dssdev);
1418  mutex_unlock(&td->lock);
1419 
1420  dev_dbg(&dssdev->dev, "sync done\n");
1421 
1422  return 0;
1423 }
1424 
1425 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1426 {
1427  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1428  int r;
1429 
1430  if (enable)
1431  r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1432  else
1433  r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
1434 
1435  if (!gpio_is_valid(td->ext_te_gpio))
1436  omapdss_dsi_enable_te(dssdev, enable);
1437 
1438  if (td->panel_config->sleep.enable_te)
1439  msleep(td->panel_config->sleep.enable_te);
1440 
1441  return r;
1442 }
1443 
1444 static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1445 {
1446  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1447  int r;
1448 
1449  mutex_lock(&td->lock);
1450 
1451  if (td->te_enabled == enable)
1452  goto end;
1453 
1454  dsi_bus_lock(dssdev);
1455 
1456  if (td->enabled) {
1457  r = taal_wake_up(dssdev);
1458  if (r)
1459  goto err;
1460 
1461  r = _taal_enable_te(dssdev, enable);
1462  if (r)
1463  goto err;
1464  }
1465 
1466  td->te_enabled = enable;
1467 
1468  dsi_bus_unlock(dssdev);
1469 end:
1470  mutex_unlock(&td->lock);
1471 
1472  return 0;
1473 err:
1474  dsi_bus_unlock(dssdev);
1475  mutex_unlock(&td->lock);
1476 
1477  return r;
1478 }
1479 
1480 static int taal_get_te(struct omap_dss_device *dssdev)
1481 {
1482  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1483  int r;
1484 
1485  mutex_lock(&td->lock);
1486  r = td->te_enabled;
1487  mutex_unlock(&td->lock);
1488 
1489  return r;
1490 }
1491 
1492 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1493 {
1494  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1495  u16 dw, dh;
1496  int r;
1497 
1498  dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
1499 
1500  mutex_lock(&td->lock);
1501 
1502  if (td->rotate == rotate)
1503  goto end;
1504 
1505  dsi_bus_lock(dssdev);
1506 
1507  if (td->enabled) {
1508  r = taal_wake_up(dssdev);
1509  if (r)
1510  goto err;
1511 
1512  r = taal_set_addr_mode(td, rotate, td->mirror);
1513  if (r)
1514  goto err;
1515  }
1516 
1517  if (rotate == 0 || rotate == 2) {
1518  dw = dssdev->panel.timings.x_res;
1519  dh = dssdev->panel.timings.y_res;
1520  } else {
1521  dw = dssdev->panel.timings.y_res;
1522  dh = dssdev->panel.timings.x_res;
1523  }
1524 
1525  omapdss_dsi_set_size(dssdev, dw, dh);
1526 
1527  td->rotate = rotate;
1528 
1529  dsi_bus_unlock(dssdev);
1530 end:
1531  mutex_unlock(&td->lock);
1532  return 0;
1533 err:
1534  dsi_bus_unlock(dssdev);
1535  mutex_unlock(&td->lock);
1536  return r;
1537 }
1538 
1539 static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1540 {
1541  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1542  int r;
1543 
1544  mutex_lock(&td->lock);
1545  r = td->rotate;
1546  mutex_unlock(&td->lock);
1547 
1548  return r;
1549 }
1550 
1551 static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1552 {
1553  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1554  int r;
1555 
1556  dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1557 
1558  mutex_lock(&td->lock);
1559 
1560  if (td->mirror == enable)
1561  goto end;
1562 
1563  dsi_bus_lock(dssdev);
1564  if (td->enabled) {
1565  r = taal_wake_up(dssdev);
1566  if (r)
1567  goto err;
1568 
1569  r = taal_set_addr_mode(td, td->rotate, enable);
1570  if (r)
1571  goto err;
1572  }
1573 
1574  td->mirror = enable;
1575 
1576  dsi_bus_unlock(dssdev);
1577 end:
1578  mutex_unlock(&td->lock);
1579  return 0;
1580 err:
1581  dsi_bus_unlock(dssdev);
1582  mutex_unlock(&td->lock);
1583  return r;
1584 }
1585 
1586 static bool taal_get_mirror(struct omap_dss_device *dssdev)
1587 {
1588  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1589  int r;
1590 
1591  mutex_lock(&td->lock);
1592  r = td->mirror;
1593  mutex_unlock(&td->lock);
1594 
1595  return r;
1596 }
1597 
1598 static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1599 {
1600  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1601  u8 id1, id2, id3;
1602  int r;
1603 
1604  mutex_lock(&td->lock);
1605 
1606  if (!td->enabled) {
1607  r = -ENODEV;
1608  goto err1;
1609  }
1610 
1611  dsi_bus_lock(dssdev);
1612 
1613  r = taal_wake_up(dssdev);
1614  if (r)
1615  goto err2;
1616 
1617  r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1618  if (r)
1619  goto err2;
1620  r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1621  if (r)
1622  goto err2;
1623  r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1624  if (r)
1625  goto err2;
1626 
1627  dsi_bus_unlock(dssdev);
1628  mutex_unlock(&td->lock);
1629  return 0;
1630 err2:
1631  dsi_bus_unlock(dssdev);
1632 err1:
1633  mutex_unlock(&td->lock);
1634  return r;
1635 }
1636 
1637 static int taal_memory_read(struct omap_dss_device *dssdev,
1638  void *buf, size_t size,
1639  u16 x, u16 y, u16 w, u16 h)
1640 {
1641  int r;
1642  int first = 1;
1643  int plen;
1644  unsigned buf_used = 0;
1645  struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1646 
1647  if (size < w * h * 3)
1648  return -ENOMEM;
1649 
1650  mutex_lock(&td->lock);
1651 
1652  if (!td->enabled) {
1653  r = -ENODEV;
1654  goto err1;
1655  }
1656 
1657  size = min(w * h * 3,
1658  dssdev->panel.timings.x_res *
1659  dssdev->panel.timings.y_res * 3);
1660 
1661  dsi_bus_lock(dssdev);
1662 
1663  r = taal_wake_up(dssdev);
1664  if (r)
1665  goto err2;
1666 
1667  /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1668  * use short packets. plen 32 works, but bigger packets seem to cause
1669  * an error. */
1670  if (size % 2)
1671  plen = 1;
1672  else
1673  plen = 2;
1674 
1675  taal_set_update_window(td, x, y, w, h);
1676 
1677  r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
1678  if (r)
1679  goto err2;
1680 
1681  while (buf_used < size) {
1682  u8 dcs_cmd = first ? 0x2e : 0x3e;
1683  first = 0;
1684 
1685  r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
1686  buf + buf_used, size - buf_used);
1687 
1688  if (r < 0) {
1689  dev_err(&dssdev->dev, "read error\n");
1690  goto err3;
1691  }
1692 
1693  buf_used += r;
1694 
1695  if (r < plen) {
1696  dev_err(&dssdev->dev, "short read\n");
1697  break;
1698  }
1699 
1700  if (signal_pending(current)) {
1701  dev_err(&dssdev->dev, "signal pending, "
1702  "aborting memory read\n");
1703  r = -ERESTARTSYS;
1704  goto err3;
1705  }
1706  }
1707 
1708  r = buf_used;
1709 
1710 err3:
1711  dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
1712 err2:
1713  dsi_bus_unlock(dssdev);
1714 err1:
1715  mutex_unlock(&td->lock);
1716  return r;
1717 }
1718 
1719 static void taal_ulps_work(struct work_struct *work)
1720 {
1721  struct taal_data *td = container_of(work, struct taal_data,
1722  ulps_work.work);
1723  struct omap_dss_device *dssdev = td->dssdev;
1724 
1725  mutex_lock(&td->lock);
1726 
1727  if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
1728  mutex_unlock(&td->lock);
1729  return;
1730  }
1731 
1732  dsi_bus_lock(dssdev);
1733 
1734  taal_enter_ulps(dssdev);
1735 
1736  dsi_bus_unlock(dssdev);
1737  mutex_unlock(&td->lock);
1738 }
1739 
1740 static void taal_esd_work(struct work_struct *work)
1741 {
1742  struct taal_data *td = container_of(work, struct taal_data,
1743  esd_work.work);
1744  struct omap_dss_device *dssdev = td->dssdev;
1745  u8 state1, state2;
1746  int r;
1747 
1748  mutex_lock(&td->lock);
1749 
1750  if (!td->enabled) {
1751  mutex_unlock(&td->lock);
1752  return;
1753  }
1754 
1755  dsi_bus_lock(dssdev);
1756 
1757  r = taal_wake_up(dssdev);
1758  if (r) {
1759  dev_err(&dssdev->dev, "failed to exit ULPS\n");
1760  goto err;
1761  }
1762 
1763  r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
1764  if (r) {
1765  dev_err(&dssdev->dev, "failed to read Taal status\n");
1766  goto err;
1767  }
1768 
1769  /* Run self diagnostics */
1770  r = taal_sleep_out(td);
1771  if (r) {
1772  dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
1773  goto err;
1774  }
1775 
1776  r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
1777  if (r) {
1778  dev_err(&dssdev->dev, "failed to read Taal status\n");
1779  goto err;
1780  }
1781 
1782  /* Each sleep out command will trigger a self diagnostic and flip
1783  * Bit6 if the test passes.
1784  */
1785  if (!((state1 ^ state2) & (1 << 6))) {
1786  dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
1787  goto err;
1788  }
1789  /* Self-diagnostics result is also shown on TE GPIO line. We need
1790  * to re-enable TE after self diagnostics */
1791  if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1792  r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1793  if (r)
1794  goto err;
1795  }
1796 
1797  dsi_bus_unlock(dssdev);
1798 
1799  taal_queue_esd_work(dssdev);
1800 
1801  mutex_unlock(&td->lock);
1802  return;
1803 err:
1804  dev_err(&dssdev->dev, "performing LCD reset\n");
1805 
1806  taal_panel_reset(dssdev);
1807 
1808  dsi_bus_unlock(dssdev);
1809 
1810  taal_queue_esd_work(dssdev);
1811 
1812  mutex_unlock(&td->lock);
1813 }
1814 
1815 static struct omap_dss_driver taal_driver = {
1816  .probe = taal_probe,
1817  .remove = __exit_p(taal_remove),
1818 
1819  .enable = taal_enable,
1820  .disable = taal_disable,
1821  .suspend = taal_suspend,
1822  .resume = taal_resume,
1823 
1824  .update = taal_update,
1825  .sync = taal_sync,
1826 
1827  .get_resolution = taal_get_resolution,
1828  .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1829 
1830  .enable_te = taal_enable_te,
1831  .get_te = taal_get_te,
1832 
1833  .set_rotate = taal_rotate,
1834  .get_rotate = taal_get_rotate,
1835  .set_mirror = taal_mirror,
1836  .get_mirror = taal_get_mirror,
1837  .run_test = taal_run_test,
1838  .memory_read = taal_memory_read,
1839 
1840  .driver = {
1841  .name = "taal",
1842  .owner = THIS_MODULE,
1843  },
1844 };
1845 
1846 static int __init taal_init(void)
1847 {
1848  omap_dss_register_driver(&taal_driver);
1849 
1850  return 0;
1851 }
1852 
1853 static void __exit taal_exit(void)
1854 {
1855  omap_dss_unregister_driver(&taal_driver);
1856 }
1857 
1858 module_init(taal_init);
1859 module_exit(taal_exit);
1860 
1861 MODULE_AUTHOR("Tomi Valkeinen <[email protected]>");
1862 MODULE_DESCRIPTION("Taal Driver");
1863 MODULE_LICENSE("GPL");