[U-Boot] [PATCH] video: support exynos fimd driver for various exynos series

This patch supports exynos fimd driver for various exynos series different from existing it supports only exynos4 chip.
Signed-off-by: Donghwa Lee dh09.lee@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- arch/arm/include/asm/arch-exynos/fb.h | 15 +++++- drivers/video/exynos_fimd.c | 85 ++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 34 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/fb.h b/arch/arm/include/asm/arch-exynos/fb.h index b10b0da..b56ab55 100644 --- a/arch/arm/include/asm/arch-exynos/fb.h +++ b/arch/arm/include/asm/arch-exynos/fb.h @@ -23,7 +23,7 @@ #define __ASM_ARM_ARCH_FB_H_
#ifndef __ASSEMBLY__ -struct exynos4_fb { +struct exynos_fb { unsigned int vidcon0; unsigned int vidcon1; unsigned int vidcon2; @@ -154,6 +154,9 @@ struct exynos4_fb { }; #endif
+/* LCD IF register offset */ +#define EXYNOS_LCD_IF_BASE_OFFSET (0x20000) + /* * Register offsets */ @@ -253,6 +256,10 @@ struct exynos4_fb { /* VIDTCON2 */ #define EXYNOS_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11) #define EXYNOS_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0) +#define EXYNOS_VIDTCON2_LINEVAL_E(x) ((((x) & 0x800) \ + >> 11) << 23) +#define EXYNOS_VIDTCON2_HOZVAL_E(x) ((((x) & 0x800) \ + >> 11) << 22)
/* Window 0~4 Control - WINCONx */ #define EXYNOS_WINCON_DATAPATH_DMA (0 << 22) @@ -330,6 +337,8 @@ struct exynos4_fb { #define EXYNOS_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0) #define EXYNOS_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11) #define EXYNOS_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0) +#define EXYNOS_VIDOSD_RIGHT_X_E(x) (((x) & 0x1) << 23) +#define EXYNOS_VIDOSD_BOTTOM_Y_E(x) (((x) & 0x1) << 22)
/* VIDOSD0C, VIDOSDxD */ #define EXYNOS_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0) @@ -354,6 +363,10 @@ struct exynos4_fb { /* Buffer Size */ #define EXYNOS_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13) #define EXYNOS_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0) +#define EXYNOS_VIDADDR_OFFSIZE_E(x) ((((x) & 0x2000) \ + >> 13) << 27) +#define EXYNOS_VIDADDR_PAGEWIDTH_E(x) ((((x) & 0x2000) \ + >> 13) << 26)
/* WIN Color Map */ #define EXYNOS_WINMAP_COLOR(x) ((x) & 0xffffff) diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c index f07568a..f8eac9d 100644 --- a/drivers/video/exynos_fimd.c +++ b/drivers/video/exynos_fimd.c @@ -41,8 +41,8 @@ void exynos_fimd_lcd_init_mem(u_long screen_base, u_long fb_size,
static void exynos_fimd_set_dualrgb(unsigned int enabled) { - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd(); unsigned int cfg = 0;
if (enabled) { @@ -60,8 +60,8 @@ static void exynos_fimd_set_dualrgb(unsigned int enabled) static void exynos_fimd_set_par(unsigned int win_id) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
/* set window control */ cfg = readl((unsigned int)&fimd_ctrl->wincon0 + @@ -93,7 +93,10 @@ static void exynos_fimd_set_par(unsigned int win_id) EXYNOS_VIDOSD(win_id));
cfg = EXYNOS_VIDOSD_RIGHT_X(pvid->vl_col - 1) | - EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1); + EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1) | + EXYNOS_VIDOSD_RIGHT_X_E(1) | + EXYNOS_VIDOSD_BOTTOM_Y_E(0); + writel(cfg, (unsigned int)&fimd_ctrl->vidosd0b + EXYNOS_VIDOSD(win_id));
@@ -106,8 +109,8 @@ static void exynos_fimd_set_par(unsigned int win_id) static void exynos_fimd_set_buffer_address(unsigned int win_id) { unsigned long start_addr, end_addr; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
start_addr = (unsigned long)lcd_base_addr; end_addr = start_addr + ((pvid->vl_col * (NBITS(pvid->vl_bpix) / 8)) * @@ -124,8 +127,8 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) unsigned int cfg = 0, div = 0, remainder, remainder_div; unsigned long pixel_clock; unsigned long long src_clock; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
if (pvid->dual_lcd_enabled) { pixel_clock = pvid->vl_freq * @@ -153,9 +156,6 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS | EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED);
- if (pixel_clock > MAX_CLOCK) - pixel_clock = MAX_CLOCK; - src_clock = (unsigned long long) get_lcd_clk();
/* get quotient and remainder. */ @@ -180,8 +180,8 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) void exynos_set_trigger(void) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
cfg = readl(&fimd_ctrl->trigcon);
@@ -194,8 +194,8 @@ int exynos_is_i80_frame_done(void) { unsigned int cfg = 0; int status; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
cfg = readl(&fimd_ctrl->trigcon);
@@ -209,8 +209,8 @@ int exynos_is_i80_frame_done(void) static void exynos_fimd_lcd_on(void) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
/* display on */ cfg = readl(&fimd_ctrl->vidcon0); @@ -221,8 +221,8 @@ static void exynos_fimd_lcd_on(void) static void exynos_fimd_window_on(unsigned int win_id) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
/* enable window */ cfg = readl((unsigned int)&fimd_ctrl->wincon0 + @@ -239,8 +239,8 @@ static void exynos_fimd_window_on(unsigned int win_id) void exynos_fimd_lcd_off(void) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
cfg = readl(&fimd_ctrl->vidcon0); cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE); @@ -250,8 +250,8 @@ void exynos_fimd_lcd_off(void) void exynos_fimd_window_off(unsigned int win_id) { unsigned int cfg = 0; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd();
cfg = readl((unsigned int)&fimd_ctrl->wincon0 + EXYNOS_WINCON(win_id)); @@ -264,11 +264,22 @@ void exynos_fimd_window_off(unsigned int win_id) writel(cfg, &fimd_ctrl->winshmap); }
+static unsigned int exynos_fimd_get_base_offset(void) +{ + if (cpu_is_exynos5()) + return EXYNOS_LCD_IF_BASE_OFFSET; + else + return 0x0; +} + void exynos_fimd_lcd_init(vidinfo_t *vid) { unsigned int cfg = 0, rgb_mode; - struct exynos4_fb *fimd_ctrl = - (struct exynos4_fb *)samsung_get_base_fimd(); + unsigned int offset; + struct exynos_fb *fimd_ctrl = + (struct exynos_fb *)samsung_get_base_fimd(); + + offset = exynos_fimd_get_base_offset();
/* store panel info to global variable */ pvid = vid; @@ -297,25 +308,27 @@ void exynos_fimd_lcd_init(vidinfo_t *vid) if (!pvid->vl_dp) cfg |= EXYNOS_VIDCON1_IVDEN_INVERT;
- writel(cfg, &fimd_ctrl->vidcon1); + writel(cfg, (unsigned int)&fimd_ctrl->vidcon1 + offset);
/* set timing */ cfg = EXYNOS_VIDTCON0_VFPD(pvid->vl_vfpd - 1); cfg |= EXYNOS_VIDTCON0_VBPD(pvid->vl_vbpd - 1); cfg |= EXYNOS_VIDTCON0_VSPW(pvid->vl_vspw - 1); - writel(cfg, &fimd_ctrl->vidtcon0); + writel(cfg, (unsigned int)&fimd_ctrl->vidtcon0 + offset);
cfg = EXYNOS_VIDTCON1_HFPD(pvid->vl_hfpd - 1); cfg |= EXYNOS_VIDTCON1_HBPD(pvid->vl_hbpd - 1); cfg |= EXYNOS_VIDTCON1_HSPW(pvid->vl_hspw - 1);
- writel(cfg, &fimd_ctrl->vidtcon1); + writel(cfg, (unsigned int)&fimd_ctrl->vidtcon1 + offset);
/* set lcd size */ - cfg = EXYNOS_VIDTCON2_HOZVAL(pvid->vl_col - 1); - cfg |= EXYNOS_VIDTCON2_LINEVAL(pvid->vl_row - 1); + cfg = EXYNOS_VIDTCON2_HOZVAL(pvid->vl_col - 1) | + EXYNOS_VIDTCON2_LINEVAL(pvid->vl_row - 1) | + EXYNOS_VIDTCON2_HOZVAL_E(pvid->vl_col - 1) | + EXYNOS_VIDTCON2_LINEVAL_E(pvid->vl_row - 1);
- writel(cfg, &fimd_ctrl->vidtcon2); + writel(cfg, (unsigned int)&fimd_ctrl->vidtcon2 + offset); }
/* set display mode */ @@ -331,7 +344,13 @@ void exynos_fimd_lcd_init(vidinfo_t *vid) exynos_fimd_set_buffer_address(pvid->win_id);
/* set buffer size */ - cfg = EXYNOS_VIDADDR_PAGEWIDTH(pvid->vl_col * NBITS(pvid->vl_bpix) / 8); + cfg = EXYNOS_VIDADDR_PAGEWIDTH(pvid->vl_col * + NBITS(pvid->vl_bpix) / 8) | + EXYNOS_VIDADDR_PAGEWIDTH_E(pvid->vl_col * + NBITS(pvid->vl_bpix) / 8) | + EXYNOS_VIDADDR_OFFSIZE(0) | + EXYNOS_VIDADDR_OFFSIZE_E(0); + writel(cfg, (unsigned int)&fimd_ctrl->vidw00add2 + EXYNOS_BUFFER_SIZE(pvid->win_id));

Dear Donghwa,
On 2 July 2012 11:22, Donghwa Lee dh09.lee@samsung.com wrote:
This patch supports exynos fimd driver for various exynos series different from existing it supports only exynos4 chip.
Signed-off-by: Donghwa Lee dh09.lee@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
arch/arm/include/asm/arch-exynos/fb.h | 15 +++++- drivers/video/exynos_fimd.c | 85 ++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 34 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/fb.h b/arch/arm/include/asm/arch-exynos/fb.h index b10b0da..b56ab55 100644 --- a/arch/arm/include/asm/arch-exynos/fb.h +++ b/arch/arm/include/asm/arch-exynos/fb.h @@ -23,7 +23,7 @@ #define __ASM_ARM_ARCH_FB_H_
#ifndef __ASSEMBLY__ -struct exynos4_fb { +struct exynos_fb { unsigned int vidcon0; unsigned int vidcon1; unsigned int vidcon2; @@ -154,6 +154,9 @@ struct exynos4_fb { }; #endif
+/* LCD IF register offset */ +#define EXYNOS_LCD_IF_BASE_OFFSET (0x20000)
for exynos4? or exynos5?
/*
- Register offsets
*/ @@ -253,6 +256,10 @@ struct exynos4_fb { /* VIDTCON2 */ #define EXYNOS_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11) #define EXYNOS_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0) +#define EXYNOS_VIDTCON2_LINEVAL_E(x) ((((x) & 0x800) \
>> 11) << 23)
+#define EXYNOS_VIDTCON2_HOZVAL_E(x) ((((x) & 0x800) \
>> 11) << 22)
/* Window 0~4 Control - WINCONx */ #define EXYNOS_WINCON_DATAPATH_DMA (0 << 22) @@ -330,6 +337,8 @@ struct exynos4_fb { #define EXYNOS_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0) #define EXYNOS_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11) #define EXYNOS_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0) +#define EXYNOS_VIDOSD_RIGHT_X_E(x) (((x) & 0x1) << 23) +#define EXYNOS_VIDOSD_BOTTOM_Y_E(x) (((x) & 0x1) << 22)
/* VIDOSD0C, VIDOSDxD */ #define EXYNOS_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0) @@ -354,6 +363,10 @@ struct exynos4_fb { /* Buffer Size */ #define EXYNOS_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13) #define EXYNOS_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0) +#define EXYNOS_VIDADDR_OFFSIZE_E(x) ((((x) & 0x2000) \
>> 13) << 27)
+#define EXYNOS_VIDADDR_PAGEWIDTH_E(x) ((((x) & 0x2000) \
>> 13) << 26)
/* WIN Color Map */ #define EXYNOS_WINMAP_COLOR(x) ((x) & 0xffffff) diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c index f07568a..f8eac9d 100644 --- a/drivers/video/exynos_fimd.c +++ b/drivers/video/exynos_fimd.c @@ -41,8 +41,8 @@ void exynos_fimd_lcd_init_mem(u_long screen_base, u_long fb_size,
static void exynos_fimd_set_dualrgb(unsigned int enabled) {
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); unsigned int cfg = 0; if (enabled) {
@@ -60,8 +60,8 @@ static void exynos_fimd_set_dualrgb(unsigned int enabled) static void exynos_fimd_set_par(unsigned int win_id) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); /* set window control */ cfg = readl((unsigned int)&fimd_ctrl->wincon0 +
@@ -93,7 +93,10 @@ static void exynos_fimd_set_par(unsigned int win_id) EXYNOS_VIDOSD(win_id));
cfg = EXYNOS_VIDOSD_RIGHT_X(pvid->vl_col - 1) |
EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1);
EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1) |
EXYNOS_VIDOSD_RIGHT_X_E(1) |
EXYNOS_VIDOSD_BOTTOM_Y_E(0);
writel(cfg, (unsigned int)&fimd_ctrl->vidosd0b + EXYNOS_VIDOSD(win_id));
@@ -106,8 +109,8 @@ static void exynos_fimd_set_par(unsigned int win_id) static void exynos_fimd_set_buffer_address(unsigned int win_id) { unsigned long start_addr, end_addr;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); start_addr = (unsigned long)lcd_base_addr; end_addr = start_addr + ((pvid->vl_col * (NBITS(pvid->vl_bpix) / 8)) *
@@ -124,8 +127,8 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) unsigned int cfg = 0, div = 0, remainder, remainder_div; unsigned long pixel_clock; unsigned long long src_clock;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); if (pvid->dual_lcd_enabled) { pixel_clock = pvid->vl_freq *
@@ -153,9 +156,6 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS | EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED);
if (pixel_clock > MAX_CLOCK)
pixel_clock = MAX_CLOCK;
src_clock = (unsigned long long) get_lcd_clk(); /* get quotient and remainder. */
@@ -180,8 +180,8 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) void exynos_set_trigger(void) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); cfg = readl(&fimd_ctrl->trigcon);
@@ -194,8 +194,8 @@ int exynos_is_i80_frame_done(void) { unsigned int cfg = 0; int status;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); cfg = readl(&fimd_ctrl->trigcon);
@@ -209,8 +209,8 @@ int exynos_is_i80_frame_done(void) static void exynos_fimd_lcd_on(void) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); /* display on */ cfg = readl(&fimd_ctrl->vidcon0);
@@ -221,8 +221,8 @@ static void exynos_fimd_lcd_on(void) static void exynos_fimd_window_on(unsigned int win_id) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); /* enable window */ cfg = readl((unsigned int)&fimd_ctrl->wincon0 +
@@ -239,8 +239,8 @@ static void exynos_fimd_window_on(unsigned int win_id) void exynos_fimd_lcd_off(void) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); cfg = readl(&fimd_ctrl->vidcon0); cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE);
@@ -250,8 +250,8 @@ void exynos_fimd_lcd_off(void) void exynos_fimd_window_off(unsigned int win_id) { unsigned int cfg = 0;
struct exynos4_fb *fimd_ctrl =
(struct exynos4_fb *)samsung_get_base_fimd();
struct exynos_fb *fimd_ctrl =
(struct exynos_fb *)samsung_get_base_fimd(); cfg = readl((unsigned int)&fimd_ctrl->wincon0 + EXYNOS_WINCON(win_id));
@@ -264,11 +264,22 @@ void exynos_fimd_window_off(unsigned int win_id) writel(cfg, &fimd_ctrl->winshmap); }
+static unsigned int exynos_fimd_get_base_offset(void) +{
if (cpu_is_exynos5())
return EXYNOS_LCD_IF_BASE_OFFSET;
else
return 0x0;
+}
Please move this function to header file.
Thanks. Minkyu Kang.
participants (2)
-
Donghwa Lee
-
Minkyu Kang