* [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer.
@ 2011-05-17 16:44 Alex Galakhov
2011-05-17 16:44 ` [PATCH 2/2] Enable display for MINI2440 board Alex Galakhov
2011-05-17 18:03 ` [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Sascha Hauer
0 siblings, 2 replies; 7+ messages in thread
From: Alex Galakhov @ 2011-05-17 16:44 UTC (permalink / raw)
To: barebox
Heavily based on original Juergen Beisert's code.
Signed-off-by: Alex Galakhov <agalakhov@gmail.com>
---
arch/arm/mach-s3c24xx/include/mach/fb.h | 59 ++++
drivers/video/Kconfig | 13 +
drivers/video/Makefile | 1 +
drivers/video/s3c.c | 451 +++++++++++++++++++++++++++++++
4 files changed, 524 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
create mode 100644 drivers/video/s3c.c
diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 0000000..05e013a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ * Copyright (C) 2011 Alexey Galakhov
+ *
+ * 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
+ *
+ */
+
+#ifndef __MACH_FB_H_
+# define __MACH_FB_H_
+
+#include <fb.h>
+
+/** Proprietary flags corresponding to S3C24x0 LCDCON5 register */
+
+/** ! INVVDEN - DE active high */
+#define FB_SYNC_DE_HIGH_ACT (1 << 23)
+/** INVVCLK - invert CLK signal */
+#define FB_SYNC_CLK_INVERT (1 << 24)
+/** INVVD - invert data */
+#define FB_SYNC_DATA_INVERT (1 << 25)
+/** INVPWREN - use PWREN signal */
+#define FB_SYNC_INVERT_PWREN (1 << 26)
+/** INVLEND - use LEND signal */
+#define FB_SYNC_INVERT_LEND (1 << 27)
+/** PWREN - use PWREN signal */
+#define FB_SYNC_USE_PWREN (1 << 28)
+/** ENLEND - use LEND signal */
+#define FB_SYNC_USE_LEND (1 << 29)
+/** BSWP - swap bytes */
+#define FB_SYNC_SWAP_BYTES (1 << 30)
+/** HWSWP - swap half words */
+#define FB_SYNC_SWAP_HW (1 << 31)
+
+struct s3c_fb_platform_data {
+ struct fb_videomode *mode_list;
+ unsigned mode_cnt;
+
+ unsigned bits_per_pixel;
+ int passive_display; /**< enable support for STN or CSTN displays */
+
+ /** hook to enable backlight and stuff */
+ void (*enable)(int enable);
+};
+
+#endif /* __MACH_FB_H_ */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c652622..28bcfed 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -27,4 +27,17 @@ config DRIVER_VIDEO_STM
Say 'Y' here to enable framebuffer and splash screen support for
i.MX23 and i.MX28 based systems.
+config DRIVER_VIDEO_S3C
+ bool "S3C244x framebuffer driver"
+ depends on ARCH_S3C24xx
+ help
+ Add support for the S3C244x LCD controller.
+
+if DRIVER_VIDEO_S3C
+
+config DRIVER_VIDEO_S3C_VERBOSE
+ bool "S3C244x verbose framebuffer info"
+
+endif
+
endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a217a0b..66b08d8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_VIDEO) += fb.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
+obj-$(CONFIG_DRIVER_VIDEO_S3C) += s3c.o
diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
new file mode 100644
index 0000000..ba3c3fa
--- /dev/null
+++ b/drivers/video/s3c.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ * Copyright (C) 2011 Alexey Galakhov
+ *
+ * This driver is based on a patch found in the web:
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge at openmoko.org>
+ *
+ * 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
+ *
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <init.h>
+#include <fb.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/fb.h>
+
+#define LCDCON1 0x00
+# define PNRMODE(x) (((x) & 3) << 5)
+# define BPPMODE(x) (((x) & 0xf) << 1)
+# define SET_CLKVAL(x) (((x) & 0x3ff) << 8)
+# define GET_CLKVAL(x) (((x) >> 8) & 0x3ff)
+# define ENVID (1 << 0)
+
+#define LCDCON2 0x04
+# define SET_VBPD(x) (((x) & 0xff) << 24)
+# define SET_LINEVAL(x) (((x) & 0x3ff) << 14)
+# define SET_VFPD(x) (((x) & 0xff) << 6)
+# define SET_VSPW(x) ((x) & 0x3f)
+
+#define LCDCON3 0x08
+# define SET_HBPD(x) (((x) & 0x7f) << 19)
+# define SET_HOZVAL(x) (((x) & 0x7ff) << 8)
+# define SET_HFPD(x) ((x) & 0xff)
+
+#define LCDCON4 0x0c
+# define SET_HSPW(x) ((x) & 0xff)
+
+#define LCDCON5 0x10
+# define BPP24BL (1 << 12)
+# define FRM565 (1 << 11)
+# define INV_CLK (1 << 10)
+# define INV_HS (1 << 9)
+# define INV_VS (1 << 8)
+# define INV_DTA (1 << 7)
+# define INV_DE (1 << 6)
+# define INV_PWREN (1 << 5)
+# define INV_LEND (1 << 4)
+# define ENA_PWREN (1 << 3)
+# define ENA_LEND (1 << 2)
+# define BSWP (1 << 1)
+# define HWSWP (1 << 0)
+
+#define LCDSADDR1 0x14
+# define SET_LCDBANK(x) (((x) & 0x1ff) << 21)
+# define GET_LCDBANK(x) (((x) >> 21) & 0x1ff)
+# define SET_LCDBASEU(x) ((x) & 0x1fffff)
+# define GET_LCDBASEU(x) ((x) & 0x1fffff)
+
+#define LCDSADDR2 0x18
+# define SET_LCDBASEL(x) ((x) & 0x1fffff)
+# define GET_LCDBASEL(x) ((x) & 0x1fffff)
+
+#define LCDSADDR3 0x1c
+# define SET_OFFSIZE(x) (((x) & 0x7ff) << 11)
+# define GET_OFFSIZE(x) (((x) >> 11) & 0x7ff)
+# define SET_PAGE_WIDTH(x) ((x) & 0x3ff)
+# define GET_PAGE_WIDTH(x) ((x) & 0x3ff)
+
+#define RED_LUT 0x20
+#define GREEN_LUT 0x24
+#define BLUE_LUT 0x28
+
+#define DITHMODE 0x4c
+
+#define TPAL 0x50
+
+#define LCDINTPND 0x54
+#define LCDSRCPND 0x58
+#define LCDINTMSK 0x5c
+# define FIWSEL (1 << 2)
+# define INT_FrSyn (1 << 1)
+# define INT_FiCnt (1 << 0)
+
+#define TCONSEL 0x60
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct s3cfb_info {
+ void __iomem *base;
+ unsigned memory_size;
+ struct fb_info info;
+ struct device_d *hw_dev;
+ int passive_display;
+ void (*enable)(int enable);
+};
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+ [RED] = {
+ .offset = 11,
+ .length = 5,
+ },
+ [GREEN] = {
+ .offset = 5,
+ .length = 6,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 5,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 8,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 8,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 8,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_enable_controller(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ uint32_t con1;
+
+ con1 = readl(fbi->base + LCDCON1);
+
+ con1 |= ENVID;
+
+ writel(con1, fbi->base + LCDCON1);
+
+ if (fbi->enable)
+ (fbi->enable)(1);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_disable_controller(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ uint32_t con1;
+
+ if (fbi->enable)
+ (fbi->enable)(0);
+
+ con1 = readl(fbi->base + LCDCON1);
+
+ con1 &= ~ENVID;
+
+ writel(con1, fbi->base + LCDCON1);
+}
+
+/**
+ * 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 s3cfb_activate_var(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ struct fb_videomode *mode = fb_info->mode;
+ unsigned size, hclk, div;
+ uint32_t con1, con2, con3, con4, con5 = 0;
+
+ if (fbi->passive_display != 0) {
+ pr_err("Passive displays are currently not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * we need at least this amount of memory for the framebuffer
+ */
+ size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+ if (fbi->memory_size != size || fb_info->screen_base == NULL) {
+ if (fb_info->screen_base)
+ free(fb_info->screen_base);
+ fbi->memory_size = 0;
+ fb_info->screen_base = malloc(size);
+ if (! fb_info->screen_base)
+ return -ENOMEM;
+ memset(fb_info->screen_base, 0, size);
+ fbi->memory_size = size;
+ }
+
+ /* ensure video output is _off_ */
+ writel(0x00000000, fbi->base + LCDCON1);
+
+ hclk = s3c24xx_get_hclk() / 1000U; /* hclk in kHz */
+ div = hclk / PICOS2KHZ(mode->pixclock);
+ if (div < 3)
+ div = 3;
+ /* pixel clock is: (hclk) / ((div + 1) * 2) */
+ div += 1;
+ div >>= 1;
+ div -= 1;
+
+ con1 = PNRMODE(3) | SET_CLKVAL(div); /* PNRMODE=3 is TFT */
+
+ switch (fb_info->bits_per_pixel) {
+#if 0
+ /* TODO add CLUT based modes */
+ case 1:
+ con1 |= BPPMODE(8);
+ break;
+ case 2:
+ con1 |= BPPMODE(9);
+ break;
+ case 4:
+ con1 |= BPPMODE(10);
+ break;
+ case 8:
+ con1 |= BPPMODE(11);
+ break;
+#endif
+ case 16:
+ con1 |= BPPMODE(12);
+ con5 |= FRM565;
+ con5 |= HWSWP;
+ fb_info->red = def_rgb565[RED];
+ fb_info->green = def_rgb565[GREEN];
+ fb_info->blue = def_rgb565[BLUE];
+ fb_info->transp = def_rgb565[TRANSP];
+ break;
+ case 24:
+ con1 |= BPPMODE(13);
+ /* con5 |= BPP24BL; */ /* FIXME maybe needed, check alignment */
+ fb_info->red = def_rgb888[RED];
+ fb_info->green = def_rgb888[GREEN];
+ fb_info->blue = def_rgb888[BLUE];
+ fb_info->transp = def_rgb888[TRANSP];
+ break;
+ default:
+ pr_err("Invalid bits per pixel value: %u\n", fb_info->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ /* 'normal' in register description means positive logic */
+ if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+ con5 |= INV_HS;
+ if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+ con5 |= INV_VS;
+ if (!(mode->sync & FB_SYNC_DE_HIGH_ACT))
+ con5 |= INV_DE;
+ if (mode->sync & FB_SYNC_CLK_INVERT)
+ con5 |= INV_CLK; /* display should latch at the rising edge */
+ if (mode->sync & FB_SYNC_DATA_INVERT)
+ con5 |= INV_DTA;
+ if (mode->sync & FB_SYNC_INVERT_PWREN)
+ con5 |= INV_PWREN;
+ if (mode->sync & FB_SYNC_INVERT_LEND)
+ con5 |= INV_LEND;
+ if (mode->sync & FB_SYNC_USE_PWREN)
+ con5 |= ENA_PWREN; /* FIXME should this be done conditionally/later? */
+ if (mode->sync & FB_SYNC_USE_LEND)
+ con5 |= ENA_LEND;
+ if (mode->sync & FB_SYNC_SWAP_BYTES)
+ con5 ^= BSWP;
+ if (mode->sync & FB_SYNC_SWAP_HW)
+ con5 ^= HWSWP;
+
+ /* vertical timing */
+ con2 = SET_VBPD(mode->upper_margin - 1) |
+ SET_LINEVAL(mode->yres - 1) |
+ SET_VFPD(mode->lower_margin - 1) |
+ SET_VSPW(mode->vsync_len - 1);
+
+ /* horizontal timing */
+ con3 = SET_HBPD(mode->left_margin - 1) |
+ SET_HOZVAL(mode->xres - 1) |
+ SET_HFPD(mode->right_margin - 1);
+ con4 = SET_HSPW(mode->hsync_len - 1);
+
+ /* basic timing setup */
+ writel(con1, fbi->base + LCDCON1);
+ pr_debug(" Writing %08X into %08X (con1)\n", con1, fbi->base + LCDCON1);
+ writel(con2, fbi->base + LCDCON2);
+ pr_debug(" Writing %08X into %08X (con2)\n", con2, fbi->base + LCDCON2);
+ writel(con3, fbi->base + LCDCON3);
+ pr_debug(" Writing %08X into %08X (con3)\n", con3, fbi->base + LCDCON3);
+ writel(con4, fbi->base + LCDCON4);
+ pr_debug(" Writing %08X into %08X (con4)\n", con4, fbi->base + LCDCON4);
+ writel(con5, fbi->base + LCDCON5);
+ pr_debug(" Writing %08X into %08X (con5)\n", con5, fbi->base + LCDCON5);
+
+ pr_debug("Setting up the fb baseadress to %08X\n", fb_info->screen_base);
+
+ /* framebuffer memory setup */
+ writel((unsigned)fb_info->screen_base >> 1, fbi->base + LCDSADDR1);
+ size = mode->xres * (fb_info->bits_per_pixel >> 3) * (mode->yres);
+ writel(SET_LCDBASEL(((unsigned)fb_info->screen_base + size) >> 1), fbi->base + LCDSADDR2);
+ writel(SET_OFFSIZE(0) |
+ SET_PAGE_WIDTH((mode->xres * fb_info->bits_per_pixel) >> 4),
+ fbi->base + LCDSADDR3);
+ writel(FIWSEL | INT_FrSyn | INT_FiCnt, fbi->base + LCDINTMSK);
+
+ return 0;
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev S3C video device
+ */
+#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
+static void s3cfb_info(struct device_d *hw_dev)
+{
+ uint32_t con1, addr1, addr2, addr3;
+
+ con1 = readl(hw_dev->map_base + LCDCON1);
+ addr1 = readl(hw_dev->map_base + LCDSADDR1);
+ addr2 = readl(hw_dev->map_base + LCDSADDR2);
+ addr3 = readl(hw_dev->map_base + LCDSADDR3);
+
+ printf(" Video hardware info:\n");
+ printf(" Video clock is running at %u Hz\n", s3c24xx_get_hclk() / ((GET_CLKVAL(con1) + 1) * 2));
+ printf(" Video memory bank starts at 0x%08X\n", GET_LCDBANK(addr1) << 22);
+ printf(" Video memory bank offset: 0x%08X\n", GET_LCDBASEU(addr1));
+ printf(" Video memory end: 0x%08X\n", GET_LCDBASEU(addr2));
+ printf(" Virtual screen offset size: %u half words\n", GET_OFFSIZE(addr3));
+ printf(" Virtual screen page width: %u half words\n", GET_PAGE_WIDTH(addr3));
+}
+#endif
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct fb_ops s3cfb_ops = {
+ .fb_activate_var = s3cfb_activate_var,
+ .fb_enable = s3cfb_enable_controller,
+ .fb_disable = s3cfb_disable_controller,
+};
+
+static struct s3cfb_info fbi = {
+ .info = {
+ .fbops = &s3cfb_ops,
+ },
+};
+
+static int s3cfb_probe(struct device_d *hw_dev)
+{
+ struct s3c_fb_platform_data *pdata = hw_dev->platform_data;
+ int ret;
+
+ if (! pdata)
+ return -ENODEV;
+
+ writel(0, hw_dev->map_base + LCDCON1);
+ writel(0, hw_dev->map_base + LCDCON5); /* FIXME not 0 for some displays */
+
+ /* just init */
+ fbi.info.priv = &fbi;
+
+ /* add runtime hardware info */
+ fbi.hw_dev = hw_dev;
+ fbi.base = (void*)hw_dev->map_base;
+
+ /* add runtime video info */
+ fbi.info.mode_list = pdata->mode_list;
+ fbi.info.num_modes = pdata->mode_cnt;
+ fbi.info.mode = &fbi.info.mode_list[1];
+ fbi.info.xres = fbi.info.mode->xres;
+ fbi.info.yres = fbi.info.mode->yres;
+ if (pdata->bits_per_pixel)
+ fbi.info.bits_per_pixel = pdata->bits_per_pixel;
+ else
+ fbi.info.bits_per_pixel = 16;
+ fbi.passive_display = pdata->passive_display;
+ fbi.enable = pdata->enable;
+
+ ret = register_framebuffer(&fbi.info);
+ if (ret != 0) {
+ dev_err(hw_dev, "Failed to register framebuffer\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct driver_d s3cfb_driver = {
+ .name = "s3c_fb",
+ .probe = s3cfb_probe,
+#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
+ .info = s3cfb_info,
+#endif
+};
+
+static int s3cfb_init(void)
+{
+ return register_driver(&s3cfb_driver);
+}
+
+device_initcall(s3cfb_init);
+
+/**
+ * The S3C244x LCD controller supports passive (CSTN/STN) and active (TFT) LC displays
+ *
+ * The driver itself currently supports only active TFT LC displays in the follwing manner:
+ *
+ * * Palletized colours
+ * - 1 bpp
+ * - 2 bpp
+ * - 4 bpp
+ * - 8 bpp
+ * * True colours
+ * - 16 bpp
+ * - 24 bpp
+ */
--
1.7.4.1
_______________________________________________
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/2] Enable display for MINI2440 board.
2011-05-17 16:44 [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Alex Galakhov
@ 2011-05-17 16:44 ` Alex Galakhov
2011-05-17 18:37 ` Alexey Galakhov
2011-05-18 9:40 ` [PATCH v2 " Alexey Galakhov
2011-05-17 18:03 ` [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Sascha Hauer
1 sibling, 2 replies; 7+ messages in thread
From: Alex Galakhov @ 2011-05-17 16:44 UTC (permalink / raw)
To: barebox
Also add display modes for usual MINI2440 displays.
Signed-off-by: Alex Galakhov <agalakhov@gmail.com>
---
arch/arm/boards/mini2440/Kconfig | 28 +++++++++++++
arch/arm/boards/mini2440/mini2440.c | 74 +++++++++++++++++++++++++++++++++++
arch/arm/mach-s3c24xx/Kconfig | 2 +
3 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boards/mini2440/Kconfig
diff --git a/arch/arm/boards/mini2440/Kconfig b/arch/arm/boards/mini2440/Kconfig
new file mode 100644
index 0000000..f719181
--- /dev/null
+++ b/arch/arm/boards/mini2440/Kconfig
@@ -0,0 +1,28 @@
+
+if MACH_MINI2440
+
+config MINI2440_VIDEO
+ bool
+ select VIDEO
+ select DRIVER_VIDEO_S3C
+
+config MINI2440_VIDEO_N35
+ bool "Support N35 display (240x320)"
+ select MINI2440_VIDEO
+ help
+ This adds support for NEC 3.5 inch TFT display,
+ the most common one used with MINI2440 board.
+
+config MINI2440_VIDEO_A70
+ bool "Support A70 display (800x480)"
+ select MINI2440_VIDEO
+ help
+ This adds support for Innolux 7.0 inch TFT display.
+
+config MINI2440_VIDEO_SVGA
+ bool "Support SVGA video adapter"
+ select MINI2440_VIDEO
+ help
+ This adds support for MINI2440 SVGA (1280x1024) video output adapter.
+
+endif
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index 448aa40..c96d177 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -34,6 +34,7 @@
#include <dm9000.h>
#include <nand.h>
#include <mci.h>
+#include <fb.h>
#include <asm/armlinux.h>
#include <asm/io.h>
#include <mach/gpio.h>
@@ -41,6 +42,7 @@
#include <mach/s3c24x0-nand.h>
#include <mach/s3c24xx-generic.h>
#include <mach/mci.h>
+#include <mach/fb.h>
static struct memory_platform_data ram_pdata = {
.name = "ram0",
@@ -99,6 +101,77 @@ static struct device_d mci_dev = {
.platform_data = &mci_data,
};
+static struct fb_videomode s3c24x0_fb_modes[] = {
+#ifdef CONFIG_MINI2440_VIDEO_N35
+ {
+ .name = "N35",
+ .refresh = 60,
+ .xres = 240,
+ .left_margin = 21,
+ .right_margin = 38,
+ .hsync_len = 6,
+ .yres = 320,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .vsync_len = 2,
+ .pixclock = 115913,
+ .sync = FB_SYNC_USE_PWREN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+#ifdef CONFIG_MINI2440_VIDEO_A70
+ {
+ .name = "A70",
+ .refresh = 50,
+ .xres = 800,
+ .left_margin = 40,
+ .right_margin = 40,
+ .hsync_len = 48,
+ .yres = 480,
+ .upper_margin = 29,
+ .lower_margin = 3,
+ .vsync_len = 3,
+ .pixclock = 41848,
+ .sync = FB_SYNC_USE_PWREN | FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+#ifdef CONFIG_MINI2440_VIDEO_SVGA
+ {
+ .name = "SVGA",
+ .refresh = 24,
+ .xres = 1024,
+ .left_margin = 1,
+ .right_margin = 2,
+ .hsync_len = 2,
+ .yres = 768,
+ .upper_margin = 200,
+ .lower_margin = 16,
+ .vsync_len = 16,
+ .pixclock = 40492,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT
+ /* | FB_SYNC_SWAP_HW */ /* FIXME maybe */ ,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+};
+
+static struct s3c_fb_platform_data s3c24x0_fb_data = {
+ .mode_list = s3c24x0_fb_modes,
+ .mode_cnt = sizeof(s3c24x0_fb_modes) / sizeof(struct fb_videomode),
+ .bits_per_pixel = 16,
+ .passive_display = 0,
+};
+
+static struct device_d s3cfb_dev = {
+ .name = "s3c_fb",
+ .map_base = S3C2410_LCD_BASE,
+ .platform_data = &s3c24x0_fb_data,
+};
+
static const unsigned pin_usage[] = {
/* address bus, used by NOR, SDRAM */
GPA1_ADDR16,
@@ -269,6 +342,7 @@ static int mini2440_devices_init(void)
dev_add_bb_dev("env_raw", "env0");
#endif
register_device(&mci_dev);
+ register_device(&s3cfb_dev);
armlinux_add_dram(&sdram_dev);
armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
armlinux_set_architecture(MACH_TYPE_MINI2440);
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 33d230c..80b65fb 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -67,6 +67,8 @@ config MACH_A9M2410DEV
endchoice
+source arch/arm/boards/mini2440/Kconfig
+
endmenu
menu "S3C24X0 Features "
--
1.7.4.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] Enable display for MINI2440 board.
2011-05-17 16:44 ` [PATCH 2/2] Enable display for MINI2440 board Alex Galakhov
@ 2011-05-17 18:37 ` Alexey Galakhov
2011-05-18 9:40 ` [PATCH v2 " Alexey Galakhov
1 sibling, 0 replies; 7+ messages in thread
From: Alexey Galakhov @ 2011-05-17 18:37 UTC (permalink / raw)
To: barebox
[-- Attachment #1.1: Type: text/plain, Size: 212 bytes --]
2011/5/17 Alex Galakhov <agalakhov@gmail.com>
>
> + This adds support for MINI2440 SVGA (1280x1024) video output
> adapter.
>
A typo, sorry: should be 1024x768 of course. Will fix it tomorrow.
--
Alex
[-- Attachment #1.2: Type: text/html, Size: 463 bytes --]
[-- Attachment #2: Type: text/plain, Size: 149 bytes --]
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] Enable display for MINI2440 board.
2011-05-17 16:44 ` [PATCH 2/2] Enable display for MINI2440 board Alex Galakhov
2011-05-17 18:37 ` Alexey Galakhov
@ 2011-05-18 9:40 ` Alexey Galakhov
1 sibling, 0 replies; 7+ messages in thread
From: Alexey Galakhov @ 2011-05-18 9:40 UTC (permalink / raw)
To: barebox
Also add display modes for usual MINI2440 displays.
Signed-off-by: Alexey Galakhov <agalakhov@gmail.com>
---
arch/arm/boards/mini2440/Kconfig | 28 +++++++++++++
arch/arm/boards/mini2440/mini2440.c | 74 +++++++++++++++++++++++++++++++++++
arch/arm/mach-s3c24xx/Kconfig | 2 +
3 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/boards/mini2440/Kconfig
diff --git a/arch/arm/boards/mini2440/Kconfig b/arch/arm/boards/mini2440/Kconfig
new file mode 100644
index 0000000..929df60
--- /dev/null
+++ b/arch/arm/boards/mini2440/Kconfig
@@ -0,0 +1,28 @@
+
+if MACH_MINI2440
+
+config MINI2440_VIDEO
+ bool
+ select VIDEO
+ select DRIVER_VIDEO_S3C
+
+config MINI2440_VIDEO_N35
+ bool "Support N35 display (240x320)"
+ select MINI2440_VIDEO
+ help
+ This adds support for NEC 3.5 inch TFT display,
+ the most common one used with MINI2440 board.
+
+config MINI2440_VIDEO_A70
+ bool "Support A70 display (800x480)"
+ select MINI2440_VIDEO
+ help
+ This adds support for Innolux 7.0 inch TFT display.
+
+config MINI2440_VIDEO_SVGA
+ bool "Support SVGA video adapter"
+ select MINI2440_VIDEO
+ help
+ This adds support for MINI2440 SVGA (1024x768) video output adapter.
+
+endif
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index 448aa40..c96d177 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -34,6 +34,7 @@
#include <dm9000.h>
#include <nand.h>
#include <mci.h>
+#include <fb.h>
#include <asm/armlinux.h>
#include <asm/io.h>
#include <mach/gpio.h>
@@ -41,6 +42,7 @@
#include <mach/s3c24x0-nand.h>
#include <mach/s3c24xx-generic.h>
#include <mach/mci.h>
+#include <mach/fb.h>
static struct memory_platform_data ram_pdata = {
.name = "ram0",
@@ -99,6 +101,77 @@ static struct device_d mci_dev = {
.platform_data = &mci_data,
};
+static struct fb_videomode s3c24x0_fb_modes[] = {
+#ifdef CONFIG_MINI2440_VIDEO_N35
+ {
+ .name = "N35",
+ .refresh = 60,
+ .xres = 240,
+ .left_margin = 21,
+ .right_margin = 38,
+ .hsync_len = 6,
+ .yres = 320,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .vsync_len = 2,
+ .pixclock = 115913,
+ .sync = FB_SYNC_USE_PWREN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+#ifdef CONFIG_MINI2440_VIDEO_A70
+ {
+ .name = "A70",
+ .refresh = 50,
+ .xres = 800,
+ .left_margin = 40,
+ .right_margin = 40,
+ .hsync_len = 48,
+ .yres = 480,
+ .upper_margin = 29,
+ .lower_margin = 3,
+ .vsync_len = 3,
+ .pixclock = 41848,
+ .sync = FB_SYNC_USE_PWREN | FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+#ifdef CONFIG_MINI2440_VIDEO_SVGA
+ {
+ .name = "SVGA",
+ .refresh = 24,
+ .xres = 1024,
+ .left_margin = 1,
+ .right_margin = 2,
+ .hsync_len = 2,
+ .yres = 768,
+ .upper_margin = 200,
+ .lower_margin = 16,
+ .vsync_len = 16,
+ .pixclock = 40492,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT
+ /* | FB_SYNC_SWAP_HW */ /* FIXME maybe */ ,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+#endif
+};
+
+static struct s3c_fb_platform_data s3c24x0_fb_data = {
+ .mode_list = s3c24x0_fb_modes,
+ .mode_cnt = sizeof(s3c24x0_fb_modes) / sizeof(struct fb_videomode),
+ .bits_per_pixel = 16,
+ .passive_display = 0,
+};
+
+static struct device_d s3cfb_dev = {
+ .name = "s3c_fb",
+ .map_base = S3C2410_LCD_BASE,
+ .platform_data = &s3c24x0_fb_data,
+};
+
static const unsigned pin_usage[] = {
/* address bus, used by NOR, SDRAM */
GPA1_ADDR16,
@@ -269,6 +342,7 @@ static int mini2440_devices_init(void)
dev_add_bb_dev("env_raw", "env0");
#endif
register_device(&mci_dev);
+ register_device(&s3cfb_dev);
armlinux_add_dram(&sdram_dev);
armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
armlinux_set_architecture(MACH_TYPE_MINI2440);
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 33d230c..80b65fb 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -67,6 +67,8 @@ config MACH_A9M2410DEV
endchoice
+source arch/arm/boards/mini2440/Kconfig
+
endmenu
menu "S3C24X0 Features "
--
1.7.4.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer.
2011-05-17 16:44 [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Alex Galakhov
2011-05-17 16:44 ` [PATCH 2/2] Enable display for MINI2440 board Alex Galakhov
@ 2011-05-17 18:03 ` Sascha Hauer
2011-05-18 8:12 ` Juergen Beisert
1 sibling, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2011-05-17 18:03 UTC (permalink / raw)
To: Alex Galakhov; +Cc: barebox
Hi Alex,
On Tue, May 17, 2011 at 10:44:00PM +0600, Alex Galakhov wrote:
> Heavily based on original Juergen Beisert's code.
>
> Signed-off-by: Alex Galakhov <agalakhov@gmail.com>
> ---
> arch/arm/mach-s3c24xx/include/mach/fb.h | 59 ++++
> drivers/video/Kconfig | 13 +
> drivers/video/Makefile | 1 +
> drivers/video/s3c.c | 451 +++++++++++++++++++++++++++++++
> 4 files changed, 524 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
> create mode 100644 drivers/video/s3c.c
The patch looks mostly fine, only small nitpicks follow.
>
> diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
> new file mode 100644
> index 0000000..05e013a
> --- /dev/null
> +++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
> +
> +/**
> + * @param fb_info Framebuffer information
> + */
> +static void s3cfb_enable_controller(struct fb_info *fb_info)
> +{
> + struct s3cfb_info *fbi = fb_info->priv;
> + uint32_t con1;
> +
> + con1 = readl(fbi->base + LCDCON1);
> +
> + con1 |= ENVID;
> +
> + writel(con1, fbi->base + LCDCON1);
> +
> + if (fbi->enable)
> + (fbi->enable)(1);
unneeded brackets.
> +}
> +
> +/**
> + * @param fb_info Framebuffer information
> + */
> +static void s3cfb_disable_controller(struct fb_info *fb_info)
> +{
> + struct s3cfb_info *fbi = fb_info->priv;
> + uint32_t con1;
> +
> + if (fbi->enable)
> + (fbi->enable)(0);
ditto
> +
> + con1 = readl(fbi->base + LCDCON1);
> +
> + con1 &= ~ENVID;
> +
> + writel(con1, fbi->base + LCDCON1);
> +}
> +
> +/**
> + * 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 s3cfb_activate_var(struct fb_info *fb_info)
> +{
> + struct s3cfb_info *fbi = fb_info->priv;
> + struct fb_videomode *mode = fb_info->mode;
> + unsigned size, hclk, div;
> + uint32_t con1, con2, con3, con4, con5 = 0;
> +
> + if (fbi->passive_display != 0) {
> + pr_err("Passive displays are currently not supported\n");
dev_err please (some more follow).
> +
> + switch (fb_info->bits_per_pixel) {
> +#if 0
> + /* TODO add CLUT based modes */
> + case 1:
> + con1 |= BPPMODE(8);
> + break;
> + case 2:
> + con1 |= BPPMODE(9);
> + break;
> + case 4:
> + con1 |= BPPMODE(10);
> + break;
> + case 8:
> + con1 |= BPPMODE(11);
> + break;
> +#endif
I think we can remove this dead code. I see no reason to add clut
support. If someone needs it, I think this missing snippet is the least
of his problems.
> +
> +/**
> + * The S3C244x LCD controller supports passive (CSTN/STN) and active (TFT) LC displays
> + *
> + * The driver itself currently supports only active TFT LC displays in the follwing manner:
> + *
> + * * Palletized colours
> + * - 1 bpp
> + * - 2 bpp
> + * - 4 bpp
> + * - 8 bpp
This doesn't seem to be true, right?
> + * * True colours
> + * - 16 bpp
> + * - 24 bpp
> + */
> --
> 1.7.4.1
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer.
2011-05-17 18:03 ` [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Sascha Hauer
@ 2011-05-18 8:12 ` Juergen Beisert
2011-05-18 9:39 ` [PATCH v2 " Alexey Galakhov
0 siblings, 1 reply; 7+ messages in thread
From: Juergen Beisert @ 2011-05-18 8:12 UTC (permalink / raw)
To: barebox
Sascha Hauer wrote:
> Hi Alex,
>
> On Tue, May 17, 2011 at 10:44:00PM +0600, Alex Galakhov wrote:
> > Heavily based on original Juergen Beisert's code.
> >
> > Signed-off-by: Alex Galakhov <agalakhov@gmail.com>
> > ---
> > arch/arm/mach-s3c24xx/include/mach/fb.h | 59 ++++
> > drivers/video/Kconfig | 13 +
> > drivers/video/Makefile | 1 +
> > drivers/video/s3c.c | 451
> > +++++++++++++++++++++++++++++++ 4 files changed, 524 insertions(+), 0
> > deletions(-)
> > create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
> > create mode 100644 drivers/video/s3c.c
>
> The patch looks mostly fine, only small nitpicks follow.
>
> > diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h
> > b/arch/arm/mach-s3c24xx/include/mach/fb.h new file mode 100644
> > index 0000000..05e013a
> > --- /dev/null
> > +++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
> > +
> > +/**
> > + * @param fb_info Framebuffer information
> > + */
> > +static void s3cfb_enable_controller(struct fb_info *fb_info)
> > +{
> > + struct s3cfb_info *fbi = fb_info->priv;
> > + uint32_t con1;
> > +
> > + con1 = readl(fbi->base + LCDCON1);
> > +
> > + con1 |= ENVID;
> > +
> > + writel(con1, fbi->base + LCDCON1);
> > +
> > + if (fbi->enable)
> > + (fbi->enable)(1);
>
> unneeded brackets.
Seem my old code.
> > +}
> > +
> > +/**
> > + * @param fb_info Framebuffer information
> > + */
> > +static void s3cfb_disable_controller(struct fb_info *fb_info)
> > +{
> > + struct s3cfb_info *fbi = fb_info->priv;
> > + uint32_t con1;
> > +
> > + if (fbi->enable)
> > + (fbi->enable)(0);
>
> ditto
>
> > +
> > + con1 = readl(fbi->base + LCDCON1);
> > +
> > + con1 &= ~ENVID;
> > +
> > + writel(con1, fbi->base + LCDCON1);
> > +}
> > +
> > +/**
> > + * 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 s3cfb_activate_var(struct fb_info *fb_info)
> > +{
> > + struct s3cfb_info *fbi = fb_info->priv;
> > + struct fb_videomode *mode = fb_info->mode;
> > + unsigned size, hclk, div;
> > + uint32_t con1, con2, con3, con4, con5 = 0;
> > +
> > + if (fbi->passive_display != 0) {
> > + pr_err("Passive displays are currently not supported\n");
>
> dev_err please (some more follow).
>
> > +
> > + switch (fb_info->bits_per_pixel) {
> > +#if 0
> > + /* TODO add CLUT based modes */
> > + case 1:
> > + con1 |= BPPMODE(8);
> > + break;
> > + case 2:
> > + con1 |= BPPMODE(9);
> > + break;
> > + case 4:
> > + con1 |= BPPMODE(10);
> > + break;
> > + case 8:
> > + con1 |= BPPMODE(11);
> > + break;
> > +#endif
>
> I think we can remove this dead code. I see no reason to add clut
> support. If someone needs it, I think this missing snippet is the least
> of his problems.
>
> > +
> > +/**
> > + * The S3C244x LCD controller supports passive (CSTN/STN) and active
> > (TFT) LC displays + *
> > + * The driver itself currently supports only active TFT LC displays in
> > the follwing manner: + *
> > + * * Palletized colours
> > + * - 1 bpp
> > + * - 2 bpp
> > + * - 4 bpp
> > + * - 8 bpp
>
> This doesn't seem to be true, right?
>
> > + * * True colours
> > + * - 16 bpp
> > + * - 24 bpp
> > + */
Its unfinished out of date. Alex should update or remove it.
jbe
--
Pengutronix e.K. | Juergen Beisert |
Linux Solutions for Science and Industry | Phone: +49-5121-206917-5128 |
Vertretung Sued/Muenchen, Germany | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de/ |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] Add support for Samsung S3C24x0 framebuffer.
2011-05-18 8:12 ` Juergen Beisert
@ 2011-05-18 9:39 ` Alexey Galakhov
0 siblings, 0 replies; 7+ messages in thread
From: Alexey Galakhov @ 2011-05-18 9:39 UTC (permalink / raw)
To: barebox
Heavily based on original Juergen Beisert's code.
Signed-off-by: Alexey Galakhov <agalakhov@gmail.com>
---
arch/arm/mach-s3c24xx/include/mach/fb.h | 59 +++++
drivers/video/Kconfig | 13 +
drivers/video/Makefile | 1 +
drivers/video/s3c.c | 429 +++++++++++++++++++++++++++++++
4 files changed, 502 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h
create mode 100644 drivers/video/s3c.c
diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 0000000..05e013a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ * Copyright (C) 2011 Alexey Galakhov
+ *
+ * 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
+ *
+ */
+
+#ifndef __MACH_FB_H_
+# define __MACH_FB_H_
+
+#include <fb.h>
+
+/** Proprietary flags corresponding to S3C24x0 LCDCON5 register */
+
+/** ! INVVDEN - DE active high */
+#define FB_SYNC_DE_HIGH_ACT (1 << 23)
+/** INVVCLK - invert CLK signal */
+#define FB_SYNC_CLK_INVERT (1 << 24)
+/** INVVD - invert data */
+#define FB_SYNC_DATA_INVERT (1 << 25)
+/** INVPWREN - use PWREN signal */
+#define FB_SYNC_INVERT_PWREN (1 << 26)
+/** INVLEND - use LEND signal */
+#define FB_SYNC_INVERT_LEND (1 << 27)
+/** PWREN - use PWREN signal */
+#define FB_SYNC_USE_PWREN (1 << 28)
+/** ENLEND - use LEND signal */
+#define FB_SYNC_USE_LEND (1 << 29)
+/** BSWP - swap bytes */
+#define FB_SYNC_SWAP_BYTES (1 << 30)
+/** HWSWP - swap half words */
+#define FB_SYNC_SWAP_HW (1 << 31)
+
+struct s3c_fb_platform_data {
+ struct fb_videomode *mode_list;
+ unsigned mode_cnt;
+
+ unsigned bits_per_pixel;
+ int passive_display; /**< enable support for STN or CSTN displays */
+
+ /** hook to enable backlight and stuff */
+ void (*enable)(int enable);
+};
+
+#endif /* __MACH_FB_H_ */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c652622..28bcfed 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -27,4 +27,17 @@ config DRIVER_VIDEO_STM
Say 'Y' here to enable framebuffer and splash screen support for
i.MX23 and i.MX28 based systems.
+config DRIVER_VIDEO_S3C
+ bool "S3C244x framebuffer driver"
+ depends on ARCH_S3C24xx
+ help
+ Add support for the S3C244x LCD controller.
+
+if DRIVER_VIDEO_S3C
+
+config DRIVER_VIDEO_S3C_VERBOSE
+ bool "S3C244x verbose framebuffer info"
+
+endif
+
endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a217a0b..66b08d8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_VIDEO) += fb.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
+obj-$(CONFIG_DRIVER_VIDEO_S3C) += s3c.o
diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
new file mode 100644
index 0000000..3715499
--- /dev/null
+++ b/drivers/video/s3c.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert
+ * Copyright (C) 2011 Alexey Galakhov
+ *
+ * This driver is based on a patch found in the web:
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge at openmoko.org>
+ *
+ * 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 <init.h>
+#include <fb.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+#include <mach/s3c24xx-generic.h>
+#include <mach/fb.h>
+
+#define LCDCON1 0x00
+# define PNRMODE(x) (((x) & 3) << 5)
+# define BPPMODE(x) (((x) & 0xf) << 1)
+# define SET_CLKVAL(x) (((x) & 0x3ff) << 8)
+# define GET_CLKVAL(x) (((x) >> 8) & 0x3ff)
+# define ENVID (1 << 0)
+
+#define LCDCON2 0x04
+# define SET_VBPD(x) (((x) & 0xff) << 24)
+# define SET_LINEVAL(x) (((x) & 0x3ff) << 14)
+# define SET_VFPD(x) (((x) & 0xff) << 6)
+# define SET_VSPW(x) ((x) & 0x3f)
+
+#define LCDCON3 0x08
+# define SET_HBPD(x) (((x) & 0x7f) << 19)
+# define SET_HOZVAL(x) (((x) & 0x7ff) << 8)
+# define SET_HFPD(x) ((x) & 0xff)
+
+#define LCDCON4 0x0c
+# define SET_HSPW(x) ((x) & 0xff)
+
+#define LCDCON5 0x10
+# define BPP24BL (1 << 12)
+# define FRM565 (1 << 11)
+# define INV_CLK (1 << 10)
+# define INV_HS (1 << 9)
+# define INV_VS (1 << 8)
+# define INV_DTA (1 << 7)
+# define INV_DE (1 << 6)
+# define INV_PWREN (1 << 5)
+# define INV_LEND (1 << 4)
+# define ENA_PWREN (1 << 3)
+# define ENA_LEND (1 << 2)
+# define BSWP (1 << 1)
+# define HWSWP (1 << 0)
+
+#define LCDSADDR1 0x14
+# define SET_LCDBANK(x) (((x) & 0x1ff) << 21)
+# define GET_LCDBANK(x) (((x) >> 21) & 0x1ff)
+# define SET_LCDBASEU(x) ((x) & 0x1fffff)
+# define GET_LCDBASEU(x) ((x) & 0x1fffff)
+
+#define LCDSADDR2 0x18
+# define SET_LCDBASEL(x) ((x) & 0x1fffff)
+# define GET_LCDBASEL(x) ((x) & 0x1fffff)
+
+#define LCDSADDR3 0x1c
+# define SET_OFFSIZE(x) (((x) & 0x7ff) << 11)
+# define GET_OFFSIZE(x) (((x) >> 11) & 0x7ff)
+# define SET_PAGE_WIDTH(x) ((x) & 0x3ff)
+# define GET_PAGE_WIDTH(x) ((x) & 0x3ff)
+
+#define RED_LUT 0x20
+#define GREEN_LUT 0x24
+#define BLUE_LUT 0x28
+
+#define DITHMODE 0x4c
+
+#define TPAL 0x50
+
+#define LCDINTPND 0x54
+#define LCDSRCPND 0x58
+#define LCDINTMSK 0x5c
+# define FIWSEL (1 << 2)
+# define INT_FrSyn (1 << 1)
+# define INT_FiCnt (1 << 0)
+
+#define TCONSEL 0x60
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct s3cfb_info {
+ void __iomem *base;
+ unsigned memory_size;
+ struct fb_info info;
+ struct device_d *hw_dev;
+ int passive_display;
+ void (*enable)(int enable);
+};
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+ [RED] = {
+ .offset = 11,
+ .length = 5,
+ },
+ [GREEN] = {
+ .offset = 5,
+ .length = 6,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 5,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 8,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 8,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 8,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_enable_controller(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ uint32_t con1;
+
+ con1 = readl(fbi->base + LCDCON1);
+
+ con1 |= ENVID;
+
+ writel(con1, fbi->base + LCDCON1);
+
+ if (fbi->enable)
+ fbi->enable(1);
+}
+
+/**
+ * @param fb_info Framebuffer information
+ */
+static void s3cfb_disable_controller(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ uint32_t con1;
+
+ if (fbi->enable)
+ fbi->enable(0);
+
+ con1 = readl(fbi->base + LCDCON1);
+
+ con1 &= ~ENVID;
+
+ writel(con1, fbi->base + LCDCON1);
+}
+
+/**
+ * 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 s3cfb_activate_var(struct fb_info *fb_info)
+{
+ struct s3cfb_info *fbi = fb_info->priv;
+ struct fb_videomode *mode = fb_info->mode;
+ unsigned size, hclk, div;
+ uint32_t con1, con2, con3, con4, con5 = 0;
+
+ if (fbi->passive_display != 0) {
+ dev_err(fbi->hw_dev, "Passive displays are currently not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * we need at least this amount of memory for the framebuffer
+ */
+ size = mode->xres * mode->yres * (fb_info->bits_per_pixel >> 3);
+ if (fbi->memory_size != size || fb_info->screen_base == NULL) {
+ if (fb_info->screen_base)
+ free(fb_info->screen_base);
+ fbi->memory_size = 0;
+ fb_info->screen_base = malloc(size);
+ if (! fb_info->screen_base)
+ return -ENOMEM;
+ memset(fb_info->screen_base, 0, size);
+ fbi->memory_size = size;
+ }
+
+ /* ensure video output is _off_ */
+ writel(0x00000000, fbi->base + LCDCON1);
+
+ hclk = s3c24xx_get_hclk() / 1000U; /* hclk in kHz */
+ div = hclk / PICOS2KHZ(mode->pixclock);
+ if (div < 3)
+ div = 3;
+ /* pixel clock is: (hclk) / ((div + 1) * 2) */
+ div += 1;
+ div >>= 1;
+ div -= 1;
+
+ con1 = PNRMODE(3) | SET_CLKVAL(div); /* PNRMODE=3 is TFT */
+
+ switch (fb_info->bits_per_pixel) {
+ case 16:
+ con1 |= BPPMODE(12);
+ con5 |= FRM565;
+ con5 |= HWSWP;
+ fb_info->red = def_rgb565[RED];
+ fb_info->green = def_rgb565[GREEN];
+ fb_info->blue = def_rgb565[BLUE];
+ fb_info->transp = def_rgb565[TRANSP];
+ break;
+ case 24:
+ con1 |= BPPMODE(13);
+ /* con5 |= BPP24BL; */ /* FIXME maybe needed, check alignment */
+ fb_info->red = def_rgb888[RED];
+ fb_info->green = def_rgb888[GREEN];
+ fb_info->blue = def_rgb888[BLUE];
+ fb_info->transp = def_rgb888[TRANSP];
+ break;
+ default:
+ dev_err(fbi->hw_dev, "Invalid bits per pixel value: %u\n", fb_info->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ /* 'normal' in register description means positive logic */
+ if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
+ con5 |= INV_HS;
+ if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
+ con5 |= INV_VS;
+ if (!(mode->sync & FB_SYNC_DE_HIGH_ACT))
+ con5 |= INV_DE;
+ if (mode->sync & FB_SYNC_CLK_INVERT)
+ con5 |= INV_CLK; /* display should latch at the rising edge */
+ if (mode->sync & FB_SYNC_DATA_INVERT)
+ con5 |= INV_DTA;
+ if (mode->sync & FB_SYNC_INVERT_PWREN)
+ con5 |= INV_PWREN;
+ if (mode->sync & FB_SYNC_INVERT_LEND)
+ con5 |= INV_LEND;
+ if (mode->sync & FB_SYNC_USE_PWREN)
+ con5 |= ENA_PWREN; /* FIXME should this be done conditionally/later? */
+ if (mode->sync & FB_SYNC_USE_LEND)
+ con5 |= ENA_LEND;
+ if (mode->sync & FB_SYNC_SWAP_BYTES)
+ con5 ^= BSWP;
+ if (mode->sync & FB_SYNC_SWAP_HW)
+ con5 ^= HWSWP;
+
+ /* vertical timing */
+ con2 = SET_VBPD(mode->upper_margin - 1) |
+ SET_LINEVAL(mode->yres - 1) |
+ SET_VFPD(mode->lower_margin - 1) |
+ SET_VSPW(mode->vsync_len - 1);
+
+ /* horizontal timing */
+ con3 = SET_HBPD(mode->left_margin - 1) |
+ SET_HOZVAL(mode->xres - 1) |
+ SET_HFPD(mode->right_margin - 1);
+ con4 = SET_HSPW(mode->hsync_len - 1);
+
+ /* basic timing setup */
+ writel(con1, fbi->base + LCDCON1);
+ dev_dbg(fbi->hw_dev, "writing %08X into %p (con1)\n", con1, fbi->base + LCDCON1);
+ writel(con2, fbi->base + LCDCON2);
+ dev_dbg(fbi->hw_dev, "writing %08X into %p (con2)\n", con2, fbi->base + LCDCON2);
+ writel(con3, fbi->base + LCDCON3);
+ dev_dbg(fbi->hw_dev, "writing %08X into %p (con3)\n", con3, fbi->base + LCDCON3);
+ writel(con4, fbi->base + LCDCON4);
+ dev_dbg(fbi->hw_dev, "writing %08X into %p (con4)\n", con4, fbi->base + LCDCON4);
+ writel(con5, fbi->base + LCDCON5);
+ dev_dbg(fbi->hw_dev, "writing %08X into %p (con5)\n", con5, fbi->base + LCDCON5);
+
+ dev_dbg(fbi->hw_dev, "setting up the fb baseadress to %p\n", fb_info->screen_base);
+
+ /* framebuffer memory setup */
+ writel((unsigned)fb_info->screen_base >> 1, fbi->base + LCDSADDR1);
+ size = mode->xres * (fb_info->bits_per_pixel >> 3) * (mode->yres);
+ writel(SET_LCDBASEL(((unsigned)fb_info->screen_base + size) >> 1), fbi->base + LCDSADDR2);
+ writel(SET_OFFSIZE(0) |
+ SET_PAGE_WIDTH((mode->xres * fb_info->bits_per_pixel) >> 4),
+ fbi->base + LCDSADDR3);
+ writel(FIWSEL | INT_FrSyn | INT_FiCnt, fbi->base + LCDINTMSK);
+
+ return 0;
+}
+
+/**
+ * Print some information about the current hardware state
+ * @param hw_dev S3C video device
+ */
+#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
+static void s3cfb_info(struct device_d *hw_dev)
+{
+ uint32_t con1, addr1, addr2, addr3;
+
+ con1 = readl(hw_dev->map_base + LCDCON1);
+ addr1 = readl(hw_dev->map_base + LCDSADDR1);
+ addr2 = readl(hw_dev->map_base + LCDSADDR2);
+ addr3 = readl(hw_dev->map_base + LCDSADDR3);
+
+ printf(" Video hardware info:\n");
+ printf(" Video clock is running at %u Hz\n", s3c24xx_get_hclk() / ((GET_CLKVAL(con1) + 1) * 2));
+ printf(" Video memory bank starts at 0x%08X\n", GET_LCDBANK(addr1) << 22);
+ printf(" Video memory bank offset: 0x%08X\n", GET_LCDBASEU(addr1));
+ printf(" Video memory end: 0x%08X\n", GET_LCDBASEU(addr2));
+ printf(" Virtual screen offset size: %u half words\n", GET_OFFSIZE(addr3));
+ printf(" Virtual screen page width: %u half words\n", GET_PAGE_WIDTH(addr3));
+}
+#endif
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct fb_ops s3cfb_ops = {
+ .fb_activate_var = s3cfb_activate_var,
+ .fb_enable = s3cfb_enable_controller,
+ .fb_disable = s3cfb_disable_controller,
+};
+
+static struct s3cfb_info fbi = {
+ .info = {
+ .fbops = &s3cfb_ops,
+ },
+};
+
+static int s3cfb_probe(struct device_d *hw_dev)
+{
+ struct s3c_fb_platform_data *pdata = hw_dev->platform_data;
+ int ret;
+
+ if (! pdata)
+ return -ENODEV;
+
+ writel(0, hw_dev->map_base + LCDCON1);
+ writel(0, hw_dev->map_base + LCDCON5); /* FIXME not 0 for some displays */
+
+ /* just init */
+ fbi.info.priv = &fbi;
+
+ /* add runtime hardware info */
+ fbi.hw_dev = hw_dev;
+ fbi.base = (void*)hw_dev->map_base;
+
+ /* add runtime video info */
+ fbi.info.mode_list = pdata->mode_list;
+ fbi.info.num_modes = pdata->mode_cnt;
+ fbi.info.mode = &fbi.info.mode_list[1];
+ fbi.info.xres = fbi.info.mode->xres;
+ fbi.info.yres = fbi.info.mode->yres;
+ if (pdata->bits_per_pixel)
+ fbi.info.bits_per_pixel = pdata->bits_per_pixel;
+ else
+ fbi.info.bits_per_pixel = 16;
+ fbi.passive_display = pdata->passive_display;
+ fbi.enable = pdata->enable;
+
+ ret = register_framebuffer(&fbi.info);
+ if (ret != 0) {
+ dev_err(hw_dev, "Failed to register framebuffer\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct driver_d s3cfb_driver = {
+ .name = "s3c_fb",
+ .probe = s3cfb_probe,
+#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
+ .info = s3cfb_info,
+#endif
+};
+
+static int s3cfb_init(void)
+{
+ return register_driver(&s3cfb_driver);
+}
+
+device_initcall(s3cfb_init);
+
+/**
+ * The S3C244x LCD controller supports passive (CSTN/STN) and active (TFT) LC displays
+ *
+ * The driver itself currently supports only active TFT LC displays in the follwing manner:
+ *
+ * * True colours
+ * - 16 bpp
+ * - 24 bpp (untested)
+ */
--
1.7.4.1
_______________________________________________
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:[~2011-05-18 9:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-17 16:44 [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Alex Galakhov
2011-05-17 16:44 ` [PATCH 2/2] Enable display for MINI2440 board Alex Galakhov
2011-05-17 18:37 ` Alexey Galakhov
2011-05-18 9:40 ` [PATCH v2 " Alexey Galakhov
2011-05-17 18:03 ` [PATCH 1/2] Add support for Samsung S3C24x0 framebuffer Sascha Hauer
2011-05-18 8:12 ` Juergen Beisert
2011-05-18 9:39 ` [PATCH v2 " Alexey Galakhov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox