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 
to_dsim_plat(struct platform_device * pdev)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 
exynos_mipi_regulator_enable(struct mipi_dsim_device * dsim)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 
exynos_mipi_regulator_disable(struct mipi_dsim_device * dsim)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. */
exynos_mipi_update_cfg(struct mipi_dsim_device * dsim)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 
exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device * dsim,int power)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 
exynos_mipi_dsi_blank_mode(struct mipi_dsim_device * dsim,int power)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 
exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device * lcd_dev)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 
exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver * lcd_drv)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 
exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver * lcd_drv)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 
exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device * dsim,const char * name)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 
exynos_mipi_dsi_probe(struct platform_device * pdev)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 
exynos_mipi_dsi_remove(struct platform_device * pdev)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
exynos_mipi_dsi_suspend(struct platform_device * pdev,pm_message_t state)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 
exynos_mipi_dsi_resume(struct platform_device * pdev)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");
601