* [PATCH 1/2] ep93xx framebuffer driver
@ 2009-07-17 3:46 Ryan Mallon
2009-07-17 3:57 ` Ryan Mallon
0 siblings, 1 reply; 5+ messages in thread
From: Ryan Mallon @ 2009-07-17 3:46 UTC (permalink / raw)
To: arm kernel, linux-fbdev-devel, hartleys, Daniele Venzano
EP93xx framebuffer driver
Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
---
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 55022f3..bda367f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2114,6 +2114,17 @@ config FB_MB862XX_LIME
---help---
Framebuffer support for Fujitsu Lime GDC on host CPU bus.
+config FB_EP93XX
+ tristate "EP93XX frame buffer support"
+ depends on FB && ARCH_EP93XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for the Cirrus Logic EP93XX series of processors.
+ This driver is also available as a module. The module will be called
+ ep93xxfb.
+
config FB_PRE_INIT_FB
bool "Don't reinitialize, use bootloader's GDC/Display configuration"
depends on FB_MB862XX_LIME
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 01a819f..6d6fdf3 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -126,6 +126,7 @@ obj-$(CONFIG_FB_OMAP) += omap/
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
+obj-$(CONFIG_FB_EP93XX) += ep93xx_fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o
diff --git a/drivers/video/ep93xx_fb.c b/drivers/video/ep93xx_fb.c
new file mode 100644
index 0000000..129ba4b
--- /dev/null
+++ b/drivers/video/ep93xx_fb.c
@@ -0,0 +1,646 @@
+/*
+ * linux/drivers/video/ep93xx_fb.c
+ *
+ * Framebuffer support for the EP93xx series.
+ *
+ * Copyright (C) 2007 Bluewater Systems
+ * Author: Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * Copyright (c) 2009 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * Based on the Cirrus Logic ep93xxfb driver, and various other ep93xxfb
+ * drivers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/fb.h>
+
+#include <mach/fb.h>
+
+/* Vertical Frame Timing Registers */
+#define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */
+#define EP93XXFB_VSYNC 0x0004 /* SW locked */
+#define EP93XXFB_VACTIVE 0x0008 /* SW locked */
+#define EP93XXFB_VBLANK 0x0228 /* SW locked */
+#define EP93XXFB_VCLK 0x000c /* SW locked */
+
+/* Horizontal Frame Timing Registers */
+#define EP93XXFB_HCLKS_TOTAL 0x0010 /* SW locked */
+#define EP93XXFB_HSYNC 0x0014 /* SW locked */
+#define EP93XXFB_HACTIVE 0x0018 /* SW locked */
+#define EP93XXFB_HBLANK 0x022c /* SW locked */
+#define EP93XXFB_HCLK 0x001c /* SW locked */
+
+/* Frame Buffer Memory Configuration Registers */
+#define EP93XXFB_SCREEN_PAGE 0x0028
+#define EP93XXFB_SCREEN_HPAGE 0x002c
+#define EP93XXFB_SCREEN_LINES 0x0030
+#define EP93XXFB_LINE_LENGTH 0x0034
+#define EP93XXFB_VLINE_STEP 0x0038
+#define EP93XXFB_LINE_CARRY 0x003c /* SW locked */
+#define EP93XXFB_EOL_OFFSET 0x0230
+
+/* Other Video Registers */
+#define EP93XXFB_BRIGHTNESS 0x0020
+#define EP93XXFB_ATTRIBS 0x0024 /* SW locked */
+#define EP93XXFB_SWLOCK 0x007c /* SW locked */
+#define EP93XXFB_AC_RATE 0x0214
+#define EP93XXFB_FIFO_LEVEL 0x0234
+#define EP93XXFB_PIXELMODE 0x0054
+#define EP93XXFB_PIXELMODE_32BPP (0x7 << 0)
+#define EP93XXFB_PIXELMODE_24BPP (0x6 << 0)
+#define EP93XXFB_PIXELMODE_16BPP (0x4 << 0)
+#define EP93XXFB_PIXELMODE_8BPP (0x2 << 0)
+#define EP93XXFB_PIXELMODE_SHIFT_1P_24B (0x0 << 3)
+#define EP93XXFB_PIXELMODE_SHIFT_1P_18B (0x1 << 3)
+#define EP93XXFB_PIXELMODE_COLOR_LUT (0x0 << 10)
+#define EP93XXFB_PIXELMODE_COLOR_888 (0x4 << 10)
+#define EP93XXFB_PIXELMODE_COLOR_555 (0x5 << 10)
+#define EP93XXFB_PARL_IF_OUT 0x0058
+#define EP93XXFB_PARL_IF_IN 0x005c
+
+/* Blink Control Registers */
+#define EP93XXFB_BLINK_RATE 0x0040
+#define EP93XXFB_BLINK_MASK 0x0044
+#define EP93XXFB_BLINK_PATTRN 0x0048
+#define EP93XXFB_PATTRN_MASK 0x004c
+#define EP93XXFB_BKGRND_OFFSET 0x0050
+
+/* Hardware Cursor Registers */
+#define EP93XXFB_CURSOR_ADR_START 0x0060
+#define EP93XXFB_CURSOR_ADR_RESET 0x0064
+#define EP93XXFB_CURSOR_SIZE 0x0068
+#define EP93XXFB_CURSOR_COLOR1 0x006c
+#define EP93XXFB_CURSOR_COLOR2 0x0070
+#define EP93XXFB_CURSOR_BLINK_COLOR1 0x021c
+#define EP93XXFB_CURSOR_BLINK_COLOR2 0x0220
+#define EP93XXFB_CURSOR_XY_LOC 0x0074
+#define EP93XXFB_CURSOR_DSCAN_HY_LOC 0x0078
+#define EP93XXFB_CURSOR_BLINK_RATE_CTRL 0x0224
+
+/* LUT Registers */
+#define EP93XXFB_GRY_SCL_LUTR 0x0080
+#define EP93XXFB_GRY_SCL_LUTG 0x0280
+#define EP93XXFB_GRY_SCL_LUTB 0x0300
+#define EP93XXFB_LUT_SW_CONTROL 0x0218
+#define EP93XXFB_LUT_SW_CONTROL_SWTCH (1 << 0)
+#define EP93XXFB_LUT_SW_CONTROL_SSTAT (1 << 1)
+#define EP93XXFB_COLOR_LUT 0x0400
+
+/* Video Signature Registers */
+#define EP93XXFB_VID_SIG_RSLT_VAL 0x0200
+#define EP93XXFB_VID_SIG_CTRL 0x0204
+#define EP93XXFB_VSIG 0x0208
+#define EP93XXFB_HSIG 0x020c
+#define EP93XXFB_SIG_CLR_STR 0x0210
+
+/* Minimum / Maximum resolutions supported */
+#define EP93XXFB_MIN_XRES 64
+#define EP93XXFB_MIN_YRES 64
+#define EP93XXFB_MAX_XRES 1024
+#define EP93XXFB_MAX_YRES 768
+
+struct ep93xx_fbi {
+ struct ep93xxfb_mach_info *mach_info;
+ struct clk *clk;
+ struct resource *res;
+ void __iomem *mmio_base;
+ unsigned int pseudo_palette[256];
+};
+
+static int check_screenpage_bug = 1;
+module_param(check_screenpage_bug, int, 0644);
+MODULE_PARM_DESC(check_screenpage_bug,
+ "Check for bit 27 screen page bug. Default = 1");
+
+static inline unsigned int ep93xxfb_readl(struct ep93xx_fbi *fbi,
+ unsigned int off)
+{
+ return __raw_readl(fbi->mmio_base + off);
+}
+
+static inline void ep93xxfb_writel(struct ep93xx_fbi *fbi, unsigned int val,
+ unsigned int off)
+{
+ __raw_writel(val, fbi->mmio_base + off);
+}
+
+/*
+ * Write to one of the locked raster registers.
+ */
+static inline void ep93xxfb_out_locked(struct ep93xx_fbi *fbi,
+ unsigned int val, unsigned int reg)
+{
+ /*
+ * We don't need a lock or delay here since the raster register
+ * block will remain unlocked until the next access.
+ */
+ ep93xxfb_writel(fbi, 0xaa, EP93XXFB_SWLOCK);
+ ep93xxfb_writel(fbi, val, reg);
+}
+
+static void ep93xxfb_set_video_attribs(struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ unsigned int attribs;
+
+ attribs = EP93XXFB_ENABLE;
+ attribs |= fbi->mach_info->flags;
+ ep93xxfb_out_locked(fbi, attribs, EP93XXFB_ATTRIBS);
+}
+
+static int ep93xxfb_set_pixelmode(struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ unsigned int val;
+
+ info->var.transp.offset = 0;
+ info->var.transp.length = 0;
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ val = EP93XXFB_PIXELMODE_8BPP | EP93XXFB_PIXELMODE_COLOR_LUT |
+ EP93XXFB_PIXELMODE_SHIFT_1P_18B;
+
+ info->var.red.offset = 0;
+ info->var.red.length = 8;
+ info->var.green.offset = 0;
+ info->var.green.length = 8;
+ info->var.blue.offset = 0;
+ info->var.blue.length = 8;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+
+ case 16:
+ val = EP93XXFB_PIXELMODE_16BPP | EP93XXFB_PIXELMODE_COLOR_555 |
+ EP93XXFB_PIXELMODE_SHIFT_1P_18B;
+
+ info->var.red.offset = 11;
+ info->var.red.length = 5;
+ info->var.green.offset = 5;
+ info->var.green.length = 6;
+ info->var.blue.offset = 0;
+ info->var.blue.length = 5;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+
+ case 24:
+ val = EP93XXFB_PIXELMODE_24BPP | EP93XXFB_PIXELMODE_COLOR_888 |
+ EP93XXFB_PIXELMODE_SHIFT_1P_24B;
+
+ info->var.red.offset = 16;
+ info->var.red.length = 8;
+ info->var.green.offset = 8;
+ info->var.green.length = 8;
+ info->var.blue.offset = 0;
+ info->var.blue.length = 8;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+
+ case 32:
+ val = EP93XXFB_PIXELMODE_32BPP | EP93XXFB_PIXELMODE_COLOR_888 |
+ EP93XXFB_PIXELMODE_SHIFT_1P_24B;
+
+ info->var.red.offset = 16;
+ info->var.red.length = 8;
+ info->var.green.offset = 8;
+ info->var.green.length = 8;
+ info->var.blue.offset = 0;
+ info->var.blue.length = 8;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ ep93xxfb_writel(fbi, val, EP93XXFB_PIXELMODE);
+ return 0;
+}
+
+static void ep93xxfb_set_timing(struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ unsigned int vlines_total, hclks_total, start, stop;
+
+ vlines_total = info->var.yres + info->var.upper_margin +
+ info->var.lower_margin + info->var.vsync_len - 1;
+
+ hclks_total = info->var.xres + info->var.left_margin +
+ info->var.right_margin + info->var.hsync_len - 1;
+
+ ep93xxfb_out_locked(fbi, vlines_total, EP93XXFB_VLINES_TOTAL);
+ ep93xxfb_out_locked(fbi, hclks_total, EP93XXFB_HCLKS_TOTAL);
+
+ start = vlines_total;
+ stop = vlines_total - info->var.vsync_len;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VSYNC);
+
+ start = vlines_total - info->var.vsync_len - info->var.upper_margin;
+ stop = info->var.lower_margin - 1;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VBLANK);
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VACTIVE);
+
+ start = vlines_total;
+ stop = vlines_total + 1;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_VCLK);
+
+ start = hclks_total;
+ stop = hclks_total - info->var.hsync_len;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HSYNC);
+
+ start = hclks_total - info->var.hsync_len - info->var.left_margin;
+ stop = info->var.right_margin - 1;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HBLANK);
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HACTIVE);
+
+ start = hclks_total;
+ stop = hclks_total;
+ ep93xxfb_out_locked(fbi, start | (stop << 16), EP93XXFB_HCLK);
+
+ ep93xxfb_out_locked(fbi, 0x0, EP93XXFB_LINE_CARRY);
+}
+
+static int ep93xxfb_set_par(struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+
+ clk_set_rate(fbi->clk, 1000 * PICOS2KHZ(info->var.pixclock));
+
+ ep93xxfb_set_timing(info);
+
+ info->fix.line_length = info->var.xres_virtual *
+ info->var.bits_per_pixel / 8;
+
+ ep93xxfb_writel(fbi, info->fix.smem_start, EP93XXFB_SCREEN_PAGE);
+ ep93xxfb_writel(fbi, info->var.yres - 1, EP93XXFB_SCREEN_LINES);
+ ep93xxfb_writel(fbi, ((info->var.xres * info->var.bits_per_pixel)
+ / 32) - 1, EP93XXFB_LINE_LENGTH);
+ ep93xxfb_writel(fbi, info->fix.line_length / 4, EP93XXFB_VLINE_STEP);
+ ep93xxfb_set_video_attribs(info);
+ return 0;
+}
+
+static int ep93xxfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int err;
+
+ err = ep93xxfb_set_pixelmode(info);
+ if (err)
+ return err;
+
+ var->xres = max(var->xres, (unsigned int)EP93XXFB_MIN_XRES);
+ var->xres = min(var->xres, (unsigned int)EP93XXFB_MAX_XRES);
+ var->xres_virtual = max(var->xres_virtual, var->xres);
+
+ var->yres = max(var->yres, (unsigned int)EP93XXFB_MIN_YRES);
+ var->yres = min(var->yres, (unsigned int)EP93XXFB_MAX_YRES);
+ var->yres_virtual = max(var->yres_virtual, var->yres);
+
+ return 0;
+}
+
+static int ep93xxfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ unsigned int offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ if (offset < info->fix.smem_len) {
+ return dma_mmap_writecombine(info->dev, vma, info->screen_base,
+ info->fix.smem_start,
+ info->fix.smem_len);
+ }
+
+ return -EINVAL;
+}
+
+static int ep93xxfb_blank(int blank_mode, struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ unsigned int attribs = ep93xxfb_readl(fbi, EP93XXFB_ATTRIBS);
+
+ if (blank_mode) {
+ if (fbi->mach_info->blank)
+ fbi->mach_info->blank(blank_mode, info);
+ ep93xxfb_out_locked(fbi, attribs & ~EP93XXFB_ENABLE,
+ EP93XXFB_ATTRIBS);
+ clk_disable(fbi->clk);
+ } else {
+ clk_enable(fbi->clk);
+ ep93xxfb_out_locked(fbi, attribs | EP93XXFB_ENABLE,
+ EP93XXFB_ATTRIBS);
+ if (fbi->mach_info->blank)
+ fbi->mach_info->blank(blank_mode, info);
+ }
+
+ return 0;
+}
+
+static inline int ep93xxfb_convert_color(int val, int width)
+{
+ return ((val << width) + 0x7fff - val) >> 16;
+}
+
+static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int transp, struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ unsigned int *pal = info->pseudo_palette;
+ unsigned int ctrl, i, rgb, lut_current, lut_stat;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ rgb = ((red & 0xff00) << 8) | (green & 0xff00) |
+ ((blue & 0xff00) >> 8);
+
+ pal[regno] = rgb;
+ ep93xxfb_writel(fbi, rgb, (EP93XXFB_COLOR_LUT + (regno << 2)));
+ ctrl = ep93xxfb_readl(fbi, EP93XXFB_LUT_SW_CONTROL);
+ lut_stat = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SSTAT);
+ lut_current = !!(ctrl & EP93XXFB_LUT_SW_CONTROL_SWTCH);
+
+ if (lut_stat == lut_current) {
+ for (i = 0; i < 256; i++) {
+ ep93xxfb_writel(fbi, pal[i],
+ EP93XXFB_COLOR_LUT + (i << 2));
+ }
+
+ ep93xxfb_writel(fbi,
+ ctrl ^ EP93XXFB_LUT_SW_CONTROL_SWTCH,
+ EP93XXFB_LUT_SW_CONTROL);
+ }
+ break;
+
+ case FB_VISUAL_TRUECOLOR:
+ if (regno > 16)
+ return 1;
+
+ red = ep93xxfb_convert_color(red, info->var.red.length);
+ green = ep93xxfb_convert_color(green, info->var.green.length);
+ blue = ep93xxfb_convert_color(blue, info->var.blue.length);
+ transp = ep93xxfb_convert_color(transp,
+ info->var.transp.length);
+
+ pal[regno] = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset) |
+ (transp << info->var.transp.offset);
+ break;
+
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct fb_ops ep93xxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = ep93xxfb_check_var,
+ .fb_set_par = ep93xxfb_set_par,
+ .fb_blank = ep93xxfb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_setcolreg = ep93xxfb_setcolreg,
+ .fb_mmap = ep93xxfb_mmap,
+};
+
+static int __init ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
+{
+ int i, fb_size = 0;
+
+ if (mach_info->num_modes == EP93XXFB_USE_MODEDB) {
+ fb_size = EP93XXFB_MAX_XRES * EP93XXFB_MAX_YRES *
+ mach_info->bpp / 8;
+ } else {
+ for (i = 0; i < mach_info->num_modes; i++) {
+ const struct fb_videomode *mode;
+ int size;
+
+ mode = &mach_info->modes[i];
+ size = mode->xres * mode->yres * mach_info->bpp / 8;
+ if (size > fb_size)
+ fb_size = size;
+ }
+ }
+
+ return fb_size;
+}
+
+static int __init ep93xxfb_alloc_videomem(struct fb_info *info)
+{
+ struct ep93xx_fbi *fbi = info->par;
+ char __iomem *virt_addr;
+ dma_addr_t phys_addr;
+ unsigned int fb_size;
+
+ fb_size = ep93xxfb_calc_fbsize(fbi->mach_info);
+ virt_addr = dma_alloc_writecombine(info->dev, fb_size,
+ &phys_addr, GFP_KERNEL);
+ if (!virt_addr)
+ return -ENOMEM;
+
+ /*
+ * There is a bug in the ep93xx framebuffer which causes problems
+ * if bit 27 of the physical address is set.
+ * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2
+ * There does not seem to be any offical errata for this, but I
+ * have confirmed the problem exists on my hardware (ep9315) at
+ * least.
+ */
+ if (check_screenpage_bug && phys_addr & (1 << 27)) {
+ dev_err(info->dev, "ep93xx framebuffer bug. phys addr (0x%x) "
+ "has bit 27 set: cannot init framebuffer\n",
+ phys_addr);
+
+ dma_free_coherent(info->dev, fb_size, virt_addr, phys_addr);
+ return -ENOMEM;
+ }
+
+ info->fix.smem_start = phys_addr;
+ info->fix.smem_len = fb_size;
+ info->screen_base = virt_addr;
+
+ return 0;
+}
+
+static void ep93xxfb_dealloc_videomem(struct fb_info *info)
+{
+ if (info->screen_base)
+ dma_free_coherent(info->dev, info->fix.smem_len,
+ info->screen_base, info->fix.smem_start);
+}
+
+static int __init ep93xxfb_probe(struct platform_device *pdev)
+{
+ struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
+ struct fb_info *info;
+ struct ep93xx_fbi *fbi;
+ struct resource *res;
+ char *video_mode;
+ int err;
+
+ if (!mach_info)
+ return -EINVAL;
+
+ info = framebuffer_alloc(sizeof(struct ep93xx_fbi), &pdev->dev);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = &pdev->dev;
+ platform_set_drvdata(pdev, info);
+ fbi = info->par;
+ fbi->mach_info = mach_info;
+
+ err = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (err)
+ goto failed;
+
+ err = ep93xxfb_alloc_videomem(info);
+ if (err)
+ goto failed;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ err = -ENXIO;
+ goto failed;
+ }
+
+ res = request_mem_region(res->start, resource_size(res), pdev->name);
+ if (res == NULL) {
+ err = -EBUSY;
+ goto failed;
+ }
+
+ fbi->res = res;
+ fbi->mmio_base = ioremap(res->start, resource_size(res));
+ if (fbi->mmio_base == NULL) {
+ err = -ENXIO;
+ goto failed;
+ }
+
+ strcpy(info->fix.id, pdev->name);
+ info->fbops = &ep93xxfb_ops;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+ info->flags = FBINFO_DEFAULT;
+ info->node = -1;
+ info->state = FBINFO_STATE_RUNNING;
+ info->pseudo_palette = &fbi->pseudo_palette;
+
+ fb_get_options("ep93xx-fb", &video_mode);
+ err = fb_find_mode(&info->var, info, video_mode,
+ fbi->mach_info->modes, fbi->mach_info->num_modes,
+ fbi->mach_info->default_mode, fbi->mach_info->bpp);
+ if (err == 0) {
+ dev_err(info->dev, "No suitable video mode found\n");
+ err = -EINVAL;
+ goto failed;
+ }
+
+ if (mach_info->setup) {
+ err = mach_info->setup(info);
+ if (err)
+ return err;
+ }
+
+ err = ep93xxfb_check_var(&info->var, info);
+ if (err)
+ goto failed;
+
+ fbi->clk = clk_get(info->dev, NULL);
+ if (IS_ERR(fbi->clk)) {
+ err = PTR_ERR(fbi->clk);
+ fbi->clk = NULL;
+ goto failed;
+ }
+
+ ep93xxfb_set_par(info);
+ clk_enable(fbi->clk);
+
+ err = register_framebuffer(info);
+ if (err)
+ goto failed;
+
+ dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
+ info->var.xres, info->var.yres, info->var.bits_per_pixel);
+ return 0;
+
+failed:
+ if (fbi->clk)
+ clk_put(fbi->clk);
+ if (fbi->mmio_base)
+ iounmap(fbi->mmio_base);
+ if (fbi->res)
+ release_mem_region(fbi->res->start, resource_size(fbi->res));
+ ep93xxfb_dealloc_videomem(info);
+ if (&info->cmap)
+ fb_dealloc_cmap(&info->cmap);
+ if (fbi->mach_info->teardown)
+ fbi->mach_info->teardown(info);
+ kfree(info);
+ platform_set_drvdata(pdev, NULL);
+
+ return err;
+}
+
+static int ep93xxfb_remove(struct platform_device *pdev)
+{
+ struct fb_info *info = platform_get_drvdata(pdev);
+ struct ep93xx_fbi *fbi = info->par;
+
+ unregister_framebuffer(info);
+ clk_disable(fbi->clk);
+ clk_put(fbi->clk);
+ iounmap(fbi->mmio_base);
+ release_mem_region(fbi->res->start, resource_size(fbi->res));
+ ep93xxfb_dealloc_videomem(info);
+ fb_dealloc_cmap(&info->cmap);
+
+ if (fbi->mach_info->teardown)
+ fbi->mach_info->teardown(info);
+
+ kfree(info);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ep93xxfb_driver = {
+ .probe = ep93xxfb_probe,
+ .remove = ep93xxfb_remove,
+ .driver = {
+ .name = "ep93xx-fb",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __devinit ep93xxfb_init(void)
+{
+ return platform_driver_register(&ep93xxfb_driver);
+}
+
+static void __exit ep93xxfb_exit(void)
+{
+ platform_driver_unregister(&ep93xxfb_driver);
+}
+
+module_init(ep93xxfb_init);
+module_exit(ep93xxfb_exit);
+
+MODULE_DESCRIPTION("EP93XX Framebuffer Driver");
+MODULE_ALIAS("platform:ep93xx-fb");
+MODULE_AUTHOR("Ryan Mallon <ryan&bluewatersys.com>, "
+ "H Hartley Sweeten <hsweeten@visionengravers.com");
+MODULE_LICENSE("GPL");
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 1/2] ep93xx framebuffer driver
2009-07-17 3:46 [PATCH 1/2] ep93xx framebuffer driver Ryan Mallon
@ 2009-07-17 3:57 ` Ryan Mallon
2009-07-17 17:05 ` H Hartley Sweeten
2009-07-17 17:35 ` H Hartley Sweeten
0 siblings, 2 replies; 5+ messages in thread
From: Ryan Mallon @ 2009-07-17 3:57 UTC (permalink / raw)
To: arm kernel, linux-fbdev-devel, hartleys, Daniele Venzano
Add platform support and video clock for ep93xx framebuffer driver
Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
---
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index b6b5344..4367a09 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -37,7 +37,7 @@ struct clk {
static unsigned long get_uart_rate(struct clk *clk);
static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
-
+static int set_div_rate(struct clk *clk, unsigned long rate);
static struct clk clk_uart1 = {
.sw_locked = 1,
@@ -73,6 +73,13 @@ static struct clk clk_keypad = {
.set_rate = set_keytchclk_rate,
};
+static struct clk clk_video = {
+ .enable_reg = EP93XX_SYSCON_VIDCLKDIV,
+ .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
+ .sw_locked = 1,
+ .set_rate = set_div_rate,
+};
+
/* DMA Clocks */
static struct clk clk_m2p0 = {
.enable_reg = EP93XX_SYSCON_PWRCNT,
@@ -137,6 +144,7 @@ static struct clk_lookup clocks[] = {
INIT_CK(NULL, "pll2", &clk_pll2),
INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
+ INIT_CK("ep93xx-fb", NULL, &clk_video),
INIT_CK(NULL, "m2p0", &clk_m2p0),
INIT_CK(NULL, "m2p1", &clk_m2p1),
INIT_CK(NULL, "m2p2", &clk_m2p2),
@@ -232,6 +240,86 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
return 0;
}
+static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
+ int *pdiv, int *div)
+{
+ unsigned long max_rate, best_rate = 0,
+ actual_rate = 0, mclk_rate = 0, rate_err = -1;
+ int i, found = 0, __div = 0, __pdiv = 0;
+
+ /* Don't exceed the maximum rate */
+ max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
+ (unsigned long)EP93XX_EXT_CLK_RATE / 4);
+ rate = min(rate, max_rate);
+
+ /*
+ * Try the two pll's and the external clock
+ * Because the valid predividers are 2, 2.5 and 3, we multiply
+ * all the clocks by 2 to avoid floating point math.
+ *
+ * This is based on the algorithm in the ep93xx raster guide:
+ * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
+ *
+ */
+ for (i = 0; i < 3; i++) {
+ if (i == 0)
+ mclk_rate = EP93XX_EXT_CLK_RATE * 2;
+ else if (i == 1)
+ mclk_rate = clk_pll1.rate * 2;
+ else if (i == 2)
+ mclk_rate = clk_pll2.rate * 2;
+
+ /* Try each predivider value */
+ for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
+ __div = mclk_rate / (rate * __pdiv);
+ if (__div < 2 || __div > 127)
+ continue;
+
+ actual_rate = mclk_rate / __pdiv * __div;
+
+ if (!found || abs(actual_rate - rate) < rate_err) {
+ *pdiv = __pdiv - 3;
+ *div = __div;
+ *psel = (i == 2);
+ *esel = (i != 0);
+ best_rate = actual_rate;
+ rate_err = actual_rate - rate;
+ found = 1;
+ }
+ }
+ }
+
+ if (!found)
+ return 0;
+
+ return best_rate;
+}
+
+static int set_div_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long actual_rate;
+ int psel = 0, esel = 0, pdiv = 0, div = 0;
+ u32 val;
+
+ actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
+ if (actual_rate == 0)
+ return -EINVAL;
+ clk->rate = actual_rate;
+
+ /* Clear the esel, psel, pdiv and div bits */
+ val = __raw_readl(clk->enable_reg);
+ val &= ~0x7fff;
+
+ /* Set the new esel, psel, pdiv and div bits for the new clock rate */
+ val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
+ (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
+ (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(val, clk->enable_reg);
+
+ return 0;
+}
+
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (clk->set_rate)
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 8e59bdc..0e96ada 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -36,6 +36,7 @@
#include <asm/hardware/vic.h>
+#include <mach/fb.h>
/*************************************************************************
* Static I/O mappings that are needed for all EP93xx platforms
@@ -570,6 +571,35 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
platform_device_register(&ep93xx_i2c_device);
}
+/*************************************************************************
+ * EP93xx video peripheral handling
+ *************************************************************************/
+static struct ep93xxfb_mach_info ep93xxfb_data;
+
+static struct resource ep93xx_fb_resource[] = {
+ {
+ .start = EP93XX_RASTER_PHYS_BASE,
+ .end = EP93XX_RASTER_PHYS_BASE + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_fb_device = {
+ .name = "ep93xx-fb",
+ .id = -1,
+ .dev.platform_data = &ep93xxfb_data,
+ .dev.coherent_dma_mask = DMA_BIT_MASK(32),
+ .dev.dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask,
+ .num_resources = ARRAY_SIZE(ep93xx_fb_resource),
+ .resource = ep93xx_fb_resource,
+};
+
+void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
+{
+ ep93xxfb_data = *data;
+ platform_device_register(&ep93xx_fb_device);
+}
+
extern void ep93xx_gpio_init(void);
void __init ep93xx_init_devices(void)
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index a11ae77..33765fa 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -70,6 +70,7 @@
#define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000)
#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
+#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000)
#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
@@ -206,13 +207,17 @@
#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
+#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84)
+#define EP93XX_SYSCON_CLKDIV_PSEL (1 << 13)
+#define EP93XX_SYSCON_CLKDIV_ESEL (1 << 14)
+#define EP93XX_SYSCON_CLKDIV_ENABLE (1 << 15)
+#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
-
#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 0af0a3b..e8787e0 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
struct i2c_board_info;
+struct ep93xxfb_mach_info;
struct ep93xx_eth_data
{
@@ -32,7 +33,7 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
-
+void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
void ep93xx_init_devices(void);
extern struct sys_timer ep93xx_timer;
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
^ permalink raw reply related [flat|nested] 5+ messages in thread* RE: [PATCH 1/2] ep93xx framebuffer driver
2009-07-17 3:57 ` Ryan Mallon
@ 2009-07-17 17:05 ` H Hartley Sweeten
2009-07-19 10:30 ` Ryan Mallon
2009-07-17 17:35 ` H Hartley Sweeten
1 sibling, 1 reply; 5+ messages in thread
From: H Hartley Sweeten @ 2009-07-17 17:05 UTC (permalink / raw)
To: Ryan Mallon, arm kernel, linux-fbdev-devel, Daniele Venzano
On Thursday, July 16, 2009 8:58 PM, Ryan Mallon wrote:
> Add platform support and video clock for ep93xx framebuffer driver
>
> Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
> ---
>
> diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
> index b6b5344..4367a09 100644
> --- a/arch/arm/mach-ep93xx/clock.c
> +++ b/arch/arm/mach-ep93xx/clock.c
> @@ -37,7 +37,7 @@ struct clk {
> static unsigned long get_uart_rate(struct clk *clk);
>
> static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
> -
> +static int set_div_rate(struct clk *clk, unsigned long rate);
>
> static struct clk clk_uart1 = {
> .sw_locked = 1,
> @@ -73,6 +73,13 @@ static struct clk clk_keypad = {
> .set_rate = set_keytchclk_rate,
> };
>
> +static struct clk clk_video = {
> + .enable_reg = EP93XX_SYSCON_VIDCLKDIV,
> + .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
> + .sw_locked = 1,
> + .set_rate = set_div_rate,
> +};
Please put .sw_locked before .enable_reg so it's consistent with the other clk's.
> +
> /* DMA Clocks */
> static struct clk clk_m2p0 = {
> .enable_reg = EP93XX_SYSCON_PWRCNT,
> @@ -137,6 +144,7 @@ static struct clk_lookup clocks[] = {
> INIT_CK(NULL, "pll2", &clk_pll2),
> INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
> INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
> + INIT_CK("ep93xx-fb", NULL, &clk_video),
> INIT_CK(NULL, "m2p0", &clk_m2p0),
> INIT_CK(NULL, "m2p1", &clk_m2p1),
> INIT_CK(NULL, "m2p2", &clk_m2p2),
> @@ -232,6 +240,86 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
> return 0;
> }
>
> +static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
> + int *pdiv, int *div)
> +{
> + unsigned long max_rate, best_rate = 0,
> + actual_rate = 0, mclk_rate = 0, rate_err = -1;
> + int i, found = 0, __div = 0, __pdiv = 0;
> +
> + /* Don't exceed the maximum rate */
> + max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
> + (unsigned long)EP93XX_EXT_CLK_RATE / 4);
> + rate = min(rate, max_rate);
> +
> + /*
> + * Try the two pll's and the external clock
> + * Because the valid predividers are 2, 2.5 and 3, we multiply
> + * all the clocks by 2 to avoid floating point math.
> + *
> + * This is based on the algorithm in the ep93xx raster guide:
> + * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
> + *
> + */
> + for (i = 0; i < 3; i++) {
> + if (i == 0)
> + mclk_rate = EP93XX_EXT_CLK_RATE * 2;
> + else if (i == 1)
> + mclk_rate = clk_pll1.rate * 2;
> + else if (i == 2)
> + mclk_rate = clk_pll2.rate * 2;
> +
> + /* Try each predivider value */
> + for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
> + __div = mclk_rate / (rate * __pdiv);
> + if (__div < 2 || __div > 127)
> + continue;
> +
> + actual_rate = mclk_rate / __pdiv * __div;
> +
> + if (!found || abs(actual_rate - rate) < rate_err) {
> + *pdiv = __pdiv - 3;
> + *div = __div;
> + *psel = (i == 2);
> + *esel = (i != 0);
> + best_rate = actual_rate;
> + rate_err = actual_rate - rate;
> + found = 1;
> + }
> + }
> + }
> +
> + if (!found)
> + return 0;
> +
> + return best_rate;
> +}
> +
> +static int set_div_rate(struct clk *clk, unsigned long rate)
> +{
> + unsigned long actual_rate;
> + int psel = 0, esel = 0, pdiv = 0, div = 0;
> + u32 val;
> +
> + actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
> + if (actual_rate == 0)
> + return -EINVAL;
> + clk->rate = actual_rate;
> +
> + /* Clear the esel, psel, pdiv and div bits */
> + val = __raw_readl(clk->enable_reg);
> + val &= ~0x7fff;
> +
> + /* Set the new esel, psel, pdiv and div bits for the new clock rate */
> + val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
> + (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
> + (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
> + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
> + __raw_writel(val, clk->enable_reg);
ep93xx_syscon_swlocked_write(val, clk->enable_reg);
> +
> + return 0;
> +}
> +
> int clk_set_rate(struct clk *clk, unsigned long rate)
> {
> if (clk->set_rate)
> diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
> index 8e59bdc..0e96ada 100644
> --- a/arch/arm/mach-ep93xx/core.c
> +++ b/arch/arm/mach-ep93xx/core.c
> @@ -36,6 +36,7 @@
>
> #include <asm/hardware/vic.h>
>
> +#include <mach/fb.h>
Please move this include up so it's right after <mach/hardware.h>
>
> /*************************************************************************
> * Static I/O mappings that are needed for all EP93xx platforms
> @@ -570,6 +571,35 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
> platform_device_register(&ep93xx_i2c_device);
> }
>
> +/*************************************************************************
> + * EP93xx video peripheral handling
> + *************************************************************************/
> +static struct ep93xxfb_mach_info ep93xxfb_data;
> +
> +static struct resource ep93xx_fb_resource[] = {
> + {
> + .start = EP93XX_RASTER_PHYS_BASE,
> + .end = EP93XX_RASTER_PHYS_BASE + 0x800 - 1,
> + .flags = IORESOURCE_MEM,
> + },
> +};
> +
> +static struct platform_device ep93xx_fb_device = {
> + .name = "ep93xx-fb",
> + .id = -1,
> + .dev.platform_data = &ep93xxfb_data,
> + .dev.coherent_dma_mask = DMA_BIT_MASK(32),
> + .dev.dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask,
> + .num_resources = ARRAY_SIZE(ep93xx_fb_resource),
> + .resource = ep93xx_fb_resource,
> +};
Question. Is ".dev.* = " preferred over:
> + .dev = {
> + .platform_data = &ep93xxfb_data,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + .dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask,
> + },
I think the form above is a bit easier to read.
> +
> +void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
> +{
> + ep93xxfb_data = *data;
> + platform_device_register(&ep93xx_fb_device);
> +}
> +
> extern void ep93xx_gpio_init(void);
>
> void __init ep93xx_init_devices(void)
> diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
> index a11ae77..33765fa 100644
> --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
> +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
> @@ -70,6 +70,7 @@
> #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000)
> #define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
>
> +#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000)
> #define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
>
> #define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
> @@ -206,13 +207,17 @@
> #define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
> #define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
> #define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
> +#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84)
> +#define EP93XX_SYSCON_CLKDIV_PSEL (1 << 13)
> +#define EP93XX_SYSCON_CLKDIV_ESEL (1 << 14)
> +#define EP93XX_SYSCON_CLKDIV_ENABLE (1 << 15)
> +#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
> #define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
> #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
> #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
> #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
> #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
> #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
What tree is this patch based on? The KEYTCHCLKDIV defines are not in Russell's
devel branch.
If (1 << 13) is preferred over (1<<13) we should eventually update this entire file
so that the defines are consistent.
> -
> #define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
>
>
> diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
> index 0af0a3b..e8787e0 100644
> --- a/arch/arm/mach-ep93xx/include/mach/platform.h
> +++ b/arch/arm/mach-ep93xx/include/mach/platform.h
> @@ -5,6 +5,7 @@
> #ifndef __ASSEMBLY__
>
> struct i2c_board_info;
> +struct ep93xxfb_mach_info;
>
> struct ep93xx_eth_data
> {
> @@ -32,7 +33,7 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
>
> void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
> void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
> -
> +void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
> void ep93xx_init_devices(void);
> extern struct sys_timer ep93xx_timer;
Please add a whitespace between ep93xx_register_fb and ep93xx_init_devices.
The ep93xx_register_* functions are all machine optional but ep93xx_init_devices
is required.
Regards,
Hartley
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 1/2] ep93xx framebuffer driver
2009-07-17 17:05 ` H Hartley Sweeten
@ 2009-07-19 10:30 ` Ryan Mallon
0 siblings, 0 replies; 5+ messages in thread
From: Ryan Mallon @ 2009-07-19 10:30 UTC (permalink / raw)
To: H Hartley Sweeten; +Cc: arm kernel, linux-fbdev-devel, Daniele Venzano
H Hartley Sweeten wrote:
> On Thursday, July 16, 2009 8:58 PM, Ryan Mallon wrote:
>> diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
>> index a11ae77..33765fa 100644
>> --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
>> +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
>> @@ -70,6 +70,7 @@
>> #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000)
>> #define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
>>
>> +#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000)
>> #define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
>>
>> #define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
>> @@ -206,13 +207,17 @@
>> #define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
>> #define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
>> #define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
>> +#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84)
>> +#define EP93XX_SYSCON_CLKDIV_PSEL (1 << 13)
>> +#define EP93XX_SYSCON_CLKDIV_ESEL (1 << 14)
>> +#define EP93XX_SYSCON_CLKDIV_ENABLE (1 << 15)
>> +#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
>> #define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
>> #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
>> #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
>> #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
>> #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
>> #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
>
> What tree is this patch based on? The KEYTCHCLKDIV defines are not in Russell's
> devel branch.
I put the patch to fix the keypad #defines in my tree before rebasing
the driver. I think this order is preferred since the keypad defines
patch is needed for the tree to build without errors.
> If (1 << 13) is preferred over (1<<13) we should eventually update this entire file
> so that the defines are consistent.
I prefer the spaces, but I'll change them in the header file so it is
consistent with the rest of the file. We can do a patch later to change
all of the defines in the header file, but I honestly don't think it
matters as long as it is consistent.
~Ryan
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] ep93xx framebuffer driver
2009-07-17 3:57 ` Ryan Mallon
2009-07-17 17:05 ` H Hartley Sweeten
@ 2009-07-17 17:35 ` H Hartley Sweeten
1 sibling, 0 replies; 5+ messages in thread
From: H Hartley Sweeten @ 2009-07-17 17:35 UTC (permalink / raw)
To: Ryan Mallon, arm kernel, linux-fbdev-devel, Daniele Venzano
On Thursday, July 16, 2009 8:58 PM, Ryan Mallon wrote:
> Add platform support and video clock for ep93xx framebuffer driver
>
> Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
> ---
> +#include <mach/fb.h>
This new header is not included in either patchset.
Thanks,
Hartley
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2009-07-19 10:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-17 3:46 [PATCH 1/2] ep93xx framebuffer driver Ryan Mallon
2009-07-17 3:57 ` Ryan Mallon
2009-07-17 17:05 ` H Hartley Sweeten
2009-07-19 10:30 ` Ryan Mallon
2009-07-17 17:35 ` H Hartley Sweeten
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).