From 55bd85311d5fb0546571f86e4ebd0b93182a34bb Mon Sep 17 00:00:00 2001 From: daeinki Date: Thu, 3 Dec 2009 17:08:07 +0900 Subject: [PATCH] s5pc110: fb: updated framebuffer and lcd panel driver. Signed-off-by: daeinki --- drivers/video/ams701ka.c | 32 ++++++++--------- drivers/video/s5p-fb.c | 60 +++++++++++++++++++++++++------- drivers/video/s5p-fb.h | 6 ++-- drivers/video/s6e63m0.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 153 insertions(+), 34 deletions(-) diff --git a/drivers/video/ams701ka.c b/drivers/video/ams701ka.c index a8ee529..80e9148 100644 --- a/drivers/video/ams701ka.c +++ b/drivers/video/ams701ka.c @@ -101,6 +101,7 @@ const unsigned short SEQ_STANDBY_OFF[] = { const unsigned short GAMMA_SETTING[] = { 0x3f, 0x0000, /* gamma setting : ams701ka */ +#if 0 /* 0.0 */ /* Low Red Gamma */ 0x4c, 0xc209, 0x4d, 0xdac8, @@ -118,7 +119,8 @@ const unsigned short GAMMA_SETTING[] = { 0x55, 0xd2c9, 0x56, 0xbcc4, 0x57, 0x00b7, -#if 0 +#endif +#if 1/* 1.0 */ /* High Red Gamma */ 0x40, 0x0720, 0x41, 0xCBA7, @@ -143,26 +145,26 @@ const unsigned short GAMMA_SETTING[] = { }; const unsigned short MANUAL_POWER_ON_SETTING[] = { 0x06, 0x0000, - - SLEEPMSEC, 30, /* FIXME */ + + SLEEPMSEC, 30, 0x06, 0x0001, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x0005, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x0007, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x000f, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x001f, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x003f, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x007f, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x00ff, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x06, 0x08ff, - SLEEPMSEC, 30, /* FIXME */ + SLEEPMSEC, 30, 0x03, 0x134A, /* ETC Register setting */ 0x04, 0x86a4, /* LTPS Power on setting VCIR=2.7V Display is not clean */ @@ -174,8 +176,8 @@ const unsigned short MANUAL_POWER_ON_SETTING[] = { }; const unsigned short SEQ_SLEEP_OUT[] = { - 0x02, 0x2300, /* Sleep Out */ - SLEEPMSEC, 1, /* FIXME */ + 0x02, 0x2300, /* Sleep Out */ + SLEEPMSEC, 1, ENDDEF, 0x0000 }; @@ -325,8 +327,6 @@ void lcd_panel_power_on(void) gpio_set_value(&gpio->gpio_j1, 4, 1); udelay(100000); - - ams701ka_panel_send_sequence(GAMMA_SETTING); ams701ka_panel_send_sequence(SEQ_SLEEP_OUT); ams701ka_panel_send_sequence(MANUAL_POWER_ON_SETTING); diff --git a/drivers/video/s5p-fb.c b/drivers/video/s5p-fb.c index ab3206a..f906387 100644 --- a/drivers/video/s5p-fb.c +++ b/drivers/video/s5p-fb.c @@ -83,8 +83,8 @@ static void read_image32(char* pImg, int x1pos, int y1pos, int x2pos, unsigned int offset_s; int i, j; - for(i = y1pos; i < y2pos; i++) { - for(j = x1pos; j < x2pos; j++) { + for (i = y1pos; i < y2pos; i++) { + for (j = x1pos; j < x2pos; j++) { offset_s = i * panel_width + j; *(pDst+offset_s) = pixel; } @@ -99,12 +99,20 @@ vidinfo_t panel_info = { .vl_tft = 1, }; +struct lcd_panel_operation { + void (*lcd_panel_init)(void); + void (*lcd_panel_power_on)(void); + void (*lcd_panel_enable)(void); +}; + +static struct lcd_panel_operation lcd_calls; + static void s5pc_lcd_init_mem(void *lcdbase, vidinfo_t *vid) { unsigned long palette_size, palette_mem_size; unsigned int fb_size; - fb_size = vid->vl_row * vid->vl_col * (vid->vl_bpix / 8); + fb_size = vid->vl_row * vid->vl_col * (vid->vl_bpix >> 3); lcd_base = lcdbase; @@ -210,14 +218,23 @@ static void draw_samsung_logo(void* lcdbase) { int x, y; - x = (panel_width - 298) / 2; - y = (panel_height - 78) / 2 - 5; + x = ((panel_width - 298) >> 1); + y = ((panel_height - 78) >> 1) - 5; _draw_samsung_logo(lcdbase, x, y, 298, 78, (unsigned short *) logo); } -static void s5pc_init_panel_info(vidinfo_t *vid) +static void s5pc_init_panel_info(vidinfo_t *vid, struct lcd_panel_operation *calls) { + if (vid == NULL) { + printf("lcd info is NULL.\n"); + return; + } + + if (calls == NULL) { + printf("lcd calls is NULL.\n"); + return; + } #if 1 vid->vl_col = 480, vid->vl_row = 800, @@ -237,6 +254,10 @@ static void s5pc_init_panel_info(vidinfo_t *vid) vid->vl_vpw = 2, /* VLW */ vid->vl_bfw = 3, /* VBP */ vid->vl_efw = 28, /* VFP */ + + calls->lcd_panel_init = s6e63m0_lcd_panel_init; + calls->lcd_panel_power_on = s6e63m0_lcd_panel_power_on; + calls->lcd_panel_enable = s6e63m0_lcd_panel_enable; #endif #if 0 vid->vl_col = 480, @@ -257,6 +278,10 @@ static void s5pc_init_panel_info(vidinfo_t *vid) vid->vl_vpw = 4, vid->vl_bfw = 8, vid->vl_efw = 8, + + calls->lcd_panel_init = /* */; + calls->lcd_panel_power_on = /* */; + calls->lcd_panel_enable = /* */; #endif #if 0 vid->vl_col = 1024, @@ -277,18 +302,29 @@ static void s5pc_init_panel_info(vidinfo_t *vid) vid->vl_vpw = 2, vid->vl_bfw = 6, vid->vl_efw = 8, + + calls->lcd_panel_init = /* */; + calls->lcd_panel_power_on = /* */; + calls->lcd_panel_enable = /* */; #endif panel_width = vid->vl_col; panel_height = vid->vl_row; } -static void lcd_panel_on(void) +static void lcd_panel_on(struct lcd_panel_operation *calls) { - lcd_panel_init(); - lcd_panel_power_on(); + if (calls == NULL) { + printf("lcd calls is NULL.\n"); + return ; + } - lcd_panel_enable(); + if (calls->lcd_panel_init) + calls->lcd_panel_init(); + if (calls->lcd_panel_power_on) + calls->lcd_panel_power_on(); + if (calls->lcd_panel_enable) + calls->lcd_panel_enable(); } void lcd_ctrl_init(void *lcdbase) @@ -298,7 +334,7 @@ void lcd_ctrl_init(void *lcdbase) s5pc_lcd_init_mem(lcdbase, &panel_info); /* initialize parameters which is specific to panel. */ - s5pc_init_panel_info(&panel_info); + s5pc_init_panel_info(&panel_info, &lcd_calls); option = getenv("lcd"); @@ -338,7 +374,7 @@ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blud) void lcd_enable(void) { - lcd_panel_on(); + lcd_panel_on((struct lcd_panel_operation *) &lcd_calls); } ulong calc_fbsize(void) diff --git a/drivers/video/s5p-fb.h b/drivers/video/s5p-fb.h index f8acac1..9bc62a3 100644 --- a/drivers/video/s5p-fb.h +++ b/drivers/video/s5p-fb.h @@ -253,9 +253,9 @@ unsigned long s5pc_fimd_calc_fbsize(void); void s5pc_c100_gpio_setup(void); void s5pc_c110_gpio_setup(void); -void lcd_panel_init(void); -void lcd_panel_power_on(void); -void lcd_panel_enable(void); +extern void s6e63m0_lcd_panel_init(void); +extern void s6e63m0_lcd_panel_power_on(void); +extern void s6e63m0_lcd_panel_enable(void); #endif diff --git a/drivers/video/s6e63m0.c b/drivers/video/s6e63m0.c index bc999e8..eb548a8 100644 --- a/drivers/video/s6e63m0.c +++ b/drivers/video/s6e63m0.c @@ -42,6 +42,8 @@ struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; #define S5PCFB_C110_SDA_LOW gpio_set_value(&gpio->gpio_mp0_4, 3, 0) #define S5PCFB_C110_SDA_HIGH gpio_set_value(&gpio->gpio_mp0_4, 3, 1) +#define S5PCFB_C110_SDA_READ gpio_get_value(&gpio->gpio_mp0_4, 3) + const unsigned short SEQ_PANEL_CONDITION_SET[] = { 0xF8, 0x01, DATA_ONLY, 0x27, @@ -109,6 +111,9 @@ const unsigned short SEQ_ETC_CONDITION_SET[] = { DATA_ONLY, 0x8c, DATA_ONLY, 0x07, + /* added */ + 0xb3, 0xc, + 0xb5, 0x2c, DATA_ONLY, 0x12, DATA_ONLY, 0x0c, @@ -275,6 +280,13 @@ const unsigned short SEQ_STAND_BY_OFF[] = { ENDDEF, 0x0000 }; +/* added */ +const unsigned short SEQ_DISPLAY_ON[] = { + 0x29, COMMAND_ONLY, + + ENDDEF, 0x0000 +}; + unsigned char DELAY=1; static void s6e63m0_c110_spi_write_byte(unsigned char address, unsigned char command) @@ -313,6 +325,72 @@ static void s6e63m0_c110_spi_write_byte(unsigned char address, unsigned char com } +static unsigned char s6e63m0_c110_spi_read_byte(unsigned char select, unsigned char address) +{ + int j; + static unsigned int first = 1; + unsigned char DELAY=1; + unsigned short data = 0; + char command = 0; + + data = (select << 8) + address; + + S5PCFB_C110_CS_HIGH; + S5PCFB_C110_SDA_HIGH; + S5PCFB_C110_CLK_HIGH; + udelay(DELAY); + + S5PCFB_C110_CS_LOW; + udelay(DELAY); + + for (j = PACKET_LEN + 8; j >= 0; j--) + { + + if (j > 7) { + S5PCFB_C110_CLK_LOW; + + /* data high or low */ + if ((data >> (j - 8)) & 0x0001) { + S5PCFB_C110_SDA_HIGH; + printf("1"); + } else { + S5PCFB_C110_SDA_LOW; + printf("0"); + } + + udelay(DELAY); + S5PCFB_C110_CLK_HIGH; + } else { + if (first) { + gpio_cfg_pin(&gpio->gpio_mp0_4, 3, GPIO_INPUT); + first = 0; + } + + S5PCFB_C110_CLK_LOW; + + if (S5PCFB_C110_SDA_READ & 0x1) { + command |= 1 << j; + printf("1"); + } else { + command |= 0 << j; + printf("0"); + } + + udelay(DELAY); + S5PCFB_C110_CLK_HIGH; + } + + udelay(DELAY); + } + + S5PCFB_C110_CS_HIGH; + udelay(DELAY); + + gpio_cfg_pin(&gpio->gpio_mp0_4, 3, GPIO_OUTPUT); + + return command; +} + static void s6e63m0_spi_write(unsigned char address, unsigned char command) { if (address != DATA_ONLY) @@ -335,14 +413,18 @@ static void s6e63m0_panel_send_sequence(const unsigned short *wbuf) } } -void lcd_panel_power_on(void) +void s6e63m0_lcd_panel_power_on(void) { + udelay(25000); + /* set gpio data for MLCD_ON to HIGH */ gpio_set_value(&gpio->gpio_j1, 3, 1); /* set gpio data for MLCD_RST to HIGH */ gpio_set_value(&gpio->gpio_mp0_5, 5, 1); + udelay(120000); + s6e63m0_panel_send_sequence(SEQ_PANEL_CONDITION_SET); s6e63m0_panel_send_sequence(SEQ_DISPLAY_CONDITION_SET); s6e63m0_panel_send_sequence(SEQ_GAMMA_SETTING); @@ -361,16 +443,17 @@ static inline void s6e63m0_c110_panel_hw_reset(void) gpio_set_value(&gpio->gpio_mp0_5, 5, 1); } -void lcd_panel_enable(void) +void s6e63m0_lcd_panel_enable(void) { s6e63m0_panel_send_sequence(SEQ_STAND_BY_OFF); + s6e63m0_panel_send_sequence(SEQ_DISPLAY_ON); } static void s6e63m0_panel_disable(void) { } -void lcd_panel_init(void) +void s6e63m0_lcd_panel_init(void) { /* set gpio pin for DISPLAY_CS to HIGH */ gpio_set_value(&gpio->gpio_mp0_1, 1, 1); -- 2.7.4