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 <m...@mimc.co.uk>
---
 cpu/at32ap/at32ap700x/clk.c                       |    5 +
 cpu/at32ap/at32ap700x/portmux.c                   |   90 +++++++++++++++++++++
 include/asm-avr32/arch-at32ap700x/chip-features.h |    5 +
 include/asm-avr32/arch-at32ap700x/clk.h           |    6 ++
 include/asm-avr32/arch-at32ap700x/portmux.h       |    5 +-
 include/asm-avr32/global_data.h                   |    3 +
 lib_avr32/board.c                                 |   11 +++
 7 files changed, 124 insertions(+), 1 deletions(-)

diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c
index 2c2e19c..742bc6b 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 2a3b004..e71b2bf 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 c47107e..40a2476 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 d83e93b..7a0b655 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 96fe70d..8574aec 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 97a6c61..efbdda9 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 5b2d0ef..cb1473d 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;
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to