- typedef unsigned int U32;
- volatile U32 FrameBuf[480][272];
- /* 填充颜色 */
- void paint_back(U32 c){
- unsigned int i, j;
- for(i = 100; i < 200; i++){
- for(j = 100; j < 200; j++){
- FrameBuf[i][j] = c;
- }
- }
- }
- void LCDDelay(int c){
- int i;
- for(; c != 0; c--){
- for(i = 0; i < 10; i++);
- }
- }
- static int lcd_open(struct inode *inode, struct file *file){
- unsigned int clock_div, u32prediv, w55fa92_upll_clock;
- ENTER();
- /* reset IC */
- #if 0
- outpw(REG_AHBCLK, inpw(REG_AHBCLK) | VPOST_CKE | HCLK4_CKE);
- outpw(REG_AHBIPRST, inpw(REG_AHBIPRST) | VPOST_RST);
- LCDDelay(10);
- outpw(REG_AHBIPRST, inpw(REG_AHBIPRST) & ~VPOST_RST);
- #endif
- outl((inl(REG_AHBCLK) | VPOST_CKE | HCLK4_CKE), REG_AHBCLK);
- outl(inl(REG_AHBIPRST) | VPOST_RST, REG_AHBIPRST);
- LCDDelay(10);
- outl(inl(REG_AHBIPRST) & ~VPOST_RST, REG_AHBIPRST);
- /* 时钟设置: DCLK 频率 -> 9MHz */
- w55fa92_upll_clock = 162000;
- clock_div = w55fa92_upll_clock / 9000;
- u32prediv = 0;
- clock_div--;
- nvt_lock();
- /* [2:0] 000 : LCD_SrcCLK / 1 */
- outl((inl(REG_CLKDIV1) & ~VPOST_N0) | u32prediv, REG_CLKDIV1);
- /* [15:8] VPOST_N = clock_div:
- * ECLKvpost = LCD_SrcCLK / (VPOST_N + 1) */
- outl((inl(REG_CLKDIV1) & ~VPOST_N1) | (clock_div << 8), REG_CLKDIV1);
- /* [4:3] LCD_SrcCLK = UCLKOut */
- outl((inl(REG_CLKDIV1) & ~VPOST_S) | (3 << 3), REG_CLKDIV1);
- nvt_unlock();
- /* 引脚设置 */
- /* 使能时钟信号 */
- outl((inl(REG_GPBFUN1) & ~MF_GPB15) | 0x20000000, REG_GPBFUN1);
- /* 使能 LVDATA[15:0] -> GPC[15:0] */
- outl(0x22222222, REG_GPCFUN0);
- outl(0x22222222, REG_GPCFUN1);
- /* 使能 LVDATA[17:16] -> GPE[1:0]*/
- outl((inl(REG_GPEFUN1) & ~(MF_GPE0 + MF_GPE1)) | 0x22, REG_GPEFUN1);
- /* 使能 LVDATA[23:18] -> GPB[12:7] */
- outl((inl(REG_GPBFUN0) & ~MF_GPB7) | 0x20000000, REG_GPEFUN0);
- outl((inl(REG_GPBFUN1) & 0xFFF00000) | 0x00022222, REG_GPEFUN1);
- /* 使能 LCD_HS, LCD_VS, LCD_DE -> GPD[12:9] */
- outl((inl(REG_GPDFUN1) & 0xFFFF000F) | 0x00002220, REG_GPDFUN1);
- #if 0
- outl((inl(REG_GPIOC_OMD) & 0xFFFF0000) | 0x0000FFFF, REG_GPIOC_OMD);
- outl((inl(REG_GPIOE_OMD) & 0xFFFCFFFF) | 0x00030000, REG_GPIOE_OMD);
- outl((inl(REG_GPIOB_OMD) & 0xFFFFFE7F) | 0x00000180, REG_GPIOB_OMD);
- #endif
- outl((inl(REG_GPIOC_PUEN) & 0xFFFF0000), REG_GPIOC_PUEN);
- outl((inl(REG_GPIOE_PUEN) & 0xFFFCFFFF), REG_GPIOE_PUEN);
- outl((inl(REG_GPIOB_PUEN) & 0xFFFFFE7F), REG_GPIOB_PUEN);
- /* LCD image LCD interface */
- outl((inl(REG_LCM_TVCtl) & ~TVCtl_LCDSrc) | (1 << 10), REG_LCM_TVCtl);
- /* 配置 LCD 接口 */
- /* [8] 使能 sync with TV */
- outl(inl(REG_LCM_LCDCPrm) & ~LCDCPrm_LCDSynTv, REG_LCM_LCDCPrm);
- /* [1:0] LCD type select:
- * 0x00 High Resolution mode
- * 0x01 Sync-type TFT LCD
- * 0x10 Reserved
- * 0x11 MPU-type LCD */
- outl(inl(REG_LCM_LCDCPrm) & ~LCDCPrm_LCDTYPE, REG_LCM_LCDCPrm);
- /* [21:20] 配置 LCD 并行 RGB 数据总线(高速模式下)
- * 00 16pin, RGB565 output
- * 01 18pin, RGB666 output
- * 10 24pin, RGB888 output
- * 11 Reserved*/
- outl((inl(REG_LCM_LCDCCtl) & ~LCDCCtl_PRDB_SEL) | (0x2 << 20), REG_LCM_LCDCCtl);
- /* [11:10] LCDSrc, [9:8] TVSrc: framebuffer
- * 00 Reserved 01 Framebuffer
- * 10 Register setting color 11 internal color bar
- * NotchE;
- * [0] enable TV encoder: 0-disable 1-enable
- * [23:22]:00 NTSC;
- * [15] TV output in D1 size: 0-640x480(VGA) 1-720x480(D1)
- * [3] Interlace: 0-non-interlace 1-interlace
- * ??? */
- outl((inl(REG_LCM_TVCtl) & 0xFFFF30DA) | 0x00008529, REG_LCM_TVCtl);
- /* 设置水平同步扫描时间线(unit: DCLK):
- * 水平同步脉冲宽度 HSPW [31:24] .min 1,
- * 前肩 HFPD [23:12] .min 2 .typ 8
- * 后肩 HBPD [11:0] .min 8 .typ 43 */
- outl(0x6302B008, REG_LCM_TCON1);
- /* 设置垂直同步扫描时间线(unit: H):
- * 水平同步脉冲宽度 HSPW [23:16] .min 1 .typ 10,
- * 前肩 HFPD [15:8] .min 1 .typ 4
- * 后肩 HBPD [7:0] .min 2 .typ 12 */
- outl((inl(REG_LCM_TCON2) & 0xFF000000) | 0x000A040C, REG_LCM_TCON2);
- /* 设置每行活跃数据的数量和每次面板显示的行数: 480x272
- * [31:16] active data count per line: 480
- * [15:0] lines per-panel: 272 */
- outl(0x01E00110, REG_LCM_TCON3);
- /* 设置桢缓冲的大小:
- * [32:16] FB_X: 480 - 1
- * [15:0] FB_Y: 272 - 1*/
- outl(0x01DF010F, REG_LCM_FB_SIZE);
- /* 信号极性,MPU 发出的是正脉冲,而 LCD 需要的是反的
- * 根据芯片手册:取 VDEN HSYNC VSYNC DCLK 的极性 */
- outl((inl(REG_LCM_TCON4) & 0xFFFFFFF0) | 0xE, REG_LCM_TCON4);
- /* set TV control register and LCD to framebuffer, disable DAC*/
- // outl((inl(REG_LCM_TVCtl) & 0xFFFFF0DA) | 0x00000510, REG_LCM_TVCtl);
- /* 桢缓冲开始地址 */
- // U32 FrameBuf = (U32)FrameBuf | 0X80000000;
- outl(FrameBuf, REG_LCM_FSADDR);
-
- /* 使能 LCD 控制器
- * [16] endian select: 0- big endian 1- little endian
- * [3:1] framebuffer data select:
- * 000 RGB555 001 RGB565
- * 010 RGB888(dummy,R,G,B) 011 RGB888(R,G,B,dummy)
- * [0] LCD controler run: 0 disable 1 enable */
- outl((inl(REG_LCM_LCDCCtl) & LCDCCtl_FBDS) | (2 << 1), REG_LCM_LCDCCtl);
- outl((inl(REG_LCM_LCDCCtl) & LCDCCtl_YUVBL) | (1 << 16), REG_LCM_LCDCCtl);
- outl((inl(REG_LCM_LCDCCtl) & LCDCCtl_LCDRUN) | 1, REG_LCM_LCDCCtl);
- paint_back(0xCD5C5C);
- outl((U32)FrameBuf, REG_LCM_FSADDR);
- return 0;
- }