* [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