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