Merge tag 'for-linus-3.5-20120601' of git://git.infradead.org/linux-mtd
[linux-2.6-microblaze.git] / drivers / video / exynos / exynos_mipi_dsi.c
1 /* linux/drivers/video/exynos/exynos_mipi_dsi.c
2  *
3  * Samsung SoC MIPI-DSIM driver.
4  *
5  * Copyright (c) 2012 Samsung Electronics Co., Ltd
6  *
7  * InKi Dae, <inki.dae@samsung.com>
8  * Donghwa Lee, <dh09.lee@samsung.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/clk.h>
19 #include <linux/mutex.h>
20 #include <linux/wait.h>
21 #include <linux/fs.h>
22 #include <linux/mm.h>
23 #include <linux/fb.h>
24 #include <linux/ctype.h>
25 #include <linux/platform_device.h>
26 #include <linux/io.h>
27 #include <linux/irq.h>
28 #include <linux/memory.h>
29 #include <linux/delay.h>
30 #include <linux/interrupt.h>
31 #include <linux/kthread.h>
32 #include <linux/notifier.h>
33 #include <linux/regulator/consumer.h>
34 #include <linux/pm_runtime.h>
35
36 #include <video/exynos_mipi_dsim.h>
37
38 #include <plat/fb.h>
39
40 #include "exynos_mipi_dsi_common.h"
41 #include "exynos_mipi_dsi_lowlevel.h"
42
43 struct mipi_dsim_ddi {
44         int                             bus_id;
45         struct list_head                list;
46         struct mipi_dsim_lcd_device     *dsim_lcd_dev;
47         struct mipi_dsim_lcd_driver     *dsim_lcd_drv;
48 };
49
50 static LIST_HEAD(dsim_ddi_list);
51
52 static DEFINE_MUTEX(mipi_dsim_lock);
53
54 static struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device
55                                                         *pdev)
56 {
57         return pdev->dev.platform_data;
58 }
59
60 static struct regulator_bulk_data supplies[] = {
61         { .supply = "vdd10", },
62         { .supply = "vdd18", },
63 };
64
65 static int exynos_mipi_regulator_enable(struct mipi_dsim_device *dsim)
66 {
67         int ret;
68
69         mutex_lock(&dsim->lock);
70         ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
71         mutex_unlock(&dsim->lock);
72
73         return ret;
74 }
75
76 static int exynos_mipi_regulator_disable(struct mipi_dsim_device *dsim)
77 {
78         int ret;
79
80         mutex_lock(&dsim->lock);
81         ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
82         mutex_unlock(&dsim->lock);
83
84         return ret;
85 }
86
87 /* update all register settings to MIPI DSI controller. */
88 static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim)
89 {
90         /*
91          * data from Display controller(FIMD) is not transferred in video mode
92          * but in case of command mode, all settings is not updated to
93          * registers.
94          */
95         exynos_mipi_dsi_stand_by(dsim, 0);
96
97         exynos_mipi_dsi_init_dsim(dsim);
98         exynos_mipi_dsi_init_link(dsim);
99
100         exynos_mipi_dsi_set_hs_enable(dsim);
101
102         /* set display timing. */
103         exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
104
105         /*
106          * data from Display controller(FIMD) is transferred in video mode
107          * but in case of command mode, all settigs is updated to registers.
108          */
109         exynos_mipi_dsi_stand_by(dsim, 1);
110 }
111
112 static int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim,
113                 int power)
114 {
115         struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
116         struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
117
118         switch (power) {
119         case FB_BLANK_POWERDOWN:
120                 if (dsim->suspended)
121                         return 0;
122
123                 if (client_drv && client_drv->suspend)
124                         client_drv->suspend(client_dev);
125
126                 clk_disable(dsim->clock);
127
128                 exynos_mipi_regulator_disable(dsim);
129
130                 dsim->suspended = true;
131
132                 break;
133         default:
134                 break;
135         }
136
137         return 0;
138 }
139
140 static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
141 {
142         struct platform_device *pdev = to_platform_device(dsim->dev);
143         struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
144         struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
145
146         switch (power) {
147         case FB_BLANK_UNBLANK:
148                 if (!dsim->suspended)
149                         return 0;
150
151                 /* lcd panel power on. */
152                 if (client_drv && client_drv->power_on)
153                         client_drv->power_on(client_dev, 1);
154
155                 exynos_mipi_regulator_disable(dsim);
156
157                 /* enable MIPI-DSI PHY. */
158                 if (dsim->pd->phy_enable)
159                         dsim->pd->phy_enable(pdev, true);
160
161                 clk_enable(dsim->clock);
162
163                 exynos_mipi_update_cfg(dsim);
164
165                 /* set lcd panel sequence commands. */
166                 if (client_drv && client_drv->set_sequence)
167                         client_drv->set_sequence(client_dev);
168
169                 dsim->suspended = false;
170
171                 break;
172         case FB_BLANK_NORMAL:
173                 /* TODO. */
174                 break;
175         default:
176                 break;
177         }
178
179         return 0;
180 }
181
182 int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
183 {
184         struct mipi_dsim_ddi *dsim_ddi;
185
186         if (!lcd_dev->name) {
187                 pr_err("dsim_lcd_device name is NULL.\n");
188                 return -EFAULT;
189         }
190
191         dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
192         if (!dsim_ddi) {
193                 pr_err("failed to allocate dsim_ddi object.\n");
194                 return -ENOMEM;
195         }
196
197         dsim_ddi->dsim_lcd_dev = lcd_dev;
198
199         mutex_lock(&mipi_dsim_lock);
200         list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
201         mutex_unlock(&mipi_dsim_lock);
202
203         return 0;
204 }
205
206 struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
207 {
208         struct mipi_dsim_ddi *dsim_ddi, *next;
209         struct mipi_dsim_lcd_device *lcd_dev;
210
211         mutex_lock(&mipi_dsim_lock);
212
213         list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
214                 if (!dsim_ddi)
215                         goto out;
216
217                 lcd_dev = dsim_ddi->dsim_lcd_dev;
218                 if (!lcd_dev)
219                         continue;
220
221                 if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
222                         /**
223                          * bus_id would be used to identify
224                          * connected bus.
225                          */
226                         dsim_ddi->bus_id = lcd_dev->bus_id;
227                         mutex_unlock(&mipi_dsim_lock);
228
229                         return dsim_ddi;
230                 }
231
232                 list_del(&dsim_ddi->list);
233                 kfree(dsim_ddi);
234         }
235
236 out:
237         mutex_unlock(&mipi_dsim_lock);
238
239         return NULL;
240 }
241
242 int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
243 {
244         struct mipi_dsim_ddi *dsim_ddi;
245
246         if (!lcd_drv->name) {
247                 pr_err("dsim_lcd_driver name is NULL.\n");
248                 return -EFAULT;
249         }
250
251         dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
252         if (!dsim_ddi) {
253                 pr_err("mipi_dsim_ddi object not found.\n");
254                 return -EFAULT;
255         }
256
257         dsim_ddi->dsim_lcd_drv = lcd_drv;
258
259         pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
260                 lcd_drv->name);
261
262         return 0;
263
264 }
265
266 struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
267                                                 const char *name)
268 {
269         struct mipi_dsim_ddi *dsim_ddi, *next;
270         struct mipi_dsim_lcd_driver *lcd_drv;
271         struct mipi_dsim_lcd_device *lcd_dev;
272         int ret;
273
274         mutex_lock(&dsim->lock);
275
276         list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
277                 lcd_drv = dsim_ddi->dsim_lcd_drv;
278                 lcd_dev = dsim_ddi->dsim_lcd_dev;
279                 if (!lcd_drv || !lcd_dev ||
280                         (dsim->id != dsim_ddi->bus_id))
281                                 continue;
282
283                 dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
284                                 lcd_drv->id, lcd_dev->id);
285                 dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
286                                 lcd_dev->bus_id, dsim->id);
287
288                 if ((strcmp(lcd_drv->name, name) == 0)) {
289                         lcd_dev->master = dsim;
290
291                         lcd_dev->dev.parent = dsim->dev;
292                         dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
293
294                         ret = device_register(&lcd_dev->dev);
295                         if (ret < 0) {
296                                 dev_err(dsim->dev,
297                                         "can't register %s, status %d\n",
298                                         dev_name(&lcd_dev->dev), ret);
299                                 mutex_unlock(&dsim->lock);
300
301                                 return NULL;
302                         }
303
304                         dsim->dsim_lcd_dev = lcd_dev;
305                         dsim->dsim_lcd_drv = lcd_drv;
306
307                         mutex_unlock(&dsim->lock);
308
309                         return dsim_ddi;
310                 }
311         }
312
313         mutex_unlock(&dsim->lock);
314
315         return NULL;
316 }
317
318 /* define MIPI-DSI Master operations. */
319 static struct mipi_dsim_master_ops master_ops = {
320         .cmd_read                       = exynos_mipi_dsi_rd_data,
321         .cmd_write                      = exynos_mipi_dsi_wr_data,
322         .get_dsim_frame_done            = exynos_mipi_dsi_get_frame_done_status,
323         .clear_dsim_frame_done          = exynos_mipi_dsi_clear_frame_done,
324         .set_early_blank_mode           = exynos_mipi_dsi_early_blank_mode,
325         .set_blank_mode                 = exynos_mipi_dsi_blank_mode,
326 };
327
328 static int exynos_mipi_dsi_probe(struct platform_device *pdev)
329 {
330         struct resource *res;
331         struct mipi_dsim_device *dsim;
332         struct mipi_dsim_config *dsim_config;
333         struct mipi_dsim_platform_data *dsim_pd;
334         struct mipi_dsim_ddi *dsim_ddi;
335         int ret = -EINVAL;
336
337         dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
338         if (!dsim) {
339                 dev_err(&pdev->dev, "failed to allocate dsim object.\n");
340                 return -ENOMEM;
341         }
342
343         dsim->pd = to_dsim_plat(pdev);
344         dsim->dev = &pdev->dev;
345         dsim->id = pdev->id;
346
347         /* get mipi_dsim_platform_data. */
348         dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
349         if (dsim_pd == NULL) {
350                 dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
351                 goto err_clock_get;
352         }
353         /* get mipi_dsim_config. */
354         dsim_config = dsim_pd->dsim_config;
355         if (dsim_config == NULL) {
356                 dev_err(&pdev->dev, "failed to get dsim config data.\n");
357                 goto err_clock_get;
358         }
359
360         dsim->dsim_config = dsim_config;
361         dsim->master_ops = &master_ops;
362
363         mutex_init(&dsim->lock);
364
365         ret = regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), supplies);
366         if (ret) {
367                 dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
368                 goto err_clock_get;
369         }
370
371         dsim->clock = clk_get(&pdev->dev, "dsim0");
372         if (IS_ERR(dsim->clock)) {
373                 dev_err(&pdev->dev, "failed to get dsim clock source\n");
374                 goto err_clock_get;
375         }
376
377         clk_enable(dsim->clock);
378
379         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
380         if (!res) {
381                 dev_err(&pdev->dev, "failed to get io memory region\n");
382                 goto err_platform_get;
383         }
384
385         dsim->res = request_mem_region(res->start, resource_size(res),
386                                         dev_name(&pdev->dev));
387         if (!dsim->res) {
388                 dev_err(&pdev->dev, "failed to request io memory region\n");
389                 ret = -ENOMEM;
390                 goto err_mem_region;
391         }
392
393         dsim->reg_base = ioremap(res->start, resource_size(res));
394         if (!dsim->reg_base) {
395                 dev_err(&pdev->dev, "failed to remap io region\n");
396                 ret = -ENOMEM;
397                 goto err_ioremap;
398         }
399
400         mutex_init(&dsim->lock);
401
402         /* bind lcd ddi matched with panel name. */
403         dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
404         if (!dsim_ddi) {
405                 dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
406                 goto err_bind;
407         }
408
409         dsim->irq = platform_get_irq(pdev, 0);
410         if (dsim->irq < 0) {
411                 dev_err(&pdev->dev, "failed to request dsim irq resource\n");
412                 ret = -EINVAL;
413                 goto err_platform_get_irq;
414         }
415
416         ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler,
417                         IRQF_SHARED, pdev->name, dsim);
418         if (ret != 0) {
419                 dev_err(&pdev->dev, "failed to request dsim irq\n");
420                 ret = -EINVAL;
421                 goto err_bind;
422         }
423
424         init_completion(&dsim_wr_comp);
425         init_completion(&dsim_rd_comp);
426
427         /* enable interrupt */
428         exynos_mipi_dsi_init_interrupt(dsim);
429
430         /* initialize mipi-dsi client(lcd panel). */
431         if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe)
432                 dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev);
433
434         /* in case that mipi got enabled at bootloader. */
435         if (dsim_pd->enabled)
436                 goto out;
437
438         /* lcd panel power on. */
439         if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on)
440                 dsim_ddi->dsim_lcd_drv->power_on(dsim_ddi->dsim_lcd_dev, 1);
441
442         exynos_mipi_regulator_enable(dsim);
443
444         /* enable MIPI-DSI PHY. */
445         if (dsim->pd->phy_enable)
446                 dsim->pd->phy_enable(pdev, true);
447
448         exynos_mipi_update_cfg(dsim);
449
450         /* set lcd panel sequence commands. */
451         if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->set_sequence)
452                 dsim_ddi->dsim_lcd_drv->set_sequence(dsim_ddi->dsim_lcd_dev);
453
454         dsim->suspended = false;
455
456 out:
457         platform_set_drvdata(pdev, dsim);
458
459         dev_dbg(&pdev->dev, "mipi-dsi driver(%s mode) has been probed.\n",
460                 (dsim_config->e_interface == DSIM_COMMAND) ?
461                         "CPU" : "RGB");
462
463         return 0;
464
465 err_bind:
466         iounmap(dsim->reg_base);
467
468 err_ioremap:
469         release_mem_region(dsim->res->start, resource_size(dsim->res));
470
471 err_mem_region:
472         release_resource(dsim->res);
473
474 err_platform_get:
475         clk_disable(dsim->clock);
476         clk_put(dsim->clock);
477 err_clock_get:
478         kfree(dsim);
479
480 err_platform_get_irq:
481         return ret;
482 }
483
484 static int __devexit exynos_mipi_dsi_remove(struct platform_device *pdev)
485 {
486         struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
487         struct mipi_dsim_ddi *dsim_ddi, *next;
488         struct mipi_dsim_lcd_driver *dsim_lcd_drv;
489
490         iounmap(dsim->reg_base);
491
492         clk_disable(dsim->clock);
493         clk_put(dsim->clock);
494
495         release_resource(dsim->res);
496         release_mem_region(dsim->res->start, resource_size(dsim->res));
497
498         list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
499                 if (dsim_ddi) {
500                         if (dsim->id != dsim_ddi->bus_id)
501                                 continue;
502
503                         dsim_lcd_drv = dsim_ddi->dsim_lcd_drv;
504
505                         if (dsim_lcd_drv->remove)
506                                 dsim_lcd_drv->remove(dsim_ddi->dsim_lcd_dev);
507
508                         kfree(dsim_ddi);
509                 }
510         }
511
512         regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
513         kfree(dsim);
514
515         return 0;
516 }
517
518 #ifdef CONFIG_PM
519 static int exynos_mipi_dsi_suspend(struct platform_device *pdev,
520                 pm_message_t state)
521 {
522         struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
523         struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
524         struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
525
526         disable_irq(dsim->irq);
527
528         if (dsim->suspended)
529                 return 0;
530
531         if (client_drv && client_drv->suspend)
532                 client_drv->suspend(client_dev);
533
534         /* enable MIPI-DSI PHY. */
535         if (dsim->pd->phy_enable)
536                 dsim->pd->phy_enable(pdev, false);
537
538         clk_disable(dsim->clock);
539
540         exynos_mipi_regulator_disable(dsim);
541
542         dsim->suspended = true;
543
544         return 0;
545 }
546
547 static int exynos_mipi_dsi_resume(struct platform_device *pdev)
548 {
549         struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
550         struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
551         struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
552
553         enable_irq(dsim->irq);
554
555         if (!dsim->suspended)
556                 return 0;
557
558         /* lcd panel power on. */
559         if (client_drv && client_drv->power_on)
560                 client_drv->power_on(client_dev, 1);
561
562         exynos_mipi_regulator_enable(dsim);
563
564         /* enable MIPI-DSI PHY. */
565         if (dsim->pd->phy_enable)
566                 dsim->pd->phy_enable(pdev, true);
567
568         clk_enable(dsim->clock);
569
570         exynos_mipi_update_cfg(dsim);
571
572         /* set lcd panel sequence commands. */
573         if (client_drv && client_drv->set_sequence)
574                 client_drv->set_sequence(client_dev);
575
576         dsim->suspended = false;
577
578         return 0;
579 }
580 #else
581 #define exynos_mipi_dsi_suspend NULL
582 #define exynos_mipi_dsi_resume NULL
583 #endif
584
585 static struct platform_driver exynos_mipi_dsi_driver = {
586         .probe = exynos_mipi_dsi_probe,
587         .remove = __devexit_p(exynos_mipi_dsi_remove),
588         .suspend = exynos_mipi_dsi_suspend,
589         .resume = exynos_mipi_dsi_resume,
590         .driver = {
591                    .name = "exynos-mipi-dsim",
592                    .owner = THIS_MODULE,
593         },
594 };
595
596 module_platform_driver(exynos_mipi_dsi_driver);
597
598 MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
599 MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver");
600 MODULE_LICENSE("GPL");