Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

Linux/drivers/video/sh_mipi_dsi.c

  1 /*
  2  * Renesas SH-mobile MIPI DSI support
  3  *
  4  * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  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 {
 55         struct sh_mobile_lcdc_entity entity;
 56 
 57         void __iomem    *base;
 58         void __iomem    *linkbase;
 59         struct clk      *dsit_clk;
 60         struct platform_device *pdev;
 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, const struct fb_videomode *mode)
131 {
132         void __iomem *base = mipi->base;
133         struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
134         u32 pctype, datatype, pixfmt, linelength, vmctr2;
135         u32 tmp, top, bottom, delay, div;
136         int bpp;
137 
138         /*
139          * Select data format. MIPI DSI is not hot-pluggable, so, we just use
140          * the default videomode. If this ever becomes a problem, We'll have to
141          * move this to mipi_display_on() above and use info->var.xres
142          */
143         switch (pdata->data_format) {
144         case MIPI_RGB888:
145                 pctype = 0;
146                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
147                 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
148                 linelength = mode->xres * 3;
149                 break;
150         case MIPI_RGB565:
151                 pctype = 1;
152                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
153                 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
154                 linelength = mode->xres * 2;
155                 break;
156         case MIPI_RGB666_LP:
157                 pctype = 2;
158                 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
159                 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
160                 linelength = mode->xres * 3;
161                 break;
162         case MIPI_RGB666:
163                 pctype = 3;
164                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
165                 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
166                 linelength = (mode->xres * 18 + 7) / 8;
167                 break;
168         case MIPI_BGR888:
169                 pctype = 8;
170                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
171                 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
172                 linelength = mode->xres * 3;
173                 break;
174         case MIPI_BGR565:
175                 pctype = 9;
176                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
177                 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
178                 linelength = mode->xres * 2;
179                 break;
180         case MIPI_BGR666_LP:
181                 pctype = 0xa;
182                 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
183                 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
184                 linelength = mode->xres * 3;
185                 break;
186         case MIPI_BGR666:
187                 pctype = 0xb;
188                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
189                 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
190                 linelength = (mode->xres * 18 + 7) / 8;
191                 break;
192         case MIPI_YUYV:
193                 pctype = 4;
194                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
195                 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
196                 linelength = mode->xres * 2;
197                 break;
198         case MIPI_UYVY:
199                 pctype = 5;
200                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
201                 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
202                 linelength = mode->xres * 2;
203                 break;
204         case MIPI_YUV420_L:
205                 pctype = 6;
206                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
207                 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
208                 linelength = (mode->xres * 12 + 7) / 8;
209                 break;
210         case MIPI_YUV420:
211                 pctype = 7;
212                 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
213                 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
214                 /* Length of U/V line */
215                 linelength = (mode->xres + 1) / 2;
216                 break;
217         default:
218                 return -EINVAL;
219         }
220 
221         if (!pdata->lane)
222                 return -EINVAL;
223 
224         /* reset DSI link */
225         iowrite32(0x00000001, base + SYSCTRL);
226         /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
227         udelay(50);
228         iowrite32(0x00000000, base + SYSCTRL);
229 
230         /* setup DSI link */
231 
232         /*
233          * T_wakeup = 0x7000
234          * T_hs-trail = 3
235          * T_hs-prepare = 3
236          * T_clk-trail = 3
237          * T_clk-prepare = 2
238          */
239         iowrite32(0x70003332, base + TIMSET);
240         /* no responses requested */
241         iowrite32(0x00000000, base + RESREQSET0);
242         /* request response to packets of type 0x28 */
243         iowrite32(0x00000100, base + RESREQSET1);
244         /* High-speed transmission timeout, default 0xffffffff */
245         iowrite32(0x0fffffff, base + HSTTOVSET);
246         /* LP reception timeout, default 0xffffffff */
247         iowrite32(0x0fffffff, base + LPRTOVSET);
248         /* Turn-around timeout, default 0xffffffff */
249         iowrite32(0x0fffffff, base + TATOVSET);
250         /* Peripheral reset timeout, default 0xffffffff */
251         iowrite32(0x0fffffff, base + PRTOVSET);
252         /* Interrupts not used, disable all */
253         iowrite32(0, base + DSIINTE);
254         /* DSI-Tx bias on */
255         iowrite32(0x00000001, base + PHYCTRL);
256         udelay(200);
257         /* Deassert resets, power on */
258         iowrite32(0x03070001 | pdata->phyctrl, base + PHYCTRL);
259 
260         /*
261          * Default = ULPS enable |
262          *      Contention detection enabled |
263          *      EoT packet transmission enable |
264          *      CRC check enable |
265          *      ECC check enable
266          */
267         bitmap_fill((unsigned long *)&tmp, pdata->lane);
268         tmp |= 0x00003700;
269         iowrite32(tmp, base + SYSCONF);
270 
271         /* setup l-bridge */
272 
273         /*
274          * Enable transmission of all packets,
275          * transmit LPS after each HS packet completion
276          */
277         iowrite32(0x00000006, mipi->linkbase + DTCTR);
278         /* VSYNC width = 2 (<< 17) */
279         iowrite32((mode->vsync_len << pdata->vsynw_offset) |
280                   (pdata->clksrc << 16) | (pctype << 12) | datatype,
281                   mipi->linkbase + VMCTR1);
282 
283         /*
284          * Non-burst mode with sync pulses: VSE and HSE are output,
285          * HSA period allowed, no commands in LP
286          */
287         vmctr2 = 0;
288         if (pdata->flags & SH_MIPI_DSI_VSEE)
289                 vmctr2 |= 1 << 23;
290         if (pdata->flags & SH_MIPI_DSI_HSEE)
291                 vmctr2 |= 1 << 22;
292         if (pdata->flags & SH_MIPI_DSI_HSAE)
293                 vmctr2 |= 1 << 21;
294         if (pdata->flags & SH_MIPI_DSI_BL2E)
295                 vmctr2 |= 1 << 17;
296         if (pdata->flags & SH_MIPI_DSI_HSABM)
297                 vmctr2 |= 1 << 5;
298         if (pdata->flags & SH_MIPI_DSI_HBPBM)
299                 vmctr2 |= 1 << 4;
300         if (pdata->flags & SH_MIPI_DSI_HFPBM)
301                 vmctr2 |= 1 << 3;
302         iowrite32(vmctr2, mipi->linkbase + VMCTR2);
303 
304         /*
305          * VMLEN1 = RGBLEN | HSALEN
306          *
307          * see
308          *  Video mode - Blanking Packet setting
309          */
310         top = linelength << 16; /* RGBLEN */
311         bottom = 0x00000001;
312         if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
313                 bottom = (pdata->lane * mode->hsync_len) - 10;
314         iowrite32(top | bottom , mipi->linkbase + VMLEN1);
315 
316         /*
317          * VMLEN2 = HBPLEN | HFPLEN
318          *
319          * see
320          *  Video mode - Blanking Packet setting
321          */
322         top     = 0x00010000;
323         bottom  = 0x00000001;
324         delay   = 0;
325 
326         div = 1;        /* HSbyteCLK is calculation base
327                          * HS4divCLK = HSbyteCLK/2
328                          * HS6divCLK is not supported for now */
329         if (pdata->flags & SH_MIPI_DSI_HS4divCLK)
330                 div = 2;
331 
332         if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */
333                 top = mode->hsync_len + mode->left_margin;
334                 top = ((pdata->lane * top / div) - 10) << 16;
335         }
336         if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
337                 bottom = mode->right_margin;
338                 bottom = (pdata->lane * bottom / div) - 12;
339         }
340 
341         bpp = linelength / mode->xres; /* byte / pixel */
342         if ((pdata->lane / div) > bpp) {
343                 tmp = mode->xres / bpp; /* output cycle */
344                 tmp = mode->xres - tmp; /* (input - output) cycle */
345                 delay = (pdata->lane * tmp);
346         }
347 
348         iowrite32(top | (bottom + delay) , mipi->linkbase + VMLEN2);
349 
350         msleep(5);
351 
352         /* setup LCD panel */
353 
354         /* cf. drivers/video/omap/lcd_mipid.c */
355         sh_mipi_dcs(pdata->channel, MIPI_DCS_EXIT_SLEEP_MODE);
356         msleep(120);
357         /*
358          * [7] - Page Address Mode
359          * [6] - Column Address Mode
360          * [5] - Page / Column Address Mode
361          * [4] - Display Device Line Refresh Order
362          * [3] - RGB/BGR Order
363          * [2] - Display Data Latch Data Order
364          * [1] - Flip Horizontal
365          * [0] - Flip Vertical
366          */
367         sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
368         /* cf. set_data_lines() */
369         sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_PIXEL_FORMAT,
370                           pixfmt << 4);
371         sh_mipi_dcs(pdata->channel, MIPI_DCS_SET_DISPLAY_ON);
372 
373         /* Enable timeout counters */
374         iowrite32(0x00000f00, base + DSICTRL);
375 
376         return 0;
377 }
378 
379 static int mipi_display_on(struct sh_mobile_lcdc_entity *entity)
380 {
381         struct sh_mipi *mipi = to_sh_mipi(entity);
382         struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
383         int ret;
384 
385         pm_runtime_get_sync(&mipi->pdev->dev);
386 
387         ret = pdata->set_dot_clock(mipi->pdev, mipi->base, 1);
388         if (ret < 0)
389                 goto mipi_display_on_fail1;
390 
391         ret = sh_mipi_setup(mipi, &entity->def_mode);
392         if (ret < 0)
393                 goto mipi_display_on_fail2;
394 
395         sh_mipi_dsi_enable(mipi, true);
396 
397         return SH_MOBILE_LCDC_DISPLAY_CONNECTED;
398 
399 mipi_display_on_fail1:
400         pm_runtime_put_sync(&mipi->pdev->dev);
401 mipi_display_on_fail2:
402         pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
403 
404         return ret;
405 }
406 
407 static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
408 {
409         struct sh_mipi *mipi = to_sh_mipi(entity);
410         struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
411 
412         sh_mipi_dsi_enable(mipi, false);
413 
414         pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
415 
416         pm_runtime_put_sync(&mipi->pdev->dev);
417 }
418 
419 static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
420         .display_on = mipi_display_on,
421         .display_off = mipi_display_off,
422 };
423 
424 static int __init sh_mipi_probe(struct platform_device *pdev)
425 {
426         struct sh_mipi *mipi;
427         struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
428         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429         struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
430         unsigned long rate, f_current;
431         int idx = pdev->id, ret;
432 
433         if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
434                 return -ENODEV;
435 
436         if (!pdata->set_dot_clock)
437                 return -EINVAL;
438 
439         mutex_lock(&array_lock);
440         if (idx < 0)
441                 for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
442                         ;
443 
444         if (idx == ARRAY_SIZE(mipi_dsi)) {
445                 ret = -EBUSY;
446                 goto efindslot;
447         }
448 
449         mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
450         if (!mipi) {
451                 ret = -ENOMEM;
452                 goto ealloc;
453         }
454 
455         mipi->entity.owner = THIS_MODULE;
456         mipi->entity.ops = &mipi_ops;
457 
458         if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
459                 dev_err(&pdev->dev, "MIPI register region already claimed\n");
460                 ret = -EBUSY;
461                 goto ereqreg;
462         }
463 
464         mipi->base = ioremap(res->start, resource_size(res));
465         if (!mipi->base) {
466                 ret = -ENOMEM;
467                 goto emap;
468         }
469 
470         if (!request_mem_region(res2->start, resource_size(res2), pdev->name)) {
471                 dev_err(&pdev->dev, "MIPI register region 2 already claimed\n");
472                 ret = -EBUSY;
473                 goto ereqreg2;
474         }
475 
476         mipi->linkbase = ioremap(res2->start, resource_size(res2));
477         if (!mipi->linkbase) {
478                 ret = -ENOMEM;
479                 goto emap2;
480         }
481 
482         mipi->pdev = pdev;
483 
484         mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
485         if (IS_ERR(mipi->dsit_clk)) {
486                 ret = PTR_ERR(mipi->dsit_clk);
487                 goto eclktget;
488         }
489 
490         f_current = clk_get_rate(mipi->dsit_clk);
491         /* 80MHz required by the datasheet */
492         rate = clk_round_rate(mipi->dsit_clk, 80000000);
493         if (rate > 0 && rate != f_current)
494                 ret = clk_set_rate(mipi->dsit_clk, rate);
495         else
496                 ret = rate;
497         if (ret < 0)
498                 goto esettrate;
499 
500         dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
501 
502         ret = clk_enable(mipi->dsit_clk);
503         if (ret < 0)
504                 goto eclkton;
505 
506         mipi_dsi[idx] = mipi;
507 
508         pm_runtime_enable(&pdev->dev);
509         pm_runtime_resume(&pdev->dev);
510 
511         mutex_unlock(&array_lock);
512         platform_set_drvdata(pdev, &mipi->entity);
513 
514         return 0;
515 
516 eclkton:
517 esettrate:
518         clk_put(mipi->dsit_clk);
519 eclktget:
520         iounmap(mipi->linkbase);
521 emap2:
522         release_mem_region(res2->start, resource_size(res2));
523 ereqreg2:
524         iounmap(mipi->base);
525 emap:
526         release_mem_region(res->start, resource_size(res));
527 ereqreg:
528         kfree(mipi);
529 ealloc:
530 efindslot:
531         mutex_unlock(&array_lock);
532 
533         return ret;
534 }
535 
536 static int sh_mipi_remove(struct platform_device *pdev)
537 {
538         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
539         struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
540         struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
541         int i, ret;
542 
543         mutex_lock(&array_lock);
544 
545         for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++)
546                 ;
547 
548         if (i == ARRAY_SIZE(mipi_dsi)) {
549                 ret = -EINVAL;
550         } else {
551                 ret = 0;
552                 mipi_dsi[i] = NULL;
553         }
554 
555         mutex_unlock(&array_lock);
556 
557         if (ret < 0)
558                 return ret;
559 
560         pm_runtime_disable(&pdev->dev);
561         clk_disable(mipi->dsit_clk);
562         clk_put(mipi->dsit_clk);
563 
564         iounmap(mipi->linkbase);
565         if (res2)
566                 release_mem_region(res2->start, resource_size(res2));
567         iounmap(mipi->base);
568         if (res)
569                 release_mem_region(res->start, resource_size(res));
570         kfree(mipi);
571 
572         return 0;
573 }
574 
575 static struct platform_driver sh_mipi_driver = {
576         .remove         = sh_mipi_remove,
577         .shutdown       = sh_mipi_shutdown,
578         .driver = {
579                 .name   = "sh-mipi-dsi",
580         },
581 };
582 
583 module_platform_driver_probe(sh_mipi_driver, sh_mipi_probe);
584 
585 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
586 MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
587 MODULE_LICENSE("GPL v2");
588 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us