diff options
author | Wolfgang Denk <wd@denx.de> | 2012-06-07 23:42:17 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2012-06-07 23:42:17 +0200 |
commit | fedab338f3459315cb69627fcf46032ec8df1753 (patch) | |
tree | f3364476201839514e578be0938832620be18244 /drivers | |
parent | 74b5b5dbc3345a8fad4bc798f8f88d07d2ef0008 (diff) | |
parent | f6b690e65c0aa5f3da22546ac597d9f01cff2e4e (diff) | |
download | u-boot-imx-fedab338f3459315cb69627fcf46032ec8df1753.zip u-boot-imx-fedab338f3459315cb69627fcf46032ec8df1753.tar.gz u-boot-imx-fedab338f3459315cb69627fcf46032ec8df1753.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-video
* 'master' of git://git.denx.de/u-boot-video:
video: atmel/lcd: add LCD driver for new Atmel SoC
video: cfb_console: flush dcache for frame buffer in DRAM
cfb_console: Ignore bell character
cfb_console: Add console_clear_line function
cfb_console: Fix function console_back
omap3_dss: cosmetic changes
omap3_dss: add optional framebuffer
mx53loco: Add LCD support
mx5: Rename mx51_fb_init()
mx53: Allow IPUv3 driver to also work on mx53
mx51evk: Add LCD support
EXYNOS: display 32bpp bitmap TIZEN logo
create lib/tizen directory
LCD: display 32bpp decompressed bitmap image
common/lcd.c: reduce one CONFIG_LCD_LOGO ifdef
common/lcd.c: reduce some CONFIG_LCD_*_LOGO ifdefs
common/lcd.c: use ARRAY_SIZE
cmd_bmp.c: make bmp_display() usable by drivers or board code
LCD: support another s6e8ax0 panel type
LCD: change s6e8ax0 panel gamma value
include/video.h: drop unused video_printf()
Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/Makefile | 3 | ||||
-rw-r--r-- | drivers/video/atmel_hlcdfb.c | 211 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 89 | ||||
-rw-r--r-- | drivers/video/exynos_fb.c | 19 | ||||
-rw-r--r-- | drivers/video/exynos_fb.h | 7 | ||||
-rw-r--r-- | drivers/video/exynos_fimd.c | 2 | ||||
-rw-r--r-- | drivers/video/ipu_regs.h | 42 | ||||
-rw-r--r-- | drivers/video/mxc_ipuv3_fb.c | 2 | ||||
-rw-r--r-- | drivers/video/omap3_dss.c | 77 | ||||
-rw-r--r-- | drivers/video/s6e8ax0.c | 25 |
10 files changed, 406 insertions, 71 deletions
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 4fad20d..44b7feb 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libvideo.o COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o +COBJS-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o COBJS-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o COBJS-$(CONFIG_CFB_CONSOLE) += cfb_console.o COBJS-$(CONFIG_EXYNOS_FB) += exynos_fb.o exynos_fimd.o @@ -42,7 +43,7 @@ COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o COBJS-$(CONFIG_VIDEO_MB86R0xGDC) += mb86r0xgdc.o videomodes.o COBJS-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o COBJS-$(CONFIG_VIDEO_MX5) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o -COBJS-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o videomodes.o +COBJS-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o COBJS-$(CONFIG_VIDEO_SM501) += sm501.o COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c new file mode 100644 index 0000000..beb7fa3 --- /dev/null +++ b/drivers/video/atmel_hlcdfb.c @@ -0,0 +1,211 @@ +/* + * Driver for AT91/AT32 MULTI LAYER LCD Controller + * + * Copyright (C) 2012 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/gpio.h> +#include <asm/arch/clk.h> +#include <lcd.h> +#include <atmel_hlcdc.h> + +int lcd_line_length; +int lcd_color_fg; +int lcd_color_bg; + +void *lcd_base; /* Start of framebuffer memory */ +void *lcd_console_address; /* Start of console buffer */ + +short console_col; +short console_row; + +/* configurable parameters */ +#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 +#define ATMEL_LCDC_DMA_BURST_LEN 8 +#ifndef ATMEL_LCDC_GUARD_TIME +#define ATMEL_LCDC_GUARD_TIME 1 +#endif + +#define ATMEL_LCDC_FIFO_SIZE 512 + +#define lcdc_readl(reg) __raw_readl((reg)) +#define lcdc_writel(reg, val) __raw_writel((val), (reg)) + +void lcd_ctrl_init(void *lcdbase) +{ + unsigned long value; + struct lcd_dma_desc *desc; + struct atmel_hlcd_regs *regs; + + if (!has_lcdc()) + return; /* No lcdc */ + + regs = (struct atmel_hlcd_regs *)panel_info.mmio; + + /* Disable DISP signal */ + lcdc_writel(®s->lcdc_lcddis, LCDC_LCDDIS_DISPDIS); + while ((lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_DISPSTS)) + udelay(1); + /* Disable synchronization */ + lcdc_writel(®s->lcdc_lcddis, LCDC_LCDDIS_SYNCDIS); + while ((lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_LCDSTS)) + udelay(1); + /* Disable pixel clock */ + lcdc_writel(®s->lcdc_lcddis, LCDC_LCDDIS_CLKDIS); + while ((lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_CLKSTS)) + udelay(1); + /* Disable PWM */ + lcdc_writel(®s->lcdc_lcddis, LCDC_LCDDIS_PWMDIS); + while ((lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_PWMSTS)) + udelay(1); + + /* Set pixel clock */ + value = get_lcdc_clk_rate(0) / panel_info.vl_clk; + if (get_lcdc_clk_rate(0) % panel_info.vl_clk) + value++; + + if (value < 1) { + /* Using system clock as pixel clock */ + lcdc_writel(®s->lcdc_lcdcfg0, + LCDC_LCDCFG0_CLKDIV(0) + | LCDC_LCDCFG0_CGDISHCR + | LCDC_LCDCFG0_CGDISHEO + | LCDC_LCDCFG0_CGDISOVR1 + | LCDC_LCDCFG0_CGDISBASE + | panel_info.vl_clk_pol + | LCDC_LCDCFG0_CLKSEL); + + } else { + lcdc_writel(®s->lcdc_lcdcfg0, + LCDC_LCDCFG0_CLKDIV(value - 2) + | LCDC_LCDCFG0_CGDISHCR + | LCDC_LCDCFG0_CGDISHEO + | LCDC_LCDCFG0_CGDISOVR1 + | LCDC_LCDCFG0_CGDISBASE + | panel_info.vl_clk_pol); + } + + /* Initialize control register 5 */ + value = 0; + + value |= panel_info.vl_sync; + +#ifndef LCD_OUTPUT_BPP + /* Output is 24bpp */ + value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; +#else + switch (LCD_OUTPUT_BPP) { + case 12: + value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; + break; + case 16: + value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; + break; + case 18: + value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; + break; + case 24: + value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; + break; + default: + BUG(); + break; + } +#endif + + value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME); + value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); + lcdc_writel(®s->lcdc_lcdcfg5, value); + + /* Vertical & Horizontal Timing */ + value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1); + value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1); + lcdc_writel(®s->lcdc_lcdcfg1, value); + + value = LCDC_LCDCFG2_VBPW(panel_info.vl_lower_margin); + value |= LCDC_LCDCFG2_VFPW(panel_info.vl_upper_margin - 1); + lcdc_writel(®s->lcdc_lcdcfg2, value); + + value = LCDC_LCDCFG3_HBPW(panel_info.vl_right_margin - 1); + value |= LCDC_LCDCFG3_HFPW(panel_info.vl_left_margin - 1); + lcdc_writel(®s->lcdc_lcdcfg3, value); + + /* Display size */ + value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1); + value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1); + lcdc_writel(®s->lcdc_lcdcfg4, value); + + lcdc_writel(®s->lcdc_basecfg0, + LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO); + + switch (NBITS(panel_info.vl_bpix)) { + case 16: + lcdc_writel(®s->lcdc_basecfg1, + LCDC_BASECFG1_RGBMODE_16BPP_RGB_565); + break; + default: + BUG(); + break; + } + + lcdc_writel(®s->lcdc_basecfg2, LCDC_BASECFG2_XSTRIDE(0)); + lcdc_writel(®s->lcdc_basecfg3, 0); + lcdc_writel(®s->lcdc_basecfg4, LCDC_BASECFG4_DMA); + + /* Disable all interrupts */ + lcdc_writel(®s->lcdc_lcdidr, ~0UL); + lcdc_writel(®s->lcdc_baseidr, ~0UL); + + /* Setup the DMA descriptor, this descriptor will loop to itself */ + desc = (struct lcd_dma_desc *)(lcdbase - 16); + + desc->address = (u32)lcdbase; + /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ + desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN + | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; + desc->next = (u32)desc; + + lcdc_writel(®s->lcdc_baseaddr, desc->address); + lcdc_writel(®s->lcdc_basectrl, desc->control); + lcdc_writel(®s->lcdc_basenext, desc->next); + lcdc_writel(®s->lcdc_basecher, LCDC_BASECHER_CHEN | + LCDC_BASECHER_UPDATEEN); + + /* Enable LCD */ + value = lcdc_readl(®s->lcdc_lcden); + lcdc_writel(®s->lcdc_lcden, value | LCDC_LCDEN_CLKEN); + while (!(lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_CLKSTS)) + udelay(1); + value = lcdc_readl(®s->lcdc_lcden); + lcdc_writel(®s->lcdc_lcden, value | LCDC_LCDEN_SYNCEN); + while (!(lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_LCDSTS)) + udelay(1); + value = lcdc_readl(®s->lcdc_lcden); + lcdc_writel(®s->lcdc_lcden, value | LCDC_LCDEN_DISPEN); + while (!(lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_DISPSTS)) + udelay(1); + value = lcdc_readl(®s->lcdc_lcden); + lcdc_writel(®s->lcdc_lcden, value | LCDC_LCDEN_PWMEN); + while (!(lcdc_readl(®s->lcdc_lcdsr) & LCDC_LCDSR_PWMSTS)) + udelay(1); +} diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 904caf7..92fa77d 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -360,6 +360,8 @@ void console_cursor(int state); extern void video_get_info_str(int line_number, char *info); #endif +DECLARE_GLOBAL_DATA_PTR; + /* Locals */ static GraphicDevice *pGD; /* Pointer to Graphic array */ @@ -377,6 +379,8 @@ static int console_row; /* cursor row */ static u32 eorx, fgx, bgx; /* color pats */ +static int cfb_do_flush_cache; + static const int video_font_draw_table8[] = { 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, @@ -553,6 +557,8 @@ static void video_drawchars(int xx, int yy, unsigned char *s, int count) SWAP32((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx); } + if (cfb_do_flush_cache) + flush_cache((ulong)dest0, 32); dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; s++; } @@ -621,6 +627,8 @@ static void video_invertchar(int xx, int yy) for (x = firstx; x < lastx; x++) { u8 *dest = (u8 *)(video_fb_address) + x + y; *dest = ~*dest; + if (cfb_do_flush_cache) + flush_cache((ulong)dest, 4); } } } @@ -683,6 +691,43 @@ static void memcpyl(int *d, int *s, int c) } #endif +static void console_clear_line(int line, int begin, int end) +{ +#ifdef VIDEO_HW_RECTFILL + video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */ + VIDEO_FONT_WIDTH * begin, /* dest pos x */ + video_logo_height + + VIDEO_FONT_HEIGHT * line, /* dest pos y */ + VIDEO_FONT_WIDTH * (end - begin + 1), /* fr. width */ + VIDEO_FONT_HEIGHT, /* frame height */ + bgx /* fill color */ + ); +#else + if (begin == 0 && (end + 1) == CONSOLE_COLS) { + memsetl(CONSOLE_ROW_FIRST + + CONSOLE_ROW_SIZE * line, /* offset of row */ + CONSOLE_ROW_SIZE >> 2, /* length of row */ + bgx /* fill color */ + ); + } else { + void *offset; + int i, size; + + offset = CONSOLE_ROW_FIRST + + CONSOLE_ROW_SIZE * line + /* offset of row */ + VIDEO_FONT_WIDTH * + VIDEO_PIXEL_SIZE * begin; /* offset of col */ + size = VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE * (end - begin + 1); + size >>= 2; /* length to end for memsetl() */ + /* fill at col offset of i'th line using bgx as fill color */ + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + memsetl(offset + i * VIDEO_LINE_LEN, size, bgx); + } +#endif + if (cfb_do_flush_cache) + flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE); +} + static void console_scrollup(void) { /* copy up rows ignoring the first one */ @@ -703,25 +748,12 @@ static void console_scrollup(void) memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE >> 2); #endif - /* clear the last one */ -#ifdef VIDEO_HW_RECTFILL - video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */ - 0, /* dest pos x */ - VIDEO_VISIBLE_ROWS - - VIDEO_FONT_HEIGHT, /* dest pos y */ - VIDEO_VISIBLE_COLS, /* frame width */ - VIDEO_FONT_HEIGHT, /* frame height */ - CONSOLE_BG_COL /* fill color */ - ); -#else - memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL); -#endif + console_clear_line(CONSOLE_ROWS - 1, 0, CONSOLE_COLS - 1); } static void console_back(void) { - CURSOR_OFF; console_col--; if (console_col < 0) { @@ -730,7 +762,6 @@ static void console_back(void) if (console_row < 0) console_row = 0; } - CURSOR_SET; } static void console_newline(void) @@ -782,6 +813,9 @@ void video_putc(const char c) console_back(); break; + case 7: /* bell */ + break; /* ignored */ + default: /* draw the char */ video_putchar(console_col * VIDEO_FONT_WIDTH, console_row * VIDEO_FONT_HEIGHT, c); @@ -1651,6 +1685,29 @@ static void *video_logo(void) } #endif +static int cfb_fb_is_in_dram(void) +{ + bd_t *bd = gd->bd; +#if defined(CONFIG_ARM) || defined(CONFIG_AVR32) || defined(COFNIG_NDS32) || \ +defined(CONFIG_SANDBOX) || defined(CONFIG_X86) + ulong start, end; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + start = bd->bi_dram[i].start; + end = bd->bi_dram[i].start + bd->bi_dram[i].size - 1; + if ((ulong)video_fb_address >= start && + (ulong)video_fb_address < end) + return 1; + } +#else + if ((ulong)video_fb_address >= bd->bi_memstart && + (ulong)video_fb_address < bd->bi_memstart + bd->bi_memsize) + return 1; +#endif + return 0; +} + static int video_init(void) { unsigned char color8; @@ -1664,6 +1721,8 @@ static int video_init(void) video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT); #endif + cfb_do_flush_cache = cfb_fb_is_in_dram() && dcache_status(); + /* Init drawing pats */ switch (VIDEO_DATA_FORMAT) { case GDF__8BIT_INDEX: diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index a1cf449..92be4ea 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -67,6 +67,18 @@ static void exynos_lcd_init(vidinfo_t *vid) exynos_fimd_lcd_init(vid); } +static void draw_logo(void) +{ + int x, y; + ulong addr; + + x = ((panel_width - panel_info.logo_width) >> 1); + y = ((panel_height - panel_info.logo_height) >> 1) - 4; + + addr = panel_info.logo_addr; + bmp_display(addr, x, y); +} + static void lcd_panel_on(vidinfo_t *vid) { udelay(vid->init_delay); @@ -118,6 +130,13 @@ void lcd_ctrl_init(void *lcdbase) void lcd_enable(void) { + if (panel_info.logo_on) { + memset(lcd_base, 0, panel_width * panel_height * + (NBITS(panel_info.vl_bpix) >> 3)); + + draw_logo(); + } + lcd_panel_on(&panel_info); } diff --git a/drivers/video/exynos_fb.h b/drivers/video/exynos_fb.h index 66f5da6..4ff2efd 100644 --- a/drivers/video/exynos_fb.h +++ b/drivers/video/exynos_fb.h @@ -27,13 +27,6 @@ #define MAX_CLOCK (86 * 1000000) -enum exynos_fb_rgb_mode_t { - MODE_RGB_P = 0, - MODE_BGR_P = 1, - MODE_RGB_S = 2, - MODE_BGR_S = 3, -}; - enum exynos_cpu_auto_cmd_rate { DISABLE_AUTO_FRM, PER_TWO_FRM, diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c index 6416b90..f07568a 100644 --- a/drivers/video/exynos_fimd.c +++ b/drivers/video/exynos_fimd.c @@ -273,7 +273,7 @@ void exynos_fimd_lcd_init(vidinfo_t *vid) /* store panel info to global variable */ pvid = vid; - rgb_mode = MODE_RGB_P; + rgb_mode = vid->rgb_mode; if (vid->interface_mode == FIMD_RGB_INTERFACE) { cfg |= EXYNOS_VIDCON0_VIDOUT_RGB; diff --git a/drivers/video/ipu_regs.h b/drivers/video/ipu_regs.h index 9964c20..93b195f 100644 --- a/drivers/video/ipu_regs.h +++ b/drivers/video/ipu_regs.h @@ -33,27 +33,27 @@ #define IPU_DISP0_BASE 0x00000000 #define IPU_MCU_T_DEFAULT 8 #define IPU_DISP1_BASE (IPU_MCU_T_DEFAULT << 25) -#define IPU_CM_REG_BASE 0x1E000000 -#define IPU_STAT_REG_BASE 0x1E000200 -#define IPU_IDMAC_REG_BASE 0x1E008000 -#define IPU_ISP_REG_BASE 0x1E010000 -#define IPU_DP_REG_BASE 0x1E018000 -#define IPU_IC_REG_BASE 0x1E020000 -#define IPU_IRT_REG_BASE 0x1E028000 -#define IPU_CSI0_REG_BASE 0x1E030000 -#define IPU_CSI1_REG_BASE 0x1E038000 -#define IPU_DI0_REG_BASE 0x1E040000 -#define IPU_DI1_REG_BASE 0x1E048000 -#define IPU_SMFC_REG_BASE 0x1E050000 -#define IPU_DC_REG_BASE 0x1E058000 -#define IPU_DMFC_REG_BASE 0x1E060000 -#define IPU_CPMEM_REG_BASE 0x1F000000 -#define IPU_LUT_REG_BASE 0x1F020000 -#define IPU_SRM_REG_BASE 0x1F040000 -#define IPU_TPM_REG_BASE 0x1F060000 -#define IPU_DC_TMPL_REG_BASE 0x1F080000 -#define IPU_ISP_TBPR_REG_BASE 0x1F0C0000 -#define IPU_VDI_REG_BASE 0x1E068000 +#define IPU_CM_REG_BASE 0x00000000 +#define IPU_STAT_REG_BASE 0x00000200 +#define IPU_IDMAC_REG_BASE 0x00008000 +#define IPU_ISP_REG_BASE 0x00010000 +#define IPU_DP_REG_BASE 0x00018000 +#define IPU_IC_REG_BASE 0x00020000 +#define IPU_IRT_REG_BASE 0x00028000 +#define IPU_CSI0_REG_BASE 0x00030000 +#define IPU_CSI1_REG_BASE 0x00038000 +#define IPU_DI0_REG_BASE 0x00040000 +#define IPU_DI1_REG_BASE 0x00048000 +#define IPU_SMFC_REG_BASE 0x00050000 +#define IPU_DC_REG_BASE 0x00058000 +#define IPU_DMFC_REG_BASE 0x00060000 +#define IPU_CPMEM_REG_BASE 0x01000000 +#define IPU_LUT_REG_BASE 0x01020000 +#define IPU_SRM_REG_BASE 0x01040000 +#define IPU_TPM_REG_BASE 0x01060000 +#define IPU_DC_TMPL_REG_BASE 0x01080000 +#define IPU_ISP_TBPR_REG_BASE 0x010C0000 +#define IPU_VDI_REG_BASE 0x00680000 extern u32 *ipu_dc_tmpl_reg; diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c index 1bee54c..c38e22d 100644 --- a/drivers/video/mxc_ipuv3_fb.c +++ b/drivers/video/mxc_ipuv3_fb.c @@ -599,7 +599,7 @@ void video_set_lut(unsigned int index, /* color number */ return; } -int mx51_fb_init(struct fb_videomode *mode, uint8_t disp, uint32_t pixfmt) +int ipuv3_fb_init(struct fb_videomode *mode, uint8_t disp, uint32_t pixfmt) { gmode = mode; gdisp = disp; diff --git a/drivers/video/omap3_dss.c b/drivers/video/omap3_dss.c index b322cc3..6686718 100644 --- a/drivers/video/omap3_dss.c +++ b/drivers/video/omap3_dss.c @@ -28,10 +28,9 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/dss.h> +#include <video_fb.h> -/* - * Configure VENC for a given Mode (NTSC / PAL) - */ +/* Configure VENC for a given Mode (NTSC / PAL) */ void omap3_dss_venc_config(const struct venc_regs *venc_cfg, u32 height, u32 width) { @@ -64,10 +63,8 @@ void omap3_dss_venc_config(const struct venc_regs *venc_cfg, writel(venc_cfg->savid__eavid, &venc->savid__eavid); writel(venc_cfg->flen__fal, &venc->flen__fal); writel(venc_cfg->lal__phase_reset, &venc->lal__phase_reset); - writel(venc_cfg->hs_int_start_stop_x, - &venc->hs_int_start_stop_x); - writel(venc_cfg->hs_ext_start_stop_x, - &venc->hs_ext_start_stop_x); + writel(venc_cfg->hs_int_start_stop_x, &venc->hs_int_start_stop_x); + writel(venc_cfg->hs_ext_start_stop_x, &venc->hs_ext_start_stop_x); writel(venc_cfg->vs_int_start_x, &venc->vs_int_start_x); writel(venc_cfg->vs_int_stop_x__vs_int_start_y, &venc->vs_int_stop_x__vs_int_start_y); @@ -93,39 +90,79 @@ void omap3_dss_venc_config(const struct venc_regs *venc_cfg, writel(venc_cfg->dac_b__dac_c, &venc->dac_b__dac_c); /* Configure DSS for VENC Settings */ - writel(VENC_DSS_CONFIG, &dss->control); + writel(VENC_CLK_ENABLE | DAC_DEMEN | DAC_POWERDN | VENC_OUT_SEL, + &dss->control); /* Configure height and width for Digital out */ - writel(((height << DIG_LPP_SHIFT) | width), &dispc->size_dig); + writel(height << DIG_LPP_SHIFT | width, &dispc->size_dig); } -/* - * Configure Panel Specific Parameters - */ +/* Configure Panel Specific Parameters */ void omap3_dss_panel_config(const struct panel_config *panel_cfg) { struct dispc_regs *dispc = (struct dispc_regs *) OMAP3_DISPC_BASE; + struct dss_regs *dss = (struct dss_regs *) OMAP3_DSS_BASE; + + writel(DSS_SOFTRESET, &dss->sysconfig); + while (!(readl(&dss->sysstatus) & DSS_RESETDONE)) + ; writel(panel_cfg->timing_h, &dispc->timing_h); writel(panel_cfg->timing_v, &dispc->timing_v); writel(panel_cfg->pol_freq, &dispc->pol_freq); writel(panel_cfg->divisor, &dispc->divisor); writel(panel_cfg->lcd_size, &dispc->size_lcd); - writel((panel_cfg->load_mode << FRAME_MODE_SHIFT), &dispc->config); - writel(((panel_cfg->panel_type << TFTSTN_SHIFT) | - (panel_cfg->data_lines << DATALINES_SHIFT)), &dispc->control); + writel(panel_cfg->load_mode << FRAME_MODE_SHIFT, &dispc->config); + writel(panel_cfg->panel_type << TFTSTN_SHIFT | + panel_cfg->data_lines << DATALINES_SHIFT, &dispc->control); writel(panel_cfg->panel_color, &dispc->default_color0); + writel((u32) panel_cfg->frame_buffer, &dispc->gfx_ba0); + + if (!panel_cfg->frame_buffer) + return; + + writel(panel_cfg->load_mode << LOADMODE_SHIFT, &dispc->config); + writel(8 << GFX_FORMAT_SHIFT | GFX_ENABLE, &dispc->gfx_attributes); + writel(1, &dispc->gfx_row_inc); + writel(1, &dispc->gfx_pixel_inc); + writel(panel_cfg->lcd_size, &dispc->gfx_size); } -/* - * Enable LCD and DIGITAL OUT in DSS - */ +/* Enable LCD and DIGITAL OUT in DSS */ void omap3_dss_enable(void) { struct dispc_regs *dispc = (struct dispc_regs *) OMAP3_DISPC_BASE; - u32 l = 0; + u32 l; l = readl(&dispc->control); - l |= DISPC_ENABLE; + l |= LCD_ENABLE | GO_LCD | DIG_ENABLE | GO_DIG | GP_OUT0 | GP_OUT1; writel(l, &dispc->control); } + +#ifdef CONFIG_CFB_CONSOLE +int __board_video_init(void) +{ + return -1; +} + +int board_video_init(void) + __attribute__((weak, alias("__board_video_init"))); + +void *video_hw_init(void) +{ + static GraphicDevice dssfb; + GraphicDevice *pGD = &dssfb; + struct dispc_regs *dispc = (struct dispc_regs *) OMAP3_DISPC_BASE; + + if (board_video_init() || !readl(&dispc->gfx_ba0)) + return NULL; + + pGD->winSizeX = (readl(&dispc->size_lcd) & 0x7FF) + 1; + pGD->winSizeY = ((readl(&dispc->size_lcd) >> 16) & 0x7FF) + 1; + pGD->gdfBytesPP = 4; + pGD->gdfIndex = GDF_32BIT_X888RGB; + pGD->frameAdrs = readl(&dispc->gfx_ba0); + + return pGD; +} +#endif diff --git a/drivers/video/s6e8ax0.c b/drivers/video/s6e8ax0.c index 1ec7fd6..176c518 100644 --- a/drivers/video/s6e8ax0.c +++ b/drivers/video/s6e8ax0.c @@ -28,6 +28,7 @@ static void s6e8ax0_panel_cond(struct mipi_dsim_device *dsim_dev) { struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; + int reverse = dsim_dev->dsim_lcd_dev->reverse_panel; const unsigned char data_to_send[] = { 0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x4c, 0x6e, 0x10, 0x27, 0x7d, 0x3f, 0x10, 0x00, 0x00, 0x20, @@ -36,8 +37,22 @@ static void s6e8ax0_panel_cond(struct mipi_dsim_device *dsim_dev) 0xff, 0xff, 0xc8 }; - ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + const unsigned char data_to_send_reverse[] = { + 0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, + 0x7d, 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, + 0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, + 0x23, 0x23, 0xc0, 0xc1, 0x01, 0x41, 0xc1, 0x00, 0xc1, + 0xf6, 0xf6, 0xc1 + }; + + if (reverse) { + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)data_to_send_reverse, + ARRAY_SIZE(data_to_send_reverse)); + } else { + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, (unsigned int)data_to_send, ARRAY_SIZE(data_to_send)); + } } static void s6e8ax0_display_cond(struct mipi_dsim_device *dsim_dev) @@ -55,11 +70,11 @@ static void s6e8ax0_display_cond(struct mipi_dsim_device *dsim_dev) static void s6e8ax0_gamma_cond(struct mipi_dsim_device *dsim_dev) { struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; - /* 7500K 2.2 Set (M3, 300cd) */ + /* 7500K 2.2 Set : 30cd */ const unsigned char data_to_send[] = { - 0xfa, 0x01, 0x0f, 0x00, 0x0f, 0xda, 0xc0, 0xe4, 0xc8, - 0xc8, 0xc6, 0xd3, 0xd6, 0xd0, 0xab, 0xb2, 0xa6, 0xbf, - 0xc2, 0xb9, 0x00, 0x93, 0x00, 0x86, 0x00, 0xd1 + 0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad, + 0xaf, 0xba, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1, + 0xdc, 0xc0, 0x00, 0x61, 0x00, 0x5a, 0x00, 0x74, }; ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, |