aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/exynos/Kconfig22
-rw-r--r--drivers/video/exynos/Makefile6
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c600
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_common.c896
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_common.h46
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_lowlevel.c618
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_lowlevel.h112
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_regs.h149
10 files changed, 2452 insertions, 1 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6ca0c407c144..e61d7ce35595 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2411,7 +2411,7 @@ config FB_PUV3_UNIGFX
2411 2411
2412source "drivers/video/omap/Kconfig" 2412source "drivers/video/omap/Kconfig"
2413source "drivers/video/omap2/Kconfig" 2413source "drivers/video/omap2/Kconfig"
2414 2414source "drivers/video/exynos/Kconfig"
2415source "drivers/video/backlight/Kconfig" 2415source "drivers/video/backlight/Kconfig"
2416 2416
2417if VT 2417if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 142606814d98..274b04ebedec 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_VT) += console/
15obj-$(CONFIG_LOGO) += logo/ 15obj-$(CONFIG_LOGO) += logo/
16obj-y += backlight/ 16obj-y += backlight/
17 17
18obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
19
18obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 20obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
19obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o 21obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
20obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o 22obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
new file mode 100644
index 000000000000..645b8a597199
--- /dev/null
+++ b/drivers/video/exynos/Kconfig
@@ -0,0 +1,22 @@
1#
2# Exynos Video configuration
3#
4
5menuconfig EXYNOS_VIDEO
6 bool "Exynos Video driver support"
7 help
8 This enables support for EXYNOS Video device.
9
10if EXYNOS_VIDEO
11
12#
13# MIPI DSI driver
14#
15
16config EXYNOS_MIPI_DSI
17 bool "EXYNOS MIPI DSI driver support."
18 depends on (ARCH_S5PV210 || ARCH_EXYNOS)
19 help
20 This enables support for MIPI-DSI device.
21
22endif # EXYNOS_VIDEO
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
new file mode 100644
index 000000000000..a1ae82abd6b8
--- /dev/null
+++ b/drivers/video/exynos/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the exynos video drivers.
3#
4
5obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
6 exynos_mipi_dsi_lowlevel.o
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
new file mode 100644
index 000000000000..557091dc0e97
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -0,0 +1,600 @@
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
43struct 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
50static LIST_HEAD(dsim_ddi_list);
51
52static DEFINE_MUTEX(mipi_dsim_lock);
53
54static struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device
55 *pdev)
56{
57 return pdev->dev.platform_data;
58}
59
60static struct regulator_bulk_data supplies[] = {
61 { .supply = "vdd10", },
62 { .supply = "vdd18", },
63};
64
65static 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
76static 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. */
88static 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
112static 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
140static 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
182int 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
206struct 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
236out:
237 mutex_unlock(&mipi_dsim_lock);
238
239 return NULL;
240}
241
242int 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
266struct 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. */
319static 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
328static 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
456out:
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
465err_bind:
466 iounmap(dsim->reg_base);
467
468err_ioremap:
469 release_mem_region(dsim->res->start, resource_size(dsim->res));
470
471err_mem_region:
472 release_resource(dsim->res);
473
474err_platform_get:
475 clk_disable(dsim->clock);
476 clk_put(dsim->clock);
477err_clock_get:
478 kfree(dsim);
479
480err_platform_get_irq:
481 return ret;
482}
483
484static 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
519static 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
547static 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
585static 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
596module_platform_driver(exynos_mipi_dsi_driver);
597
598MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
599MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver");
600MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
new file mode 100644
index 000000000000..14909c1d3832
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -0,0 +1,896 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_common.c
2 *
3 * Samsung SoC MIPI-DSI common 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/mutex.h>
19#include <linux/wait.h>
20#include <linux/fs.h>
21#include <linux/mm.h>
22#include <linux/fb.h>
23#include <linux/ctype.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/memory.h>
27#include <linux/delay.h>
28#include <linux/kthread.h>
29
30#include <video/mipi_display.h>
31#include <video/exynos_mipi_dsim.h>
32
33#include <mach/map.h>
34
35#include "exynos_mipi_dsi_regs.h"
36#include "exynos_mipi_dsi_lowlevel.h"
37#include "exynos_mipi_dsi_common.h"
38
39#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(250)
40#define MIPI_RX_FIFO_READ_DONE 0x30800002
41#define MIPI_MAX_RX_FIFO 20
42#define MHZ (1000 * 1000)
43#define FIN_HZ (24 * MHZ)
44
45#define DFIN_PLL_MIN_HZ (6 * MHZ)
46#define DFIN_PLL_MAX_HZ (12 * MHZ)
47
48#define DFVCO_MIN_HZ (500 * MHZ)
49#define DFVCO_MAX_HZ (1000 * MHZ)
50
51#define TRY_GET_FIFO_TIMEOUT (5000 * 2)
52#define TRY_FIFO_CLEAR (10)
53
54/* MIPI-DSIM status types. */
55enum {
56 DSIM_STATE_INIT, /* should be initialized. */
57 DSIM_STATE_STOP, /* CPU and LCDC are LP mode. */
58 DSIM_STATE_HSCLKEN, /* HS clock was enabled. */
59 DSIM_STATE_ULPS
60};
61
62/* define DSI lane types. */
63enum {
64 DSIM_LANE_CLOCK = (1 << 0),
65 DSIM_LANE_DATA0 = (1 << 1),
66 DSIM_LANE_DATA1 = (1 << 2),
67 DSIM_LANE_DATA2 = (1 << 3),
68 DSIM_LANE_DATA3 = (1 << 4)
69};
70
71static unsigned int dpll_table[15] = {
72 100, 120, 170, 220, 270,
73 320, 390, 450, 510, 560,
74 640, 690, 770, 870, 950
75};
76
77irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
78{
79 unsigned int intsrc = 0;
80 unsigned int intmsk = 0;
81 struct mipi_dsim_device *dsim = NULL;
82
83 dsim = dev_id;
84 if (!dsim) {
85 dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n",
86 __func__);
87 return IRQ_HANDLED;
88 }
89
90 intsrc = exynos_mipi_dsi_read_interrupt(dsim);
91 intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
92
93 intmsk = ~(intmsk) & intsrc;
94
95 switch (intmsk) {
96 case INTMSK_RX_DONE:
97 complete(&dsim_rd_comp);
98 dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
99 break;
100 case INTMSK_FIFO_EMPTY:
101 complete(&dsim_wr_comp);
102 dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
103 break;
104 default:
105 break;
106 }
107
108 exynos_mipi_dsi_clear_interrupt(dsim, intmsk);
109
110 return IRQ_HANDLED;
111}
112
113/*
114 * write long packet to mipi dsi slave
115 * @dsim: mipi dsim device structure.
116 * @data0: packet data to send.
117 * @data1: size of packet data
118 */
119static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
120 const unsigned char *data0, unsigned int data_size)
121{
122 unsigned int data_cnt = 0, payload = 0;
123
124 /* in case that data count is more then 4 */
125 for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
126 /*
127 * after sending 4bytes per one time,
128 * send remainder data less then 4.
129 */
130 if ((data_size - data_cnt) < 4) {
131 if ((data_size - data_cnt) == 3) {
132 payload = data0[data_cnt] |
133 data0[data_cnt + 1] << 8 |
134 data0[data_cnt + 2] << 16;
135 dev_dbg(dsim->dev, "count = 3 payload = %x, %x %x %x\n",
136 payload, data0[data_cnt],
137 data0[data_cnt + 1],
138 data0[data_cnt + 2]);
139 } else if ((data_size - data_cnt) == 2) {
140 payload = data0[data_cnt] |
141 data0[data_cnt + 1] << 8;
142 dev_dbg(dsim->dev,
143 "count = 2 payload = %x, %x %x\n", payload,
144 data0[data_cnt],
145 data0[data_cnt + 1]);
146 } else if ((data_size - data_cnt) == 1) {
147 payload = data0[data_cnt];
148 }
149
150 exynos_mipi_dsi_wr_tx_data(dsim, payload);
151 /* send 4bytes per one time. */
152 } else {
153 payload = data0[data_cnt] |
154 data0[data_cnt + 1] << 8 |
155 data0[data_cnt + 2] << 16 |
156 data0[data_cnt + 3] << 24;
157
158 dev_dbg(dsim->dev,
159 "count = 4 payload = %x, %x %x %x %x\n",
160 payload, *(u8 *)(data0 + data_cnt),
161 data0[data_cnt + 1],
162 data0[data_cnt + 2],
163 data0[data_cnt + 3]);
164
165 exynos_mipi_dsi_wr_tx_data(dsim, payload);
166 }
167 }
168}
169
170int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
171 const unsigned char *data0, unsigned int data_size)
172{
173 unsigned int check_rx_ack = 0;
174
175 if (dsim->state == DSIM_STATE_ULPS) {
176 dev_err(dsim->dev, "state is ULPS.\n");
177
178 return -EINVAL;
179 }
180
181 /* FIXME!!! why does it need this delay? */
182 msleep(20);
183
184 mutex_lock(&dsim->lock);
185
186 switch (data_id) {
187 /* short packet types of packet types for command. */
188 case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
189 case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
190 case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
191 case MIPI_DSI_DCS_SHORT_WRITE:
192 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
193 case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
194 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
195 if (check_rx_ack) {
196 /* process response func should be implemented */
197 mutex_unlock(&dsim->lock);
198 return 0;
199 } else {
200 mutex_unlock(&dsim->lock);
201 return -EINVAL;
202 }
203
204 /* general command */
205 case MIPI_DSI_COLOR_MODE_OFF:
206 case MIPI_DSI_COLOR_MODE_ON:
207 case MIPI_DSI_SHUTDOWN_PERIPHERAL:
208 case MIPI_DSI_TURN_ON_PERIPHERAL:
209 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
210 if (check_rx_ack) {
211 /* process response func should be implemented. */
212 mutex_unlock(&dsim->lock);
213 return 0;
214 } else {
215 mutex_unlock(&dsim->lock);
216 return -EINVAL;
217 }
218
219 /* packet types for video data */
220 case MIPI_DSI_V_SYNC_START:
221 case MIPI_DSI_V_SYNC_END:
222 case MIPI_DSI_H_SYNC_START:
223 case MIPI_DSI_H_SYNC_END:
224 case MIPI_DSI_END_OF_TRANSMISSION:
225 mutex_unlock(&dsim->lock);
226 return 0;
227
228 /* long packet type and null packet */
229 case MIPI_DSI_NULL_PACKET:
230 case MIPI_DSI_BLANKING_PACKET:
231 mutex_unlock(&dsim->lock);
232 return 0;
233 case MIPI_DSI_GENERIC_LONG_WRITE:
234 case MIPI_DSI_DCS_LONG_WRITE:
235 {
236 unsigned int size, payload = 0;
237 INIT_COMPLETION(dsim_wr_comp);
238
239 size = data_size * 4;
240
241 /* if data count is less then 4, then send 3bytes data. */
242 if (data_size < 4) {
243 payload = data0[0] |
244 data0[1] << 8 |
245 data0[2] << 16;
246
247 exynos_mipi_dsi_wr_tx_data(dsim, payload);
248
249 dev_dbg(dsim->dev, "count = %d payload = %x,%x %x %x\n",
250 data_size, payload, data0[0],
251 data0[1], data0[2]);
252
253 /* in case that data count is more then 4 */
254 } else
255 exynos_mipi_dsi_long_data_wr(dsim, data0, data_size);
256
257 /* put data into header fifo */
258 exynos_mipi_dsi_wr_tx_header(dsim, data_id, data_size & 0xff,
259 (data_size & 0xff00) >> 8);
260
261 if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp,
262 MIPI_FIFO_TIMEOUT)) {
263 dev_warn(dsim->dev, "command write timeout.\n");
264 mutex_unlock(&dsim->lock);
265 return -EAGAIN;
266 }
267
268 if (check_rx_ack) {
269 /* process response func should be implemented. */
270 mutex_unlock(&dsim->lock);
271 return 0;
272 } else {
273 mutex_unlock(&dsim->lock);
274 return -EINVAL;
275 }
276 }
277
278 /* packet typo for video data */
279 case MIPI_DSI_PACKED_PIXEL_STREAM_16:
280 case MIPI_DSI_PACKED_PIXEL_STREAM_18:
281 case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
282 case MIPI_DSI_PACKED_PIXEL_STREAM_24:
283 if (check_rx_ack) {
284 /* process response func should be implemented. */
285 mutex_unlock(&dsim->lock);
286 return 0;
287 } else {
288 mutex_unlock(&dsim->lock);
289 return -EINVAL;
290 }
291 default:
292 dev_warn(dsim->dev,
293 "data id %x is not supported current DSI spec.\n",
294 data_id);
295
296 mutex_unlock(&dsim->lock);
297 return -EINVAL;
298 }
299
300 mutex_unlock(&dsim->lock);
301 return 0;
302}
303
304static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
305 unsigned int req_size, unsigned int rx_data, u8 *rx_buf)
306{
307 unsigned int rcv_pkt, i, j;
308 u16 rxsize;
309
310 /* for long packet */
311 rxsize = (u16)((rx_data & 0x00ffff00) >> 8);
312 dev_dbg(dsim->dev, "mipi dsi rx size : %d\n", rxsize);
313 if (rxsize != req_size) {
314 dev_dbg(dsim->dev,
315 "received size mismatch received: %d, requested: %d\n",
316 rxsize, req_size);
317 goto err;
318 }
319
320 for (i = 0; i < (rxsize >> 2); i++) {
321 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
322 dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
323 for (j = 0; j < 4; j++) {
324 rx_buf[(i * 4) + j] =
325 (u8)(rcv_pkt >> (j * 8)) & 0xff;
326 dev_dbg(dsim->dev, "received value : %02x\n",
327 (rcv_pkt >> (j * 8)) & 0xff);
328 }
329 }
330 if (rxsize % 4) {
331 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
332 dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
333 for (j = 0; j < (rxsize % 4); j++) {
334 rx_buf[(i * 4) + j] =
335 (u8)(rcv_pkt >> (j * 8)) & 0xff;
336 dev_dbg(dsim->dev, "received value : %02x\n",
337 (rcv_pkt >> (j * 8)) & 0xff);
338 }
339 }
340
341 return rxsize;
342
343err:
344 return -EINVAL;
345}
346
347static unsigned int exynos_mipi_dsi_response_size(unsigned int req_size)
348{
349 switch (req_size) {
350 case 1:
351 return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE;
352 case 2:
353 return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE;
354 default:
355 return MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE;
356 }
357}
358
359int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
360 unsigned int data0, unsigned int req_size, u8 *rx_buf)
361{
362 unsigned int rx_data, rcv_pkt, i;
363 u8 response = 0;
364 u16 rxsize;
365
366 if (dsim->state == DSIM_STATE_ULPS) {
367 dev_err(dsim->dev, "state is ULPS.\n");
368
369 return -EINVAL;
370 }
371
372 /* FIXME!!! */
373 msleep(20);
374
375 mutex_lock(&dsim->lock);
376 INIT_COMPLETION(dsim_rd_comp);
377 exynos_mipi_dsi_rd_tx_header(dsim,
378 MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, req_size);
379
380 response = exynos_mipi_dsi_response_size(req_size);
381
382 switch (data_id) {
383 case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
384 case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
385 case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
386 case MIPI_DSI_DCS_READ:
387 exynos_mipi_dsi_rd_tx_header(dsim,
388 data_id, data0);
389 /* process response func should be implemented. */
390 break;
391 default:
392 dev_warn(dsim->dev,
393 "data id %x is not supported current DSI spec.\n",
394 data_id);
395
396 return -EINVAL;
397 }
398
399 if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp,
400 MIPI_FIFO_TIMEOUT)) {
401 pr_err("RX done interrupt timeout\n");
402 mutex_unlock(&dsim->lock);
403 return 0;
404 }
405
406 msleep(20);
407
408 rx_data = exynos_mipi_dsi_rd_rx_fifo(dsim);
409
410 if ((u8)(rx_data & 0xff) != response) {
411 printk(KERN_ERR
412 "mipi dsi wrong response rx_data : %x, response:%x\n",
413 rx_data, response);
414 goto clear_rx_fifo;
415 }
416
417 if (req_size <= 2) {
418 /* for short packet */
419 for (i = 0; i < req_size; i++)
420 rx_buf[i] = (rx_data >> (8 + (i * 8))) & 0xff;
421 rxsize = req_size;
422 } else {
423 /* for long packet */
424 rxsize = exynos_mipi_dsi_long_data_rd(dsim, req_size, rx_data,
425 rx_buf);
426 if (rxsize != req_size)
427 goto clear_rx_fifo;
428 }
429
430 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
431
432 msleep(20);
433
434 if (rcv_pkt != MIPI_RX_FIFO_READ_DONE) {
435 dev_info(dsim->dev,
436 "Can't found RX FIFO READ DONE FLAG : %x\n", rcv_pkt);
437 goto clear_rx_fifo;
438 }
439
440 mutex_unlock(&dsim->lock);
441
442 return rxsize;
443
444clear_rx_fifo:
445 i = 0;
446 while (1) {
447 rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
448 if ((rcv_pkt == MIPI_RX_FIFO_READ_DONE)
449 || (i > MIPI_MAX_RX_FIFO))
450 break;
451 dev_dbg(dsim->dev,
452 "mipi dsi clear rx fifo : %08x\n", rcv_pkt);
453 i++;
454 }
455 dev_info(dsim->dev,
456 "mipi dsi rx done count : %d, rcv_pkt : %08x\n", i, rcv_pkt);
457
458 mutex_unlock(&dsim->lock);
459
460 return 0;
461}
462
463static int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim,
464 unsigned int enable)
465{
466 int sw_timeout;
467
468 if (enable) {
469 sw_timeout = 1000;
470
471 exynos_mipi_dsi_enable_pll(dsim, 1);
472 while (1) {
473 sw_timeout--;
474 if (exynos_mipi_dsi_is_pll_stable(dsim))
475 return 0;
476 if (sw_timeout == 0)
477 return -EINVAL;
478 }
479 } else
480 exynos_mipi_dsi_enable_pll(dsim, 0);
481
482 return 0;
483}
484
485static unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
486 unsigned int pre_divider, unsigned int main_divider,
487 unsigned int scaler)
488{
489 unsigned long dfin_pll, dfvco, dpll_out;
490 unsigned int i, freq_band = 0xf;
491
492 dfin_pll = (FIN_HZ / pre_divider);
493
494 /******************************************************
495 * Serial Clock(=ByteClk X 8) FreqBand[3:0] *
496 ******************************************************
497 * ~ 99.99 MHz 0000
498 * 100 ~ 119.99 MHz 0001
499 * 120 ~ 159.99 MHz 0010
500 * 160 ~ 199.99 MHz 0011
501 * 200 ~ 239.99 MHz 0100
502 * 140 ~ 319.99 MHz 0101
503 * 320 ~ 389.99 MHz 0110
504 * 390 ~ 449.99 MHz 0111
505 * 450 ~ 509.99 MHz 1000
506 * 510 ~ 559.99 MHz 1001
507 * 560 ~ 639.99 MHz 1010
508 * 640 ~ 689.99 MHz 1011
509 * 690 ~ 769.99 MHz 1100
510 * 770 ~ 869.99 MHz 1101
511 * 870 ~ 949.99 MHz 1110
512 * 950 ~ 1000 MHz 1111
513 ******************************************************/
514 if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
515 dev_warn(dsim->dev, "fin_pll range should be 6MHz ~ 12MHz\n");
516 exynos_mipi_dsi_enable_afc(dsim, 0, 0);
517 } else {
518 if (dfin_pll < 7 * MHZ)
519 exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
520 else if (dfin_pll < 8 * MHZ)
521 exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
522 else if (dfin_pll < 9 * MHZ)
523 exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
524 else if (dfin_pll < 10 * MHZ)
525 exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
526 else if (dfin_pll < 11 * MHZ)
527 exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
528 else
529 exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
530 }
531
532 dfvco = dfin_pll * main_divider;
533 dev_dbg(dsim->dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
534 dfvco, dfin_pll, main_divider);
535 if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
536 dev_warn(dsim->dev, "fvco range should be 500MHz ~ 1000MHz\n");
537
538 dpll_out = dfvco / (1 << scaler);
539 dev_dbg(dsim->dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
540 dpll_out, dfvco, scaler);
541
542 for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
543 if (dpll_out < dpll_table[i] * MHZ) {
544 freq_band = i;
545 break;
546 }
547 }
548
549 dev_dbg(dsim->dev, "freq_band = %d\n", freq_band);
550
551 exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
552
553 exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
554 exynos_mipi_dsi_prep_ctrl(dsim, 0);
555
556 /* Freq Band */
557 exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
558
559 /* Stable time */
560 exynos_mipi_dsi_pll_stable_time(dsim, dsim->dsim_config->pll_stable_time);
561
562 /* Enable PLL */
563 dev_dbg(dsim->dev, "FOUT of mipi dphy pll is %luMHz\n",
564 (dpll_out / MHZ));
565
566 return dpll_out;
567}
568
569static int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
570 unsigned int byte_clk_sel, unsigned int enable)
571{
572 unsigned int esc_div;
573 unsigned long esc_clk_error_rate;
574 unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
575
576 if (enable) {
577 dsim->e_clk_src = byte_clk_sel;
578
579 /* Escape mode clock and byte clock source */
580 exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
581
582 /* DPHY, DSIM Link : D-PHY clock out */
583 if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
584 hs_clk = exynos_mipi_dsi_change_pll(dsim,
585 dsim->dsim_config->p, dsim->dsim_config->m,
586 dsim->dsim_config->s);
587 if (hs_clk == 0) {
588 dev_err(dsim->dev,
589 "failed to get hs clock.\n");
590 return -EINVAL;
591 }
592
593 byte_clk = hs_clk / 8;
594 exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
595 exynos_mipi_dsi_pll_on(dsim, 1);
596 /* DPHY : D-PHY clock out, DSIM link : external clock out */
597 } else if (byte_clk_sel == DSIM_EXT_CLK_DIV8) {
598 dev_warn(dsim->dev, "this project is not support\n");
599 dev_warn(dsim->dev,
600 "external clock source for MIPI DSIM.\n");
601 } else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS) {
602 dev_warn(dsim->dev, "this project is not support\n");
603 dev_warn(dsim->dev,
604 "external clock source for MIPI DSIM\n");
605 }
606
607 /* escape clock divider */
608 esc_div = byte_clk / (dsim->dsim_config->esc_clk);
609 dev_dbg(dsim->dev,
610 "esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
611 esc_div, byte_clk, dsim->dsim_config->esc_clk);
612 if ((byte_clk / esc_div) >= (20 * MHZ) ||
613 (byte_clk / esc_div) >
614 dsim->dsim_config->esc_clk)
615 esc_div += 1;
616
617 escape_clk = byte_clk / esc_div;
618 dev_dbg(dsim->dev,
619 "escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
620 escape_clk, byte_clk, esc_div);
621
622 /* enable escape clock. */
623 exynos_mipi_dsi_enable_byte_clock(dsim, 1);
624
625 /* enable byte clk and escape clock */
626 exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
627 /* escape clock on lane */
628 exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
629 (DSIM_LANE_CLOCK | dsim->data_lane), 1);
630
631 dev_dbg(dsim->dev, "byte clock is %luMHz\n",
632 (byte_clk / MHZ));
633 dev_dbg(dsim->dev, "escape clock that user's need is %lu\n",
634 (dsim->dsim_config->esc_clk / MHZ));
635 dev_dbg(dsim->dev, "escape clock divider is %x\n", esc_div);
636 dev_dbg(dsim->dev, "escape clock is %luMHz\n",
637 ((byte_clk / esc_div) / MHZ));
638
639 if ((byte_clk / esc_div) > escape_clk) {
640 esc_clk_error_rate = escape_clk /
641 (byte_clk / esc_div);
642 dev_warn(dsim->dev, "error rate is %lu over.\n",
643 (esc_clk_error_rate / 100));
644 } else if ((byte_clk / esc_div) < (escape_clk)) {
645 esc_clk_error_rate = (byte_clk / esc_div) /
646 escape_clk;
647 dev_warn(dsim->dev, "error rate is %lu under.\n",
648 (esc_clk_error_rate / 100));
649 }
650 } else {
651 exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
652 (DSIM_LANE_CLOCK | dsim->data_lane), 0);
653 exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
654
655 /* disable escape clock. */
656 exynos_mipi_dsi_enable_byte_clock(dsim, 0);
657
658 if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
659 exynos_mipi_dsi_pll_on(dsim, 0);
660 }
661
662 return 0;
663}
664
665int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
666{
667 dsim->state = DSIM_STATE_INIT;
668
669 switch (dsim->dsim_config->e_no_data_lane) {
670 case DSIM_DATA_LANE_1:
671 dsim->data_lane = DSIM_LANE_DATA0;
672 break;
673 case DSIM_DATA_LANE_2:
674 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
675 break;
676 case DSIM_DATA_LANE_3:
677 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
678 DSIM_LANE_DATA2;
679 break;
680 case DSIM_DATA_LANE_4:
681 dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
682 DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
683 break;
684 default:
685 dev_info(dsim->dev, "data lane is invalid.\n");
686 return -EINVAL;
687 };
688
689 exynos_mipi_dsi_sw_reset(dsim);
690 exynos_mipi_dsi_func_reset(dsim);
691
692 exynos_mipi_dsi_dp_dn_swap(dsim, 0);
693
694 return 0;
695}
696
697void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim)
698{
699 unsigned int src = 0;
700
701 src = (INTSRC_SFR_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
702 exynos_mipi_dsi_set_interrupt(dsim, src, 1);
703
704 src = 0;
705 src = ~(INTMSK_RX_DONE | INTMSK_FIFO_EMPTY);
706 exynos_mipi_dsi_set_interrupt_mask(dsim, src, 1);
707}
708
709int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
710 unsigned int enable)
711{
712 /* enable only frame done interrupt */
713 exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
714
715 return 0;
716}
717
718void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
719 unsigned int enable)
720{
721
722 /* consider Main display and Sub display. */
723
724 exynos_mipi_dsi_set_main_stand_by(dsim, enable);
725}
726
727int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
728 struct mipi_dsim_config *dsim_config)
729{
730 struct mipi_dsim_platform_data *dsim_pd;
731 struct fb_videomode *timing;
732
733 dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
734 timing = (struct fb_videomode *)dsim_pd->lcd_panel_info;
735
736 /* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
737 if (dsim_config->e_interface == (u32) DSIM_VIDEO) {
738 if (dsim_config->auto_vertical_cnt == 0) {
739 exynos_mipi_dsi_set_main_disp_vporch(dsim,
740 dsim_config->cmd_allow,
741 timing->upper_margin,
742 timing->lower_margin);
743 exynos_mipi_dsi_set_main_disp_hporch(dsim,
744 timing->left_margin,
745 timing->right_margin);
746 exynos_mipi_dsi_set_main_disp_sync_area(dsim,
747 timing->vsync_len,
748 timing->hsync_len);
749 }
750 }
751
752 exynos_mipi_dsi_set_main_disp_resol(dsim, timing->xres,
753 timing->yres);
754
755 exynos_mipi_dsi_display_config(dsim, dsim_config);
756
757 dev_info(dsim->dev, "lcd panel ==> width = %d, height = %d\n",
758 timing->xres, timing->yres);
759
760 return 0;
761}
762
763int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
764{
765 unsigned int time_out = 100;
766
767 switch (dsim->state) {
768 case DSIM_STATE_INIT:
769 exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
770
771 /* dsi configuration */
772 exynos_mipi_dsi_init_config(dsim);
773 exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
774 exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
775
776 /* set clock configuration */
777 exynos_mipi_dsi_set_clock(dsim, dsim->dsim_config->e_byte_clk, 1);
778
779 /* check clock and data lane state are stop state */
780 while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
781 time_out--;
782 if (time_out == 0) {
783 dev_err(dsim->dev,
784 "DSI Master is not stop state.\n");
785 dev_err(dsim->dev,
786 "Check initialization process\n");
787
788 return -EINVAL;
789 }
790 }
791 if (time_out != 0) {
792 dev_info(dsim->dev,
793 "DSI Master driver has been completed.\n");
794 dev_info(dsim->dev, "DSI Master state is stop state\n");
795 }
796
797 dsim->state = DSIM_STATE_STOP;
798
799 /* BTA sequence counters */
800 exynos_mipi_dsi_set_stop_state_counter(dsim,
801 dsim->dsim_config->stop_holding_cnt);
802 exynos_mipi_dsi_set_bta_timeout(dsim,
803 dsim->dsim_config->bta_timeout);
804 exynos_mipi_dsi_set_lpdr_timeout(dsim,
805 dsim->dsim_config->rx_timeout);
806
807 return 0;
808 default:
809 dev_info(dsim->dev, "DSI Master is already init.\n");
810 return 0;
811 }
812
813 return 0;
814}
815
816int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
817{
818 if (dsim->state != DSIM_STATE_STOP) {
819 dev_warn(dsim->dev, "DSIM is not in stop state.\n");
820 return 0;
821 }
822
823 if (dsim->e_clk_src == DSIM_EXT_CLK_BYPASS) {
824 dev_warn(dsim->dev, "clock source is external bypass.\n");
825 return 0;
826 }
827
828 dsim->state = DSIM_STATE_HSCLKEN;
829
830 /* set LCDC and CPU transfer mode to HS. */
831 exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
832 exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
833 exynos_mipi_dsi_enable_hs_clock(dsim, 1);
834
835 return 0;
836}
837
838int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
839 unsigned int mode)
840{
841 if (mode) {
842 if (dsim->state != DSIM_STATE_HSCLKEN) {
843 dev_err(dsim->dev, "HS Clock lane is not enabled.\n");
844 return -EINVAL;
845 }
846
847 exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
848 } else {
849 if (dsim->state == DSIM_STATE_INIT || dsim->state ==
850 DSIM_STATE_ULPS) {
851 dev_err(dsim->dev,
852 "DSI Master is not STOP or HSDT state.\n");
853 return -EINVAL;
854 }
855
856 exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
857 }
858
859 return 0;
860}
861
862int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
863{
864 return _exynos_mipi_dsi_get_frame_done_status(dsim);
865}
866
867int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
868{
869 _exynos_mipi_dsi_clear_frame_done(dsim);
870
871 return 0;
872}
873
874int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
875 unsigned int val)
876{
877 int try = TRY_FIFO_CLEAR;
878
879 exynos_mipi_dsi_sw_reset_release(dsim);
880 exynos_mipi_dsi_func_reset(dsim);
881
882 do {
883 if (exynos_mipi_dsi_get_sw_reset_release(dsim)) {
884 exynos_mipi_dsi_init_interrupt(dsim);
885 dev_dbg(dsim->dev, "reset release done.\n");
886 return 0;
887 }
888 } while (--try);
889
890 dev_err(dsim->dev, "failed to clear dsim fifo.\n");
891 return -EAGAIN;
892}
893
894MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
895MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver");
896MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/exynos/exynos_mipi_dsi_common.h
new file mode 100644
index 000000000000..412552274df3
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.h
@@ -0,0 +1,46 @@
1/* linux/drivers/video/exynos_mipi_dsi_common.h
2 *
3 * Header file for Samsung SoC MIPI-DSI common 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#ifndef _EXYNOS_MIPI_DSI_COMMON_H
16#define _EXYNOS_MIPI_DSI_COMMON_H
17
18static DECLARE_COMPLETION(dsim_rd_comp);
19static DECLARE_COMPLETION(dsim_wr_comp);
20
21int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
22 const unsigned char *data0, unsigned int data_size);
23int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
24 unsigned int data0, unsigned int req_size, u8 *rx_buf);
25irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id);
26void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim);
27int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim);
28void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
29 unsigned int enable);
30int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
31 struct mipi_dsim_config *dsim_info);
32int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
33int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
34int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
35 unsigned int mode);
36int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
37 unsigned int enable);
38int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
39int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
40
41extern struct fb_info *registered_fb[FB_MAX] __read_mostly;
42
43int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
44 unsigned int val);
45
46#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
new file mode 100644
index 000000000000..0ef38ce72af6
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
@@ -0,0 +1,618 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
2 *
3 * Samsung SoC MIPI-DSI lowlevel 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/mutex.h>
19#include <linux/wait.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/ctype.h>
24#include <linux/io.h>
25
26#include <video/exynos_mipi_dsim.h>
27
28#include <mach/map.h>
29
30#include "exynos_mipi_dsi_regs.h"
31
32void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
33{
34 unsigned int reg;
35
36 reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
37
38 reg |= DSIM_FUNCRST;
39
40 writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
41}
42
43void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
44{
45 unsigned int reg;
46
47 reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
48
49 reg |= DSIM_SWRST;
50
51 writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
52}
53
54void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim)
55{
56 unsigned int reg;
57
58 reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
59
60 reg |= INTSRC_SW_RST_RELEASE;
61
62 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
63}
64
65int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim)
66{
67 return (readl(dsim->reg_base + EXYNOS_DSIM_INTSRC)) &
68 INTSRC_SW_RST_RELEASE;
69}
70
71unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim)
72{
73 unsigned int reg;
74
75 reg = readl(dsim->reg_base + EXYNOS_DSIM_INTMSK);
76
77 return reg;
78}
79
80void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
81 unsigned int mode, unsigned int mask)
82{
83 unsigned int reg = 0;
84
85 if (mask)
86 reg |= mode;
87 else
88 reg &= ~mode;
89
90 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTMSK);
91}
92
93void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
94 unsigned int cfg)
95{
96 unsigned int reg;
97
98 reg = readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
99
100 writel(reg & ~(cfg), dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
101 mdelay(10);
102 reg |= cfg;
103
104 writel(reg, dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
105}
106
107/*
108 * this function set PLL P, M and S value in D-PHY
109 */
110void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
111 unsigned int value)
112{
113 writel(DSIM_AFC_CTL(value), dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
114}
115
116void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
117 unsigned int enable)
118{
119 unsigned int reg;
120
121 reg = readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL);
122
123 reg &= ~DSIM_MAIN_STAND_BY;
124
125 if (enable)
126 reg |= DSIM_MAIN_STAND_BY;
127
128 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
129}
130
131void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
132 unsigned int width_resol, unsigned int height_resol)
133{
134 unsigned int reg;
135
136 /* standby should be set after configuration so set to not ready*/
137 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL)) &
138 ~(DSIM_MAIN_STAND_BY);
139 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
140
141 reg &= ~((0x7ff << 16) | (0x7ff << 0));
142 reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
143
144 reg |= DSIM_MAIN_STAND_BY;
145 writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
146}
147
148void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
149 unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
150{
151 unsigned int reg;
152
153 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MVPORCH)) &
154 ~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
155 (DSIM_MAIN_VBP_MASK));
156
157 reg |= (DSIM_CMD_ALLOW_SHIFT(cmd_allow & 0xf) |
158 DSIM_STABLE_VFP_SHIFT(vfront & 0x7ff) |
159 DSIM_MAIN_VBP_SHIFT(vback & 0x7ff));
160
161 writel(reg, dsim->reg_base + EXYNOS_DSIM_MVPORCH);
162}
163
164void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
165 unsigned int front, unsigned int back)
166{
167 unsigned int reg;
168
169 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MHPORCH)) &
170 ~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
171
172 reg |= DSIM_MAIN_HFP_SHIFT(front) | DSIM_MAIN_HBP_SHIFT(back);
173
174 writel(reg, dsim->reg_base + EXYNOS_DSIM_MHPORCH);
175}
176
177void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
178 unsigned int vert, unsigned int hori)
179{
180 unsigned int reg;
181
182 reg = (readl(dsim->reg_base + EXYNOS_DSIM_MSYNC)) &
183 ~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
184
185 reg |= (DSIM_MAIN_VSA_SHIFT(vert & 0x3ff) |
186 DSIM_MAIN_HSA_SHIFT(hori));
187
188 writel(reg, dsim->reg_base + EXYNOS_DSIM_MSYNC);
189}
190
191void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
192 unsigned int vert, unsigned int hori)
193{
194 unsigned int reg;
195
196 reg = (readl(dsim->reg_base + EXYNOS_DSIM_SDRESOL)) &
197 ~(DSIM_SUB_STANDY_MASK);
198
199 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
200
201 reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
202 reg |= (DSIM_SUB_VRESOL_SHIFT(vert & 0x7ff) |
203 DSIM_SUB_HRESOL_SHIFT(hori & 0x7ff));
204 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
205
206 reg |= DSIM_SUB_STANDY_SHIFT(1);
207 writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
208}
209
210void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
211{
212 struct mipi_dsim_config *dsim_config = dsim->dsim_config;
213
214 unsigned int cfg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
215 ~((1 << 28) | (0x1f << 20) | (0x3 << 5));
216
217 cfg = ((DSIM_AUTO_FLUSH(dsim_config->auto_flush)) |
218 (DSIM_EOT_DISABLE(dsim_config->eot_disable)) |
219 (DSIM_AUTO_MODE_SHIFT(dsim_config->auto_vertical_cnt)) |
220 (DSIM_HSE_MODE_SHIFT(dsim_config->hse)) |
221 (DSIM_HFP_MODE_SHIFT(dsim_config->hfp)) |
222 (DSIM_HBP_MODE_SHIFT(dsim_config->hbp)) |
223 (DSIM_HSA_MODE_SHIFT(dsim_config->hsa)) |
224 (DSIM_NUM_OF_DATALANE_SHIFT(dsim_config->e_no_data_lane)));
225
226 writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
227}
228
229void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
230 struct mipi_dsim_config *dsim_config)
231{
232 u32 reg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
233 ~((0x3 << 26) | (1 << 25) | (0x3 << 18) | (0x7 << 12) |
234 (0x3 << 16) | (0x7 << 8));
235
236 if (dsim_config->e_interface == DSIM_VIDEO)
237 reg |= (1 << 25);
238 else if (dsim_config->e_interface == DSIM_COMMAND)
239 reg &= ~(1 << 25);
240 else {
241 dev_err(dsim->dev, "unknown lcd type.\n");
242 return;
243 }
244
245 /* main lcd */
246 reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << 26 |
247 ((u8) (dsim_config->e_virtual_ch) & 0x3) << 18 |
248 ((u8) (dsim_config->e_pixel_format) & 0x7) << 12;
249
250 writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
251}
252
253void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
254 unsigned int enable)
255{
256 unsigned int reg;
257
258 reg = readl(dsim->reg_base + EXYNOS_DSIM_CONFIG);
259
260 if (enable)
261 reg |= DSIM_LANE_ENx(lane);
262 else
263 reg &= ~DSIM_LANE_ENx(lane);
264
265 writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
266}
267
268
269void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
270 unsigned int count)
271{
272 unsigned int cfg;
273
274 /* get the data lane number. */
275 cfg = DSIM_NUM_OF_DATALANE_SHIFT(count);
276
277 writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
278}
279
280void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
281 unsigned int afc_code)
282{
283 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
284
285 if (enable) {
286 reg |= (1 << 14);
287 reg &= ~(0x7 << 5);
288 reg |= (afc_code & 0x7) << 5;
289 } else
290 reg &= ~(1 << 14);
291
292 writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
293}
294
295void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
296 unsigned int enable)
297{
298 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
299 ~(DSIM_PLL_BYPASS_SHIFT(0x1));
300
301 reg |= DSIM_PLL_BYPASS_SHIFT(enable);
302
303 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
304}
305
306void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
307 unsigned int m, unsigned int s)
308{
309 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
310
311 reg |= ((p & 0x3f) << 13) | ((m & 0x1ff) << 4) | ((s & 0x7) << 1);
312
313 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
314}
315
316void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
317 unsigned int freq_band)
318{
319 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
320 ~(DSIM_FREQ_BAND_SHIFT(0x1f));
321
322 reg |= DSIM_FREQ_BAND_SHIFT(freq_band & 0x1f);
323
324 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
325}
326
327void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
328 unsigned int pre_divider, unsigned int main_divider,
329 unsigned int scaler)
330{
331 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
332 ~(0x7ffff << 1);
333
334 reg |= (pre_divider & 0x3f) << 13 | (main_divider & 0x1ff) << 4 |
335 (scaler & 0x7) << 1;
336
337 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
338}
339
340void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
341 unsigned int lock_time)
342{
343 writel(lock_time, dsim->reg_base + EXYNOS_DSIM_PLLTMR);
344}
345
346void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim, unsigned int enable)
347{
348 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
349 ~(DSIM_PLL_EN_SHIFT(0x1));
350
351 reg |= DSIM_PLL_EN_SHIFT(enable & 0x1);
352
353 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
354}
355
356void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
357 unsigned int src)
358{
359 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
360 ~(DSIM_BYTE_CLK_SRC_SHIFT(0x3));
361
362 reg |= (DSIM_BYTE_CLK_SRC_SHIFT(src));
363
364 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
365}
366
367void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
368 unsigned int enable)
369{
370 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
371 ~(DSIM_BYTE_CLKEN_SHIFT(0x1));
372
373 reg |= DSIM_BYTE_CLKEN_SHIFT(enable);
374
375 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
376}
377
378void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
379 unsigned int enable, unsigned int prs_val)
380{
381 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
382 ~(DSIM_ESC_CLKEN_SHIFT(0x1) | 0xffff);
383
384 reg |= DSIM_ESC_CLKEN_SHIFT(enable);
385 if (enable)
386 reg |= prs_val;
387
388 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
389}
390
391void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
392 unsigned int lane_sel, unsigned int enable)
393{
394 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
395
396 if (enable)
397 reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
398 else
399
400 reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
401
402 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
403}
404
405void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
406 unsigned int enable)
407{
408 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
409 ~(DSIM_FORCE_STOP_STATE_SHIFT(0x1));
410
411 reg |= (DSIM_FORCE_STOP_STATE_SHIFT(enable & 0x1));
412
413 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
414}
415
416unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
417{
418 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
419
420 /**
421 * check clock and data lane states.
422 * if MIPI-DSI controller was enabled at bootloader then
423 * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
424 * so it should be checked for two case.
425 */
426 if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
427 ((reg & DSIM_STOP_STATE_CLK) ||
428 (reg & DSIM_TX_READY_HS_CLK)))
429 return 1;
430
431 return 0;
432}
433
434void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
435 unsigned int cnt_val)
436{
437 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
438 ~(DSIM_STOP_STATE_CNT_SHIFT(0x7ff));
439
440 reg |= (DSIM_STOP_STATE_CNT_SHIFT(cnt_val & 0x7ff));
441
442 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
443}
444
445void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
446 unsigned int timeout)
447{
448 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
449 ~(DSIM_BTA_TOUT_SHIFT(0xff));
450
451 reg |= (DSIM_BTA_TOUT_SHIFT(timeout));
452
453 writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
454}
455
456void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
457 unsigned int timeout)
458{
459 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
460 ~(DSIM_LPDR_TOUT_SHIFT(0xffff));
461
462 reg |= (DSIM_LPDR_TOUT_SHIFT(timeout));
463
464 writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
465}
466
467void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
468 unsigned int lp)
469{
470 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
471
472 reg &= ~DSIM_CMD_LPDT_LP;
473
474 if (lp)
475 reg |= DSIM_CMD_LPDT_LP;
476
477 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
478}
479
480void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
481 unsigned int lp)
482{
483 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
484
485 reg &= ~DSIM_TX_LPDT_LP;
486
487 if (lp)
488 reg |= DSIM_TX_LPDT_LP;
489
490 writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
491}
492
493void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
494 unsigned int enable)
495{
496 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
497 ~(DSIM_TX_REQUEST_HSCLK_SHIFT(0x1));
498
499 reg |= DSIM_TX_REQUEST_HSCLK_SHIFT(enable);
500
501 writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
502}
503
504void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
505 unsigned int swap_en)
506{
507 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
508
509 reg &= ~(0x3 << 0);
510 reg |= (swap_en & 0x3) << 0;
511
512 writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
513}
514
515void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
516 unsigned int hs_zero)
517{
518 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
519 ~(0xf << 28);
520
521 reg |= ((hs_zero & 0xf) << 28);
522
523 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
524}
525
526void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
527{
528 unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
529 ~(0x7 << 20);
530
531 reg |= ((prep & 0x7) << 20);
532
533 writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
534}
535
536unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim)
537{
538 return readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
539}
540
541void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
542 unsigned int src)
543{
544 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
545
546 reg |= src;
547
548 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
549}
550
551void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
552 unsigned int src, unsigned int enable)
553{
554 unsigned int reg = 0;
555
556 if (enable)
557 reg |= src;
558 else
559 reg &= ~src;
560
561 writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
562}
563
564unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
565{
566 unsigned int reg;
567
568 reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
569
570 return reg & (1 << 31) ? 1 : 0;
571}
572
573unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
574{
575 return readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL) & ~(0x1f);
576}
577
578void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
579 unsigned int di, unsigned int data0, unsigned int data1)
580{
581 unsigned int reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
582
583 writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
584}
585
586void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
587 unsigned int di, unsigned int data0)
588{
589 unsigned int reg = (data0 << 8) | (di << 0);
590
591 writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
592}
593
594unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim)
595{
596 return readl(dsim->reg_base + EXYNOS_DSIM_RXFIFO);
597}
598
599unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
600{
601 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
602
603 return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
604}
605
606void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
607{
608 unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
609
610 writel(reg | INTSRC_FRAME_DONE, dsim->reg_base +
611 EXYNOS_DSIM_INTSRC);
612}
613
614void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
615 unsigned int tx_data)
616{
617 writel(tx_data, dsim->reg_base + EXYNOS_DSIM_PAYLOAD);
618}
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
new file mode 100644
index 000000000000..85460701c7ea
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
@@ -0,0 +1,112 @@
1/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
2 *
3 * Header file for Samsung SoC MIPI-DSI lowlevel 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#ifndef _EXYNOS_MIPI_DSI_LOWLEVEL_H
16#define _EXYNOS_MIPI_DSI_LOWLEVEL_H
17
18void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim);
19void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim);
20void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim);
21int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim);
22void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
23 unsigned int mode, unsigned int mask);
24void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
25 unsigned int count);
26void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
27 unsigned int cfg);
28void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
29 unsigned int value);
30void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
31 unsigned int value);
32void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
33 unsigned int enable);
34void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
35 unsigned int width_resol, unsigned int height_resol);
36void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
37 unsigned int cmd_allow, unsigned int vfront, unsigned int vback);
38void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
39 unsigned int front, unsigned int back);
40void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
41 unsigned int vert, unsigned int hori);
42void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
43 unsigned int vert, unsigned int hori);
44void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim);
45void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
46 struct mipi_dsim_config *dsim_config);
47void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
48 unsigned int count);
49void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
50 unsigned int enable);
51void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
52 unsigned int afc_code);
53void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
54 unsigned int enable);
55void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
56 unsigned int m, unsigned int s);
57void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
58 unsigned int freq_band);
59void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
60 unsigned int pre_divider, unsigned int main_divider,
61 unsigned int scaler);
62void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
63 unsigned int lock_time);
64void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
65 unsigned int enable);
66void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
67 unsigned int src);
68void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
69 unsigned int enable);
70void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
71 unsigned int enable, unsigned int prs_val);
72void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
73 unsigned int lane_sel, unsigned int enable);
74void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
75 unsigned int enable);
76unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim);
77void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
78 unsigned int cnt_val);
79void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
80 unsigned int timeout);
81void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
82 unsigned int timeout);
83void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
84 unsigned int lp);
85void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
86 unsigned int lp);
87void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
88 unsigned int enable);
89void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
90 unsigned int swap_en);
91void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
92 unsigned int hs_zero);
93void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep);
94unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim);
95unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim);
96void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
97 unsigned int src);
98void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
99 unsigned int src, unsigned int enable);
100unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim);
101unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim);
102unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
103void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
104void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim, unsigned int di,
105 unsigned int data0, unsigned int data1);
106void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
107 unsigned int tx_data);
108void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
109 unsigned int data0, unsigned int data1);
110unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim);
111
112#endif /* _EXYNOS_MIPI_DSI_LOWLEVEL_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/exynos/exynos_mipi_dsi_regs.h
new file mode 100644
index 000000000000..4227106d3fd0
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_regs.h
@@ -0,0 +1,149 @@
1/* linux/driver/video/exynos/exynos_mipi_dsi_regs.h
2 *
3 * Register definition file for Samsung 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#ifndef _EXYNOS_MIPI_DSI_REGS_H
16#define _EXYNOS_MIPI_DSI_REGS_H
17
18#define EXYNOS_DSIM_STATUS 0x0 /* Status register */
19#define EXYNOS_DSIM_SWRST 0x4 /* Software reset register */
20#define EXYNOS_DSIM_CLKCTRL 0x8 /* Clock control register */
21#define EXYNOS_DSIM_TIMEOUT 0xc /* Time out register */
22#define EXYNOS_DSIM_CONFIG 0x10 /* Configuration register */
23#define EXYNOS_DSIM_ESCMODE 0x14 /* Escape mode register */
24
25/* Main display image resolution register */
26#define EXYNOS_DSIM_MDRESOL 0x18
27#define EXYNOS_DSIM_MVPORCH 0x1c /* Main display Vporch register */
28#define EXYNOS_DSIM_MHPORCH 0x20 /* Main display Hporch register */
29#define EXYNOS_DSIM_MSYNC 0x24 /* Main display sync area register */
30
31/* Sub display image resolution register */
32#define EXYNOS_DSIM_SDRESOL 0x28
33#define EXYNOS_DSIM_INTSRC 0x2c /* Interrupt source register */
34#define EXYNOS_DSIM_INTMSK 0x30 /* Interrupt mask register */
35#define EXYNOS_DSIM_PKTHDR 0x34 /* Packet Header FIFO register */
36#define EXYNOS_DSIM_PAYLOAD 0x38 /* Payload FIFO register */
37#define EXYNOS_DSIM_RXFIFO 0x3c /* Read FIFO register */
38#define EXYNOS_DSIM_FIFOTHLD 0x40 /* FIFO threshold level register */
39#define EXYNOS_DSIM_FIFOCTRL 0x44 /* FIFO status and control register */
40
41/* FIFO memory AC characteristic register */
42#define EXYNOS_DSIM_PLLCTRL 0x4c /* PLL control register */
43#define EXYNOS_DSIM_PLLTMR 0x50 /* PLL timer register */
44#define EXYNOS_DSIM_PHYACCHR 0x54 /* D-PHY AC characteristic register */
45#define EXYNOS_DSIM_PHYACCHR1 0x58 /* D-PHY AC characteristic register1 */
46
47/* DSIM_STATUS */
48#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
49#define DSIM_STOP_STATE_CLK (1 << 8)
50#define DSIM_TX_READY_HS_CLK (1 << 10)
51
52/* DSIM_SWRST */
53#define DSIM_FUNCRST (1 << 16)
54#define DSIM_SWRST (1 << 0)
55
56/* EXYNOS_DSIM_TIMEOUT */
57#define DSIM_LPDR_TOUT_SHIFT(x) ((x) << 0)
58#define DSIM_BTA_TOUT_SHIFT(x) ((x) << 16)
59
60/* EXYNOS_DSIM_CLKCTRL */
61#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << 19)
62#define DSIM_BYTE_CLKEN_SHIFT(x) ((x) << 24)
63#define DSIM_BYTE_CLK_SRC_SHIFT(x) ((x) << 25)
64#define DSIM_PLL_BYPASS_SHIFT(x) ((x) << 27)
65#define DSIM_ESC_CLKEN_SHIFT(x) ((x) << 28)
66#define DSIM_TX_REQUEST_HSCLK_SHIFT(x) ((x) << 31)
67
68/* EXYNOS_DSIM_CONFIG */
69#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0)
70#define DSIM_NUM_OF_DATALANE_SHIFT(x) ((x) << 5)
71#define DSIM_HSA_MODE_SHIFT(x) ((x) << 20)
72#define DSIM_HBP_MODE_SHIFT(x) ((x) << 21)
73#define DSIM_HFP_MODE_SHIFT(x) ((x) << 22)
74#define DSIM_HSE_MODE_SHIFT(x) ((x) << 23)
75#define DSIM_AUTO_MODE_SHIFT(x) ((x) << 24)
76#define DSIM_EOT_DISABLE(x) ((x) << 28)
77#define DSIM_AUTO_FLUSH(x) ((x) << 29)
78
79#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT)
80
81/* EXYNOS_DSIM_ESCMODE */
82#define DSIM_TX_LPDT_LP (1 << 6)
83#define DSIM_CMD_LPDT_LP (1 << 7)
84#define DSIM_FORCE_STOP_STATE_SHIFT(x) ((x) << 20)
85#define DSIM_STOP_STATE_CNT_SHIFT(x) ((x) << 21)
86
87/* EXYNOS_DSIM_MDRESOL */
88#define DSIM_MAIN_STAND_BY (1 << 31)
89#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
90#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
91
92/* EXYNOS_DSIM_MVPORCH */
93#define DSIM_CMD_ALLOW_SHIFT(x) ((x) << 28)
94#define DSIM_STABLE_VFP_SHIFT(x) ((x) << 16)
95#define DSIM_MAIN_VBP_SHIFT(x) ((x) << 0)
96#define DSIM_CMD_ALLOW_MASK (0xf << 28)
97#define DSIM_STABLE_VFP_MASK (0x7ff << 16)
98#define DSIM_MAIN_VBP_MASK (0x7ff << 0)
99
100/* EXYNOS_DSIM_MHPORCH */
101#define DSIM_MAIN_HFP_SHIFT(x) ((x) << 16)
102#define DSIM_MAIN_HBP_SHIFT(x) ((x) << 0)
103#define DSIM_MAIN_HFP_MASK ((0xffff) << 16)
104#define DSIM_MAIN_HBP_MASK ((0xffff) << 0)
105
106/* EXYNOS_DSIM_MSYNC */
107#define DSIM_MAIN_VSA_SHIFT(x) ((x) << 22)
108#define DSIM_MAIN_HSA_SHIFT(x) ((x) << 0)
109#define DSIM_MAIN_VSA_MASK ((0x3ff) << 22)
110#define DSIM_MAIN_HSA_MASK ((0xffff) << 0)
111
112/* EXYNOS_DSIM_SDRESOL */
113#define DSIM_SUB_STANDY_SHIFT(x) ((x) << 31)
114#define DSIM_SUB_VRESOL_SHIFT(x) ((x) << 16)
115#define DSIM_SUB_HRESOL_SHIFT(x) ((x) << 0)
116#define DSIM_SUB_STANDY_MASK ((0x1) << 31)
117#define DSIM_SUB_VRESOL_MASK ((0x7ff) << 16)
118#define DSIM_SUB_HRESOL_MASK ((0x7ff) << 0)
119
120/* EXYNOS_DSIM_INTSRC */
121#define INTSRC_PLL_STABLE (1 << 31)
122#define INTSRC_SW_RST_RELEASE (1 << 30)
123#define INTSRC_SFR_FIFO_EMPTY (1 << 29)
124#define INTSRC_FRAME_DONE (1 << 24)
125#define INTSRC_RX_DATA_DONE (1 << 18)
126
127/* EXYNOS_DSIM_INTMSK */
128#define INTMSK_FIFO_EMPTY (1 << 29)
129#define INTMSK_BTA (1 << 25)
130#define INTMSK_FRAME_DONE (1 << 24)
131#define INTMSK_RX_TIMEOUT (1 << 21)
132#define INTMSK_BTA_TIMEOUT (1 << 20)
133#define INTMSK_RX_DONE (1 << 18)
134#define INTMSK_RX_TE (1 << 17)
135#define INTMSK_RX_ACK (1 << 16)
136#define INTMSK_RX_ECC_ERR (1 << 15)
137#define INTMSK_RX_CRC_ERR (1 << 14)
138
139/* EXYNOS_DSIM_FIFOCTRL */
140#define SFR_HEADER_EMPTY (1 << 22)
141
142/* EXYNOS_DSIM_PHYACCHR */
143#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
144
145/* EXYNOS_DSIM_PLLCTRL */
146#define DSIM_PLL_EN_SHIFT(x) ((x) << 23)
147#define DSIM_FREQ_BAND_SHIFT(x) ((x) << 24)
148
149#endif /* _EXYNOS_MIPI_DSI_REGS_H */