OMAP: DSS2: Taal: Remove platform enable/disable
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / video / omap2 / displays / panel-taal.c
1 /*
2  * Taal DSI command mode panel
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published by
9  * the Free Software Foundation.
10  *
11  * 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/completion.h>
32 #include <linux/workqueue.h>
33 #include <linux/slab.h>
34 #include <linux/mutex.h>
35
36 #include <plat/display.h>
37
38 /* DSI Virtual channel. Hardcoded for now. */
39 #define TCH 0
40
41 #define DCS_READ_NUM_ERRORS     0x05
42 #define DCS_READ_POWER_MODE     0x0a
43 #define DCS_READ_MADCTL         0x0b
44 #define DCS_READ_PIXEL_FORMAT   0x0c
45 #define DCS_RDDSDR              0x0f
46 #define DCS_SLEEP_IN            0x10
47 #define DCS_SLEEP_OUT           0x11
48 #define DCS_DISPLAY_OFF         0x28
49 #define DCS_DISPLAY_ON          0x29
50 #define DCS_COLUMN_ADDR         0x2a
51 #define DCS_PAGE_ADDR           0x2b
52 #define DCS_MEMORY_WRITE        0x2c
53 #define DCS_TEAR_OFF            0x34
54 #define DCS_TEAR_ON             0x35
55 #define DCS_MEM_ACC_CTRL        0x36
56 #define DCS_PIXEL_FORMAT        0x3a
57 #define DCS_BRIGHTNESS          0x51
58 #define DCS_CTRL_DISPLAY        0x53
59 #define DCS_WRITE_CABC          0x55
60 #define DCS_READ_CABC           0x56
61 #define DCS_GET_ID1             0xda
62 #define DCS_GET_ID2             0xdb
63 #define DCS_GET_ID3             0xdc
64
65 /* #define TAAL_USE_ESD_CHECK */
66 #define TAAL_ESD_CHECK_PERIOD   msecs_to_jiffies(5000)
67
68 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
69
70 struct taal_data {
71         struct mutex lock;
72
73         struct backlight_device *bldev;
74
75         unsigned long   hw_guard_end;   /* next value of jiffies when we can
76                                          * issue the next sleep in/out command
77                                          */
78         unsigned long   hw_guard_wait;  /* max guard time in jiffies */
79
80         struct omap_dss_device *dssdev;
81
82         bool enabled;
83         u8 rotate;
84         bool mirror;
85
86         bool te_enabled;
87         bool use_ext_te;
88         struct completion te_completion;
89
90         bool use_dsi_bl;
91
92         bool cabc_broken;
93         unsigned cabc_mode;
94
95         bool intro_printed;
96
97         struct workqueue_struct *esd_wq;
98         struct delayed_work esd_work;
99 };
100
101 static void taal_esd_work(struct work_struct *work);
102
103 static void hw_guard_start(struct taal_data *td, int guard_msec)
104 {
105         td->hw_guard_wait = msecs_to_jiffies(guard_msec);
106         td->hw_guard_end = jiffies + td->hw_guard_wait;
107 }
108
109 static void hw_guard_wait(struct taal_data *td)
110 {
111         unsigned long wait = td->hw_guard_end - jiffies;
112
113         if ((long)wait > 0 && wait <= td->hw_guard_wait) {
114                 set_current_state(TASK_UNINTERRUPTIBLE);
115                 schedule_timeout(wait);
116         }
117 }
118
119 static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
120 {
121         int r;
122         u8 buf[1];
123
124         r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1);
125
126         if (r < 0)
127                 return r;
128
129         *data = buf[0];
130
131         return 0;
132 }
133
134 static int taal_dcs_write_0(u8 dcs_cmd)
135 {
136         return dsi_vc_dcs_write(TCH, &dcs_cmd, 1);
137 }
138
139 static int taal_dcs_write_1(u8 dcs_cmd, u8 param)
140 {
141         u8 buf[2];
142         buf[0] = dcs_cmd;
143         buf[1] = param;
144         return dsi_vc_dcs_write(TCH, buf, 2);
145 }
146
147 static int taal_sleep_in(struct taal_data *td)
148
149 {
150         u8 cmd;
151         int r;
152
153         hw_guard_wait(td);
154
155         cmd = DCS_SLEEP_IN;
156         r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1);
157         if (r)
158                 return r;
159
160         hw_guard_start(td, 120);
161
162         msleep(5);
163
164         return 0;
165 }
166
167 static int taal_sleep_out(struct taal_data *td)
168 {
169         int r;
170
171         hw_guard_wait(td);
172
173         r = taal_dcs_write_0(DCS_SLEEP_OUT);
174         if (r)
175                 return r;
176
177         hw_guard_start(td, 120);
178
179         msleep(5);
180
181         return 0;
182 }
183
184 static int taal_get_id(u8 *id1, u8 *id2, u8 *id3)
185 {
186         int r;
187
188         r = taal_dcs_read_1(DCS_GET_ID1, id1);
189         if (r)
190                 return r;
191         r = taal_dcs_read_1(DCS_GET_ID2, id2);
192         if (r)
193                 return r;
194         r = taal_dcs_read_1(DCS_GET_ID3, id3);
195         if (r)
196                 return r;
197
198         return 0;
199 }
200
201 static int taal_set_addr_mode(u8 rotate, bool mirror)
202 {
203         int r;
204         u8 mode;
205         int b5, b6, b7;
206
207         r = taal_dcs_read_1(DCS_READ_MADCTL, &mode);
208         if (r)
209                 return r;
210
211         switch (rotate) {
212         default:
213         case 0:
214                 b7 = 0;
215                 b6 = 0;
216                 b5 = 0;
217                 break;
218         case 1:
219                 b7 = 0;
220                 b6 = 1;
221                 b5 = 1;
222                 break;
223         case 2:
224                 b7 = 1;
225                 b6 = 1;
226                 b5 = 0;
227                 break;
228         case 3:
229                 b7 = 1;
230                 b6 = 0;
231                 b5 = 1;
232                 break;
233         }
234
235         if (mirror)
236                 b6 = !b6;
237
238         mode &= ~((1<<7) | (1<<6) | (1<<5));
239         mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
240
241         return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode);
242 }
243
244 static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
245 {
246         int r;
247         u16 x1 = x;
248         u16 x2 = x + w - 1;
249         u16 y1 = y;
250         u16 y2 = y + h - 1;
251
252         u8 buf[5];
253         buf[0] = DCS_COLUMN_ADDR;
254         buf[1] = (x1 >> 8) & 0xff;
255         buf[2] = (x1 >> 0) & 0xff;
256         buf[3] = (x2 >> 8) & 0xff;
257         buf[4] = (x2 >> 0) & 0xff;
258
259         r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
260         if (r)
261                 return r;
262
263         buf[0] = DCS_PAGE_ADDR;
264         buf[1] = (y1 >> 8) & 0xff;
265         buf[2] = (y1 >> 0) & 0xff;
266         buf[3] = (y2 >> 8) & 0xff;
267         buf[4] = (y2 >> 0) & 0xff;
268
269         r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
270         if (r)
271                 return r;
272
273         dsi_vc_send_bta_sync(TCH);
274
275         return r;
276 }
277
278 static int taal_bl_update_status(struct backlight_device *dev)
279 {
280         struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
281         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
282         int r;
283         int level;
284
285         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
286                         dev->props.power == FB_BLANK_UNBLANK)
287                 level = dev->props.brightness;
288         else
289                 level = 0;
290
291         dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
292
293         mutex_lock(&td->lock);
294
295         if (td->use_dsi_bl) {
296                 if (td->enabled) {
297                         dsi_bus_lock();
298                         r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
299                         dsi_bus_unlock();
300                 } else {
301                         r = 0;
302                 }
303         } else {
304                 if (!dssdev->set_backlight)
305                         r = -EINVAL;
306                 else
307                         r = dssdev->set_backlight(dssdev, level);
308         }
309
310         mutex_unlock(&td->lock);
311
312         return r;
313 }
314
315 static int taal_bl_get_intensity(struct backlight_device *dev)
316 {
317         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
318                         dev->props.power == FB_BLANK_UNBLANK)
319                 return dev->props.brightness;
320
321         return 0;
322 }
323
324 static struct backlight_ops taal_bl_ops = {
325         .get_brightness = taal_bl_get_intensity,
326         .update_status  = taal_bl_update_status,
327 };
328
329 static void taal_get_timings(struct omap_dss_device *dssdev,
330                         struct omap_video_timings *timings)
331 {
332         *timings = dssdev->panel.timings;
333 }
334
335 static void taal_get_resolution(struct omap_dss_device *dssdev,
336                 u16 *xres, u16 *yres)
337 {
338         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
339
340         if (td->rotate == 0 || td->rotate == 2) {
341                 *xres = dssdev->panel.timings.x_res;
342                 *yres = dssdev->panel.timings.y_res;
343         } else {
344                 *yres = dssdev->panel.timings.x_res;
345                 *xres = dssdev->panel.timings.y_res;
346         }
347 }
348
349 static irqreturn_t taal_te_isr(int irq, void *data)
350 {
351         struct omap_dss_device *dssdev = data;
352         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
353
354         complete_all(&td->te_completion);
355
356         return IRQ_HANDLED;
357 }
358
359 static ssize_t taal_num_errors_show(struct device *dev,
360                 struct device_attribute *attr, char *buf)
361 {
362         struct omap_dss_device *dssdev = to_dss_device(dev);
363         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
364         u8 errors;
365         int r;
366
367         mutex_lock(&td->lock);
368
369         if (td->enabled) {
370                 dsi_bus_lock();
371                 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
372                 dsi_bus_unlock();
373         } else {
374                 r = -ENODEV;
375         }
376
377         mutex_unlock(&td->lock);
378
379         if (r)
380                 return r;
381
382         return snprintf(buf, PAGE_SIZE, "%d\n", errors);
383 }
384
385 static ssize_t taal_hw_revision_show(struct device *dev,
386                 struct device_attribute *attr, char *buf)
387 {
388         struct omap_dss_device *dssdev = to_dss_device(dev);
389         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
390         u8 id1, id2, id3;
391         int r;
392
393         mutex_lock(&td->lock);
394
395         if (td->enabled) {
396                 dsi_bus_lock();
397                 r = taal_get_id(&id1, &id2, &id3);
398                 dsi_bus_unlock();
399         } else {
400                 r = -ENODEV;
401         }
402
403         mutex_unlock(&td->lock);
404
405         if (r)
406                 return r;
407
408         return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
409 }
410
411 static const char *cabc_modes[] = {
412         "off",          /* used also always when CABC is not supported */
413         "ui",
414         "still-image",
415         "moving-image",
416 };
417
418 static ssize_t show_cabc_mode(struct device *dev,
419                 struct device_attribute *attr,
420                 char *buf)
421 {
422         struct omap_dss_device *dssdev = to_dss_device(dev);
423         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
424         const char *mode_str;
425         int mode;
426         int len;
427
428         mode = td->cabc_mode;
429
430         mode_str = "unknown";
431         if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
432                 mode_str = cabc_modes[mode];
433         len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
434
435         return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
436 }
437
438 static ssize_t store_cabc_mode(struct device *dev,
439                 struct device_attribute *attr,
440                 const char *buf, size_t count)
441 {
442         struct omap_dss_device *dssdev = to_dss_device(dev);
443         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
444         int i;
445
446         for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
447                 if (sysfs_streq(cabc_modes[i], buf))
448                         break;
449         }
450
451         if (i == ARRAY_SIZE(cabc_modes))
452                 return -EINVAL;
453
454         mutex_lock(&td->lock);
455
456         if (td->enabled) {
457                 dsi_bus_lock();
458                 if (!td->cabc_broken)
459                         taal_dcs_write_1(DCS_WRITE_CABC, i);
460                 dsi_bus_unlock();
461         }
462
463         td->cabc_mode = i;
464
465         mutex_unlock(&td->lock);
466
467         return count;
468 }
469
470 static ssize_t show_cabc_available_modes(struct device *dev,
471                 struct device_attribute *attr,
472                 char *buf)
473 {
474         int len;
475         int i;
476
477         for (i = 0, len = 0;
478              len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
479                 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
480                         i ? " " : "", cabc_modes[i],
481                         i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
482
483         return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
484 }
485
486 static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
487 static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
488 static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
489                 show_cabc_mode, store_cabc_mode);
490 static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
491                 show_cabc_available_modes, NULL);
492
493 static struct attribute *taal_attrs[] = {
494         &dev_attr_num_dsi_errors.attr,
495         &dev_attr_hw_revision.attr,
496         &dev_attr_cabc_mode.attr,
497         &dev_attr_cabc_available_modes.attr,
498         NULL,
499 };
500
501 static struct attribute_group taal_attr_group = {
502         .attrs = taal_attrs,
503 };
504
505 static void taal_hw_reset(struct omap_dss_device *dssdev)
506 {
507         if (dssdev->reset_gpio == -1)
508                 return;
509
510         gpio_set_value(dssdev->reset_gpio, 1);
511         udelay(10);
512         /* reset the panel */
513         gpio_set_value(dssdev->reset_gpio, 0);
514         /* assert reset for at least 10us */
515         udelay(10);
516         gpio_set_value(dssdev->reset_gpio, 1);
517         /* wait 5ms after releasing reset */
518         msleep(5);
519 }
520
521 static int taal_probe(struct omap_dss_device *dssdev)
522 {
523         struct backlight_properties props;
524         struct taal_data *td;
525         struct backlight_device *bldev;
526         int r;
527
528         const struct omap_video_timings taal_panel_timings = {
529                 .x_res          = 864,
530                 .y_res          = 480,
531         };
532
533         dev_dbg(&dssdev->dev, "probe\n");
534
535         dssdev->panel.config = OMAP_DSS_LCD_TFT;
536         dssdev->panel.timings = taal_panel_timings;
537         dssdev->ctrl.pixel_size = 24;
538
539         td = kzalloc(sizeof(*td), GFP_KERNEL);
540         if (!td) {
541                 r = -ENOMEM;
542                 goto err0;
543         }
544         td->dssdev = dssdev;
545
546         mutex_init(&td->lock);
547
548         td->esd_wq = create_singlethread_workqueue("taal_esd");
549         if (td->esd_wq == NULL) {
550                 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
551                 r = -ENOMEM;
552                 goto err1;
553         }
554         INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
555
556         dev_set_drvdata(&dssdev->dev, td);
557
558         taal_hw_reset(dssdev);
559
560         /* if no platform set_backlight() defined, presume DSI backlight
561          * control */
562         memset(&props, 0, sizeof(struct backlight_properties));
563         if (!dssdev->set_backlight)
564                 td->use_dsi_bl = true;
565
566         if (td->use_dsi_bl)
567                 props.max_brightness = 255;
568         else
569                 props.max_brightness = 127;
570         bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
571                                           &taal_bl_ops, &props);
572         if (IS_ERR(bldev)) {
573                 r = PTR_ERR(bldev);
574                 goto err2;
575         }
576
577         td->bldev = bldev;
578
579         bldev->props.fb_blank = FB_BLANK_UNBLANK;
580         bldev->props.power = FB_BLANK_UNBLANK;
581         if (td->use_dsi_bl)
582                 bldev->props.brightness = 255;
583         else
584                 bldev->props.brightness = 127;
585
586         taal_bl_update_status(bldev);
587
588         if (dssdev->phy.dsi.ext_te) {
589                 int gpio = dssdev->phy.dsi.ext_te_gpio;
590
591                 r = gpio_request(gpio, "taal irq");
592                 if (r) {
593                         dev_err(&dssdev->dev, "GPIO request failed\n");
594                         goto err3;
595                 }
596
597                 gpio_direction_input(gpio);
598
599                 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
600                                 IRQF_DISABLED | IRQF_TRIGGER_RISING,
601                                 "taal vsync", dssdev);
602
603                 if (r) {
604                         dev_err(&dssdev->dev, "IRQ request failed\n");
605                         gpio_free(gpio);
606                         goto err3;
607                 }
608
609                 init_completion(&td->te_completion);
610
611                 td->use_ext_te = true;
612         }
613
614         r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
615         if (r) {
616                 dev_err(&dssdev->dev, "failed to create sysfs files\n");
617                 goto err4;
618         }
619
620         return 0;
621 err4:
622         if (td->use_ext_te) {
623                 int gpio = dssdev->phy.dsi.ext_te_gpio;
624                 free_irq(gpio_to_irq(gpio), dssdev);
625                 gpio_free(gpio);
626         }
627 err3:
628         backlight_device_unregister(bldev);
629 err2:
630         cancel_delayed_work_sync(&td->esd_work);
631         destroy_workqueue(td->esd_wq);
632 err1:
633         kfree(td);
634 err0:
635         return r;
636 }
637
638 static void taal_remove(struct omap_dss_device *dssdev)
639 {
640         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
641         struct backlight_device *bldev;
642
643         dev_dbg(&dssdev->dev, "remove\n");
644
645         sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
646
647         if (td->use_ext_te) {
648                 int gpio = dssdev->phy.dsi.ext_te_gpio;
649                 free_irq(gpio_to_irq(gpio), dssdev);
650                 gpio_free(gpio);
651         }
652
653         bldev = td->bldev;
654         bldev->props.power = FB_BLANK_POWERDOWN;
655         taal_bl_update_status(bldev);
656         backlight_device_unregister(bldev);
657
658         cancel_delayed_work_sync(&td->esd_work);
659         destroy_workqueue(td->esd_wq);
660
661         /* reset, to be sure that the panel is in a valid state */
662         taal_hw_reset(dssdev);
663
664         kfree(td);
665 }
666
667 static int taal_power_on(struct omap_dss_device *dssdev)
668 {
669         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
670         u8 id1, id2, id3;
671         int r;
672
673         /* it seems we have to wait a bit until taal is ready */
674         msleep(5);
675
676         dsi_bus_lock();
677
678         r = omapdss_dsi_display_enable(dssdev);
679         if (r) {
680                 dev_err(&dssdev->dev, "failed to enable DSI\n");
681                 goto err0;
682         }
683
684         taal_hw_reset(dssdev);
685
686         omapdss_dsi_vc_enable_hs(TCH, false);
687
688         r = taal_sleep_out(td);
689         if (r)
690                 goto err;
691
692         r = taal_get_id(&id1, &id2, &id3);
693         if (r)
694                 goto err;
695
696         /* on early revisions CABC is broken */
697         if (id2 == 0x00 || id2 == 0xff || id2 == 0x81)
698                 td->cabc_broken = true;
699
700         taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
701         taal_dcs_write_1(DCS_CTRL_DISPLAY, (1<<2) | (1<<5)); /* BL | BCTRL */
702
703         taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
704
705         taal_set_addr_mode(td->rotate, td->mirror);
706         if (!td->cabc_broken)
707                 taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
708
709         taal_dcs_write_0(DCS_DISPLAY_ON);
710
711         r = _taal_enable_te(dssdev, td->te_enabled);
712         if (r)
713                 goto err;
714
715 #ifdef TAAL_USE_ESD_CHECK
716         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
717 #endif
718
719         td->enabled = 1;
720
721         if (!td->intro_printed) {
722                 dev_info(&dssdev->dev, "revision %02x.%02x.%02x\n",
723                                 id1, id2, id3);
724                 if (td->cabc_broken)
725                         dev_info(&dssdev->dev,
726                                         "old Taal version, CABC disabled\n");
727                 td->intro_printed = true;
728         }
729
730         omapdss_dsi_vc_enable_hs(TCH, true);
731
732         dsi_bus_unlock();
733
734         return 0;
735 err:
736         dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
737
738         taal_hw_reset(dssdev);
739
740         omapdss_dsi_display_disable(dssdev);
741 err0:
742         dsi_bus_unlock();
743
744         return r;
745 }
746
747 static void taal_power_off(struct omap_dss_device *dssdev)
748 {
749         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
750         int r;
751
752         dsi_bus_lock();
753
754         cancel_delayed_work(&td->esd_work);
755
756         r = taal_dcs_write_0(DCS_DISPLAY_OFF);
757         if (!r) {
758                 r = taal_sleep_in(td);
759                 /* wait a bit so that the message goes through */
760                 msleep(10);
761         }
762
763         if (r) {
764                 dev_err(&dssdev->dev,
765                                 "error disabling panel, issuing HW reset\n");
766                 taal_hw_reset(dssdev);
767         }
768
769         omapdss_dsi_display_disable(dssdev);
770
771         td->enabled = 0;
772
773         dsi_bus_unlock();
774 }
775
776 static int taal_enable(struct omap_dss_device *dssdev)
777 {
778         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
779         int r;
780
781         dev_dbg(&dssdev->dev, "enable\n");
782
783         mutex_lock(&td->lock);
784
785         if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
786                 r = -EINVAL;
787                 goto err;
788         }
789
790         r = taal_power_on(dssdev);
791         if (r)
792                 goto err;
793
794         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
795
796         mutex_unlock(&td->lock);
797
798         return 0;
799 err:
800         dev_dbg(&dssdev->dev, "enable failed\n");
801         mutex_unlock(&td->lock);
802         return r;
803 }
804
805 static void taal_disable(struct omap_dss_device *dssdev)
806 {
807         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
808
809         dev_dbg(&dssdev->dev, "disable\n");
810
811         mutex_lock(&td->lock);
812
813         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
814                 taal_power_off(dssdev);
815
816         dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
817
818         mutex_unlock(&td->lock);
819 }
820
821 static int taal_suspend(struct omap_dss_device *dssdev)
822 {
823         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
824         int r;
825
826         dev_dbg(&dssdev->dev, "suspend\n");
827
828         mutex_lock(&td->lock);
829
830         if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
831                 r = -EINVAL;
832                 goto err;
833         }
834
835         taal_power_off(dssdev);
836         dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
837
838         mutex_unlock(&td->lock);
839
840         return 0;
841 err:
842         mutex_unlock(&td->lock);
843         return r;
844 }
845
846 static int taal_resume(struct omap_dss_device *dssdev)
847 {
848         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
849         int r;
850
851         dev_dbg(&dssdev->dev, "resume\n");
852
853         mutex_lock(&td->lock);
854
855         if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
856                 r = -EINVAL;
857                 goto err;
858         }
859
860         r = taal_power_on(dssdev);
861         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
862
863         mutex_unlock(&td->lock);
864
865         return r;
866 err:
867         mutex_unlock(&td->lock);
868         return r;
869 }
870
871 static void taal_framedone_cb(int err, void *data)
872 {
873         struct omap_dss_device *dssdev = data;
874         dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
875         dsi_bus_unlock();
876 }
877
878 static int taal_update(struct omap_dss_device *dssdev,
879                                     u16 x, u16 y, u16 w, u16 h)
880 {
881         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
882         int r;
883
884         dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
885
886         mutex_lock(&td->lock);
887         dsi_bus_lock();
888
889         if (!td->enabled) {
890                 r = 0;
891                 goto err;
892         }
893
894         r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h);
895         if (r)
896                 goto err;
897
898         r = taal_set_update_window(x, y, w, h);
899         if (r)
900                 goto err;
901
902         r = omap_dsi_update(dssdev, TCH, x, y, w, h,
903                         taal_framedone_cb, dssdev);
904         if (r)
905                 goto err;
906
907         /* note: no bus_unlock here. unlock is in framedone_cb */
908         mutex_unlock(&td->lock);
909         return 0;
910 err:
911         dsi_bus_unlock();
912         mutex_unlock(&td->lock);
913         return r;
914 }
915
916 static int taal_sync(struct omap_dss_device *dssdev)
917 {
918         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
919
920         dev_dbg(&dssdev->dev, "sync\n");
921
922         mutex_lock(&td->lock);
923         dsi_bus_lock();
924         dsi_bus_unlock();
925         mutex_unlock(&td->lock);
926
927         dev_dbg(&dssdev->dev, "sync done\n");
928
929         return 0;
930 }
931
932 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
933 {
934         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
935         int r;
936
937         td->te_enabled = enable;
938
939         if (enable)
940                 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
941         else
942                 r = taal_dcs_write_0(DCS_TEAR_OFF);
943
944         omapdss_dsi_enable_te(dssdev, enable);
945
946         /* XXX for some reason, DSI TE breaks if we don't wait here.
947          * Panel bug? Needs more studying */
948         msleep(100);
949
950         return r;
951 }
952
953 static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
954 {
955         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
956         int r;
957
958         mutex_lock(&td->lock);
959         dsi_bus_lock();
960
961         r = _taal_enable_te(dssdev, enable);
962
963         dsi_bus_unlock();
964         mutex_unlock(&td->lock);
965
966         return r;
967 }
968
969 static int taal_get_te(struct omap_dss_device *dssdev)
970 {
971         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
972         int r;
973
974         mutex_lock(&td->lock);
975         r = td->te_enabled;
976         mutex_unlock(&td->lock);
977
978         return r;
979 }
980
981 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
982 {
983         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
984         int r;
985
986         dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
987
988         mutex_lock(&td->lock);
989         dsi_bus_lock();
990
991         if (td->enabled) {
992                 r = taal_set_addr_mode(rotate, td->mirror);
993                 if (r)
994                         goto err;
995         }
996
997         td->rotate = rotate;
998
999         dsi_bus_unlock();
1000         mutex_unlock(&td->lock);
1001         return 0;
1002 err:
1003         dsi_bus_unlock();
1004         mutex_unlock(&td->lock);
1005         return r;
1006 }
1007
1008 static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1009 {
1010         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1011         int r;
1012
1013         mutex_lock(&td->lock);
1014         r = td->rotate;
1015         mutex_unlock(&td->lock);
1016
1017         return r;
1018 }
1019
1020 static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1021 {
1022         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1023         int r;
1024
1025         dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1026
1027         mutex_lock(&td->lock);
1028         dsi_bus_lock();
1029         if (td->enabled) {
1030                 r = taal_set_addr_mode(td->rotate, enable);
1031                 if (r)
1032                         goto err;
1033         }
1034
1035         td->mirror = enable;
1036
1037         dsi_bus_unlock();
1038         mutex_unlock(&td->lock);
1039         return 0;
1040 err:
1041         dsi_bus_unlock();
1042         mutex_unlock(&td->lock);
1043         return r;
1044 }
1045
1046 static bool taal_get_mirror(struct omap_dss_device *dssdev)
1047 {
1048         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1049         int r;
1050
1051         mutex_lock(&td->lock);
1052         r = td->mirror;
1053         mutex_unlock(&td->lock);
1054
1055         return r;
1056 }
1057
1058 static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1059 {
1060         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1061         u8 id1, id2, id3;
1062         int r;
1063
1064         mutex_lock(&td->lock);
1065         dsi_bus_lock();
1066
1067         r = taal_dcs_read_1(DCS_GET_ID1, &id1);
1068         if (r)
1069                 goto err;
1070         r = taal_dcs_read_1(DCS_GET_ID2, &id2);
1071         if (r)
1072                 goto err;
1073         r = taal_dcs_read_1(DCS_GET_ID3, &id3);
1074         if (r)
1075                 goto err;
1076
1077         dsi_bus_unlock();
1078         mutex_unlock(&td->lock);
1079         return 0;
1080 err:
1081         dsi_bus_unlock();
1082         mutex_unlock(&td->lock);
1083         return r;
1084 }
1085
1086 static int taal_memory_read(struct omap_dss_device *dssdev,
1087                 void *buf, size_t size,
1088                 u16 x, u16 y, u16 w, u16 h)
1089 {
1090         int r;
1091         int first = 1;
1092         int plen;
1093         unsigned buf_used = 0;
1094         struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1095
1096         if (size < w * h * 3)
1097                 return -ENOMEM;
1098
1099         mutex_lock(&td->lock);
1100
1101         if (!td->enabled) {
1102                 r = -ENODEV;
1103                 goto err1;
1104         }
1105
1106         size = min(w * h * 3,
1107                         dssdev->panel.timings.x_res *
1108                         dssdev->panel.timings.y_res * 3);
1109
1110         dsi_bus_lock();
1111
1112         /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1113          * use short packets. plen 32 works, but bigger packets seem to cause
1114          * an error. */
1115         if (size % 2)
1116                 plen = 1;
1117         else
1118                 plen = 2;
1119
1120         taal_set_update_window(x, y, w, h);
1121
1122         r = dsi_vc_set_max_rx_packet_size(TCH, plen);
1123         if (r)
1124                 goto err2;
1125
1126         while (buf_used < size) {
1127                 u8 dcs_cmd = first ? 0x2e : 0x3e;
1128                 first = 0;
1129
1130                 r = dsi_vc_dcs_read(TCH, dcs_cmd,
1131                                 buf + buf_used, size - buf_used);
1132
1133                 if (r < 0) {
1134                         dev_err(&dssdev->dev, "read error\n");
1135                         goto err3;
1136                 }
1137
1138                 buf_used += r;
1139
1140                 if (r < plen) {
1141                         dev_err(&dssdev->dev, "short read\n");
1142                         break;
1143                 }
1144
1145                 if (signal_pending(current)) {
1146                         dev_err(&dssdev->dev, "signal pending, "
1147                                         "aborting memory read\n");
1148                         r = -ERESTARTSYS;
1149                         goto err3;
1150                 }
1151         }
1152
1153         r = buf_used;
1154
1155 err3:
1156         dsi_vc_set_max_rx_packet_size(TCH, 1);
1157 err2:
1158         dsi_bus_unlock();
1159 err1:
1160         mutex_unlock(&td->lock);
1161         return r;
1162 }
1163
1164 static void taal_esd_work(struct work_struct *work)
1165 {
1166         struct taal_data *td = container_of(work, struct taal_data,
1167                         esd_work.work);
1168         struct omap_dss_device *dssdev = td->dssdev;
1169         u8 state1, state2;
1170         int r;
1171
1172         mutex_lock(&td->lock);
1173
1174         if (!td->enabled) {
1175                 mutex_unlock(&td->lock);
1176                 return;
1177         }
1178
1179         dsi_bus_lock();
1180
1181         r = taal_dcs_read_1(DCS_RDDSDR, &state1);
1182         if (r) {
1183                 dev_err(&dssdev->dev, "failed to read Taal status\n");
1184                 goto err;
1185         }
1186
1187         /* Run self diagnostics */
1188         r = taal_sleep_out(td);
1189         if (r) {
1190                 dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
1191                 goto err;
1192         }
1193
1194         r = taal_dcs_read_1(DCS_RDDSDR, &state2);
1195         if (r) {
1196                 dev_err(&dssdev->dev, "failed to read Taal status\n");
1197                 goto err;
1198         }
1199
1200         /* Each sleep out command will trigger a self diagnostic and flip
1201          * Bit6 if the test passes.
1202          */
1203         if (!((state1 ^ state2) & (1 << 6))) {
1204                 dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
1205                 goto err;
1206         }
1207         /* Self-diagnostics result is also shown on TE GPIO line. We need
1208          * to re-enable TE after self diagnostics */
1209         if (td->use_ext_te && td->te_enabled) {
1210                 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
1211                 if (r)
1212                         goto err;
1213         }
1214
1215         dsi_bus_unlock();
1216
1217         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
1218
1219         mutex_unlock(&td->lock);
1220         return;
1221 err:
1222         dev_err(&dssdev->dev, "performing LCD reset\n");
1223
1224         taal_power_off(dssdev);
1225         taal_hw_reset(dssdev);
1226         taal_power_on(dssdev);
1227
1228         dsi_bus_unlock();
1229
1230         queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
1231
1232         mutex_unlock(&td->lock);
1233 }
1234
1235 static int taal_set_update_mode(struct omap_dss_device *dssdev,
1236                 enum omap_dss_update_mode mode)
1237 {
1238         if (mode != OMAP_DSS_UPDATE_MANUAL)
1239                 return -EINVAL;
1240         return 0;
1241 }
1242
1243 static enum omap_dss_update_mode taal_get_update_mode(
1244                 struct omap_dss_device *dssdev)
1245 {
1246         return OMAP_DSS_UPDATE_MANUAL;
1247 }
1248
1249 static struct omap_dss_driver taal_driver = {
1250         .probe          = taal_probe,
1251         .remove         = taal_remove,
1252
1253         .enable         = taal_enable,
1254         .disable        = taal_disable,
1255         .suspend        = taal_suspend,
1256         .resume         = taal_resume,
1257
1258         .set_update_mode = taal_set_update_mode,
1259         .get_update_mode = taal_get_update_mode,
1260
1261         .update         = taal_update,
1262         .sync           = taal_sync,
1263
1264         .get_resolution = taal_get_resolution,
1265         .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1266
1267         .enable_te      = taal_enable_te,
1268         .get_te         = taal_get_te,
1269
1270         .set_rotate     = taal_rotate,
1271         .get_rotate     = taal_get_rotate,
1272         .set_mirror     = taal_mirror,
1273         .get_mirror     = taal_get_mirror,
1274         .run_test       = taal_run_test,
1275         .memory_read    = taal_memory_read,
1276
1277         .get_timings    = taal_get_timings,
1278
1279         .driver         = {
1280                 .name   = "taal",
1281                 .owner  = THIS_MODULE,
1282         },
1283 };
1284
1285 static int __init taal_init(void)
1286 {
1287         omap_dss_register_driver(&taal_driver);
1288
1289         return 0;
1290 }
1291
1292 static void __exit taal_exit(void)
1293 {
1294         omap_dss_unregister_driver(&taal_driver);
1295 }
1296
1297 module_init(taal_init);
1298 module_exit(taal_exit);
1299
1300 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1301 MODULE_DESCRIPTION("Taal Driver");
1302 MODULE_LICENSE("GPL");