xref: /OK3568_Linux_fs/kernel/Documentation/fb/sh7760fb.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun================================================
2*4882a593SmuzhiyunSH7760/SH7763 integrated LCDC Framebuffer driver
3*4882a593Smuzhiyun================================================
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun0. Overview
6*4882a593Smuzhiyun-----------
7*4882a593SmuzhiyunThe SH7760/SH7763 have an integrated LCD Display controller (LCDC) which
8*4882a593Smuzhiyunsupports (in theory) resolutions ranging from 1x1 to 1024x1024,
9*4882a593Smuzhiyunwith color depths ranging from 1 to 16 bits, on STN, DSTN and TFT Panels.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunCaveats:
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun* Framebuffer memory must be a large chunk allocated at the top
14*4882a593Smuzhiyun  of Area3 (HW requirement). Because of this requirement you should NOT
15*4882a593Smuzhiyun  make the driver a module since at runtime it may become impossible to
16*4882a593Smuzhiyun  get a large enough contiguous chunk of memory.
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun* The driver does not support changing resolution while loaded
19*4882a593Smuzhiyun  (displays aren't hotpluggable anyway)
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun* Heavy flickering may be observed
22*4882a593Smuzhiyun  a) if you're using 15/16bit color modes at >= 640x480 px resolutions,
23*4882a593Smuzhiyun  b) during PCMCIA (or any other slow bus) activity.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun* Rotation works only 90degress clockwise, and only if horizontal
26*4882a593Smuzhiyun  resolution is <= 320 pixels.
27*4882a593Smuzhiyun
28*4882a593SmuzhiyunFiles:
29*4882a593Smuzhiyun	- drivers/video/sh7760fb.c
30*4882a593Smuzhiyun	- include/asm-sh/sh7760fb.h
31*4882a593Smuzhiyun	- Documentation/fb/sh7760fb.rst
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun1. Platform setup
34*4882a593Smuzhiyun-----------------
35*4882a593SmuzhiyunSH7760:
36*4882a593Smuzhiyun Video data is fetched via the DMABRG DMA engine, so you have to
37*4882a593Smuzhiyun configure the SH DMAC for DMABRG mode (write 0x94808080 to the
38*4882a593Smuzhiyun DMARSRA register somewhere at boot).
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun PFC registers PCCR and PCDR must be set to peripheral mode.
41*4882a593Smuzhiyun (write zeros to both).
42*4882a593Smuzhiyun
43*4882a593SmuzhiyunThe driver does NOT do the above for you since board setup is, well, job
44*4882a593Smuzhiyunof the board setup code.
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun2. Panel definitions
47*4882a593Smuzhiyun--------------------
48*4882a593SmuzhiyunThe LCDC must explicitly be told about the type of LCD panel
49*4882a593Smuzhiyunattached.  Data must be wrapped in a "struct sh7760fb_platdata" and
50*4882a593Smuzhiyunpassed to the driver as platform_data.
51*4882a593Smuzhiyun
52*4882a593SmuzhiyunSuggest you take a closer look at the SH7760 Manual, Section 30.
53*4882a593Smuzhiyun(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf)
54*4882a593Smuzhiyun
55*4882a593SmuzhiyunThe following code illustrates what needs to be done to
56*4882a593Smuzhiyunget the framebuffer working on a 640x480 TFT::
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun  #include <linux/fb.h>
59*4882a593Smuzhiyun  #include <asm/sh7760fb.h>
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun  /*
62*4882a593Smuzhiyun   * NEC NL6440bc26-01 640x480 TFT
63*4882a593Smuzhiyun   * dotclock 25175 kHz
64*4882a593Smuzhiyun   * Xres                640     Yres            480
65*4882a593Smuzhiyun   * Htotal      800     Vtotal          525
66*4882a593Smuzhiyun   * HsynStart   656     VsynStart       490
67*4882a593Smuzhiyun   * HsynLenn    30      VsynLenn        2
68*4882a593Smuzhiyun   *
69*4882a593Smuzhiyun   * The linux framebuffer layer does not use the syncstart/synclen
70*4882a593Smuzhiyun   * values but right/left/upper/lower margin values. The comments
71*4882a593Smuzhiyun   * for the x_margin explain how to calculate those from given
72*4882a593Smuzhiyun   * panel sync timings.
73*4882a593Smuzhiyun   */
74*4882a593Smuzhiyun  static struct fb_videomode nl6448bc26 = {
75*4882a593Smuzhiyun         .name           = "NL6448BC26",
76*4882a593Smuzhiyun         .refresh        = 60,
77*4882a593Smuzhiyun         .xres           = 640,
78*4882a593Smuzhiyun         .yres           = 480,
79*4882a593Smuzhiyun         .pixclock       = 39683,        /* in picoseconds! */
80*4882a593Smuzhiyun         .hsync_len      = 30,
81*4882a593Smuzhiyun         .vsync_len      = 2,
82*4882a593Smuzhiyun         .left_margin    = 114,  /* HTOT - (HSYNSLEN + HSYNSTART) */
83*4882a593Smuzhiyun         .right_margin   = 16,   /* HSYNSTART - XRES */
84*4882a593Smuzhiyun         .upper_margin   = 33,   /* VTOT - (VSYNLEN + VSYNSTART) */
85*4882a593Smuzhiyun         .lower_margin   = 10,   /* VSYNSTART - YRES */
86*4882a593Smuzhiyun         .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
87*4882a593Smuzhiyun         .vmode          = FB_VMODE_NONINTERLACED,
88*4882a593Smuzhiyun         .flag           = 0,
89*4882a593Smuzhiyun  };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun  static struct sh7760fb_platdata sh7760fb_nl6448 = {
92*4882a593Smuzhiyun         .def_mode       = &nl6448bc26,
93*4882a593Smuzhiyun         .ldmtr          = LDMTR_TFT_COLOR_16,   /* 16bit TFT panel */
94*4882a593Smuzhiyun         .lddfr          = LDDFR_8BPP,           /* we want 8bit output */
95*4882a593Smuzhiyun         .ldpmmr         = 0x0070,
96*4882a593Smuzhiyun         .ldpspr         = 0x0500,
97*4882a593Smuzhiyun         .ldaclnr        = 0,
98*4882a593Smuzhiyun         .ldickr         = LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
99*4882a593Smuzhiyun			 LDICKR_CLKDIV(1),
100*4882a593Smuzhiyun         .rotate         = 0,
101*4882a593Smuzhiyun         .novsync        = 1,
102*4882a593Smuzhiyun         .blank          = NULL,
103*4882a593Smuzhiyun  };
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun  /* SH7760:
106*4882a593Smuzhiyun   * 0xFE300800: 256 * 4byte xRGB palette ram
107*4882a593Smuzhiyun   * 0xFE300C00: 42 bytes ctrl registers
108*4882a593Smuzhiyun   */
109*4882a593Smuzhiyun  static struct resource sh7760_lcdc_res[] = {
110*4882a593Smuzhiyun         [0] = {
111*4882a593Smuzhiyun	       .start  = 0xFE300800,
112*4882a593Smuzhiyun	       .end    = 0xFE300CFF,
113*4882a593Smuzhiyun	       .flags  = IORESOURCE_MEM,
114*4882a593Smuzhiyun         },
115*4882a593Smuzhiyun         [1] = {
116*4882a593Smuzhiyun	       .start  = 65,
117*4882a593Smuzhiyun	       .end    = 65,
118*4882a593Smuzhiyun	       .flags  = IORESOURCE_IRQ,
119*4882a593Smuzhiyun         },
120*4882a593Smuzhiyun  };
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun  static struct platform_device sh7760_lcdc_dev = {
123*4882a593Smuzhiyun         .dev    = {
124*4882a593Smuzhiyun	       .platform_data = &sh7760fb_nl6448,
125*4882a593Smuzhiyun         },
126*4882a593Smuzhiyun         .name           = "sh7760-lcdc",
127*4882a593Smuzhiyun         .id             = -1,
128*4882a593Smuzhiyun         .resource       = sh7760_lcdc_res,
129*4882a593Smuzhiyun         .num_resources  = ARRAY_SIZE(sh7760_lcdc_res),
130*4882a593Smuzhiyun  };
131