* fb_setcolreg(), CNVT_TOHW() and chan_to_field()
From: Rabin Vincent @ 2011-10-25 7:46 UTC (permalink / raw)
To: linux-fbdev
I'm trying to figure out the best way to implement fb_setcolreg() for
FB_VISUAL_TRUECOLOR.
14 or so drivers copy/paste the CNVT_TOHW from skeletonfb.c:
#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
...
red = CNVT_TOHW(red, info->var.red.length);
Another 18 or so drivers copy/paste a chan_to_field() function which has
a straightforward shift:
static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
return chan << bf->offset;
}
...
val = chan_to_field(red, &info->var.red);
Both methods return similar values, except that with CNVT_TOHW() the
extreme values seem to have a smaller range than the other values, while
with the chan_to_field() shift all the values have an equal range.
What's the reason behind choosing one over the other? Could/should a
common function be provided for all the drivers to use?
^ permalink raw reply
* 群发软件+买家搜索机+最新广交会买家、海
From: 仅10元每天。 @ 2011-10-24 21:16 UTC (permalink / raw)
To: linux-fbdev
576k5Y+R6L2v5Lu2K+S5sOWutuaQnOe0ouacuisxMDnlsYrlub/kuqTkvJrkubDlrrbjgIHlsZXk
vJrkubDlrrbjgIHmtbflhbPmlbDmja4sQjJC6K+i55uY5Lmw5a62NTAw5LiH44CCDQoNCuS4gOWF
sTjkuKrljIUo5pWw5o2u5piv5YWo6KGM5Lia55qE77yM5oyJ54Wn6KGM5Lia5YiG5aW957G777yM
5bm25LiU5Y+v5Lul5oyJ54Wn5YWz6ZSu6K+N5p+l6K+i55qEKe+8miANCjHvvIwyMDEx5pil5a2j
MTA55bGK5bm/5Lqk5Lya5Lmw5a625pWw5o2u5bqT5paw6bKc5Ye654KJ77yM6LaF57qn5paw6bKc
5Lmw5a6277yM5paw6bKc5pWw5o2u77yM5a655piT5oiQ5Y2V77yBIA0KMu+8jOacgOaWsOWFqOeQ
g+S5sOWutuW6kyzlhbE0NTE2NjDmnaHmlbDmja7jgIIgDQoz77yMMjAwOOW5tCwyMDA55bm0LDIw
MTDlubQg5pil5a2jK+eni+Wto+W5v+S6pOS8muS5sOWutuWQjeW9le+8jDEwMyAxMDQgMTA1IDEw
NiAxMDcgMTA4IOWFseWFreWxiiDlhbExMjAuNuS4h+aVsOaNruOAgg0KNO+8jDIwMTDlubTlm73p
mYXkv4PplIDljY/kvJrvvIhQUEFJ77yJ5oiQ5ZGY5ZCN5Y2VIFBQQUkgTWVtYmVycyBEaXJlY3Rv
cnnvvIzpnZ7luLjph43opoHnmoTlpKfkubDlrrbjgIINCjXvvIwyMDEw5bm05Yiw6aaZ5riv6YeH
6LSt55qE5Zu95aSW5a6i5Lq65ZCN5b2VKOmmmea4r+i0uOWPkeWxgOaPkOS+mynvvIzlhbE3LjLk
uIfmlbDmja7vvIzotoXnuqfph43opoHnmoTkubDlrrbjgIINCjbvvIw2MC445LiH5p2h5pyA5paw
5Zu95aSWQjJC5Lmw5a626K+i55uY44CCDQo377yMMjAwOeW5tOa1t+WFs+aPkOWNleaVsOaNrnBp
ZXJz54mI5pWw5o2uIDHljYPkuIfjgIINCjjvvIznvqTlj5Hova/ku7bvvIznvqTlj5Hova/ku7bn
moTpg6jnvbLkuI7lronoo4XjgIINCg0K5YWxIDUwMOS4h+S4quS5sOWutu+8jOavj+S4quWdh+ac
iUVtYWlsLiANCg0K5L+d6K+B5q+P5aSp6YO95pyJ5Lmw5a625Zue5aSN44CCDQrkv53or4Hmr4/l
pKnpg73mnInkubDlrrblm57lpI3jgIINCg0K6KaB55qE5oqT57Sn6IGU57O7UVE6IDQ2NzY0Mzk3
NSAgIOaIluiAheeri+WNs+WbnuWkjemCrueusTogIDQ2NzY0Mzk3NUBxcS5jb20NCuimgeeahOaK
k+e0p+iBlOezu1FROiA0Njc2NDM5NzUgICDmiJbogIXnq4vljbPlm57lpI3pgq7nrrE6ICA0Njc2
NDM5NzVAcXEuY29tDQropoHnmoTmipPntKfogZTns7tRUTogNDY3NjQzOTc1ICAg5oiW6ICF56uL
5Y2z5Zue5aSN6YKu566xOiAgNDY3NjQzOTc1QHFxLmNvbQ0KDQoNCuivmuS/oeS4uuacrO+8jOWm
guaenOS4jeS/oeS7u+acrOS6uizlj6/ku6XotbDmt5jlrp3kuqTmmJMs5pS26LSn6aqM6K+B5ZCO
5YaN5LuY5qy+LOi/meaYr+WvueaCqOacgOWlveeahOS/nemanOS6huOAgiANCg0K5L+d6K+B5q+P
5aSp6YO95pyJ5Lmw5a625Zue5aSN44CCDQrkv53or4Hmr4/lpKnpg73mnInkubDlrrblm57lpI3j
gIINCuS/neivgeavj+WkqemDveacieS5sOWutuWbnuWkjeOAgg0KDQoNCg0KDQrlub/kuqTkvJrk
ubDlrrbmjInkuqflk4HnsbvliKvliIbnsbvvvIzliIbkuLrku6XkuIvlh6DnsbvvvJoNCjEg5Yqe
5YWs6K6+5aSHDQoyIOe8lue7h+WPiuiXpOmTgeW3peiJuuWTgQ0KMyDnjrvnkoMNCjQg6aSQ5Y6o
55So5YW3DQo1IOi9pui+hg0KNiDlpKflnovmnLrmorDlj4rorr7lpIcNCjcg55S15a2Q55S15rCU
DQo4IOeUteWtkOa2iOi0ueWTgQ0KOSDnurrnu4cNCjEwIOacjeijhQ0KMTEg5Liq5Lq65oqk55CG
DQoxMiDlt6XnqIvmnLrmorANCjEzIOW3peWFtw0KMTQg5YyW5belDQoxNSDorqHnrpfmnLrlj4rp
gJrorq8NCjE2IOWutuWxheeUqOWTgQ0KMTcg5a625bGF6KOF6aWwDQoxOCDlrrblhbcNCjE5IOWu
tueUqOeUteWZqA0KMjAg5bu6562R5Y+K6KOF6aWw5p2Q5paZDQoyMSDoioLml6XnlKjlk4ENCjIy
IOekvOWTgeWPiui1oOWTgQ0KMjMg5pGp5omY6L2mDQoyNCDmsb3ovabphY3ku7YNCjI1IOmjn+WT
gQ0KMjYg6Zm255O3DQoyNyDpk4Hnn7MNCjI4IOeOqeWFtw0KMjkg5Y2r5rW0DQozMCDkupTph5EN
CjMxIOWwj+Wei+acuuaisA0KMzIg6Z6LDQozMyDkvJHpl7LnlKjlk4ENCjM0IOWMu+eWlw0KMzUg
5rW05a6k5Lqn5ZOBDQozNiDlm63mnpcNCjM3IOeFp+aYjuS6p+WTgQ0KMzgg6ZKf6KGo55y86ZWc
DQozOSDoh6rooYzovaYNCjQwIOWMhQ0KDQoNCuS/neivgeavj+WkqemDveacieS5sOWutuWbnuWk
jeOAgg0K5L+d6K+B5q+P5aSp6YO95pyJ5Lmw5a625Zue5aSN44CCDQrkv53or4Hmr4/lpKnpg73m
nInkubDlrrblm57lpI3jgIINCuS/neivgeavj+WkqemDveacieS5sOWutuWbnuWkjeOAgg0K5L+d
6K+B5q+P5aSp6YO95pyJ5Lmw5a625Zue5aSN44CCDQo
^ permalink raw reply
* [PATCH 02/16] macfb: fix black and white modes
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, Florian Tobias Schandinat, linux-fbdev
In-Reply-To: <20111023141108.856998818@telegraphics.com.au>
macfb won't init in black & white modes since fb_alloc_cmap() no longer works for zero cmap length. Fix this and also clean up a few printk's and some stylistic inconsistencies.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/drivers/video/macfb.c
=================================--- linux-m68k.orig/drivers/video/macfb.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/video/macfb.c 2011-10-23 00:50:51.000000000 +1100
@@ -592,12 +592,12 @@ static int __init macfb_init(void)
if (!fb_info.screen_base)
return -ENODEV;
- printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
- macfb_fix.smem_start, fb_info.screen_base,
- macfb_fix.smem_len / 1024);
- printk("macfb: mode is %dx%dx%d, linelength=%d\n",
- macfb_defined.xres, macfb_defined.yres,
- macfb_defined.bits_per_pixel, macfb_fix.line_length);
+ pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+ macfb_fix.smem_start, fb_info.screen_base,
+ macfb_fix.smem_len / 1024);
+ pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
+ macfb_defined.xres, macfb_defined.yres,
+ macfb_defined.bits_per_pixel, macfb_fix.line_length);
/* Fill in the available video resolution */
macfb_defined.xres_virtual = macfb_defined.xres;
@@ -613,14 +613,10 @@ static int __init macfb_init(void)
switch (macfb_defined.bits_per_pixel) {
case 1:
- /*
- * XXX: I think this will catch any program that tries
- * to do FBIO_PUTCMAP when the visual is monochrome.
- */
macfb_defined.red.length = macfb_defined.bits_per_pixel;
macfb_defined.green.length = macfb_defined.bits_per_pixel;
macfb_defined.blue.length = macfb_defined.bits_per_pixel;
- video_cmap_len = 0;
+ video_cmap_len = 2;
macfb_fix.visual = FB_VISUAL_MONO01;
break;
case 2:
@@ -660,11 +656,10 @@ static int __init macfb_init(void)
macfb_fix.visual = FB_VISUAL_TRUECOLOR;
break;
default:
- video_cmap_len = 0;
- macfb_fix.visual = FB_VISUAL_MONO01;
- printk("macfb: unknown or unsupported bit depth: %d\n",
+ pr_err("macfb: unknown or unsupported bit depth: %d\n",
macfb_defined.bits_per_pixel);
- break;
+ err = -EINVAL;
+ goto fail_unmap;
}
/*
@@ -734,8 +729,8 @@ static int __init macfb_init(void)
case MAC_MODEL_Q950:
strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -744,8 +739,8 @@ static int __init macfb_init(void)
case MAC_MODEL_LCII:
strcpy(macfb_fix.id, "V8");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -758,8 +753,8 @@ static int __init macfb_init(void)
case MAC_MODEL_P600:
strcpy(macfb_fix.id, "Brazil");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -773,10 +768,10 @@ static int __init macfb_init(void)
case MAC_MODEL_P520:
case MAC_MODEL_P550:
case MAC_MODEL_P460:
- macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Sonora");
+ macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -786,10 +781,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_IICI:
case MAC_MODEL_IISI:
- macfb_setpalette = rbv_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "RBV");
+ macfb_setpalette = rbv_setpalette;
rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -797,10 +792,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_Q840:
case MAC_MODEL_C660:
- macfb_setpalette = civic_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Civic");
+ macfb_setpalette = civic_setpalette;
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
@@ -809,26 +804,26 @@ static int __init macfb_init(void)
* We think this may be like the LC II
*/
case MAC_MODEL_LC:
+ strcpy(macfb_fix.id, "LC");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "LC");
break;
/*
* We think this may be like the LC II
*/
case MAC_MODEL_CCL:
+ strcpy(macfb_fix.id, "Color Classic");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "Color Classic");
break;
/*
@@ -893,10 +888,10 @@ static int __init macfb_init(void)
case MAC_MODEL_PB270C:
case MAC_MODEL_PB280:
case MAC_MODEL_PB280C:
- macfb_setpalette = csc_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "CSC");
+ macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
default:
@@ -918,8 +913,9 @@ static int __init macfb_init(void)
if (err)
goto fail_dealloc;
- printk("fb%d: %s frame buffer device\n",
- fb_info.node, fb_info.fix.id);
+ pr_info("fb%d: %s frame buffer device\n",
+ fb_info.node, fb_info.fix.id);
+
return 0;
fail_dealloc:
^ permalink raw reply
* lxfb_core: support 800x480 panel
From: pavel @ 2011-10-23 14:00 UTC (permalink / raw)
To: linux-geode, linux-fbdev, linux-kernel
(very old message; maybe it was fixed in the meantime)
I need something like this to support full resolution of internal LCD
panel on Kohjinsha subnotebook.
(Note: I basically made up the numbers, if someone knows how to
generate them properly, let me know. It somehow works even on external
display, but last few columns are missing.)
Signed-off-by: Pavel Machek <pavel@ucw.cz>
index 889cbe3..2c04a01 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -37,6 +37,9 @@ static int vt_switch;
*/
static struct fb_videomode geode_modedb[] __initdata = {
+ /* 800x480-?? */
+ { NULL, 60, 800, 480, 25131, 72, 32, 29, 1, 136, 6,
+ 0, FB_VMODE_NONINTERLACED, 0 },
/* 640x480-60 */
{ NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
^ permalink raw reply related
* [PATCH v2] GIO bus support for SGI IP22/28
From: Thomas Bogendoerfer @ 2011-10-20 22:19 UTC (permalink / raw)
To: linux-mips, linux-fbdev; +Cc: ralf, FlorianSchandinat
SGI IP22/IP28 machines have GIO busses for adding graphics and other
extension cards. This patch adds support for GIO driver/device
handling and converts the newport console driver to a GIO driver.
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
Changes to last version:
- use EXPORT_SYMBOL_GPL
- ChallengeS has only 2 slots
- use subsys_initcall for gio detection
Florian, the whole patch should go through the MIPS tree, if it's ok for
you.
arch/mips/include/asm/gio_device.h | 56 +++++
arch/mips/sgi-ip22/Makefile | 2 +-
arch/mips/sgi-ip22/ip22-gio.c | 414 +++++++++++++++++++++++++++++++++++
arch/mips/sgi-ip22/ip22-mc.c | 10 +-
arch/mips/sgi-ip22/ip22-setup.c | 21 --
drivers/video/console/newport_con.c | 61 ++++--
6 files changed, 518 insertions(+), 46 deletions(-)
diff --git a/arch/mips/include/asm/gio_device.h b/arch/mips/include/asm/gio_device.h
new file mode 100644
index 0000000..5437c84
--- /dev/null
+++ b/arch/mips/include/asm/gio_device.h
@@ -0,0 +1,56 @@
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+struct gio_device_id {
+ __u8 id;
+};
+
+struct gio_device {
+ struct device dev;
+ struct resource resource;
+ unsigned int irq;
+ unsigned int slotno;
+
+ const char *name;
+ struct gio_device_id id;
+ unsigned id32:1;
+ unsigned gio64:1;
+};
+#define to_gio_device(d) container_of(d, struct gio_device, dev)
+
+struct gio_driver {
+ const char *name;
+ struct module *owner;
+ const struct gio_device_id *id_table;
+
+ int (*probe)(struct gio_device *, const struct gio_device_id *);
+ void (*remove)(struct gio_device *);
+ int (*suspend)(struct gio_device *, pm_message_t);
+ int (*resume)(struct gio_device *);
+ void (*shutdown)(struct gio_device *);
+
+ struct device_driver driver;
+};
+#define to_gio_driver(drv) container_of(drv, struct gio_driver, driver)
+
+extern const struct gio_device_id *gio_match_device(const struct gio_device_id *,
+ const struct gio_device *);
+extern struct gio_device *gio_dev_get(struct gio_device *);
+extern void gio_dev_put(struct gio_device *);
+
+extern int gio_device_register(struct gio_device *);
+extern void gio_device_unregister(struct gio_device *);
+extern void gio_release_dev(struct device *);
+
+static inline void gio_device_free(struct gio_device *dev)
+{
+ gio_release_dev(&dev->dev);
+}
+
+extern int gio_register_driver(struct gio_driver *);
+extern void gio_unregister_driver(struct gio_driver *);
+
+#define gio_get_drvdata(_dev) drv_get_drvdata(&(_dev)->dev)
+#define gio_set_drvdata(_dev, data) drv_set_drvdata(&(_dev)->dev, (data))
+
+extern void gio_set_master(struct gio_device *);
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index cc53849..411cda9 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -4,7 +4,7 @@
#
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
- ip22-platform.o ip22-reset.o ip22-setup.o
+ ip22-platform.o ip22-reset.o ip22-setup.o ip22-gio.o
obj-$(CONFIG_SGI_IP22) += ip22-berr.o
obj-$(CONFIG_SGI_IP28) += ip28-berr.o
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
new file mode 100644
index 0000000..d841529
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -0,0 +1,414 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include <asm/addrspace.h>
+#include <asm/paccess.h>
+#include <asm/gio_device.h>
+#include <asm/sgi/gio.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+
+static struct bus_type gio_bus;
+
+static struct {
+ const char *name;
+ __u8 id;
+} gio_name_table[] = {
+ { .name = "SGI Impact", .id = 0x10 },
+ { .name = "Phobos G160", .id = 0x35 },
+ /* fake IDs */
+ { .name = "SGI Newport", .id = 0x7e },
+ { .name = "SGI GR2/GR3", .id = 0x7f },
+};
+
+/**
+ * gio_match_device - Tell if an of_device structure has a matching
+ * gio_match structure
+ * @ids: array of of device match structures to search in
+ * @dev: the of device structure to match against
+ *
+ * Used by a driver to check whether an of_device present in the
+ * system is in its list of supported devices.
+ */
+const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
+ const struct gio_device *dev)
+{
+ const struct gio_device_id *ids;
+
+ for (ids = match; ids->id != 0xff; ids++)
+ if (ids->id = dev->id.id)
+ return ids;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gio_match_device);
+
+struct gio_device *gio_dev_get(struct gio_device *dev)
+{
+ struct device *tmp;
+
+ if (!dev)
+ return NULL;
+ tmp = get_device(&dev->dev);
+ if (tmp)
+ return to_gio_device(tmp);
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gio_dev_get);
+
+void gio_dev_put(struct gio_device *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(gio_dev_put);
+
+static ssize_t dev_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ return sprintf(buf, "%s", giodev->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, dev_show_name, NULL);
+
+static ssize_t dev_show_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ return sprintf(buf, "%x", giodev->id.id);
+}
+
+static DEVICE_ATTR(id, S_IRUGO, dev_show_id, NULL);
+
+/**
+ * gio_release_dev - free an gio device structure when all users of it are finished.
+ * @dev: device that's been disconnected
+ *
+ * Will be called only by the device core when all users of this gio device are
+ * done.
+ */
+void gio_release_dev(struct device *dev)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ kfree(giodev);
+}
+EXPORT_SYMBOL_GPL(gio_release_dev);
+
+int gio_device_register(struct gio_device *giodev)
+{
+ int rc;
+
+ giodev->dev.bus = &gio_bus;
+ rc = device_register(&giodev->dev);
+ if (rc)
+ return rc;
+
+ rc = device_create_file(&giodev->dev, &dev_attr_name);
+ if (rc)
+ goto err;
+ rc = device_create_file(&giodev->dev, &dev_attr_id);
+ if (rc)
+ goto err;
+
+ return 0;
+
+err:
+ device_unregister(&giodev->dev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(gio_device_register);
+
+void gio_device_unregister(struct gio_device *giodev)
+{
+ device_remove_file(&giodev->dev, &dev_attr_id);
+ device_remove_file(&giodev->dev, &dev_attr_name);
+ device_unregister(&giodev->dev);
+}
+EXPORT_SYMBOL_GPL(gio_device_unregister);
+
+static int gio_bus_match(struct device *dev, struct device_driver *drv)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *gio_drv = to_gio_driver(drv);
+
+ return gio_match_device(gio_drv->id_table, gio_dev) != NULL;
+}
+
+static int gio_device_probe(struct device *dev)
+{
+ int error = -ENODEV;
+ struct gio_driver *drv;
+ struct gio_device *gio_dev;
+ const struct gio_device_id *match;
+
+ drv = to_gio_driver(dev->driver);
+ gio_dev = to_gio_device(dev);
+
+ if (!drv->probe)
+ return error;
+
+ gio_dev_get(gio_dev);
+
+ match = gio_match_device(drv->id_table, gio_dev);
+ if (match)
+ error = drv->probe(gio_dev, match);
+ if (error)
+ gio_dev_put(gio_dev);
+
+ return error;
+}
+
+static int gio_device_remove(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+
+ if (dev->driver && drv->remove)
+ drv->remove(gio_dev);
+ return 0;
+}
+
+static int gio_device_suspend(struct device *dev, pm_message_t state)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+ int error = 0;
+
+ if (dev->driver && drv->suspend)
+ error = drv->suspend(gio_dev, state);
+ return error;
+}
+
+static int gio_device_resume(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+ int error = 0;
+
+ if (dev->driver && drv->resume)
+ error = drv->resume(gio_dev);
+ return error;
+}
+
+static void gio_device_shutdown(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+
+ if (dev->driver && drv->shutdown)
+ drv->shutdown(gio_dev);
+}
+
+int gio_register_driver(struct gio_driver *drv)
+{
+ /* initialize common driver fields */
+ if (!drv->driver.name)
+ drv->driver.name = drv->name;
+ if (!drv->driver.owner)
+ drv->driver.owner = drv->owner;
+ drv->driver.bus = &gio_bus;
+
+ /* register with core */
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(gio_register_driver);
+
+void gio_unregister_driver(struct gio_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(gio_unregister_driver);
+
+void gio_set_master(struct gio_device *dev)
+{
+ u32 tmp = sgimc->giopar;
+
+ switch (dev->slotno) {
+ case 0:
+ tmp |= SGIMC_GIOPAR_MASTERGFX;
+ break;
+ case 1:
+ tmp |= SGIMC_GIOPAR_MASTEREXP0;
+ break;
+ case 2:
+ tmp |= SGIMC_GIOPAR_MASTEREXP1;
+ break;
+ }
+ sgimc->giopar = tmp;
+}
+EXPORT_SYMBOL_GPL(gio_set_master);
+
+void ip22_gio_set_64bit(int slotno)
+{
+ u32 tmp = sgimc->giopar;
+
+ switch (slotno) {
+ case 0:
+ tmp |= SGIMC_GIOPAR_GFX64;
+ break;
+ case 1:
+ tmp |= SGIMC_GIOPAR_EXP064;
+ break;
+ case 2:
+ tmp |= SGIMC_GIOPAR_EXP164;
+ break;
+ }
+ sgimc->giopar = tmp;
+}
+
+static int ip22_gio_id(unsigned long addr, u32 *res)
+{
+ u8 tmp8;
+ u8 tmp16;
+ u32 tmp32;
+ u8 *ptr8;
+ u16 *ptr16;
+ u32 *ptr32;
+
+ ptr32 = (void *)CKSEG1ADDR(addr);
+ if (!get_dbe(tmp32, ptr32)) {
+ /*
+ * We got no DBE, but this doesn't mean anything.
+ * If GIO is pipelined (which can't be disabled
+ * for GFX slot) we don't get a DBE, but we see
+ * the transfer size as data. So we do an 8bit
+ * and a 16bit access and check whether the common
+ * data matches
+ */
+ ptr8 = (void *)CKSEG1ADDR(addr + 3);
+ get_dbe(tmp8, ptr8);
+ ptr16 = (void *)CKSEG1ADDR(addr + 2);
+ get_dbe(tmp16, ptr16);
+ if (tmp8 = (tmp16 & 0xff) &&
+ tmp8 = (tmp32 & 0xff) &&
+ tmp16 = (tmp32 & 0xffff)) {
+ *res = tmp32;
+ return 1;
+ }
+ }
+ return 0; /* nothing here */
+}
+
+#define HQ2_MYSTERY_OFFS 0x6A07C
+#define NEWPORT_USTATUS_OFFS 0xF133C
+
+static int ip22_is_gr2(unsigned long addr)
+{
+ u32 tmp;
+ u32 *ptr;
+
+ /* HQ2 only allows 32bit accesses */
+ ptr = (void *)CKSEG1ADDR(addr + HQ2_MYSTERY_OFFS);
+ if (!get_dbe(tmp, ptr)) {
+ if (tmp = 0xdeadbeef)
+ return 1;
+ }
+ return 0;
+}
+
+
+static void ip22_check_gio(int slotno, unsigned long addr)
+{
+ const char *name = "Unknown";
+ struct gio_device *gio_dev;
+ u32 tmp;
+ __u8 id;
+ int i;
+
+ /* first look for GR2/GR3 by checking mystery register */
+ if (ip22_is_gr2(addr))
+ tmp = 0x7f;
+ else {
+ if (!ip22_gio_id(addr, &tmp)) {
+ /*
+ * no GIO signature at start address of slot, but
+ * Newport doesn't have one, so let's check usea
+ * status register
+ */
+ if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp))
+ tmp = 0x7e;
+ else
+ tmp = 0;
+ }
+ }
+ if (tmp) {
+ id = GIO_ID(tmp);
+ if (tmp & GIO_32BIT_ID) {
+ if (tmp & GIO_64BIT_IFACE)
+ ip22_gio_set_64bit(slotno);
+ }
+ for (i = 0; i < ARRAY_SIZE(gio_name_table); i++) {
+ if (id = gio_name_table[i].id) {
+ name = gio_name_table[i].name;
+ break;
+ }
+ }
+ printk(KERN_INFO "GIO: slot %d : %s (id %x)\n",
+ slotno, name, id);
+ gio_dev = kzalloc(sizeof *gio_dev, GFP_KERNEL);
+ gio_dev->name = name;
+ gio_dev->slotno = slotno;
+ gio_dev->id.id = id;
+ gio_dev->resource.start = addr;
+ gio_dev->resource.end = addr + 0x3fffff;
+ gio_dev->resource.flags = IORESOURCE_MEM;
+ dev_set_name(&gio_dev->dev, "gio%d", slotno);
+ gio_device_register(gio_dev);
+ } else
+ printk(KERN_INFO "GIO: slot %d : Empty\n", slotno);
+}
+
+static struct bus_type gio_bus = {
+ .name = "gio",
+ .match = gio_bus_match,
+ .probe = gio_device_probe,
+ .remove = gio_device_remove,
+ .suspend = gio_device_suspend,
+ .resume = gio_device_resume,
+ .shutdown = gio_device_shutdown,
+};
+
+static struct resource gio_bus_resource = {
+ .start = GIO_SLOT_GFX_BASE,
+ .end = GIO_SLOT_GFX_BASE + 0x9fffff,
+ .name = "GIO Bus",
+ .flags = IORESOURCE_MEM,
+};
+
+int __init ip22_gio_init(void)
+{
+ unsigned int pbdma __maybe_unused;
+ int ret;
+
+ ret = bus_register(&gio_bus);
+ if (!ret) {
+ request_resource(&iomem_resource, &gio_bus_resource);
+ printk(KERN_INFO "GIO: Probing bus...\n");
+
+ if (ip22_is_fullhouse() ||
+ !get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) {
+ /* Indigo2 and ChallengeS */
+ ip22_check_gio(0, GIO_SLOT_GFX_BASE);
+ ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
+ } else {
+ /* Indy */
+ ip22_check_gio(0, GIO_SLOT_GFX_BASE);
+ ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
+ ip22_check_gio(2, GIO_SLOT_EXP1_BASE);
+ }
+ }
+ return ret;
+}
+
+subsys_initcall(ip22_gio_init);
+
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index d22262e..75ada8a 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -139,11 +139,11 @@ void __init sgimc_init(void)
* zero.
*/
/* don't touch parity settings for IP28 */
-#ifndef CONFIG_SGI_IP28
tmp = sgimc->cpuctrl0;
- tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
- SGIMC_CCTRL0_R4KNOCHKPARR);
+#ifndef CONFIG_SGI_IP28
+ tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM;
#endif
+ tmp |= SGIMC_CCTRL0_R4KNOCHKPARR;
sgimc->cpuctrl0 = tmp;
/* Step 3: Setup the MC write buffer depth, this is controlled
@@ -178,7 +178,8 @@ void __init sgimc_init(void)
*/
/* First the basic invariants across all GIO64 implementations. */
- tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
+ tmp = sgimc->giopar & SGIMC_GIOPAR_GFX64; /* keep gfx 64bit settings */
+ tmp |= SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */
if (ip22_is_fullhouse()) {
@@ -193,7 +194,6 @@ void __init sgimc_init(void)
tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */
tmp |= SGIMC_GIOPAR_PLINEEXP1;
tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */
- tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */
}
} else {
/* Guiness specific settings. */
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 5e66213..c7bdfe4 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -26,9 +26,6 @@
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
-unsigned long sgi_gfxaddr;
-EXPORT_SYMBOL_GPL(sgi_gfxaddr);
-
extern void ip22_be_init(void) __init;
void __init plat_mem_setup(void)
@@ -78,22 +75,4 @@ void __init plat_mem_setup(void)
prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
add_preferred_console("arc", 0, NULL);
}
-
-#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
- {
- ULONG *gfxinfo;
- ULONG * (*__vec)(void) = (void *) (long)
- *((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
-
- gfxinfo = __vec();
- sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000
- && gfxinfo[1] <= 0xc0000000)
- ? gfxinfo[1] - 0xa0000000 : 0);
-
- /* newport addresses? */
- if (sgi_gfxaddr = 0x1f0f0000 || sgi_gfxaddr = 0x1f4f0000) {
- conswitchp = &newport_con;
- }
- }
-#endif
}
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 93317b5..628b7ec 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -25,14 +25,13 @@
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm/gio_device.h>
+
#include <video/newport.h>
#include <linux/linux_logo.h>
#include <linux/font.h>
-
-extern unsigned long sgi_gfxaddr;
-
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
/* borrowed from fbcon.c */
@@ -304,12 +303,6 @@ static const char *newport_startup(void)
{
int i;
- if (!sgi_gfxaddr)
- return NULL;
-
- if (!npregs)
- npregs = (struct newport_regs *)/* ioremap cannot fail */
- ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
npregs->cset.config = NPORT_CFG_GD0;
if (newport_wait(npregs))
@@ -743,26 +736,56 @@ const struct consw newport_con = {
.con_save_screen = DUMMY
};
-#ifdef MODULE
-static int __init newport_console_init(void)
+static int newport_probe(struct gio_device *dev,
+ const struct gio_device_id *id)
{
- if (!sgi_gfxaddr)
- return 0;
+ unsigned long newport_addr;
- if (!npregs)
- npregs = (struct newport_regs *)/* ioremap cannot fail */
- ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
+ if (!dev->resource.start)
+ return -EINVAL;
+
+ if (npregs)
+ return -EBUSY; /* we only support one Newport as console */
+
+ newport_addr = dev->resource.start + 0xF0000;
+ if (!request_mem_region(newport_addr, 0x10000, "Newport"))
+ return -ENODEV;
+
+ npregs = (struct newport_regs *)/* ioremap cannot fail */
+ ioremap(newport_addr, sizeof(struct newport_regs));
return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
}
-module_init(newport_console_init);
-static void __exit newport_console_exit(void)
+static void newport_remove(struct gio_device *dev)
{
give_up_console(&newport_con);
iounmap((void *)npregs);
}
+
+static struct gio_device_id newport_ids[] = {
+ { .id = 0x7e },
+ { .id = 0xff }
+};
+
+static struct gio_driver newport_driver = {
+ .name = "newport",
+ .id_table = newport_ids,
+ .probe = newport_probe,
+ .remove = newport_remove,
+};
+
+int __init newport_console_init(void)
+{
+ return gio_register_driver(&newport_driver);
+}
+
+void __exit newport_console_exit(void)
+{
+ gio_unregister_driver(&newport_driver);
+}
+
+module_init(newport_console_init);
module_exit(newport_console_exit);
-#endif
MODULE_LICENSE("GPL");
^ permalink raw reply related
* Re: [PATCH 4/4] fbdev/cirrusfb: Add support for "64 MiB" version
From: Jeff Garzik @ 2011-10-20 17:03 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies, linux-kernel, Ingo Jürgensmann
In-Reply-To: <1319110945-25684-4-git-send-email-geert@linux-m68k.org>
On 10/20/2011 07:42 AM, Geert Uytterhoeven wrote:
> Some Village Tronic Picasso IV graphics cards identify as a 64 MiB Zorro
> device in Zorro III mode.
>
> While the total graphics memory size is the same on such cards, the offset
> of the graphics memory differs. Add a quirk to handle this.
>
> Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD.
>
> Signed-off-by: Geert Uytterhoeven<geert@linux-m68k.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
^ permalink raw reply
* Re: [PATCH 3/4] fbdev/cirrusfb: Add support for Picasso IV in Zorro
From: Jeff Garzik @ 2011-10-20 17:03 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies, linux-kernel, Ingo Jürgensmann
In-Reply-To: <1319110945-25684-3-git-send-email-geert@linux-m68k.org>
On 10/20/2011 07:42 AM, Geert Uytterhoeven wrote:
> In Zorro II mode, the Village Tronic Picasso IV graphics card shows up as
> either 2 or 3 Zorro devices:
> - One for the registers of the Cirrus Logic graphics chip,
> - One for the first bank of 2 MiB of graphics memory,
> - An optional one for the second bank of 2 MiB of graphics memory,
> if there was enough free Zorro II address space.
>
> Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD.
>
> Signed-off-by: Geert Uytterhoeven<geert@linux-m68k.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
^ permalink raw reply
* Re: [PATCH 2/4] fbdev/cirrusfb: Rewrite Zorro graphics card probing
From: Jeff Garzik @ 2011-10-20 17:03 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies, linux-kernel, Ingo Jürgensmann
In-Reply-To: <1319110945-25684-2-git-send-email-geert@linux-m68k.org>
On 10/20/2011 07:42 AM, Geert Uytterhoeven wrote:
> As indicated by commit a7f4d00a82feb5b311f765bf9522bc55bee0684f ("zorro:
> Defer device_register() until all devices have been identified"), cirrusfb
> crashes if zorro_find_device() cannot find an expected device.
>
> Rewrite the Zorro device probe code to make it more robust, easier to
> understand, and more extensible.
>
> Other logical changes:
> - For cards that show up as 2 Zorro devices, autoprobe graphics memory
> sizes based on the size of the Zorro device containing the graphics
> memory.
> Acording to the NetBSD sources, this is safe.
>
> Signed-off-by: Geert Uytterhoeven<geert@linux-m68k.org>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
^ permalink raw reply
* [PATCH 4/4] fbdev/cirrusfb: Add support for "64 MiB" version of Picasso IV
From: Geert Uytterhoeven @ 2011-10-20 11:42 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies
Cc: linux-kernel, Ingo Jürgensmann, Geert Uytterhoeven
In-Reply-To: <1319110945-25684-1-git-send-email-geert@linux-m68k.org>
Some Village Tronic Picasso IV graphics cards identify as a 64 MiB Zorro
device in Zorro III mode.
While the total graphics memory size is the same on such cards, the offset
of the graphics memory differs. Add a quirk to handle this.
Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
--
Untested, due to lack of hardware
---
drivers/video/cirrusfb.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 816433f..6ea505c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -314,7 +314,7 @@ static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
.type = BT_PICASSO4,
.regoffset = 0x00600000,
.ramsize = 4 * MB_,
- .ramoffset = 0x01000000,
+ .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */
};
static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
@@ -2259,6 +2259,10 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
ramsize = zcl->ramsize;
if (ramsize) {
rambase = zorro_resource_start(z) + zcl->ramoffset;
+ if (zorro_resource_len(z) = 64 * MB_) {
+ /* Quirk for 64 MiB Picasso IV */
+ rambase += zcl->ramoffset;
+ }
} else {
struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
if (!ram || !zorro_resource_len(ram)) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/4] fbdev/cirrusfb: Add support for Picasso IV in Zorro II mode
From: Geert Uytterhoeven @ 2011-10-20 11:42 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies
Cc: linux-kernel, Ingo Jürgensmann, Geert Uytterhoeven
In-Reply-To: <1319110945-25684-1-git-send-email-geert@linux-m68k.org>
In Zorro II mode, the Village Tronic Picasso IV graphics card shows up as
either 2 or 3 Zorro devices:
- One for the registers of the Cirrus Logic graphics chip,
- One for the first bank of 2 MiB of graphics memory,
- An optional one for the second bank of 2 MiB of graphics memory,
if there was enough free Zorro II address space.
Based on src/sys/arch/amiga/dev/grf_cl.c from NetBSD.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
--
Untested, due to lack of hardware
---
drivers/video/cirrusfb.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 357139a..816433f 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -287,6 +287,7 @@ struct zorrocl {
/* If zero, use autoprobe on RAM device */
u32 ramoffset; /* Offset of video RAM in first Zorro device */
zorro_id ramid; /* Zorro ID of RAM device */
+ zorro_id ramid2; /* Zorro ID of optional second RAM device */
};
static const struct zorrocl zcl_sd64 __devinitconst = {
@@ -316,6 +317,13 @@ static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
.ramoffset = 0x01000000,
};
+static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
+ .type = BT_PICASSO4,
+ .regoffset = 0x10000,
+ .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
+ .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
+};
+
static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
{
@@ -333,6 +341,9 @@ static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
}, {
.id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
.driver_data = (unsigned long)&zcl_picasso4_z3,
+ }, {
+ .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
+ .driver_data = (unsigned long)&zcl_picasso4_z2,
},
{ 0 }
};
@@ -2257,6 +2268,16 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
}
rambase = zorro_resource_start(ram);
ramsize = zorro_resource_len(ram);
+ if (zcl->ramid2 &&
+ (ram = zorro_find_device(zcl->ramid2, NULL))) {
+ if (zorro_resource_start(ram) != rambase + ramsize) {
+ dev_warn(info->device,
+ "Skipping non-contiguous RAM at %pR\n",
+ &ram->resource);
+ } else {
+ ramsize += zorro_resource_len(ram);
+ }
+ }
}
dev_info(info->device,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/4] fbdev/cirrusfb: Rewrite Zorro graphics card probing
From: Geert Uytterhoeven @ 2011-10-20 11:42 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies
Cc: linux-kernel, Ingo Jürgensmann, Geert Uytterhoeven
In-Reply-To: <1319110945-25684-1-git-send-email-geert@linux-m68k.org>
As indicated by commit a7f4d00a82feb5b311f765bf9522bc55bee0684f ("zorro:
Defer device_register() until all devices have been identified"), cirrusfb
crashes if zorro_find_device() cannot find an expected device.
Rewrite the Zorro device probe code to make it more robust, easier to
understand, and more extensible.
Other logical changes:
- For cards that show up as 2 Zorro devices, autoprobe graphics memory
sizes based on the size of the Zorro device containing the graphics
memory.
Acording to the NetBSD sources, this is safe.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
--
Untested, due to lack of hardware
---
drivers/video/cirrusfb.c | 241 ++++++++++++++++++++++-----------------------
1 files changed, 118 insertions(+), 123 deletions(-)
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 6df7c54..357139a 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -280,52 +280,63 @@ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
#endif /* CONFIG_PCI */
#ifdef CONFIG_ZORRO
-static const struct zorro_device_id cirrusfb_zorro_table[] = {
+struct zorrocl {
+ enum cirrus_board type; /* Board type */
+ u32 regoffset; /* Offset of registers in first Zorro device */
+ u32 ramsize; /* Size of video RAM in first Zorro device */
+ /* If zero, use autoprobe on RAM device */
+ u32 ramoffset; /* Offset of video RAM in first Zorro device */
+ zorro_id ramid; /* Zorro ID of RAM device */
+};
+
+static const struct zorrocl zcl_sd64 __devinitconst = {
+ .type = BT_SD64,
+ .ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
+};
+
+static const struct zorrocl zcl_piccolo __devinitconst = {
+ .type = BT_PICCOLO,
+ .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
+};
+
+static const struct zorrocl zcl_picasso __devinitconst = {
+ .type = BT_PICASSO,
+ .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
+};
+
+static const struct zorrocl zcl_spectrum __devinitconst = {
+ .type = BT_SPECTRUM,
+ .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
+};
+
+static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
+ .type = BT_PICASSO4,
+ .regoffset = 0x00600000,
+ .ramsize = 4 * MB_,
+ .ramoffset = 0x01000000,
+};
+
+
+static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
{
- .id = ZORRO_PROD_HELFRICH_SD64_RAM,
- .driver_data = BT_SD64,
+ .id = ZORRO_PROD_HELFRICH_SD64_REG,
+ .driver_data = (unsigned long)&zcl_sd64,
}, {
- .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
- .driver_data = BT_PICCOLO,
+ .id = ZORRO_PROD_HELFRICH_PICCOLO_REG,
+ .driver_data = (unsigned long)&zcl_piccolo,
}, {
- .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
- .driver_data = BT_PICASSO,
+ .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
+ .driver_data = (unsigned long)&zcl_picasso,
}, {
- .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
- .driver_data = BT_SPECTRUM,
+ .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
+ .driver_data = (unsigned long)&zcl_spectrum,
}, {
.id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
- .driver_data = BT_PICASSO4,
+ .driver_data = (unsigned long)&zcl_picasso4_z3,
},
{ 0 }
};
MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
-
-static const struct {
- zorro_id id2;
- unsigned long size;
-} cirrusfb_zorro_table2[] = {
- [BT_SD64] = {
- .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
- .size = 0x400000
- },
- [BT_PICCOLO] = {
- .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
- .size = 0x200000
- },
- [BT_PICASSO] = {
- .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
- .size = 0x200000
- },
- [BT_SPECTRUM] = {
- .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
- .size = 0x200000
- },
- [BT_PICASSO4] = {
- .id2 = 0,
- .size = 0x400000
- }
-};
#endif /* CONFIG_ZORRO */
#ifdef CIRRUSFB_DEBUG
@@ -1956,16 +1967,12 @@ static void cirrusfb_zorro_unmap(struct fb_info *info)
struct cirrusfb_info *cinfo = info->par;
struct zorro_dev *zdev = to_zorro_dev(info->device);
- zorro_release_device(zdev);
-
- if (cinfo->btype = BT_PICASSO4) {
- cinfo->regbase -= 0x600000;
- iounmap((void *)cinfo->regbase);
+ if (info->fix.smem_start > 16 * MB_)
iounmap(info->screen_base);
- } else {
- if (zorro_resource_start(zdev) > 0x01000000)
- iounmap(info->screen_base);
- }
+ if (info->fix.mmio_start > 16 * MB_)
+ iounmap(cinfo->regbase);
+
+ zorro_release_device(zdev);
}
#endif /* CONFIG_ZORRO */
@@ -2222,115 +2229,102 @@ static struct pci_driver cirrusfb_pci_driver = {
static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
const struct zorro_device_id *ent)
{
- struct cirrusfb_info *cinfo;
struct fb_info *info;
+ int error;
+ const struct zorrocl *zcl;
enum cirrus_board btype;
- struct zorro_dev *z2 = NULL;
- unsigned long board_addr, board_size, size;
- int ret;
-
- btype = ent->driver_data;
- if (cirrusfb_zorro_table2[btype].id2)
- z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
- size = cirrusfb_zorro_table2[btype].size;
+ unsigned long regbase, ramsize, rambase;
+ struct cirrusfb_info *cinfo;
info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
if (!info) {
printk(KERN_ERR "cirrusfb: could not allocate memory\n");
- ret = -ENOMEM;
- goto err_out;
+ return -ENOMEM;
}
- dev_info(info->device, "%s board detected\n",
- cirrusfb_board_info[btype].name);
-
- cinfo = info->par;
- cinfo->btype = btype;
-
- assert(z);
- assert(btype != BT_NONE);
+ zcl = (const struct zorrocl *)ent->driver_data;
+ btype = zcl->type;
+ regbase = zorro_resource_start(z) + zcl->regoffset;
+ ramsize = zcl->ramsize;
+ if (ramsize) {
+ rambase = zorro_resource_start(z) + zcl->ramoffset;
+ } else {
+ struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
+ if (!ram || !zorro_resource_len(ram)) {
+ dev_err(info->device, "No video RAM found\n");
+ error = -ENODEV;
+ goto err_release_fb;
+ }
+ rambase = zorro_resource_start(ram);
+ ramsize = zorro_resource_len(ram);
+ }
- board_addr = zorro_resource_start(z);
- board_size = zorro_resource_len(z);
- info->screen_size = size;
+ dev_info(info->device,
+ "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
+ cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
+ rambase);
if (!zorro_request_device(z, "cirrusfb")) {
- dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
- board_addr);
- ret = -EBUSY;
+ dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
+ error = -EBUSY;
goto err_release_fb;
}
- ret = -EIO;
-
- if (btype = BT_PICASSO4) {
- dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
-
- /* To be precise, for the P4 this is not the */
- /* begin of the board, but the begin of RAM. */
- /* for P4, map in its address space in 2 chunks (### TEST! ) */
- /* (note the ugly hardcoded 16M number) */
- cinfo->regbase = ioremap(board_addr, 16777216);
- if (!cinfo->regbase)
- goto err_release_region;
-
- dev_dbg(info->device, "Virtual address for board set to: $%p\n",
- cinfo->regbase);
- cinfo->regbase += 0x600000;
- info->fix.mmio_start = board_addr + 0x600000;
-
- info->fix.smem_start = board_addr + 16777216;
- info->screen_base = ioremap(info->fix.smem_start, 16777216);
- if (!info->screen_base)
- goto err_unmap_regbase;
- } else {
- dev_info(info->device, " REG at $%lx\n",
- (unsigned long) z2->resource.start);
-
- info->fix.smem_start = board_addr;
- if (board_addr > 0x01000000)
- info->screen_base = ioremap(board_addr, board_size);
- else
- info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
- if (!info->screen_base)
- goto err_release_region;
+ cinfo = info->par;
+ cinfo->btype = btype;
- /* set address for REG area of board */
- cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
- info->fix.mmio_start = z2->resource.start;
+ info->fix.mmio_start = regbase;
+ cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
+ : (caddr_t)ZTWO_VADDR(regbase);
+ if (!cinfo->regbase) {
+ dev_err(info->device, "Cannot map registers\n");
+ error = -EIO;
+ goto err_release_dev;
+ }
- dev_dbg(info->device, "Virtual address for board set to: $%p\n",
- cinfo->regbase);
+ info->fix.smem_start = rambase;
+ info->screen_size = ramsize;
+ info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
+ : (caddr_t)ZTWO_VADDR(rambase);
+ if (!info->screen_base) {
+ dev_err(info->device, "Cannot map video RAM\n");
+ error = -EIO;
+ goto err_unmap_reg;
}
+
cinfo->unmap = cirrusfb_zorro_unmap;
dev_info(info->device,
- "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
- board_size / MB_, board_addr);
-
- zorro_set_drvdata(z, info);
+ "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
+ ramsize / MB_, rambase);
/* MCLK select etc. */
if (cirrusfb_board_info[btype].init_sr1f)
vga_wseq(cinfo->regbase, CL_SEQR1F,
cirrusfb_board_info[btype].sr1f);
- ret = cirrusfb_register(info);
- if (!ret)
- return 0;
+ error = cirrusfb_register(info);
+ if (error) {
+ dev_err(info->device, "Failed to register device, error %d\n",
+ error);
+ goto err_unmap_ram;
+ }
- if (btype = BT_PICASSO4 || board_addr > 0x01000000)
+ zorro_set_drvdata(z, info);
+ return 0;
+
+err_unmap_ram:
+ if (rambase > 16 * MB_)
iounmap(info->screen_base);
-err_unmap_regbase:
- if (btype = BT_PICASSO4)
- iounmap(cinfo->regbase - 0x600000);
-err_release_region:
- release_region(board_addr, board_size);
+err_unmap_reg:
+ if (regbase > 16 * MB_)
+ iounmap(cinfo->regbase);
+err_release_dev:
+ zorro_release_device(z);
err_release_fb:
framebuffer_release(info);
-err_out:
- return ret;
+ return error;
}
void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
@@ -2338,6 +2332,7 @@ void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
struct fb_info *info = zorro_get_drvdata(z);
cirrusfb_cleanup(info);
+ zorro_set_drvdata(z, NULL);
}
static struct zorro_driver cirrusfb_zorro_driver = {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/4] zorro: Rename Picasso IV Z2 "MEM" to "RAM" for consistency
From: Geert Uytterhoeven @ 2011-10-20 11:42 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev, linux-m68k,
Christian T. Steigies
Cc: linux-kernel, Ingo Jürgensmann, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
include/linux/zorro_ids.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/zorro_ids.h b/include/linux/zorro_ids.h
index 7e74908..74bc53b 100644
--- a/include/linux/zorro_ids.h
+++ b/include/linux/zorro_ids.h
@@ -360,8 +360,8 @@
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0)
-#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0)
-#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0)
--
1.7.0.4
^ permalink raw reply related
* Re:
From: Wayne Johnson @ 2011-10-20 0:40 UTC (permalink / raw)
To: linux-fbdev
--1006711009-1319071212=:21299
Content-transfer-encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
--1006711009-1319071212=:21299
Content-Disposition: attachment; filename="bn1840572.pdf"
Content-Transfer-Encoding: base64
Content-Type: application/pdf; charset=UTF-8; name="bn1840572.pdf"
Content-Length: 32299
JVBERi0xLjQKJf////8KMjMgMCBvYmoKPDwvTGVuZ3RoIDI0OTgKL1N1YnR5cGUgL1hNTAovVHlw
ZSAvTWV0YWRhdGEKPj4Kc3RyZWFtCjw/eHBhY2tldCBiZWdpbj0n77u/JyBpZD0nVzVNME1wQ2Vo
aUh6cmVTek5UY3prYzlkJz8+Cjx4OnhtcG1ldGEgeDp4bXB0az0iMy4xLTcwMSIgeG1sbnM6eD0i
YWRvYmU6bnM6bWV0YS8iPgogIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcv
MTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91
dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICA8eG1w
OkNyZWF0ZURhdGU+MjAxMS0xMC0yMFQwMDoxOTozOFo8L3htcDpDcmVhdGVEYXRlPgogICAgICA8
eG1wOkNyZWF0b3JUb29sPk5pdHJvIFBERiBQcm9mZXNzaW9uYWwgICg2LCAxLCAwLCAzMCk8L3ht
cDpDcmVhdG9yVG9vbD4KICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTEtMTAtMjBUMDA6MTk6Mzha
PC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxMS0xMC0yMFQwMDox
OTozOFo8L3htcDpNZXRhZGF0YURhdGU+CiAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgIDxyZGY6
RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxl
bWVudHMvMS4xLyI+CiAgICAgIDxkYzpmb3JtYXQ+YXBwbGljYXRpb24vcGRmPC9kYzpmb3JtYXQ+
CiAgICAgIDxkYzpjcmVhdG9yPgogICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgPHJkZjpsaT48
L3JkZjpsaT4KICAgICAgICA8L3JkZjpTZXE+CiAgICAgIDwvZGM6Y3JlYXRvcj4KICAgICAgPGRj
OnRpdGxlPgogICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1k
ZWZhdWx0Ij48L3JkZjpsaT4KICAgICAgICA8L3JkZjpBbHQ+CiAgICAgIDwvZGM6dGl0bGU+CiAg
ICAgIDxkYzpkZXNjcmlwdGlvbj4KICAgICAgICA8cmRmOkFsdD4KICAgICAgICAgIDxyZGY6bGkg
eG1sOmxhbmc9IngtZGVmYXVsdCIvPgogICAgICAgIDwvcmRmOkFsdD4KICAgICAgPC9kYzpkZXNj
cmlwdGlvbj4KICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6
YWJvdXQ9IiIgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIj4KICAgICAg
PHBkZjpLZXl3b3Jkcz48L3BkZjpLZXl3b3Jkcz4KICAgICAgPHBkZjpQcm9kdWNlcj5OaXRybyBQ
REYgUHJvZmVzc2lvbmFsICAoNiwgMSwgMCwgMzApPC9wZGY6UHJvZHVjZXI+CiAgICA8L3JkZjpE
ZXNjcmlwdGlvbj4KICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1N
PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgPHhtcE1NOkRvY3VtZW50
SUQ+dXVpZDo3MWZhYTZmNS0zNjY4LTQ0ODYtYWE4My05M2MyYTc3MDMyMWY8L3htcE1NOkRvY3Vt
ZW50SUQ+CiAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgog
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQo8P3hwYWNr
ZXQgZW5kPSd3Jz8+CmVuZHN0cmVhbQplbmRvYmoKMjIgMCBvYmoKPDwvQ3JlYXRpb25EYXRlIChE
OjIwMTExMDIwMDAxOTM4WikKL0NyZWF0b3IgKP7/AE4AaQB0AHIAbwAgAFAARABGACAAUAByAG8A
ZgBlAHMAcwBpAG8AbgBhAGwAIAAgAFwoADYALAAgADEALAAgADAALAAgADMAMABcKSkKL01vZERh
dGUgKEQ6MjAxMTEwMjAwMDE5MzhaKQovUHJvZHVjZXIgKP7/AE4AaQB0AHIAbwAgAFAARABGACAA
UAByAG8AZgBlAHMAcwBpAG8AbgBhAGwAIAAgAFwoADYALAAgADEALAAgADAALAAgADMAMABcKSkK
Pj4KZW5kb2JqCjIxIDAgb2JqCjw8L0RlY29kZVBhcm1zIFtudWxsIF0KL0ZpbHRlciBbL0ZsYXRl
RGVjb2RlIF0KL0xlbmd0aCAzNgo+PgpzdHJlYW0KeNpiAAAAAP//YmBgaGBm0OI4IMCgcKIjAQAA
AP//AwAR0wNWCmVuZHN0cmVhbQplbmRvYmoKMjAgMCBvYmoKPDwvRGVjb2RlUGFybXMgW251bGwg
XQovRmlsdGVyIFsvRmxhdGVEZWNvZGUgXQovTGVuZ3RoIDcwCj4+CnN0cmVhbQp42mJgoBAw4pFj
YmDGKs4CxKxAzIYkxg6lORg4sejgwusGbiQ2DwMvmAYAAAD//+KD8vmhtABchSCDEAAAAP//AwAi
JQCsCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKPDwvRGVjb2RlUGFybXMgW251bGwgXQovRmls
dGVyIFsvRmxhdGVEZWNvZGUgXQovTGVuZ3RoIDg3MzYKL0xlbmd0aDEgMAo+PgpzdHJlYW0KeNos
Un1M1VUYft5zfueC48IfzQ+4agE2J1Jzslm5XOHHbBWu/Mz83BWRi3m9lyvGzRgCptQaLd2VBYoO
0YljpmNXJyw/p+Yf3aBsfTgHQluCa3nX5pgav9NDa8/e/X7POed93+d9zqmI7CzBONRAo7D4w4ps
7+Cz9wAcBjwrtoRLg95N0WX8TzK2l277aEvl4pa1QPoGYPzZQIl/893yUAaQy8BLAS743boU8kXk
zweCFdFYauur5AHyt7aFiv3BvMlTyTvJZwT90XCtM+yQ3yHPDkdKwrvW9L1N/gRIu2S6kcXwmZPI
cqYjE7D3GUNjX7fMDo3tj33VA2Zf+D+AdpyWMpzGZVyTJLPOoAtx3MIkLOJcVYihHh6s4cpnWEYY
rscky8YxC630oRUJnn0P1ejGRMm0w9iNvfo2s/YiHbmYj3cRQoMU2Z1Yh35nD15GEbYjLDV2tf3C
HrDHcQJd+pYdRRp8KCYS9i/zq72LF5lxEE3olwPjzqGQXWp4sgURNOv1jthS+4QKclBJDQ6WICFX
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
7JAJSchWPUKE+AoRYjubAbrHIan1iLluDhGTBp8AXCPoOFNFxJ4Rm89Nxb/z35hyiDo+7Z/OYktL
EsEdtdxWNnwKKrO5pAdfCn8PgsMAhUUtMfZhHhtiUn1PcMxjlo25MraQptQtoYkYTTIlNBadLCYp
/QUAAP//AwAmfYOqCmVuZHN0cmVhbQplbmRvYmoKMTggMCBvYmoKWzMyIDMyIDI3NyA0NiA0NiAy
NzcgNDcgNDcgMjc3IDU4IDU4IDI3NyA2MCA2MCA1ODMgNjIgNjIgNTgzIDY4IDY4IDcyMiA3MiA3
MiA3MjIgNzMgNzMgMjc3IDgzIDgzIDY2NiA5OCA5OCA1NTYgMTA0IDEwNCA1NTYgMTA1IDEwNSAy
MjIgMTA4IDEwOCAyMjIgMTEyIDExMiA1NTYgMTE2IDExNiAyNzcgMTIxIDEyMSA1MDAgMTIyIDEy
MiA1MDAgXQplbmRvYmoKMTcgMCBvYmoKPDwvRGVjb2RlUGFybXMgW251bGwgXQovRmlsdGVyIFsv
RmxhdGVEZWNvZGUgXQovTGVuZ3RoIDIyCj4+CnN0cmVhbQp42mIAAAAA//9iAAAAAP//AwAAAgAB
CmVuZHN0cmVhbQplbmRvYmoKMTYgMCBvYmoKPDwvRGVjb2RlUGFybXMgW251bGwgXQovRmlsdGVy
IFsvRmxhdGVEZWNvZGUgXQovTGVuZ3RoIDQ0NjUKL0xlbmd0aDEgMAo+PgpzdHJlYW0KeNosUn1M
1VUYfp5zDje6czjdqBhBlLWMSxtNMnKXRaumznDN7lVkNfkQuW1cuRkQzg8Iq63VCqWPO3H+EfnH
lQ8NbK25VZvoYnLVgoDmH7Q+VyzIVuuf7nl7RX9n53f2vOf9Os/ztu5pa8St6IJFZUN7a9H6FwKT
AI4Bt7y1K9EUTz6cuwnIXg1kzTY1790Vnl84DeSoC3bHGut27jg6qCBnt+K1MTX0ZU4GFH+k+N5Y
vLWjCWmn+CvFrrmloe6R65HImbiO43UdiSOBZVbxFcVFiT2NiZHe1ArFfwLBj92v6nQE+XoW2noU
AjJ3c//gD+qd3vuMiJnR6MjNfeOL6Hpv6R9h1Y0TOzGFOA7jA7Wt4SWkUInlap+CJViNMHrxMr5F
VK6p9W70YxEleBQx8ViBTngeQD8NjEaVYxKN6DFhG3LzIIpZagfYjQc1SwTv43Zc1ozFElQ8agpM
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
EeXa34AqWbLLpeaH5Mw/aWc2hiQQVax2dtY7X2b8GG88qKWk3/TzRXZ7K2Hj8tA8/HCwvvdFzBn8
cmxOmtmcPsAzqWU/j772s181mX2myd+aPMI7R1/3hbFrbDuiMHZIyX5RGRq7zjGtV4ZCTjiwcF0U
wElpDiziwHrB1Y0d4jZJjbm65uozXN7ijsg5f2JammnNMoNZZqCZQcksjBk+xSw9AtcMX3p8xdTf
wGzOZabuZtht/qexAjw2ynsJlUa+7YQofnZzeW5mwzPLKqDHRmXV9Mk/+3ZOOgj/sJEdiqxnCyv3
ktf2LCGzZ4scEueknyftUPz22p5jB0Leu0EjnQl3/RQubwRznAXkrEGx3HSOOSWzS7FSipVSLLft
6lg66zEt30FX4re41vfGcgUT2K9y2d1YuzjQ2bzPzavqwyKwO1jG0mQFy9z3KGTa6mx1yIRvGZlW
qQIuTebVPq8+sLvStIbL63YXTOe7wK5UOXljV0pFp+pUkdZdRTEKPSZQoCLAK+is6P+3j7gb0958
g/JD79ELSskI9DNVMZC3iIaJ8+dZjJ6Zmk4CUC8bZUYTxoLuVMyQIjAu00YxNKIboJP8BwAA//+C
iAEAAAD//wMADTdxlQplbmRzdHJlYW0KZW5kb2JqCjE1IDAgb2JqCltdCmVuZG9iagoxNCAwIG9i
ago8PC9CaXRzUGVyQ29tcG9uZW50IDEKL0NvbG9yU3BhY2UgMTIgMCBSCi9EZWNvZGVQYXJtcyBb
bnVsbCBdCi9GaWx0ZXIgWy9GbGF0ZURlY29kZSBdCi9IZWlnaHQgMTI3Ci9MZW5ndGggMzc1Nwov
U3VidHlwZSAvSW1hZ2UKL1R5cGUgL1hPYmplY3QKL1dpZHRoIDcxNwo+PgpzdHJlYW0KeNr6DwAA
AP//7Mw9TsMwFADgkbErEhK5BRSh0mtwAyZkoQxBCW0HpDL2ApV6AiSkDB7SKiNjttLiRIYFljqv
U15VxzFOStUODGFg41nvx7bep/8oVvpf3pPztqmj4vtaQFlDk4lJUk2b6JmzDVJLVrxcM7LcyWWo
SvtZ7tWSpZGL0sHK49sPWT7vjEIXejfXk5O1ypvX0Ph4fodx6x5RDMi4dfPU1X1m3bqHd6fWkll9
3V/mJ+N2Y7Dyjpn1UEeerGWBj0NMz2OwEwa4cIgdi6Cj3Rk4Zy/elMMluNqN7KkdI8FmOku9GvLS
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
c3RyZWFtCmVuZG9iagoxMiAwIG9iagpbL0luZGV4ZWQgL0RldmljZVJHQiAxIDEzIDAgUiBdCmVu
ZG9iagoxMSAwIG9iago8PC9CYXNlRm9udCAvQXJpYWwKL0Rlc2NlbmRhbnRGb250cyBbMTAgMCBS
IF0KL0VuY29kaW5nIC9JZGVudGl0eS1ICi9OYW1lIC9GMgovU3VidHlwZSAvVHlwZTAKL1RvVW5p
Y29kZSAvSWRlbnRpdHktSAovVHlwZSAvRm9udAo+PgplbmRvYmoKMTAgMCBvYmoKPDwvQmFzZUZv
bnQgL0FyaWFsCi9DSURTeXN0ZW1JbmZvIDw8L09yZGVyaW5nIChJZGVudGl0eSkKL1JlZ2lzdHJ5
IChBZG9iZSkKL1N1cHBsZW1lbnQgMQo+PgovQ0lEVG9HSURNYXAgMjAgMCBSCi9Gb250RGVzY3Jp
cHRvciA5IDAgUgovU3VidHlwZSAvQ0lERm9udFR5cGUyCi9UeXBlIC9Gb250Ci9XIDE4IDAgUgo+
PgplbmRvYmoKOSAwIG9iago8PC9Bc2NlbnQgMTAwNQovQ0lEU2V0IDIxIDAgUgovQ2FwSGVpZ2h0
IDAKL0Rlc2NlbnQgLTMyNAovRmxhZ3MgMzIKL0ZvbnRCQm94IFstNjY0IC0zMjQgMjAwMCAxMDA1
IF0KL0ZvbnRGaWxlMiAxOSAwIFIKL0ZvbnROYW1lIC9BcmlhbAovSXRhbGljQW5nbGUgMAovU3Rl
bVYgMAovVHlwZSAvRm9udERlc2NyaXB0b3IKPj4KZW5kb2JqCjggMCBvYmoKPDwvRGVjb2RlUGFy
bXMgW251bGwgXQovRmlsdGVyIFsvRmxhdGVEZWNvZGUgXQovTGVuZ3RoIDMxMQo+PgpzdHJlYW0K
eNrMUT1PAzEMvTm/wmNvuNR2YidBiAGVj7JVnMSAWEBQkHpAERKiv54ktNIhYGNAUV7iF9vvyUE4
MQRLszaLvNcmsEXnnI8QKNqkicXDMKKVnSVUjQlWRgktInt0v/KjNitzAY9ZQ1woFIoA5pXERmVR
Dz+q3AxmOh+WBLOn7HFRfaIlRhSFN4PVfO6TBREJlNhydF4IQsLcWckxvNxW7cV/Sk/JRkJJCv3G
HPZmesyQbPISPEF/l7+lTIdGU5EQrCYKgaEfzOWkOWhdgS4WvOrPzFH/Fy6IbIoceewiRetYhPS7
i/u2k0nz2nZuh8+V2av36RZ10lxX+qGlXZ6tuCrEext3uZ/Vs+a02RTyvO0ox/P6BjnQ0blfarfw
dQAfAAAA//8iPtYCwakfAAAA//8DAHqml/0KZW5kc3RyZWFtCmVuZG9iago3IDAgb2JqCjw8L0Jh
c2VGb250IC9Db3VyaWVyTmV3Ci9EZXNjZW5kYW50Rm9udHMgWzYgMCBSIF0KL0VuY29kaW5nIC9J
ZGVudGl0eS1ICi9OYW1lIC9GMQovU3VidHlwZSAvVHlwZTAKL1RvVW5pY29kZSAvSWRlbnRpdHkt
SAovVHlwZSAvRm9udAo+PgplbmRvYmoKNiAwIG9iago8PC9CYXNlRm9udCAvQ291cmllck5ldwov
Q0lEU3lzdGVtSW5mbyA8PC9PcmRlcmluZyAoSWRlbnRpdHkpCi9SZWdpc3RyeSAoQWRvYmUpCi9T
dXBwbGVtZW50IDEKPj4KL0NJRFRvR0lETWFwIDE3IDAgUgovRm9udERlc2NyaXB0b3IgNSAwIFIK
L1N1YnR5cGUgL0NJREZvbnRUeXBlMgovVHlwZSAvRm9udAovVyAxNSAwIFIKPj4KZW5kb2JqCjUg
MCBvYmoKPDwvQXNjZW50IDEwMjAKL0NhcEhlaWdodCAwCi9EZXNjZW50IC02NzkKL0ZsYWdzIDMy
Ci9Gb250QkJveCBbLTEyMSAtNjc5IDYyMiAxMDIwIF0KL0ZvbnRGaWxlMiAxNiAwIFIKL0ZvbnRO
YW1lIC9Db3VyaWVyTmV3Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViAwCi9UeXBlIC9Gb250RGVzY3Jp
cHRvcgo+PgplbmRvYmoKNCAwIG9iago8PC9Db250ZW50cyA4IDAgUgovTWVkaWFCb3ggWzAgMCA2
MTIuMjgzNDY1IDc5MC44NjYxNDIgXQovUGFyZW50IDEgMCBSCi9UeXBlIC9QYWdlCj4+CmVuZG9i
agozIDAgb2JqCjw8L0NvbG9yU3BhY2UgPDwvQ1MxIDEyIDAgUgo+PgovRm9udCA8PC9GMSA3IDAg
UgovRjIgMTEgMCBSCj4+Ci9YT2JqZWN0IDw8L0ltZzEgMTQgMCBSCj4+Cj4+CmVuZG9iagoyIDAg
b2JqCjw8L01ldGFkYXRhIDIzIDAgUgovT3BlbkFjdGlvbiBbNCAwIFIgL1hZWiAtMzI3NjggLTMy
NzY4IDEgXQovUGFnZUxheW91dCAvU2luZ2xlUGFnZQovUGFnZU1vZGUgL1VzZU5vbmUKL1BhZ2Vz
IDEgMCBSCi9UeXBlIC9DYXRhbG9nCi9WaWV3ZXJQcmVmZXJlbmNlcyA8PC9DZW50ZXJXaW5kb3cg
ZmFsc2UKL0RpcmVjdGlvbiAvTDJSCi9EaXNwbGF5RG9jVGl0bGUgZmFsc2UKL0ZpdFdpbmRvdyBm
YWxzZQovSGlkZU1lbnViYXIgZmFsc2UKL0hpZGVUb29sYmFyIGZhbHNlCi9IaWRlV2luZG93VUkg
ZmFsc2UKL05vbkZ1bGxTY3JlZW5QYWdlTW9kZSAvVXNlTm9uZQovUHJpbnRBcmVhIC9Dcm9wQm94
Ci9QcmludENsaXAgL0Nyb3BCb3gKL1ByaW50U2NhbGluZyAvQXBwRGVmYXVsdAovVmlld0FyZWEg
L0Nyb3BCb3gKL1ZpZXdDbGlwIC9Dcm9wQm94Cj4+Cj4+CmVuZG9iagoxIDAgb2JqCjw8L0NvdW50
IDEKL0tpZHMgWzQgMCBSIF0KL01lZGlhQm94IFswIDAgNTk1LjI3NTU5MSA4NDEuODg5NzY0IF0K
L1Jlc291cmNlcyAzIDAgUgovVHlwZSAvUGFnZXMKPj4KZW5kb2JqCnhyZWYNCjAgMjQNCjAwMDAw
MDAwMDAgNjU1MzUgZg0KMDAwMDAyMzE4MyAwMDAwMCBuDQowMDAwMDIyNzM5IDAwMDAwIG4NCjAw
MDAwMjI2MzEgMDAwMDAgbg0KMDAwMDAyMjUzMCAwMDAwMCBuDQowMDAwMDIyMzQyIDAwMDAwIG4N
CjAwMDAwMjIxNDAgMDAwMDAgbg0KMDAwMDAyMTk4OSAwMDAwMCBuDQowMDAwMDIxNTgzIDAwMDAw
IG4NCjAwMDAwMjEzODQgMDAwMDAgbg0KMDAwMDAyMTE4NiAwMDAwMCBuDQowMDAwMDIxMDM4IDAw
MDAwIG4NCjAwMDAwMjA5OTAgMDAwMDAgbg0KMDAwMDAyMDg2OSAwMDAwMCBuDQowMDAwMDE2OTIy
IDAwMDAwIG4NCjAwMDAwMTY5MDMgMDAwMDAgbg0KMDAwMDAxMjMzMCAwMDAwMCBuDQowMDAwMDEy
MjEzIDAwMDAwIG4NCjAwMDAwMTIwMDAgMDAwMDAgbg0KMDAwMDAwMzE1NiAwMDAwMCBuDQowMDAw
MDAyOTkxIDAwMDAwIG4NCjAwMDAwMDI4NjAgMDAwMDAgbg0KMDAwMDAwMjU5NSAwMDAwMCBuDQow
MDAwMDAwMDE1IDAwMDAwIG4NCnRyYWlsZXINCjw8L0lEIFsoFsP4ubwbSGi6mi5Cr0tFZUVlKSAo
eOBy/frUTDeS0erDJi6kg6SDKSBdCi9JbmZvIDIyIDAgUgovUm9vdCAyIDAgUgovU2l6ZSAyNAo+
Pg0Kc3RhcnR4cmVmDQoyMzI5Ng0KJSVFT0Y--1006711009-1319071212=:21299--
^ permalink raw reply
* RE: [RFC PATCH 0/3] fbdev driver for dm644x
From: Hadli, Manjunath @ 2011-10-19 11:40 UTC (permalink / raw)
To: linux-fbdev
Hello,
Can some one review this patches, so that I can issue a pull request.
Thanks.
Regards,
--Manju
On Mon, Sep 26, 2011 at 19:05:06, Hadli, Manjunath wrote:
> This patch series adds an fbdev driver for Texas Instruments Davinci SoC.The display subsystem consists of OSD and VENC, with OSD supporting 2 RGb planes and
> 2 video planes.
> http://focus.ti.com/general/docs/lit/
> getliterature.tsp?literatureNumber=sprue37d&fileType=pdf
>
> A good amount of the OSD and VENC enabling code is present in the kernel, and this patch series adds the fbdev interface.
>
> The fbdev driver exports 4 nodes representing each plane to the user - from fb0 to fb3.
>
> Manjunath Hadli (3):
> davinci: vpbe: enable vpbe for fbdev addition
> davinci: vpbe: add fbdev driver for dm644x
> davinci: vpbe: add build infrastructure for fbdev driver
>
> drivers/media/video/davinci/Kconfig | 13 +
> drivers/media/video/davinci/Makefile | 1 +
> drivers/media/video/davinci/vpbe_display.c | 6 +
> drivers/media/video/davinci/vpbe_fb.c | 2537 +++++++++++++++++++++++++++
> drivers/media/video/davinci/vpbe_fb.h | 66 +
> drivers/media/video/davinci/vpbe_fb_ioctl.h | 159 ++
> drivers/media/video/davinci/vpbe_osd.c | 793 +++++++++-
> drivers/media/video/davinci/vpbe_venc.c | 84 +
> include/media/davinci/vpbe_osd.h | 64 +-
> include/media/davinci/vpbe_venc.h | 21 +
> 10 files changed, 3735 insertions(+), 9 deletions(-) create mode 100644 drivers/media/video/davinci/vpbe_fb.c
> create mode 100644 drivers/media/video/davinci/vpbe_fb.h
> create mode 100644 drivers/media/video/davinci/vpbe_fb_ioctl.h
>
>
^ permalink raw reply
* PAYMENT INFORMATION
From: Western Union Money Transfer @ 2011-10-18 7:25 UTC (permalink / raw)
To: linux-fbdev
How are you today?
I write to inform you that we have already sent you $5,000.00USD through Western Union as we have been given the mandate to transfer your full compensation payment of $1.800, 000.00USD via Western Union Money Transfer by the United Nations (ECOWAS). This is because the United Nations and (ECOWAS) are supporting individuals due to the worldwide economy meltdown.
I would have requested for your phone number to give you the information through phone but Internet hackers were many. So i decided to email you the MTCN and sender name so that you can pick up this $5,000.00USD to enable us send another $5,000.00USD by tomorrow as you know that we will be sending you only $5,000.00USD per day. The fund was sent in the name which you use in opening your e-mail address.
Please pick up this information and rush to any Western Union to pick up the $5,000.00USD and send us an email back to enable us send you another payment by tomorrow.
Below is the western union information to pick up the USD5000.00 to pick up.
Payment Information.
MTCN: _______________4661-297-503
Sender's Name: _________Alice Johnson
Text Question: __________How Long
Answer: _______________Immediately
Amount Sent___________$5000.00USD
Country: _______________Nigeria
Email me once you picked up this USD5000.00 today.
Thanks
Mrs. Anita Daniel.
Email: westernunionmoneytransfer_w@yahoo.cn
®Western Union Office.
^ permalink raw reply
* Re: [GIT PULL] OMAP DSS for v3.2
From: Tomi Valkeinen @ 2011-10-17 6:49 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-omap mailing list, lfbdev-ml
In-Reply-To: <4E9B52E7.7020601@gmx.de>
On 10/17/2011 12:55 AM, Florian Tobias Schandinat wrote:
> Hi Tomi,
>
> On 10/07/2011 07:20 AM, Tomi Valkeinen wrote:
>> Hi Florian,
>>
>> Please pull OMAP DSS patches for v3.2 merge window.
>
> Pulled.
Thanks.
>> Note that there are some conflicts with other trees. The board file
>> conflicts are trivial, changes in code which just happen to be next to
>> each other. The LCD driver conflicts are even simpler, there were
>> changes to them from some other tree, but I have removed the files.
>>
>> The conflicts have been solved properly by Stephen in linux-next:
>>
>> https://github.com/sfrothwell/linux-next/commit/3e31b3042760e3906d0a275d7adedfaf55ee5b0a
>>
>> I also attached the output from git show, as github seems to show the
>> full diff for the merge commit.
>>
>> Are you ok with the conflicts?
>
> No problem.
> Well, as I understand, Linus prefers to see (and solve) these conflicts himself,
> so I don't have any work with them at all. I'd only have to resolve them if
> Linus gave up and that would probably point to a more fundamental issue in the
> workflow, like changes going mainline via the wrong tree or such things.
This is also my understanding. However, Linus isn't that fond of ARM
board files, which is where the conflicts are...
One could argue that the board file changes should go through the OMAP
tree, but both the driver and the board files need to be changed at the
same time to keep kernel compiling.
Tomi
^ permalink raw reply
* Re: [PATCH 1/1] OMAP: DSS2: Add TI Boxer display panel driver
From: Archit Taneja @ 2011-10-17 6:26 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: Valkeinen, Tomi, David Bolcsfoldi, linux-omap@vger.kernel.org,
linux-fbdev@vger.kernel.org
In-Reply-To: <1318689957-14743-1-git-send-email-martinez.javier@gmail.com>
Hi,
Some comments.
On Saturday 15 October 2011 08:15 PM, Javier Martinez Canillas wrote:
> Add panel driver for TI Boxer LCD.
>
> This panel is used on many embedded devices such as
> Barnes& Nobles's Nook Color e-reader.
>
> Signed-off-by: Javier Martinez Canillas<martinez.javier@gmail.com>
> ---
> drivers/video/omap2/displays/Kconfig | 6 +
> drivers/video/omap2/displays/Makefile | 1 +
> drivers/video/omap2/displays/panel-boxer.c | 333 ++++++++++++++++++++++++++++
> 3 files changed, 340 insertions(+), 0 deletions(-)
> create mode 100644 drivers/video/omap2/displays/panel-boxer.c
>
> diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
> index 609a280..6c9fe26 100644
> --- a/drivers/video/omap2/displays/Kconfig
> +++ b/drivers/video/omap2/displays/Kconfig
> @@ -48,4 +48,10 @@ config PANEL_ACX565AKM
> select BACKLIGHT_CLASS_DEVICE
> help
> This is the LCD panel used on Nokia N900
> +
> +config PANEL_BOXER
> + tristate "TI Boxer Panel"
> + help
> + LCD Panel used in the TI Boxer
> +
> endmenu
> diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
> index 0f601ab3a..26c662e 100644
> --- a/drivers/video/omap2/displays/Makefile
> +++ b/drivers/video/omap2/displays/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
> obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
> obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
> obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
> +obj-$(CONFIG_PANEL_BOXER) += panel-boxer.o
> diff --git a/drivers/video/omap2/displays/panel-boxer.c b/drivers/video/omap2/displays/panel-boxer.c
> new file mode 100644
> index 0000000..6429960
> --- /dev/null
> +++ b/drivers/video/omap2/displays/panel-boxer.c
> @@ -0,0 +1,333 @@
> +/*
> + * Boxer panel support
> + *
> + * Copyright (C) 2008 Nokia Corporation
> + * Author: Tomi Valkeinen<tomi.valkeinen@nokia.com>
> + *
> + * Copyright (c) 2010 Barnes& Noble
> + * David Bolcsfoldi<dbolcsfoldi@intrinsyc.com>
> + *
> + * 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.
> + *
> + * 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, see<http://www.gnu.org/licenses/>.
> + */
> +
> +#include<linux/module.h>
> +#include<linux/kernel.h>
> +#include<linux/delay.h>
> +#include<linux/platform_device.h>
> +#include<linux/spi/spi.h>
> +#include<linux/regulator/consumer.h>
> +#include<linux/err.h>
> +#include<linux/workqueue.h>
> +
> +#include<plat/mcspi.h>
> +#include<mach/gpio.h>
> +#include<mach/gpio.h>
> +#include<plat/mux.h>
> +#include<asm/mach-types.h>
> +
> +#include<video/omapdss.h>
> +
> +/* Delay between Panel configuration and Panel enabling */
> +#define LCD_RST_DELAY 100
> +#define LCD_INIT_DELAY 200
> +
> +#define LCD_XRES 1024
> +#define LCD_YRES 600
> +
> +#define LCD_PIXCLOCK_MIN 39000 /* CPT MIN PIX Clock is 39MHz */
> +#define Lcd_Pixclock_Typ 45000 /* Typical PIX clock is 45MHz */
> +#define LCD_PIXCLOCK_MAX 52000 /* Maximum is 52MHz */
These don't seem to be used. We should remove these.
> +
> +/* Current Pixel clock */
> +#define LCD_PIXEL_CLOCK 68000
> +
> +static struct workqueue_struct *boxer_panel_wq;
> +static struct omap_dss_device *boxer_panel_dssdev;
> +static struct regulator *boxer_panel_regulator;
> +static struct spi_device *boxer_spi_device;
> +static atomic_t boxer_panel_is_enabled = ATOMIC_INIT(0);
It would be cleaner to group these together as one driver data struct.
This struct can then be kzalloc'd at probe, and be linked to the dssdev
struct through 'dev_set_drvdata', this will help the driver support more
than one instances of boxer panel devices running in parallel. You could
see panel-generic-dpi.c for reference.
> +
> +/*NEC NL8048HL11-01B Manual
> + * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below
> + */
Its not clear what the comment above is trying to say. Is panel boxer
"NEC NL8048HL11-01B"?
> +
> +static struct omap_video_timings boxer_panel_timings = {
> + /* 1024 x 600 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
> + .x_res = LCD_XRES,
> + .y_res = LCD_YRES,
> + .pixel_clock = LCD_PIXEL_CLOCK,
> + .hfp = 48,
> + .hsw = 40,
> + .hbp = 65,
> + .vfp = 3,
> + .vsw = 10,
> + .vbp = 25,
> +};
> +
> +static void boxer_get_resolution(struct omap_dss_device *dssdev,
> + u16 *xres, u16 *yres)
> +{
> +
> + *xres = dssdev->panel.timings.x_res;
> + *yres = dssdev->panel.timings.y_res;
> +}
> +
> +int boxer_get_recommended_bpp(struct omap_dss_device *dssdev)
> +{
> + return 24;
> +}
> +
> +
> +static int boxer_panel_probe(struct omap_dss_device *dssdev)
> +{
> + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
> + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC;
> + dssdev->panel.timings = boxer_panel_timings;
> + return 0;
> +}
> +
> +static void boxer_panel_remove(struct omap_dss_device *dssdev)
> +{
> +}
> +
> +static int spi_send(struct spi_device *spi, unsigned char reg_addr,
> + unsigned char reg_data)
> +{
> + int ret = 0;
> + uint16_t msg;
> + msg = (reg_addr<< 10) | reg_data;
> +
> + if (spi_write(spi, (unsigned char *)&msg, 2))
> + printk(KERN_ERR "error in spi_write %x\n", msg);
> +
> + udelay(10);
> +
> + return ret;
> +}
> +
> +static void boxer_init_panel(void)
> +{
> + spi_send(boxer_spi_device, 0, 0x00);
> +
> + spi_send(boxer_spi_device, 0, 0xad);
> + spi_send(boxer_spi_device, 1, 0x30);
> + spi_send(boxer_spi_device, 2, 0x40);
You might want to use hex representations above for consistency.
> + spi_send(boxer_spi_device, 0xe, 0x5f);
> + spi_send(boxer_spi_device, 0xf, 0xa4);
> + spi_send(boxer_spi_device, 0xd, 0x00);
> + spi_send(boxer_spi_device, 0x2, 0x43);
> + spi_send(boxer_spi_device, 0xa, 0x28);
> + spi_send(boxer_spi_device, 0x10, 0x41);
> +}
> +
> +static void boxer_panel_work_func(struct work_struct *work)
> +{
> + if (!regulator_is_enabled(boxer_panel_regulator))
> + regulator_enable(boxer_panel_regulator);
> +
> + msleep(LCD_RST_DELAY);
> +
> + boxer_spi_device->mode = SPI_MODE_0;
> + boxer_spi_device->bits_per_word = 16;
> + spi_setup(boxer_spi_device);
> +
> + boxer_init_panel();
> +
> + msleep(LCD_INIT_DELAY);
> +
> + if (boxer_panel_dssdev->platform_enable)
> + boxer_panel_dssdev->platform_enable(boxer_panel_dssdev);
> +}
> +
> +static DECLARE_WORK(boxer_panel_work, boxer_panel_work_func);
> +
> +static int boxer_panel_enable(struct omap_dss_device *dssdev)
> +{
> + if (atomic_add_unless(&boxer_panel_is_enabled, 1, 1)) {
> + boxer_panel_dssdev = dssdev;
> + queue_work(boxer_panel_wq,&boxer_panel_work);
> + }
> +
You need to set the dssdev->state values correctly in the
enable/disable/suspend/resume functions, otherwise DSS2 won't have the
correct knowledge of the panel state.
> + return 0;
> +}
> +
> +static void boxer_panel_disable(struct omap_dss_device *dssdev)
> +{
> + if (atomic_dec_and_test(&boxer_panel_is_enabled)) {
> + cancel_work_sync(&boxer_panel_work);
> +
> + if (dssdev->platform_disable)
> + dssdev->platform_disable(dssdev);
> +
> + if (regulator_is_enabled(boxer_panel_regulator))
> + regulator_disable(boxer_panel_regulator);
> + } else {
> + printk(KERN_WARNING "%s: attempting to disable panel twice!\n",
> + __func__);
You should use dev_err, dev_warn and dev_info instead of printks using
the dssdev->dev device.
Archit
> + WARN_ON(1);
> + }
> +}
> +
> +static int boxer_panel_suspend(struct omap_dss_device *dssdev)
> +{
> + boxer_panel_disable(dssdev);
> + return 0;
> +}
> +
> +static int boxer_panel_resume(struct omap_dss_device *dssdev)
> +{
> + return boxer_panel_enable(dssdev);
> +}
> +
> +static struct omap_dss_driver boxer_driver = {
> + .probe = boxer_panel_probe,
> + .remove = boxer_panel_remove,
> +
> + .enable = boxer_panel_enable,
> + .disable = boxer_panel_disable,
> + .suspend = boxer_panel_suspend,
> + .resume = boxer_panel_resume,
> + .get_resolution = boxer_get_resolution,
> + .get_recommended_bpp = boxer_get_recommended_bpp,
> + .driver = {
> + .name = "boxer_panel",
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +static ssize_t lcd_reg_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + int argc;
> + char **args;
> + unsigned long r, val;
> + int ret;
> +
> + struct spi_device *spi = to_spi_device(dev);
> +
> + args = argv_split(GFP_KERNEL, buf,&argc);
> +
> + if (args = NULL) {
> + dev_err(dev, "error getting arguments\n");
> + return count;
> + }
> +
> + if (argc = 2) {
> + ret = strict_strtoul(*args, 0, (unsigned long *)&r);
> + if (ret)
> + return ret;
> + args++;
> + ret = strict_strtoul(*args, 0, (unsigned long *)&val);
> + if (ret)
> + return ret;
> + dev_info(dev, "set lcd panel spi reg %lu = %lu\n", r, val);
> + spi_send(spi, r, val);
> + }
> + argv_free(args);
> +
> + return count;
> +}
> +
> +
> +static DEVICE_ATTR(lcd_reg, S_IWUSR, NULL, lcd_reg_store);
> +
> +static struct attribute *boxer_lcd_spi_attributes[] = {
> + &dev_attr_lcd_reg,
> + NULL
> +};
> +
> +
> +static struct attribute_group boxer_lcd_spi_attributes_group = {
> + .attrs = boxer_lcd_spi_attributes,
> +};
> +
> +
> +
> +static int boxer_spi_probe(struct spi_device *spi)
> +{
> + spi->mode = SPI_MODE_0;
> + spi->bits_per_word = 16;
> + spi_setup(spi);
> +
> + boxer_spi_device = spi;
> +
> + boxer_init_panel();
> +
> + if (sysfs_create_group(&spi->dev.kobj,&boxer_lcd_spi_attributes_group))
> + printk(KERN_WARNING "error creating sysfs entries\n");
> +
> + omap_dss_register_driver(&boxer_driver);
> + return 0;
> +}
> +
> +static int boxer_spi_remove(struct spi_device *spi)
> +{
> + sysfs_remove_group(&spi->dev.kobj,&boxer_lcd_spi_attributes_group);
> + omap_dss_unregister_driver(&boxer_driver);
> +
> + return 0;
> +}
> +
> +
> +static struct spi_driver boxer_spi_driver = {
> + .probe = boxer_spi_probe,
> + .remove = __devexit_p(boxer_spi_remove),
> + .driver = {
> + .name = "boxer_disp_spi",
> + .bus =&spi_bus_type,
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +static int __init boxer_lcd_init(void)
> +{
> + int ret = 0;
> +
> + boxer_panel_wq = create_singlethread_workqueue("boxer-panel-wq");
> +
> + printk(KERN_WARNING "Enabling power for LCD\n");
> + boxer_panel_regulator = regulator_get(NULL, "vlcd");
> +
> + if (IS_ERR(boxer_panel_regulator)) {
> + printk(KERN_ERR "Unable to get vlcd regulator, reason: %ld!\n",
> + IS_ERR(boxer_panel_regulator));
> + ret = -ENODEV;
> + goto out;
> + }
> +
> + ret = regulator_enable(boxer_panel_regulator);
> +
> + if (ret) {
> + printk(KERN_ERR "Failed to enable regulator vlcd!\n");
> + regulator_put(boxer_panel_regulator);
> + goto out;
> + }
> +
> + return spi_register_driver(&boxer_spi_driver);
> +out:
> + return ret;
> +}
> +
> +static void __exit boxer_lcd_exit(void)
> +{
> + spi_unregister_driver(&boxer_spi_driver);
> + regulator_disable(boxer_panel_regulator);
> + regulator_put(boxer_panel_regulator);
> + destroy_workqueue(boxer_panel_wq);
> +}
> +
> +
> +module_init(boxer_lcd_init);
> +module_exit(boxer_lcd_exit);
> +MODULE_LICENSE("GPL");
> +
^ permalink raw reply
* Re: [GIT PULL] OMAP DSS for v3.2
From: Florian Tobias Schandinat @ 2011-10-16 21:55 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap mailing list, lfbdev-ml
In-Reply-To: <1317972007.2374.12.camel@deskari>
Hi Tomi,
On 10/07/2011 07:20 AM, Tomi Valkeinen wrote:
> Hi Florian,
>
> Please pull OMAP DSS patches for v3.2 merge window.
Pulled.
> Note that there are some conflicts with other trees. The board file
> conflicts are trivial, changes in code which just happen to be next to
> each other. The LCD driver conflicts are even simpler, there were
> changes to them from some other tree, but I have removed the files.
>
> The conflicts have been solved properly by Stephen in linux-next:
>
> https://github.com/sfrothwell/linux-next/commit/3e31b3042760e3906d0a275d7adedfaf55ee5b0a
>
> I also attached the output from git show, as github seems to show the
> full diff for the merge commit.
>
> Are you ok with the conflicts?
No problem.
Well, as I understand, Linus prefers to see (and solve) these conflicts himself,
so I don't have any work with them at all. I'd only have to resolve them if
Linus gave up and that would probably point to a more fundamental issue in the
workflow, like changes going mainline via the wrong tree or such things.
Thanks,
Florian Tobias Schandinat
> The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb:
>
> Linux 3.1-rc6 (2011-09-12 14:02:02 -0700)
>
> are available in the git repository at:
> git://gitorious.org/linux-omap-dss2/linux.git for-florian
>
> Andy Doan (1):
> OMAPFB: make debug message more useful
>
> Archit Taneja (26):
> OMAP: DSS2: DISPC: Prepare dispc_dump_regs() for shortening
> OMAP: DSS2: DISPC: Shorten dispc_dump_regs()
> OMAP: DSS2: DISPC: dispc_save_context() and dispc_restore_context() cleanup
> OMAP: DSS2: DISPC: Shorten _dispc_set_color_conv_coef()
> OMAP: DSS2: Use a macro to declare size of the fifo_size array in dispc.c
> OMAP: DSS2: Use MIPI DSI enums from include/video/mipi_display.h
> OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of modes
> OMAP: DSS2: Create enum for DSI operation modes
> OMAP: DSS2: DSI: Introduce generic write functions
> OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2()
> OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions
> OMAP: DSS2: DSI: Introduce generic read functions
> OMAP: DSS2: Clean up stallmode and io pad mode selection
> OMAP: DSS2: Create an enum for DSI pixel formats
> OMAP: DSS2: DSI: Send zero length packet in dsi_vc_send_null()
> OMAP: DSS2: DSI Video mode support
> OMAPDSS: DISPC: Reduce the number of arguments in dispc_ovl_setup()
> OMAPDSS: DISPC: Pass overlay params as arguments to dispc_ovl_setup()
> OMAPDSS: DISPC: Create helper function dispc_mgr_is_lcd()
> OMAPDSS: DISPC: Get correct pixel clock for TV manager
> OMAPDSS: DISPC: Remove hardcoded use of PPL in five tap clock calculation
> OMAPDSS: DISPC: Clean up scaling related clock and five tap calculations
> OMAPDSS: FEATURES: Create a range param to get max downscaling
> OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
> OMAPDSS: DISPC: VIDEO3 pipeline support
> OMAPDSS: DISPC: zorder support for DSS overlays
>
> Arnd Bergmann (1):
> video/omap: fix build dependencies
>
> Daniel Morsing (1):
> OMAP: DSS2: Don't allow moving managers away from enabled displays
>
> Dima Zavin (1):
> OMAP: DSS: dispc: enable/disable clocks in error handler
>
> Mayuresh Janorkar (1):
> OMAP: DSS2: Add picodlp panel driver
>
> Mythri P K (14):
> OMAP4: DSS2: HDMI: HDMI clean up to pass base_address
> OMAP4: DSS2: HDMI: Move pll and video configuration
> OMAP4: DSS2: HDMI: Use specific HDMI timings structure
> OMAP4: DSS2: HDMI: Move HDMI IP independent generic header
> OMAP4: DSS2: HDMI: Move the EDID definition from HDMI
> OMAP4: DSS2: HDMI: Split the current HDMI driver to move
> OMAP4: DSS2: HDMI: Move the HDMI IP dependent audio
> OMAP4: DSS2: HDMI: Rename the functions in HDMI IP library
> OMAP4: DSS2: HDMI: Function pointer approach to call
> OMAP4: DSS2: Rename hdmi_omap4_panel.c to hdmi_panel.c
> OMAPDSS: HDMI: Move the comments in avi infoframe
> OMAPDSS: HDMI: Replace hdmi_reg struct with u16
> OMAPDSS: HDMI: Add missing register definitions
> OMAPDSS: HDMI: Add support to dump registers through debugfs
>
> Thomas Weber (2):
> OMAP: DSS2: Support for Innolux AT070TN83
> OMAP: Devkit8000: Change lcd driver to AT070TN83
>
> Tomi Valkeinen (63):
> OMAP: DSS2: PicoDLP: fix error handling in power_on
> OMAP: DSS2: check for manager when enabling display
> Revert "HACK: OMAP: DSS2: clk hack for OMAP2/3"
> Revert "OMAP: DSS2: HDMI: fix hdmi clock name"
> OMAP: DSS2: remove unneeded fck enable/disables
> OMAP: DSS2: Change DSI device naming
> OMAP4: TWL: Add common omapdss supplies
> OMAP: DSS2: DSI: Improve dsi_mux_pads parameters
> OMAP: DSS2: Implement dsi_mux_pads for OMAP4
> OMAP: OMAPFB: make omapfb start even when a display is missing a driver
> OMAP: DSS2: fix clock sources on error and uninit
> OMAP: DSS2: Handle manager change in apply
> OMAP: DSS2: Remove "EXPERIMENTAL" from Kconfig
> OMAP: DSS2: Remove support for non-DISPC overlays
> OMAP: DSS2: DISPC: use lookup tables for bit shifts
> OMAP: DSS2: Add overlay caps to DSS features
> OMAP: DSS2: Add GLOBAL_ALPHA & PRE_MULT_ALPHA to ovl caps
> OMAP: DSS2: string parsing cleanups
> OMAP: OMAPFB: string parsing cleanups
> OMAP: DSS2: DISPC: remove non-existing func prototypes
> OMAP: DSS2: DISPC: rename overlay related funcs
> OMAP: DSS2: DISPC: rename manager related funcs
> OMAP: DSS2: reorganize functions in dss.h
> OMAP: DSS2: DISPC: Fix minimum PCD value
> OMAP: DSS2: HDMI: use default dividers
> OMAP: DSS2: HDMI: change regn definition
> OMAP: DSS2: DSI: Add comment about regn
> OMAP: DSS2: DISPC: Add missing IRQ definitions
> OMAP: DSS2: add dss_get_hdmi_venc_clk_source()
> OMAP: DSS2: DISPC: improve dispc_mgr_enable_digit_out()
> OMAP: DSS2: HDMI: improve hdmi output enable
> OMAP: DSS2: add read_edid() to omap_dss_driver struct
> OMAP: DSS2: add detect() to omap_dss_driver struct
> OMAP: DSS2: HDMI: make set_timing saner
> OMAP: DSS2: HDMI: implement read_edid()
> OMAP: DSS2: HDMI: remove edid parsing
> OMAP: DSS2: HDMI: split hdmi_core_ddc_edid
> OMAP: DSS2: HDMI: clean up edid reading & fix checksum
> OMAP: DSS2: HDMI: remove error prints in check_timings
> OMAP: DSS2: HDMI: implement detect()
> OMAP: DSS2: add panel-dvi driver
> OMAP: use dvi panel driver instead of generic-dpi
> OMAP: stalker: Remove LCD device from board file
> OMAP: DSS2: panel-generic-dpi: remove "generic" panel
> OMAP: Add DDC i2c_bus_num to board files
> OMAPFB: find best mode from edid
> OMAPDSS: Taal: remove external backlight support
> OMAPFB: Remove unused lcd drivers
> OMAPDSS: Port 2430sdp display driver to DSS2
> OMAPDSS: Port the H4 display driver to DSS2
> OMAPDSS: Port the Apollon display driver to DSS2
> OMAPDSS: Add N800 panel driver
> OMAPDSS: remove vaddr from overlay info
> OMAP: 4430SDP: Remove unneeded lcd config
> OMAP4: 4430SDP: Add panel support to board file
> OMAP4: 4430SDP: Add picodlp support to board file
> OMAP: RX51: Remove unused old omapfb stuff
> OMAP: omap3touchbook: Remove unused lcd stuff
> OMAP: 2420SDP: Port the display driver to new DSS2
> OMAP: LDP: Port the display driver to new DSS2
> OMAP: H4: Port the display driver to new DSS2
> OMAP: Apollon: Port the display driver to new DSS2
> OMAPDSS: picodlp: add missing #include <linux/module.h>
>
> arch/arm/mach-omap2/board-2430sdp.c | 78 +-
> arch/arm/mach-omap2/board-3430sdp.c | 7 +-
> arch/arm/mach-omap2/board-4430sdp.c | 208 +++-
> arch/arm/mach-omap2/board-am3517evm.c | 6 +-
> arch/arm/mach-omap2/board-apollon.c | 35 +-
> arch/arm/mach-omap2/board-cm-t35.c | 6 +-
> arch/arm/mach-omap2/board-devkit8000.c | 10 +-
> arch/arm/mach-omap2/board-h4.c | 42 +-
> arch/arm/mach-omap2/board-igep0020.c | 8 +-
> arch/arm/mach-omap2/board-ldp.c | 123 ++-
> arch/arm/mach-omap2/board-omap3beagle.c | 8 +-
> arch/arm/mach-omap2/board-omap3evm.c | 7 +-
> arch/arm/mach-omap2/board-omap3pandora.c | 2 +-
> arch/arm/mach-omap2/board-omap3stalker.c | 40 +-
> arch/arm/mach-omap2/board-omap3touchbook.c | 18 -
> arch/arm/mach-omap2/board-omap4panda.c | 8 +-
> arch/arm/mach-omap2/board-overo.c | 7 +-
> arch/arm/mach-omap2/board-rx51.c | 25 -
> arch/arm/mach-omap2/display.c | 60 +-
> arch/arm/mach-omap2/twl-common.c | 11 +-
> drivers/media/video/omap/omap_vout.c | 18 +-
> drivers/video/omap/Kconfig | 29 -
> drivers/video/omap/Makefile | 8 -
> drivers/video/omap/lcd_2430sdp.c | 203 ---
> drivers/video/omap/lcd_apollon.c | 136 --
> drivers/video/omap/lcd_h4.c | 117 --
> drivers/video/omap/lcd_ldp.c | 201 ---
> drivers/video/omap/lcd_omap3beagle.c | 130 --
> drivers/video/omap/lcd_omap3evm.c | 193 ---
> drivers/video/omap/lcd_overo.c | 180 ---
> drivers/video/omap2/displays/Kconfig | 28 +-
> drivers/video/omap2/displays/Makefile | 3 +
> drivers/video/omap2/displays/panel-dvi.c | 363 +++++
> drivers/video/omap2/displays/panel-generic-dpi.c | 113 +-
> drivers/video/omap2/displays/panel-n8x0.c | 747 +++++++++
> drivers/video/omap2/displays/panel-picodlp.c | 594 +++++++
> drivers/video/omap2/displays/panel-picodlp.h | 288 ++++
> drivers/video/omap2/displays/panel-taal.c | 123 +-
> drivers/video/omap2/dss/Kconfig | 2 +-
> drivers/video/omap2/dss/Makefile | 2 +-
> drivers/video/omap2/dss/core.c | 4 +
> drivers/video/omap2/dss/dispc.c | 1700 ++++++++------------
> drivers/video/omap2/dss/dispc.h | 57 +
> drivers/video/omap2/dss/display.c | 31 +-
> drivers/video/omap2/dss/dpi.c | 28 +-
> drivers/video/omap2/dss/dsi.c | 929 +++++++-----
> drivers/video/omap2/dss/dss.c | 18 +-
> drivers/video/omap2/dss/dss.h | 156 +-
> drivers/video/omap2/dss/dss_features.c | 130 ++-
> drivers/video/omap2/dss/dss_features.h | 17 +-
> drivers/video/omap2/dss/hdmi.c | 1260 ++-------------
> .../omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} | 68 +-
> drivers/video/omap2/dss/manager.c | 191 +--
> drivers/video/omap2/dss/overlay.c | 122 +-
> drivers/video/omap2/dss/rfbi.c | 45 +-
> drivers/video/omap2/dss/sdi.c | 19 +-
> drivers/video/omap2/dss/ti_hdmi.h | 138 ++
> drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 1239 ++++++++++++++
> .../video/omap2/dss/{hdmi.h => ti_hdmi_4xxx_ip.h} | 400 +++---
> drivers/video/omap2/dss/venc.c | 27 +-
> drivers/video/omap2/omapfb/Kconfig | 2 +-
> drivers/video/omap2/omapfb/omapfb-main.c | 134 ++-
> drivers/video/omap2/omapfb/omapfb-sysfs.c | 6 +-
> include/video/omap-panel-dvi.h | 37 +
> include/video/omap-panel-n8x0.h | 15 +
> include/video/omap-panel-nokia-dsi.h | 8 +-
> include/video/omap-panel-picodlp.h | 23 +
> include/video/omapdss.h | 100 +-
> 68 files changed, 6495 insertions(+), 4596 deletions(-)
> delete mode 100644 drivers/video/omap/lcd_2430sdp.c
> delete mode 100644 drivers/video/omap/lcd_apollon.c
> delete mode 100644 drivers/video/omap/lcd_h4.c
> delete mode 100644 drivers/video/omap/lcd_ldp.c
> delete mode 100644 drivers/video/omap/lcd_omap3beagle.c
> delete mode 100644 drivers/video/omap/lcd_omap3evm.c
> delete mode 100644 drivers/video/omap/lcd_overo.c
> create mode 100644 drivers/video/omap2/displays/panel-dvi.c
> create mode 100644 drivers/video/omap2/displays/panel-n8x0.c
> create mode 100644 drivers/video/omap2/displays/panel-picodlp.c
> create mode 100644 drivers/video/omap2/displays/panel-picodlp.h
> rename drivers/video/omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} (79%)
> create mode 100644 drivers/video/omap2/dss/ti_hdmi.h
> create mode 100644 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
> rename drivers/video/omap2/dss/{hdmi.h => ti_hdmi_4xxx_ip.h} (54%)
> create mode 100644 include/video/omap-panel-dvi.h
> create mode 100644 include/video/omap-panel-n8x0.h
> create mode 100644 include/video/omap-panel-picodlp.h
>
^ permalink raw reply
* Re: [PATCH] video: platinumfb: Add __devexit_p at necessary place
From: Florian Tobias Schandinat @ 2011-10-16 21:34 UTC (permalink / raw)
To: Axel Lin; +Cc: linux-kernel, linux-fbdev
In-Reply-To: <1317801698.12133.1.camel@phoenix>
On 10/05/2011 08:01 AM, Axel Lin wrote:
> According to the comments in include/linux/init.h:
>
> "Pointers to __devexit functions must use __devexit_p(function_name), the
> wrapper will insert either the function_name or NULL, depending on the config
> options."
>
> We have __devexit annotation for platinumfb_remove(), thus add __devexit_p at
> necessary place.
Applied.
Thanks,
Florian Tobias Schandinat
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> drivers/video/platinumfb.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
> index 6694923..ae3caa6 100644
> --- a/drivers/video/platinumfb.c
> +++ b/drivers/video/platinumfb.c
> @@ -683,7 +683,7 @@ static struct platform_driver platinum_driver > .of_match_table = platinumfb_match,
> },
> .probe = platinumfb_probe,
> - .remove = platinumfb_remove,
> + .remove = __devexit_p(platinumfb_remove),
> };
>
> static int __init platinumfb_init(void)
^ permalink raw reply
* [PATCH 1/1] OMAP: DSS2: Add TI Boxer display panel driver
From: Javier Martinez Canillas @ 2011-10-15 14:45 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: David Bolcsfoldi, linux-omap, linux-fbdev,
Javier Martinez Canillas
Add panel driver for TI Boxer LCD.
This panel is used on many embedded devices such as
Barnes & Nobles's Nook Color e-reader.
Signed-off-by: Javier Martinez Canillas <martinez.javier@gmail.com>
---
drivers/video/omap2/displays/Kconfig | 6 +
drivers/video/omap2/displays/Makefile | 1 +
drivers/video/omap2/displays/panel-boxer.c | 333 ++++++++++++++++++++++++++++
3 files changed, 340 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/omap2/displays/panel-boxer.c
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 609a280..6c9fe26 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -48,4 +48,10 @@ config PANEL_ACX565AKM
select BACKLIGHT_CLASS_DEVICE
help
This is the LCD panel used on Nokia N900
+
+config PANEL_BOXER
+ tristate "TI Boxer Panel"
+ help
+ LCD Panel used in the TI Boxer
+
endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 0f601ab3a..26c662e 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
+obj-$(CONFIG_PANEL_BOXER) += panel-boxer.o
diff --git a/drivers/video/omap2/displays/panel-boxer.c b/drivers/video/omap2/displays/panel-boxer.c
new file mode 100644
index 0000000..6429960
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-boxer.c
@@ -0,0 +1,333 @@
+/*
+ * Boxer panel support
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Copyright (c) 2010 Barnes & Noble
+ * David Bolcsfoldi <dbolcsfoldi@intrinsyc.com>
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/workqueue.h>
+
+#include <plat/mcspi.h>
+#include <mach/gpio.h>
+#include <mach/gpio.h>
+#include <plat/mux.h>
+#include <asm/mach-types.h>
+
+#include <video/omapdss.h>
+
+/* Delay between Panel configuration and Panel enabling */
+#define LCD_RST_DELAY 100
+#define LCD_INIT_DELAY 200
+
+#define LCD_XRES 1024
+#define LCD_YRES 600
+
+#define LCD_PIXCLOCK_MIN 39000 /* CPT MIN PIX Clock is 39MHz */
+#define Lcd_Pixclock_Typ 45000 /* Typical PIX clock is 45MHz */
+#define LCD_PIXCLOCK_MAX 52000 /* Maximum is 52MHz */
+
+/* Current Pixel clock */
+#define LCD_PIXEL_CLOCK 68000
+
+static struct workqueue_struct *boxer_panel_wq;
+static struct omap_dss_device *boxer_panel_dssdev;
+static struct regulator *boxer_panel_regulator;
+static struct spi_device *boxer_spi_device;
+static atomic_t boxer_panel_is_enabled = ATOMIC_INIT(0);
+
+/*NEC NL8048HL11-01B Manual
+ * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below
+ */
+
+static struct omap_video_timings boxer_panel_timings = {
+ /* 1024 x 600 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
+ .x_res = LCD_XRES,
+ .y_res = LCD_YRES,
+ .pixel_clock = LCD_PIXEL_CLOCK,
+ .hfp = 48,
+ .hsw = 40,
+ .hbp = 65,
+ .vfp = 3,
+ .vsw = 10,
+ .vbp = 25,
+};
+
+static void boxer_get_resolution(struct omap_dss_device *dssdev,
+ u16 *xres, u16 *yres)
+{
+
+ *xres = dssdev->panel.timings.x_res;
+ *yres = dssdev->panel.timings.y_res;
+}
+
+int boxer_get_recommended_bpp(struct omap_dss_device *dssdev)
+{
+ return 24;
+}
+
+
+static int boxer_panel_probe(struct omap_dss_device *dssdev)
+{
+ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC;
+ dssdev->panel.timings = boxer_panel_timings;
+ return 0;
+}
+
+static void boxer_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int spi_send(struct spi_device *spi, unsigned char reg_addr,
+ unsigned char reg_data)
+{
+ int ret = 0;
+ uint16_t msg;
+ msg = (reg_addr << 10) | reg_data;
+
+ if (spi_write(spi, (unsigned char *)&msg, 2))
+ printk(KERN_ERR "error in spi_write %x\n", msg);
+
+ udelay(10);
+
+ return ret;
+}
+
+static void boxer_init_panel(void)
+{
+ spi_send(boxer_spi_device, 0, 0x00);
+
+ spi_send(boxer_spi_device, 0, 0xad);
+ spi_send(boxer_spi_device, 1, 0x30);
+ spi_send(boxer_spi_device, 2, 0x40);
+ spi_send(boxer_spi_device, 0xe, 0x5f);
+ spi_send(boxer_spi_device, 0xf, 0xa4);
+ spi_send(boxer_spi_device, 0xd, 0x00);
+ spi_send(boxer_spi_device, 0x2, 0x43);
+ spi_send(boxer_spi_device, 0xa, 0x28);
+ spi_send(boxer_spi_device, 0x10, 0x41);
+}
+
+static void boxer_panel_work_func(struct work_struct *work)
+{
+ if (!regulator_is_enabled(boxer_panel_regulator))
+ regulator_enable(boxer_panel_regulator);
+
+ msleep(LCD_RST_DELAY);
+
+ boxer_spi_device->mode = SPI_MODE_0;
+ boxer_spi_device->bits_per_word = 16;
+ spi_setup(boxer_spi_device);
+
+ boxer_init_panel();
+
+ msleep(LCD_INIT_DELAY);
+
+ if (boxer_panel_dssdev->platform_enable)
+ boxer_panel_dssdev->platform_enable(boxer_panel_dssdev);
+}
+
+static DECLARE_WORK(boxer_panel_work, boxer_panel_work_func);
+
+static int boxer_panel_enable(struct omap_dss_device *dssdev)
+{
+ if (atomic_add_unless(&boxer_panel_is_enabled, 1, 1)) {
+ boxer_panel_dssdev = dssdev;
+ queue_work(boxer_panel_wq, &boxer_panel_work);
+ }
+
+ return 0;
+}
+
+static void boxer_panel_disable(struct omap_dss_device *dssdev)
+{
+ if (atomic_dec_and_test(&boxer_panel_is_enabled)) {
+ cancel_work_sync(&boxer_panel_work);
+
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
+
+ if (regulator_is_enabled(boxer_panel_regulator))
+ regulator_disable(boxer_panel_regulator);
+ } else {
+ printk(KERN_WARNING "%s: attempting to disable panel twice!\n",
+ __func__);
+ WARN_ON(1);
+ }
+}
+
+static int boxer_panel_suspend(struct omap_dss_device *dssdev)
+{
+ boxer_panel_disable(dssdev);
+ return 0;
+}
+
+static int boxer_panel_resume(struct omap_dss_device *dssdev)
+{
+ return boxer_panel_enable(dssdev);
+}
+
+static struct omap_dss_driver boxer_driver = {
+ .probe = boxer_panel_probe,
+ .remove = boxer_panel_remove,
+
+ .enable = boxer_panel_enable,
+ .disable = boxer_panel_disable,
+ .suspend = boxer_panel_suspend,
+ .resume = boxer_panel_resume,
+ .get_resolution = boxer_get_resolution,
+ .get_recommended_bpp = boxer_get_recommended_bpp,
+ .driver = {
+ .name = "boxer_panel",
+ .owner = THIS_MODULE,
+ },
+};
+
+static ssize_t lcd_reg_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int argc;
+ char **args;
+ unsigned long r, val;
+ int ret;
+
+ struct spi_device *spi = to_spi_device(dev);
+
+ args = argv_split(GFP_KERNEL, buf, &argc);
+
+ if (args = NULL) {
+ dev_err(dev, "error getting arguments\n");
+ return count;
+ }
+
+ if (argc = 2) {
+ ret = strict_strtoul(*args, 0, (unsigned long *)&r);
+ if (ret)
+ return ret;
+ args++;
+ ret = strict_strtoul(*args, 0, (unsigned long *)&val);
+ if (ret)
+ return ret;
+ dev_info(dev, "set lcd panel spi reg %lu = %lu\n", r, val);
+ spi_send(spi, r, val);
+ }
+ argv_free(args);
+
+ return count;
+}
+
+
+static DEVICE_ATTR(lcd_reg, S_IWUSR, NULL, lcd_reg_store);
+
+static struct attribute *boxer_lcd_spi_attributes[] = {
+ &dev_attr_lcd_reg,
+ NULL
+};
+
+
+static struct attribute_group boxer_lcd_spi_attributes_group = {
+ .attrs = boxer_lcd_spi_attributes,
+};
+
+
+
+static int boxer_spi_probe(struct spi_device *spi)
+{
+ spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 16;
+ spi_setup(spi);
+
+ boxer_spi_device = spi;
+
+ boxer_init_panel();
+
+ if (sysfs_create_group(&spi->dev.kobj, &boxer_lcd_spi_attributes_group))
+ printk(KERN_WARNING "error creating sysfs entries\n");
+
+ omap_dss_register_driver(&boxer_driver);
+ return 0;
+}
+
+static int boxer_spi_remove(struct spi_device *spi)
+{
+ sysfs_remove_group(&spi->dev.kobj, &boxer_lcd_spi_attributes_group);
+ omap_dss_unregister_driver(&boxer_driver);
+
+ return 0;
+}
+
+
+static struct spi_driver boxer_spi_driver = {
+ .probe = boxer_spi_probe,
+ .remove = __devexit_p(boxer_spi_remove),
+ .driver = {
+ .name = "boxer_disp_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init boxer_lcd_init(void)
+{
+ int ret = 0;
+
+ boxer_panel_wq = create_singlethread_workqueue("boxer-panel-wq");
+
+ printk(KERN_WARNING "Enabling power for LCD\n");
+ boxer_panel_regulator = regulator_get(NULL, "vlcd");
+
+ if (IS_ERR(boxer_panel_regulator)) {
+ printk(KERN_ERR "Unable to get vlcd regulator, reason: %ld!\n",
+ IS_ERR(boxer_panel_regulator));
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = regulator_enable(boxer_panel_regulator);
+
+ if (ret) {
+ printk(KERN_ERR "Failed to enable regulator vlcd!\n");
+ regulator_put(boxer_panel_regulator);
+ goto out;
+ }
+
+ return spi_register_driver(&boxer_spi_driver);
+out:
+ return ret;
+}
+
+static void __exit boxer_lcd_exit(void)
+{
+ spi_unregister_driver(&boxer_spi_driver);
+ regulator_disable(boxer_panel_regulator);
+ regulator_put(boxer_panel_regulator);
+ destroy_workqueue(boxer_panel_wq);
+}
+
+
+module_init(boxer_lcd_init);
+module_exit(boxer_lcd_exit);
+MODULE_LICENSE("GPL");
+
--
1.7.4.1
^ permalink raw reply related
* Re: linux-next: manual merge of the staging tree with the fbdev tree
From: Greg KH @ 2011-10-13 15:10 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-next, linux-kernel, Laurent Pinchart,
Florian Tobias Schandinat, linux-fbdev, Aaro Koskinen
In-Reply-To: <20111013170225.254bc2d590deee544913ab6c@canb.auug.org.au>
On Thu, Oct 13, 2011 at 05:02:25PM +1100, Stephen Rothwell wrote:
> Hi Greg,
>
> Today's linux-next merge of the staging tree got a conflict in
> drivers/staging/xgifb/XGI_main_26.c between commit 0d5c6ca30bb0
> ("staging: xgifb: use display information in info not in var for
> panning") from the fbdev tree and commit fd26d42019cb ("staging: xgifb:
> avoid direct references xgi_video_info") from the staging tree.
>
> I fixed it up (I think - see below) and can carry the fix as necessary.
The fix looks correct to me, thanks.
greg k-h
^ permalink raw reply
* [PATCH] atmel_lcdfb: support 16bit BGR:565 mode, remove unsupported 15bit modes
From: Peter Korsgaard @ 2011-10-13 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Allow framebuffer to be configured in 16bit mode when panel is wired in
(the default) BGR configuration, and don't claim to support 15bit input
modes, which the LCD controller cannot handle.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
drivers/video/atmel_lcdfb.c | 12 +++---------
1 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 7ca3eaf..143f6d9 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -418,24 +418,18 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
var->red.length = var->green.length = var->blue.length
= var->bits_per_pixel;
break;
- case 15:
case 16:
if (sinfo->lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB) {
/* RGB:565 mode */
var->red.offset = 11;
var->blue.offset = 0;
- var->green.length = 6;
- } else if (sinfo->lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB555) {
- var->red.offset = 10;
- var->blue.offset = 0;
- var->green.length = 5;
} else {
- /* BGR:555 mode */
+ /* BGR:565 mode */
var->red.offset = 0;
- var->blue.offset = 10;
- var->green.length = 5;
+ var->blue.offset = 11;
}
var->green.offset = 5;
+ var->green.length = 6;
var->red.length = var->blue.length = 5;
break;
case 32:
--
1.7.6.3
^ permalink raw reply related
* [PATCHv2] atmel_lcdfb: support new-style palette format
From: Peter Korsgaard @ 2011-10-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
The newer Atmel SoCs use normal 16bit 565 BGR/RGB for the palette data,
rather than the special intensity + 555 format.
Fill out palette data correctly on these devices, and at the same time
respect the RGB/BGR wiring mode.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
Changes since v1:
- ATMEL_LCDC_WIRING_RGB/BGR was swapped
drivers/video/atmel_lcdfb.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 63409c1..7ca3eaf 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -682,14 +682,30 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
case FB_VISUAL_PSEUDOCOLOR:
if (regno < 256) {
- val = ((red >> 11) & 0x001f);
- val |= ((green >> 6) & 0x03e0);
- val |= ((blue >> 1) & 0x7c00);
-
- /*
- * TODO: intensity bit. Maybe something like
- * ~(red[10] ^ green[10] ^ blue[10]) & 1
- */
+ if (cpu_is_at91sam9261() || cpu_is_at91sam9263()
+ || cpu_is_at91sam9rl()) {
+ /* old style I+BGR:555 */
+ val = ((red >> 11) & 0x001f);
+ val |= ((green >> 6) & 0x03e0);
+ val |= ((blue >> 1) & 0x7c00);
+
+ /*
+ * TODO: intensity bit. Maybe something like
+ * ~(red[10] ^ green[10] ^ blue[10]) & 1
+ */
+ } else {
+ /* new style BGR:565 / RGB:565 */
+ if (sinfo->lcd_wiring_mode =
+ ATMEL_LCDC_WIRING_RGB) {
+ val = ((blue >> 11) & 0x001f);
+ val |= ((red >> 0) & 0xf800);
+ } else {
+ val = ((red >> 11) & 0x001f);
+ val |= ((blue >> 0) & 0xf800);
+ }
+
+ val |= ((green >> 5) & 0x07e0);
+ }
lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
ret = 0;
--
1.7.6.3
^ permalink raw reply related
* Re: [PATCH] atmel_lcdfb: support new-style palette format
From: Peter Korsgaard @ 2011-10-13 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1318507395-23143-1-git-send-email-jacmet@sunsite.dk>
>>>>> "Peter" = Peter Korsgaard <jacmet@sunsite.dk> writes:
Peter> The newer Atmel SoCs use normal 16bit 565 BGR/RGB for the palette data,
Peter> rather than the special intensity + 555 format.
Peter> Fill out palette data correctly on these devices, and at the same time
Peter> respect the RGB/BGR wiring mode.
Ups, wrong patch - This has RGB/BGR modes swapped. Will resend.
--
Bye, Peter Korsgaard
^ permalink raw reply
* [PATCH] atmel_lcdfb: support new-style palette format
From: Peter Korsgaard @ 2011-10-13 12:03 UTC (permalink / raw)
To: linux-arm-kernel
The newer Atmel SoCs use normal 16bit 565 BGR/RGB for the palette data,
rather than the special intensity + 555 format.
Fill out palette data correctly on these devices, and at the same time
respect the RGB/BGR wiring mode.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
drivers/video/atmel_lcdfb.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 63409c1..0e8c38e 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -682,14 +682,30 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
case FB_VISUAL_PSEUDOCOLOR:
if (regno < 256) {
- val = ((red >> 11) & 0x001f);
- val |= ((green >> 6) & 0x03e0);
- val |= ((blue >> 1) & 0x7c00);
-
- /*
- * TODO: intensity bit. Maybe something like
- * ~(red[10] ^ green[10] ^ blue[10]) & 1
- */
+ if (cpu_is_at91sam9261() || cpu_is_at91sam9263()
+ || cpu_is_at91sam9rl()) {
+ /* old style I+BGR:555 */
+ val = ((red >> 11) & 0x001f);
+ val |= ((green >> 6) & 0x03e0);
+ val |= ((blue >> 1) & 0x7c00);
+
+ /*
+ * TODO: intensity bit. Maybe something like
+ * ~(red[10] ^ green[10] ^ blue[10]) & 1
+ */
+ } else {
+ /* new style BGR:565 / RGB:565 */
+ if (sinfo->lcd_wiring_mode =
+ ATMEL_LCDC_WIRING_RGB) {
+ val = ((red >> 11) & 0x001f);
+ val |= ((blue >> 0) & 0xf800);
+ } else {
+ val = ((blue >> 11) & 0x001f);
+ val |= ((red >> 0) & 0xf800);
+ }
+
+ val |= ((green >> 5) & 0x07e0);
+ }
lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
ret = 0;
--
1.7.6.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox