* [PATCH 0/6] atmel: add Atmel HLCDC support and boards @ 2013-01-30 23:08 Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 1 reply; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:08 UTC (permalink / raw) To: barebox Hi, The following changes since commit 1164d59f7aa2164569ba46188cfc874cdc0b9a66: at91rm9200: fix default TEXT_BASE to 15MiB (2013-01-31 05:17:26 +0800) are available in the git repository at: git://git.jcrosoft.org/barebox.git delivery/atmel_hlcdc for you to fetch changes up to 5fa22362f842612da24125fd81d9d3c83e53bb9b: sama5d3xek: add lcd support (2013-01-31 05:17:38 +0800) ---------------------------------------------------------------- Jean-Christophe PLAGNIOL-VILLARD (6): atmel_lcdfb: factorise common code between lcdc and new hlcdc IP video: add Atmel HLCD support at91sam9x5: add lcd support at91sam9x5ek: add lcd support sama5d3: add lcd support sama5d3xek: add lcd support arch/arm/boards/at91sam9x5ek/init.c | 44 ++++++ arch/arm/boards/sama5d3xek/init.c | 45 ++++++ arch/arm/configs/at91sam9x5ek_defconfig | 4 +- arch/arm/configs/sama5d3xek_defconfig | 4 + arch/arm/mach-at91/at91sam9x5.c | 1 + arch/arm/mach-at91/at91sam9x5_devices.c | 55 +++++++ arch/arm/mach-at91/include/mach/atmel_hlcdc.h | 760 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-at91/include/mach/board.h | 1 + arch/arm/mach-at91/sama5d3.c | 1 + arch/arm/mach-at91/sama5d3_devices.c | 53 +++++++ drivers/video/Kconfig | 4 + drivers/video/Makefile | 3 +- drivers/video/atmel_hlcdfb.c | 297 ++++++++++++++++++++++++++++++++++++ drivers/video/atmel_lcdfb.c | 313 +++++--------------------------------- drivers/video/atmel_lcdfb.h | 37 +++++ drivers/video/atmel_lcdfb_core.c | 313 ++++++++++++++++++++++++++++++++++++++ 16 files changed, 1654 insertions(+), 281 deletions(-) create mode 100644 arch/arm/mach-at91/include/mach/atmel_hlcdc.h create mode 100644 drivers/video/atmel_hlcdfb.c create mode 100644 drivers/video/atmel_lcdfb.h create mode 100644 drivers/video/atmel_lcdfb_core.c Best Regards, J. _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP 2013-01-30 23:08 [PATCH 0/6] atmel: add Atmel HLCDC support and boards Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 2/6] video: add Atmel HLCD support Jean-Christophe PLAGNIOL-VILLARD ` (4 more replies) 0 siblings, 5 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- drivers/video/Makefile | 2 +- drivers/video/atmel_lcdfb.c | 313 +++----------------- drivers/video/atmel_lcdfb.h | 37 +++ .../video/{atmel_lcdfb.c => atmel_lcdfb_core.c} | 259 ++-------------- 4 files changed, 102 insertions(+), 509 deletions(-) create mode 100644 drivers/video/atmel_lcdfb.h copy drivers/video/{atmel_lcdfb.c => atmel_lcdfb_core.c} (53%) diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 1953307..724ef99 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_VIDEO) += fb.o -obj-$(CONFIG_DRIVER_VIDEO_ATMEL) += atmel_lcdfb.o +obj-$(CONFIG_DRIVER_VIDEO_ATMEL) += atmel_lcdfb.o atmel_lcdfb_core.o obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 3a49688..736b25e 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -25,50 +25,19 @@ #include <common.h> #include <io.h> #include <init.h> -#include <linux/clk.h> -#include <fb.h> -#include <video/atmel_lcdc.h> #include <mach/hardware.h> #include <mach/io.h> #include <mach/cpu.h> #include <errno.h> -#include <linux/err.h> -#include <malloc.h> #include <asm/mmu.h> -struct atmel_lcdfb_info { - struct fb_info info; - void __iomem *mmio; - struct device_d *device; - - unsigned int guard_time; - unsigned int smem_len; - struct clk *bus_clk; - struct clk *lcdc_clk; - - struct atmel_lcdfb_platform_data *pdata; -}; - -#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg)) -#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg)) +#include "atmel_lcdfb.h" /* configurable parameters */ #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 #define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ #define ATMEL_LCDC_FIFO_SIZE 512 /* words */ -static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) -{ - clk_enable(sinfo->bus_clk); - clk_enable(sinfo->lcdc_clk); -} - -static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) -{ - clk_disable(sinfo->bus_clk); - clk_disable(sinfo->lcdc_clk); -} - static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) { unsigned long value; @@ -94,7 +63,7 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) return value; } -static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) +static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags) { /* Turn off the LCD controller and the DMA controller */ lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, @@ -105,11 +74,9 @@ static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) mdelay(10); lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); -} - -static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) -{ - atmel_lcdfb_stop_nowait(sinfo); + + if (flags & ATMEL_LCDC_STOP_NOWAIT) + return; /* Wait for DMA engine to become idle... */ while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) @@ -126,31 +93,6 @@ static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) | ATMEL_LCDC_PWR); } -static void atmel_lcdc_power_controller(struct fb_info *fb_info, int i) -{ - struct atmel_lcdfb_info *sinfo = fb_info->priv; - struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; - - if (pdata->atmel_lcdfb_power_control) - pdata->atmel_lcdfb_power_control(1); -} - -/** - * @param fb_info Framebuffer information - */ -static void atmel_lcdc_enable_controller(struct fb_info *fb_info) -{ - atmel_lcdc_power_controller(fb_info, 1); -} - -/** - * @param fb_info Framebuffer information - */ -static void atmel_lcdc_disable_controller(struct fb_info *fb_info) -{ - atmel_lcdc_power_controller(fb_info, 0); -} - static void atmel_lcdfb_update_dma(struct fb_info *info) { struct atmel_lcdfb_info *sinfo = info->priv; @@ -164,29 +106,39 @@ static void atmel_lcdfb_update_dma(struct fb_info *info) lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr); } -static void atmel_lcdfb_set_par(struct fb_info *info) +static void atmel_lcdfb_limit_screeninfo(struct fb_videomode *mode) +{ + /* Saturate vertical and horizontal timings at maximum values */ + mode->vsync_len = min_t(u32, mode->vsync_len, + (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); + mode->upper_margin = min_t(u32, mode->upper_margin, + ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET); + mode->lower_margin = min_t(u32, mode->lower_margin, + ATMEL_LCDC_VFP); + mode->right_margin = min_t(u32, mode->right_margin, + (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); + mode->hsync_len = min_t(u32, mode->hsync_len, + (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); + mode->left_margin = min_t(u32, mode->left_margin, + ATMEL_LCDC_HBP + 1); + +} + +static void atmel_lcdfb_setup_core(struct fb_info *info) { struct atmel_lcdfb_info *sinfo = info->priv; struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; struct fb_videomode *mode = info->mode; unsigned long clk_value_khz; - unsigned long value; unsigned long pix_factor = 2; unsigned long hozval_linesz; - - atmel_lcdfb_stop(sinfo); - - /* Re-initialize the DMA engine... */ - dev_dbg(&info->dev, " * update DMA engine\n"); - atmel_lcdfb_update_dma(info); + unsigned long value; /* ...set frame size and burst length = 8 words (?) */ value = (mode->yres * mode->xres * info->bits_per_pixel) / 32; value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET); lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value); - /* Now, the LCDC core... */ - /* Set pixel clock */ if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) pix_factor = 1; @@ -271,228 +223,31 @@ static void atmel_lcdfb_set_par(struct fb_info *info) /* ...wait for DMA engine to become idle... */ while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) mdelay(10); - - atmel_lcdfb_start(sinfo); - - dev_dbg(&info->dev, " * DONE\n"); } -static int atmel_lcdfb_check_var(struct fb_info *info) +static void atmel_lcdfb_init_contrast(struct atmel_lcdfb_info *sinfo) { - struct device_d *dev = &info->dev; - struct atmel_lcdfb_info *sinfo = info->priv; - struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; - struct fb_videomode *mode = info->mode; - unsigned long clk_value_khz; - - clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; - - dev_dbg(dev, "%s:\n", __func__); - - if (!(mode->pixclock && info->bits_per_pixel)) { - dev_err(dev, "needed value not specified\n"); - return -EINVAL; - } - - dev_dbg(dev, " resolution: %ux%u\n", mode->xres, mode->yres); - dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(mode->pixclock)); - dev_dbg(dev, " bpp: %u\n", info->bits_per_pixel); - dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz); - - if (PICOS2KHZ(mode->pixclock) > clk_value_khz) { - dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(mode->pixclock)); - return -EINVAL; - } - - /* Saturate vertical and horizontal timings at maximum values */ - mode->vsync_len = min_t(u32, mode->vsync_len, - (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); - mode->upper_margin = min_t(u32, mode->upper_margin, - ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET); - mode->lower_margin = min_t(u32, mode->lower_margin, - ATMEL_LCDC_VFP); - mode->right_margin = min_t(u32, mode->right_margin, - (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); - mode->hsync_len = min_t(u32, mode->hsync_len, - (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); - mode->left_margin = min_t(u32, mode->left_margin, - ATMEL_LCDC_HBP + 1); - - /* Some parameters can't be zero */ - mode->vsync_len = max_t(u32, mode->vsync_len, 1); - mode->right_margin = max_t(u32, mode->right_margin, 1); - mode->hsync_len = max_t(u32, mode->hsync_len, 1); - mode->left_margin = max_t(u32, mode->left_margin, 1); - - switch (info->bits_per_pixel) { - case 1: - case 2: - case 4: - case 8: - info->red.offset = info->green.offset = info->blue.offset = 0; - info->red.length = info->green.length = info->blue.length - = info->bits_per_pixel; - break; - case 16: - /* Older SOCs use IBGR:555 rather than BGR:565. */ - if (pdata->have_intensity_bit) - info->green.length = 5; - else - info->green.length = 6; - if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { - /* RGB:5X5 mode */ - info->red.offset = info->green.length + 5; - info->blue.offset = 0; - } else { - /* BGR:5X5 mode */ - info->red.offset = 0; - info->blue.offset = info->green.length + 5; - } - info->green.offset = 5; - info->red.length = info->blue.length = 5; - break; - case 32: - info->transp.offset = 24; - info->transp.length = 8; - /* fall through */ - case 24: - if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { - /* RGB:888 mode */ - info->red.offset = 16; - info->blue.offset = 0; - } else { - /* BGR:888 mode */ - info->red.offset = 0; - info->blue.offset = 16; - } - info->green.offset = 8; - info->red.length = info->green.length = info->blue.length = 8; - break; - default: - dev_err(dev, "color depth %d not supported\n", - info->bits_per_pixel); - return -EINVAL; - } - - return 0; -} - -static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) -{ - struct fb_info *info = &sinfo->info; - struct fb_videomode *mode = info->mode; - unsigned int smem_len; - - free(info->screen_base); - - smem_len = (mode->xres * mode->yres - * ((info->bits_per_pixel + 7) / 8)); - smem_len = max(smem_len, sinfo->smem_len); - - info->screen_base = dma_alloc_coherent(smem_len); - - if (!info->screen_base) - return -ENOMEM; - - memset(info->screen_base, 0, smem_len); - - return 0; -} - -/** - * Prepare the video hardware for a specified video mode - * @param fb_info Framebuffer information - * @param mode The video mode description to initialize - * @return 0 on success - */ -static int atmel_lcdc_activate_var(struct fb_info *info) -{ - struct atmel_lcdfb_info *sinfo = info->priv; unsigned long value; - int ret; - - ret = atmel_lcdfb_alloc_video_memory(sinfo); - if (ret) - return ret; - atmel_lcdfb_set_par(info); - - /* Set contrast */ value = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE; lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); - - return atmel_lcdfb_check_var(info); } -/* - * There is only one video hardware instance available. - * It makes no sense to dynamically allocate this data - */ -static struct fb_ops atmel_lcdc_ops = { - .fb_activate_var = atmel_lcdc_activate_var, - .fb_enable = atmel_lcdc_enable_controller, - .fb_disable = atmel_lcdc_disable_controller, +struct atmel_lcdfb_devdata atmel_lcdfb_data = { + .start = atmel_lcdfb_start, + .stop = atmel_lcdfb_stop, + .update_dma = atmel_lcdfb_update_dma, + .setup_core = atmel_lcdfb_setup_core, + .init_contrast = atmel_lcdfb_init_contrast, + .limit_screeninfo = atmel_lcdfb_limit_screeninfo, }; static int atmel_lcdc_probe(struct device_d *dev) { - struct atmel_lcdfb_info *sinfo; - struct atmel_lcdfb_platform_data *pdata = dev->platform_data; - int ret = 0; - struct fb_info *info; - - if (!pdata) { - dev_err(dev, "missing platform_data\n"); - return -EINVAL; - } - - sinfo = xzalloc(sizeof(*sinfo)); - sinfo->pdata = pdata; - sinfo->mmio = dev_request_mem_region(dev, 0); - - /* just init */ - info = &sinfo->info; - info->priv = sinfo; - info->fbops = &atmel_lcdc_ops; - info->mode_list = pdata->mode_list; - info->num_modes = pdata->num_modes; - info->mode = &info->mode_list[0]; - info->xres = info->mode->xres; - info->yres = info->mode->yres; - info->bits_per_pixel = pdata->default_bpp; - - /* Enable LCDC Clocks */ - sinfo->bus_clk = clk_get(dev, "hck1"); - if (IS_ERR(sinfo->bus_clk)) { - ret = PTR_ERR(sinfo->bus_clk); - goto err; - } - sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); - if (IS_ERR(sinfo->lcdc_clk)) { - ret = PTR_ERR(sinfo->lcdc_clk); - goto put_bus_clk; - } - - atmel_lcdfb_start_clock(sinfo); - - ret = register_framebuffer(info); - if (ret != 0) { - dev_err(dev, "Failed to register framebuffer\n"); - goto stop_clk; - } - - return ret; - -stop_clk: - atmel_lcdfb_stop_clock(sinfo); - clk_put(sinfo->lcdc_clk); -put_bus_clk: - clk_put(sinfo->bus_clk); -err: - return ret; + return atmel_lcdc_register(dev, &atmel_lcdfb_data); } static struct driver_d atmel_lcdc_driver = { diff --git a/drivers/video/atmel_lcdfb.h b/drivers/video/atmel_lcdfb.h new file mode 100644 index 0000000..6c53dd4 --- /dev/null +++ b/drivers/video/atmel_lcdfb.h @@ -0,0 +1,37 @@ + +#include <fb.h> +#include <video/atmel_lcdc.h> + +struct atmel_lcdfb_info; + +struct atmel_lcdfb_devdata { + void (*start)(struct atmel_lcdfb_info *sinfo); + void (*stop)(struct atmel_lcdfb_info *sinfo, u32 flags); + void (*update_dma)(struct fb_info *info); + void (*setup_core)(struct fb_info *info); + void (*init_contrast)(struct atmel_lcdfb_info *sinfo); + void (*limit_screeninfo)(struct fb_videomode *mode); + int fbinfo_flags; + int dma_desc_size; +}; + +struct atmel_lcdfb_info { + struct fb_info info; + void __iomem *mmio; + struct device_d *device; + + unsigned int guard_time; + unsigned int smem_len; + struct clk *bus_clk; + struct clk *lcdc_clk; + + struct atmel_lcdfb_platform_data *pdata; + struct atmel_lcdfb_devdata *dev_data; +}; + +#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg)) +#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg)) + +#define ATMEL_LCDC_STOP_NOWAIT (1 << 0) + +int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data); diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb_core.c similarity index 53% copy from drivers/video/atmel_lcdfb.c copy to drivers/video/atmel_lcdfb_core.c index 3a49688..528bcd8 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb_core.c @@ -24,38 +24,12 @@ #include <common.h> #include <io.h> -#include <init.h> -#include <linux/clk.h> -#include <fb.h> -#include <video/atmel_lcdc.h> -#include <mach/hardware.h> -#include <mach/io.h> -#include <mach/cpu.h> -#include <errno.h> #include <linux/err.h> +#include <linux/clk.h> #include <malloc.h> #include <asm/mmu.h> -struct atmel_lcdfb_info { - struct fb_info info; - void __iomem *mmio; - struct device_d *device; - - unsigned int guard_time; - unsigned int smem_len; - struct clk *bus_clk; - struct clk *lcdc_clk; - - struct atmel_lcdfb_platform_data *pdata; -}; - -#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg)) -#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg)) - -/* configurable parameters */ -#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 -#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ -#define ATMEL_LCDC_FIFO_SIZE 512 /* words */ +#include "atmel_lcdfb.h" static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) { @@ -69,63 +43,6 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) clk_disable(sinfo->lcdc_clk); } -static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) -{ - unsigned long value; - - if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000())) - return xres; - - value = xres; - if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { - /* STN display */ - if ((lcdcon2 & ATMEL_LCDC_DISTYPE) == ATMEL_LCDC_DISTYPE_STNCOLOR) - value *= 3; - - if ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_4 - || ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_8 - && (lcdcon2 & ATMEL_LCDC_SCANMOD) == ATMEL_LCDC_SCANMOD_DUAL )) - value = DIV_ROUND_UP(value, 4); - else - value = DIV_ROUND_UP(value, 8); - } - - return value; -} - -static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) -{ - /* Turn off the LCD controller and the DMA controller */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); - - /* Wait for the LCDC core to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) - mdelay(10); - - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); -} - -static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) -{ - atmel_lcdfb_stop_nowait(sinfo); - - /* Wait for DMA engine to become idle... */ - while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) - mdelay(10); -} - -static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) -{ - struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; - - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, pdata->default_dmacon); - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - (pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET) - | ATMEL_LCDC_PWR); -} - static void atmel_lcdc_power_controller(struct fb_info *fb_info, int i) { struct atmel_lcdfb_info *sinfo = fb_info->priv; @@ -151,131 +68,6 @@ static void atmel_lcdc_disable_controller(struct fb_info *fb_info) atmel_lcdc_power_controller(fb_info, 0); } -static void atmel_lcdfb_update_dma(struct fb_info *info) -{ - struct atmel_lcdfb_info *sinfo = info->priv; - unsigned long dma_addr; - - dma_addr = (unsigned long)info->screen_base; - - dma_addr &= ~3UL; - - /* Set framebuffer DMA base address and pixel offset */ - lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr); -} - -static void atmel_lcdfb_set_par(struct fb_info *info) -{ - struct atmel_lcdfb_info *sinfo = info->priv; - struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; - struct fb_videomode *mode = info->mode; - unsigned long clk_value_khz; - unsigned long value; - unsigned long pix_factor = 2; - unsigned long hozval_linesz; - - atmel_lcdfb_stop(sinfo); - - /* Re-initialize the DMA engine... */ - dev_dbg(&info->dev, " * update DMA engine\n"); - atmel_lcdfb_update_dma(info); - - /* ...set frame size and burst length = 8 words (?) */ - value = (mode->yres * mode->xres * info->bits_per_pixel) / 32; - value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET); - lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value); - - /* Now, the LCDC core... */ - - /* Set pixel clock */ - if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) - pix_factor = 1; - - clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; - - value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(mode->pixclock)); - - if (value < pix_factor) { - dev_notice(&info->dev, "Bypassing pixel clock divider\n"); - lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); - } else { - value = (value / pix_factor) - 1; - dev_dbg(&info->dev, " * programming CLKVAL = 0x%08lx\n", - value); - lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, - value << ATMEL_LCDC_CLKVAL_OFFSET); - mode->pixclock = - KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1))); - dev_dbg(&info->dev, " updated pixclk: %lu KHz\n", - PICOS2KHZ(mode->pixclock)); - } - - /* Initialize control register 2 */ - value = pdata->default_lcdcon2; - - if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) - value |= ATMEL_LCDC_INVLINE_INVERTED; - if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) - value |= ATMEL_LCDC_INVFRAME_INVERTED; - - switch (info->bits_per_pixel) { - case 1: value |= ATMEL_LCDC_PIXELSIZE_1; break; - case 2: value |= ATMEL_LCDC_PIXELSIZE_2; break; - case 4: value |= ATMEL_LCDC_PIXELSIZE_4; break; - case 8: value |= ATMEL_LCDC_PIXELSIZE_8; break; - case 16: value |= ATMEL_LCDC_PIXELSIZE_16; break; - case 24: value |= ATMEL_LCDC_PIXELSIZE_24; break; - case 32: value |= ATMEL_LCDC_PIXELSIZE_32; break; - default: BUG(); break; - } - dev_dbg(&info->dev, " * LCDCON2 = %08lx\n", value); - lcdc_writel(sinfo, ATMEL_LCDC_LCDCON2, value); - - /* Vertical timing */ - value = (mode->vsync_len - 1) << ATMEL_LCDC_VPW_OFFSET; - value |= mode->upper_margin << ATMEL_LCDC_VBP_OFFSET; - value |= mode->lower_margin; - dev_dbg(&info->dev, " * LCDTIM1 = %08lx\n", value); - lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value); - - /* Horizontal timing */ - value = (mode->right_margin - 1) << ATMEL_LCDC_HFP_OFFSET; - value |= (mode->hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET; - value |= (mode->left_margin - 1); - dev_dbg(&info->dev, " * LCDTIM2 = %08lx\n", value); - lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); - - /* Horizontal value (aka line size) */ - hozval_linesz = compute_hozval(mode->xres, - lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2)); - - /* Display size */ - value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; - value |= mode->yres - 1; - dev_dbg(&info->dev, " * LCDFRMCFG = %08lx\n", value); - lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value); - - /* FIFO Threshold: Use formula from data sheet */ - value = ATMEL_LCDC_FIFO_SIZE - (2 * ATMEL_LCDC_DMA_BURST_LEN + 3); - lcdc_writel(sinfo, ATMEL_LCDC_FIFO, value); - - /* Toggle LCD_MODE every frame */ - lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0); - - /* Disable all interrupts */ - lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); - - /* Enable FIFO & DMA errors */ - lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); - - /* ...wait for DMA engine to become idle... */ - while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) - mdelay(10); - - atmel_lcdfb_start(sinfo); - - dev_dbg(&info->dev, " * DONE\n"); -} static int atmel_lcdfb_check_var(struct fb_info *info) { @@ -305,6 +97,9 @@ static int atmel_lcdfb_check_var(struct fb_info *info) } /* Saturate vertical and horizontal timings at maximum values */ + if (sinfo->dev_data->limit_screeninfo) + sinfo->dev_data->limit_screeninfo(mode); + mode->vsync_len = min_t(u32, mode->vsync_len, (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); mode->upper_margin = min_t(u32, mode->upper_margin, @@ -377,6 +172,26 @@ static int atmel_lcdfb_check_var(struct fb_info *info) return 0; } +static void atmel_lcdfb_set_par(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + + if (sinfo->dev_data->stop) + sinfo->dev_data->stop(sinfo, ATMEL_LCDC_STOP_NOWAIT); + + /* Re-initialize the DMA engine... */ + dev_dbg(&info->dev, " * update DMA engine\n"); + sinfo->dev_data->update_dma(info); + + /* Now, the LCDC core... */ + sinfo->dev_data->setup_core(info); + + if (sinfo->dev_data->start) + sinfo->dev_data->start(sinfo); + + dev_dbg(&info->dev, " * DONE\n"); +} + static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) { struct fb_info *info = &sinfo->info; @@ -408,7 +223,6 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) static int atmel_lcdc_activate_var(struct fb_info *info) { struct atmel_lcdfb_info *sinfo = info->priv; - unsigned long value; int ret; ret = atmel_lcdfb_alloc_video_memory(sinfo); @@ -417,12 +231,8 @@ static int atmel_lcdc_activate_var(struct fb_info *info) atmel_lcdfb_set_par(info); - /* Set contrast */ - value = ATMEL_LCDC_PS_DIV8 | - ATMEL_LCDC_POL_POSITIVE | - ATMEL_LCDC_ENA_PWMENABLE; - lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value); - lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); + if (sinfo->dev_data->init_contrast) + sinfo->dev_data->init_contrast(sinfo); return atmel_lcdfb_check_var(info); } @@ -437,7 +247,7 @@ static struct fb_ops atmel_lcdc_ops = { .fb_disable = atmel_lcdc_disable_controller, }; -static int atmel_lcdc_probe(struct device_d *dev) +int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) { struct atmel_lcdfb_info *sinfo; struct atmel_lcdfb_platform_data *pdata = dev->platform_data; @@ -453,6 +263,8 @@ static int atmel_lcdc_probe(struct device_d *dev) sinfo->pdata = pdata; sinfo->mmio = dev_request_mem_region(dev, 0); + sinfo->dev_data = data; + /* just init */ info = &sinfo->info; info->priv = sinfo; @@ -494,14 +306,3 @@ put_bus_clk: err: return ret; } - -static struct driver_d atmel_lcdc_driver = { - .name = "atmel_lcdfb", - .probe = atmel_lcdc_probe, -}; - -static int atmel_lcdc_init(void) -{ - return platform_driver_register(&atmel_lcdc_driver); -} -device_initcall(atmel_lcdc_init); -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/6] video: add Atmel HLCD support 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 3/6] at91sam9x5: add lcd support Jean-Christophe PLAGNIOL-VILLARD ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- arch/arm/mach-at91/include/mach/atmel_hlcdc.h | 760 +++++++++++++++++++++++++ drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/atmel_hlcdfb.c | 297 ++++++++++ drivers/video/atmel_lcdfb.h | 2 +- drivers/video/atmel_lcdfb_core.c | 5 + 6 files changed, 1068 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-at91/include/mach/atmel_hlcdc.h create mode 100644 drivers/video/atmel_hlcdfb.c diff --git a/arch/arm/mach-at91/include/mach/atmel_hlcdc.h b/arch/arm/mach-at91/include/mach/atmel_hlcdc.h new file mode 100644 index 0000000..71ccb96 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel_hlcdc.h @@ -0,0 +1,760 @@ +/* + * Header file for AT91 High end LCD Controller + * + * Data structure and register user interface + * + * Copyright (C) 2010 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PUROFFSETE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __MACH_ATMEL_HLCD_H__ +#define __MACH_ATMEL_HLCD_H__ + +/* Lcdc hardware registers */ +#define ATMEL_LCDC_LCDCFG0 0x0000 +#define LCDC_LCDCFG0_CLKPOL (0x1 << 0) +#define LCDC_LCDCFG0_CLKSEL (0x1 << 2) +#define LCDC_LCDCFG0_CLKPWMSEL (0x1 << 3) +#define LCDC_LCDCFG0_CGDISBASE (0x1 << 8) +#define LCDC_LCDCFG0_CGDISOVR1 (0x1 << 9) +#define LCDC_LCDCFG0_CGDISOVR2 (0x1 << 10) +#define LCDC_LCDCFG0_CGDISHEO (0x1 << 11) +#define LCDC_LCDCFG0_CGDISHCR (0x1 << 12) +#define LCDC_LCDCFG0_CGDISPP (0x1 << 13) +#define LCDC_LCDCFG0_CLKDIV_OFFSET 16 +#define LCDC_LCDCFG0_CLKDIV (0xff << LCDC_LCDCFG0_CLKDIV_OFFSET) + +#define ATMEL_LCDC_LCDCFG1 0x0004 +#define LCDC_LCDCFG1_HSPW_OFFSET 0 +#define LCDC_LCDCFG1_HSPW (0x3f << LCDC_LCDCFG1_HSPW_OFFSET) +#define LCDC_LCDCFG1_VSPW_OFFSET 16 +#define LCDC_LCDCFG1_VSPW (0x3f << LCDC_LCDCFG1_VSPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG2 0x0008 +#define LCDC_LCDCFG2_VFPW_OFFSET 0 +#define LCDC_LCDCFG2_VFPW (0x3f << LCDC_LCDCFG2_VFPW_OFFSET) +#define LCDC_LCDCFG2_VBPW_OFFSET 16 +#define LCDC_LCDCFG2_VBPW (0x3f << LCDC_LCDCFG2_VBPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG3 0x000C +#define LCDC_LCDCFG3_HFPW_OFFSET 0 +#define LCDC_LCDCFG3_HFPW (0xff << LCDC_LCDCFG3_HFPW_OFFSET) +#define LCDC2_LCDCFG3_HFPW (0x1ff << LCDC_LCDCFG3_HFPW_OFFSET) +#define LCDC_LCDCFG3_HBPW_OFFSET 16 +#define LCDC_LCDCFG3_HBPW (0xff << LCDC_LCDCFG3_HBPW_OFFSET) +#define LCDC2_LCDCFG3_HBPW (0x1ff << LCDC_LCDCFG3_HBPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG4 0x0010 +#define LCDC_LCDCFG4_PPL_OFFSET 0 +#define LCDC_LCDCFG4_PPL (0x7ff << LCDC_LCDCFG4_PPL_OFFSET) +#define LCDC_LCDCFG4_RPF_OFFSET 16 +#define LCDC_LCDCFG4_RPF (0x7ff << LCDC_LCDCFG4_RPF_OFFSET) + +#define ATMEL_LCDC_LCDCFG5 0x0014 +#define LCDC_LCDCFG5_HSPOL (0x1 << 0) +#define LCDC_LCDCFG5_VSPOL (0x1 << 1) +#define LCDC_LCDCFG5_VSPDLYS (0x1 << 2) +#define LCDC_LCDCFG5_VSPDLYE (0x1 << 3) +#define LCDC_LCDCFG5_DISPPOL (0x1 << 4) +#define LCDC_LCDCFG5_SERIAL (0x1 << 5) +#define LCDC_LCDCFG5_DITHER (0x1 << 6) +#define LCDC_LCDCFG5_DISPDLY (0x1 << 7) +#define LCDC_LCDCFG5_MODE_OFFSET 8 +#define LCDC_LCDCFG5_MODE (0x3 << LCDC_LCDCFG5_MODE_OFFSET) +#define LCDC_LCDCFG5_MODE_OUTPUT_12BPP (0x0 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_16BPP (0x1 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_18BPP (0x2 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_24BPP (0x3 << 8) +#define LCDC_LCDCFG5_PP (0x1 << 10) +#define LCDC_LCDCFG5_VSPSU (0x1 << 12) +#define LCDC_LCDCFG5_VSPHO (0x1 << 13) +#define LCDC_LCDCFG5_GUARDTIME_OFFSET 16 +#define LCDC_LCDCFG5_GUARDTIME (0x1f << LCDC_LCDCFG5_GUARDTIME_OFFSET) + +#define ATMEL_LCDC_LCDCFG6 0x0018 +#define LCDC_LCDCFG6_PWMPS_OFFSET 0 +#define LCDC_LCDCFG6_PWMPS (0x7 << LCDC_LCDCFG6_PWMPS_OFFSET) +#define LCDC_LCDCFG6_PWMPOL (0x1 << 4) +#define LCDC_LCDCFG6_PWMCVAL_OFFSET 8 +#define LCDC_LCDCFG6_PWMCVAL (0xff << LCDC_LCDCFG6_PWMCVAL_OFFSET) + +#define ATMEL_LCDC_LCDEN 0x0020 +#define LCDC_LCDEN_CLKEN (0x1 << 0) +#define LCDC_LCDEN_SYNCEN (0x1 << 1) +#define LCDC_LCDEN_DISPEN (0x1 << 2) +#define LCDC_LCDEN_PWMEN (0x1 << 3) + +#define ATMEL_LCDC_LCDDIS 0x0024 +#define LCDC_LCDDIS_CLKDIS (0x1 << 0) +#define LCDC_LCDDIS_SYNCDIS (0x1 << 1) +#define LCDC_LCDDIS_DISPDIS (0x1 << 2) +#define LCDC_LCDDIS_PWMDIS (0x1 << 3) +#define LCDC_LCDDIS_CLKRST (0x1 << 8) +#define LCDC_LCDDIS_SYNCRST (0x1 << 9) +#define LCDC_LCDDIS_DISPRST (0x1 << 10) +#define LCDC_LCDDIS_PWMRST (0x1 << 11) + +#define ATMEL_LCDC_LCDSR 0x0028 +#define LCDC_LCDSR_CLKSTS (0x1 << 0) +#define LCDC_LCDSR_LCDSTS (0x1 << 1) +#define LCDC_LCDSR_DISPSTS (0x1 << 2) +#define LCDC_LCDSR_PWMSTS (0x1 << 3) +#define LCDC_LCDSR_SIPSTS (0x1 << 4) + +#define ATMEL_LCDC_LCDIER 0x002C +#define LCDC_LCDIER_SOFIE (0x1 << 0) +#define LCDC_LCDIER_DISIE (0x1 << 1) +#define LCDC_LCDIER_DISPIE (0x1 << 2) +#define LCDC_LCDIER_FIFOERRIE (0x1 << 4) +#define LCDC_LCDIER_BASEIE (0x1 << 8) +#define LCDC_LCDIER_OVR1IE (0x1 << 9) +#define LCDC_LCDIER_OVR2IE (0x1 << 10) +#define LCDC_LCDIER_HEOIE (0x1 << 11) +#define LCDC_LCDIER_HCRIE (0x1 << 12) +#define LCDC_LCDIER_PPIE (0x1 << 13) + +#define ATMEL_LCDC_LCDIDR 0x0030 +#define LCDC_LCDIDR_SOFID (0x1 << 0) +#define LCDC_LCDIDR_DISID (0x1 << 1) +#define LCDC_LCDIDR_DISPID (0x1 << 2) +#define LCDC_LCDIDR_FIFOERRID (0x1 << 4) +#define LCDC_LCDIDR_BASEID (0x1 << 8) +#define LCDC_LCDIDR_OVR1ID (0x1 << 9) +#define LCDC_LCDIDR_OVR2ID (0x1 << 10) +#define LCDC_LCDIDR_HEOID (0x1 << 11) +#define LCDC_LCDIDR_HCRID (0x1 << 12) +#define LCDC_LCDIDR_PPID (0x1 << 13) + +#define ATMEL_LCDC_LCDIMR 0x0034 +#define LCDC_LCDIMR_SOFIM (0x1 << 0) +#define LCDC_LCDIMR_DISIM (0x1 << 1) +#define LCDC_LCDIMR_DISPIM (0x1 << 2) +#define LCDC_LCDIMR_FIFOERRIM (0x1 << 4) +#define LCDC_LCDIMR_BASEIM (0x1 << 8) +#define LCDC_LCDIMR_OVR1IM (0x1 << 9) +#define LCDC_LCDIMR_OVR2IM (0x1 << 10) +#define LCDC_LCDIMR_HEOIM (0x1 << 11) +#define LCDC_LCDIMR_HCRIM (0x1 << 12) +#define LCDC_LCDIMR_PPIM (0x1 << 13) + +#define ATMEL_LCDC_LCDISR 0x0038 +#define LCDC_LCDISR_SOF (0x1 << 0) +#define LCDC_LCDISR_DIS (0x1 << 1) +#define LCDC_LCDISR_DISP (0x1 << 2) +#define LCDC_LCDISR_FIFOERR (0x1 << 4) +#define LCDC_LCDISR_BASE (0x1 << 8) +#define LCDC_LCDISR_OVR1 (0x1 << 9) +#define LCDC_LCDISR_OVR2 (0x1 << 10) +#define LCDC_LCDISR_HEO (0x1 << 11) +#define LCDC_LCDISR_HCR (0x1 << 12) +#define LCDC_LCDISR_PP (0x1 << 13) + +#define ATMEL_LCDC_BASECHER 0x0040 +#define LCDC_BASECHER_CHEN (0x1 << 0) +#define LCDC_BASECHER_UPDATEEN (0x1 << 1) +#define LCDC_BASECHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_BASECHDR 0x0044 +#define LCDC_BASECHDR_CHDIS (0x1 << 0) +#define LCDC_BASECHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_BASECHSR 0x0048 +#define LCDC_BASECHSR_CHSR (0x1 << 0) +#define LCDC_BASECHSR_UPDATESR (0x1 << 1) +#define LCDC_BASECHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_BASEIER 0x004C +#define LCDC_BASEIER_DMA (0x1 << 2) +#define LCDC_BASEIER_DSCR (0x1 << 3) +#define LCDC_BASEIER_ADD (0x1 << 4) +#define LCDC_BASEIER_DONE (0x1 << 5) +#define LCDC_BASEIER_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEIDR 0x0050 +#define LCDC_BASEIDR_DMA (0x1 << 2) +#define LCDC_BASEIDR_DSCR (0x1 << 3) +#define LCDC_BASEIDR_ADD (0x1 << 4) +#define LCDC_BASEIDR_DONE (0x1 << 5) +#define LCDC_BASEIDR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEIMR 0x0054 +#define LCDC_BASEIMR_DMA (0x1 << 2) +#define LCDC_BASEIMR_DSCR (0x1 << 3) +#define LCDC_BASEIMR_ADD (0x1 << 4) +#define LCDC_BASEIMR_DONE (0x1 << 5) +#define LCDC_BASEIMR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEISR 0x0058 +#define LCDC_BASEISR_DMA (0x1 << 2) +#define LCDC_BASEISR_DSCR (0x1 << 3) +#define LCDC_BASEISR_ADD (0x1 << 4) +#define LCDC_BASEISR_DONE (0x1 << 5) +#define LCDC_BASEISR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEHEAD 0x005C + +#define ATMEL_LCDC_BASEADDR 0x0060 + +#define ATMEL_LCDC_BASECTRL 0x0064 +#define LCDC_BASECTRL_DFETCH (0x1 << 0) +#define LCDC_BASECTRL_LFETCH (0x1 << 1) +#define LCDC_BASECTRL_DMAIEN (0x1 << 2) +#define LCDC_BASECTRL_DSCRIEN (0x1 << 3) +#define LCDC_BASECTRL_ADDIEN (0x1 << 4) +#define LCDC_BASECTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_BASENEXT 0x0068 + +#define ATMEL_LCDC_BASECFG0 0x006C +#define LCDC_BASECFG0_SIF (0x1 << 0) +#define LCDC_BASECFG0_BLEN_OFFSET 4 +#define LCDC_BASECFG0_BLEN (0x3 << LCDC_BASECFG0_BLEN_OFFSET) +#define LCDC_BASECFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_BASECFG0_DLBO (0x1 << 8) + +#define ATMEL_LCDC_BASECFG1 0x0070 +#define LCDC_BASECFG1_CLUTEN (0x1 << 0) +#define LCDC_BASECFG1_RGBMODE_OFFSET 4 +#define LCDC_BASECFG1_RGBMODE (0xf << LCDC_BASECFG1_RGBMODE_OFFSET) +#define LCDC_BASECFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_BASECFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_BASECFG1_CLUTMODE_OFFSET 8 +#define LCDC_BASECFG1_CLUTMODE (0x3 << LCDC_BASECFG1_CLUTMODE_OFFSET) +#define LCDC_BASECFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_BASECFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_BASECFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_BASECFG1_CLUTMODE_8BPP (0x3 << 8) + +#define ATMEL_LCDC_BASECFG2 0x0074 + +#define ATMEL_LCDC_BASECFG3 0x0078 +#define LCDC_BASECFG3_BDEF_OFFSET 0 +#define LCDC_BASECFG3_BDEF (0xff << LCDC_BASECFG3_BDEF_OFFSET) +#define LCDC_BASECFG3_GDEF_OFFSET 8 +#define LCDC_BASECFG3_GDEF (0xff << LCDC_BASECFG3_GDEF_OFFSET) +#define LCDC_BASECFG3_RDEF_OFFSET 16 +#define LCDC_BASECFG3_RDEF (0xff << LCDC_BASECFG3_RDEF_OFFSET) + +#define ATMEL_LCDC_BASECFG4 0x007C +#define LCDC_BASECFG4_DMA (0x1 << 8) +#define LCDC_BASECFG4_REP (0x1 << 9) +#define LCDC_BASECFG4_DISCEN (0x1 << 11) + +#define ATMEL_LCDC_BASECFG5 0x0080 +#define LCDC_BASECFG5_DISCXPOS_OFFSET 0 +#define LCDC_BASECFG5_DISCXPOS (0x7ff << LCDC_BASECFG5_DISCXPOS_OFFSET) +#define LCDC_BASECFG5_DISCYPOS_OFFSET 16 +#define LCDC_BASECFG5_DISCYPOS (0x7ff << LCDC_BASECFG5_DISCYPOS_OFFSET) + +#define ATMEL_LCDC_BASECFG6 0x0084 +#define LCDC_BASECFG6_DISCXSIZE_OFFSET 0 +#define LCDC_BASECFG6_DISCXSIZE (0x7ff << LCDC_BASECFG6_DISCXSIZE_OFFSET) +#define LCDC_BASECFG6_DISCYSIZE_OFFSET 16 +#define LCDC_BASECFG6_DISCYSIZE (0x7ff << LCDC_BASECFG6_DISCYSIZE_OFFSET) + +#define ATMEL_LCDC_HEOCHER 0x0280 +#define ATMEL_LCDC2_HEOCHER 0x0340 +#define LCDC_HEOCHER_CHEN (0x1 << 0) +#define LCDC_HEOCHER_UPDATEEN (0x1 << 1) +#define LCDC_HEOCHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_HEOCHDR 0x0284 +#define LCDC_HEOCHDR_CHDIS (0x1 << 0) +#define LCDC_HEOCHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_HEOCHSR 0x0288 +#define LCDC_HEOCHSR_CHSR (0x1 << 0) +#define LCDC_HEOCHSR_UPDATESR (0x1 << 1) +#define LCDC_HEOCHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_HEOIER 0x028C +#define LCDC_HEOIER_DMA (0x1 << 2) +#define LCDC_HEOIER_DSCR (0x1 << 3) +#define LCDC_HEOIER_ADD (0x1 << 4) +#define LCDC_HEOIER_DONE (0x1 << 5) +#define LCDC_HEOIER_OVR (0x1 << 6) +#define LCDC_HEOIER_UDMA (0x1 << 10) +#define LCDC_HEOIER_UDSCR (0x1 << 11) +#define LCDC_HEOIER_UADD (0x1 << 12) +#define LCDC_HEOIER_UDONE (0x1 << 13) +#define LCDC_HEOIER_UOVR (0x1 << 14) +#define LCDC_HEOIER_VDMA (0x1 << 18) +#define LCDC_HEOIER_VDSCR (0x1 << 19) +#define LCDC_HEOIER_VADD (0x1 << 20) +#define LCDC_HEOIER_VDONE (0x1 << 21) +#define LCDC_HEOIER_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOIDR 0x0290 +#define LCDC_HEOIDR_DMA (0x1 << 2) +#define LCDC_HEOIDR_DSCR (0x1 << 3) +#define LCDC_HEOIDR_ADD (0x1 << 4) +#define LCDC_HEOIDR_DONE (0x1 << 5) +#define LCDC_HEOIDR_OVR (0x1 << 6) +#define LCDC_HEOIDR_UDMA (0x1 << 10) +#define LCDC_HEOIDR_UDSCR (0x1 << 11) +#define LCDC_HEOIDR_UADD (0x1 << 12) +#define LCDC_HEOIDR_UDONE (0x1 << 13) +#define LCDC_HEOIDR_UOVR (0x1 << 14) +#define LCDC_HEOIDR_VDMA (0x1 << 18) +#define LCDC_HEOIDR_VDSCR (0x1 << 19) +#define LCDC_HEOIDR_VADD (0x1 << 20) +#define LCDC_HEOIDR_VDONE (0x1 << 21) +#define LCDC_HEOIDR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOIMR 0x0294 +#define LCDC_HEOIMR_DMA (0x1 << 2) +#define LCDC_HEOIMR_DSCR (0x1 << 3) +#define LCDC_HEOIMR_ADD (0x1 << 4) +#define LCDC_HEOIMR_DONE (0x1 << 5) +#define LCDC_HEOIMR_OVR (0x1 << 6) +#define LCDC_HEOIMR_UDMA (0x1 << 10) +#define LCDC_HEOIMR_UDSCR (0x1 << 11) +#define LCDC_HEOIMR_UADD (0x1 << 12) +#define LCDC_HEOIMR_UDONE (0x1 << 13) +#define LCDC_HEOIMR_UOVR (0x1 << 14) +#define LCDC_HEOIMR_VDMA (0x1 << 18) +#define LCDC_HEOIMR_VDSCR (0x1 << 19) +#define LCDC_HEOIMR_VADD (0x1 << 20) +#define LCDC_HEOIMR_VDONE (0x1 << 21) +#define LCDC_HEOIMR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOISR 0x0298 +#define LCDC_HEOISR_DMA (0x1 << 2) +#define LCDC_HEOISR_DSCR (0x1 << 3) +#define LCDC_HEOISR_ADD (0x1 << 4) +#define LCDC_HEOISR_DONE (0x1 << 5) +#define LCDC_HEOISR_OVR (0x1 << 6) +#define LCDC_HEOISR_UDMA (0x1 << 10) +#define LCDC_HEOISR_UDSCR (0x1 << 11) +#define LCDC_HEOISR_UADD (0x1 << 12) +#define LCDC_HEOISR_UDONE (0x1 << 13) +#define LCDC_HEOISR_UOVR (0x1 << 14) +#define LCDC_HEOISR_VDMA (0x1 << 18) +#define LCDC_HEOISR_VDSCR (0x1 << 19) +#define LCDC_HEOISR_VADD (0x1 << 20) +#define LCDC_HEOISR_VDONE (0x1 << 21) +#define LCDC_HEOISR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOHEAD 0x029C + +#define ATMEL_LCDC_HEOADDR 0x02A0 + +#define ATMEL_LCDC_HEOCTRL 0x02A4 +#define LCDC_HEOCTRL_DFETCH (0x1 << 0) +#define LCDC_HEOCTRL_LFETCH (0x1 << 1) +#define LCDC_HEOCTRL_DMAIEN (0x1 << 2) +#define LCDC_HEOCTRL_DSCRIEN (0x1 << 3) +#define LCDC_HEOCTRL_ADDIEN (0x1 << 4) +#define LCDC_HEOCTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEONEXT 0x02A8 + +#define ATMEL_LCDC_HEOUHEAD 0x02AC + +#define ATMEL_LCDC_HEOUADDR 0x02B0 + +#define ATMEL_LCDC_HEOUCTRL 0x02B4 +#define LCDC_HEOUCTRL_UDFETCH (0x1 << 0) +#define LCDC_HEOUCTRL_UDMAIEN (0x1 << 2) +#define LCDC_HEOUCTRL_UDSCRIEN (0x1 << 3) +#define LCDC_HEOUCTRL_UADDIEN (0x1 << 4) +#define LCDC_HEOUCTRL_UDONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEOUNEXT 0x02B8 + +#define ATMEL_LCDC_HEOVHEAD 0x02BC + +#define ATMEL_LCDC_HEOVADDR 0x02C0 + +#define ATMEL_LCDC_HEOVCTRL 0x02C4 +#define LCDC_HEOVCTRL_VDFETCH (0x1 << 0) +#define LCDC_HEOVCTRL_VDMAIEN (0x1 << 2) +#define LCDC_HEOVCTRL_VDSCRIEN (0x1 << 3) +#define LCDC_HEOVCTRL_VADDIEN (0x1 << 4) +#define LCDC_HEOVCTRL_VDONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEOVNEXT 0x02C8 + +#define ATMEL_LCDC_HEOCFG0 0x02CC +#define LCDC_HEOCFG0_BLEN_OFFSET 4 +#define LCDC_HEOCFG0_BLEN (0x3 << LCDC_HEOCFG0_BLEN_OFFSET) +#define LCDC_HEOCFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_HEOCFG0_BLENUV_OFFSET 6 +#define LCDC_HEOCFG0_BLENUV (0x3 << LCDC_HEOCFG0_BLENUV_OFFSET) +#define LCDC_HEOCFG0_BLENUV_AHB_SINGLE (0x0 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR4 (0x1 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR8 (0x2 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR16 (0x3 << 6) +#define LCDC_HEOCFG0_DLBO (0x1 << 8) +#define LCDC_HEOCFG0_ROTDIS (0x1 << 12) +#define LCDC_HEOCFG0_LOCKDIS (0x1 << 13) + +#define ATMEL_LCDC_HEOCFG1 0x02D0 +#define LCDC_HEOCFG1_CLUTEN (0x1 << 0) +#define LCDC_HEOCFG1_YUVEN (0x1 << 1) +#define LCDC_HEOCFG1_RGBMODE_OFFSET 4 +#define LCDC_HEOCFG1_RGBMODE (0xf << LCDC_HEOCFG1_RGBMODE_OFFSET) +#define LCDC_HEOCFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_HEOCFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_HEOCFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_HEOCFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_HEOCFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_HEOCFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_HEOCFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_HEOCFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_HEOCFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_HEOCFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_HEOCFG1_CLUTMODE_OFFSET 8 +#define LCDC_HEOCFG1_CLUTMODE (0x3 << LCDC_HEOCFG1_CLUTMODE_OFFSET) +#define LCDC_HEOCFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_HEOCFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_HEOCFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_HEOCFG1_CLUTMODE_8BPP (0x3 << 8) +#define LCDC_HEOCFG1_YUVMODE_OFFSET 12 +#define LCDC_HEOCFG1_YUVMODE (0xf << LCDC_HEOCFG1_YUVMODE_OFFSET) +#define LCDC_HEOCFG1_YUVMODE_32BPP_AYCBCR (0x0 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE0 (0x1 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE1 (0x2 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE2 (0x3 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE3 (0x4 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_SEMIPLANAR (0x5 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_PLANAR (0x6 << 12) +#define LCDC_HEOCFG1_YUVMODE_12BPP_YCBCR_SEMIPLANAR (0x7 << 12) +#define LCDC_HEOCFG1_YUVMODE_12BPP_YCBCR_PLANAR (0x8 << 12) +#define LCDC_HEOCFG1_YUV422ROT (0x1 << 16) +#define LCDC_HEOCFG1_YUV422SWP (0x1 << 17) + +#define ATMEL_LCDC_HEOCFG2 0x02D4 +#define LCDC_HEOCFG2_XOFFSET_OFFSET 0 +#define LCDC_HEOCFG2_XOFFSET (0x7ff << LCDC_HEOCFG2_XOFFSET_OFFSET) +#define LCDC_HEOCFG2_YOFFSET_OFFSET 16 +#define LCDC_HEOCFG2_YOFFSET (0x7ff << LCDC_HEOCFG2_YOFFSET_OFFSET) + +#define ATMEL_LCDC_HEOCFG3 0x02D8 +#define LCDC_HEOCFG3_XSIZE_OFFSET 0 +#define LCDC_HEOCFG3_XSIZE (0x7ff << LCDC_HEOCFG3_XSIZE_OFFSET) +#define LCDC_HEOCFG3_YSIZE_OFFSET 16 +#define LCDC_HEOCFG3_YSIZE (0x7ff << LCDC_HEOCFG3_YSIZE_OFFSET) + +#define ATMEL_LCDC_HEOCFG4 0x02DC +#define LCDC_HEOCFG4_XMEM_SIZE_OFFSET 0 +#define LCDC_HEOCFG4_XMEM_SIZE (0x7ff << LCDC_HEOCFG4_XMEM_SIZE_OFFSET) +#define LCDC_HEOCFG4_YMEM_SIZE_OFFSET 16 +#define LCDC_HEOCFG4_YMEM_SIZE (0x7ff << LCDC_HEOCFG4_YMEM_SIZE_OFFSET) + +#define ATMEL_LCDC_HEOCFG5 0x02E0 + +#define ATMEL_LCDC_HEOCFG6 0x02E4 + +#define ATMEL_LCDC_HEOCFG7 0x02E8 + +#define ATMEL_LCDC_HEOCFG8 0x02EC + +#define ATMEL_LCDC_HEOCFG9 0x02F0 +#define LCDC_HEOCFG9_BDEF_OFFSET 0 +#define LCDC_HEOCFG9_BDEF (0xff << LCDC_HEOCFG9_BDEF_OFFSET) +#define LCDC_HEOCFG9_GDEF_OFFSET 8 +#define LCDC_HEOCFG9_GDEF (0xff << LCDC_HEOCFG9_GDEF_OFFSET) +#define LCDC_HEOCFG9_RDEF_OFFSET 16 +#define LCDC_HEOCFG9_RDEF (0xff << LCDC_HEOCFG9_RDEF_OFFSET) + +#define ATMEL_LCDC_HEOCFG10 0x02F4 +#define LCDC_HEOCFG10_BKEY_OFFSET 0 +#define LCDC_HEOCFG10_BKEY (0xff << LCDC_HEOCFG10_BKEY_OFFSET) +#define LCDC_HEOCFG10_GKEY_OFFSET 8 +#define LCDC_HEOCFG10_GKEY (0xff << LCDC_HEOCFG10_GKEY_OFFSET) +#define LCDC_HEOCFG10_RKEY_OFFSET 16 +#define LCDC_HEOCFG10_RKEY (0xff << LCDC_HEOCFG10_RKEY_OFFSET) + +#define ATMEL_LCDC_HEOCFG11 0x02F8 +#define LCDC_HEOCFG11_BMASK_OFFSET 0 +#define LCDC_HEOCFG11_BMASK (0xff << LCDC_HEOCFG11_BMASK_OFFSET) +#define LCDC_HEOCFG11_GMASK_OFFSET 8 +#define LCDC_HEOCFG11_GMASK (0xff << LCDC_HEOCFG11_GMASK_OFFSET) +#define LCDC_HEOCFG11_RMASK_OFFSET 16 +#define LCDC_HEOCFG11_RMASK (0xff << LCDC_HEOCFG11_RMASK_OFFSET) + +#define ATMEL_LCDC_HEOCFG12 0x02FC +#define LCDC_HEOCFG12_CRKEY (0x1 << 0) +#define LCDC_HEOCFG12_INV (0x1 << 1) +#define LCDC_HEOCFG12_ITER2BL (0x1 << 2) +#define LCDC_HEOCFG12_ITER (0x1 << 3) +#define LCDC_HEOCFG12_REVALPHA (0x1 << 4) +#define LCDC_HEOCFG12_GAEN (0x1 << 5) +#define LCDC_HEOCFG12_LAEN (0x1 << 6) +#define LCDC_HEOCFG12_OVR (0x1 << 7) +#define LCDC_HEOCFG12_DMA (0x1 << 8) +#define LCDC_HEOCFG12_REP (0x1 << 9) +#define LCDC_HEOCFG12_DSTKEY (0x1 << 10) +#define LCDC_HEOCFG12_VIDPRI (0x1 << 12) +#define LCDC_HEOCFG12_GA_OFFSET 16 +#define LCDC_HEOCFG12_GA (0xff << LCDC_HEOCFG12_GA_OFFSET) + +#define ATMEL_LCDC_HEOCFG13 0x0300 +#define LCDC_HEOCFG13_XFACTOR_OFFSET 0 +#define LCDC_HEOCFG13_XFACTOR (0x1fff << LCDC_HEOCFG13_XFACTOR_OFFSET) +#define LCDC_HEOCFG13_YFACTOR_OFFSET 16 +#define LCDC_HEOCFG13_YFACTOR (0x1fff << LCDC_HEOCFG13_YFACTOR_OFFSET) +#define LCDC_HEOCFG13_SCALEN (0x1 << 31) + +#define ATMEL_LCDC_HEOCFG14 0x0304 +#define LCDC_HEOCFG14_CSCRY_OFFSET 0 +#define LCDC_HEOCFG14_CSCRY (0x3ff << LCDC_HEOCFG14_CSCRY_OFFSET) +#define LCDC_HEOCFG14_CSCRU_OFFSET 10 +#define LCDC_HEOCFG14_CSCRU (0x3ff << LCDC_HEOCFG14_CSCRU_OFFSET) +#define LCDC_HEOCFG14_CSCRV_OFFSET 20 +#define LCDC_HEOCFG14_CSCRV (0x3ff << LCDC_HEOCFG14_CSCRV_OFFSET) +#define LCDC_HEOCFG14_CSCYOFF (0x1 << 30) + +#define ATMEL_LCDC_HEOCFG15 0x0308 +#define LCDC_HEOCFG15_CSCGY_OFFSET 0 +#define LCDC_HEOCFG15_CSCGY (0x3ff << LCDC_HEOCFG15_CSCGY_OFFSET) +#define LCDC_HEOCFG15_CSCGU_OFFSET 10 +#define LCDC_HEOCFG15_CSCGU (0x3ff << LCDC_HEOCFG15_CSCGU_OFFSET) +#define LCDC_HEOCFG15_CSCGV_OFFSET 20 +#define LCDC_HEOCFG15_CSCGV (0x3ff << LCDC_HEOCFG15_CSCGV_OFFSET) +#define LCDC_HEOCFG15_CSCUOFF (0x1 << 30) + +#define ATMEL_LCDC_HEOCFG16 0x030C +#define LCDC_HEOCFG16_CSCBY_OFFSET 0 +#define LCDC_HEOCFG16_CSCBY (0x3ff << LCDC_HEOCFG16_CSCBY_OFFSET) +#define LCDC_HEOCFG16_CSCBU_OFFSET 10 +#define LCDC_HEOCFG16_CSCBU (0x3ff << LCDC_HEOCFG16_CSCBU_OFFSET) +#define LCDC_HEOCFG16_CSCBV_OFFSET 20 +#define LCDC_HEOCFG16_CSCBV (0x3ff << LCDC_HEOCFG16_CSCBV_OFFSET) +#define LCDC_HEOCFG16_CSCVOFF (0x1 << 30) + +#define ATMEL_LCDC_HCRCHER 0x0340 +#define LCDC_HCRCHER_CHEN (0x1 << 0) +#define LCDC_HCRCHER_UPDATEEN (0x1 << 1) +#define LCDC_HCRCHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_HCRCHDR 0x0344 +#define LCDC_HCRCHDR_CHDIS (0x1 << 0) +#define LCDC_HCRCHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_HCRCHSR 0x0348 +#define LCDC_HCRCHSR_CHSR (0x1 << 0) +#define LCDC_HCRCHSR_UPDATESR (0x1 << 1) +#define LCDC_HCRCHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_HCRIER 0x034C +#define LCDC_HCRIER_DMA (0x1 << 2) +#define LCDC_HCRIER_DSCR (0x1 << 3) +#define LCDC_HCRIER_ADD (0x1 << 4) +#define LCDC_HCRIER_DONE (0x1 << 5) +#define LCDC_HCRIER_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRIDR 0x0350 +#define LCDC_HCRIDR_DMA (0x1 << 2) +#define LCDC_HCRIDR_DSCR (0x1 << 3) +#define LCDC_HCRIDR_ADD (0x1 << 4) +#define LCDC_HCRIDR_DONE (0x1 << 5) +#define LCDC_HCRIDR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRIMR 0x0354 +#define LCDC_HCRIMR_DMA (0x1 << 2) +#define LCDC_HCRIMR_DSCR (0x1 << 3) +#define LCDC_HCRIMR_ADD (0x1 << 4) +#define LCDC_HCRIMR_DONE (0x1 << 5) +#define LCDC_HCRIMR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRISR 0x0358 +#define LCDC_HCRISR_DMA (0x1 << 2) +#define LCDC_HCRISR_DSCR (0x1 << 3) +#define LCDC_HCRISR_ADD (0x1 << 4) +#define LCDC_HCRISR_DONE (0x1 << 5) +#define LCDC_HCRISR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRHEAD 0x035C + +#define ATMEL_LCDC_HCRADDR 0x0360 + +#define ATMEL_LCDC_HCRCTRL 0x0364 +#define LCDC_HCRCTRL_DFETCH (0x1 << 0) +#define LCDC_HCRCTRL_LFETCH (0x1 << 1) +#define LCDC_HCRCTRL_DMAIEN (0x1 << 2) +#define LCDC_HCRCTRL_DSCRIEN (0x1 << 3) +#define LCDC_HCRCTRL_ADDIEN (0x1 << 4) +#define LCDC_HCRCTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HCRNEXT 0x0368 + +#define ATMEL_LCDC_HCRCFG0 0x036C +#define LCDC_HCRCFG0_BLEN_OFFSET 4 +#define LCDC_HCRCFG0_BLEN (0x3 << LCDC_HCRCFG0_BLEN_OFFSET) +#define LCDC_HCRCFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_HCRCFG0_DLBO (0x1 << 8) + +#define ATMEL_LCDC_HCRCFG1 0x0370 +#define LCDC_HCRCFG1_CLUTEN (0x1 << 0) +#define LCDC_HCRCFG1_RGBMODE_OFFSET 4 +#define LCDC_HCRCFG1_RGBMODE (0xf << LCDC_HCRCFG1_RGBMODE_OFFSET) +#define LCDC_HCRCFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_HCRCFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_HCRCFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_HCRCFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_HCRCFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_HCRCFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_HCRCFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_HCRCFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_HCRCFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_HCRCFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_HCRCFG1_CLUTMODE_OFFSET 8 +#define LCDC_HCRCFG1_CLUTMODE (0x3 << LCDC_HCRCFG1_CLUTMODE_OFFSET) +#define LCDC_HCRCFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_HCRCFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_HCRCFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_HCRCFG1_CLUTMODE_8BPP (0x3 << 8) + +#define ATMEL_LCDC_HCRCFG2 0x0374 +#define LCDC_HCRCFG2_XOFFSET_OFFSET 0 +#define LCDC_HCRCFG2_XOFFSET (0x7ff << LCDC_HCRCFG2_XOFFSET_OFFSET) +#define LCDC_HCRCFG2_YOFFSET_OFFSET 16 +#define LCDC_HCRCFG2_YOFFSET (0x7ff << LCDC_HCRCFG2_YOFFSET_OFFSET) + +#define ATMEL_LCDC_HCRCFG3 0x0378 +#define LCDC_HCRCFG3_XSIZE_OFFSET 0 +#define LCDC_HCRCFG3_XSIZE (0x7f << LCDC_HCRCFG3_XSIZE_OFFSET) +#define LCDC_HCRCFG3_YSIZE_OFFSET 16 +#define LCDC_HCRCFG3_YSIZE (0x7f << LCDC_HCRCFG3_YSIZE_OFFSET) + +#define ATMEL_LCDC_HCRCFG4 0x037C + +#define ATMEL_LCDC_HCRCFG6 0x0384 +#define LCDC_HCRCFG6_BDEF_OFFSET 0 +#define LCDC_HCRCFG6_BDEF (0xff << LCDC_HCRCFG6_BDEF_OFFSET) +#define LCDC_HCRCFG6_GDEF_OFFSET 8 +#define LCDC_HCRCFG6_GDEF (0xff << LCDC_HCRCFG6_GDEF_OFFSET) +#define LCDC_HCRCFG6_RDEF_OFFSET 16 +#define LCDC_HCRCFG6_RDEF (0xff << LCDC_HCRCFG6_RDEF_OFFSET) + +#define ATMEL_LCDC_HCRCFG7 0x0388 +#define LCDC_HCRCFG7_BKEY_OFFSET 0 +#define LCDC_HCRCFG7_BKEY (0xff << LCDC_HCRCFG7_BKEY_OFFSET) +#define LCDC_HCRCFG7_GKEY_OFFSET 8 +#define LCDC_HCRCFG7_GKEY (0xff << LCDC_HCRCFG7_GKEY_OFFSET) +#define LCDC_HCRCFG7_RKEY_OFFSET 16 +#define LCDC_HCRCFG7_RKEY (0xff << LCDC_HCRCFG7_RKEY_OFFSET) + +#define ATMEL_LCDC_HCRCFG8 0x038C +#define LCDC_HCRCFG8_BMASK_OFFSET 0 +#define LCDC_HCRCFG8_BMASK (0xff << LCDC_HCRCFG8_BMASK_OFFSET) +#define LCDC_HCRCFG8_GMASK_OFFSET 8 +#define LCDC_HCRCFG8_GMASK (0xff << LCDC_HCRCFG8_GMASK_OFFSET) +#define LCDC_HCRCFG8_RMASK_OFFSET 16 +#define LCDC_HCRCFG8_RMASK (0xff << LCDC_HCRCFG8_RMASK_OFFSET) + +#define ATMEL_LCDC_HCRCFG9 0x0390 +#define LCDC_HCRCFG9_CRKEY (0x1 << 0) +#define LCDC_HCRCFG9_INV (0x1 << 1) +#define LCDC_HCRCFG9_ITER2BL (0x1 << 2) +#define LCDC_HCRCFG9_ITER (0x1 << 3) +#define LCDC_HCRCFG9_REVALPHA (0x1 << 4) +#define LCDC_HCRCFG9_GAEN (0x1 << 5) +#define LCDC_HCRCFG9_LAEN (0x1 << 6) +#define LCDC_HCRCFG9_OVR (0x1 << 7) +#define LCDC_HCRCFG9_DMA (0x1 << 8) +#define LCDC_HCRCFG9_REP (0x1 << 9) +#define LCDC_HCRCFG9_DSTKEY (0x1 << 10) +#define LCDC_HCRCFG9_GA_OFFSET 16 +#define LCDC_HCRCFG9_GA_Msk (0xff << LCDC_HCRCFG9_GA_OFFSET) + +#define ATMEL_LCDC_BASECLUT 0x400 +#define ATMEL_LCDC2_BASECLUT 0x600 +#define LCDC_BASECLUT_BCLUT_OFFSET 0 +#define LCDC_BASECLUT_BCLUT (0xff << LCDC_BASECLUT_BCLUT_OFFSET) +#define LCDC_BASECLUT_GCLUT_OFFSET 8 +#define LCDC_BASECLUT_GCLUT (0xff << LCDC_BASECLUT_GCLUT_OFFSET) +#define LCDC_BASECLUT_RCLUT_OFFSET 16 +#define LCDC_BASECLUT_RCLUT (0xff << LCDC_BASECLUT_RCLUT_OFFSET) + +#define ATMEL_LCDC_OVR1CLUT 0x800 +#define ATMEL_LCDC2_OVR1CLUT 0xa00 +#define LCDC_OVR1CLUT_BCLUT_OFFSET 0 +#define LCDC_OVR1CLUT_BCLUT (0xff << LCDC_OVR1CLUT_BCLUT_OFFSET) +#define LCDC_OVR1CLUT_GCLUT_OFFSET 8 +#define LCDC_OVR1CLUT_GCLUT (0xff << LCDC_OVR1CLUT_GCLUT_OFFSET) +#define LCDC_OVR1CLUT_RCLUT_OFFSET 16 +#define LCDC_OVR1CLUT_RCLUT (0xff << LCDC_OVR1CLUT_RCLUT_OFFSET) +#define LCDC_OVR1CLUT_ACLUT_OFFSET 24 +#define LCDC_OVR1CLUT_ACLUT (0xff << LCDC_OVR1CLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_OVR2CLUT 0xe00 +#define LCDC_OVR2CLUT_BCLUT_OFFSET 0 +#define LCDC_OVR2CLUT_BCLUT (0xff << LCDC_OVR2CLUT_BCLUT_OFFSET) +#define LCDC_OVR2CLUT_GCLUT_OFFSET 8 +#define LCDC_OVR2CLUT_GCLUT (0xff << LCDC_OVR2CLUT_GCLUT_OFFSET) +#define LCDC_OVR2CLUT_RCLUT_OFFSET 16 +#define LCDC_OVR2CLUT_RCLUT (0xff << LCDC_OVR2CLUT_RCLUT_OFFSET) +#define LCDC_OVR2CLUT_ACLUT_OFFSET 24 +#define LCDC_OVR2CLUT_ACLUT (0xff << LCDC_OVR2CLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_HEOCLUT 0x1000 +#define ATMEL_LCDC2_HEOCLUT 0x1200 +#define LCDC_HEOCLUT_BCLUT_OFFSET 0 +#define LCDC_HEOCLUT_BCLUT (0xff << LCDC_HEOCLUT_BCLUT_OFFSET) +#define LCDC_HEOCLUT_GCLUT_OFFSET 8 +#define LCDC_HEOCLUT_GCLUT (0xff << LCDC_HEOCLUT_GCLUT_OFFSET) +#define LCDC_HEOCLUT_RCLUT_OFFSET 16 +#define LCDC_HEOCLUT_RCLUT (0xff << LCDC_HEOCLUT_RCLUT_OFFSET) +#define LCDC_HEOCLUT_ACLUT_OFFSET 24 +#define LCDC_HEOCLUT_ACLUT (0xff << LCDC_HEOCLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_HCRCLUT 0x1400 +#define ATMEL_LCDC2_HCRCLUT 0x1600 +#define LCDC_HCRCLUT_BCLUT_OFFSET 0 +#define LCDC_HCRCLUT_BCLUT (0xff << LCDC_HCRCLUT_BCLUT_OFFSET) +#define LCDC_HCRCLUT_GCLUT_OFFSET 8 +#define LCDC_HCRCLUT_GCLUT (0xff << LCDC_HCRCLUT_GCLUT_OFFSET) +#define LCDC_HCRCLUT_RCLUT_OFFSET 16 +#define LCDC_HCRCLUT_RCLUT (0xff << LCDC_HCRCLUT_RCLUT_OFFSET) +#define LCDC_HCRCLUT_ACLUT_OFFSET 24 +#define LCDC_HCRCLUT_ACLUT (0xff << LCDC_HCRCLUT_ACLUT_OFFSET) + +/* Base layer CLUT */ +#define ATMEL_HLCDC_LUT 0x0400 + + +#endif /* __MACH_ATMEL_HLCDC4_H__ */ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fcf9425..6d6b08f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -9,6 +9,10 @@ config DRIVER_VIDEO_ATMEL bool "Atmel LCDC framebuffer driver" depends on ARCH_AT91 +config DRIVER_VIDEO_ATMEL_HLCD + bool "Atmel HLCDC framebuffer driver" + depends on ARCH_AT91 + config DRIVER_VIDEO_IMX bool "i.MX framebuffer driver" depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 724ef99..7429141 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_VIDEO) += fb.o obj-$(CONFIG_DRIVER_VIDEO_ATMEL) += atmel_lcdfb.o atmel_lcdfb_core.o +obj-$(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) += atmel_hlcdfb.o atmel_lcdfb_core.o obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c new file mode 100644 index 0000000..78a737d --- /dev/null +++ b/drivers/video/atmel_hlcdfb.c @@ -0,0 +1,297 @@ +/* + * Driver for AT91/AT32 LCD Controller + * + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <io.h> +#include <init.h> +#include <linux/clk.h> +#include <mach/hardware.h> +#include <mach/atmel_hlcdc.h> +#include <mach/io.h> +#include <mach/cpu.h> +#include <errno.h> +#include <asm/mmu.h> + +#include "atmel_lcdfb.h" + +#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 + +static void atmel_hlcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags) +{ + /* Disable DISP signal */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_DISPDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS)) + mdelay(1); + /* Disable synchronization */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_SYNCDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS)) + mdelay(1); + /* Disable pixel clock */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_CLKDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS)) + mdelay(1); + /* Disable PWM */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_PWMDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS)) + mdelay(1); + + if (!(flags & ATMEL_LCDC_STOP_NOWAIT)) + /* Wait for the end of DMA transfer */ + while (!(lcdc_readl(sinfo, ATMEL_LCDC_BASEISR) & LCDC_BASEISR_DMA)) + mdelay(10); + /*FIXME: OVL DMA? */ +} + +static void atmel_hlcdfb_start(struct atmel_lcdfb_info *sinfo) +{ + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_CLKEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_SYNCEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_DISPEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_PWMEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS)) + mdelay(1); +} + +struct atmel_hlcd_dma_desc { + u32 address; + u32 control; + u32 next; +}; + +static void atmel_hlcdfb_update_dma(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + unsigned long dma_addr; + struct atmel_hlcd_dma_desc *desc; + + dma_addr = (u32)info->screen_base; + dma_addr &= ~3UL; + + /* Setup the DMA descriptor, this descriptor will loop to itself */ + desc = sinfo->dma_desc; + + desc->address = dma_addr; + /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ + desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN + | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; + desc->next = (u32)desc; + + lcdc_writel(sinfo, ATMEL_LCDC_BASEADDR, desc->address); + lcdc_writel(sinfo, ATMEL_LCDC_BASECTRL, desc->control); + lcdc_writel(sinfo, ATMEL_LCDC_BASENEXT, desc->next); + lcdc_writel(sinfo, ATMEL_LCDC_BASECHER, LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN); +} + +static void atmel_hlcdfb_limit_screeninfo(struct fb_videomode *mode) +{ + u32 hbpw, hfpw; + + if (cpu_is_at91sam9x5()) { + hbpw = LCDC_LCDCFG3_HBPW; + hfpw = LCDC_LCDCFG3_HFPW; + } else { + hbpw = LCDC2_LCDCFG3_HBPW; + hfpw = LCDC2_LCDCFG3_HFPW; + } + + /* Saturate vertical and horizontal timings at maximum values */ + mode->vsync_len = min_t(u32, mode->vsync_len, + (LCDC_LCDCFG1_VSPW >> LCDC_LCDCFG1_VSPW_OFFSET) + 1); + mode->upper_margin = min_t(u32, mode->upper_margin, + (LCDC_LCDCFG2_VFPW >> LCDC_LCDCFG2_VFPW_OFFSET) + 1); + mode->lower_margin = min_t(u32, mode->lower_margin, + LCDC_LCDCFG2_VBPW >> LCDC_LCDCFG2_VBPW_OFFSET); + mode->right_margin = min_t(u32, mode->right_margin, + (hbpw >> LCDC_LCDCFG3_HBPW_OFFSET) + 1); + mode->hsync_len = min_t(u32, mode->hsync_len, + (LCDC_LCDCFG1_HSPW >> LCDC_LCDCFG1_HSPW_OFFSET) + 1); + mode->left_margin = min_t(u32, mode->left_margin, + (hfpw >> LCDC_LCDCFG3_HFPW_OFFSET) + 1); +} + +static u32 atmel_hlcdfb_get_rgbmode(struct fb_info *info) +{ + u32 value = 0; + + switch (info->bits_per_pixel) { + case 1: + value = LCDC_BASECFG1_CLUTMODE_1BPP | LCDC_BASECFG1_CLUTEN; + break; + case 2: + value = LCDC_BASECFG1_CLUTMODE_2BPP | LCDC_BASECFG1_CLUTEN; + break; + case 4: + value = LCDC_BASECFG1_CLUTMODE_4BPP | LCDC_BASECFG1_CLUTEN; + break; + case 8: + value = LCDC_BASECFG1_CLUTMODE_8BPP | LCDC_BASECFG1_CLUTEN; + break; + case 12: + value = LCDC_BASECFG1_RGBMODE_12BPP_RGB_444; + break; + case 16: + if (info->transp.offset) + value = LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444; + else + value = LCDC_BASECFG1_RGBMODE_16BPP_RGB_565; + break; + case 18: + value = LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED; + break; + case 24: + value = LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED; + break; + case 32: + value = LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888; + break; + default: + dev_err(&info->dev, "Cannot set video mode for %dbpp\n", + info->bits_per_pixel); + break; + } + + return value; +} + +static void atmel_hlcdfb_setup_core_base(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + struct fb_videomode *mode = info->mode; + unsigned long value; + unsigned long clk_value_khz; + + dev_dbg(&info->dev, "%s:\n", __func__); + /* Set pixel clock */ + clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; + + value = DIV_ROUND_CLOSEST(clk_value_khz, PICOS2KHZ(mode->pixclock)); + + if (value < 1) { + dev_notice(&info->dev, "using system clock as pixel clock\n"); + value = LCDC_LCDCFG0_CLKPWMSEL; + } else { + mode->pixclock = KHZ2PICOS(clk_value_khz / value); + dev_dbg(&info->dev, " updated pixclk: %lu KHz\n", + PICOS2KHZ(mode->pixclock)); + value = value - 2; + dev_dbg(&info->dev, " * programming CLKDIV = 0x%08lx\n", + value); + value = (value << LCDC_LCDCFG0_CLKDIV_OFFSET); + } + value |= LCDC_LCDCFG0_CGDISBASE; + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG0, value); + + /* Initialize control register 5 */ + /* In 9x5, the default_lcdcon2 will use for LCDCFG5 */ + value = pdata->default_lcdcon2; + value |= (sinfo->guard_time << LCDC_LCDCFG5_GUARDTIME_OFFSET) + | LCDC_LCDCFG5_DISPDLY + | LCDC_LCDCFG5_VSPDLYS; + + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) + value |= LCDC_LCDCFG5_HSPOL; + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) + value |= LCDC_LCDCFG5_VSPOL; + + dev_dbg(&info->dev, " * LCDC_LCDCFG5 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG5, value); + + /* Vertical & Horizontal Timing */ + value = (mode->vsync_len - 1) << LCDC_LCDCFG1_VSPW_OFFSET; + value |= (mode->hsync_len - 1) << LCDC_LCDCFG1_HSPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG1 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG1, value); + + value = (mode->upper_margin) << LCDC_LCDCFG2_VBPW_OFFSET; + value |= (mode->lower_margin - 1) << LCDC_LCDCFG2_VFPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG2 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG2, value); + + value = (mode->left_margin - 1) << LCDC_LCDCFG3_HBPW_OFFSET; + value |= (mode->right_margin - 1) << LCDC_LCDCFG3_HFPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG3 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG3, value); + + /* Display size */ + value = (mode->yres - 1) << LCDC_LCDCFG4_RPF_OFFSET; + value |= (mode->xres - 1) << LCDC_LCDCFG4_PPL_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG4 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG4, value); + + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG0, LCDC_BASECFG0_BLEN_AHB_INCR16 | LCDC_BASECFG0_DLBO); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG1, atmel_hlcdfb_get_rgbmode(info)); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG2, 0); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG3, 0); /* Default color */ + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG4, LCDC_BASECFG4_DMA); + + /* Disable all interrupts */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDIDR, ~0UL); + lcdc_writel(sinfo, ATMEL_LCDC_BASEIDR, ~0UL); + /* Enable BASE LAYER overflow interrupts, if want to enable DMA interrupt, also need set it at LCDC_BASECTRL reg */ + lcdc_writel(sinfo, ATMEL_LCDC_BASEIER, LCDC_BASEIER_OVR); + /* FIXME: Let video-driver register a callback */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDIER, LCDC_LCDIER_FIFOERRIE | + LCDC_LCDIER_BASEIE | LCDC_LCDIER_HEOIE); +} + + +static void atmel_hlcdfb_init_contrast(struct atmel_lcdfb_info *sinfo) +{ + /* have some default contrast/backlight settings */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG6, LCDC_LCDCFG6_PWMPOL | + (ATMEL_LCDC_CVAL_DEFAULT << LCDC_LCDCFG6_PWMCVAL_OFFSET)); +} + +struct atmel_lcdfb_devdata atmel_hlcdfb_data = { + .start = atmel_hlcdfb_start, + .stop = atmel_hlcdfb_stop, + .update_dma = atmel_hlcdfb_update_dma, + .setup_core = atmel_hlcdfb_setup_core_base, + .init_contrast = atmel_hlcdfb_init_contrast, + .limit_screeninfo = atmel_hlcdfb_limit_screeninfo, + .dma_desc_size = sizeof(struct atmel_hlcd_dma_desc), +}; + +static int atmel_hlcdc_probe(struct device_d *dev) +{ + return atmel_lcdc_register(dev, &atmel_hlcdfb_data); +} + +static struct driver_d atmel_hlcdc_driver = { + .name = "atmel_hlcdfb", + .probe = atmel_hlcdc_probe, +}; + +static int atmel_hlcdc_init(void) +{ + return platform_driver_register(&atmel_hlcdc_driver); +} +device_initcall(atmel_hlcdc_init); diff --git a/drivers/video/atmel_lcdfb.h b/drivers/video/atmel_lcdfb.h index 6c53dd4..ea4c7e6 100644 --- a/drivers/video/atmel_lcdfb.h +++ b/drivers/video/atmel_lcdfb.h @@ -11,7 +11,6 @@ struct atmel_lcdfb_devdata { void (*setup_core)(struct fb_info *info); void (*init_contrast)(struct atmel_lcdfb_info *sinfo); void (*limit_screeninfo)(struct fb_videomode *mode); - int fbinfo_flags; int dma_desc_size; }; @@ -27,6 +26,7 @@ struct atmel_lcdfb_info { struct atmel_lcdfb_platform_data *pdata; struct atmel_lcdfb_devdata *dev_data; + void *dma_desc; }; #define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg)) diff --git a/drivers/video/atmel_lcdfb_core.c b/drivers/video/atmel_lcdfb_core.c index 528bcd8..bed540d 100644 --- a/drivers/video/atmel_lcdfb_core.c +++ b/drivers/video/atmel_lcdfb_core.c @@ -290,6 +290,9 @@ int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) atmel_lcdfb_start_clock(sinfo); + if (data->dma_desc_size) + sinfo->dma_desc = dma_alloc_coherent(data->dma_desc_size); + ret = register_framebuffer(info); if (ret != 0) { dev_err(dev, "Failed to register framebuffer\n"); @@ -299,6 +302,8 @@ int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) return ret; stop_clk: + if (sinfo->dma_desc) + free(sinfo->dma_desc); atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); put_bus_clk: -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/6] at91sam9x5: add lcd support 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 2/6] video: add Atmel HLCD support Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 4/6] at91sam9x5ek: " Jean-Christophe PLAGNIOL-VILLARD ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox the sam9x5 have multiple overlay but only register the base one Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- arch/arm/mach-at91/at91sam9x5.c | 1 + arch/arm/mach-at91/at91sam9x5_devices.c | 55 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index e6e3a2f..01eac18 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -216,6 +216,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_DEV_ID("at91sam9x5-gpio2", &pioCD_clk), CLKDEV_DEV_ID("at91sam9x5-gpio3", &pioCD_clk), CLKDEV_DEV_ID("at91-pit", &mck), + CLKDEV_CON_DEV_ID("hck1", "atmel_hlcdfb", &lcdc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c index 21aead9..9f211e3 100644 --- a/arch/arm/mach-at91/at91sam9x5_devices.c +++ b/arch/arm/mach-at91/at91sam9x5_devices.c @@ -391,6 +391,61 @@ void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {} #endif /* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + if (cpu_is_at91sam9g25() || cpu_is_at91sam9x25()) { + pr_warn("AT91: no lcd on at91sam9g25 or at91sam9x25\n"); + return; + } + + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDPWM */ + + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PC28, 0); /* LCDHSYNC */ + + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDDISP */ + at91_set_A_periph(AT91_PIN_PC29, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PC30, 0); /* LCDPCK */ + + at91_set_A_periph(AT91_PIN_PC0, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC4, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD16 */ + at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD17 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC20, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PC21, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9X5_BASE_LCDC, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- * UART * -------------------------------------------------------------------- */ -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 4/6] at91sam9x5ek: add lcd support 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 2/6] video: add Atmel HLCD support Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 3/6] at91sam9x5: add lcd support Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 5/6] sama5d3: " Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 6/6] sama5d3xek: " Jean-Christophe PLAGNIOL-VILLARD 4 siblings, 0 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- arch/arm/boards/at91sam9x5ek/init.c | 44 +++++++++++++++++++++++++++++++ arch/arm/configs/at91sam9x5ek_defconfig | 4 ++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/arch/arm/boards/at91sam9x5ek/init.c b/arch/arm/boards/at91sam9x5ek/init.c index 9c45d31..4e1e069 100644 --- a/arch/arm/boards/at91sam9x5ek/init.c +++ b/arch/arm/boards/at91sam9x5ek/init.c @@ -118,6 +118,49 @@ static void ek_add_device_eth(void) at91_add_device_eth(0, &macb_pdata); } +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +/* + * LCD Controller + */ +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "LG", + .refresh = 60, + .xres = 800, .yres = 480, + .pixclock = KHZ2PICOS(33260), + + .left_margin = 88, .right_margin = 168, + .upper_margin = 8, .lower_margin = 37, + .hsync_len = 128, .vsync_len = 2, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +/* Default output mode is TFT 24 bit */ +#define AT91SAM9X5_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_24BPP) + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_lcdcon2 = AT91SAM9X5_DEFAULT_LCDCFG5, + .guard_time = 9, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static void ek_add_device_lcdc(void) +{ + at91_add_device_lcdc(&ek_lcdc_data); +} + +#else +static void ek_add_device_lcdc(void) {} +#endif + /* * MCI (SD/MMC) */ @@ -263,6 +306,7 @@ static int at91sam9x5ek_devices_init(void) ek_add_device_usb(); ek_add_led(); ek_add_device_i2c(); + ek_add_device_lcdc(); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); armlinux_set_architecture(CONFIG_MACH_AT91SAM9X5EK); diff --git a/arch/arm/configs/at91sam9x5ek_defconfig b/arch/arm/configs/at91sam9x5ek_defconfig index 400a35b..d2cdaf2 100644 --- a/arch/arm/configs/at91sam9x5ek_defconfig +++ b/arch/arm/configs/at91sam9x5ek_defconfig @@ -4,6 +4,7 @@ CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_PBL_IMAGE=y CONFIG_MMU=y +CONFIG_MALLOC_SIZE=0xa00000 CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 CONFIG_EXPERIMENTAL=y CONFIG_MALLOC_TLSF=y @@ -40,6 +41,7 @@ CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y CONFIG_CMD_MTEST=y CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -89,4 +91,4 @@ CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y -CONFIG_ZLIB=y +CONFIG_PNG=y -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 5/6] sama5d3: add lcd support 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD ` (2 preceding siblings ...) 2013-01-30 23:20 ` [PATCH 4/6] at91sam9x5ek: " Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 6/6] sama5d3xek: " Jean-Christophe PLAGNIOL-VILLARD 4 siblings, 0 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox the sam9x5 have multiple overlay but only register the base one Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- arch/arm/mach-at91/include/mach/board.h | 1 + arch/arm/mach-at91/sama5d3.c | 1 + arch/arm/mach-at91/sama5d3_devices.c | 53 +++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e7b1171..71267e1 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -26,6 +26,7 @@ #include <linux/mtd/mtd.h> #include <fb.h> #include <video/atmel_lcdc.h> +#include <mach/atmel_hlcdc.h> #include <linux/phy.h> /* USB Host */ diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c index 17d5654..0eec696 100644 --- a/arch/arm/mach-at91/sama5d3.c +++ b/arch/arm/mach-at91/sama5d3.c @@ -323,6 +323,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_DEV_ID("at91sam9x5-gpio3", &pioD_clk), CLKDEV_DEV_ID("at91sam9x5-gpio4", &pioE_clk), CLKDEV_DEV_ID("at91-pit", &pit_clk), + CLKDEV_CON_DEV_ID("hck1", "atmel_hlcdfb", &lcdc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c index 23e4ab9..3e4531e 100644 --- a/arch/arm/mach-at91/sama5d3_devices.c +++ b/arch/arm/mach-at91/sama5d3_devices.c @@ -404,6 +404,59 @@ void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {} #endif /* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + if (cpu_is_sama5d35()) { + pr_warn("AT91: no lcd on sama5d35\n"); + return; + } + + at91_set_A_periph(AT91_PIN_PA24, 0); /* LCDPWM */ + at91_set_A_periph(AT91_PIN_PA25, 0); /* LCDDISP */ + at91_set_A_periph(AT91_PIN_PA26, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PA27, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PA28, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PA29, 0); /* LCDDEN */ + + at91_set_A_periph(AT91_PIN_PA0, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PA3, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PA4, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PA5, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PA6, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PA8, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* LCDD15 */ + at91_set_C_periph(AT91_PIN_PC14, 0); /* LCDD16 */ + at91_set_C_periph(AT91_PIN_PC13, 0); /* LCDD17 */ + at91_set_C_periph(AT91_PIN_PC12, 0); /* LCDD18 */ + at91_set_C_periph(AT91_PIN_PC11, 0); /* LCDD19 */ + at91_set_C_periph(AT91_PIN_PC10, 0); /* LCDD20 */ + at91_set_C_periph(AT91_PIN_PC15, 0); /* LCDD21 */ + at91_set_C_periph(AT91_PIN_PE27, 0); /* LCDD22 */ + at91_set_C_periph(AT91_PIN_PE28, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, SAMA5D3_BASE_LCDC, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- * UART * -------------------------------------------------------------------- */ -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 6/6] sama5d3xek: add lcd support 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD ` (3 preceding siblings ...) 2013-01-30 23:20 ` [PATCH 5/6] sama5d3: " Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 ` Jean-Christophe PLAGNIOL-VILLARD 4 siblings, 0 replies; 7+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-01-30 23:20 UTC (permalink / raw) To: barebox Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- arch/arm/boards/sama5d3xek/init.c | 45 +++++++++++++++++++++++++++++++++ arch/arm/configs/sama5d3xek_defconfig | 4 +++ 2 files changed, 49 insertions(+) diff --git a/arch/arm/boards/sama5d3xek/init.c b/arch/arm/boards/sama5d3xek/init.c index ae23a31..d58bf44 100644 --- a/arch/arm/boards/sama5d3xek/init.c +++ b/arch/arm/boards/sama5d3xek/init.c @@ -153,6 +153,50 @@ static void ek_add_device_eth(void) static void ek_add_device_eth(void) {} #endif +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +/* + * LCD Controller + */ +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "LG", + .refresh = 60, + .xres = 800, .yres = 480, + .pixclock = KHZ2PICOS(33260), + + .left_margin = 88, .right_margin = 168, + .upper_margin = 8, .lower_margin = 37, + .hsync_len = 128, .vsync_len = 2, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +/* Default output mode is TFT 24 bit */ +#define BPP_OUT_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_24BPP) + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = BPP_OUT_DEFAULT_LCDCFG5, + .guard_time = 9, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static void ek_add_device_lcdc(void) +{ + at91_add_device_lcdc(&ek_lcdc_data); +} + +#else +static void ek_add_device_lcdc(void) {} +#endif + #if defined(CONFIG_MCI_ATMEL) /* * MCI (SD/MMC) @@ -333,6 +377,7 @@ static int at91sama5d3xek_devices_init(void) ek_add_device_eth(); ek_add_device_spi(); ek_add_device_mci(); + ek_add_device_lcdc(); armlinux_set_bootparams((void *)(SAMA5_DDRCS + 0x100)); diff --git a/arch/arm/configs/sama5d3xek_defconfig b/arch/arm/configs/sama5d3xek_defconfig index c94419a..970ded5 100644 --- a/arch/arm/configs/sama5d3xek_defconfig +++ b/arch/arm/configs/sama5d3xek_defconfig @@ -43,6 +43,7 @@ CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y CONFIG_CMD_MTEST=y CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -71,6 +72,8 @@ CONFIG_NAND=y CONFIG_NAND_ATMEL=y CONFIG_NAND_ATMEL_PMECC=y CONFIG_UBI=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL_HLCD=y CONFIG_MCI=y CONFIG_MCI_STARTUP=y CONFIG_MCI_ATMEL=y @@ -89,3 +92,4 @@ CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y +CONFIG_PNG=y -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-01-30 23:21 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-01-30 23:08 [PATCH 0/6] atmel: add Atmel HLCDC support and boards Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 1/6] atmel_lcdfb: factorise common code between lcdc and new hlcdc IP Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 2/6] video: add Atmel HLCD support Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 3/6] at91sam9x5: add lcd support Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 4/6] at91sam9x5ek: " Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 5/6] sama5d3: " Jean-Christophe PLAGNIOL-VILLARD 2013-01-30 23:20 ` [PATCH 6/6] sama5d3xek: " Jean-Christophe PLAGNIOL-VILLARD
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox