From 716ece1de9a7d43a61d8698ac41b71b64f66f9e9 Mon Sep 17 00:00:00 2001 From: Mark Jackson Date: Tue, 21 Jul 2009 11:11:37 +0100 Subject: [PATCH] Add AVR32 LCD support This patch adds support for the AVR32 LCD controller. This patch is based off the latest u-boot-video. A quick summary of what's going on:- Enable LCDC pixel clock Enable LCDC port pins Add framebuffer pointer to global_data struct Allocate framebuffer To use the new code, update your board config to include something like this:- #define CONFIG_LCD 1 #if defined(CONFIG_LCD) #define CONFIG_CMD_BMP #define CONFIG_ATMEL_LCD 1 #define LCD_BPP LCD_COLOR16 #define CONFIG_BMP_16BPP 1 #define CONFIG_FB_ADDR 0x10600000 #define CONFIG_WHITE_ON_BLACK 1 #define CONFIG_VIDEO_BMP_GZIP 1 #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE 262144 #define CONFIG_ATMEL_LCD_BGR555 1 #define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 #define CONFIG_SPLASH_SCREEN 1 #endif The standard U-Boot BMP and Splash-screen features should just work. Signed-off-by: Mark Jackson [agust@denx.de: fixed some style issues] Signed-off-by: Anatolij Gustschin --- cpu/at32ap/at32ap700x/clk.c | 5 ++ cpu/at32ap/at32ap700x/portmux.c | 90 +++++++++++++++++++ .../asm-avr32/arch-at32ap700x/chip-features.h | 5 ++ include/asm-avr32/arch-at32ap700x/clk.h | 6 ++ include/asm-avr32/arch-at32ap700x/portmux.h | 3 + include/asm-avr32/global_data.h | 3 + lib_avr32/board.c | 11 +++ 7 files changed, 123 insertions(+) diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c index 2c2e19c296..742bc6b5a2 100644 --- a/cpu/at32ap/at32ap700x/clk.c +++ b/cpu/at32ap/at32ap700x/clk.c @@ -65,6 +65,11 @@ void clk_init(void) #ifdef CONFIG_PLL /* Use PLL0 as main clock */ sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); + +#ifdef CONFIG_LCD + /* Set up pixel clock for the LCDC */ + sm_writel(PM_GCCTRL(7), SM_BIT(PLLSEL) | SM_BIT(CEN)); +#endif #endif } diff --git a/cpu/at32ap/at32ap700x/portmux.c b/cpu/at32ap/at32ap700x/portmux.c index 2a3b004b04..b1f2c6f1ff 100644 --- a/cpu/at32ap/at32ap700x/portmux.c +++ b/cpu/at32ap/at32ap700x/portmux.c @@ -202,3 +202,93 @@ void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength) PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); } #endif + +#ifdef AT32AP700x_CHIP_HAS_LCDC +void portmux_enable_lcdc(int pin_config) +{ + unsigned long portc_mask = 0; + unsigned long portd_mask = 0; + unsigned long porte_mask = 0; + + switch (pin_config) { + case 0: + portc_mask = (1 << 19) /* CC */ + | (1 << 20) /* HSYNC */ + | (1 << 21) /* PCLK */ + | (1 << 22) /* VSYNC */ + | (1 << 23) /* DVAL */ + | (1 << 24) /* MODE */ + | (1 << 25) /* PWR */ + | (1 << 26) /* DATA0 */ + | (1 << 27) /* DATA1 */ + | (1 << 28) /* DATA2 */ + | (1 << 29) /* DATA3 */ + | (1 << 30) /* DATA4 */ + | (1 << 31); /* DATA5 */ + + portd_mask = (1 << 0) /* DATA6 */ + | (1 << 1) /* DATA7 */ + | (1 << 2) /* DATA8 */ + | (1 << 3) /* DATA9 */ + | (1 << 4) /* DATA10 */ + | (1 << 5) /* DATA11 */ + | (1 << 6) /* DATA12 */ + | (1 << 7) /* DATA13 */ + | (1 << 8) /* DATA14 */ + | (1 << 9) /* DATA15 */ + | (1 << 10) /* DATA16 */ + | (1 << 11) /* DATA17 */ + | (1 << 12) /* DATA18 */ + | (1 << 13) /* DATA19 */ + | (1 << 14) /* DATA20 */ + | (1 << 15) /* DATA21 */ + | (1 << 16) /* DATA22 */ + | (1 << 17); /* DATA23 */ + break; + + case 1: + portc_mask = (1 << 20) /* HSYNC */ + | (1 << 21) /* PCLK */ + | (1 << 22) /* VSYNC */ + | (1 << 25) /* PWR */ + | (1 << 31); /* DATA5 */ + + portd_mask = (1 << 0) /* DATA6 */ + | (1 << 1) /* DATA7 */ + | (1 << 7) /* DATA13 */ + | (1 << 8) /* DATA14 */ + | (1 << 9) /* DATA15 */ + | (1 << 16) /* DATA22 */ + | (1 << 17); /* DATA23 */ + + porte_mask = (1 << 0) /* CC */ + | (1 << 1) /* DVAL */ + | (1 << 2) /* MODE */ + | (1 << 3) /* DATA0 */ + | (1 << 4) /* DATA1 */ + | (1 << 5) /* DATA2 */ + | (1 << 6) /* DATA3 */ + | (1 << 7) /* DATA4 */ + | (1 << 8) /* DATA8 */ + | (1 << 9) /* DATA9 */ + | (1 << 10) /* DATA10 */ + | (1 << 11) /* DATA11 */ + | (1 << 12) /* DATA12 */ + | (1 << 13) /* DATA16 */ + | (1 << 14) /* DATA17 */ + | (1 << 15) /* DATA18 */ + | (1 << 16) /* DATA19 */ + | (1 << 17) /* DATA20 */ + | (1 << 18); /* DATA21 */ + break; + } + + /* REVISIT: Some pins are probably pure outputs */ + portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, + PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); + portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, + PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); + portmux_select_peripheral(PORTMUX_PORT_E, porte_mask, + PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); +} +#endif diff --git a/include/asm-avr32/arch-at32ap700x/chip-features.h b/include/asm-avr32/arch-at32ap700x/chip-features.h index c47107e2a6..40a2476c9a 100644 --- a/include/asm-avr32/arch-at32ap700x/chip-features.h +++ b/include/asm-avr32/arch-at32ap700x/chip-features.h @@ -32,4 +32,9 @@ #define AT32AP700x_CHIP_HAS_MACB #endif +/* AP7000 and AP7002 have LCD controller, but AP7001 does not */ +#if defined(CONFIG_AT32AP7000) || defined(CONFIG_AT32AP7002) +#define AT32AP700x_CHIP_HAS_LCDC +#endif + #endif /* __ASM_AVR32_ARCH_CHIP_FEATURES_H__ */ diff --git a/include/asm-avr32/arch-at32ap700x/clk.h b/include/asm-avr32/arch-at32ap700x/clk.h index d83e93b74f..7a0b6559e0 100644 --- a/include/asm-avr32/arch-at32ap700x/clk.h +++ b/include/asm-avr32/arch-at32ap700x/clk.h @@ -83,6 +83,12 @@ static inline unsigned long get_spi_clk_rate(unsigned int dev_id) return get_pba_clk_rate(); } #endif +#ifdef AT32AP700x_CHIP_HAS_LCDC +static inline unsigned long get_lcdc_clk_rate(unsigned int dev_id) +{ + return get_hsb_clk_rate(); +} +#endif extern void clk_init(void); diff --git a/include/asm-avr32/arch-at32ap700x/portmux.h b/include/asm-avr32/arch-at32ap700x/portmux.h index 96fe70d4bd..1ba52e5ddb 100644 --- a/include/asm-avr32/arch-at32ap700x/portmux.h +++ b/include/asm-avr32/arch-at32ap700x/portmux.h @@ -85,5 +85,8 @@ void portmux_enable_mmci(unsigned int slot, unsigned long flags, void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength); void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength); #endif +#ifdef AT32AP700x_CHIP_HAS_LCDC +void portmux_enable_lcdc(int pin_config); +#endif #endif /* __ASM_AVR32_ARCH_PORTMUX_H__ */ diff --git a/include/asm-avr32/global_data.h b/include/asm-avr32/global_data.h index 97a6c6173c..efbdda9ba4 100644 --- a/include/asm-avr32/global_data.h +++ b/include/asm-avr32/global_data.h @@ -42,6 +42,9 @@ typedef struct global_data { unsigned long env_addr; /* Address of env struct */ unsigned long env_valid; /* Checksum of env valid? */ unsigned long cpu_hz; /* cpu core clock frequency */ +#if defined(CONFIG_LCD) + void *fb_base; /* framebuffer address */ +#endif void **jt; /* jump table */ } gd_t; diff --git a/lib_avr32/board.c b/lib_avr32/board.c index 5b2d0ef1d3..da035063db 100644 --- a/lib_avr32/board.c +++ b/lib_avr32/board.c @@ -239,6 +239,17 @@ void board_init_f(ulong board_type) addr -= CONFIG_SYS_DMA_ALLOC_LEN; #endif +#ifdef CONFIG_LCD +#ifdef CONFIG_FB_ADDR + printf("LCD: Frame buffer allocated at preset 0x%08x\n", CONFIG_FB_ADDR); + gd->fb_base = (void *)CONFIG_FB_ADDR; +#else + addr = lcd_setmem(addr); + printf("LCD: Frame buffer allocated at 0x%08lx\n", addr); + gd->fb_base = (void *)addr; +#endif /* CONFIG_FB_ADDR */ +#endif /* CONFIG_LCD */ + /* Allocate a Board Info struct on a word boundary */ addr -= sizeof(bd_t); addr &= ~3UL; -- 2.39.5