* [PATCH v3 01/29] 68328fb: use display information in info not in var for panning
From: Laurent Pinchart @ 2011-07-08 11:14 UTC (permalink / raw)
To: linux-fbdev
We must not use any information in the passed var besides xoffset,
yoffset and vmode as otherwise applications might abuse it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/68328fb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 75a39ea..a425d65 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -378,8 +378,8 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
|| var->xoffset)
return -EINVAL;
} else {
- if (var->xoffset + var->xres > info->var.xres_virtual ||
- var->yoffset + var->yres > info->var.yres_virtual)
+ if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
info->var.xoffset = var->xoffset;
--
1.7.3.4
^ permalink raw reply related
* [PATCH v3 00/29] Use display information in info not in var for panning
From: Laurent Pinchart @ 2011-07-08 11:14 UTC (permalink / raw)
To: linux-fbdev
Hi everybody,
Here's the third version of the FBIOPAN_DISPLAY fixes patch series.
As a reminder, while playing with the FBIOPAN_DISPLAY ioctl I noticed that many
drivers use information from the ioctl argument such as the display resolution
when they should use the current settings from the fb_info structure.
These 29 patches fix most of those drivers. Missing drivers are ivtv (for
which a patch has Andy Walls has already pushed a patch), sh_mobile_lcdcfb (for
which the fix is a bit more complex, I will work on it later) and viafb (for
which Florian Tobias Schandinat has already sent a patch).
The patches have been compile-tested on architectures for which I have a
working compiler (x86 and ARM) with allyesconfig. I don't own any hardware
supported by these drivers so I haven't been able to perform additional tests.
I've split the fixes in one patch per driver for easier review and handling of
potential problems. The patches can be squashed together if needed. I've tried
to CC individual driver maintainers when possible, and Acked-by lines received
in reply to the first version have been included.
Compared to v2, I've fixed a compile issue in the atmel_lcdfb driver and added
a couple of SoB lines.
Paul, is it time to push this for 3.1 ?
Laurent Pinchart (29):
68328fb: use display information in info not in var for panning
acornfb: Dont BUG() on invalid pan parameters
acornfb: use display information in info not in var for panning
arkfb: use display information in info not in var for panning
atmel_lcdfb: use display information in info not in var for panning
radeonfb: use display information in info not in var for panning
fbdev: da8xx: use display information in info not in var for panning
fbdev: unicore32: use display information in info not in var for
panning
g364fb: use display information in info not in var for panning
gxt4500: use display information in info not in var for panning
hgafb: use display information in info not in var for panning
imsttfb: use display information in info not in var for panning
intelfb: use display information in info not in var for panning
mb862xxfb: use display information in info not in var for panning
mx3fb: use display information in info not in var for panning
neofb: use display information in info not in var for panning
pm2fb: use display information in info not in var for panning
pm3fb: use display information in info not in var for panning
s3c-fb: use display information in info not in var for panning
s3fb: use display information in info not in var for panning
savagefb: use display information in info not in var for panning
sisfb: use display information in info not in var for panning
sm501fb: use display information in info not in var for panning
tridentfb: use display information in info not in var for panning
vfb: use display information in info not in var for panning
vga16fb: use display information in info not in var for panning
vt8500lcdfb: use display information in info not in var for panning
vt8623fb: use display information in info not in var for panning
staging: xgifb: use display information in info not in var for
panning
drivers/staging/xgifb/XGI_main_26.c | 22 ++++++----------------
drivers/video/68328fb.c | 4 ++--
drivers/video/acornfb.c | 5 +++--
drivers/video/arkfb.c | 9 +++++----
drivers/video/atmel_lcdfb.c | 15 +++++++++------
drivers/video/aty/radeon_base.c | 10 +++++-----
drivers/video/da8xx-fb.c | 4 ++--
drivers/video/fb-puv3.c | 4 ++--
drivers/video/g364fb.c | 5 +++--
drivers/video/gxt4500.c | 4 ++--
drivers/video/hgafb.c | 4 ++--
drivers/video/imsttfb.c | 2 +-
drivers/video/intelfb/intelfbhw.c | 6 +++---
drivers/video/mb862xx/mb862xxfbdrv.c | 2 +-
drivers/video/mx3fb.c | 6 +++---
drivers/video/neofb.c | 4 ++--
drivers/video/pm2fb.c | 4 ++--
drivers/video/pm3fb.c | 4 ++--
drivers/video/s3c-fb.c | 2 +-
drivers/video/s3fb.c | 7 ++++---
drivers/video/savage/savagefb_driver.c | 16 +++++++---------
drivers/video/sis/sis_main.c | 30 ++++++++++--------------------
drivers/video/sm501fb.c | 6 +++---
drivers/video/tridentfb.c | 4 ++--
drivers/video/vfb.c | 4 ++--
drivers/video/vga16fb.c | 2 +-
drivers/video/vt8500lcdfb.c | 4 ++--
drivers/video/vt8623fb.c | 9 +++++----
28 files changed, 92 insertions(+), 106 deletions(-)
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH] ARM: OMAP2+ Add Primview dispalys to panel-generic
From: Jan Weitzel @ 2011-07-08 10:47 UTC (permalink / raw)
To: linux-arm-kernel
Add displays to panel-generic-dpi.c
Prime View PD035VL1 (640 x 480)
Prime View PD050VL1 (640 x 480)
Prime View PD104SLF (800 x 600)
Prime View PM070WL4 (800 x 480)
Signed-off-by: Jan Weitzel <j.weitzel@phytec.de>
---
drivers/video/omap2/displays/panel-generic-dpi.c | 100 ++++++++++++++++++++++
1 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 9c90f75..87d9ba1 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -232,6 +232,106 @@ static struct panel_config generic_dpi_panels[] = {
.power_off_delay = 0,
.name = "powertip_ph480272t",
},
+
+ /* Prime-View PD035VL1 */
+ {
+ {
+ .x_res = 640,
+ .y_res = 480,
+
+ .pixel_clock = 25000,
+
+ .hsw = 96,
+ .hfp = 18,
+ .hbp = 46,
+
+ .vsw = 2,
+ .vfp = 10,
+ .vbp = 33,
+ },
+ .acbi = 0x0,
+ .acb = 0x28,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+ .power_on_delay = 50,
+ .power_off_delay = 100,
+ .name = "pd035vl1",
+ },
+
+ /* Prime-View PD050VL1 */
+ {
+ {
+ .x_res = 640,
+ .y_res = 480,
+
+ .pixel_clock = 25000,
+
+ .hsw = 96,
+ .hfp = 18,
+ .hbp = 46,
+
+ .vsw = 2,
+ .vfp = 10,
+ .vbp = 33,
+ },
+ .acbi = 0x0,
+ .acb = 0x28,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+ .power_on_delay = 50,
+ .power_off_delay = 100,
+ .name = "pd050vl1",
+ },
+
+ /* Prime-View PM070WL4 */
+ {
+ {
+ .x_res = 800,
+ .y_res = 480,
+
+ .pixel_clock = 32000,
+
+ .hsw = 128,
+ .hfp = 42,
+ .hbp = 86,
+
+ .vsw = 2,
+ .vfp = 10,
+ .vbp = 33,
+ },
+ .acbi = 0x0,
+ .acb = 0x28,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+ .power_on_delay = 50,
+ .power_off_delay = 100,
+ .name = "pm070wl4",
+ },
+
+ /* Prime-View PD104SLF */
+ {
+ {
+ .x_res = 800,
+ .y_res = 600,
+
+ .pixel_clock = 40000,
+
+ .hsw = 128,
+ .hfp = 42,
+ .hbp = 86,
+
+ .vsw = 4,
+ .vfp = 1,
+ .vbp = 23,
+ },
+ .acbi = 0x0,
+ .acb = 0x28,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+ .power_on_delay = 50,
+ .power_off_delay = 100,
+ .name = "pd104slf",
+ },
};
struct panel_drv_data {
--
1.7.0.4
^ permalink raw reply related
* [PATCH] carminefb: Fix module parameters permissions
From: Jean Delvare @ 2011-07-08 9:04 UTC (permalink / raw)
To: linux-fbdev
The third parameter of module_param is supposed to be an octal value.
The missing leading "0" causes the following:
$ ls -l /sys/module/carminefb/parameters/
total 0
-rw-rwxr-- 1 root root 4096 Jul 8 08:55 fb_displays
-rw-rwxr-- 1 root root 4096 Jul 8 08:55 fb_mode
-rw-rwxr-- 1 root root 4096 Jul 8 08:55 fb_mode_str
After fixing the perm parameter, we get the expected:
$ ls -l /sys/module/carminefb/parameters/
total 0
-r--r--r-- 1 root root 4096 Jul 8 08:56 fb_displays
-r--r--r-- 1 root root 4096 Jul 8 08:56 fb_mode
-r--r--r-- 1 root root 4096 Jul 8 08:56 fb_mode_str
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: stable@kernel.org
---
drivers/video/carminefb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- linux-3.0-rc6.orig/drivers/video/carminefb.c 2011-07-08 08:47:52.000000000 +0200
+++ linux-3.0-rc6/drivers/video/carminefb.c 2011-07-08 08:55:21.000000000 +0200
@@ -32,11 +32,11 @@
#define CARMINEFB_DEFAULT_VIDEO_MODE 1
static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
-module_param(fb_mode, uint, 444);
+module_param(fb_mode, uint, 0444);
MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
static char *fb_mode_str;
-module_param(fb_mode_str, charp, 444);
+module_param(fb_mode_str, charp, 0444);
MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
/*
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial v
* 0b010 Display 1
*/
static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
-module_param(fb_displays, int, 444);
+module_param(fb_displays, int, 0444);
MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
struct carmine_hw {
--
Jean Delvare
Suse L3
^ permalink raw reply
* [PATCH] backlight/ep93xx_bl: fix section mismatch
From: H Hartley Sweeten @ 2011-07-07 18:56 UTC (permalink / raw)
To: Linux Kernel; +Cc: linux-fbdev, rpurdie, lethal
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Paul Mundt <lethal@linux-sh.org>
---
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index 9f1e389..91dce60 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -65,7 +65,7 @@ static const struct backlight_ops ep93xxbl_ops = {
.get_brightness = ep93xxbl_get_brightness,
};
-static int __init ep93xxbl_probe(struct platform_device *dev)
+static int __devinit ep93xxbl_probe(struct platform_device *dev)
{
struct ep93xxbl *ep93xxbl;
struct backlight_device *bl;
@@ -103,7 +103,7 @@ static int __init ep93xxbl_probe(struct platform_device *dev)
return 0;
}
-static int ep93xxbl_remove(struct platform_device *dev)
+static int __devexit ep93xxbl_remove(struct platform_device *dev)
{
struct backlight_device *bl = platform_get_drvdata(dev);
^ permalink raw reply related
* [PATCH] drivers/video: use strings to specify the Freescale DIU monitor port
From: Timur Tabi @ 2011-07-07 16:51 UTC (permalink / raw)
To: kumar.gala, lethal, linuxppc-dev, linux-fbdev
Instead of using ill-defined numbers (0, 1, and 2) for the monitor port, allow
the user to specify the port by name ("dvi", "lvds", or "dlvds"). This works
on the kernel command line, the module command-line, and the sysfs "monitor"
device.
Note that changing the monitor port does not currently work on the P1022DS,
because the code that talks to the PIXIS FPGA is broken.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/platforms/512x/mpc512x_shared.c | 22 +++-----
arch/powerpc/platforms/85xx/p1022_ds.c | 47 ++++++++---------
arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 55 +++++++++-----------
arch/powerpc/sysdev/fsl_soc.h | 25 ++++++---
drivers/video/fsl-diu-fb.c | 73 +++++++++++++++++++------
5 files changed, 128 insertions(+), 94 deletions(-)
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index e41ebbd..3dc62f9 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -66,8 +66,8 @@ struct fsl_diu_shared_fb {
bool in_use;
};
-unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
- int monitor_port)
+u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
+ unsigned int bits_per_pixel)
{
switch (bits_per_pixel) {
case 32:
@@ -80,11 +80,12 @@ unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
return 0x00000400;
}
-void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
+ char *gamma_table_base)
{
}
-void mpc512x_set_monitor_port(int monitor_port)
+void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
{
}
@@ -182,14 +183,10 @@ void mpc512x_set_pixel_clock(unsigned int pixclock)
iounmap(ccm);
}
-ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf)
+enum fsl_diu_monitor_port
+mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
{
- return sprintf(buf, "0 - 5121 LCD\n");
-}
-
-int mpc512x_set_sysfs_monitor_port(int val)
-{
- return 0;
+ return FSL_DIU_PORT_DVI;
}
static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
@@ -332,8 +329,7 @@ void __init mpc512x_setup_diu(void)
diu_ops.set_gamma_table = mpc512x_set_gamma_table;
diu_ops.set_monitor_port = mpc512x_set_monitor_port;
diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
- diu_ops.show_monitor_port = mpc512x_show_monitor_port;
- diu_ops.set_sysfs_monitor_port = mpc512x_set_sysfs_monitor_port;
+ diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
diu_ops.release_bootmem = mpc512x_release_bootmem;
#endif
}
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 266b3aa..c01c727 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -93,8 +93,8 @@
* The Area Descriptor is a 32-bit value that determine which bits in each
* pixel are to be used for each color.
*/
-static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
- int monitor_port)
+static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port,
+ unsigned int bits_per_pixel)
{
switch (bits_per_pixel) {
case 32:
@@ -118,7 +118,8 @@ static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
* On some boards, the gamma table for some ports may need to be modified.
* This is not the case on the P1022DS, so we do nothing.
*/
-static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
+static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
+ char *gamma_table_base)
{
}
@@ -126,7 +127,7 @@ static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
* p1022ds_set_monitor_port: switch the output to a different monitor port
*
*/
-static void p1022ds_set_monitor_port(int monitor_port)
+static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
{
struct device_node *pixis_node;
void __iomem *pixis;
@@ -145,19 +146,21 @@ static void p1022ds_set_monitor_port(int monitor_port)
}
brdcfg1 = pixis + 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */
- switch (monitor_port) {
- case 0: /* DVI */
+ switch (port) {
+ case FSL_DIU_PORT_DVI:
+ printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DVI port, disable the DFP and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DVIEN);
break;
- case 1: /* Single link LVDS */
+ case FSL_DIU_PORT_LVDS:
+ printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DFP port, disable the DVI and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DFPEN);
break;
default:
- pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
+ pr_err("p1022ds: unsupported monitor port %i\n", port);
}
iounmap(pixis);
@@ -214,23 +217,18 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
}
/**
- * p1022ds_show_monitor_port: show the current monitor
- *
- * This function returns a string indicating whether the current monitor is
- * set to DVI or LVDS.
- */
-ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
-{
- return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
- monitor_port = 0 ? '*' : ' ', monitor_port = 1 ? '*' : ' ');
-}
-
-/**
- * p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
+ * p1022ds_valid_monitor_port: set the monitor port for sysfs
*/
-int p1022ds_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
{
- return val < 2 ? val : 0;
+ switch (port) {
+ case FSL_DIU_PORT_DVI:
+ case FSL_DIU_PORT_LVDS:
+ return port;
+ default:
+ return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
+ }
}
#endif
@@ -305,8 +303,7 @@ static void __init p1022_ds_setup_arch(void)
diu_ops.set_gamma_table = p1022ds_set_gamma_table;
diu_ops.set_monitor_port = p1022ds_set_monitor_port;
diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
- diu_ops.show_monitor_port = p1022ds_show_monitor_port;
- diu_ops.set_sysfs_monitor_port = p1022ds_set_sysfs_monitor_port;
+ diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
#endif
#ifdef CONFIG_SMP
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 74e018e..13fa9a6 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -152,10 +152,10 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
(c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
(c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
-unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
- int monitor_port)
+u32 mpc8610hpcd_get_pixel_format(enum fsl_diu_monitor_port port,
+ unsigned int bits_per_pixel)
{
- static const unsigned long pixelformat[][3] = {
+ static const u32 pixelformat[][3] = {
{
MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
@@ -170,7 +170,8 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
unsigned int arch_monitor;
/* The DVI port is mis-wired on revision 1 of this board. */
- arch_monitor = ((*pixis_arch = 0x01) && (monitor_port = 0))? 0 : 1;
+ arch_monitor + ((*pixis_arch = 0x01) && (port = FSL_DIU_PORT_DVI)) ? 0 : 1;
switch (bits_per_pixel) {
case 32:
@@ -185,10 +186,11 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
}
}
-void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc8610hpcd_set_gamma_table(enum fsl_diu_monitor_port port,
+ char *gamma_table_base)
{
int i;
- if (monitor_port = 2) { /* dual link LVDS */
+ if (port = FSL_DIU_PORT_DLVDS) {
for (i = 0; i < 256*3; i++)
gamma_table_base[i] = (gamma_table_base[i] << 2) |
((gamma_table_base[i] >> 6) & 0x03);
@@ -199,17 +201,21 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
#define PX_BRDCFG0_DLINK (1 << 4)
#define PX_BRDCFG0_DIU_MASK (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK)
-void mpc8610hpcd_set_monitor_port(int monitor_port)
+void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port)
{
- static const u8 bdcfg[] = {
- PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK,
- PX_BRDCFG0_DLINK,
- 0,
- };
-
- if (monitor_port < 3)
+ switch (port) {
+ case FSL_DIU_PORT_DVI:
clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
- bdcfg[monitor_port]);
+ PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK);
+ break;
+ case FSL_DIU_PORT_LVDS:
+ clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
+ PX_BRDCFG0_DLINK);
+ break;
+ case FSL_DIU_PORT_DLVDS:
+ clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK);
+ break;
+ }
}
/**
@@ -262,20 +268,10 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
iounmap(guts);
}
-ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf)
-{
- return snprintf(buf, PAGE_SIZE,
- "%c0 - DVI\n"
- "%c1 - Single link LVDS\n"
- "%c2 - Dual link LVDS\n",
- monitor_port = 0 ? '*' : ' ',
- monitor_port = 1 ? '*' : ' ',
- monitor_port = 2 ? '*' : ' ');
-}
-
-int mpc8610hpcd_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port)
{
- return val < 3 ? val : 0;
+ return port;
}
#endif
@@ -307,8 +303,7 @@ static void __init mpc86xx_hpcd_setup_arch(void)
diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table;
diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port;
diu_ops.set_pixel_clock = mpc8610hpcd_set_pixel_clock;
- diu_ops.show_monitor_port = mpc8610hpcd_show_monitor_port;
- diu_ops.set_sysfs_monitor_port = mpc8610hpcd_set_sysfs_monitor_port;
+ diu_ops.valid_monitor_port = mpc8610hpcd_valid_monitor_port;
#endif
pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 5360948..064bc70 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -22,15 +22,24 @@ struct device_node;
extern void fsl_rstcr_restart(char *cmd);
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+
+/* The different ports that the DIU can be connected to */
+enum fsl_diu_monitor_port {
+ FSL_DIU_PORT_DVI, /* DVI */
+ FSL_DIU_PORT_LVDS, /* Single-link LVDS */
+ FSL_DIU_PORT_DLVDS /* Dual-link LVDS */
+};
+
struct platform_diu_data_ops {
- unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
- int monitor_port);
- void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
- void (*set_monitor_port) (int monitor_port);
- void (*set_pixel_clock) (unsigned int pixclock);
- ssize_t (*show_monitor_port) (int monitor_port, char *buf);
- int (*set_sysfs_monitor_port) (int val);
- void (*release_bootmem) (void);
+ u32 (*get_pixel_format)(enum fsl_diu_monitor_port port,
+ unsigned int bpp);
+ void (*set_gamma_table)(enum fsl_diu_monitor_port port,
+ char *gamma_table_base);
+ void (*set_monitor_port)(enum fsl_diu_monitor_port port);
+ void (*set_pixel_clock)(unsigned int pixclock);
+ enum fsl_diu_monitor_port (*valid_monitor_port)
+ (enum fsl_diu_monitor_port port);
+ void (*release_bootmem)(void);
};
extern struct platform_diu_data_ops diu_ops;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 0acc7d6..9c6837e 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -31,8 +31,6 @@
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/of_platform.h>
-
#include <sysdev/fsl_soc.h>
#include <linux/fsl-diu-fb.h>
#include "edid.h"
@@ -183,7 +181,8 @@ static struct fb_videomode __devinitdata fsl_diu_mode_db[] = {
static char *fb_mode = "1024x768-32@60";
static unsigned long default_bpp = 32;
-static int monitor_port;
+static enum fsl_diu_monitor_port monitor_port;
+static char *monitor_string;
#if defined(CONFIG_NOT_COHERENT_CACHE)
static u8 *coherence_data;
@@ -201,7 +200,7 @@ struct fsl_diu_data {
void *dummy_aoi_virt;
unsigned int irq;
int fb_enabled;
- int monitor_port;
+ enum fsl_diu_monitor_port monitor_port;
};
struct mfb_info {
@@ -282,6 +281,37 @@ static struct diu_hw dr = {
static struct diu_pool pool;
/**
+ * fsl_diu_name_to_port - convert a port name to a monitor port enum
+ *
+ * Takes the name of a monitor port ("dvi", "lvds", or "dlvds") and returns
+ * the enum fsl_diu_monitor_port that corresponds to that string.
+ *
+ * For compatibility with older versions, a number ("0", "1", or "2") is also
+ * supported.
+ *
+ * If the string is unknown, DVI is assumed.
+ *
+ * If the particular port is not supported by the platform, another port
+ * (platform-specific) is chosen instead.
+ */
+static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
+{
+ enum fsl_diu_monitor_port port = FSL_DIU_PORT_DVI;
+ unsigned long val;
+
+ if (s) {
+ if (!strict_strtoul(s, 10, &val) && (val <= 2))
+ port = (enum fsl_diu_monitor_port) val;
+ else if (strncmp(s, "lvds", 4) = 0)
+ port = FSL_DIU_PORT_LVDS;
+ else if (strncmp(s, "dlvds", 5) = 0)
+ port = FSL_DIU_PORT_DLVDS;
+ }
+
+ return diu_ops.valid_monitor_port(port);
+}
+
+/**
* fsl_diu_alloc - allocate memory for the DIU
* @size: number of bytes to allocate
* @param: returned physical address of memory
@@ -832,8 +862,8 @@ static int fsl_diu_set_par(struct fb_info *info)
}
ad->pix_fmt - diu_ops.get_pixel_format(var->bits_per_pixel,
- machine_data->monitor_port);
+ cpu_to_be32(diu_ops.get_pixel_format(machine_data->monitor_port,
+ var->bits_per_pixel));
ad->addr = cpu_to_le32(info->fix.smem_start);
ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
var->xres_virtual) | mfbi->g_alpha;
@@ -1439,16 +1469,12 @@ static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
static ssize_t store_monitor(struct device *device,
struct device_attribute *attr, const char *buf, size_t count)
{
- int old_monitor_port;
- unsigned long val;
+ enum fsl_diu_monitor_port old_monitor_port;
struct fsl_diu_data *machine_data container_of(attr, struct fsl_diu_data, dev_attr);
- if (strict_strtoul(buf, 10, &val))
- return 0;
-
old_monitor_port = machine_data->monitor_port;
- machine_data->monitor_port = diu_ops.set_sysfs_monitor_port(val);
+ machine_data->monitor_port = fsl_diu_name_to_port(buf);
if (old_monitor_port != machine_data->monitor_port) {
/* All AOIs need adjust pixel format
@@ -1468,7 +1494,17 @@ static ssize_t show_monitor(struct device *device,
{
struct fsl_diu_data *machine_data container_of(attr, struct fsl_diu_data, dev_attr);
- return diu_ops.show_monitor_port(machine_data->monitor_port, buf);
+
+ switch (machine_data->monitor_port) {
+ case FSL_DIU_PORT_DVI:
+ return sprintf(buf, "DVI\n");
+ case FSL_DIU_PORT_LVDS:
+ return sprintf(buf, "Single-link LVDS\n");
+ case FSL_DIU_PORT_DLVDS:
+ return sprintf(buf, "Dual-link LVDS\n");
+ }
+
+ return 0;
}
static int __devinit fsl_diu_probe(struct platform_device *ofdev)
@@ -1692,8 +1728,7 @@ static int __init fsl_diu_setup(char *options)
if (!*opt)
continue;
if (!strncmp(opt, "monitor=", 8)) {
- if (!strict_strtoul(opt + 8, 10, &val) && (val <= 2))
- monitor_port = val;
+ monitor_port = fsl_diu_name_to_port(opt + 8);
} else if (!strncmp(opt, "bpp=", 4)) {
if (!strict_strtoul(opt + 4, 10, &val))
default_bpp = val;
@@ -1746,6 +1781,8 @@ static int __init fsl_diu_init(void)
if (fb_get_options("fslfb", &option))
return -ENODEV;
fsl_diu_setup(option);
+#else
+ monitor_port = fsl_diu_name_to_port(monitor_string);
#endif
printk(KERN_INFO "Freescale DIU driver\n");
@@ -1812,7 +1849,7 @@ MODULE_PARM_DESC(mode,
"Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
module_param_named(bpp, default_bpp, ulong, 0);
MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
-module_param_named(monitor, monitor_port, int, 0);
-MODULE_PARM_DESC(monitor,
- "Specify the monitor port (0, 1 or 2) if supported by the platform");
+module_param_named(monitor, monitor_string, charp, 0);
+MODULE_PARM_DESC(monitor, "Specify the monitor port "
+ "(\"dvi\", \"lvds\", or \"dlvds\") if supported by the platform");
--
1.7.3.4
^ permalink raw reply related
* [PATCH] video: s3c2410: remove unused variable
From: Wolfram Sang @ 2011-07-07 10:20 UTC (permalink / raw)
To: linux-fbdev
Fixes:
drivers/video/s3c2410fb.c: In function 's3c2410fb_cpufreq_transition':
drivers/video/s3c2410fb.c:770:24: warning: unused variable 'freqs'
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Paul Mundt <lethal@linux-sh.org>
---
drivers/video/s3c2410fb.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 0aa1376..798144a 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -767,7 +767,6 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
unsigned long val, void *data)
{
- struct cpufreq_freqs *freqs = data;
struct s3c2410fb_info *info;
struct fb_info *fbinfo;
long delta_f;
--
1.7.5.4
^ permalink raw reply related
* [PATCH] OMAPFB: make debug message more useful
From: Andy Doan @ 2011-07-06 17:08 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: Tomi Valkeinen, Andy Doan
Make the debug message useful by printing the name of the device
that no associated driver could be found for.
Signed-off-by: Andy Doan <andy.doan@linaro.org>
---
drivers/video/omap2/omapfb/omapfb-main.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 602b71a..e5a64b3 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2373,7 +2373,8 @@ static int omapfb_probe(struct platform_device *pdev)
omap_dss_get_device(dssdev);
if (!dssdev->driver) {
- dev_err(&pdev->dev, "no driver for display\n");
+ dev_err(&pdev->dev, "no driver for display: %s\n",
+ dssdev->name);
r = -ENODEV;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH] video: output: remove video_output_{register,unregister}
From: Pavel Roskin @ 2011-07-06 15:02 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Pavel Roskin <proski@gnu.org>
video_output_register() and video_output_unregister() are not called
anywhere in the kernel code. Also remove the fallback implementation
from the header.
---
drivers/video/output.c | 38 --------------------------------------
include/linux/video_output.h | 19 -------------------
2 files changed, 0 insertions(+), 57 deletions(-)
diff --git a/drivers/video/output.c b/drivers/video/output.c
index 0d6f2cd..858b6d1 100644
--- a/drivers/video/output.c
+++ b/drivers/video/output.c
@@ -81,44 +81,6 @@ static struct class video_output_class = {
.dev_attrs = video_output_attributes,
};
-struct output_device *video_output_register(const char *name,
- struct device *dev,
- void *devdata,
- struct output_properties *op)
-{
- struct output_device *new_dev;
- int ret_code = 0;
-
- new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL);
- if (!new_dev) {
- ret_code = -ENOMEM;
- goto error_return;
- }
- new_dev->props = op;
- new_dev->dev.class = &video_output_class;
- new_dev->dev.parent = dev;
- dev_set_name(&new_dev->dev, name);
- dev_set_drvdata(&new_dev->dev, devdata);
- ret_code = device_register(&new_dev->dev);
- if (ret_code) {
- kfree(new_dev);
- goto error_return;
- }
- return new_dev;
-
-error_return:
- return ERR_PTR(ret_code);
-}
-EXPORT_SYMBOL(video_output_register);
-
-void video_output_unregister(struct output_device *dev)
-{
- if (!dev)
- return;
- device_unregister(&dev->dev);
-}
-EXPORT_SYMBOL(video_output_unregister);
-
static void __exit video_output_class_exit(void)
{
class_unregister(&video_output_class);
diff --git a/include/linux/video_output.h b/include/linux/video_output.h
index ed5cdeb..be03118 100644
--- a/include/linux/video_output.h
+++ b/include/linux/video_output.h
@@ -35,23 +35,4 @@ struct output_device {
struct device dev;
};
#define to_output_device(obj) container_of(obj, struct output_device, dev)
-#if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
-struct output_device *video_output_register(const char *name,
- struct device *dev,
- void *devdata,
- struct output_properties *op);
-void video_output_unregister(struct output_device *dev);
-#else
-static struct output_device *video_output_register(const char *name,
- struct device *dev,
- void *devdata,
- struct output_properties *op)
-{
- return ERR_PTR(-ENODEV);
-}
-static void video_output_unregister(struct output_device *dev)
-{
- return;
-}
-#endif
#endif
^ permalink raw reply related
* [PATCH] drivers/video/udlfb bind framebuffer to interface.
From: bernie @ 2011-07-06 0:04 UTC (permalink / raw)
To: linux-fbdev
From: Kay Sievers <kay.sievers@vrfy.org>
Udlfb has been binding the framebuffer device to its parent, which
isn't correct and causes confusion with operations like udev remove.
Coming plug and play multiseat support is dependent on this fix.
Signed-off-by: Bernie Thompson <bernie@plugable.com>
---
drivers/video/udlfb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 816a4fd..c6584c9 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1549,7 +1549,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
/* We don't register a new USB class. Our client interface is fbdev */
/* allocates framebuffer driver structure, not framebuffer memory */
- info = framebuffer_alloc(0, &usbdev->dev);
+ info = framebuffer_alloc(0, &interface->dev);
if (!info) {
retval = -ENOMEM;
pr_err("framebuffer_alloc failed\n");
--
1.7.4.1
^ permalink raw reply related
* [PATCH v2] video: da8xx-fb: Interrupt configuration of revised LCDC IP
From: Manjunathappa, Prakash @ 2011-07-05 10:33 UTC (permalink / raw)
To: linux-fbdev
An upcoming SoC of TI comes with an LCD controller which is an updated
version of that found on TI's DA850 SoC. The da8xx-fb driver can support
this LCD with some enhancements.
This patch adds support for updated interrupt configuration on the new
SoC.
1) Registers for setting and clearing interrupts are different.
2) Raw and masked status registers are different.
The updates have been tested on an emulation platform for new features
and the patch has been tested on DA850 platform to make sure nothing
existing breaks.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
Since v1:
1)Added verification details in commit message.
2)Removed random white spaces in code.
drivers/video/da8xx-fb.c | 151 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 142 insertions(+), 9 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index fcdac87..620f1c3 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -35,6 +35,9 @@
#define DRIVER_NAME "da8xx_lcdc"
+#define LCD_VERSION_1 1
+#define LCD_VERSION_2 2
+
/* LCD Status Register */
#define LCD_END_OF_FRAME1 BIT(9)
#define LCD_END_OF_FRAME0 BIT(8)
@@ -49,7 +52,9 @@
#define LCD_DMA_BURST_4 0x2
#define LCD_DMA_BURST_8 0x3
#define LCD_DMA_BURST_16 0x4
-#define LCD_END_OF_FRAME_INT_ENA BIT(2)
+#define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
+#define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
+#define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
/* LCD Control Register */
@@ -65,12 +70,18 @@
#define LCD_MONO_8BIT_MODE BIT(9)
#define LCD_RASTER_ORDER BIT(8)
#define LCD_TFT_MODE BIT(7)
-#define LCD_UNDERFLOW_INT_ENA BIT(6)
-#define LCD_PL_ENABLE BIT(4)
+#define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
+#define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
+#define LCD_V1_PL_INT_ENA BIT(4)
+#define LCD_V2_PL_INT_ENA BIT(6)
#define LCD_MONOCHROME_MODE BIT(1)
#define LCD_RASTER_ENABLE BIT(0)
#define LCD_TFT_ALT_ENABLE BIT(23)
#define LCD_STN_565_ENABLE BIT(24)
+#define LCD_V2_DMA_CLK_EN BIT(2)
+#define LCD_V2_LIDD_CLK_EN BIT(1)
+#define LCD_V2_CORE_CLK_EN BIT(0)
+#define LCD_V2_LPP_B10 26
/* LCD Raster Timing 2 Register */
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
@@ -82,6 +93,7 @@
#define LCD_INVERT_FRAME_CLOCK BIT(20)
/* LCD Block */
+#define LCD_PID_REG 0x0
#define LCD_CTRL_REG 0x4
#define LCD_STAT_REG 0x8
#define LCD_RASTER_CTRL_REG 0x28
@@ -94,6 +106,17 @@
#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
+/* Interrupt Registers available only in Version 2 */
+#define LCD_RAW_STAT_REG 0x58
+#define LCD_MASKED_STAT_REG 0x5c
+#define LCD_INT_ENABLE_SET_REG 0x60
+#define LCD_INT_ENABLE_CLR_REG 0x64
+#define LCD_END_OF_INT_IND_REG 0x68
+
+/* Clock registers available only on Version 2 */
+#define LCD_CLK_ENABLE_REG 0x6c
+#define LCD_CLK_RESET_REG 0x70
+
#define LCD_NUM_BUFFERS 2
#define WSI_TIMEOUT 50
@@ -105,6 +128,8 @@
static resource_size_t da8xx_fb_reg_base;
static struct resource *lcdc_regs;
+static unsigned int lcd_revision;
+static irq_handler_t lcdc_irq_handler;
static inline unsigned int lcdc_read(unsigned int addr)
{
@@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
u32 end;
u32 reg_ras;
u32 reg_dma;
+ u32 reg_int;
/* init reg to clear PLM (loading mode) fields */
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
@@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
end = par->dma_end;
reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
- reg_dma |= LCD_END_OF_FRAME_INT_ENA;
+ if (lcd_revision = LCD_VERSION_1) {
+ reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
+ } else {
+ reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+ LCD_V2_END_OF_FRAME0_INT_ENA |
+ LCD_V2_END_OF_FRAME1_INT_ENA;
+ lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+ }
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
@@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
end = start + par->palette_sz - 1;
reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
- reg_ras |= LCD_PL_ENABLE;
+
+ if (lcd_revision = LCD_VERSION_1) {
+ reg_ras |= LCD_V1_PL_INT_ENA;
+ } else {
+ reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+ LCD_V2_PL_INT_ENA;
+ lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+ }
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
@@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
{
u32 reg;
+ u32 reg_int;
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
LCD_MONO_8BIT_MODE |
@@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
}
/* enable additional interrupts here */
- reg |= LCD_UNDERFLOW_INT_ENA;
+ if (lcd_revision = LCD_VERSION_1) {
+ reg |= LCD_V1_UNDERFLOW_INT_ENA;
+ } else {
+ reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+ LCD_V2_UNDERFLOW_INT_ENA;
+ lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+ }
lcdc_write(reg, LCD_RASTER_CTRL_REG);
@@ -511,6 +558,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
/* DMA has to be disabled */
lcdc_write(0, LCD_DMA_CTRL_REG);
lcdc_write(0, LCD_RASTER_CTRL_REG);
+
+ if (lcd_revision = LCD_VERSION_2)
+ lcdc_write(0, LCD_INT_ENABLE_SET_REG);
}
static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
@@ -523,6 +573,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
+
+ if (lcd_revision = LCD_VERSION_2)
+ lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
+ LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -583,7 +638,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
return 0;
}
-static irqreturn_t lcdc_irq_handler(int irq, void *arg)
+/* IRQ handler for version 2 of LCDC */
+static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
+{
+ struct da8xx_fb_par *par = arg;
+ u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
+ u32 reg_int;
+
+ if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
+ lcd_disable_raster();
+ lcdc_write(stat, LCD_MASKED_STAT_REG);
+ lcd_enable_raster();
+ } else if (stat & LCD_PL_LOAD_DONE) {
+ /*
+ * Must disable raster before changing state of any control bit.
+ * And also must be disabled before clearing the PL loading
+ * interrupt via the following write to the status register. If
+ * this is done after then one gets multiple PL done interrupts.
+ */
+ lcd_disable_raster();
+
+ lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+ /* Disable PL completion inerrupt */
+ reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
+ (LCD_V2_PL_INT_ENA);
+ lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
+
+ /* Setup and start data loading mode */
+ lcd_blit(LOAD_DATA, par);
+ } else {
+ lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+ if (stat & LCD_END_OF_FRAME0) {
+ lcdc_write(par->dma_start,
+ LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+ lcdc_write(par->dma_end,
+ LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+ par->vsync_flag = 1;
+ wake_up_interruptible(&par->vsync_wait);
+ }
+
+ if (stat & LCD_END_OF_FRAME1) {
+ lcdc_write(par->dma_start,
+ LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+ lcdc_write(par->dma_end,
+ LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+ par->vsync_flag = 1;
+ wake_up_interruptible(&par->vsync_wait);
+ }
+ }
+
+ lcdc_write(0, LCD_END_OF_INT_IND_REG);
+ return IRQ_HANDLED;
+}
+
+/* IRQ handler for version 1 LCDC */
+static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
{
struct da8xx_fb_par *par = arg;
u32 stat = lcdc_read(LCD_STAT_REG);
@@ -606,7 +717,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
/* Disable PL completion inerrupt */
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
- reg_ras &= ~LCD_PL_ENABLE;
+ reg_ras &= ~LCD_V1_PL_INT_ENA;
lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
/* Setup and start data loading mode */
@@ -945,6 +1056,22 @@ static int __devinit fb_probe(struct platform_device *device)
if (ret)
goto err_clk_put;
+ /* Determine LCD IP Version */
+ switch (lcdc_read(LCD_PID_REG)) {
+ case 0x4C100102:
+ lcd_revision = LCD_VERSION_1;
+ break;
+ case 0x4F200800:
+ lcd_revision = LCD_VERSION_2;
+ break;
+ default:
+ dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
+ "defaulting to LCD revision 1\n",
+ lcdc_read(LCD_PID_REG));
+ lcd_revision = LCD_VERSION_1;
+ break;
+ }
+
for (i = 0, lcdc_info = known_lcd_panels;
i < ARRAY_SIZE(known_lcd_panels);
i++, lcdc_info++) {
@@ -1085,7 +1212,13 @@ static int __devinit fb_probe(struct platform_device *device)
}
#endif
- ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+ if (lcd_revision = LCD_VERSION_1)
+ lcdc_irq_handler = lcdc_irq_handler_rev01;
+ else
+ lcdc_irq_handler = lcdc_irq_handler_rev02;
+
+ ret = request_irq(par->irq, lcdc_irq_handler, 0,
+ DRIVER_NAME, par);
if (ret)
goto irq_freq;
return 0;
--
1.7.1
^ permalink raw reply related
* [PATCH v3] video: Add Aeroflex Gaisler GRVGA framebuffer device driver
From: Kristoffer Glembo @ 2011-07-05 7:29 UTC (permalink / raw)
To: linux-fbdev
This patch adds support for the GRVGA framebuffer IP core from Aeroflex Gaisler.
The device is used in LEON SPARCV8 based System on Chips. Documentation can
be found here: www.gaisler.com/products/grlib/grip.pdf.
Signed-off-by: Kristoffer Glembo <kristoffer@gaisler.com>
---
drivers/video/Kconfig | 10 +
drivers/video/Makefile | 1 +
drivers/video/grvga.c | 579 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 590 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/grvga.c
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..18ee201 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -259,6 +259,16 @@ config FB_TILEBLITTING
comment "Frame buffer hardware drivers"
depends on FB
+config FB_GRVGA
+ tristate "Aeroflex Gaisler framebuffer support"
+ depends on FB && SPARC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
+
config FB_CIRRUS
tristate "Cirrus Logic support"
depends on FB && (ZORRO || PCI)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8b83129..4cff5ec 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
# Hardware specific drivers go first
+obj-$(CONFIG_FB_GRVGA) += grvga.o
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
obj-$(CONFIG_FB_ARC) += arcfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
new file mode 100644
index 0000000..f37e025
--- /dev/null
+++ b/drivers/video/grvga.c
@@ -0,0 +1,579 @@
+/*
+ * Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
+ *
+ * 2011 (c) Aeroflex Gaisler AB
+ *
+ * Full documentation of the core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+struct grvga_regs {
+ u32 status; /* 0x00 */
+ u32 video_length; /* 0x04 */
+ u32 front_porch; /* 0x08 */
+ u32 sync_length; /* 0x0C */
+ u32 line_length; /* 0x10 */
+ u32 fb_pos; /* 0x14 */
+ u32 clk_vector[4]; /* 0x18 */
+ u32 clut; /* 0x20 */
+};
+
+struct grvga_par {
+ struct grvga_regs *regs;
+ u32 color_palette[16]; /* 16 entry pseudo palette used by fbcon in true color mode */
+ int clk_sel;
+ int fb_alloced; /* = 1 if framebuffer is allocated in main memory */
+};
+
+
+static const struct fb_videomode grvga_modedb[] = {
+ {
+ /* 640x480 @ 60 Hz */
+ NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600 @ 60 Hz */
+ NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600 @ 72 Hz */
+ NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 60 Hz */
+ NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }
+ };
+
+static struct fb_fix_screeninfo grvga_fix __initdata = {
+ .id = "AG SVGACTRL",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 0,
+ .ypanstep = 1,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
+
+static int grvga_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct grvga_par *par = info->par;
+ int i;
+
+ if (!var->xres)
+ var->xres = 1;
+ if (!var->yres)
+ var->yres = 1;
+ if (var->bits_per_pixel <= 8)
+ var->bits_per_pixel = 8;
+ else if (var->bits_per_pixel <= 16)
+ var->bits_per_pixel = 16;
+ else if (var->bits_per_pixel <= 24)
+ var->bits_per_pixel = 24;
+ else if (var->bits_per_pixel <= 32)
+ var->bits_per_pixel = 32;
+ else
+ return -EINVAL;
+
+ var->xres_virtual = var->xres;
+ var->yres_virtual = 2*var->yres;
+
+ if (info->fix.smem_len) {
+ if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
+ return -ENOMEM;
+ }
+
+ /* Which clocks that are available can be read out in these registers */
+ for (i = 0; i <= 3 ; i++) {
+ if (var->pixclock = par->regs->clk_vector[i])
+ break;
+ }
+ if (i <= 3)
+ par->clk_sel = i;
+ else
+ return -EINVAL;
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ var->red = (struct fb_bitfield) {0, 8, 0}; /* offset, length, msb-right */
+ var->green = (struct fb_bitfield) {0, 8, 0};
+ var->blue = (struct fb_bitfield) {0, 8, 0};
+ var->transp = (struct fb_bitfield) {0, 0, 0};
+ break;
+ case 16:
+ var->red = (struct fb_bitfield) {11, 5, 0};
+ var->green = (struct fb_bitfield) {5, 6, 0};
+ var->blue = (struct fb_bitfield) {0, 5, 0};
+ var->transp = (struct fb_bitfield) {0, 0, 0};
+ break;
+ case 24:
+ case 32:
+ var->red = (struct fb_bitfield) {16, 8, 0};
+ var->green = (struct fb_bitfield) {8, 8, 0};
+ var->blue = (struct fb_bitfield) {0, 8, 0};
+ var->transp = (struct fb_bitfield) {24, 8, 0};
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int grvga_set_par(struct fb_info *info)
+{
+
+ u32 func = 0;
+ struct grvga_par *par = info->par;
+
+ __raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
+ &par->regs->video_length);
+
+ __raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
+ &par->regs->front_porch);
+
+ __raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
+ &par->regs->sync_length);
+
+ __raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
+ (info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
+ &par->regs->line_length);
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ func = 1;
+ break;
+ case 16:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ func = 2;
+ break;
+ case 24:
+ case 32:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ func = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ __raw_writel((par->clk_sel << 6) | (func << 4) | 1,
+ &par->regs->status);
+
+ info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
+ return 0;
+}
+
+static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
+{
+ struct grvga_par *par;
+ par = info->par;
+
+ if (regno >= 256) /* Size of CLUT */
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+
+
+#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+ red = CNVT_TOHW(red, info->var.red.length);
+ green = CNVT_TOHW(green, info->var.green.length);
+ blue = CNVT_TOHW(blue, info->var.blue.length);
+ transp = CNVT_TOHW(transp, info->var.transp.length);
+
+#undef CNVT_TOHW
+
+ /* In PSEUDOCOLOR we use the hardware CLUT */
+ if (info->fix.visual = FB_VISUAL_PSEUDOCOLOR)
+ __raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
+ &par->regs->clut);
+
+ /* Truecolor uses the pseudo palette */
+ else if (info->fix.visual = FB_VISUAL_TRUECOLOR) {
+ u32 v;
+ if (regno >= 16)
+ return -EINVAL;
+
+
+ v = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset) |
+ (transp << info->var.transp.offset);
+
+ ((u32 *) (info->pseudo_palette))[regno] = v;
+ }
+ return 0;
+}
+
+static int grvga_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct grvga_par *par = info->par;
+ struct fb_fix_screeninfo *fix = &info->fix;
+ u32 base_addr;
+
+ if (var->xoffset != 0)
+ return -EINVAL;
+
+ base_addr = fix->smem_start + (var->yoffset * fix->line_length);
+ base_addr &= ~3UL;
+
+ /* Set framebuffer base address */
+ __raw_writel(base_addr,
+ &par->regs->fb_pos);
+
+ return 0;
+}
+
+static struct fb_ops grvga_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = grvga_check_var,
+ .fb_set_par = grvga_set_par,
+ .fb_setcolreg = grvga_setcolreg,
+ .fb_pan_display = grvga_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit
+};
+
+static int __init grvga_parse_custom(char *options,
+ struct fb_var_screeninfo *screendata)
+{
+ char *this_opt;
+ int count = 0;
+ if (!options || !*options)
+ return -1;
+
+ while ((this_opt = strsep(&options, " ")) != NULL) {
+ if (!*this_opt)
+ continue;
+
+ switch (count) {
+ case 0:
+ screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 1:
+ screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 2:
+ screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 3:
+ screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 4:
+ screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 5:
+ screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 6:
+ screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 7:
+ screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 8:
+ screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ case 9:
+ screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
+ count++;
+ break;
+ default:
+ return -1;
+ }
+ }
+ screendata->activate = FB_ACTIVATE_NOW;
+ screendata->vmode = FB_VMODE_NONINTERLACED;
+ return 0;
+}
+
+static int __devinit grvga_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int retval = -ENOMEM;
+ unsigned long virtual_start;
+ unsigned long grvga_fix_addr = 0;
+ unsigned long physical_start = 0;
+ unsigned long grvga_mem_size = 0;
+ struct grvga_par *par = NULL;
+ char *options = NULL, *mode_opt = NULL;
+
+ info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
+ if (!info) {
+ dev_err(&dev->dev, "framebuffer_alloc failed\n");
+ return -ENOMEM;
+ }
+
+ /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
+ *
+ * If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
+ * If address is left out, we allocate memory,
+ * if size is left out we only allocate enough to support the given mode.
+ */
+ if (fb_get_options("grvga", &options)) {
+ retval = -ENODEV;
+ goto err;
+ }
+
+ if (!options || !*options)
+ options = "640x480-8@60";
+
+ while (1) {
+ char *this_opt = strsep(&options, ",");
+
+ if (!this_opt)
+ break;
+
+ if (!strncmp(this_opt, "custom", 6)) {
+ if (grvga_parse_custom(this_opt, &info->var) < 0) {
+ dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
+ retval = -EINVAL;
+ goto err1;
+ }
+ } else if (!strncmp(this_opt, "addr", 4))
+ grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
+ else if (!strncmp(this_opt, "size", 4))
+ grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
+ else
+ mode_opt = this_opt;
+ }
+
+ par = info->par;
+ info->fbops = &grvga_ops;
+ info->fix = grvga_fix;
+ info->pseudo_palette = par->color_palette;
+ info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
+ info->fix.smem_len = grvga_mem_size;
+
+ if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
+ dev_err(&dev->dev, "registers already mapped\n");
+ retval = -EBUSY;
+ goto err;
+ }
+
+ par->regs = of_ioremap(&dev->resource[0], 0,
+ resource_size(&dev->resource[0]),
+ "grlib-svgactrl regs");
+
+ if (!par->regs) {
+ dev_err(&dev->dev, "failed to map registers\n");
+ retval = -ENOMEM;
+ goto err1;
+ }
+
+ retval = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (retval < 0) {
+ dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
+ retval = -ENOMEM;
+ goto err2;
+ }
+
+ if (mode_opt) {
+ retval = fb_find_mode(&info->var, info, mode_opt,
+ grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
+ if (!retval || retval = 4) {
+ retval = -EINVAL;
+ goto err3;
+ }
+ }
+
+ if (!grvga_mem_size)
+ grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
+
+ if (grvga_fix_addr) {
+ /* Got framebuffer base address from argument list */
+
+ physical_start = grvga_fix_addr;
+
+ if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
+ dev_err(&dev->dev, "failed to request memory region\n");
+ retval = -ENOMEM;
+ goto err3;
+ }
+
+ virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
+
+ if (!virtual_start) {
+ dev_err(&dev->dev, "error mapping framebuffer memory\n");
+ retval = -ENOMEM;
+ goto err4;
+ }
+ } else { /* Allocate frambuffer memory */
+
+ unsigned long page;
+
+ virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
+ get_order(grvga_mem_size));
+ if (!virtual_start) {
+ dev_err(&dev->dev,
+ "unable to allocate framebuffer memory (%lu bytes)\n",
+ grvga_mem_size);
+ retval = -ENOMEM;
+ goto err3;
+ }
+
+ physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
+
+ /* Set page reserved so that mmap will work. This is necessary
+ * since we'll be remapping normal memory.
+ */
+ for (page = virtual_start;
+ page < PAGE_ALIGN(virtual_start + grvga_mem_size);
+ page += PAGE_SIZE) {
+ SetPageReserved(virt_to_page(page));
+ }
+
+ par->fb_alloced = 1;
+ }
+
+ memset((unsigned long *) virtual_start, 0, grvga_mem_size);
+
+ info->screen_base = (char __iomem *) virtual_start;
+ info->fix.smem_start = physical_start;
+ info->fix.smem_len = grvga_mem_size;
+
+ dev_set_drvdata(&dev->dev, info);
+
+ dev_info(&dev->dev,
+ "Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
+ info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
+ grvga_mem_size >> 10, info->screen_base);
+
+ retval = register_framebuffer(info);
+ if (retval < 0) {
+ dev_err(&dev->dev, "failed to register framebuffer\n");
+ goto err4;
+ }
+
+ __raw_writel(physical_start, &par->regs->fb_pos);
+ __raw_writel(__raw_readl(&par->regs->status) | 1, /* Enable framebuffer */
+ &par->regs->status);
+
+ return 0;
+
+err4:
+ dev_set_drvdata(&dev->dev, NULL);
+ if (grvga_fix_addr) {
+ release_mem_region(physical_start, grvga_mem_size);
+ iounmap((void *)virtual_start);
+ } else
+ kfree((void *)virtual_start);
+err3:
+ fb_dealloc_cmap(&info->cmap);
+err2:
+ of_iounmap(&dev->resource[0], par->regs,
+ resource_size(&dev->resource[0]));
+err1:
+ release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
+err:
+ framebuffer_release(info);
+
+ return retval;
+}
+
+static int __devexit grvga_remove(struct platform_device *device)
+{
+ struct fb_info *info = dev_get_drvdata(&device->dev);
+ struct grvga_par *par = info->par;
+
+ if (info) {
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+
+ of_iounmap(&device->resource[0], par->regs,
+ resource_size(&device->resource[0]));
+ release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
+
+ if (!par->fb_alloced) {
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ iounmap(info->screen_base);
+ } else
+ kfree((void *)info->screen_base);
+
+ framebuffer_release(info);
+ dev_set_drvdata(&device->dev, NULL);
+ }
+
+ return 0;
+}
+
+static struct of_device_id svgactrl_of_match[] = {
+ {
+ .name = "GAISLER_SVGACTRL",
+ },
+ {
+ .name = "01_063",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, svgactrl_of_match);
+
+static struct platform_driver grvga_driver = {
+ .driver = {
+ .name = "grlib-svgactrl",
+ .owner = THIS_MODULE,
+ .of_match_table = svgactrl_of_match,
+ },
+ .probe = grvga_probe,
+ .remove = __devexit_p(grvga_remove),
+};
+
+
+static int __init grvga_init(void)
+{
+ return platform_driver_register(&grvga_driver);
+}
+
+static void __exit grvga_exit(void)
+{
+ platform_driver_unregister(&grvga_driver);
+}
+
+module_init(grvga_init);
+module_exit(grvga_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aeroflex Gaisler");
+MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/5] drivers/video/msm/mdp.c: adjust error handling code
From: Julia Lawall @ 2011-07-04 14:11 UTC (permalink / raw)
To: David Brown
Cc: kernel-janitors, Daniel Walker, Bryan Huntsman, Paul Mundt,
linux-arm-msm, linux-fbdev, linux-kernel
From: Julia Lawall <julia@diku.dk>
Use the error handling code at the end of the function, rather than
returning directly.
The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@r@
identifier x;
@@
kfree(x)
@@
identifier r.x;
expression E1!=0,E2,E3,E4;
statement S;
@@
(
if (<+...x...+>) S
|
if (...) { ... when != kfree(x)
when != if (...) { ... kfree(x); ... }
when != x = E3
* return E1;
}
... when != x = E2
if (...) { ... when != x = E4
kfree(x); ... return ...; }
)
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
I wonder if the error handling code at the end of the function should be
calling clk_put as well? In that case, having a separate label for this
case would be useful. Otherwise, one of error_request_irq and error_get_clk
can be deleted
drivers/video/msm/mdp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 243d16f..01fa660 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -421,7 +421,8 @@ int mdp_probe(struct platform_device *pdev)
clk = clk_get(&pdev->dev, "mdp_clk");
if (IS_ERR(clk)) {
printk(KERN_INFO "mdp: failed to get mdp clk");
- return PTR_ERR(clk);
+ ret = PTR_ERR(clk);
+ goto error_get_clk;
}
ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
@@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
error_device_register:
free_irq(mdp->irq, mdp);
error_request_irq:
+error_get_clk:
iounmap(mdp->base);
error_get_irq:
error_ioremap:
^ permalink raw reply related
* [GIT PULL] fbdev fixes for 3.0-rc6
From: Paul Mundt @ 2011-07-04 8:21 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-fbdev, linux-kernel
Please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/lethal/fbdev-3.x.git fbdev-fixes-for-linus
Which contains:
Damian Hobson-Garcia (1):
fbdev: sh_mobile_meram: Correct pointer check for YCbCr chroma plane
Daniel J Blueman (1):
vesafb: fix memory leak
Loïc Minier (1):
fbdev: amba: Link fb device to its parent
Pavel Shved (1):
hecubafb: add module_put on error path in hecubafb_probe()
Randy Dunlap (2):
gx1fb: Fix section mismatch warnings
sm501fb: fix section mismatch warning
Timur Tabi (1):
fsl-diu-fb: remove check for pixel clock ranges
William Katsak (1):
udlfb: Correct sub-optimal resolution selection.
drivers/video/amba-clcd.c | 2 ++
drivers/video/fsl-diu-fb.c | 16 ----------------
drivers/video/geode/gx1fb_core.c | 14 +++++++-------
drivers/video/hecubafb.c | 3 ++-
drivers/video/sh_mobile_meram.c | 2 +-
drivers/video/sm501fb.c | 2 +-
drivers/video/udlfb.c | 8 ++++++--
drivers/video/vesafb.c | 1 +
include/linux/fsl-diu-fb.h | 6 ------
9 files changed, 20 insertions(+), 34 deletions(-)
^ permalink raw reply
* [PATCH 2/5 v4] fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC
From: Damian Hobson-Garcia @ 2011-07-04 8:06 UTC (permalink / raw)
To: linux-fbdev
The MERAM reference counts should be tied to the two LCDC devices (LCD/HDMI)
so that when they are enable/disabled, the MERAM is as well.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V3
=======* Remove the MERAM callbacks used to runtime_get/runtime_put the device from
the LCDC driver. Instead, just call the functions on the MERAM device
directly
drivers/video/sh_mobile_lcdcfb.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 019dbd3..15e77f3 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -259,6 +259,8 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
pm_runtime_get_sync(priv->dev);
if (priv->dot_clk)
clk_enable(priv->dot_clk);
+ if (priv->meram_dev && priv->meram_dev->pdev)
+ pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
}
}
@@ -267,6 +270,8 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
if (priv->dot_clk)
clk_disable(priv->dot_clk);
+ if (priv->meram_dev && priv->meram_dev->pdev)
+ pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
pm_runtime_put(priv->dev);
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH 1/5] fbdev: sh_mobile_meram: Enable runtime PM
From: Damian Hobson-Garcia @ 2011-07-04 8:06 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
drivers/video/sh_mobile_meram.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 9170c82..61e106f 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
@@ -515,6 +516,8 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
if (pdata->addr_mode = SH_MOBILE_MERAM_MODE1)
meram_write_reg(priv->base, MEVCR1, 1 << 29);
+ pm_runtime_enable(&pdev->dev);
+
dev_info(&pdev->dev, "sh_mobile_meram initialized.");
return 0;
@@ -530,6 +533,8 @@ static int sh_mobile_meram_remove(struct platform_device *pdev)
{
struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+ pm_runtime_disable(&pdev->dev);
+
if (priv->base)
iounmap(priv->base);
--
1.7.1
^ permalink raw reply related
* [PATCH 0/5 v4] LCDC MERAM runtime PM support
From: Damian Hobson-Garcia @ 2011-07-04 8:05 UTC (permalink / raw)
To: linux-fbdev
This patch series is a provides PM runtime support for the LCDC MERAM.
The runtime_pm_get/put calls are made at the same time as the LCDC calls, so
that the LCDC MERAM is enabled with the first LCDC device and disabled
with the last LCDC device.
The first 4 patches will apply to rmobile-latest or common/fbdev-meram as-is,
but the final patch needs to have the "PM / Domains: Support for generic I/O PM
domains" patch series.
Only the first 2 patches of the series have been updated from v3 sent on
2011/06/22
Changes from V3
* Remove the MERAM callbacks used to runtime_get/runtime_put the device from
the LCDC driver. Instead, just call the functions on the MERAM device
directly
Damian Hobson-Garcia (5):
fbdev: sh_mobile_meram: Enable runtime PM
fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC - v4
fbdev: sh_mobile_meram: Move private data from .h to .c
fbdev: sh_mobile_meram: Backup/restore device registers on
shutdown/resume - v3
fbdev: sh_mobile_meram: Assign meram to the SH7372_A4LC power domain
arch/arm/mach-shmobile/board-mackerel.c | 1 +
drivers/video/sh_mobile_lcdcfb.c | 6 ++
drivers/video/sh_mobile_meram.c | 84 +++++++++++++++++++++++++++++++
drivers/video/sh_mobile_meram.h | 8 ---
4 files changed, 91 insertions(+), 8 deletions(-)
^ permalink raw reply
* [PATCH] video: backlight: fix const array syntax
From: Greg Dietsche @ 2011-07-01 22:47 UTC (permalink / raw)
To: linux-fbdev
Correct the syntax so that both array and pointer are const.
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
---
drivers/video/backlight/backlight.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 80d292f..4bda2e7 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -19,7 +19,7 @@
#include <asm/backlight.h>
#endif
-static const char const *backlight_types[] = {
+static const char * const backlight_types[] = {
[BACKLIGHT_RAW] = "raw",
[BACKLIGHT_PLATFORM] = "platform",
[BACKLIGHT_FIRMWARE] = "firmware",
--
1.7.2.5
^ permalink raw reply related
* Equity Business Investment
From: PROF.MAURICE IWU @ 2011-06-30 15:44 UTC (permalink / raw)
To: linux-fbdev
Equity Business Investment
From Prof. Maurice Iwu
Dear Friend,
I am Prof. Maurice M. Iwu, Former Chairman Independent Electoral Commission
(INEC).Currently, I am on compulsory terminal leave presently in UK ,
leading up to my final retirement from public service.
I am seeking your partnership in a mutual benefit project involving
investing into your company and secondly on properties and to be precise Estate Development or any other profitable venture of your great idea for our mutual benefit of Equity Market Investment.,
Sincerely,
Prof. Maurice M.Iwu.
{INEC.}
^ permalink raw reply
* Re: [uclinux-dist-devel] [PATCH] fbdev: bfin_adv7393fb: convert to seq_file
From: Mike Frysinger @ 2011-06-29 21:05 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1309213715-31842-1-git-send-email-vapier@gentoo.org>
On Mon, Jun 27, 2011 at 18:28, Mike Frysinger wrote:
> ->read_proc and ->write_proc interfaces are going away,
> switch to seq_file/->write().
actually, let's not merge this. it has build errors:
drivers/video/bfin_adv7393fb.c:364: error: ‘adv7393_proc_write’
undeclared here (not in a function)
the code originally had "adv7393_write_proc", but the new code refers
to "adv7393fb_proc_write". also, file_operations.write does not take
the same arguments as proc_dir_entry.write. so this needs a little
more love than renaming the func.
-mike
^ permalink raw reply
* Re: [PATCH] OMAP: DSS: dispc: enable/disable clocks in error handler
From: Archit Taneja @ 2011-06-29 17:02 UTC (permalink / raw)
To: Valkeinen, Tomi
Cc: Taneja, Archit, Dima Zavin, linux-fbdev@vger.kernel.org,
linux-omap@vger.kernel.org
In-Reply-To: <1309323487.1829.9.camel@deskari>
Hi,
On Tuesday 28 June 2011 09:58 PM, Valkeinen, Tomi wrote:
> On Tue, 2011-06-28 at 09:19 -0700, Archit Taneja wrote:
>> Hi,
>>
>> On Monday 27 June 2011 10:31 AM, Dima Zavin wrote:
>>> There's no guarantee that the error handler worker thread
>>> will run while the dispc clocks are on. Explicitly enable/disable
>>> them.
>>
>> I agree with this.
>
> Yes, I think this patch is fine. I'll apply it to DSS tree.
>
>> Tomi,
>>
>> We could get prevent scheduling of the error worker by registering
>> omap_dispc_irq_handler() as an interrupt thread.
>
> But then we would get extra latency on the interrupt handlers. I wanted
> to keep handling DSS interrupts in interrupt context, because some use
> cases may require very fast reaction to an interrupt.
Okay..we don't need to handle the errors in interrupt context..the
request_threaded_irq() takes 2 functions I think, we could have have
omap_dispc_irq_handler() as the primary handler, and the error_worker as
the thread.
I think the change I'm just suggesting just leads to some beautification
in the end :), we would still need to ensure that clocks are enabled in
the error_worker path.
Archit
^ permalink raw reply
* RE: [PATCH V7 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Kukjin Kim @ 2011-06-29 13:58 UTC (permalink / raw)
To: 'Jingoo Han', 'Paul Mundt', linux-samsung-soc,
linux-fbdev
Cc: 'Anand Kumar N', 'Thomas Abraham',
'Sylwester Nawrocki', 'Marek Szyprowski',
'Kyungmin Park', 'Inki Dae', 'ARM Linux',
'Ben Dooks', 'Jonghun Han'
In-Reply-To: <1309171858-30397-1-git-send-email-jg1.han@samsung.com>
Jingoo Han wrote:
>
> From: Jonghun Han <jonghun.han@samsung.com>
>
> This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
>
> Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
> arch/arm/mach-exynos4/mach-smdkc210.c | 71
> +++++++++++++++++++++++++++++++++
> arch/arm/mach-exynos4/mach-smdkv310.c | 71
> +++++++++++++++++++++++++++++++++
> 2 files changed, 142 insertions(+), 0 deletions(-)
>
As I said, don't push same codes into both.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* RE: [PATCH] video: da8xx-fb: Interrupt configuration of revised
From: Manjunathappa, Prakash @ 2011-06-29 12:31 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1309150507-32512-1-git-send-email-prakash.pm@ti.com>
Hi All,
I have found couple of below minor nits. Hence I am planning to submit version 2 of this patch. Please let me know if you have any other comments?
Thanks,
Prakash
On Mon, Jun 27, 2011 at 10:25:07, Manjunathappa, Prakash wrote:
> Interrupt configuration support for revised LCDC IP of DA850 in
> upcoming SOC from TI.
> The revised LCDC IP differs in interrupt configuration; registers
> for setting and clearing interrupts, raw and masked status registers
> to depict raw and enabled interrupts status.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
> drivers/video/da8xx-fb.c | 153 +++++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 144 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index fcdac87..0e02665 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -35,6 +35,9 @@
>
> #define DRIVER_NAME "da8xx_lcdc"
>
> +#define LCD_VERSION_1 1
> +#define LCD_VERSION_2 2
> +
> /* LCD Status Register */
> #define LCD_END_OF_FRAME1 BIT(9)
> #define LCD_END_OF_FRAME0 BIT(8)
> @@ -49,7 +52,9 @@
> #define LCD_DMA_BURST_4 0x2
> #define LCD_DMA_BURST_8 0x3
> #define LCD_DMA_BURST_16 0x4
> -#define LCD_END_OF_FRAME_INT_ENA BIT(2)
> +#define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
> +#define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
> +#define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
> #define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
>
> /* LCD Control Register */
> @@ -65,12 +70,18 @@
> #define LCD_MONO_8BIT_MODE BIT(9)
> #define LCD_RASTER_ORDER BIT(8)
> #define LCD_TFT_MODE BIT(7)
> -#define LCD_UNDERFLOW_INT_ENA BIT(6)
> -#define LCD_PL_ENABLE BIT(4)
> +#define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
> +#define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
> +#define LCD_V1_PL_INT_ENA BIT(4)
> +#define LCD_V2_PL_INT_ENA BIT(6)
> #define LCD_MONOCHROME_MODE BIT(1)
> #define LCD_RASTER_ENABLE BIT(0)
> #define LCD_TFT_ALT_ENABLE BIT(23)
> #define LCD_STN_565_ENABLE BIT(24)
> +#define LCD_V2_DMA_CLK_EN BIT(2)
> +#define LCD_V2_LIDD_CLK_EN BIT(1)
> +#define LCD_V2_CORE_CLK_EN BIT(0)
> +#define LCD_V2_LPP_B10 26
>
> /* LCD Raster Timing 2 Register */
> #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
> @@ -82,6 +93,7 @@
> #define LCD_INVERT_FRAME_CLOCK BIT(20)
>
> /* LCD Block */
> +#define LCD_PID_REG 0x0
> #define LCD_CTRL_REG 0x4
> #define LCD_STAT_REG 0x8
> #define LCD_RASTER_CTRL_REG 0x28
> @@ -94,6 +106,17 @@
> #define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
> #define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
>
> +/* Interrupt Registers available only in Version 2 */
> +#define LCD_RAW_STAT_REG 0x58
> +#define LCD_MASKED_STAT_REG 0x5c
> +#define LCD_INT_ENABLE_SET_REG 0x60
> +#define LCD_INT_ENABLE_CLR_REG 0x64
> +#define LCD_END_OF_INT_IND_REG 0x68
> +
> +/* Clock registers available only on Version 2 */
> +#define LCD_CLK_ENABLE_REG 0x6c
> +#define LCD_CLK_RESET_REG 0x70
> +
> #define LCD_NUM_BUFFERS 2
>
> #define WSI_TIMEOUT 50
> @@ -105,6 +128,8 @@
>
> static resource_size_t da8xx_fb_reg_base;
> static struct resource *lcdc_regs;
> +static unsigned int lcd_revision;
> +static irq_handler_t lcdc_irq_handler;
>
> static inline unsigned int lcdc_read(unsigned int addr)
> {
> @@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> u32 end;
> u32 reg_ras;
> u32 reg_dma;
> + u32 reg_int;
>
> /* init reg to clear PLM (loading mode) fields */
> reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
> @@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> end = par->dma_end;
>
> reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
> - reg_dma |= LCD_END_OF_FRAME_INT_ENA;
> + if (lcd_revision = LCD_VERSION_1) {
> + reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
> + } else {
> + reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> + LCD_V2_END_OF_FRAME0_INT_ENA |
> + LCD_V2_END_OF_FRAME1_INT_ENA;
> + lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> + }
> reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
>
> lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
> @@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> end = start + par->palette_sz - 1;
>
> reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
> - reg_ras |= LCD_PL_ENABLE;
> +
> + if (lcd_revision = LCD_VERSION_1) {
> + reg_ras |= LCD_V1_PL_INT_ENA;
> + } else {
> + reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> + LCD_V2_PL_INT_ENA;
> + lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> + }
>
> lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
> lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
> @@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
> static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
> {
> u32 reg;
> + u32 reg_int;
>
> reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
> LCD_MONO_8BIT_MODE |
> @@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
> }
>
> /* enable additional interrupts here */
> - reg |= LCD_UNDERFLOW_INT_ENA;
> + if (lcd_revision = LCD_VERSION_1) {
> + reg |= LCD_V1_UNDERFLOW_INT_ENA;
> + } else {
> + reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> + (LCD_V2_UNDERFLOW_INT_ENA);
^ ^
[Prakash] I will remove above marked braces.
> + lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> + }
>
> lcdc_write(reg, LCD_RASTER_CTRL_REG);
>
> @@ -415,12 +462,14 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
> /* Pixels per line = (PPL + 1)*16 */
> /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
> width &= 0x3f0;
> +
[Prakash] Will remove random white space.
> reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
> reg &= 0xfffffc00;
> reg |= ((width >> 4) - 1) << 4;
> lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
>
> /* Set the Panel Height */
> +
[Prakash] Will remove random white space.
> reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
> reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
> lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
> @@ -511,6 +560,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
> /* DMA has to be disabled */
> lcdc_write(0, LCD_DMA_CTRL_REG);
> lcdc_write(0, LCD_RASTER_CTRL_REG);
> +
> + if (lcd_revision = LCD_VERSION_2)
> + lcdc_write(0, LCD_INT_ENABLE_SET_REG);
> }
>
> static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
> @@ -523,6 +575,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
> /* Configure the LCD clock divisor. */
> lcdc_write(LCD_CLK_DIVISOR(div) |
> (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
> +
> + if (lcd_revision = LCD_VERSION_2)
> + lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
> + LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
> +
> }
>
> static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> @@ -583,7 +640,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> return 0;
> }
>
> -static irqreturn_t lcdc_irq_handler(int irq, void *arg)
> +/* IRQ handler for version 2 of LCDC */
> +static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> +{
> + struct da8xx_fb_par *par = arg;
> + u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
> + u32 reg_int;
> +
> + if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> + lcd_disable_raster();
> + lcdc_write(stat, LCD_MASKED_STAT_REG);
> + lcd_enable_raster();
> + } else if (stat & LCD_PL_LOAD_DONE) {
> + /*
> + * Must disable raster before changing state of any control bit.
> + * And also must be disabled before clearing the PL loading
> + * interrupt via the following write to the status register. If
> + * this is done after then one gets multiple PL done interrupts.
> + */
> + lcd_disable_raster();
> +
> + lcdc_write(stat, LCD_MASKED_STAT_REG);
> +
> + /* Disable PL completion inerrupt */
> + reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
> + (LCD_V2_PL_INT_ENA);
> + lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
> +
> + /* Setup and start data loading mode */
> + lcd_blit(LOAD_DATA, par);
> + } else {
> + lcdc_write(stat, LCD_MASKED_STAT_REG);
> +
> + if (stat & LCD_END_OF_FRAME0) {
> + lcdc_write(par->dma_start,
> + LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
> + lcdc_write(par->dma_end,
> + LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
> + par->vsync_flag = 1;
> + wake_up_interruptible(&par->vsync_wait);
> + }
> +
> + if (stat & LCD_END_OF_FRAME1) {
> + lcdc_write(par->dma_start,
> + LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
> + lcdc_write(par->dma_end,
> + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
> + par->vsync_flag = 1;
> + wake_up_interruptible(&par->vsync_wait);
> + }
> + }
> +
> + lcdc_write(0, LCD_END_OF_INT_IND_REG);
> + return IRQ_HANDLED;
> +}
> +
> +/* IRQ handler for version 1 LCDC */
> +static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
> {
> struct da8xx_fb_par *par = arg;
> u32 stat = lcdc_read(LCD_STAT_REG);
> @@ -606,7 +719,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
>
> /* Disable PL completion inerrupt */
> reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
> - reg_ras &= ~LCD_PL_ENABLE;
> + reg_ras &= ~LCD_V1_PL_INT_ENA;
> lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
>
> /* Setup and start data loading mode */
> @@ -945,6 +1058,22 @@ static int __devinit fb_probe(struct platform_device *device)
> if (ret)
> goto err_clk_put;
>
> + /* Determine LCD IP Version */
> + switch (lcdc_read(LCD_PID_REG)) {
> + case 0x4C100102:
> + lcd_revision = LCD_VERSION_1;
> + break;
> + case 0x4F200800:
> + lcd_revision = LCD_VERSION_2;
> + break;
> + default:
> + dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
> + "defaulting to LCD revision 1\n",
> + lcdc_read(LCD_PID_REG));
> + lcd_revision = LCD_VERSION_1;
> + break;
> + }
> +
> for (i = 0, lcdc_info = known_lcd_panels;
> i < ARRAY_SIZE(known_lcd_panels);
> i++, lcdc_info++) {
> @@ -1085,7 +1214,13 @@ static int __devinit fb_probe(struct platform_device *device)
> }
> #endif
>
> - ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
> + if (lcd_revision = LCD_VERSION_1)
> + lcdc_irq_handler = lcdc_irq_handler_rev01;
> + else
> + lcdc_irq_handler = lcdc_irq_handler_rev02;
> +
> + ret = request_irq(par->irq, lcdc_irq_handler, 0,
> + DRIVER_NAME, par);
> if (ret)
> goto irq_freq;
> return 0;
> --
> 1.7.1
>
>
^ permalink raw reply
* Re: [PATCH 1/5 v3] fbdev: sh_mobile_meram: Add enable/disble hooks
From: Damian Hobson-Garcia @ 2011-06-29 5:26 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1308728992-9660-2-git-send-email-dhobsong@igel.co.jp>
Hi Paul,
On 2011/06/24 14:34, Paul Mundt wrote:
> On Wed, Jun 22, 2011 at 04:49:48PM +0900, Damian Hobson-Garcia wrote:
>> +static int sh_mobile_meram_pm_get_sync(struct sh_mobile_meram_info *pdata)
>> +{
>> + if (!pdata || !pdata->pdev)
>> + return -EINVAL;
>> +
>> + dev_dbg(&pdata->pdev->dev, "Enabling sh_mobile_meram clock.");
>> + pm_runtime_get_sync(&pdata->pdev->dev);
>> + return 0;
>> +}
>> +
>
> On Wed, Jun 22, 2011 at 04:49:49PM +0900, Damian Hobson-Garcia wrote:
>> @@ -259,6 +259,11 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
>> pm_runtime_get_sync(priv->dev);
>> if (priv->dot_clk)
>> clk_enable(priv->dot_clk);
>> + if (priv->meram_dev && priv->meram_dev->ops) {
>> + struct sh_mobile_meram_info *mdev;
>> + mdev = priv->meram_dev;
>> + mdev->ops->meram_pm_get_sync(mdev);
>> + }
>> }
>> }
>>
> I'm not sure that I really see the point in the callbacks. The callbacks
> would make sense in the case where you're dealing with opaque types that
> you don't wish to have knowledge of in the other drivers, but when all
> you're doing is fetching the pointer and wrapping verbatim in to the
> runtime pm calls, it just seems like a pointless layer of indirection.
>
> You could easily just do this as:
>
> if (priv->meram_dev)
> pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
>
> and be done with it.
>
> This will also save you from having to add additional callbacks should
> you decide that you suddenly require async behaviour or so in other
> cases, too.
Thanks for your comment.
You raise a good point here. I'll get rid of the useless call.
Damian
^ permalink raw reply
* Re: [PATCH] OMAP: DSS: dispc: enable/disable clocks in error
From: Tomi Valkeinen @ 2011-06-29 4:58 UTC (permalink / raw)
To: Archit Taneja
Cc: Dima Zavin, linux-fbdev@vger.kernel.org,
linux-omap@vger.kernel.org
In-Reply-To: <4E09FEFD.9020005@ti.com>
On Tue, 2011-06-28 at 09:19 -0700, Archit Taneja wrote:
> Hi,
>
> On Monday 27 June 2011 10:31 AM, Dima Zavin wrote:
> > There's no guarantee that the error handler worker thread
> > will run while the dispc clocks are on. Explicitly enable/disable
> > them.
>
> I agree with this.
Yes, I think this patch is fine. I'll apply it to DSS tree.
> Tomi,
>
> We could get prevent scheduling of the error worker by registering
> omap_dispc_irq_handler() as an interrupt thread.
But then we would get extra latency on the interrupt handlers. I wanted
to keep handling DSS interrupts in interrupt context, because some use
cases may require very fast reaction to an interrupt.
Tomi
^ permalink raw reply
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