Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sh_mipi_dsi.c
Go to the documentation of this file.
1 /*
2  * Renesas SH-mobile MIPI DSI support
3  *
4  * Copyright (C) 2010 Guennadi Liakhovetski <[email protected]>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  */
10 
11 #include <linux/bitmap.h>
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/init.h>
15 #include <linux/io.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/slab.h>
19 #include <linux/string.h>
20 #include <linux/types.h>
21 #include <linux/module.h>
22 
23 #include <video/mipi_display.h>
24 #include <video/sh_mipi_dsi.h>
25 #include <video/sh_mobile_lcdc.h>
26 
27 #include "sh_mobile_lcdcfb.h"
28 
29 #define SYSCTRL 0x0000
30 #define SYSCONF 0x0004
31 #define TIMSET 0x0008
32 #define RESREQSET0 0x0018
33 #define RESREQSET1 0x001c
34 #define HSTTOVSET 0x0020
35 #define LPRTOVSET 0x0024
36 #define TATOVSET 0x0028
37 #define PRTOVSET 0x002c
38 #define DSICTRL 0x0030
39 #define DSIINTE 0x0060
40 #define PHYCTRL 0x0070
41 
42 /* relative to linkbase */
43 #define DTCTR 0x0000
44 #define VMCTR1 0x0020
45 #define VMCTR2 0x0024
46 #define VMLEN1 0x0028
47 #define VMLEN2 0x002c
48 #define CMTSRTREQ 0x0070
49 #define CMTSRTCTR 0x00d0
50 
51 /* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */
52 #define MAX_SH_MIPI_DSI 2
53 
54 struct sh_mipi {
56 
57  void __iomem *base;
59  struct clk *dsit_clk;
61 };
62 
63 #define to_sh_mipi(e) container_of(e, struct sh_mipi, entity)
64 
65 static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
66 
67 /* Protect the above array */
68 static DEFINE_MUTEX(array_lock);
69 
70 static struct sh_mipi *sh_mipi_by_handle(int handle)
71 {
72  if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0)
73  return NULL;
74 
75  return mipi_dsi[handle];
76 }
77 
78 static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd,
79  u8 cmd, u8 param)
80 {
81  u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8);
82  int cnt = 100;
83 
84  /* transmit a short packet to LCD panel */
85  iowrite32(1 | data, mipi->linkbase + CMTSRTCTR);
86  iowrite32(1, mipi->linkbase + CMTSRTREQ);
87 
88  while ((ioread32(mipi->linkbase + CMTSRTREQ) & 1) && --cnt)
89  udelay(1);
90 
91  return cnt ? 0 : -ETIMEDOUT;
92 }
93 
94 #define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \
95  -EINVAL : (c) - 1)
96 
97 static int sh_mipi_dcs(int handle, u8 cmd)
98 {
99  struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
100  if (!mipi)
101  return -ENODEV;
102  return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
103 }
104 
105 static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param)
106 {
107  struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
108  if (!mipi)
109  return -ENODEV;
110  return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd,
111  param);
112 }
113 
114 static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
115 {
116  /*
117  * enable LCDC data tx, transition to LPS after completion of each HS
118  * packet
119  */
120  iowrite32(0x00000002 | enable, mipi->linkbase + DTCTR);
121 }
122 
123 static void sh_mipi_shutdown(struct platform_device *pdev)
124 {
125  struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
126 
127  sh_mipi_dsi_enable(mipi, false);
128 }
129 
130 static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
131 {
132  void __iomem *base = mipi->base;
133  struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
134  u32 pctype, datatype, pixfmt, linelength, vmctr2;
135  u32 tmp, top, bottom, delay, div;
136  bool yuv;
137  int bpp;
138 
139  /*
140  * Select data format. MIPI DSI is not hot-pluggable, so, we just use
141  * the default videomode. If this ever becomes a problem, We'll have to
142  * move this to mipi_display_on() above and use info->var.xres
143  */
144  switch (pdata->data_format) {
145  case MIPI_RGB888:
146  pctype = 0;
148  pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
149  linelength = ch->lcd_modes[0].xres * 3;
150  yuv = false;
151  break;
152  case MIPI_RGB565:
153  pctype = 1;
155  pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
156  linelength = ch->lcd_modes[0].xres * 2;
157  yuv = false;
158  break;
159  case MIPI_RGB666_LP:
160  pctype = 2;
162  pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
163  linelength = ch->lcd_modes[0].xres * 3;
164  yuv = false;
165  break;
166  case MIPI_RGB666:
167  pctype = 3;
169  pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
170  linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
171  yuv = false;
172  break;
173  case MIPI_BGR888:
174  pctype = 8;
176  pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
177  linelength = ch->lcd_modes[0].xres * 3;
178  yuv = false;
179  break;
180  case MIPI_BGR565:
181  pctype = 9;
183  pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
184  linelength = ch->lcd_modes[0].xres * 2;
185  yuv = false;
186  break;
187  case MIPI_BGR666_LP:
188  pctype = 0xa;
190  pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
191  linelength = ch->lcd_modes[0].xres * 3;
192  yuv = false;
193  break;
194  case MIPI_BGR666:
195  pctype = 0xb;
197  pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
198  linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
199  yuv = false;
200  break;
201  case MIPI_YUYV:
202  pctype = 4;
204  pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
205  linelength = ch->lcd_modes[0].xres * 2;
206  yuv = true;
207  break;
208  case MIPI_UYVY:
209  pctype = 5;
211  pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
212  linelength = ch->lcd_modes[0].xres * 2;
213  yuv = true;
214  break;
215  case MIPI_YUV420_L:
216  pctype = 6;
218  pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
219  linelength = (ch->lcd_modes[0].xres * 12 + 7) / 8;
220  yuv = true;
221  break;
222  case MIPI_YUV420:
223  pctype = 7;
225  pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
226  /* Length of U/V line */
227  linelength = (ch->lcd_modes[0].xres + 1) / 2;
228  yuv = true;
229  break;
230  default:
231  return -EINVAL;
232  }
233 
234  if ((yuv && ch->interface_type != YUV422) ||
235  (!yuv && ch->interface_type != RGB24))
236  return -EINVAL;
237 
238  if (!pdata->lane)
239  return -EINVAL;
240 
241  /* reset DSI link */
242  iowrite32(0x00000001, base + SYSCTRL);
243  /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
244  udelay(50);
245  iowrite32(0x00000000, base + SYSCTRL);
246 
247  /* setup DSI link */
248 
249  /*
250  * T_wakeup = 0x7000
251  * T_hs-trail = 3
252  * T_hs-prepare = 3
253  * T_clk-trail = 3
254  * T_clk-prepare = 2
255  */
256  iowrite32(0x70003332, base + TIMSET);
257  /* no responses requested */
258  iowrite32(0x00000000, base + RESREQSET0);
259  /* request response to packets of type 0x28 */
260  iowrite32(0x00000100, base + RESREQSET1);
261  /* High-speed transmission timeout, default 0xffffffff */
262  iowrite32(0x0fffffff, base + HSTTOVSET);
263  /* LP reception timeout, default 0xffffffff */
264  iowrite32(0x0fffffff, base + LPRTOVSET);
265  /* Turn-around timeout, default 0xffffffff */
266  iowrite32(0x0fffffff, base + TATOVSET);
267  /* Peripheral reset timeout, default 0xffffffff */
268  iowrite32(0x0fffffff, base + PRTOVSET);
269  /* Interrupts not used, disable all */
270  iowrite32(0, base + DSIINTE);
271  /* DSI-Tx bias on */
272  iowrite32(0x00000001, base + PHYCTRL);
273  udelay(200);
274  /* Deassert resets, power on */
275  iowrite32(0x03070001 | pdata->phyctrl, base + PHYCTRL);
276 
277  /*
278  * Default = ULPS enable |
279  * Contention detection enabled |
280  * EoT packet transmission enable |
281  * CRC check enable |
282  * ECC check enable
283  */
284  bitmap_fill((unsigned long *)&tmp, pdata->lane);
285  tmp |= 0x00003700;
286  iowrite32(tmp, base + SYSCONF);
287 
288  /* setup l-bridge */
289 
290  /*
291  * Enable transmission of all packets,
292  * transmit LPS after each HS packet completion
293  */
294  iowrite32(0x00000006, mipi->linkbase + DTCTR);
295  /* VSYNC width = 2 (<< 17) */
296  iowrite32((ch->lcd_modes[0].vsync_len << pdata->vsynw_offset) |
297  (pdata->clksrc << 16) | (pctype << 12) | datatype,
298  mipi->linkbase + VMCTR1);
299 
300  /*
301  * Non-burst mode with sync pulses: VSE and HSE are output,
302  * HSA period allowed, no commands in LP
303  */
304  vmctr2 = 0;
305  if (pdata->flags & SH_MIPI_DSI_VSEE)
306  vmctr2 |= 1 << 23;
307  if (pdata->flags & SH_MIPI_DSI_HSEE)
308  vmctr2 |= 1 << 22;
309  if (pdata->flags & SH_MIPI_DSI_HSAE)
310  vmctr2 |= 1 << 21;
311  if (pdata->flags & SH_MIPI_DSI_BL2E)
312  vmctr2 |= 1 << 17;
313  if (pdata->flags & SH_MIPI_DSI_HSABM)
314  vmctr2 |= 1 << 5;
315  if (pdata->flags & SH_MIPI_DSI_HBPBM)
316  vmctr2 |= 1 << 4;
317  if (pdata->flags & SH_MIPI_DSI_HFPBM)
318  vmctr2 |= 1 << 3;
319  iowrite32(vmctr2, mipi->linkbase + VMCTR2);
320 
321  /*
322  * VMLEN1 = RGBLEN | HSALEN
323  *
324  * see
325  * Video mode - Blanking Packet setting
326  */
327  top = linelength << 16; /* RGBLEN */
328  bottom = 0x00000001;
329  if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
330  bottom = (pdata->lane * ch->lcd_modes[0].hsync_len) - 10;
331  iowrite32(top | bottom , mipi->linkbase + VMLEN1);
332 
333  /*
334  * VMLEN2 = HBPLEN | HFPLEN
335  *
336  * see
337  * Video mode - Blanking Packet setting
338  */
339  top = 0x00010000;
340  bottom = 0x00000001;
341  delay = 0;
342 
343  div = 1; /* HSbyteCLK is calculation base
344  * HS4divCLK = HSbyteCLK/2
345  * HS6divCLK is not supported for now */
346  if (pdata->flags & SH_MIPI_DSI_HS4divCLK)
347  div = 2;
348 
349  if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */
350  top = ch->lcd_modes[0].hsync_len + ch->lcd_modes[0].left_margin;
351  top = ((pdata->lane * top / div) - 10) << 16;
352  }
353  if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
354  bottom = ch->lcd_modes[0].right_margin;
355  bottom = (pdata->lane * bottom / div) - 12;
356  }
357 
358  bpp = linelength / ch->lcd_modes[0].xres; /* byte / pixel */
359  if ((pdata->lane / div) > bpp) {
360  tmp = ch->lcd_modes[0].xres / bpp; /* output cycle */
361  tmp = ch->lcd_modes[0].xres - tmp; /* (input - output) cycle */
362  delay = (pdata->lane * tmp);
363  }
364 
365  iowrite32(top | (bottom + delay) , mipi->linkbase + VMLEN2);
366 
367  msleep(5);
368 
369  /* setup LCD panel */
370 
371  /* cf. drivers/video/omap/lcd_mipid.c */
372  sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE);
373  msleep(120);
374  /*
375  * [7] - Page Address Mode
376  * [6] - Column Address Mode
377  * [5] - Page / Column Address Mode
378  * [4] - Display Device Line Refresh Order
379  * [3] - RGB/BGR Order
380  * [2] - Display Data Latch Data Order
381  * [1] - Flip Horizontal
382  * [0] - Flip Vertical
383  */
384  sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
385  /* cf. set_data_lines() */
386  sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT,
387  pixfmt << 4);
388  sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
389 
390  /* Enable timeout counters */
391  iowrite32(0x00000f00, base + DSICTRL);
392 
393  return 0;
394 }
395 
396 static int mipi_display_on(struct sh_mobile_lcdc_entity *entity)
397 {
398  struct sh_mipi *mipi = to_sh_mipi(entity);
399  struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
400  int ret;
401 
402  pm_runtime_get_sync(&mipi->pdev->dev);
403 
404  ret = pdata->set_dot_clock(mipi->pdev, mipi->base, 1);
405  if (ret < 0)
406  goto mipi_display_on_fail1;
407 
408  ret = sh_mipi_setup(mipi, pdata);
409  if (ret < 0)
410  goto mipi_display_on_fail2;
411 
412  sh_mipi_dsi_enable(mipi, true);
413 
415 
416 mipi_display_on_fail1:
417  pm_runtime_put_sync(&mipi->pdev->dev);
418 mipi_display_on_fail2:
419  pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
420 
421  return ret;
422 }
423 
424 static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
425 {
426  struct sh_mipi *mipi = to_sh_mipi(entity);
427  struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
428 
429  sh_mipi_dsi_enable(mipi, false);
430 
431  pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
432 
433  pm_runtime_put_sync(&mipi->pdev->dev);
434 }
435 
436 static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
437  .display_on = mipi_display_on,
438  .display_off = mipi_display_off,
439 };
440 
441 static int __init sh_mipi_probe(struct platform_device *pdev)
442 {
443  struct sh_mipi *mipi;
444  struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
445  struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447  unsigned long rate, f_current;
448  int idx = pdev->id, ret;
449 
450  if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
451  return -ENODEV;
452 
453  if (!pdata->set_dot_clock)
454  return -EINVAL;
455 
456  mutex_lock(&array_lock);
457  if (idx < 0)
458  for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
459  ;
460 
461  if (idx == ARRAY_SIZE(mipi_dsi)) {
462  ret = -EBUSY;
463  goto efindslot;
464  }
465 
466  mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
467  if (!mipi) {
468  ret = -ENOMEM;
469  goto ealloc;
470  }
471 
472  mipi->entity.owner = THIS_MODULE;
473  mipi->entity.ops = &mipi_ops;
474 
475  if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
476  dev_err(&pdev->dev, "MIPI register region already claimed\n");
477  ret = -EBUSY;
478  goto ereqreg;
479  }
480 
481  mipi->base = ioremap(res->start, resource_size(res));
482  if (!mipi->base) {
483  ret = -ENOMEM;
484  goto emap;
485  }
486 
487  if (!request_mem_region(res2->start, resource_size(res2), pdev->name)) {
488  dev_err(&pdev->dev, "MIPI register region 2 already claimed\n");
489  ret = -EBUSY;
490  goto ereqreg2;
491  }
492 
493  mipi->linkbase = ioremap(res2->start, resource_size(res2));
494  if (!mipi->linkbase) {
495  ret = -ENOMEM;
496  goto emap2;
497  }
498 
499  mipi->pdev = pdev;
500 
501  mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
502  if (IS_ERR(mipi->dsit_clk)) {
503  ret = PTR_ERR(mipi->dsit_clk);
504  goto eclktget;
505  }
506 
507  f_current = clk_get_rate(mipi->dsit_clk);
508  /* 80MHz required by the datasheet */
509  rate = clk_round_rate(mipi->dsit_clk, 80000000);
510  if (rate > 0 && rate != f_current)
511  ret = clk_set_rate(mipi->dsit_clk, rate);
512  else
513  ret = rate;
514  if (ret < 0)
515  goto esettrate;
516 
517  dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
518 
519  ret = clk_enable(mipi->dsit_clk);
520  if (ret < 0)
521  goto eclkton;
522 
523  mipi_dsi[idx] = mipi;
524 
525  pm_runtime_enable(&pdev->dev);
526  pm_runtime_resume(&pdev->dev);
527 
528  mutex_unlock(&array_lock);
529  platform_set_drvdata(pdev, &mipi->entity);
530 
531  return 0;
532 
533 eclkton:
534 esettrate:
535  clk_put(mipi->dsit_clk);
536 eclktget:
537  iounmap(mipi->linkbase);
538 emap2:
539  release_mem_region(res2->start, resource_size(res2));
540 ereqreg2:
541  iounmap(mipi->base);
542 emap:
543  release_mem_region(res->start, resource_size(res));
544 ereqreg:
545  kfree(mipi);
546 ealloc:
547 efindslot:
548  mutex_unlock(&array_lock);
549 
550  return ret;
551 }
552 
553 static int __devexit sh_mipi_remove(struct platform_device *pdev)
554 {
555  struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
556  struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
557  struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
558  int i, ret;
559 
560  mutex_lock(&array_lock);
561 
562  for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++)
563  ;
564 
565  if (i == ARRAY_SIZE(mipi_dsi)) {
566  ret = -EINVAL;
567  } else {
568  ret = 0;
569  mipi_dsi[i] = NULL;
570  }
571 
572  mutex_unlock(&array_lock);
573 
574  if (ret < 0)
575  return ret;
576 
577  pm_runtime_disable(&pdev->dev);
578  clk_disable(mipi->dsit_clk);
579  clk_put(mipi->dsit_clk);
580 
581  iounmap(mipi->linkbase);
582  if (res2)
583  release_mem_region(res2->start, resource_size(res2));
584  iounmap(mipi->base);
585  if (res)
586  release_mem_region(res->start, resource_size(res));
587  platform_set_drvdata(pdev, NULL);
588  kfree(mipi);
589 
590  return 0;
591 }
592 
593 static struct platform_driver sh_mipi_driver = {
594  .remove = __devexit_p(sh_mipi_remove),
595  .shutdown = sh_mipi_shutdown,
596  .driver = {
597  .name = "sh-mipi-dsi",
598  },
599 };
600 
601 static int __init sh_mipi_init(void)
602 {
603  return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe);
604 }
605 module_init(sh_mipi_init);
606 
607 static void __exit sh_mipi_exit(void)
608 {
609  platform_driver_unregister(&sh_mipi_driver);
610 }
611 module_exit(sh_mipi_exit);
612 
613 MODULE_AUTHOR("Guennadi Liakhovetski <[email protected]>");
614 MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
615 MODULE_LICENSE("GPL v2");