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