From 9654496b476a12bcb3924098c89eb76a23316260 Mon Sep 17 00:00:00 2001 From: daeinki Date: Fri, 18 Dec 2009 11:43:08 +0900 Subject: [PATCH] s5pc110: added Cypress lcd support and updated lcd driver. 1. Cypress lcd panel on. 2. changed panel parameter names to more generic. 3. updated s6e63m0 lcd driver. Signed-off-by: daeinki --- board/samsung/universal/universal.c | 121 ++++++++++++++++++++++------------- drivers/video/s5p-fimd.c | 18 +++--- drivers/video/s6e63m0.c | 124 ++++++++++++++++++++++++------------ include/lcd.h | 12 ++-- 4 files changed, 175 insertions(+), 100 deletions(-) diff --git a/board/samsung/universal/universal.c b/board/samsung/universal/universal.c index 60f579c..2f882ff 100644 --- a/board/samsung/universal/universal.c +++ b/board/samsung/universal/universal.c @@ -1363,75 +1363,110 @@ static void setup_power_down_mode_registers(void) } #ifdef CONFIG_LCD +struct s6e63m0_platform_data { + struct s5pc1xx_gpio_bank *bank; + unsigned int num; +}; + +extern void s6e63m0_set_spi_interface(struct s6e63m0_platform_data *cs, + struct s6e63m0_platform_data *clk, struct s6e63m0_platform_data *si, + struct s6e63m0_platform_data *so); + +struct s6e63m0_platform_data pd_cs, pd_clk, pd_si, pd_so; +struct s5pc110_gpio *gpio_base = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; + void lcd_cfg_gpio(void) { unsigned int i; - struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; for (i = 0; i < 8; i++) { /* set GPF0,1,2[0:7] for RGB Interface and Data lines (32bit) */ - gpio_cfg_pin(&gpio->gpio_f0, i, GPIO_FUNC(2)); - gpio_cfg_pin(&gpio->gpio_f1, i, GPIO_FUNC(2)); - gpio_cfg_pin(&gpio->gpio_f2, i, GPIO_FUNC(2)); + gpio_cfg_pin(&gpio_base->gpio_f0, i, GPIO_FUNC(2)); + gpio_cfg_pin(&gpio_base->gpio_f1, i, GPIO_FUNC(2)); + gpio_cfg_pin(&gpio_base->gpio_f2, i, GPIO_FUNC(2)); /* pull-up/down disable */ - gpio_set_pull(&gpio->gpio_f0, i, GPIO_PULL_NONE); - gpio_set_pull(&gpio->gpio_f1, i, GPIO_PULL_NONE); - gpio_set_pull(&gpio->gpio_f2, i, GPIO_PULL_NONE); + gpio_set_pull(&gpio_base->gpio_f0, i, GPIO_PULL_NONE); + gpio_set_pull(&gpio_base->gpio_f1, i, GPIO_PULL_NONE); + gpio_set_pull(&gpio_base->gpio_f2, i, GPIO_PULL_NONE); /* drive strength to max (24bit) */ - gpio_set_drv(&gpio->gpio_f0, i, GPIO_DRV_4x); - gpio_set_rate(&gpio->gpio_f0, i, GPIO_DRV_SLOW); - gpio_set_drv(&gpio->gpio_f1, i, GPIO_DRV_4x); - gpio_set_rate(&gpio->gpio_f1, i, GPIO_DRV_SLOW); - gpio_set_drv(&gpio->gpio_f2, i, GPIO_DRV_4x); - gpio_set_rate(&gpio->gpio_f2, i, GPIO_DRV_SLOW); + gpio_set_drv(&gpio_base->gpio_f0, i, GPIO_DRV_4x); + gpio_set_rate(&gpio_base->gpio_f0, i, GPIO_DRV_SLOW); + gpio_set_drv(&gpio_base->gpio_f1, i, GPIO_DRV_4x); + gpio_set_rate(&gpio_base->gpio_f1, i, GPIO_DRV_SLOW); + gpio_set_drv(&gpio_base->gpio_f2, i, GPIO_DRV_4x); + gpio_set_rate(&gpio_base->gpio_f2, i, GPIO_DRV_SLOW); } for (i =0; i < 4; i++) { /* set GPF3[0:3] for RGB Interface and Data lines (32bit) */ - gpio_cfg_pin(&gpio->gpio_f3, i, GPIO_PULL_UP); + gpio_cfg_pin(&gpio_base->gpio_f3, i, GPIO_PULL_UP); /* pull-up/down disable */ - gpio_set_pull(&gpio->gpio_f3, i, GPIO_PULL_NONE); + gpio_set_pull(&gpio_base->gpio_f3, i, GPIO_PULL_NONE); /* drive strength to max (24bit) */ - gpio_set_drv(&gpio->gpio_f3, i, GPIO_DRV_4x); - gpio_set_rate(&gpio->gpio_f3, i, GPIO_DRV_SLOW); + gpio_set_drv(&gpio_base->gpio_f3, i, GPIO_DRV_4x); + gpio_set_rate(&gpio_base->gpio_f3, i, GPIO_DRV_SLOW); } /* display output path selection (only [1:0] valid) */ writel(0x2, 0xE0107008); /* gpio pad configuration for LCD reset. */ - gpio_cfg_pin(&gpio->gpio_mp0_5, 5, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_5, 5, GPIO_OUTPUT); /* gpio pad configuration for LCD ON. */ - gpio_cfg_pin(&gpio->gpio_j1, 3, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_j1, 3, GPIO_OUTPUT); /* MLCD_ON2 */ /* if (board_is_p2_real()) - gpio_cfg_pin(&gpio->gpio_j1, 4, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_j1, 4, GPIO_OUTPUT); */ /* LCD_BACKLIGHT_EN */ if (machine_is_geminus()) - gpio_cfg_pin(&gpio->gpio_mp0_5, 0, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_5, 0, GPIO_OUTPUT); /* gpio pad configuration for DISPLAY_CS, DISPLAY_CLK, DISPLAY_SO, DISPLAY_SI. */ - gpio_cfg_pin(&gpio->gpio_mp0_1, 1, GPIO_OUTPUT); - gpio_cfg_pin(&gpio->gpio_mp0_4, 1, GPIO_OUTPUT); - gpio_cfg_pin(&gpio->gpio_mp0_4, 2, GPIO_INPUT); - gpio_cfg_pin(&gpio->gpio_mp0_4, 3, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_1, 1, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 1, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 2, GPIO_INPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 3, GPIO_OUTPUT); + + if (machine_is_aquila()) { + pd_cs.bank = &gpio_base->gpio_mp0_1; + pd_cs.num = 1; + pd_clk.bank = &gpio_base->gpio_mp0_4; + pd_clk.num = 1; + pd_si.bank = &gpio_base->gpio_mp0_4; + pd_si.num = 3; + pd_so.bank = &gpio_base->gpio_mp0_4; + pd_so.num = 2; + + /* these data would be sent to s6e63m0 lcd panel driver. */ + s6e63m0_set_spi_interface(&pd_cs, &pd_clk, &pd_si, &pd_so); + } if (machine_is_cypress()) { /* FLCD_CS */ - gpio_cfg_pin(&gpio->gpio_mp0_1, 0, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_1, 0, GPIO_OUTPUT); /* FLCD_CLK */ - gpio_cfg_pin(&gpio->gpio_mp0_4, 0, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 0, GPIO_OUTPUT); /* FLCD_SDI */ - gpio_cfg_pin(&gpio->gpio_mp0_4, 2, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 2, GPIO_OUTPUT); /* FLCD_RST_S */ - gpio_cfg_pin(&gpio->gpio_mp0_4, 5, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_mp0_4, 5, GPIO_OUTPUT); /* FLCD_ON_S */ - gpio_cfg_pin(&gpio->gpio_g2, 2, GPIO_OUTPUT); + gpio_cfg_pin(&gpio_base->gpio_g2, 2, GPIO_OUTPUT); + + pd_cs.bank = &gpio_base->gpio_mp0_1; + pd_cs.num = 0; + pd_clk.bank = &gpio_base->gpio_mp0_4; + pd_clk.num = 0; + pd_si.bank = &gpio_base->gpio_mp0_4; + pd_si.num = 2; + + /* these data would be sent to s6e63m0 lcd panel driver. */ + s6e63m0_set_spi_interface(&pd_cs, &pd_clk, &pd_si, NULL); } return; @@ -1518,15 +1553,15 @@ void init_panel_info(vidinfo_t *vid) vid->vl_bpix = 32; /* S6E63M0 LCD Panel */ - vid->vl_hpw = 2; /* HLW */ - vid->vl_blw = 16; /* HBP */ - vid->vl_elw = 16; /* HFP */ + vid->vl_hspw = 2; + vid->vl_hbpd = 16; + vid->vl_hfpd = 16; - vid->vl_vpw = 2; /* VLW */ - vid->vl_bfw = 3; /* VBP */ - vid->vl_efw = 28; /* VFP */ + vid->vl_vspw = 2; + vid->vl_vbpd = 3; + vid->vl_vfpd = 28; - if (machine_is_aquila()) { + if (machine_is_aquila() || machine_is_cypress()) { vid->cfg_gpio = lcd_cfg_gpio; vid->reset_lcd = reset_lcd; vid->backlight_on = backlight_on; @@ -1551,13 +1586,13 @@ void init_panel_info(vidinfo_t *vid) vid->vl_dp = CONFIG_SYS_LOW, vid->vl_bpix = 32, - vid->vl_hpw = 32, - vid->vl_blw = 80, - vid->vl_elw = 48, + vid->vl_hspw = 32, + vid->vl_hfpd = 48, + vid->vl_hbpd = 80, - vid->vl_vpw = 1, - vid->vl_bfw = 4, - vid->vl_efw = 3, + vid->vl_vspw = 1, + vid->vl_vfpd = 3, + vid->vl_vbpd = 4, vid->cfg_gpio = lcd_cfg_gpio; vid->reset_lcd = reset_lcd; diff --git a/drivers/video/s5p-fimd.c b/drivers/video/s5p-fimd.c index 4fe1ff8..e0ca5c2 100644 --- a/drivers/video/s5p-fimd.c +++ b/drivers/video/s5p-fimd.c @@ -125,9 +125,9 @@ static void s5pc_fimd_set_clock(void) max_clock = 66 * 1000000; - pixel_clock = pvid->vl_freq * (pvid->vl_hpw + pvid->vl_blw + - pvid->vl_elw + pvid->vl_width) * (pvid->vl_vpw + - pvid->vl_bfw + pvid->vl_efw + pvid->vl_height); + pixel_clock = pvid->vl_freq * (pvid->vl_hspw + pvid->vl_hfpd + + pvid->vl_hbpd + pvid->vl_width) * (pvid->vl_vspw + + pvid->vl_vfpd + pvid->vl_vbpd + pvid->vl_height); if (get_pll_clk == NULL) { printf("get_pll_clk is null.\n"); @@ -241,16 +241,16 @@ void s5pc_fimd_lcd_init(vidinfo_t *vid) /* set timing */ cfg = 0; - cfg |= S5P_VIDTCON0_VBPD(pvid->vl_bfw - 1); - cfg |= S5P_VIDTCON0_VFPD(pvid->vl_efw - 1); - cfg |= S5P_VIDTCON0_VSPW(pvid->vl_vpw - 1); + cfg |= S5P_VIDTCON0_VFPD(pvid->vl_vfpd - 1); + cfg |= S5P_VIDTCON0_VBPD(pvid->vl_vbpd - 1); + cfg |= S5P_VIDTCON0_VSPW(pvid->vl_vspw - 1); writel(cfg, ctrl_base + S5P_VIDTCON0); udebug("vidtcon0 = %x\n", cfg); cfg = 0; - cfg |= S5P_VIDTCON1_HBPD(pvid->vl_blw - 1); - cfg |= S5P_VIDTCON1_HFPD(pvid->vl_elw - 1); - cfg |= S5P_VIDTCON1_HSPW(pvid->vl_hpw - 1); + cfg |= S5P_VIDTCON1_HFPD(pvid->vl_hfpd - 1); + cfg |= S5P_VIDTCON1_HBPD(pvid->vl_hbpd - 1); + cfg |= S5P_VIDTCON1_HSPW(pvid->vl_hspw - 1); writel(cfg, ctrl_base + S5P_VIDTCON1); udebug("vidtcon1 = %x\n", cfg); diff --git a/drivers/video/s6e63m0.c b/drivers/video/s6e63m0.c index ebe8774..8ed40ca 100644 --- a/drivers/video/s6e63m0.c +++ b/drivers/video/s6e63m0.c @@ -25,8 +25,6 @@ #include #include -struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; - #define SLEEPMSEC 0x1000 #define ENDDEF 0x2000 #define DEFMASK 0xFF00 @@ -35,14 +33,50 @@ struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; #define PACKET_LEN 8 -#define S5PCFB_C110_CS_LOW gpio_set_value(&gpio->gpio_mp0_1, 1, 0) -#define S5PCFB_C110_CS_HIGH gpio_set_value(&gpio->gpio_mp0_1, 1, 1) -#define S5PCFB_C110_CLK_LOW gpio_set_value(&gpio->gpio_mp0_4, 1, 0) -#define S5PCFB_C110_CLK_HIGH gpio_set_value(&gpio->gpio_mp0_4, 1, 1) -#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) +struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE; + +struct s6e63m0_platform_data { + struct s5pc1xx_gpio_bank *bank; + unsigned int num; +}; + +/* these machine specific platform datas would be setting at universal.c */ +struct s6e63m0_platform_data *spi_cs, *spi_clk, *spi_si, *spi_so; + +void cs_low(void) +{ + gpio_set_value(spi_cs->bank, spi_cs->num, 0); +} + +void cs_high(void) +{ + gpio_set_value(spi_cs->bank, spi_cs->num, 1); +} -#define S5PCFB_C110_SDA_READ gpio_get_value(&gpio->gpio_mp0_4, 3) +void clk_low(void) +{ + gpio_set_value(spi_clk->bank, spi_clk->num, 0); +} + +void clk_high(void) +{ + gpio_set_value(spi_clk->bank, spi_clk->num, 1); +} + +void si_low(void) +{ + gpio_set_value(spi_si->bank, spi_si->num, 0); +} + +void si_high(void) +{ + gpio_set_value(spi_si->bank, spi_si->num, 1); +} + +char so_read(void) +{ + return gpio_get_value(spi_so->bank, spi_so->num); +} static const unsigned short SEQ_PANEL_CONDITION_SET[] = { 0xF8, 0x01, @@ -301,31 +335,31 @@ static void s6e63m0_c110_spi_write_byte(unsigned char address, unsigned char com data = (address << 8) + command; - S5PCFB_C110_CS_HIGH; - S5PCFB_C110_SDA_HIGH; - S5PCFB_C110_CLK_HIGH; + cs_high(); + si_high(); + clk_high(); udelay(DELAY); - S5PCFB_C110_CS_LOW; + cs_low(); udelay(DELAY); for (j = PACKET_LEN; j >= 0; j--) { - S5PCFB_C110_CLK_LOW; + clk_low(); /* data high or low */ if ((data >> j) & 0x0001) - S5PCFB_C110_SDA_HIGH; + si_high(); else - S5PCFB_C110_SDA_LOW; + si_low(); udelay(DELAY); - S5PCFB_C110_CLK_HIGH; + clk_high(); udelay(DELAY); } - S5PCFB_C110_CS_HIGH; + cs_high(); udelay(DELAY); } @@ -340,52 +374,52 @@ static unsigned char s6e63m0_c110_spi_read_byte(unsigned char select, unsigned c data = (select << 8) + address; - S5PCFB_C110_CS_HIGH; - S5PCFB_C110_SDA_HIGH; - S5PCFB_C110_CLK_HIGH; + cs_high(); + si_high(); + clk_high(); udelay(DELAY); - S5PCFB_C110_CS_LOW; + clk_low(); udelay(DELAY); for (j = PACKET_LEN + 8; j >= 0; j--) { if (j > 7) { - S5PCFB_C110_CLK_LOW; + clk_low(); /* data high or low */ if ((data >> (j - 8)) & 0x0001) - S5PCFB_C110_SDA_HIGH; + si_high(); else - S5PCFB_C110_SDA_LOW; + si_low(); udelay(DELAY); - S5PCFB_C110_CLK_HIGH; + clk_high(); } else { if (first) { - gpio_cfg_pin(&gpio->gpio_mp0_4, 3, GPIO_INPUT); + gpio_cfg_pin(spi_so->bank, spi_so->num, GPIO_INPUT); first = 0; } - S5PCFB_C110_CLK_LOW; + clk_low(); - if (S5PCFB_C110_SDA_READ & 0x1) + if (so_read() & 0x1) command |= 1 << j; else command |= 0 << j; udelay(DELAY); - S5PCFB_C110_CLK_HIGH; + clk_high(); } udelay(DELAY); } - S5PCFB_C110_CS_HIGH; + cs_high(); udelay(DELAY); - gpio_cfg_pin(&gpio->gpio_mp0_4, 3, GPIO_OUTPUT); + gpio_cfg_pin(spi_so->bank, spi_so->num, GPIO_OUTPUT); return command; } @@ -412,15 +446,13 @@ static void s6e63m0_panel_send_sequence(const unsigned short *wbuf) } } -void s6e63m0_lcd_panel_init(void); - void s6e63m0_cfg_ldo(void) { - s6e63m0_lcd_panel_init(); /* data = s6e63m0_c110_spi_read_byte(0x0, 0xdd); printf("data = %d, %x\n", data, &data); */ + s6e63m0_panel_send_sequence(SEQ_PANEL_CONDITION_SET); s6e63m0_panel_send_sequence(SEQ_DISPLAY_CONDITION_SET); s6e63m0_panel_send_sequence(SEQ_GAMMA_SETTING); @@ -437,12 +469,20 @@ void s6e63m0_enable_ldo(unsigned int onoff) } } -void s6e63m0_lcd_panel_init(void) +/* this function would be called at universal.c */ +void s6e63m0_set_spi_interface(struct s6e63m0_platform_data *cs, + struct s6e63m0_platform_data *clk, struct s6e63m0_platform_data *si, + struct s6e63m0_platform_data *so) { - /* set gpio pin for DISPLAY_CS to HIGH */ - gpio_set_value(&gpio->gpio_mp0_1, 1, 1); - /* set gpio pin for DISPLAY_CLK to HIGH */ - gpio_set_value(&gpio->gpio_mp0_4, 1, 1); - /* set gpio pin for DISPLAY_SI to HIGH */ - gpio_set_value(&gpio->gpio_mp0_4, 3, 1); + if (cs == NULL || clk == NULL || si == NULL) { + printf("gpio bank is NULL.\n"); + return; + } + + spi_cs = cs; + spi_clk = clk; + spi_si = si; + + /* so could be NULL. */ + spi_so = so; } diff --git a/include/lcd.h b/include/lcd.h index 2768443..3c024ec 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -199,14 +199,14 @@ typedef struct vidinfo { u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ /* Horizontal control register. Timing from data sheet */ - ushort vl_hpw; /* Horz sync pulse width */ - u_char vl_blw; /* Wait before of line */ - u_char vl_elw; /* Wait end of line */ + u_char vl_hspw; /* Horz sync pulse width */ + u_char vl_hfpd; /* Wait before of line */ + u_char vl_hbpd; /* Wait end of line */ /* Vertical control register. */ - u_char vl_vpw; /* Vertical sync pulse width */ - u_char vl_bfw; /* Wait before of frame */ - u_char vl_efw; /* Wait end of frame */ + u_char vl_vspw; /* Vertical sync pulse width */ + u_char vl_vfpd; /* Wait before of frame */ + u_char vl_vbpd; /* Wait end of frame */ void (*cfg_gpio)(void); void (*backlight_on)(unsigned int onoff); -- 2.7.4