* [PATCH] video: hecubafb: add __devexit_p around reference to
From: Axel Lin @ 2011-02-13 13:06 UTC (permalink / raw)
To: linux-kernel; +Cc: Jaya Kumar, Paul Mundt, linux-fbdev
hecubafb_remove is marked __devexit,
thus add __devexit_p around reference to hecubafb_remove.
Signed-off-by: Axel Lin <axel.lin@gmail.com>
---
drivers/video/hecubafb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index c77bcc6..1b94643 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
static struct platform_driver hecubafb_driver = {
.probe = hecubafb_probe,
- .remove = hecubafb_remove,
+ .remove = __devexit_p(hecubafb_remove),
.driver = {
.owner = THIS_MODULE,
.name = "hecubafb",
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Russell King - ARM Linux @ 2011-02-13 13:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1296679619-32666-1-git-send-email-anarsoul@gmail.com>
Eric - ping?
On Wed, Feb 02, 2011 at 10:46:59PM +0200, Vasily Khoruzhick wrote:
> From: "Russell King - ARM Linux" <linux@arm.linux.org.uk>
>
> Release callback tries to free memory even if it was not allocated in
> map_video_memory. Fix PXA27x/3xx overlay memory management and make overlay
> actually work.
>
> Added by Vasily Khoruzhick:
>
> - Move overlay Z-ordering selection into main fb initialization,
> otherwise plane ordering is wrong.
> - Clear x_res/y_res fields of fb.var on release, to make sure
> our callback will be called on next FBIOPUT_VSCREENINFO ioctl.
> - Disable overlay only if it was enabled.
>
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
> drivers/video/pxafb.c | 86 ++++++++++++++++++++++++++++++------------------
> drivers/video/pxafb.h | 2 +-
> 2 files changed, 55 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
> index 825b665..33f607a 100644
> --- a/drivers/video/pxafb.c
> +++ b/drivers/video/pxafb.c
> @@ -629,16 +629,19 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
> {
> uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
>
> - lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
> + if (lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN) {
> + lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
>
> - lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> - lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
> - lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
> + lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> + lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
> + lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
>
> - if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> - pr_warning("%s: timeout disabling overlay1\n", __func__);
> + if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> + pr_warning("%s: timeout disabling overlay1\n",
> + __func__);
>
> - lcd_writel(ofb->fbi, LCCR5, lccr5);
> + lcd_writel(ofb->fbi, LCCR5, lccr5);
> + }
> }
>
> static void overlay2fb_setup(struct pxafb_layer *ofb)
> @@ -687,16 +690,19 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
> {
> uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
>
> - lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
> + if (lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN) {
> + lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
>
> - lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> - lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
> - lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
> - lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
> - lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
> + lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> + lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
> + lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
> + lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
> + lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
>
> - if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> - pr_warning("%s: timeout disabling overlay2\n", __func__);
> + if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> + pr_warning("%s: timeout disabling overlay2\n",
> + __func__);
> + }
> }
>
> static struct pxafb_layer_ops ofb_ops[] = {
> @@ -720,12 +726,10 @@ static int overlayfb_open(struct fb_info *info, int user)
> if (user = 0)
> return -ENODEV;
>
> - /* allow only one user at a time */
> - if (atomic_inc_and_test(&ofb->usage))
> - return -EBUSY;
> + if (ofb->usage++ = 0)
> + /* unblank the base framebuffer */
> + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>
> - /* unblank the base framebuffer */
> - fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
> return 0;
> }
>
> @@ -733,12 +737,24 @@ static int overlayfb_release(struct fb_info *info, int user)
> {
> struct pxafb_layer *ofb = (struct pxafb_layer*) info;
>
> - atomic_dec(&ofb->usage);
> - ofb->ops->disable(ofb);
> -
> - free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> - ofb->video_mem = NULL;
> - ofb->video_mem_size = 0;
> + if (--ofb->usage = 0) {
> + ofb->ops->disable(ofb);
> + ofb->fb.var.height = -1;
> + ofb->fb.var.width = -1;
> + ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
> + ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
> +
> + mutex_lock(&ofb->fb.mm_lock);
> + ofb->fb.fix.smem_start = 0;
> + ofb->fb.fix.smem_len = 0;
> + mutex_unlock(&ofb->fb.mm_lock);
> +
> + if (ofb->video_mem) {
> + free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> + ofb->video_mem = NULL;
> + ofb->video_mem_size = 0;
> + }
> + }
> return 0;
> }
>
> @@ -817,7 +833,8 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
> if (ofb->video_mem_size >= size)
> return 0;
>
> - free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> + /* don't re-allocate: userspace may have the buffer mapped */
> + return -EINVAL;
> }
>
> ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
> @@ -891,7 +908,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
>
> ofb->id = id;
> ofb->ops = &ofb_ops[id];
> - atomic_set(&ofb->usage, 0);
> + ofb->usage = 0;
> ofb->fbi = fbi;
> init_completion(&ofb->branch_done);
> }
> @@ -923,8 +940,6 @@ static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
> /* mask all IU/BS/EOF/SOF interrupts */
> lcd_writel(fbi, LCCR5, ~0);
>
> - /* place overlay(s) on top of base */
> - fbi->lccr0 |= LCCR0_OUC;
> pr_info("PXA Overlay driver loaded successfully!\n");
> return 0;
> }
> @@ -1368,7 +1383,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
> (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
> (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
> (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
> - (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
> + ((fbi->lccr0 & LCCR0_SDS) &&
> + (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
> pxafb_schedule_work(fbi, C_REENABLE);
>
> return 0;
> @@ -1420,7 +1436,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
> lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
>
> lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> - lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> + if (fbi->lccr0 & LCCR0_SDS)
> + lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
> }
>
> @@ -1806,6 +1823,11 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
>
> pxafb_decode_mach_info(fbi, inf);
>
> +#ifdef CONFIG_FB_PXA_OVERLAY
> + if (cpu_is_pxa27x())
> + fbi->lccr0 |= LCCR0_OUC;
> +#endif
> +
> init_waitqueue_head(&fbi->ctrlr_wait);
> INIT_WORK(&fbi->task, pxafb_task);
> mutex_init(&fbi->ctrlr_lock);
> diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
> index 2353521..84e3ae1 100644
> --- a/drivers/video/pxafb.h
> +++ b/drivers/video/pxafb.h
> @@ -92,7 +92,7 @@ struct pxafb_layer_ops {
> struct pxafb_layer {
> struct fb_info fb;
> int id;
> - atomic_t usage;
> + uint32_t usage;
> uint32_t control[2];
>
> struct pxafb_layer_ops *ops;
> --
> 1.7.4.rc1
>
^ permalink raw reply
* [PATCH] Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET
From: Martin Decky @ 2011-02-13 19:28 UTC (permalink / raw)
To: linux-fbdev
From: Martin Decky <martin@decky.cz>
The macros for getting the values for horizontal sync width and offset
do not respect the EDID specification. Both these values are 10 bit
values according to [1], not 6 bit values. The lower 8 bits are stored
in byte 8 and byte 9 of the DTD respectively, while two additional bits
for each value are stored in byte 11. The original macros just slammed
the bits together.
Although the original macros usually worked fine because the higher two
bits are rarely used, it can cause severe problems on plasma panels
running at 1920x1080 @ 50 Hz with drivers that rely on the correct
parsing of the EDID data by fbmon.c (e.g. udlfb).
The patch should apply cleanly to both the fbdev-2.6.git branch and
linux-next.git branch.
[1] VESA Enhanced Extended Display Identification Data Standard,
Release A, Revision 2, page 34, notes 7 & 8, VESA, Sep 2006
Signed-off-by: Martin Decky <martin@decky.cz>
----
diff -Naurp fbdev-2.6.orig/drivers/video/edid.h fbdev-2.6/drivers/video/edid.h
--- fbdev-2.6.orig/drivers/video/edid.h 2011-02-13 19:45:22.000000000 +0100
+++ fbdev-2.6/drivers/video/edid.h 2011-02-13 19:56:02.080350929 +0100
@@ -101,8 +101,8 @@
#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
-#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
-#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
+#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
+#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
#define H_SIZE_LO (unsigned)block[ 12 ]
#define V_SIZE_LO (unsigned)block[ 13 ]
^ permalink raw reply
* [PATCH 0/6] sisfb: XGI Z9 POST
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel
Here's some patches to get POST working with XGI Z9. I have tested them
with the following card:
http://www.roboard.com/Files/RB-100/MiniPCI-VGA-Z9s_UM_v1r1A.pdf
I'm using the card on an ARM board where the bootloader knows nothing
about VGA or VGA BIOS, so having POST support in the kernel driver
is mandatory. With these patches the memory size is correct detected,
R/W test passes and it's possible to use e.g. framebuffer console.
Aaro Koskinen (6):
sisfb: POST should fail if R/W test fails
sisfb: move XGI POST RAM type detection into a subroutine
sisfb: add subroutine for detecting XGI Z9
sisfb: add RAM type detection for XGI Z9
sisfb: move XGI POST DDR2 bootup code into subroutines
sisfb: add support for XGI Z9 DDR2 POST
drivers/video/sis/sis.h | 1 +
drivers/video/sis/sis_main.c | 315 ++++++++++++++++++++++++++++++------------
drivers/video/sis/vgatypes.h | 1 +
3 files changed, 228 insertions(+), 89 deletions(-)
^ permalink raw reply
* [PATCH 1/6] sisfb: POST should fail if R/W test fails
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Currently there is no indication if R/W test fails during POST. This can
happen e.g. when user plugs in a card with unsupported type of memory.
Since the driver will be unusable, it's better to fail the whole POST
if the memory cannot be configured properly.
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis_main.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a..2c5de66 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
return 1;
}
-static void __devinit
+static int __devinit
sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
{
unsigned int buswidth, ranksize, channelab, mapsize;
- int i, j, k, l;
+ int i, j, k, l, status;
u8 reg, sr14;
static const u8 dramsr13[12 * 5] = {
0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
SiS_SetReg(SISSR, 0x13, 0x35);
SiS_SetReg(SISSR, 0x14, 0x41);
/* TODO */
- return;
+ return -ENOMEM;
}
/* Non-interleaving */
@@ -4835,6 +4835,7 @@ bail_out:
j = (ivideo->chip = XGI_20) ? 5 : 9;
k = (ivideo->chip = XGI_20) ? 12 : 4;
+ status = -EIO;
for(i = 0; i < k; i++) {
@@ -4868,11 +4869,15 @@ bail_out:
SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
sisfb_post_xgi_delay(ivideo, 1);
- if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
+ if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
+ status = 0;
break;
+ }
}
iounmap(ivideo->video_vbase);
+
+ return status;
}
static void __devinit
@@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
} else {
+ int err;
/* Set default mode, don't clear screen */
ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
/* Disable read-cache */
SiS_SetRegAND(SISSR, 0x21, 0xdf);
- sisfb_post_xgi_ramsize(ivideo);
+ err = sisfb_post_xgi_ramsize(ivideo);
/* Enable read-cache */
SiS_SetRegOR(SISSR, 0x21, 0x20);
+ if (err) {
+ dev_err(&pdev->dev,
+ "%s: RAM size detection failed: %d\n",
+ __func__, err);
+ return 0;
+ }
}
#if 0
--
1.5.6.5
^ permalink raw reply related
* [PATCH 2/6] sisfb: move XGI POST RAM type detection into a subroutine
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Move XGI POST RAM type detection into a separate subroutine to make
further code changes easier. No changes in functionality
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis_main.c | 57 +++++++++++++++++++++++++----------------
1 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2c5de66..364559b 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4936,6 +4936,40 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
sisfb_post_xgi_delay(ivideo, 0x43);
}
+static u8 __devinit
+sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
+{
+ unsigned char *bios = ivideo->bios_abase;
+ u8 ramtype;
+ u8 reg;
+ u8 v1;
+
+ ramtype = 0x00; v1 = 0x10;
+ if (ivideo->haveXGIROM) {
+ ramtype = bios[0x62];
+ v1 = bios[0x1d2];
+ }
+ if (!(ramtype & 0x80)) {
+ if (ivideo->chip = XGI_20) {
+ SiS_SetReg(SISCR, 0x97, v1);
+ reg = SiS_GetReg(SISCR, 0x97);
+ if (reg & 0x10) {
+ ramtype = (reg & 0x01) << 1;
+ }
+ } else {
+ reg = SiS_GetReg(SISSR, 0x39);
+ ramtype = reg & 0x02;
+ if (!(ramtype)) {
+ reg = SiS_GetReg(SISSR, 0x3a);
+ ramtype = (reg >> 1) & 0x01;
+ }
+ }
+ }
+ ramtype &= 0x07;
+
+ return ramtype;
+}
+
static int __devinit
sisfb_post_xgi(struct pci_dev *pdev)
{
@@ -5380,28 +5414,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
SiS_SetReg(SISSR, 0x1c, 0x00);
}
- ramtype = 0x00; v1 = 0x10;
- if(ivideo->haveXGIROM) {
- ramtype = bios[0x62];
- v1 = bios[0x1d2];
- }
- if(!(ramtype & 0x80)) {
- if(ivideo->chip = XGI_20) {
- SiS_SetReg(SISCR, 0x97, v1);
- reg = SiS_GetReg(SISCR, 0x97);
- if(reg & 0x10) {
- ramtype = (reg & 0x01) << 1;
- }
- } else {
- reg = SiS_GetReg(SISSR, 0x39);
- ramtype = reg & 0x02;
- if(!(ramtype)) {
- reg = SiS_GetReg(SISSR, 0x3a);
- ramtype = (reg >> 1) & 0x01;
- }
- }
- }
- ramtype &= 0x07;
+ ramtype = sisfb_post_xgi_ramtype(ivideo);
regb = 0; /* ! */
--
1.5.6.5
^ permalink raw reply related
* [PATCH 3/6] sisfb: add subroutine for detecting XGI Z9
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Z7 and Z9 have the same PCI ID, so additional checking is needed to
detect Z9. The method was "documented" in XGI's xgifb driver.
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis.h | 1 +
drivers/video/sis/sis_main.c | 18 ++++++++++++++++++
drivers/video/sis/vgatypes.h | 1 +
3 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01..1987f1b 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
unsigned int refresh_rate;
unsigned int chip;
+ unsigned int chip_real_id;
u8 revision_id;
int sisvga_enabled; /* PCI device was enabled */
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 364559b..f0c48e8 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
}
#endif
+static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
+{
+ return ivideo->chip_real_id = XGI_21;
+}
+
static void __devinit
sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
{
@@ -5802,6 +5807,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif
ivideo->chip = chipinfo->chip;
+ ivideo->chip_real_id = chipinfo->chip;
ivideo->sisvga_engine = chipinfo->vgaengine;
ivideo->hwcursor_size = chipinfo->hwcursor_size;
ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6035,6 +6041,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
sisfb_detect_custom_timing(ivideo);
}
+#ifdef CONFIG_FB_SIS_315
+ if (ivideo->chip = XGI_20) {
+ /* Check if our Z7 chip is actually Z9 */
+ SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
+ reg = SiS_GetReg(SISCR, 0x48);
+ if (reg & 0x02) { /* GPIOG */
+ ivideo->chip_real_id = XGI_21;
+ dev_info(&pdev->dev, "Z9 detected\n");
+ }
+ }
+#endif
+
/* POST card in case this has not been done by the BIOS */
if( (!ivideo->sisvga_enabled)
#if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfa..e3f9976 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
SIS_341,
SIS_342,
XGI_20 = 75,
+ XGI_21,
XGI_40,
MAX_SIS_CHIP
} SIS_CHIP_TYPE;
--
1.5.6.5
^ permalink raw reply related
* [PATCH 4/6] sisfb: add RAM type detection for XGI Z9
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Detect the XGI Z9 RAM type as "documented" by the XGI's xgifb driver.
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis_main.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index f0c48e8..de03567 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4955,7 +4955,13 @@ sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
v1 = bios[0x1d2];
}
if (!(ramtype & 0x80)) {
- if (ivideo->chip = XGI_20) {
+ if (sisfb_xgi_is21(ivideo)) {
+ SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
+ SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
+ reg = SiS_GetReg(SISCR, 0x48);
+ SiS_SetRegOR(SISCR, 0xb4, 0x02);
+ ramtype = reg & 0x01; /* GPIOH */
+ } else if (ivideo->chip = XGI_20) {
SiS_SetReg(SISCR, 0x97, v1);
reg = SiS_GetReg(SISCR, 0x97);
if (reg & 0x10) {
--
1.5.6.5
^ permalink raw reply related
* [PATCH 5/6] sisfb: move XGI POST DDR2 bootup code into subroutines
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Move DDR2 register setting code into separate subroutines. No changes
in functionality.
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis_main.c | 139 +++++++++++++++++++++++++-----------------
1 files changed, 84 insertions(+), 55 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index de03567..9c52d7b 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4941,6 +4941,89 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
sisfb_post_xgi_delay(ivideo, 0x43);
}
+static void __devinit
+sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
+{
+ unsigned char *bios = ivideo->bios_abase;
+ u8 v1;
+
+ SiS_SetReg(SISSR, 0x28, 0x64);
+ SiS_SetReg(SISSR, 0x29, 0x63);
+ sisfb_post_xgi_delay(ivideo, 15);
+ SiS_SetReg(SISSR, 0x18, 0x00);
+ SiS_SetReg(SISSR, 0x19, 0x20);
+ SiS_SetReg(SISSR, 0x16, 0x00);
+ SiS_SetReg(SISSR, 0x16, 0x80);
+ SiS_SetReg(SISSR, 0x18, 0xc5);
+ SiS_SetReg(SISSR, 0x19, 0x23);
+ SiS_SetReg(SISSR, 0x16, 0x00);
+ SiS_SetReg(SISSR, 0x16, 0x80);
+ sisfb_post_xgi_delay(ivideo, 1);
+ SiS_SetReg(SISCR, 0x97, 0x11);
+ sisfb_post_xgi_setclocks(ivideo, regb);
+ sisfb_post_xgi_delay(ivideo, 0x46);
+ SiS_SetReg(SISSR, 0x18, 0xc5);
+ SiS_SetReg(SISSR, 0x19, 0x23);
+ SiS_SetReg(SISSR, 0x16, 0x00);
+ SiS_SetReg(SISSR, 0x16, 0x80);
+ sisfb_post_xgi_delay(ivideo, 1);
+ SiS_SetReg(SISSR, 0x1b, 0x04);
+ sisfb_post_xgi_delay(ivideo, 1);
+ SiS_SetReg(SISSR, 0x1b, 0x00);
+ sisfb_post_xgi_delay(ivideo, 1);
+ v1 = 0x31;
+ if (ivideo->haveXGIROM) {
+ v1 = bios[0xf0];
+ }
+ SiS_SetReg(SISSR, 0x18, v1);
+ SiS_SetReg(SISSR, 0x19, 0x06);
+ SiS_SetReg(SISSR, 0x16, 0x04);
+ SiS_SetReg(SISSR, 0x16, 0x84);
+ sisfb_post_xgi_delay(ivideo, 1);
+}
+
+static void __devinit
+sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
+{
+ unsigned char *bios = ivideo->bios_abase;
+ static const u8 cs158[8] = {
+ 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs160[8] = {
+ 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs168[8] = {
+ 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ u8 reg;
+ u8 v1;
+ u8 v2;
+ u8 v3;
+
+ SiS_SetReg(SISCR, 0x82, 0x77);
+ SiS_SetReg(SISCR, 0x86, 0x00);
+ reg = SiS_GetReg(SISCR, 0x86);
+ SiS_SetReg(SISCR, 0x86, 0x88);
+ reg = SiS_GetReg(SISCR, 0x86);
+ v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
+ if (ivideo->haveXGIROM) {
+ v1 = bios[regb + 0x168];
+ v2 = bios[regb + 0x160];
+ v3 = bios[regb + 0x158];
+ }
+ SiS_SetReg(SISCR, 0x86, v1);
+ SiS_SetReg(SISCR, 0x82, 0x77);
+ SiS_SetReg(SISCR, 0x85, 0x00);
+ reg = SiS_GetReg(SISCR, 0x85);
+ SiS_SetReg(SISCR, 0x85, 0x88);
+ reg = SiS_GetReg(SISCR, 0x85);
+ SiS_SetReg(SISCR, 0x85, v2);
+ SiS_SetReg(SISCR, 0x82, v3);
+ SiS_SetReg(SISCR, 0x98, 0x01);
+ SiS_SetReg(SISCR, 0x9a, 0x02);
+ sisfb_post_xgi_ddr2_default(ivideo, regb);
+}
+
static u8 __devinit
sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
{
@@ -5514,61 +5597,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
SiS_SetReg(SISSR, 0x1b, 0x00);
break;
case 1:
- SiS_SetReg(SISCR, 0x82, 0x77);
- SiS_SetReg(SISCR, 0x86, 0x00);
- reg = SiS_GetReg(SISCR, 0x86);
- SiS_SetReg(SISCR, 0x86, 0x88);
- reg = SiS_GetReg(SISCR, 0x86);
- v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
- if(ivideo->haveXGIROM) {
- v1 = bios[regb + 0x168];
- v2 = bios[regb + 0x160];
- v3 = bios[regb + 0x158];
- }
- SiS_SetReg(SISCR, 0x86, v1);
- SiS_SetReg(SISCR, 0x82, 0x77);
- SiS_SetReg(SISCR, 0x85, 0x00);
- reg = SiS_GetReg(SISCR, 0x85);
- SiS_SetReg(SISCR, 0x85, 0x88);
- reg = SiS_GetReg(SISCR, 0x85);
- SiS_SetReg(SISCR, 0x85, v2);
- SiS_SetReg(SISCR, 0x82, v3);
- SiS_SetReg(SISCR, 0x98, 0x01);
- SiS_SetReg(SISCR, 0x9a, 0x02);
-
- SiS_SetReg(SISSR, 0x28, 0x64);
- SiS_SetReg(SISSR, 0x29, 0x63);
- sisfb_post_xgi_delay(ivideo, 15);
- SiS_SetReg(SISSR, 0x18, 0x00);
- SiS_SetReg(SISSR, 0x19, 0x20);
- SiS_SetReg(SISSR, 0x16, 0x00);
- SiS_SetReg(SISSR, 0x16, 0x80);
- SiS_SetReg(SISSR, 0x18, 0xc5);
- SiS_SetReg(SISSR, 0x19, 0x23);
- SiS_SetReg(SISSR, 0x16, 0x00);
- SiS_SetReg(SISSR, 0x16, 0x80);
- sisfb_post_xgi_delay(ivideo, 1);
- SiS_SetReg(SISCR, 0x97, 0x11);
- sisfb_post_xgi_setclocks(ivideo, regb);
- sisfb_post_xgi_delay(ivideo, 0x46);
- SiS_SetReg(SISSR, 0x18, 0xc5);
- SiS_SetReg(SISSR, 0x19, 0x23);
- SiS_SetReg(SISSR, 0x16, 0x00);
- SiS_SetReg(SISSR, 0x16, 0x80);
- sisfb_post_xgi_delay(ivideo, 1);
- SiS_SetReg(SISSR, 0x1b, 0x04);
- sisfb_post_xgi_delay(ivideo, 1);
- SiS_SetReg(SISSR, 0x1b, 0x00);
- sisfb_post_xgi_delay(ivideo, 1);
- v1 = 0x31;
- if(ivideo->haveXGIROM) {
- v1 = bios[0xf0];
- }
- SiS_SetReg(SISSR, 0x18, v1);
- SiS_SetReg(SISSR, 0x19, 0x06);
- SiS_SetReg(SISSR, 0x16, 0x04);
- SiS_SetReg(SISSR, 0x16, 0x84);
- sisfb_post_xgi_delay(ivideo, 1);
+ sisfb_post_xgi_ddr2(ivideo, regb);
break;
default:
sisfb_post_xgi_setclocks(ivideo, regb);
--
1.5.6.5
^ permalink raw reply related
* [PATCH 6/6] sisfb: add support for XGI Z9 DDR2 POST
From: Aaro Koskinen @ 2011-02-13 22:11 UTC (permalink / raw)
To: linux-fbdev, linux-kernel; +Cc: Thomas Winischhofer
In-Reply-To: <1297635088-13224-1-git-send-email-aaro.koskinen@iki.fi>
Add support for ZGI Z9 DDR2 POST. The init sequence is from XGI's
xgifb driver.
Tested with ARM board using a PCI card with XGI Z9s and 32 MB DDR2
memory. After a cold reset the POST succeeds.
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
drivers/video/sis/sis_main.c | 77 +++++++++++++++++++++++++++++++++++++-----
1 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 9c52d7b..7525984 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4983,6 +4983,48 @@ sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
}
static void __devinit
+sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
+{
+ sisfb_post_xgi_setclocks(ivideo, 1);
+
+ SiS_SetReg(SISCR, 0x97, 0x11);
+ sisfb_post_xgi_delay(ivideo, 0x46);
+
+ SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
+ SiS_SetReg(SISSR, 0x19, 0x80);
+ SiS_SetReg(SISSR, 0x16, 0x05);
+ SiS_SetReg(SISSR, 0x16, 0x85);
+
+ SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
+ SiS_SetReg(SISSR, 0x19, 0xc0);
+ SiS_SetReg(SISSR, 0x16, 0x05);
+ SiS_SetReg(SISSR, 0x16, 0x85);
+
+ SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
+ SiS_SetReg(SISSR, 0x19, 0x40);
+ SiS_SetReg(SISSR, 0x16, 0x05);
+ SiS_SetReg(SISSR, 0x16, 0x85);
+
+ SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
+ SiS_SetReg(SISSR, 0x19, 0x02);
+ SiS_SetReg(SISSR, 0x16, 0x05);
+ SiS_SetReg(SISSR, 0x16, 0x85);
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ SiS_SetReg(SISSR, 0x1b, 0x04);
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ SiS_SetReg(SISSR, 0x1b, 0x00);
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
+ SiS_SetReg(SISSR, 0x19, 0x00);
+ SiS_SetReg(SISSR, 0x16, 0x05);
+ SiS_SetReg(SISSR, 0x16, 0x85);
+ sisfb_post_xgi_delay(ivideo, 1);
+}
+
+static void __devinit
sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
{
unsigned char *bios = ivideo->bios_abase;
@@ -5000,6 +5042,7 @@ sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
u8 v2;
u8 v3;
+ SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
SiS_SetReg(SISCR, 0x82, 0x77);
SiS_SetReg(SISCR, 0x86, 0x00);
reg = SiS_GetReg(SISCR, 0x86);
@@ -5021,7 +5064,10 @@ sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
SiS_SetReg(SISCR, 0x82, v3);
SiS_SetReg(SISCR, 0x98, 0x01);
SiS_SetReg(SISCR, 0x9a, 0x02);
- sisfb_post_xgi_ddr2_default(ivideo, regb);
+ if (sisfb_xgi_is21(ivideo))
+ sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
+ else
+ sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
}
static u8 __devinit
@@ -5346,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
SiS_SetReg(SISCR, 0x77, v1);
}
- /* RAM type */
-
- regb = 0; /* ! */
+ /* RAM type:
+ *
+ * 0 = DDR1, 1 = DDR2, 2..7 = reserved?
+ *
+ * The code seems to written so that regb should equal ramtype,
+ * however, so far it has been hardcoded to 0. Enable other values only
+ * on XGI Z9, as it passes the POST, and add a warning for others.
+ */
+ ramtype = sisfb_post_xgi_ramtype(ivideo);
+ if (!sisfb_xgi_is21(ivideo) && ramtype) {
+ dev_warn(&pdev->dev,
+ "RAM type something else than expected: %d\n",
+ ramtype);
+ regb = 0;
+ } else {
+ regb = ramtype;
+ }
v1 = 0xff;
if(ivideo->haveXGIROM) {
@@ -5500,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
}
}
- SiS_SetReg(SISSR, 0x17, 0x00);
+ if (regb = 1)
+ SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
+ else
+ SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
SiS_SetReg(SISSR, 0x1a, 0x87);
if(ivideo->chip = XGI_20) {
@@ -5508,10 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
SiS_SetReg(SISSR, 0x1c, 0x00);
}
- ramtype = sisfb_post_xgi_ramtype(ivideo);
-
- regb = 0; /* ! */
-
switch(ramtype) {
case 0:
sisfb_post_xgi_setclocks(ivideo, regb);
--
1.5.6.5
^ permalink raw reply related
* Re: [PATCH] video: s3c-fb: return proper error if clk_get fails
From: Kyungmin Park @ 2011-02-14 0:19 UTC (permalink / raw)
To: Axel Lin; +Cc: linux-kernel, Ben Dooks, Paul Mundt, linux-fbdev
In-Reply-To: <1297414270.14046.1.camel@mola>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
On Fri, Feb 11, 2011 at 5:51 PM, Axel Lin <axel.lin@gmail.com> wrote:
> Return PTR_ERR(sfb->bus_clk) instead of 0 if clk_get fails.
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> drivers/video/s3c-fb.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
> index 83ce9a0..6817d18 100644
> --- a/drivers/video/s3c-fb.c
> +++ b/drivers/video/s3c-fb.c
> @@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
> sfb->bus_clk = clk_get(dev, "lcd");
> if (IS_ERR(sfb->bus_clk)) {
> dev_err(dev, "failed to get bus clock\n");
> + ret = PTR_ERR(sfb->bus_clk);
> goto err_sfb;
> }
>
> --
> 1.7.2
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* RE: [PATCH 1/6] sisfb: POST should fail if R/W test fails
From: Janorkar, Mayuresh @ 2011-02-14 6:20 UTC (permalink / raw)
To: Aaro Koskinen
Cc: Thomas Winischhofer, linux-fbdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1297635088-13224-2-git-send-email-aaro.koskinen@iki.fi>
> -----Original Message-----
> From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev-
> owner@vger.kernel.org] On Behalf Of Aaro Koskinen
> Sent: Monday, February 14, 2011 3:41 AM
> To: linux-fbdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Cc: Thomas Winischhofer
> Subject: [PATCH 1/6] sisfb: POST should fail if R/W test fails
>
> Currently there is no indication if R/W test fails during POST. This can
> happen e.g. when user plugs in a card with unsupported type of memory.
> Since the driver will be unusable, it's better to fail the whole POST
> if the memory cannot be configured properly.
>
> Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
> Cc: Thomas Winischhofer <thomas@winischhofer.net>
> ---
> drivers/video/sis/sis_main.c | 22 +++++++++++++++++-----
> 1 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
> index 2fb8c5a..2c5de66 100644
> --- a/drivers/video/sis/sis_main.c
> +++ b/drivers/video/sis/sis_main.c
> @@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info
> *ivideo, int starta,
> return 1;
> }
>
> -static void __devinit
> +static int __devinit
> sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
> {
> unsigned int buswidth, ranksize, channelab, mapsize;
> - int i, j, k, l;
> + int i, j, k, l, status;
> u8 reg, sr14;
> static const u8 dramsr13[12 * 5] = {
> 0x02, 0x0e, 0x0b, 0x80, 0x5d,
> @@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info
> *ivideo)
> SiS_SetReg(SISSR, 0x13, 0x35);
> SiS_SetReg(SISSR, 0x14, 0x41);
> /* TODO */
> - return;
> + return -ENOMEM;
> }
>
> /* Non-interleaving */
> @@ -4835,6 +4835,7 @@ bail_out:
>
> j = (ivideo->chip = XGI_20) ? 5 : 9;
> k = (ivideo->chip = XGI_20) ? 12 : 4;
> + status = -EIO;
How about assigning this value during variable declaration?
>
> for(i = 0; i < k; i++) {
>
> @@ -4868,11 +4869,15 @@ bail_out:
> SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
> sisfb_post_xgi_delay(ivideo, 1);
>
> - if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
> 2 + 20), mapsize))
> + if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
> 2 + 20), mapsize)) {
> + status = 0;
> break;
> + }
> }
>
> iounmap(ivideo->video_vbase);
> +
> + return status;
> }
>
> static void __devinit
> @@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
> SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
>
> } else {
> + int err;
>
> /* Set default mode, don't clear screen */
> ivideo->SiS_Pr.SiS_UseOEM = false;
> @@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
>
> /* Disable read-cache */
> SiS_SetRegAND(SISSR, 0x21, 0xdf);
> - sisfb_post_xgi_ramsize(ivideo);
> + err = sisfb_post_xgi_ramsize(ivideo);
> /* Enable read-cache */
> SiS_SetRegOR(SISSR, 0x21, 0x20);
>
> + if (err) {
> + dev_err(&pdev->dev,
> + "%s: RAM size detection failed: %d\n",
> + __func__, err);
> + return 0;
Are you sure you wish to return 0 when there is an error?
> + }
> }
>
> #if 0
> --
> 1.5.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] mx3fb: Fix parameter to sdc_init_panel
From: Alexander Stein @ 2011-02-14 7:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201102101401.18331.alexander.stein@systec-electronic.com>
On Thursday 10 February 2011, 14:01:17 Alexander Stein wrote:
> On Thursday 10 February 2011, 13:48:23 Guennadi Liakhovetski wrote:
> > > I don't know which display you used, but I guess your right_margin (and
> > > lower_margin) needs to be adjusted.
> >
> > Ok, agree. But then you need to adjust all current users and have them
> > tested... Otherwise, of course, you can just adjust your platform panel
> > data to work with the current calculations, even though in principle your
> > patch seems to be doing the right thing (tm), according to the manual.
> > But if applied as is without fixing all the users, it can very well
> > break them...
>
> Ok, I've just seen there are some model defines in mx3fb.c which would also
> be affected.
> I'll try to find all mx3fb users and fix their videomodes and repost a new
> patch.
Uh, this seems next to impossible for me to handle it my own. I checked some
users of the mx3fb but I cant say which ones will be affected and which ones
not (e.g. without any hsync/vsync, on data enable).
I've not idea how to fix it then.
Alexander
^ permalink raw reply
* Re: [PATCH] mx3fb: Fix parameter to sdc_init_panel
From: Guennadi Liakhovetski @ 2011-02-14 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201102140846.47249.alexander.stein@systec-electronic.com>
On Mon, 14 Feb 2011, Alexander Stein wrote:
> On Thursday 10 February 2011, 14:01:17 Alexander Stein wrote:
> > On Thursday 10 February 2011, 13:48:23 Guennadi Liakhovetski wrote:
> > > > I don't know which display you used, but I guess your right_margin (and
> > > > lower_margin) needs to be adjusted.
> > >
> > > Ok, agree. But then you need to adjust all current users and have them
> > > tested... Otherwise, of course, you can just adjust your platform panel
> > > data to work with the current calculations, even though in principle your
> > > patch seems to be doing the right thing (tm), according to the manual.
> > > But if applied as is without fixing all the users, it can very well
> > > break them...
> >
> > Ok, I've just seen there are some model defines in mx3fb.c which would also
> > be affected.
> > I'll try to find all mx3fb users and fix their videomodes and repost a new
> > patch.
>
> Uh, this seems next to impossible for me to handle it my own. I checked some
> users of the mx3fb but I cant say which ones will be affected and which ones
> not (e.g. without any hsync/vsync, on data enable).
> I've not idea how to fix it then.
Well, you can, of course, adjust parameters for your platform to be able
to run with this incorrect parameter definition...
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCH] mx3fb: Fix parameter to sdc_init_panel
From: Alexander Stein @ 2011-02-14 12:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.64.1102140856070.7331@axis700.grange>
On Monday 14 February 2011, 08:57:04 Guennadi Liakhovetski wrote:
> On Mon, 14 Feb 2011, Alexander Stein wrote:
> > On Thursday 10 February 2011, 14:01:17 Alexander Stein wrote:
> > > On Thursday 10 February 2011, 13:48:23 Guennadi Liakhovetski wrote:
> > > > > I don't know which display you used, but I guess your right_margin
> > > > > (and lower_margin) needs to be adjusted.
> > > >
> > > > Ok, agree. But then you need to adjust all current users and have
> > > > them tested... Otherwise, of course, you can just adjust your
> > > > platform panel data to work with the current calculations, even
> > > > though in principle your patch seems to be doing the right thing
> > > > (tm), according to the manual. But if applied as is without fixing
> > > > all the users, it can very well break them...
> > >
> > > Ok, I've just seen there are some model defines in mx3fb.c which would
> > > also be affected.
> > > I'll try to find all mx3fb users and fix their videomodes and repost a
> > > new patch.
> >
> > Uh, this seems next to impossible for me to handle it my own. I checked
> > some users of the mx3fb but I cant say which ones will be affected and
> > which ones not (e.g. without any hsync/vsync, on data enable).
> > I've not idea how to fix it then.
>
> Well, you can, of course, adjust parameters for your platform to be able
> to run with this incorrect parameter definition...
This is just an ugly work-around. Depending on the settings you may even get
an overflow resulting in a not-working display at all.
Alexander
^ permalink raw reply
* Re: [PATCH 1/6] sisfb: POST should fail if R/W test fails
From: Aaro Koskinen @ 2011-02-14 19:01 UTC (permalink / raw)
To: Janorkar, Mayuresh
Cc: Aaro Koskinen, Thomas Winischhofer, linux-fbdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <EAF47CD23C76F840A9E7FCE10091EFAB0323A959C3@dbde02.ent.ti.com>
Hi,
On Mon, 14 Feb 2011, Janorkar, Mayuresh wrote:
>> diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
>> index 2fb8c5a..2c5de66 100644
>> --- a/drivers/video/sis/sis_main.c
>> +++ b/drivers/video/sis/sis_main.c
>> @@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info
>> *ivideo, int starta,
>> return 1;
>> }
>>
>> -static void __devinit
>> +static int __devinit
>> sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
>> {
>> unsigned int buswidth, ranksize, channelab, mapsize;
>> - int i, j, k, l;
>> + int i, j, k, l, status;
>> u8 reg, sr14;
>> static const u8 dramsr13[12 * 5] = {
>> 0x02, 0x0e, 0x0b, 0x80, 0x5d,
>> @@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info
>> *ivideo)
>> SiS_SetReg(SISSR, 0x13, 0x35);
>> SiS_SetReg(SISSR, 0x14, 0x41);
>> /* TODO */
>> - return;
>> + return -ENOMEM;
>> }
>>
>> /* Non-interleaving */
>> @@ -4835,6 +4835,7 @@ bail_out:
>>
>> j = (ivideo->chip = XGI_20) ? 5 : 9;
>> k = (ivideo->chip = XGI_20) ? 12 : 4;
>> + status = -EIO;
>
> How about assigning this value during variable declaration?
Yes, that can be done.
>>
>> for(i = 0; i < k; i++) {
>>
>> @@ -4868,11 +4869,15 @@ bail_out:
>> SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
>> sisfb_post_xgi_delay(ivideo, 1);
>>
>> - if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
>> 2 + 20), mapsize))
>> + if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
>> 2 + 20), mapsize)) {
>> + status = 0;
>> break;
>> + }
>> }
>>
>> iounmap(ivideo->video_vbase);
>> +
>> + return status;
>> }
>>
>> static void __devinit
>> @@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
>> SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
>>
>> } else {
>> + int err;
>>
>> /* Set default mode, don't clear screen */
>> ivideo->SiS_Pr.SiS_UseOEM = false;
>> @@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
>>
>> /* Disable read-cache */
>> SiS_SetRegAND(SISSR, 0x21, 0xdf);
>> - sisfb_post_xgi_ramsize(ivideo);
>> + err = sisfb_post_xgi_ramsize(ivideo);
>> /* Enable read-cache */
>> SiS_SetRegOR(SISSR, 0x21, 0x20);
>>
>> + if (err) {
>> + dev_err(&pdev->dev,
>> + "%s: RAM size detection failed: %d\n",
>> + __func__, err);
>> + return 0;
>
>
> Are you sure you wish to return 0 when there is an error?
sisfb_post_xgi() returns zero on failure.
A.
^ permalink raw reply
* [PATCH 0/1] sh_mobile_lcdc: Add NV12 input framebuffer support
From: Damian Hobson-Garcia @ 2011-02-15 1:51 UTC (permalink / raw)
To: linux-fbdev
These patches add initial support for YUV 4:2:0 (NV12) framebuffer input for the
LCDC.
Due to the encoding of the NV12 color format, writing 0s to the entire
framebuffer memory area produces a green, rather than a black screen.
Specifying .bpp = 12 and .yuv = 1 when configuring the LCDC channel will enable
NV12 input support.
Damian Hobson-Garcia (1):
Add NV12 input support for framebuffer
drivers/video/sh_mobile_lcdcfb.c | 45 ++++++++++++++++++++++++++++++++-----
drivers/video/sh_mobile_lcdcfb.h | 2 +-
include/video/sh_mobile_lcdc.h | 3 ++
3 files changed, 43 insertions(+), 7 deletions(-)
^ permalink raw reply
* [PATCH 1/1] sh_mobile_lcdc: Add NV12 input framebuffer support
From: Damian Hobson-Garcia @ 2011-02-15 1:51 UTC (permalink / raw)
To: linux-fbdev
Specify .bpp = 12 and .yuv = 1 when configuring the LCDC channel that you want
to you with NV12 input support.
Due to the encoding of YUV data, writing 0s to the framebuffer will clear to
green instead of black.
There is also no native framebuffer support for YUV formats,
so this mode will not work with most software rendering.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
drivers/video/sh_mobile_lcdcfb.c | 45 ++++++++++++++++++++++++++++++++-----
drivers/video/sh_mobile_lcdcfb.h | 2 +-
include/video/sh_mobile_lcdc.h | 3 ++
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index bd4840a..3a3b7d6 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -67,6 +67,7 @@ static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
[LDSM1R] = 0x428,
[LDSM2R] = 0x42c,
[LDSA1R] = 0x430,
+ [LDSA2R] = 0x434,
[LDMLSR] = 0x438,
[LDHCNR] = 0x448,
[LDHSYNR] = 0x44c,
@@ -151,6 +152,7 @@ static bool banked(int reg_nr)
case LDDFR:
case LDSM1R:
case LDSA1R:
+ case LDSA2R:
case LDMLSR:
case LDHCNR:
case LDHSYNR:
@@ -545,6 +547,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
case 16:
lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
break;
+ case 12:
case 24:
lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 7);
break;
@@ -561,8 +564,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* set bpp format in PKF[4:0] */
tmp = lcdc_read_chan(ch, LDDFR);
- tmp &= ~0x0001001f;
+ tmp &= ~0x0003031f;
switch (ch->info->var.bits_per_pixel) {
+ case 12:
+ tmp |= (0x3 << 16);
+ break;
case 16:
tmp |= 0x03;
break;
@@ -576,6 +582,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* point out our frame buffer */
lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
+ if (ch->info->var.nonstd = REN_COLOR_NV12)
+ lcdc_write_chan(ch, LDSA2R,
+ ch->info->fix.smem_start +
+ ch->info->var.xres * ch->info->var.yres);
/* set line size */
lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
@@ -808,6 +818,9 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
new_pan_offset = (var->yoffset * info->fix.line_length) +
(var->xoffset * (info->var.bits_per_pixel / 8));
+ if (var->nonstd = REN_COLOR_NV12)
+ new_pan_offset = new_pan_offset * 3 / 2;
+
if (new_pan_offset = ch->pan_offset)
return 0; /* No change, do nothing */
@@ -815,6 +828,9 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
/* Set the source address for the next refresh */
lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset);
+ if (var->nonstd = REN_COLOR_NV12)
+ lcdc_write_chan_mirror(ch, LDSA2R, ch->dma_handle
+ + new_pan_offset + var->xres * var->yres);
if (lcdc_chan_is_sublcd(ch))
lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
else
@@ -885,7 +901,10 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
/* Couldn't reconfigure, hopefully, can continue as before */
return;
- info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
+ if (info->var.nonstd = REN_COLOR_NV12)
+ info->fix.line_length = mode1.xres;
+ else
+ info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
/*
* fb_set_var() calls the notifier change internally, only if
@@ -980,8 +999,18 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_check_var = sh_mobile_check_var,
};
-static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
+static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp,
+ int yuv)
{
+ if (yuv) {
+ if (bpp = 12) { /*NV12*/
+ var->bits_per_pixel = 12;
+ var->nonstd = REN_COLOR_NV12;
+ return 0;
+ }
+ return -EINVAL;
+ }
+
switch (bpp) {
case 16: /* PKF[4:0] = 00011 - RGB 565 */
var->red.offset = 11;
@@ -1274,7 +1303,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
max_cfg->xres, max_cfg->yres);
info->fix = sh_mobile_lcdc_fix;
- info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
+ info->fix.smem_len = max_size * 2 * cfg->bpp / 8;
if (!mode) {
mode = &default_720p;
@@ -1292,7 +1321,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
var->yres_virtual = var->yres * 2;
var->activate = FB_ACTIVATE_NOW;
- error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
+ error = sh_mobile_lcdc_set_bpp(var, cfg->bpp, cfg->yuv);
if (error)
break;
@@ -1316,7 +1345,11 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
info->fix.smem_start = ch->dma_handle;
- info->fix.line_length = var->xres * (cfg->bpp / 8);
+ if (var->nonstd = REN_COLOR_NV12)
+ info->fix.line_length = var->xres;
+ else
+ info->fix.line_length = var->xres * (cfg->bpp / 8);
+
info->screen_base = buf;
info->device = &pdev->dev;
ch->display_var = *var;
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 9ecee2f..c953cb0 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -8,7 +8,7 @@
/* per-channel registers */
enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
- LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
+ LDSM2R, LDSA1R, LDSA2R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
LDHAJR,
NR_CH_REGS };
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index daabae5..147c80d 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -25,6 +25,8 @@ enum {
SYS24, /* 24bpp */
};
+#define REN_COLOR_NV12 0x1 /* Non-standard framebuffer color format - NV12 */
+
enum { LCDC_CHAN_DISABLED = 0,
LCDC_CHAN_MAINLCD,
LCDC_CHAN_SUBLCD };
@@ -77,6 +79,7 @@ struct sh_mobile_lcdc_chan_cfg {
struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
struct sh_mobile_lcdc_board_cfg board_cfg;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
+ int yuv;
};
struct sh_mobile_lcdc_info {
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Eric Miao @ 2011-02-15 7:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1296679619-32666-1-git-send-email-anarsoul@gmail.com>
On Thu, Feb 3, 2011 at 4:46 AM, Vasily Khoruzhick <anarsoul@gmail.com> wrote:
> From: "Russell King - ARM Linux" <linux@arm.linux.org.uk>
>
> Release callback tries to free memory even if it was not allocated in
> map_video_memory. Fix PXA27x/3xx overlay memory management and make overlay
> actually work.
That's indeed an issue.
>
> Added by Vasily Khoruzhick:
>
> - Move overlay Z-ordering selection into main fb initialization,
> otherwise plane ordering is wrong.
> - Clear x_res/y_res fields of fb.var on release, to make sure
> our callback will be called on next FBIOPUT_VSCREENINFO ioctl.
> - Disable overlay only if it was enabled.
The patch looks generally OK to me, some points for discussion
below though:
>
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
> drivers/video/pxafb.c | 86 ++++++++++++++++++++++++++++++------------------
> drivers/video/pxafb.h | 2 +-
> 2 files changed, 55 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
> index 825b665..33f607a 100644
> --- a/drivers/video/pxafb.c
> +++ b/drivers/video/pxafb.c
> @@ -629,16 +629,19 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
> {
> uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
>
Or maybe simply:
if (lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)
return;
this makes this block of change much cleaner.
> - lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
> + if (lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN) {
> + lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
>
> - lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> - lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
> - lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
> + lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
> + lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(1));
> + lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
>
> - if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> - pr_warning("%s: timeout disabling overlay1\n", __func__);
> + if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> + pr_warning("%s: timeout disabling overlay1\n",
> + __func__);
>
> - lcd_writel(ofb->fbi, LCCR5, lccr5);
> + lcd_writel(ofb->fbi, LCCR5, lccr5);
> + }
> }
>
> static void overlay2fb_setup(struct pxafb_layer *ofb)
> @@ -687,16 +690,19 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
> {
> uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
>
> - lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
> + if (lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN) {
> + lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
Ditto.
>
> - lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> - lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
> - lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
> - lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
> - lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
> + lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
> + lcd_writel(ofb->fbi, LCCR5, lccr5 & ~LCSR1_BS(2));
> + lcd_writel(ofb->fbi, FBR2, ofb->fbi->fdadr[DMA_OV2_Y] | 0x3);
> + lcd_writel(ofb->fbi, FBR3, ofb->fbi->fdadr[DMA_OV2_Cb] | 0x3);
> + lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
>
> - if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> - pr_warning("%s: timeout disabling overlay2\n", __func__);
> + if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) = 0)
> + pr_warning("%s: timeout disabling overlay2\n",
> + __func__);
> + }
> }
>
> static struct pxafb_layer_ops ofb_ops[] = {
> @@ -720,12 +726,10 @@ static int overlayfb_open(struct fb_info *info, int user)
> if (user = 0)
> return -ENODEV;
>
> - /* allow only one user at a time */
> - if (atomic_inc_and_test(&ofb->usage))
> - return -EBUSY;
> + if (ofb->usage++ = 0)
> + /* unblank the base framebuffer */
> + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
The change above allows multiple user at a time? Then I guess
some other places need to be changed accordingly to avoid the
racing conditions.
If this is a feature request, can we postpone it to subsequent
patches?
>
> - /* unblank the base framebuffer */
> - fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
> return 0;
> }
>
> @@ -733,12 +737,24 @@ static int overlayfb_release(struct fb_info *info, int user)
> {
> struct pxafb_layer *ofb = (struct pxafb_layer*) info;
>
> - atomic_dec(&ofb->usage);
> - ofb->ops->disable(ofb);
> -
> - free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> - ofb->video_mem = NULL;
> - ofb->video_mem_size = 0;
> + if (--ofb->usage = 0) {
> + ofb->ops->disable(ofb);
> + ofb->fb.var.height = -1;
> + ofb->fb.var.width = -1;
> + ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
> + ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
> +
> + mutex_lock(&ofb->fb.mm_lock);
> + ofb->fb.fix.smem_start = 0;
> + ofb->fb.fix.smem_len = 0;
> + mutex_unlock(&ofb->fb.mm_lock);
> +
> + if (ofb->video_mem) {
> + free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> + ofb->video_mem = NULL;
> + ofb->video_mem_size = 0;
> + }
> + }
> return 0;
> }
>
> @@ -817,7 +833,8 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
> if (ofb->video_mem_size >= size)
> return 0;
>
> - free_pages_exact(ofb->video_mem, ofb->video_mem_size);
> + /* don't re-allocate: userspace may have the buffer mapped */
> + return -EINVAL;
> }
>
> ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
> @@ -891,7 +908,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
>
> ofb->id = id;
> ofb->ops = &ofb_ops[id];
> - atomic_set(&ofb->usage, 0);
> + ofb->usage = 0;
> ofb->fbi = fbi;
> init_completion(&ofb->branch_done);
> }
> @@ -923,8 +940,6 @@ static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
> /* mask all IU/BS/EOF/SOF interrupts */
> lcd_writel(fbi, LCCR5, ~0);
>
> - /* place overlay(s) on top of base */
> - fbi->lccr0 |= LCCR0_OUC;
> pr_info("PXA Overlay driver loaded successfully!\n");
> return 0;
> }
> @@ -1368,7 +1383,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
> (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
> (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
> (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
> - (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
> + ((fbi->lccr0 & LCCR0_SDS) &&
> + (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
> pxafb_schedule_work(fbi, C_REENABLE);
>
> return 0;
> @@ -1420,7 +1436,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
> lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
>
> lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> - lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> + if (fbi->lccr0 & LCCR0_SDS)
> + lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
My original intention was to simplify the code a bit by ignoring
LCCR0_SDS, as FDADR1 would not take effect if not enabled even
if it's being read/written.
> lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
> }
>
> @@ -1806,6 +1823,11 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
>
> pxafb_decode_mach_info(fbi, inf);
>
> +#ifdef CONFIG_FB_PXA_OVERLAY
> + if (cpu_is_pxa27x())
> + fbi->lccr0 |= LCCR0_OUC;
> +#endif
> +
I seem to remember LCCR0_OUC is still valid on pxa3xx, did you
do some test on pxa3xx as well?
> init_waitqueue_head(&fbi->ctrlr_wait);
> INIT_WORK(&fbi->task, pxafb_task);
> mutex_init(&fbi->ctrlr_lock);
> diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
> index 2353521..84e3ae1 100644
> --- a/drivers/video/pxafb.h
> +++ b/drivers/video/pxafb.h
> @@ -92,7 +92,7 @@ struct pxafb_layer_ops {
> struct pxafb_layer {
> struct fb_info fb;
> int id;
> - atomic_t usage;
> + uint32_t usage;
> uint32_t control[2];
>
> struct pxafb_layer_ops *ops;
> --
> 1.7.4.rc1
>
>
^ permalink raw reply
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Vasily Khoruzhick @ 2011-02-15 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=AfxN73pSNZ5RiTiTWfxR7PhcyJUyXzzeaYNWw@mail.gmail.com>
On Tuesday 15 February 2011 09:35:44 Eric Miao wrote:
> Or maybe simply:
>
> if (lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)
> return;
You mean if (!lcd_readl.....) return? Then OK.
> this makes this block of change much cleaner.
>
> > - lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
> > + if (lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN) {
> > + lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] &
<skip>
> > static struct pxafb_layer_ops ofb_ops[] = {
> > @@ -720,12 +726,10 @@ static int overlayfb_open(struct fb_info *info, int
> > user) if (user = 0)
> > return -ENODEV;
> >
> > - /* allow only one user at a time */
> > - if (atomic_inc_and_test(&ofb->usage))
> > - return -EBUSY;
> > + if (ofb->usage++ = 0)
> > + /* unblank the base framebuffer */
> > + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>
> The change above allows multiple user at a time? Then I guess
> some other places need to be changed accordingly to avoid the
> racing conditions.
For multiple users driver needs some rework indeed.
> If this is a feature request, can we postpone it to subsequent
> patches?
I prefer to fix it later.
> > lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> > - lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> > + if (fbi->lccr0 & LCCR0_SDS)
> > + lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
>
> My original intention was to simplify the code a bit by ignoring
> LCCR0_SDS, as FDADR1 would not take effect if not enabled even
> if it's being read/written.
It leads to potential race condition when you try to reconfigure main plane
and overlay1 simultaneously.
> > +#ifdef CONFIG_FB_PXA_OVERLAY
> > + if (cpu_is_pxa27x())
> > + fbi->lccr0 |= LCCR0_OUC;
> > +#endif
> > +
>
> I seem to remember LCCR0_OUC is still valid on pxa3xx, did you
> do some test on pxa3xx as well?
Sorry, I have no any pxa3xx boards.
Regards
Vasily
^ permalink raw reply
* [PATCH] video: add missing framebuffer_release in error path
From: Axel Lin @ 2011-02-15 9:35 UTC (permalink / raw)
To: linux-kernel; +Cc: David S. Miller, Paul Mundt, linux-fbdev
This patch fixes a memory leak in the error path.
Signed-off-by: Axel Lin <axel.lin@gmail.com>
---
drivers/video/cg14.c | 1 +
drivers/video/cg6.c | 1 +
drivers/video/tcx.c | 1 +
3 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 2424953..2063a63 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -565,6 +565,7 @@ out_dealloc_cmap:
out_unmap_regs:
cg14_unmap_regs(op, info, par);
+ framebuffer_release(info);
out_err:
return err;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 2b5a970..f3b8848 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -822,6 +822,7 @@ out_dealloc_cmap:
out_unmap_regs:
cg6_unmap_regs(op, info, par);
+ framebuffer_release(info);
out_err:
return err;
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 77ad279..3d84235 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -481,6 +481,7 @@ out_dealloc_cmap:
out_unmap_regs:
tcx_unmap_regs(op, info, par);
+ framebuffer_release(info);
out_err:
return err;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Russell King - ARM Linux @ 2011-02-15 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=AfxN73pSNZ5RiTiTWfxR7PhcyJUyXzzeaYNWw@mail.gmail.com>
On Tue, Feb 15, 2011 at 03:35:44PM +0800, Eric Miao wrote:
> > @@ -720,12 +726,10 @@ static int overlayfb_open(struct fb_info *info, int user)
> > if (user = 0)
> > return -ENODEV;
> >
> > - /* allow only one user at a time */
> > - if (atomic_inc_and_test(&ofb->usage))
> > - return -EBUSY;
> > + if (ofb->usage++ = 0)
> > + /* unblank the base framebuffer */
> > + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>
> The change above allows multiple user at a time? Then I guess
> some other places need to be changed accordingly to avoid the
> racing conditions.
You can't prevent multiple users. Think threaded applications which
share the same set of fds.
Any driver which tries to do so by restricting the number of open()s is
simply buggy.
^ permalink raw reply
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Eric Miao @ 2011-02-15 11:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110215094808.GB4152@n2100.arm.linux.org.uk>
On Tue, Feb 15, 2011 at 5:48 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 15, 2011 at 03:35:44PM +0800, Eric Miao wrote:
>> > @@ -720,12 +726,10 @@ static int overlayfb_open(struct fb_info *info, int user)
>> > if (user = 0)
>> > return -ENODEV;
>> >
>> > - /* allow only one user at a time */
>> > - if (atomic_inc_and_test(&ofb->usage))
>> > - return -EBUSY;
>> > + if (ofb->usage++ = 0)
>> > + /* unblank the base framebuffer */
>> > + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
>>
>> The change above allows multiple user at a time? Then I guess
>> some other places need to be changed accordingly to avoid the
>> racing conditions.
>
> You can't prevent multiple users. Think threaded applications which
> share the same set of fds.
>
> Any driver which tries to do so by restricting the number of open()s is
> simply buggy.
>
OK, let's go ahead fix the racing conditions later.
^ permalink raw reply
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Eric Miao @ 2011-02-15 11:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201102151041.21560.anarsoul@gmail.com>
>> > lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
>> > - lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
>> > + if (fbi->lccr0 & LCCR0_SDS)
>> > + lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
>>
>> My original intention was to simplify the code a bit by ignoring
>> LCCR0_SDS, as FDADR1 would not take effect if not enabled even
>> if it's being read/written.
>
> It leads to potential race condition when you try to reconfigure main plane
> and overlay1 simultaneously.
>
You are right on this.
>> > +#ifdef CONFIG_FB_PXA_OVERLAY
>> > + if (cpu_is_pxa27x())
>> > + fbi->lccr0 |= LCCR0_OUC;
>> > +#endif
>> > +
>>
>> I seem to remember LCCR0_OUC is still valid on pxa3xx, did you
>> do some test on pxa3xx as well?
>
> Sorry, I have no any pxa3xx boards.
That's all right, I can give it a test later. The point is, why
did you move the code here from pxafb_overlay_init()?
^ permalink raw reply
* Re: [PATCH] ARM: PXA: Make PXA27x/PXA3xx overlay actually work
From: Vasily Khoruzhick @ 2011-02-15 11:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimR_6fYuJHuVC8TD5agjyCoUWiKQmEunhZHSQE5@mail.gmail.com>
On Tuesday 15 February 2011 13:51:06 Eric Miao wrote:
> >> > lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
> >> > - lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> >> > + if (fbi->lccr0 & LCCR0_SDS)
> >> > + lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
> >>
> >> My original intention was to simplify the code a bit by ignoring
> >> LCCR0_SDS, as FDADR1 would not take effect if not enabled even
> >> if it's being read/written.
> >
> > It leads to potential race condition when you try to reconfigure main
> > plane and overlay1 simultaneously.
>
> You are right on this.
>
> >> > +#ifdef CONFIG_FB_PXA_OVERLAY
> >> > + if (cpu_is_pxa27x())
> >> > + fbi->lccr0 |= LCCR0_OUC;
> >> > +#endif
> >> > +
> >>
> >> I seem to remember LCCR0_OUC is still valid on pxa3xx, did you
> >> do some test on pxa3xx as well?
> >
> > Sorry, I have no any pxa3xx boards.
>
> That's all right, I can give it a test later. The point is, why
> did you move the code here from pxafb_overlay_init()?
Because otherwise correct plane order (overlays on top) will be selected only
on next main plane reconfigure.
Regards
Vasily
^ 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