void lcd_set_flip(bool yesno) { __cpm_start_lcd(); #if CONFIG_ORIENTATION == SCREEN_PORTRAIT if(yesno) { SLCD_SEND_COMMAND(REG_ENTRY_MODE, ENTRY_MODE_BGR); } else { SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_VID | ENTRY_MODE_HID)); } #else if(yesno) { SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_HID | ENTRY_MODE_AM)); } else { SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_VID | ENTRY_MODE_AM)); } #endif DELAY; __cpm_stop_lcd(); }
static void _set_lcd_clock(void) { unsigned int val; __cpm_stop_lcd(); val = (__cpm_get_pllout2() / LCD_PCLK) - 1; if ( val > 0x1ff ) val = 0x1ff; /* CPM_LPCDR is too large, set it to 0x1ff */ __cpm_set_pixdiv(val); __cpm_start_lcd(); }
static int jz_lcd_hw_init(vidinfo_t *vid) { struct jz_fb_info *fbi = &vid->jz_fb; unsigned int val = 0; unsigned int pclk; /* Setting Control register */ val = jzfb.panel.ctrl; switch (vid->vl_bpix) { case 0: val |= LCD_CTRL_BPP_1; break; case 1: val |= LCD_CTRL_BPP_2; break; case 2: val |= LCD_CTRL_BPP_4; break; case 3: val |= LCD_CTRL_BPP_8; break; case 4: val |= LCD_CTRL_BPP_16; break; case 5: val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ break; default: printf("The BPP %d is not supported\n", 1 << panel_info.vl_bpix); val |= LCD_CTRL_BPP_18_24; break; } // val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ // val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ jzfb.panel.ctrl = val; REG_LCD_CTRL = val; switch ( jzfb.panel.cfg & LCD_CFG_MODE_MASK ) { case LCD_CFG_MODE_GENERIC_TFT: case LCD_CFG_MODE_INTER_CCIR656: case LCD_CFG_MODE_NONINTER_CCIR656: case LCD_CFG_MODE_SLCD: default: /* only support TFT16 TFT32, not support STN and Special TFT by now(10-06-2008)*/ REG_LCD_VAT = (((jzfb.panel.blw + jzfb.panel.w + jzfb.panel.elw + jzfb.panel.hsw)) << 16) | (jzfb.panel.vsw + jzfb.panel.bfw + jzfb.panel.h + jzfb.panel.efw); REG_LCD_DAH = ((jzfb.panel.hsw + jzfb.panel.blw) << 16) | (jzfb.panel.hsw + jzfb.panel.blw + jzfb.panel.w); REG_LCD_DAV = ((jzfb.panel.vsw + jzfb.panel.bfw) << 16) | (jzfb.panel.vsw + jzfb.panel.bfw + jzfb.panel.h); REG_LCD_HSYNC = (0 << 16) | jzfb.panel.hsw; REG_LCD_VSYNC = (0 << 16) | jzfb.panel.vsw; break; } /* Configure the LCD panel */ REG_LCD_CFG = jzfb.panel.cfg; REG_LCD_OSDCTRL = jzfb.osd.osd_ctrl; /* IPUEN, bpp */ REG_LCD_RGBC = jzfb.osd.rgb_ctrl; REG_LCD_BGC = jzfb.osd.bgcolor; REG_LCD_KEY0 = jzfb.osd.colorkey0; REG_LCD_KEY1 = jzfb.osd.colorkey1; REG_LCD_ALPHA = jzfb.osd.alpha; REG_LCD_IPUR = jzfb.osd.ipu_restart; /* Timing setting */ __cpm_stop_lcd(); val = jzfb.panel.fclk; /* frame clk */ if ( (jzfb.panel.cfg & LCD_CFG_MODE_MASK) != LCD_CFG_MODE_SERIAL_TFT) { pclk = val * (jzfb.panel.w + jzfb.panel.hsw + jzfb.panel.elw + jzfb.panel.blw) * (jzfb.panel.h + jzfb.panel.vsw + jzfb.panel.efw + jzfb.panel.bfw); /* Pixclk */ } else { /* serial mode: Hsync period = 3*Width_Pixel */ pclk = val * (jzfb.panel.w*3 + jzfb.panel.hsw + jzfb.panel.elw + jzfb.panel.blw) * (jzfb.panel.h + jzfb.panel.vsw + jzfb.panel.efw + jzfb.panel.bfw); /* Pixclk */ } val = __cpm_get_pllout2() / pclk; /* pclk */ val--; if ( val > 0x7ff ) { printf("pixel clock divid is too large, set it to 0x7ff\n"); val = 0x7ff; } __cpm_set_pixdiv(val); #if defined(CONFIG_JZ4750) val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */ val =__cpm_get_pllout2() / val; if ( val > 0x1f ) { printf("lcd clock divide is too large, set it to 0x1f\n"); val = 0x1f; } __cpm_set_ldiv( val ); #endif REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */ __cpm_start_lcd(); udelay(1000); REG_LCD_DA0 = fbi->fdadr0; /* foreground 0 descripter*/ REG_LCD_DA1 = fbi->fdadr1; /* foreground 1 descripter*/ return 0; }
static int jz_lcd_hw_init(vidinfo_t *vid) { struct jz_fb_info *fbi = &vid->jz_fb; unsigned int val = 0; unsigned int pclk,pll_clk,pll1_flag; /* Setting Control register */ val = jzfb.panel.ctrl; switch (vid->vl_bpix) { case 0: val |= LCD_CTRL_BPP_1; break; case 1: val |= LCD_CTRL_BPP_2; break; case 2: val |= LCD_CTRL_BPP_4; break; case 3: val |= LCD_CTRL_BPP_8; break; case 4: val |= LCD_CTRL_BPP_16; break; case 5: val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ break; default: // printf("The BPP %d is not supported\n", 1 << panel_info.vl_bpix); val |= LCD_CTRL_BPP_18_24; break; } // val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ // val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ jzfb.panel.ctrl = val; REG_LCD_CTRL = val; switch (jzfb.panel.cfg & LCD_CFG_MODE_MASK) { case LCD_CFG_MODE_GENERIC_TFT: case LCD_CFG_MODE_INTER_CCIR656: case LCD_CFG_MODE_NONINTER_CCIR656: case LCD_CFG_MODE_SLCD: default: /* only support TFT16 TFT32 */ REG_LCD_VAT = (((jzfb.panel.blw + jzfb.panel.w + jzfb.panel.elw + jzfb.panel.hsw)) << 16) | (jzfb.panel.vsw + jzfb.panel.bfw + jzfb.panel.h + jzfb.panel.efw); REG_LCD_DAH = ((jzfb.panel.hsw + jzfb.panel.blw) << 16) | (jzfb.panel.hsw + jzfb.panel.blw + jzfb.panel.w); REG_LCD_DAV = ((jzfb.panel.vsw + jzfb.panel.bfw) << 16) | (jzfb.panel.vsw + jzfb.panel.bfw + jzfb.panel.h); REG_LCD_HSYNC = (0 << 16) | jzfb.panel.hsw; REG_LCD_VSYNC = (0 << 16) | jzfb.panel.vsw; break; } /* Configure the LCD panel */ REG_LCD_CFG = jzfb.panel.cfg; REG_LCD_OSDC = jzfb.osd.osd_cfg; REG_LCD_OSDCTRL = jzfb.osd.osd_ctrl; /* IPUEN, bpp */ REG_LCD_RGBC = jzfb.osd.rgb_ctrl; REG_LCD_BGC = jzfb.osd.bgcolor; REG_LCD_KEY0 = jzfb.osd.colorkey0; REG_LCD_KEY1 = jzfb.osd.colorkey1; REG_LCD_ALPHA = jzfb.osd.alpha; REG_LCD_IPUR = jzfb.osd.ipu_restart; /* Timing setting */ __cpm_stop_lcd(); val = jzfb.panel.fclk; /* frame clk */ if ( (jzfb.panel.cfg & LCD_CFG_MODE_MASK) != LCD_CFG_MODE_SERIAL_TFT) { pclk = val * (jzfb.panel.w + jzfb.panel.hsw + jzfb.panel.elw + jzfb.panel.blw) * (jzfb.panel.h + jzfb.panel.vsw + jzfb.panel.efw + jzfb.panel.bfw); /* Pixclk */ } else { /* serial mode: Hsync period = 3*Width_Pixel */ pclk = val * (jzfb.panel.w*3 + jzfb.panel.hsw + jzfb.panel.elw + jzfb.panel.blw) * (jzfb.panel.h + jzfb.panel.vsw + jzfb.panel.efw + jzfb.panel.bfw); /* Pixclk */ } #ifndef CONFIG_LCD_GET_PIXCLK_FROM_PLL1 pll_clk = __cpm_get_pllout2(); /* pixclk get from PLL 0 */ pll1_flag = 0; #else serial_puts_msg("PixCLK get from PLL1 !\n"); pll_clk = cpm_get_pllout1(); /* pixclk get from PLL 1 */ pll1_flag = 1; if(!pll_clk){ serial_puts_msg("PLL1 isn't on, pixclk will get from PLL0 !!!\n"); pll_clk = __cpm_get_pllout2(); /* pixclk get from PLL 0 */ pll1_flag = 0; } #endif val = pll_clk / pclk; /* pclk */ val--; if ( val > 0x7ff ) { #ifdef DEBUG serial_puts_msg("Pixel Clock Divid Is Too Large, Set it to 0x7ff\n"); #endif val = 0x7ff; } if(pll1_flag) __cpm_select_lcdpclk_pll1(); __cpm_set_pixdiv(val); #if 1 serial_puts_info("PixCLK = 0x"); dump_uint(pclk); serial_puts_msg(" \n"); serial_puts_info("PLL_CLK = 0x"); dump_uint(pll_clk); serial_puts_msg(" \n"); #endif #if 0 /*Jz4760 has no ldiv*/ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */ val =__cpm_get_pllout2() / val; if ( val > 0x1f ) { printf("lcd clock divide is too large, set it to 0x1f\n"); val = 0x1f; } __cpm_set_ldiv( val ); #endif REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */ __cpm_start_lcd(); udelay(1000); REG_LCD_DA0 = fbi->fdadr0; /* foreground 0 descripter*/ REG_LCD_DA1 = fbi->fdadr1; /* foreground 1 descripter*/ return 0; }
static void jz_fb_hw_set_pixclock(struct jz_fb_ctrl *ctrl) { struct jz_fb_ot_info *ot = ctrl->ot; struct jz_fb_panel_info *panel = ot->config->panel; unsigned int pixclock, refresh_rate; unsigned int w, h; unsigned int v; D("Called."); refresh_rate = panel->fclk; if (ot->use_tve) { pixclock = 27000000; }else{ if ((panel->lcd_cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_SERIAL_TFT) { /* serial mode: Hsync period = 3*Width_Pixel */ w = (panel->w * 3 + panel->hsw + panel->elw + panel->blw); h = (panel->h + panel->vsw + panel->efw + panel->bfw); pixclock = w * h * refresh_rate; }else { w = (panel->w + panel->hsw + panel->elw + panel->blw); h = (panel->h + panel->vsw + panel->efw + panel->bfw); pixclock = w * h * refresh_rate; } } ctrl->pixclock = pixclock; /* ------------ HW: Set LCD Controller ---------------- */ __cpm_stop_lcd(); if (ot->use_tve) { REG_CPM_LPCDR |= CPM_LPCDR_LTCS; __cpm_select_pixclk_tve(); }else{ REG_CPM_LPCDR &= ~CPM_LPCDR_LTCS; __cpm_select_pixclk_lcd(); } v = __cpm_get_pllout2() / pixclock; v--; __cpm_set_pixdiv(v); #if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */ v = pixclock * 3 ; /* LCDClock > 2.5*Pixclock */ v = (__cpm_get_pllout()) / v; if (v > 0x1f) { printk("lcd clock divide is too large, set it to 0x1f\n"); v = 0x1f; } __cpm_set_ldiv(v); #endif REG_CPM_CPCCR |= CPM_CPCCR_CE; /* update divide */ jz_clocks.pixclk = __cpm_get_pixclk(); #if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */ jz_clocks.lcdclk = __cpm_get_lcdclk(); I("LCD Controller Clock: %dMHz.", jz_clocks.lcdclk / 1000 / 1000); #endif I("Pixel Clock: %dMHz.", pixclock / 1000 / 1000); __cpm_start_lcd(); mdelay(1); return; }