SH7760/SH7763 整合 LCDC 幀緩衝驅動程式

0. 概述

SH7760/SH7763 集成了 LCD 顯示控制器 (LCDC),理論上支援 1x1 到 1024x1024 的解析度,顏色深度範圍從 1 到 16 位,支援 STN、DSTN 和 TFT 面板。

注意事項

  • 幀緩衝記憶體必須是在 Area3 頂部分配的大塊記憶體(硬體要求)。由於此要求,您不應該將驅動程式做成模組,因為在執行時可能無法獲得足夠大的連續記憶體塊。

  • 驅動程式不支援在載入後更改解析度(顯示器無論如何都不支援熱插拔)

  • 在以下情況下可能會觀察到嚴重閃爍:a) 如果您使用 15/16 位色彩模式且解析度 >= 640x480 畫素,b) 在 PCMCIA(或任何其他慢速匯流排)活動期間。

  • 旋轉僅支援順時針 90 度,並且僅當水平解析度 <= 320 畫素時。

檔案

1. 平臺設定

SH7760

影片資料透過 DMABRG DMA 引擎獲取,因此您必須將 SH DMAC 配置為 DMABRG 模式(在啟動時某處將 0x94808080 寫入 DMARSRA 暫存器)。

PFC 暫存器 PCCR 和 PCDR 必須設定為外設模式。(將兩者都寫入零)。

驅動程式不會為您執行上述操作,因為板級設定是板級設定程式碼的工作。

2. 面板定義

LCDC 必須明確告知所連線 LCD 面板的型別。資料必須封裝在“struct sh7760fb_platdata”中,並作為 platform_data 傳遞給驅動程式。

建議您仔細查閱 SH7760 手冊,第 30 節。(http://documentation.renesas.com/eng/products/mpumcu/e602291_sh7760.pdf

以下程式碼說明了在 640x480 TFT 上使幀緩衝工作所需的操作

#include <linux/fb.h>
#include <asm/sh7760fb.h>

/*
 * NEC NL6440bc26-01 640x480 TFT
 * dotclock 25175 kHz
 * Xres                640     Yres            480
 * Htotal      800     Vtotal          525
 * HsynStart   656     VsynStart       490
 * HsynLenn    30      VsynLenn        2
 *
 * The linux framebuffer layer does not use the syncstart/synclen
 * values but right/left/upper/lower margin values. The comments
 * for the x_margin explain how to calculate those from given
 * panel sync timings.
 */
static struct fb_videomode nl6448bc26 = {
       .name           = "NL6448BC26",
       .refresh        = 60,
       .xres           = 640,
       .yres           = 480,
       .pixclock       = 39683,        /* in picoseconds! */
       .hsync_len      = 30,
       .vsync_len      = 2,
       .left_margin    = 114,  /* HTOT - (HSYNSLEN + HSYNSTART) */
       .right_margin   = 16,   /* HSYNSTART - XRES */
       .upper_margin   = 33,   /* VTOT - (VSYNLEN + VSYNSTART) */
       .lower_margin   = 10,   /* VSYNSTART - YRES */
       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
       .vmode          = FB_VMODE_NONINTERLACED,
       .flag           = 0,
};

static struct sh7760fb_platdata sh7760fb_nl6448 = {
       .def_mode       = &nl6448bc26,
       .ldmtr          = LDMTR_TFT_COLOR_16,   /* 16bit TFT panel */
       .lddfr          = LDDFR_8BPP,           /* we want 8bit output */
       .ldpmmr         = 0x0070,
       .ldpspr         = 0x0500,
       .ldaclnr        = 0,
       .ldickr         = LDICKR_CLKSRC(LCDC_CLKSRC_EXTERNAL) |
                       LDICKR_CLKDIV(1),
       .rotate         = 0,
       .novsync        = 1,
       .blank          = NULL,
};

/* SH7760:
 * 0xFE300800: 256 * 4byte xRGB palette ram
 * 0xFE300C00: 42 bytes ctrl registers
 */
static struct resource sh7760_lcdc_res[] = {
       [0] = {
             .start  = 0xFE300800,
             .end    = 0xFE300CFF,
             .flags  = IORESOURCE_MEM,
       },
       [1] = {
             .start  = 65,
             .end    = 65,
             .flags  = IORESOURCE_IRQ,
       },
};

static struct platform_device sh7760_lcdc_dev = {
       .dev    = {
             .platform_data = &sh7760fb_nl6448,
       },
       .name           = "sh7760-lcdc",
       .id             = -1,
       .resource       = sh7760_lcdc_res,
       .num_resources  = ARRAY_SIZE(sh7760_lcdc_res),
};