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