LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [patch 05/13] ps3fb: Clean up includes
From: Geert Uytterhoeven @ 2007-10-12 14:50 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Clean up includes
  
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   10 +---------
 1 files changed, 1 insertion(+), 9 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -22,22 +22,14 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/ioctl.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
-
-#include <asm/uaccess.h>
 #include <linux/fb.h>
 #include <linux/init.h>
-#include <asm/time.h>
+#include <linux/uaccess.h>
 
 #include <asm/abs_addr.h>
 #include <asm/lv1call.h>

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 06/13] ps3fb: Make ps3fb_wait_for_vsync() and ps3fb_flip_ctl() static
From: Geert Uytterhoeven @ 2007-10-12 14:50 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1425 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Make ps3fb_wait_for_vsync() and ps3fb_flip_ctl() static, as they're no
(longer) used outside ps3fb.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -652,7 +652,7 @@ static int ps3fb_get_vblank(struct fb_vb
 	return 0;
 }
 
-int ps3fb_wait_for_vsync(u32 crtc)
+static int ps3fb_wait_for_vsync(u32 crtc)
 {
 	int ret;
 	u64 count;
@@ -667,9 +667,7 @@ int ps3fb_wait_for_vsync(u32 crtc)
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
-
-void ps3fb_flip_ctl(int on, void *data)
+static void ps3fb_flip_ctl(int on, void *data)
 {
 	struct ps3fb_priv *priv = data;
 	if (on)

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 07/13] ps3fb: Fix possible overlap of GPU command buffer and frame buffer
From: Geert Uytterhoeven @ 2007-10-12 14:50 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6909 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: In the case of non-fullscreen video modes, there was a partial overlap
of the GPU command buffer and the frame buffer. Fix and cleanup various issues
with overlap and alignment:
  - Move the GPU command buffer from the beginning to the end of video memory
  - Exclude the GPU command buffer from the actual frame buffer memory
  - Align the start of the virtual frame buffer to PAGE_SIZE instead of to 64
    KiB, and don't waste memory if it's already aligned (for fullscreen modes)
  - Take into account the alignment when checking memory requirements and
    maximum number of frames
  - Make sure fb_fix_screeninfo.smem_start always points to the virtual frame
    buffer start, so we don't have to compensate for that in ps3fb_mmap()

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   66 +++++++++++++++++++++++++++++---------------------
 1 files changed, 39 insertions(+), 27 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -52,7 +52,7 @@
 #define L1GPU_DISPLAY_SYNC_VSYNC		2
 
 #define DDR_SIZE				(0)	/* used no ddr */
-#define GPU_OFFSET				(64 * 1024)
+#define GPU_CMD_BUF_SIZE			(64 * 1024)
 #define GPU_IOIF				(0x0d000000UL)
 
 #define PS3FB_FULL_MODE_BIT			0x80
@@ -117,6 +117,7 @@ struct ps3fb_priv {
 
 	u64 context_handle, memory_handle;
 	void *xdr_ea;
+	size_t xdr_size;
 	struct gpu_driver_info *dinfo;
 	u32 res_index;
 
@@ -280,9 +281,20 @@ static const struct fb_videomode ps3fb_m
 #define Y_OFF(i)	(ps3fb_res[i].yoff)	/* top/bottom margin (pixel) */
 #define WIDTH(i)	(ps3fb_res[i].xres)	/* width of FB */
 #define HEIGHT(i)	(ps3fb_res[i].yres)	/* height of FB */
-#define BPP	4		/* number of bytes per pixel */
-#define VP_OFF(i)	(WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP)
-#define FB_OFF(i)	(GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
+#define BPP		4			/* number of bytes per pixel */
+
+/* Start of the virtual frame buffer (relative to fullscreen ) */
+#define VP_OFF(i)	((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
+
+/*
+ * Start of the virtual frame buffer (relative to start of video memory)
+ * This is PAGE_SIZE aligned for easier mmap()
+ */
+#define VFB_OFF(i)	PAGE_ALIGN(VP_OFF(i))
+
+/* Start of the fullscreen frame buffer (relative to start of video memory) */
+#define FB_OFF(i)	(-VP_OFF(i) & ~PAGE_MASK)
+
 
 static int ps3fb_mode;
 module_param(ps3fb_mode, int, 0);
@@ -517,7 +529,8 @@ static int ps3fb_check_var(struct fb_var
 
 	/* Memory limit */
 	i = ps3fb_get_res_table(var->xres, var->yres, mode);
-	if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP > ps3fb_videomemory.size) {
+	if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP >
+	    ps3fb.xdr_size - VFB_OFF(i)) {
 		dev_dbg(info->device, "Not enough memory\n");
 		return -ENOMEM;
 	}
@@ -549,12 +562,13 @@ static int ps3fb_set_par(struct fb_info 
 	i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
 	ps3fb.res_index = i;
 
-	offset = FB_OFF(i) + VP_OFF(i);
-	info->fix.smem_len = ps3fb_videomemory.size - offset;
+	offset = VFB_OFF(i);
+	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
+	info->fix.smem_len = ps3fb.xdr_size - offset;
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
-	memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
 
-	ps3fb.num_frames = ps3fb_videomemory.size/
+	ps3fb.num_frames = info->fix.smem_len/
 			   (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
@@ -596,18 +610,13 @@ static int ps3fb_setcolreg(unsigned int 
 static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 	unsigned long size, offset;
-	int i;
-
-	i = ps3fb_get_res_table(info->var.xres, info->var.yres, ps3fb_mode);
-	if (i == -1)
-		return -EINVAL;
 
 	size = vma->vm_end - vma->vm_start;
 	offset = vma->vm_pgoff << PAGE_SHIFT;
 	if (offset + size > info->fix.smem_len)
 		return -EINVAL;
 
-	offset += info->fix.smem_start + FB_OFF(i) + VP_OFF(i);
+	offset += info->fix.smem_start;
 	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
 			    size, vma->vm_page_prot))
 		return -EAGAIN;
@@ -899,8 +908,9 @@ static int ps3fb_xdr_settings(u64 xdr_lp
 
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
-					   xdr_lpar, ps3fb_videomemory.size,
-					   GPU_IOIF, 0);
+					   xdr_lpar + ps3fb.xdr_size,
+					   GPU_CMD_BUF_SIZE,
+					   GPU_IOIF + ps3fb.xdr_size, 0);
 	if (status) {
 		dev_err(dev,
 			"%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
@@ -1038,29 +1048,31 @@ static int __devinit ps3fb_probe(struct 
 	if (retval)
 		goto err_iounmap_dinfo;
 
-	/* xdr frame buffer */
+	/* XDR frame buffer */
 	ps3fb.xdr_ea = ps3fb_videomemory.address;
 	xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
+
+	/* Clear memory to prevent kernel info leakage into userspace */
+	memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+
+	/* The GPU command buffer is at the end of video memory */
+	ps3fb.xdr_size = ps3fb_videomemory.size - GPU_CMD_BUF_SIZE;
+
 	retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
 	if (retval)
 		goto err_free_irq;
 
-	/*
-	 * ps3fb must clear memory to prevent kernel info
-	 * leakage into userspace
-	 */
-	memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
 	info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
 	if (!info)
 		goto err_free_irq;
 
-	offset = FB_OFF(ps3fb.res_index) + VP_OFF(ps3fb.res_index);
+	offset = VFB_OFF(ps3fb.res_index);
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
 	info->fbops = &ps3fb_ops;
 
 	info->fix = ps3fb_fix;
-	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
-	info->fix.smem_len = ps3fb_videomemory.size - offset;
+	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
+	info->fix.smem_len = ps3fb.xdr_size - offset;
 	info->pseudo_palette = info->par;
 	info->par = NULL;
 	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
@@ -1086,7 +1098,7 @@ static int __devinit ps3fb_probe(struct 
 
 	dev_info(info->device, "%s %s, using %lu KiB of video memory\n",
 		 dev_driver_string(info->dev), info->dev->bus_id,
-		 ps3fb_videomemory.size >> 10);
+		 ps3fb.xdr_size >> 10);
 
 	task = kthread_run(ps3fbd, info, DEVICE_NAME);
 	if (IS_ERR(task)) {

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 08/13] ps3fb: Use fb_info.par properly
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 8812 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Use fb_info.par properly:
  o Move mode-specific fields into struct ps3fb_par
  o Allocate struct ps3fb_par using framebuffer_alloc()
  o Protect access to ps3fb_par in ps3fb_sync() using the console semaphore
    (this semaphore is already held when ps3fb_set_par() is called)
  o Avoid calling ps3av_set_video_mode() if the actual video mode hasn't
    changed

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   92 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 57 insertions(+), 35 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -119,12 +119,10 @@ struct ps3fb_priv {
 	void *xdr_ea;
 	size_t xdr_size;
 	struct gpu_driver_info *dinfo;
-	u32 res_index;
 
 	u64 vblank_count;	/* frame count */
 	wait_queue_head_t wait_vsync;
 
-	u32 num_frames;		/* num of frame buffers */
 	atomic_t ext_flip;	/* on/off flip with vsync */
 	atomic_t f_count;	/* fb_open count */
 	int is_blanked;
@@ -133,6 +131,13 @@ struct ps3fb_priv {
 };
 static struct ps3fb_priv ps3fb;
 
+struct ps3fb_par {
+	u32 pseudo_palette[16];
+	int mode_id, new_mode_id;
+	int res_index;
+	unsigned int num_frames;	/* num of frame buffers */
+};
+
 struct ps3fb_res_table {
 	u32 xres;
 	u32 yres;
@@ -361,18 +366,17 @@ static unsigned int ps3fb_find_mode(cons
 
 	pr_debug("ps3fb_find_mode: mode not found\n");
 	return 0;
-
 }
 
-static const struct fb_videomode *ps3fb_default_mode(void)
+static const struct fb_videomode *ps3fb_default_mode(int id)
 {
-	u32 mode = ps3fb_mode & PS3AV_MODE_MASK;
+	u32 mode = id & PS3AV_MODE_MASK;
 	u32 flags;
 
 	if (mode < 1 || mode > 13)
 		return NULL;
 
-	flags = ps3fb_mode & ~PS3AV_MODE_MASK;
+	flags = id & ~PS3AV_MODE_MASK;
 
 	if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
 		/* Full broadcast mode */
@@ -384,18 +388,22 @@ static const struct fb_videomode *ps3fb_
 
 static int ps3fb_sync(struct fb_info *info, u32 frame)
 {
-	int i, status;
+	struct ps3fb_par *par = info->par;
+	int i, status, error = 0;
 	u32 xres, yres;
 	u64 fb_ioif, offset;
 
-	i = ps3fb.res_index;
+	acquire_console_sem();
+
+	i = par->res_index;
 	xres = ps3fb_res[i].xres;
 	yres = ps3fb_res[i].yres;
 
-	if (frame > ps3fb.num_frames - 1) {
+	if (frame > par->num_frames - 1) {
 		dev_dbg(info->device, "%s: invalid frame number (%u)\n",
 			__func__, frame);
-		return -EINVAL;
+		error = -EINVAL;
+		goto out;
 	}
 	offset = xres * yres * BPP * frame;
 
@@ -428,7 +436,10 @@ static int ps3fb_sync(struct fb_info *in
 			"%s: lv1_gpu_context_attribute FLIP failed: %d\n",
 			__func__, status);
 #endif
-	return 0;
+
+out:
+	release_console_sem();
+	return error;
 }
 
 
@@ -547,6 +558,7 @@ static int ps3fb_check_var(struct fb_var
 
 static int ps3fb_set_par(struct fb_info *info)
 {
+	struct ps3fb_par *par = info->par;
 	unsigned int mode;
 	int i;
 	unsigned long offset;
@@ -560,7 +572,7 @@ static int ps3fb_set_par(struct fb_info 
 		return -EINVAL;
 
 	i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
-	ps3fb.res_index = i;
+	par->res_index = i;
 
 	offset = VFB_OFF(i);
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
@@ -568,14 +580,19 @@ static int ps3fb_set_par(struct fb_info 
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
 	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
 
-	ps3fb.num_frames = info->fix.smem_len/
-			   (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
+	par->num_frames = info->fix.smem_len/
+			  (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
-	ps3fb_mode = (ps3fb_mode & ~PS3AV_MODE_MASK) | mode;
+	par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
 
-	if (ps3av_set_video_mode(ps3fb_mode))
-		return -EINVAL;
+	if (par->new_mode_id != par->mode_id) {
+		if (ps3av_set_video_mode(par->new_mode_id)) {
+			par->new_mode_id = par->mode_id;
+			return -EINVAL;
+		}
+		par->mode_id = par->new_mode_id;
+	}
 
 	return 0;
 }
@@ -694,7 +711,7 @@ static int ps3fb_ioctl(struct fb_info *i
 		       unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
-	u32 val, old_mode;
+	u32 val;
 	int retval = -EFAULT;
 
 	switch (cmd) {
@@ -724,6 +741,7 @@ static int ps3fb_ioctl(struct fb_info *i
 
 	case PS3FB_IOCTL_SETMODE:
 		{
+			struct ps3fb_par *par = info->par;
 			const struct fb_videomode *mode;
 			struct fb_var_screeninfo var;
 
@@ -737,9 +755,7 @@ static int ps3fb_ioctl(struct fb_info *i
 			}
 			dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
 			retval = -EINVAL;
-			old_mode = ps3fb_mode;
-			ps3fb_mode = val;
-			mode = ps3fb_default_mode();
+			mode = ps3fb_default_mode(val);
 			if (mode) {
 				var = info->var;
 				fb_videomode_to_var(&var, mode);
@@ -747,12 +763,11 @@ static int ps3fb_ioctl(struct fb_info *i
 				info->flags |= FBINFO_MISC_USEREVENT;
 				/* Force, in case only special bits changed */
 				var.activate |= FB_ACTIVATE_FORCE;
+				par->new_mode_id = val;
 				retval = fb_set_var(info, &var);
 				info->flags &= ~FBINFO_MISC_USEREVENT;
 				release_console_sem();
 			}
-			if (retval)
-				ps3fb_mode = old_mode;
 			break;
 		}
 
@@ -765,14 +780,15 @@ static int ps3fb_ioctl(struct fb_info *i
 
 	case PS3FB_IOCTL_SCREENINFO:
 		{
+			struct ps3fb_par *par = info->par;
 			struct ps3fb_ioctl_res res;
-			int i = ps3fb.res_index;
+			int i = par->res_index;
 			dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
 			res.xres = ps3fb_res[i].xres;
 			res.yres = ps3fb_res[i].yres;
 			res.xoff = ps3fb_res[i].xoff;
 			res.yoff = ps3fb_res[i].yoff;
-			res.num_frames = ps3fb.num_frames;
+			res.num_frames = par->num_frames;
 			if (!copy_to_user(argp, &res, sizeof(res)))
 				retval = 0;
 			break;
@@ -979,6 +995,7 @@ static int ps3fb_set_sync(struct device 
 static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
 {
 	struct fb_info *info;
+	struct ps3fb_par *par;
 	int retval = -ENOMEM;
 	u32 xres, yres;
 	u64 ddr_lpar = 0;
@@ -987,7 +1004,7 @@ static int __devinit ps3fb_probe(struct 
 	u64 lpar_reports = 0;
 	u64 lpar_reports_size = 0;
 	u64 xdr_lpar;
-	int status;
+	int status, res_index;
 	unsigned long offset;
 	struct task_struct *task;
 
@@ -1004,15 +1021,14 @@ static int __devinit ps3fb_probe(struct 
 
 	if (ps3fb_mode > 0 &&
 	    !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
-		ps3fb.res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
-		dev_dbg(&dev->core, "res_index:%d\n", ps3fb.res_index);
+		res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
+		dev_dbg(&dev->core, "res_index:%d\n", res_index);
 	} else
-		ps3fb.res_index = GPU_RES_INDEX;
+		res_index = GPU_RES_INDEX;
 
 	atomic_set(&ps3fb.f_count, -1);	/* fbcon opens ps3fb */
 	atomic_set(&ps3fb.ext_flip, 0);	/* for flip with vsync */
 	init_waitqueue_head(&ps3fb.wait_vsync);
-	ps3fb.num_frames = 1;
 
 	ps3fb_set_sync(&dev->core);
 
@@ -1062,19 +1078,24 @@ static int __devinit ps3fb_probe(struct 
 	if (retval)
 		goto err_free_irq;
 
-	info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
+	info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
 	if (!info)
 		goto err_free_irq;
 
-	offset = VFB_OFF(ps3fb.res_index);
+	par = info->par;
+	par->mode_id = ~ps3fb_mode;	/* != ps3fb_mode, to trigger change */
+	par->new_mode_id = ps3fb_mode;
+	par->res_index = res_index;
+	par->num_frames = 1;
+
+	offset = VFB_OFF(res_index);
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
 	info->fbops = &ps3fb_ops;
 
 	info->fix = ps3fb_fix;
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
 	info->fix.smem_len = ps3fb.xdr_size - offset;
-	info->pseudo_palette = info->par;
-	info->par = NULL;
+	info->pseudo_palette = par->pseudo_palette;
 	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
 
 	retval = fb_alloc_cmap(&info->cmap, 256, 0);
@@ -1082,7 +1103,8 @@ static int __devinit ps3fb_probe(struct 
 		goto err_framebuffer_release;
 
 	if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
-			  ARRAY_SIZE(ps3fb_modedb), ps3fb_default_mode(), 32)) {
+			  ARRAY_SIZE(ps3fb_modedb),
+			  ps3fb_default_mode(par->new_mode_id), 32)) {
 		retval = -EINVAL;
 		goto err_fb_dealloc;
 	}

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 09/13] ps3fb: Dont keep the borders for non-fullscreen modes in XDR memory
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 8736 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

Don't keep the borders for non-fullscreen modes in XDR memory:
  - Extract ps3fb_sync_image()
  - Work around the alignment restrictions of L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT
    by using an offset with L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP
  - Only copy the visible part of the screen on every vblank
  - Always put the real frame buffer at the start of video memory
  - Clear fullscreen DDR memory on mode change

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |  131 ++++++++++++++++++++++++++++----------------------
 1 files changed, 75 insertions(+), 56 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -54,6 +54,7 @@
 #define DDR_SIZE				(0)	/* used no ddr */
 #define GPU_CMD_BUF_SIZE			(64 * 1024)
 #define GPU_IOIF				(0x0d000000UL)
+#define GPU_ALIGN_UP(x)				_ALIGN_UP((x), 64)
 
 #define PS3FB_FULL_MODE_BIT			0x80
 
@@ -136,6 +137,10 @@ struct ps3fb_par {
 	int mode_id, new_mode_id;
 	int res_index;
 	unsigned int num_frames;	/* num of frame buffers */
+	unsigned int width;
+	unsigned int height;
+	unsigned long full_offset;	/* start of fullscreen DDR fb */
+	unsigned long fb_offset;	/* start of actual DDR fb */
 };
 
 struct ps3fb_res_table {
@@ -291,15 +296,6 @@ static const struct fb_videomode ps3fb_m
 /* Start of the virtual frame buffer (relative to fullscreen ) */
 #define VP_OFF(i)	((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
 
-/*
- * Start of the virtual frame buffer (relative to start of video memory)
- * This is PAGE_SIZE aligned for easier mmap()
- */
-#define VFB_OFF(i)	PAGE_ALIGN(VP_OFF(i))
-
-/* Start of the fullscreen frame buffer (relative to start of video memory) */
-#define FB_OFF(i)	(-VP_OFF(i) & ~PAGE_MASK)
-
 
 static int ps3fb_mode;
 module_param(ps3fb_mode, int, 0);
@@ -386,63 +382,72 @@ static const struct fb_videomode *ps3fb_
 	return &ps3fb_modedb[mode - 1];
 }
 
-static int ps3fb_sync(struct fb_info *info, u32 frame)
+static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
+			     u64 dst_offset, u64 src_offset, u32 width,
+			     u32 height, u64 line_length)
 {
-	struct ps3fb_par *par = info->par;
-	int i, status, error = 0;
-	u32 xres, yres;
-	u64 fb_ioif, offset;
-
-	acquire_console_sem();
-
-	i = par->res_index;
-	xres = ps3fb_res[i].xres;
-	yres = ps3fb_res[i].yres;
-
-	if (frame > par->num_frames - 1) {
-		dev_dbg(info->device, "%s: invalid frame number (%u)\n",
-			__func__, frame);
-		error = -EINVAL;
-		goto out;
-	}
-	offset = xres * yres * BPP * frame;
+	int status;
 
-	fb_ioif = GPU_IOIF + FB_OFF(i) + offset;
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
-					   offset, fb_ioif,
+					   dst_offset, GPU_IOIF + src_offset,
 					   L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
-					   (xres << 16) | yres,
-					   xres * BPP);	/* line_length */
+					   (width << 16) | height,
+					   line_length);
 	if (status)
-		dev_err(info->device,
+		dev_err(dev,
 			"%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
 			__func__, status);
 #ifdef HEAD_A
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
-					   0, offset, 0, 0);
+					   0, frame_offset, 0, 0);
 	if (status)
-		dev_err(info->device,
-			"%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+		dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
 			__func__, status);
 #endif
 #ifdef HEAD_B
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
-					   1, offset, 0, 0);
+					   1, frame_offset, 0, 0);
 	if (status)
-		dev_err(info->device,
-			"%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+		dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
 			__func__, status);
 #endif
+}
+
+static int ps3fb_sync(struct fb_info *info, u32 frame)
+{
+	struct ps3fb_par *par = info->par;
+	int i, error = 0;
+	u32 xres, yres;
+	u64 line_length, base;
+
+	acquire_console_sem();
+
+	if (frame > par->num_frames - 1) {
+		dev_dbg(info->device, "%s: invalid frame number (%u)\n",
+			__func__, frame);
+		error = -EINVAL;
+		goto out;
+	}
+
+	i = par->res_index;
+	xres = ps3fb_res[i].xres;
+	yres = ps3fb_res[i].yres;
+
+	line_length = xres * BPP;
+	base = frame * yres * line_length;
+
+	ps3fb_sync_image(info->device, base + par->full_offset,
+			 base + par->fb_offset, base, par->width, par->height,
+			 line_length);
 
 out:
 	release_console_sem();
 	return error;
 }
 
-
 static int ps3fb_open(struct fb_info *info, int user)
 {
 	atomic_inc(&ps3fb.f_count);
@@ -472,7 +477,6 @@ static int ps3fb_check_var(struct fb_var
 {
 	u32 line_length;
 	int mode;
-	int i;
 
 	dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
 		info->var.xres);
@@ -539,9 +543,7 @@ static int ps3fb_check_var(struct fb_var
 	}
 
 	/* Memory limit */
-	i = ps3fb_get_res_table(var->xres, var->yres, mode);
-	if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP >
-	    ps3fb.xdr_size - VFB_OFF(i)) {
+	if (var->yres * line_length > ps3fb.xdr_size) {
 		dev_dbg(info->device, "Not enough memory\n");
 		return -ENOMEM;
 	}
@@ -559,9 +561,9 @@ static int ps3fb_check_var(struct fb_var
 static int ps3fb_set_par(struct fb_info *info)
 {
 	struct ps3fb_par *par = info->par;
-	unsigned int mode;
+	unsigned int mode, lines, maxlines;
 	int i;
-	unsigned long offset;
+	unsigned long offset, dst;
 
 	dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
 		info->var.xres, info->var.xres_virtual,
@@ -574,11 +576,9 @@ static int ps3fb_set_par(struct fb_info 
 	i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
 	par->res_index = i;
 
-	offset = VFB_OFF(i);
-	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
-	info->fix.smem_len = ps3fb.xdr_size - offset;
-	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
-	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
+	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
+	info->fix.smem_len = ps3fb.xdr_size;
+	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 
 	par->num_frames = info->fix.smem_len/
 			  (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
@@ -586,6 +586,12 @@ static int ps3fb_set_par(struct fb_info 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
 	par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
 
+	par->width = info->var.xres;
+	par->height = info->var.yres;
+	offset = VP_OFF(i);
+	par->fb_offset = GPU_ALIGN_UP(offset);
+	par->full_offset = par->fb_offset - offset;
+
 	if (par->new_mode_id != par->mode_id) {
 		if (ps3av_set_video_mode(par->new_mode_id)) {
 			par->new_mode_id = par->mode_id;
@@ -594,6 +600,21 @@ static int ps3fb_set_par(struct fb_info 
 		par->mode_id = par->new_mode_id;
 	}
 
+	/* Clear XDR frame buffer memory */
+	memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
+
+	/* Clear DDR frame buffer memory */
+	lines = ps3fb_res[i].yres * par->num_frames;
+	if (par->full_offset)
+		lines++;
+	maxlines = ps3fb.xdr_size / info->fix.line_length;
+	for (dst = 0; lines; dst += maxlines * info->fix.line_length) {
+		unsigned int l = min(lines, maxlines);
+		ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
+				 info->fix.line_length);
+		lines -= l;
+	}
+
 	return 0;
 }
 
@@ -1005,7 +1026,6 @@ static int __devinit ps3fb_probe(struct 
 	u64 lpar_reports_size = 0;
 	u64 xdr_lpar;
 	int status, res_index;
-	unsigned long offset;
 	struct task_struct *task;
 
 	status = ps3_open_hv_device(dev);
@@ -1088,13 +1108,12 @@ static int __devinit ps3fb_probe(struct 
 	par->res_index = res_index;
 	par->num_frames = 1;
 
-	offset = VFB_OFF(res_index);
-	info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
+	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 	info->fbops = &ps3fb_ops;
 
 	info->fix = ps3fb_fix;
-	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea) + offset;
-	info->fix.smem_len = ps3fb.xdr_size - offset;
+	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
+	info->fix.smem_len = ps3fb.xdr_size;
 	info->pseudo_palette = par->pseudo_palette;
 	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
 

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 10/13] ps3fb: Add virtual screen and panning support
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6553 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Add virtual screen and panning support:
  - The vertical virtual screen size is limited by the amount of memory
    reserved for ps3fb,
  - The horizontal virtual screen size is limited to the fullscreen width,
  - Advertise that we support panning, so fbcon will use it if the virtual
    screen is enabled.
    Enabling a virtual screen (using `fbset -vyres nnn') can speed up text
    console scrolling by a factor of 10-15, depending on the video mode.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   65 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 40 insertions(+), 25 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -141,6 +141,7 @@ struct ps3fb_par {
 	unsigned int height;
 	unsigned long full_offset;	/* start of fullscreen DDR fb */
 	unsigned long fb_offset;	/* start of actual DDR fb */
+	unsigned long pan_offset;
 };
 
 struct ps3fb_res_table {
@@ -440,8 +441,8 @@ static int ps3fb_sync(struct fb_info *in
 	base = frame * yres * line_length;
 
 	ps3fb_sync_image(info->device, base + par->full_offset,
-			 base + par->fb_offset, base, par->width, par->height,
-			 line_length);
+			 base + par->fb_offset, base + par->pan_offset,
+			 par->width, par->height, line_length);
 
 out:
 	release_console_sem();
@@ -488,27 +489,23 @@ static int ps3fb_check_var(struct fb_var
 	if (!mode)
 		return -EINVAL;
 
-	/*
-	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
-	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
-	 */
-
-	if (var->vmode & FB_VMODE_CONUPDATE) {
-		var->vmode |= FB_VMODE_YWRAP;
-		var->xoffset = info->var.xoffset;
-		var->yoffset = info->var.yoffset;
-	}
+	/* Virtual screen */
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
 
-	/* Virtual screen and panning are not supported */
-	if (var->xres_virtual > var->xres || var->yres_virtual > var->yres ||
-	    var->xoffset || var->yoffset) {
+	if (var->xres_virtual > line_length / BPP) {
 		dev_dbg(info->device,
-			"Virtual screen and panning are not supported\n");
+			"Horizontal virtual screen size too large\n");
 		return -EINVAL;
 	}
 
-	var->xres_virtual = var->xres;
-	var->yres_virtual = var->yres;
+	if (var->xoffset + var->xres > var->xres_virtual ||
+	    var->yoffset + var->yres > var->yres_virtual) {
+		dev_dbg(info->device, "panning out-of-range\n");
+		return -EINVAL;
+	}
 
 	/* We support ARGB8888 only */
 	if (var->bits_per_pixel > 32 || var->grayscale ||
@@ -543,7 +540,7 @@ static int ps3fb_check_var(struct fb_var
 	}
 
 	/* Memory limit */
-	if (var->yres * line_length > ps3fb.xdr_size) {
+	if (var->yres_virtual * line_length > ps3fb.xdr_size) {
 		dev_dbg(info->device, "Not enough memory\n");
 		return -ENOMEM;
 	}
@@ -561,7 +558,7 @@ static int ps3fb_check_var(struct fb_var
 static int ps3fb_set_par(struct fb_info *info)
 {
 	struct ps3fb_par *par = info->par;
-	unsigned int mode, lines, maxlines;
+	unsigned int mode, line_length, lines, maxlines;
 	int i;
 	unsigned long offset, dst;
 
@@ -569,7 +566,7 @@ static int ps3fb_set_par(struct fb_info 
 		info->var.xres, info->var.xres_virtual,
 		info->var.yres, info->var.yres_virtual, info->var.pixclock);
 
-	mode = ps3fb_find_mode(&info->var, &info->fix.line_length);
+	mode = ps3fb_find_mode(&info->var, &line_length);
 	if (!mode)
 		return -EINVAL;
 
@@ -578,6 +575,10 @@ static int ps3fb_set_par(struct fb_info 
 
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
 	info->fix.smem_len = ps3fb.xdr_size;
+	info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
+	info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
+	info->fix.line_length = line_length;
+
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 
 	par->num_frames = info->fix.smem_len/
@@ -591,6 +592,8 @@ static int ps3fb_set_par(struct fb_info 
 	offset = VP_OFF(i);
 	par->fb_offset = GPU_ALIGN_UP(offset);
 	par->full_offset = par->fb_offset - offset;
+	par->pan_offset = info->var.yoffset * line_length +
+			  info->var.xoffset * BPP;
 
 	if (par->new_mode_id != par->mode_id) {
 		if (ps3av_set_video_mode(par->new_mode_id)) {
@@ -607,11 +610,11 @@ static int ps3fb_set_par(struct fb_info 
 	lines = ps3fb_res[i].yres * par->num_frames;
 	if (par->full_offset)
 		lines++;
-	maxlines = ps3fb.xdr_size / info->fix.line_length;
-	for (dst = 0; lines; dst += maxlines * info->fix.line_length) {
+	maxlines = ps3fb.xdr_size / line_length;
+	for (dst = 0; lines; dst += maxlines * line_length) {
 		unsigned int l = min(lines, maxlines);
 		ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
-				 info->fix.line_length);
+				 line_length);
 		lines -= l;
 	}
 
@@ -641,6 +644,16 @@ static int ps3fb_setcolreg(unsigned int 
 	return 0;
 }
 
+static int ps3fb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct ps3fb_par *par = info->par;
+
+	par->pan_offset = var->yoffset * info->fix.line_length +
+			  var->xoffset * BPP;
+	return 0;
+}
+
     /*
      *  As we have a virtual frame buffer, we need our own mmap function
      */
@@ -965,6 +978,7 @@ static struct fb_ops ps3fb_ops = {
 	.fb_check_var	= ps3fb_check_var,
 	.fb_set_par	= ps3fb_set_par,
 	.fb_setcolreg	= ps3fb_setcolreg,
+	.fb_pan_display	= ps3fb_pan_display,
 	.fb_fillrect	= sys_fillrect,
 	.fb_copyarea	= sys_copyarea,
 	.fb_imageblit	= sys_imageblit,
@@ -1115,7 +1129,8 @@ static int __devinit ps3fb_probe(struct 
 	info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
 	info->fix.smem_len = ps3fb.xdr_size;
 	info->pseudo_palette = par->pseudo_palette;
-	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
+	info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
+		      FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
 
 	retval = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (retval < 0)

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 11/13] ps3fb: Enhance horizontal panning on firmware 1.90 and up
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 9150 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Enhance horizontal panning on firmware 1.90 and up:
  - On firmware 1.90 and up, L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT supports copying
    rectangles from XDR to DDR memory with different source and destination
    line lengths. Hence larger horizontal virtual resolutions can be supported
    (up to 16368 pixels).
  - As the actual frame buffer memory layout no longer matches the entries in
    ps3fb_res[], create fake struct ps3fb_ioctl_res data for the
    PS3FB_IOCTL_SCREENINFO ioctl, so user space applications that depend on it
    keep on working.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |  103 +++++++++++++++++++++++++++++---------------------
 1 files changed, 61 insertions(+), 42 deletions(-)

--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -55,6 +55,7 @@
 #define GPU_CMD_BUF_SIZE			(64 * 1024)
 #define GPU_IOIF				(0x0d000000UL)
 #define GPU_ALIGN_UP(x)				_ALIGN_UP((x), 64)
+#define GPU_MAX_LINE_LENGTH			(65536 - 64)
 
 #define PS3FB_FULL_MODE_BIT			0x80
 
@@ -335,7 +336,7 @@ static int ps3fb_get_res_table(u32 xres,
 }
 
 static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
-				    u32 *line_length)
+				    u32 *ddr_line_length, u32 *xdr_line_length)
 {
 	unsigned int i, mode;
 
@@ -350,19 +351,30 @@ static unsigned int ps3fb_find_mode(cons
 		    var->upper_margin == ps3fb_modedb[i].upper_margin &&
 		    var->lower_margin == ps3fb_modedb[i].lower_margin &&
 		    var->sync == ps3fb_modedb[i].sync &&
-		    (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) {
-			/* Cropped broadcast modes use the full line_length */
-			*line_length =
-			    ps3fb_modedb[i < 10 ? i + 13 : i].xres * 4;
-			/* Full broadcast modes have the full mode bit set */
-			mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
-
-			pr_debug("ps3fb_find_mode: mode %u\n", mode);
-			return mode;
-		}
+		    (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode)
+			goto found;
 
 	pr_debug("ps3fb_find_mode: mode not found\n");
 	return 0;
+
+found:
+	/* Cropped broadcast modes use the full line length */
+	*ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP;
+
+	if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
+		*xdr_line_length = GPU_ALIGN_UP(max(var->xres,
+						    var->xres_virtual) * BPP);
+		if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
+			*xdr_line_length = GPU_MAX_LINE_LENGTH;
+	} else
+		*xdr_line_length = *ddr_line_length;
+
+	/* Full broadcast modes have the full mode bit set */
+	mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
+
+	pr_debug("ps3fb_find_mode: mode %u\n", mode);
+
+	return mode;
 }
 
 static const struct fb_videomode *ps3fb_default_mode(int id)
@@ -385,9 +397,15 @@ static const struct fb_videomode *ps3fb_
 
 static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
 			     u64 dst_offset, u64 src_offset, u32 width,
-			     u32 height, u64 line_length)
+			     u32 height, u32 dst_line_length,
+			     u32 src_line_length)
 {
 	int status;
+	u64 line_length;
+
+	line_length = dst_line_length;
+	if (src_line_length != dst_line_length)
+		line_length |= (u64)src_line_length << 32;
 
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
@@ -421,8 +439,8 @@ static int ps3fb_sync(struct fb_info *in
 {
 	struct ps3fb_par *par = info->par;
 	int i, error = 0;
-	u32 xres, yres;
-	u64 line_length, base;
+	u32 ddr_line_length, xdr_line_length;
+	u64 ddr_base, xdr_base;
 
 	acquire_console_sem();
 
@@ -434,15 +452,15 @@ static int ps3fb_sync(struct fb_info *in
 	}
 
 	i = par->res_index;
-	xres = ps3fb_res[i].xres;
-	yres = ps3fb_res[i].yres;
-
-	line_length = xres * BPP;
-	base = frame * yres * line_length;
-
-	ps3fb_sync_image(info->device, base + par->full_offset,
-			 base + par->fb_offset, base + par->pan_offset,
-			 par->width, par->height, line_length);
+	xdr_line_length = info->fix.line_length;
+	ddr_line_length = ps3fb_res[i].xres * BPP;
+	xdr_base = frame * info->var.yres_virtual * xdr_line_length;
+	ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
+
+	ps3fb_sync_image(info->device, ddr_base + par->full_offset,
+			 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
+			 par->width, par->height, ddr_line_length,
+			 xdr_line_length);
 
 out:
 	release_console_sem();
@@ -476,7 +494,7 @@ static int ps3fb_release(struct fb_info 
 
 static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	u32 line_length;
+	u32 xdr_line_length, ddr_line_length;
 	int mode;
 
 	dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
@@ -485,7 +503,7 @@ static int ps3fb_check_var(struct fb_var
 		info->var.yres);
 
 	/* FIXME For now we do exact matches only */
-	mode = ps3fb_find_mode(var, &line_length);
+	mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
 	if (!mode)
 		return -EINVAL;
 
@@ -495,7 +513,7 @@ static int ps3fb_check_var(struct fb_var
 	if (var->yres_virtual < var->yres)
 		var->yres_virtual = var->yres;
 
-	if (var->xres_virtual > line_length / BPP) {
+	if (var->xres_virtual > xdr_line_length / BPP) {
 		dev_dbg(info->device,
 			"Horizontal virtual screen size too large\n");
 		return -EINVAL;
@@ -540,7 +558,7 @@ static int ps3fb_check_var(struct fb_var
 	}
 
 	/* Memory limit */
-	if (var->yres_virtual * line_length > ps3fb.xdr_size) {
+	if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) {
 		dev_dbg(info->device, "Not enough memory\n");
 		return -ENOMEM;
 	}
@@ -558,15 +576,16 @@ static int ps3fb_check_var(struct fb_var
 static int ps3fb_set_par(struct fb_info *info)
 {
 	struct ps3fb_par *par = info->par;
-	unsigned int mode, line_length, lines, maxlines;
+	unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
 	int i;
-	unsigned long offset, dst;
+	unsigned long offset;
+	u64 dst;
 
 	dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
 		info->var.xres, info->var.xres_virtual,
 		info->var.yres, info->var.yres_virtual, info->var.pixclock);
 
-	mode = ps3fb_find_mode(&info->var, &line_length);
+	mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
 	if (!mode)
 		return -EINVAL;
 
@@ -577,12 +596,13 @@ static int ps3fb_set_par(struct fb_info 
 	info->fix.smem_len = ps3fb.xdr_size;
 	info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
 	info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
-	info->fix.line_length = line_length;
+	info->fix.line_length = xdr_line_length;
 
 	info->screen_base = (char __iomem *)ps3fb.xdr_ea;
 
-	par->num_frames = info->fix.smem_len/
-			  (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
+	par->num_frames = ps3fb.xdr_size /
+			  max(ps3fb_res[i].yres * ddr_line_length,
+			      info->var.yres_virtual * xdr_line_length);
 
 	/* Keep the special bits we cannot set using fb_var_screeninfo */
 	par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
@@ -592,7 +612,7 @@ static int ps3fb_set_par(struct fb_info 
 	offset = VP_OFF(i);
 	par->fb_offset = GPU_ALIGN_UP(offset);
 	par->full_offset = par->fb_offset - offset;
-	par->pan_offset = info->var.yoffset * line_length +
+	par->pan_offset = info->var.yoffset * xdr_line_length +
 			  info->var.xoffset * BPP;
 
 	if (par->new_mode_id != par->mode_id) {
@@ -610,11 +630,11 @@ static int ps3fb_set_par(struct fb_info 
 	lines = ps3fb_res[i].yres * par->num_frames;
 	if (par->full_offset)
 		lines++;
-	maxlines = ps3fb.xdr_size / line_length;
-	for (dst = 0; lines; dst += maxlines * line_length) {
+	maxlines = ps3fb.xdr_size / ddr_line_length;
+	for (dst = 0; lines; dst += maxlines * ddr_line_length) {
 		unsigned int l = min(lines, maxlines);
 		ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
-				 line_length);
+				 ddr_line_length, ddr_line_length);
 		lines -= l;
 	}
 
@@ -816,12 +836,11 @@ static int ps3fb_ioctl(struct fb_info *i
 		{
 			struct ps3fb_par *par = info->par;
 			struct ps3fb_ioctl_res res;
-			int i = par->res_index;
 			dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
-			res.xres = ps3fb_res[i].xres;
-			res.yres = ps3fb_res[i].yres;
-			res.xoff = ps3fb_res[i].xoff;
-			res.yoff = ps3fb_res[i].yoff;
+			res.xres = info->fix.line_length / BPP;
+			res.yres = info->var.yres_virtual;
+			res.xoff = (res.xres - info->var.xres) / 2;
+			res.yoff = (res.yres - info->var.yres) / 2;
 			res.num_frames = par->num_frames;
 			if (!copy_to_user(argp, &res, sizeof(res)))
 				retval = 0;

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 12/13] fb: Move and rename extern declaration for global_mode_option
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2418 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

Move the extern declaration for global_mode_option to <linux/fb.h> and rename
the variable to fb_mode_option.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/fbmem.c  |    4 +---
 drivers/video/modedb.c |    4 ++--
 include/linux/fb.h     |    1 +
 3 files changed, 4 insertions(+), 5 deletions(-)

--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1567,8 +1567,6 @@ int fb_new_modelist(struct fb_info *info
 static char *video_options[FB_MAX] __read_mostly;
 static int ofonly __read_mostly;
 
-extern const char *global_mode_option;
-
 /**
  * fb_get_options - get kernel boot parameters
  * @name:   framebuffer name as it would appear in
@@ -1636,7 +1634,7 @@ static int __init video_setup(char *opti
  	}
 
  	if (!global && !strstr(options, "fb:")) {
- 		global_mode_option = options;
+ 		fb_mode_option = options;
  		global = 1;
  	}
 
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -27,7 +27,7 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-const char *global_mode_option;
+const char *fb_mode_option;
 
     /*
      *  Standard video mode definitions (taken from XFree86)
@@ -510,7 +510,7 @@ int fb_find_mode(struct fb_var_screeninf
 	default_bpp = 8;
 
     /* Did the user specify a video mode? */
-    if (mode_option || (mode_option = global_mode_option)) {
+    if (mode_option || (mode_option = fb_mode_option)) {
 	const char *name = mode_option;
 	unsigned int namelen = strlen(name);
 	int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1054,6 +1054,7 @@ struct fb_videomode {
 	u32 flag;
 };
 
+extern const char *fb_mode_option;
 extern const struct fb_videomode vesa_modes[];
 
 struct fb_modelist {

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [patch 13/13] ps3fb: Default to 480p on DVI-D/HDMI if video=safe
From: Geert Uytterhoeven @ 2007-10-12 14:51 UTC (permalink / raw)
  To: Antonino A. Daplas, Andrew Morton
  Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel, cbe-oss-dev
In-Reply-To: <20071012145052.640177000@pademelon.sonytel.be>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2186 bytes --]

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

ps3fb: Default to the 480p video mode on DVI-D and HDMI displays if
`video=safe' is passed on the kernel command line.

This is intended to be used by `kboot'-style boot loaders (i.e. first-stage
kernels) for the PS3, to provide a failsafe video mode.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/ps3/ps3av.c |   13 +++++++++++++
 1 files changed, 13 insertions(+)

--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/notifier.h>
 #include <linux/ioctl.h>
+#include <linux/fb.h>
 
 #include <asm/firmware.h>
 #include <asm/ps3av.h>
@@ -33,6 +34,8 @@
 #define BUFSIZE          4096	/* vuart buf size */
 #define PS3AV_BUF_SIZE   512	/* max packet size */
 
+static int safe_mode;
+
 static int timeout = 5000;	/* in msec ( 5 sec ) */
 module_param(timeout, int, 0644);
 
@@ -639,6 +642,9 @@ static int ps3av_hdmi_get_id(struct ps3a
 {
 	int id;
 
+	if (safe_mode)
+		return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
+
 	/* check native resolution */
 	id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
 			     info->res_vesa.native);
@@ -1021,7 +1027,14 @@ static int ps3av_probe(struct ps3_system
 		       res);
 
 	ps3av_get_hw_conf(ps3av);
+
+#ifdef CONFIG_FB
+	if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
+		safe_mode = 1;
+#endif /* CONFIG_FB */
 	id = ps3av_auto_videomode(&ps3av->av_hw_conf);
+	safe_mode = 0;
+
 	mutex_lock(&ps3av->mutex);
 	ps3av->ps3av_mode = id;
 	mutex_unlock(&ps3av->mutex);

-- 
With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* Re: [PATCH 4/4 v2] [POWERPC] Kilauea defconfig file
From: Scott Wood @ 2007-10-12 15:20 UTC (permalink / raw)
  To: Josh Boyer, Scott Wood, linuxppc-dev, Stefan Roese
In-Reply-To: <20071012032344.GG21056@localhost.localdomain>

David Gibson wrote:
> This is, of course, why CONFIG_DEVICE_TREE makes no real sense and
> never has: it's a per-image, not a per-configuration variable.

Enh.  It's useful.  When we have an image config file, let me know. :-)

-Scott

^ permalink raw reply

* mpc52xx bestcomm patches.
From: Grant Likely @ 2007-10-12 18:30 UTC (permalink / raw)
  To: Paul Mackerras, linuxppc-dev, Sylvain Munaut

Paulus, how do you feel about merging these changes?

This is Sylvain's series of bestcomm patches.

http://patchwork.ozlabs.org/linuxppc/patch?id=13488
http://patchwork.ozlabs.org/linuxppc/patch?id=13489
http://patchwork.ozlabs.org/linuxppc/patch?id=13490
http://patchwork.ozlabs.org/linuxppc/patch?id=13491
http://patchwork.ozlabs.org/linuxppc/patch?id=13492
http://patchwork.ozlabs.org/linuxppc/patch?id=13493
http://patchwork.ozlabs.org/linuxppc/patch?id=13494

There are still a few minor issues to be resolved, but Sylvain is
suffering from a severe lack of time and this series has been stalled
for a long time because of it.  Domen and others have been working on
drivers which use bestcomm, but they can neither get their drivers
included nor address the issues in this series because of it.

Personally, I think it will be better to just merge it now and allow
others to address the remaining comments.  It's not like this is a
change to an old device that could be risky.

/me thinks about somebody saying at some time "The perfect is the
enemy of the good"  :-)

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: mpc52xx bestcomm patches.
From: Kumar Gala @ 2007-10-12 18:40 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <fa686aa40710121130p7ec957bar471c2e8245bd162b@mail.gmail.com>


On Oct 12, 2007, at 1:30 PM, Grant Likely wrote:

> Paulus, how do you feel about merging these changes?
>
> This is Sylvain's series of bestcomm patches.
>
> http://patchwork.ozlabs.org/linuxppc/patch?id=13488
> http://patchwork.ozlabs.org/linuxppc/patch?id=13489
> http://patchwork.ozlabs.org/linuxppc/patch?id=13490
> http://patchwork.ozlabs.org/linuxppc/patch?id=13491
> http://patchwork.ozlabs.org/linuxppc/patch?id=13492
> http://patchwork.ozlabs.org/linuxppc/patch?id=13493
> http://patchwork.ozlabs.org/linuxppc/patch?id=13494
>
> There are still a few minor issues to be resolved, but Sylvain is
> suffering from a severe lack of time and this series has been stalled
> for a long time because of it.  Domen and others have been working on
> drivers which use bestcomm, but they can neither get their drivers
> included nor address the issues in this series because of it.
>
> Personally, I think it will be better to just merge it now and allow
> others to address the remaining comments.  It's not like this is a
> change to an old device that could be risky.

I'm against this getting merged w/o addressing some of the long  
standing comments I've made:

http://ozlabs.org/pipermail/linuxppc-dev/2007-May/036224.html
http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042632.html
http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042633.html

Additionally I think ALL new "libraries" like this should come with  
kerneldoc.

- k

^ permalink raw reply

* Re: mpc52xx bestcomm patches.
From: Grant Likely @ 2007-10-12 18:54 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <903EBFBB-D6B6-42EA-A0E3-63CAA55F6E23@kernel.crashing.org>

On 10/12/07, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Oct 12, 2007, at 1:30 PM, Grant Likely wrote:
>
> > Paulus, how do you feel about merging these changes?
> >
> > This is Sylvain's series of bestcomm patches.
> >
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13488
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13489
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13490
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13491
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13492
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13493
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13494
> >
> > There are still a few minor issues to be resolved, but Sylvain is
> > suffering from a severe lack of time and this series has been stalled
> > for a long time because of it.  Domen and others have been working on
> > drivers which use bestcomm, but they can neither get their drivers
> > included nor address the issues in this series because of it.
> >
> > Personally, I think it will be better to just merge it now and allow
> > others to address the remaining comments.  It's not like this is a
> > change to an old device that could be risky.
>
> I'm against this getting merged w/o addressing some of the long
> standing comments I've made:
>
> http://ozlabs.org/pipermail/linuxppc-dev/2007-May/036224.html
> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042632.html
> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042633.html
>
> Additionally I think ALL new "libraries" like this should come with
> kerneldoc.

The problem is that bestcomm is completely stalled on Sylvain.  He's
done good work, but he isn't able to put in the effort for the last
push to get it fixed and in.  But until that happens, nobody else will
step in to add patches on top of it to fix it up.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* MPC85xx and linux IDE driver
From: Michael Brian Willis @ 2007-10-12 18:29 UTC (permalink / raw)
  To: linuxppc-embedded

Hello, 

I am using an MPC8540 based embedded system with a Compact Flash card in
true IDE mode. The Compact Flash card is directly connected to the
MPC8540 bus without the use of a pcmcia adapter. 

The Compact Flash card is being initialized correctly using the U-boot
boot-loader and is working properly as an ide device in U-boot. However
I cannot get linux to recognize the ide device.

I have tried several different linux config options and have tried
passing kernel command line options as advised in the
Documentation/ide.txt help file. However I have not been able to get the
kernel to recognize my ide device. 

Does anybody know if I can use the generic linux ide drivers? Or will I
need to modify/write my own driver for this type of setup? 

Any help is greatly appreciated. 


Regards, 

Michael Willis
Applied Research Labs - University of Texas
willis  <at>  arlut.utexas.edu

^ permalink raw reply

* Re: MPC85xx and linux IDE driver
From: Ben Warren @ 2007-10-12 19:48 UTC (permalink / raw)
  To: Michael Brian Willis; +Cc: linuxppc-embedded
In-Reply-To: <1192213784.4862.48.camel@louie>

Michael Brian Willis wrote:
> Hello, 
>
> I am using an MPC8540 based embedded system with a Compact Flash card in
> true IDE mode. The Compact Flash card is directly connected to the
> MPC8540 bus without the use of a pcmcia adapter. 
>
> The Compact Flash card is being initialized correctly using the U-boot
> boot-loader and is working properly as an ide device in U-boot. However
> I cannot get linux to recognize the ide device.
>
> I have tried several different linux config options and have tried
> passing kernel command line options as advised in the
> Documentation/ide.txt help file. However I have not been able to get the
> kernel to recognize my ide device. 
>
> Does anybody know if I can use the generic linux ide drivers? Or will I
> need to modify/write my own driver for this type of setup? 
>   
Here's what I use:

http://marc.info/?l=linux-kernel&m=113877891224982&w=2

Please note that if you're using a kernel newer than 2.6.18, the _insw() 
and _outsw() calls no longer exist, so you'll need to replace them. 
Here's how I modified Kumar's functions. Not necessarily the right way, 
but it seems to work:

/* xxx: use standard outsw, insw when byte lanes swapped */
static void cfide_outsw(unsigned long port, void *addr, u32 count)
{
u16 *tmp = addr;
while (count--)
out_le16((u16 *)port, *tmp++);
}

static void cfide_insw(unsigned long port, void *addr, u32 count)
{
u16 *tmp = addr;
while (count--)
*tmp++ = in_le16((u16 *)port);
}


regards,
Ben

^ permalink raw reply

* Re: mpc52xx bestcomm patches.
From: Kumar Gala @ 2007-10-12 20:11 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <fa686aa40710121154i52e6caa0ve1130ea146b55a3f@mail.gmail.com>


On Oct 12, 2007, at 1:54 PM, Grant Likely wrote:

> On 10/12/07, Kumar Gala <galak@kernel.crashing.org> wrote:
>>
>> On Oct 12, 2007, at 1:30 PM, Grant Likely wrote:
>>
>>> Paulus, how do you feel about merging these changes?
>>>
>>> This is Sylvain's series of bestcomm patches.
>>>
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13488
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13489
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13490
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13491
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13492
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13493
>>> http://patchwork.ozlabs.org/linuxppc/patch?id=13494
>>>
>>> There are still a few minor issues to be resolved, but Sylvain is
>>> suffering from a severe lack of time and this series has been  
>>> stalled
>>> for a long time because of it.  Domen and others have been  
>>> working on
>>> drivers which use bestcomm, but they can neither get their drivers
>>> included nor address the issues in this series because of it.
>>>
>>> Personally, I think it will be better to just merge it now and allow
>>> others to address the remaining comments.  It's not like this is a
>>> change to an old device that could be risky.
>>
>> I'm against this getting merged w/o addressing some of the long
>> standing comments I've made:
>>
>> http://ozlabs.org/pipermail/linuxppc-dev/2007-May/036224.html
>> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042632.html
>> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042633.html
>>
>> Additionally I think ALL new "libraries" like this should come with
>> kerneldoc.
>
> The problem is that bestcomm is completely stalled on Sylvain.  He's
> done good work, but he isn't able to put in the effort for the last
> push to get it fixed and in.  But until that happens, nobody else will
> step in to add patches on top of it to fix it up.

If Sylvain doesn't have the time can't someone else pick up what he's  
done and fixup the issues with it?

- k

^ permalink raw reply

* [PATCH] cpm: Fix a couple minor issues in cpm_common.c.
From: Scott Wood @ 2007-10-12 20:19 UTC (permalink / raw)
  To: linuxppc-dev

A debugging printk is removed, and a comment is fixed to match
the code.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/sysdev/cpm_common.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 66c8ad4..165981c 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -77,8 +77,6 @@ int __init cpm_muram_init(void)
 	int i = 0;
 	int ret = 0;
 
-	printk("cpm_muram_init\n");
-
 	spin_lock_init(&cpm_muram_lock);
 	/* initialize the info header */
 	rh_init(&cpm_muram_info, 1,
@@ -193,7 +191,7 @@ void __iomem *cpm_muram_addr(unsigned long offset)
 EXPORT_SYMBOL(cpm_muram_addr);
 
 /**
- * cpm_muram_phys - turn a muram virtual address into a DMA address
+ * cpm_muram_dma - turn a muram virtual address into a DMA address
  * @offset: virtual address from cpm_muram_addr() to convert
  */
 dma_addr_t cpm_muram_dma(void __iomem *addr)
-- 
1.5.3.4

^ permalink raw reply related

* Re: mpc52xx bestcomm patches.
From: Grant Likely @ 2007-10-12 20:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Paul Mackerras, Domen Puncer
In-Reply-To: <DDF4941D-02CA-49FA-999D-8BD08740902C@kernel.crashing.org>

On 10/12/07, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Oct 12, 2007, at 1:54 PM, Grant Likely wrote:
>
> > On 10/12/07, Kumar Gala <galak@kernel.crashing.org> wrote:
> >>
> >> On Oct 12, 2007, at 1:30 PM, Grant Likely wrote:
> >>
> >>> Paulus, how do you feel about merging these changes?
> >>>
> >>> This is Sylvain's series of bestcomm patches.
> >>>
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13488
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13489
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13490
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13491
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13492
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13493
> >>> http://patchwork.ozlabs.org/linuxppc/patch?id=13494
> >>>
> >>> There are still a few minor issues to be resolved, but Sylvain is
> >>> suffering from a severe lack of time and this series has been
> >>> stalled
> >>> for a long time because of it.  Domen and others have been
> >>> working on
> >>> drivers which use bestcomm, but they can neither get their drivers
> >>> included nor address the issues in this series because of it.
> >>>
> >>> Personally, I think it will be better to just merge it now and allow
> >>> others to address the remaining comments.  It's not like this is a
> >>> change to an old device that could be risky.
> >>
> >> I'm against this getting merged w/o addressing some of the long
> >> standing comments I've made:
> >>
> >> http://ozlabs.org/pipermail/linuxppc-dev/2007-May/036224.html
> >> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042632.html
> >> http://ozlabs.org/pipermail/linuxppc-dev/2007-September/042633.html
> >>
> >> Additionally I think ALL new "libraries" like this should come with
> >> kerneldoc.
> >
> > The problem is that bestcomm is completely stalled on Sylvain.  He's
> > done good work, but he isn't able to put in the effort for the last
> > push to get it fixed and in.  But until that happens, nobody else will
> > step in to add patches on top of it to fix it up.
>
> If Sylvain doesn't have the time can't someone else pick up what he's
> done and fixup the issues with it?

As we talked about on IRC, I'm rebasing the patches now and I'll deal
with the minor issues.  There are a couple of developers actively
working on drivers which depend on bestcomm; since they are using it,
they will be able to support it too.

The code is in good shape; is well layed out and coded.  There are
developers actively using this driver in private trees.

However, that leaves the last major issue; documentation.  The
requested documentation has not been written.  However, I do not thing
this device driver should be blocked from merging over this issue.  I
think there is a better chance of it getting documented if it is
merged instead of sitting in Sylvain's queue.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Override timer interrupt
From: Rune Torgersen @ 2007-10-12 20:43 UTC (permalink / raw)
  To: linuxppc-embedded

Is there an easy way to use something other than the decrementer for the
timer interrupt?

Reason i'm asking is tha t on our board, the decrementer cannot be
divided to 1khz evenly, so we have rounding errors for time, but we do
have a 1KHz timer interrupt from an FPGA that is source of a T1 clock.

Right now I let the decrementer interrupt do nothing, and made my own
timer interrupt handler that calls the stuff the timer_interrupt usually
does.=20

This works, but there are some instability (ie unexplained hangs) that
showed up when I did this.

^ permalink raw reply

* Override timer interrupt
From: Rune Torgersen @ 2007-10-12 20:49 UTC (permalink / raw)
  To: linuxppc-dev

Is there an easy way to use something other than the decrementer for the
timer interrupt?

Reason i'm asking is tha t on our board, the decrementer cannot be
divided to 1khz evenly, so we have rounding errors for time, but we do
have a 1KHz timer interrupt from an FPGA that is source of a T1 clock.

Right now I let the decrementer interrupt do nothing, and made my own
timer interrupt handler that calls the stuff the timer_interrupt usually
does.=20

This works, but there are some instability (ie unexplained hangs) that
showed up when I did this.

^ permalink raw reply

* Re: Override timer interrupt
From: Mark A. Greer @ 2007-10-12 21:30 UTC (permalink / raw)
  To: Rune Torgersen; +Cc: linuxppc-embedded
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B037D4BA9@ismail.innsys.innovsys.com>

On Fri, Oct 12, 2007 at 03:43:39PM -0500, Rune Torgersen wrote:
> Is there an easy way to use something other than the decrementer for the
> timer interrupt?
> 
> Reason i'm asking is tha t on our board, the decrementer cannot be
> divided to 1khz evenly, so we have rounding errors for time, but we do
> have a 1KHz timer interrupt from an FPGA that is source of a T1 clock.
> 
> Right now I let the decrementer interrupt do nothing, and made my own
> timer interrupt handler that calls the stuff the timer_interrupt usually
> does. 
> 
> This works, but there are some instability (ie unexplained hangs) that
> showed up when I did this.

Check out the clocksource stuff.  It let's you set up numerous clock
sources and set the rating of each one.  You can start looking in
arch/powerpc/kernel/time.c for example code.

Mark

^ permalink raw reply

* Re: Override timer interrupt
From: Mark A. Greer @ 2007-10-12 21:32 UTC (permalink / raw)
  To: Rune Torgersen; +Cc: linuxppc-dev
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B037D4BB7@ismail.innsys.innovsys.com>

On Fri, Oct 12, 2007 at 03:49:02PM -0500, Rune Torgersen wrote:
> Is there an easy way to use something other than the decrementer for the
> timer interrupt?
> 
> Reason i'm asking is tha t on our board, the decrementer cannot be
> divided to 1khz evenly, so we have rounding errors for time, but we do
> have a 1KHz timer interrupt from an FPGA that is source of a T1 clock.
> 
> Right now I let the decrementer interrupt do nothing, and made my own
> timer interrupt handler that calls the stuff the timer_interrupt usually
> does. 
> 
> This works, but there are some instability (ie unexplained hangs) that
> showed up when I did this.

I just responded to you on -embedded with this:

"Check out the clocksource stuff.  It let's you set up numerous clock
 sources and set the rating of each one.  You can start looking in
 arch/powerpc/kernel/time.c for example code."

Mark

^ permalink raw reply

* RE: Override timer interrupt
From: Rune Torgersen @ 2007-10-12 21:39 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <20071012213041.GB22894@mag.az.mvista.com>

> From: Mark A. Greer=20
> > Is there an easy way to use something other than the decrementer for
the
> > timer interrupt?

> Check out the clocksource stuff.  It let's you set up numerous clock
> sources and set the rating of each one.  You can start looking in
> arch/powerpc/kernel/time.c for example code.

Thanks I will.=20
Currently our board port lives in /arch/ppc (2.6.18) but I will take a
look in powerpc.

^ permalink raw reply

* Re: [RFC] [PATCH] PowerPC: add more than 4MB kernel image size support to bootwarapper
From: Mark A. Greer @ 2007-10-12 21:53 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <47098882.1010900@freescale.com>

On Sun, Oct 07, 2007 at 08:31:46PM -0500, Scott Wood wrote:

Sorry for the delay, Scott.

> Mark A. Greer wrote:
> >Why?  Because its only safe to download a zImage to certain "safe" 
> >locations.
> >Where those "safe" locations are vary by firmware, firmware version, and
> >zImage size.  This is the issue we're discussing.
> 
> In theory, yes -- but in practice the odds of this particular heuristic 
> choosing an unsuitable address seem slim.

Yes, it probably will work fairly well for most powerpc 32-bit platforms
since the default in arch/ppc was 8MB (but there was a manual override
that was used by some platforms).  That still doesn't make it safe for
everyone 32-bit or 64-bit.

> >I've already explained _why_ the link address matters WRT where its 
> >downloaded.
> 
> Sorry, I was being a bit too pendantic with respect to the distinction 
> between link and load address.

And I was probably too impatient.  Sorry.

> >>>Also, being able to control the link address (that is, the download
> >>>address with some firmwares) is not a u-boot specific issue and we
> >>>shouldn't make a u-boot specific solution.
> >>How is this a u-boot specific solution?
> >
> >Because the hoops being jumped through in the patch(es) are to make
> >u-boot happy and no other firmware.
> 
> No, the "hoops" (which I don't think are sufficiently complicated to 
> warrant such a name)

Not yet maybe but as exceptions come along
	". = ALIGN((_kend - _kstart + 64*1024), (4*1024*1024));"
will become more complicated.

> are to address a generic issue with the bootwrapper 
> -- it wants to put the kernel at zero.  It'd be really nice if, in the 
> absense of a vmlinux_alloc method, the generic code would do an ordinary 
> malloc() if there's not enough room at zero.

Actually, that's a good idea but its only for safety sake.  When you
unpack the kernel at somewhere other than 0, there will be an additional
copy very early during kernel boot to copy itself to address 0.  So, if
we add that feature we should print a warning so the user knows extra
time was spent copying the kernel to 0.  If we can come up with a simple
way to control the link address we can avoid that copy.

> >>I'd much rather it be automatic than require the user to guess an
> >>appropriate value (and be aware in the first place that it needs to be 
> >>set).
> >
> >Sure, automatic is nice; conjuring up the magic to make it work in all
> >situations isn't.
> 
> I think this heuristic would work in most situations, so if we do add a 
> manual override it should be an override, and not something that 
> everybody has to put up with.

Okay, so how about we just leave the default at 4MB and come up with
that manual override??  ;)

> >Having the link address--and therefore the download address on some
> >systems--mysteriously and uncontrollably jump around based on the zImage
> >size is asking for trouble.
> 
> It's a source of potential issues, but I think "asking for trouble" is 
> exaggerating somewhat.

Noted and disagreed with. :)

Mark

^ permalink raw reply

* Re: Override timer interrupt
From: Mark A. Greer @ 2007-10-12 21:55 UTC (permalink / raw)
  To: Rune Torgersen; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B037D4C1B@ismail.innsys.innovsys.com>

On Fri, Oct 12, 2007 at 04:39:53PM -0500, Rune Torgersen wrote:
> > From: Mark A. Greer 
> > > Is there an easy way to use something other than the decrementer for
> the
> > > timer interrupt?
> 
> > Check out the clocksource stuff.  It let's you set up numerous clock
> > sources and set the rating of each one.  You can start looking in
> > arch/powerpc/kernel/time.c for example code.
> 
> Thanks I will. 
> Currently our board port lives in /arch/ppc (2.6.18) but I will take a
> look in powerpc.

Okay.  Just an FYI, arch/ppc will evaporate next summer.

Mark

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox