All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][LINUX] Dynamic modes support for PV xenfb
       [not found] ` <4774DEFD02000018006084F9@sinclair.provo.novell.com>
@ 2007-12-28 18:33   ` Pat Campbell
  2007-12-28 19:00     ` John Levon
  0 siblings, 1 reply; 4+ messages in thread
From: Pat Campbell @ 2007-12-28 18:33 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 538 bytes --]


Attached patch adds multiple frame buffer resolution support to 
the PV xenfb frame buffer driver.

Code is essentially the same as I sent in the previous RFC except
the frame buffer size is now 800x600 if the backend does not
support feature-resize,  same memory footprint.

Corresponding backend IOEMU patch is required for functionality but 
this patch is not dependent on it, preserving backwards compatibility.

Please apply to tip of linux-2.6.18-xen

Signed-     off-     by: Pat Campbell <plc@novell.com>






[-- Attachment #2: xen-fbfront-resize.patch --]
[-- Type: text/plain, Size: 8285 bytes --]

diff -r 61c96456a3e1 drivers/xen/fbfront/xenfb.c
--- a/drivers/xen/fbfront/xenfb.c	Thu Dec 20 16:58:14 2007 +0000
+++ b/drivers/xen/fbfront/xenfb.c	Fri Dec 28 03:12:41 2007 -0700
@@ -62,6 +62,9 @@ struct xenfb_info
 	struct xenfb_page	*page;
 	unsigned long 		*mfns;
 	int			update_wanted; /* XENFB_TYPE_UPDATE wanted */
+	int			feature_resize; /* Backend has resize feature */
+	int			resize_dpy;
+	int			xres, yres;
 
 	struct xenbus_device	*xbdev;
 };
@@ -130,13 +133,18 @@ struct xenfb_info
  * Oh well, we wont be updating the writes to this page anytime soon.
  */
 
+#define XENFB_PIXCLOCK  9025  /* Xorg "1280x1024" 110.80 to FB 1000000/110.80 */ 
+#define XENFB_MAX_WIDTH 1024
+#define XENFB_MAX_HEIGHT 768
+
 static int xenfb_fps = 20;
-static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
+static unsigned long xenfb_mem_len = XENFB_MAX_WIDTH * XENFB_MAX_HEIGHT * XENFB_DEPTH / 8;
 
 static int xenfb_remove(struct xenbus_device *);
 static void xenfb_init_shared_page(struct xenfb_info *);
 static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
 static void xenfb_disconnect_backend(struct xenfb_info *);
+static void xenfb_refresh(struct xenfb_info *info, int x1, int y1, int w, int h);
 
 static void xenfb_do_update(struct xenfb_info *info,
 			    int x, int y, int w, int h)
@@ -155,6 +163,25 @@ static void xenfb_do_update(struct xenfb
 	mb();			/* ensure ring space available */
 	XENFB_OUT_RING_REF(info->page, prod) = event;
 	wmb();			/* ensure ring contents visible */
+	info->page->out_prod = prod + 1;
+
+	notify_remote_via_irq(info->irq);
+}
+
+static void xenfb_do_resize(struct xenfb_info *info)
+{
+	union xenfb_out_event event;
+	__u32 prod;
+
+	event.type = XENFB_TYPE_RESIZE;
+	event.resize.width = info->xres;
+	event.resize.height = info->yres;
+
+	prod = info->page->out_prod;
+	/* caller ensures !xenfb_queue_full() */
+	mb();           /* ensure ring space available */
+	XENFB_OUT_RING_REF(info->page, prod) = event;
+	wmb();          /* ensure ring contents visible */
 	info->page->out_prod = prod + 1;
 
 	notify_remote_via_irq(info->irq);
@@ -209,6 +236,16 @@ static void xenfb_update_screen(struct x
 	xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
 }
 
+static void xenfb_resize_screen(struct xenfb_info *info)
+{
+	if (xenfb_queue_full(info))
+		return;
+
+	info->resize_dpy = 0;
+	xenfb_do_resize(info);
+	xenfb_refresh(info, 0, 0, info->xres, info->yres);
+}
+
 static int xenfb_thread(void *data)
 {
 	struct xenfb_info *info = data;
@@ -217,6 +254,9 @@ static int xenfb_thread(void *data)
 		if (info->dirty) {
 			info->dirty = 0;
 			xenfb_update_screen(info);
+		}
+		if (info->resize_dpy) {
+			xenfb_resize_screen(info);
 		}
 		wait_event_interruptible(info->wq,
 			kthread_should_stop() || info->dirty);
@@ -413,6 +453,46 @@ static int xenfb_mmap(struct fb_info *fb
 	return 0;
 }
 
+static int
+xenfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct xenfb_info *xenfb_info;
+
+	xenfb_info = info->par;
+
+	if (!xenfb_info->feature_resize) {
+		if (var->xres == XENFB_WIDTH && var->yres == XENFB_HEIGHT) {
+			return 0;
+		}
+		return -EINVAL;
+	}
+	if (var->xres == 1024 && var->yres == 768) {
+		return 0;
+	}
+	if (var->xres == 800 && var->yres == 600) {
+		return 0;
+	}
+	if (var->xres == 640 && var->yres == 480) {
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int xenfb_set_par(struct fb_info *info)
+{
+	struct xenfb_info *xenfb_info;
+
+	xenfb_info = info->par;
+
+	if (xenfb_info->xres != info->var.xres || 
+			xenfb_info->yres != info->var.yres) {
+		xenfb_info->xres = info->var.xres;
+		xenfb_info->yres = info->var.yres;
+		xenfb_info->resize_dpy = 1;
+	}
+	return 0;
+}
+
 static struct fb_ops xenfb_fb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_setcolreg	= xenfb_setcolreg,
@@ -420,6 +500,8 @@ static struct fb_ops xenfb_fb_ops = {
 	.fb_copyarea	= xenfb_copyarea,
 	.fb_imageblit	= xenfb_imageblit,
 	.fb_mmap	= xenfb_mmap,
+	.fb_check_var	= xenfb_check_var,
+	.fb_set_par     = xenfb_set_par,
 };
 
 static irqreturn_t xenfb_event_handler(int rq, void *dev_id,
@@ -451,16 +533,28 @@ static int __devinit xenfb_probe(struct 
 	struct xenfb_info *info;
 	struct fb_info *fb_info;
 	int ret;
+	int val;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (info == NULL) {
 		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
 		return -ENOMEM;
 	}
+
+	if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-resize", "%d", &val) < 0)
+		val = 0;
+	info->feature_resize = val;
+	if (info->feature_resize)
+		xenfb_mem_len = XENFB_MAX_WIDTH * XENFB_MAX_HEIGHT * XENFB_DEPTH / 8;
+	else
+		xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
+
 	dev->dev.driver_data = info;
 	info->xbdev = dev;
 	info->irq = -1;
 	info->x1 = info->y1 = INT_MAX;
+	info->xres = XENFB_WIDTH;
+	info->yres = XENFB_HEIGHT;
 	spin_lock_init(&info->dirty_lock);
 	mutex_init(&info->mm_lock);
 	init_waitqueue_head(&info->wq);
@@ -504,9 +598,10 @@ static int __devinit xenfb_probe(struct 
 	fb_info->screen_base = info->fb;
 
 	fb_info->fbops = &xenfb_fb_ops;
-	fb_info->var.xres_virtual = fb_info->var.xres = info->page->width;
-	fb_info->var.yres_virtual = fb_info->var.yres = info->page->height;
+	fb_info->var.xres_virtual = fb_info->var.xres = info->xres;
+	fb_info->var.yres_virtual = fb_info->var.yres = info->yres;
 	fb_info->var.bits_per_pixel = info->page->depth;
+	fb_info->var.pixclock = XENFB_PIXCLOCK;
 
 	fb_info->var.red = (struct fb_bitfield){16, 8, 0};
 	fb_info->var.green = (struct fb_bitfield){8, 8, 0};
@@ -600,19 +695,30 @@ static void xenfb_init_shared_page(struc
 static void xenfb_init_shared_page(struct xenfb_info *info)
 {
 	int i;
-
+	int j;
+	int entries_per_pd;
+
+	entries_per_pd = PAGE_SIZE/sizeof(unsigned long);
+	
 	for (i = 0; i < info->nr_pages; i++)
 		info->pages[i] = vmalloc_to_page(info->fb + i * PAGE_SIZE);
 
-	for (i = 0; i < info->nr_pages; i++)
-		info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
-
 	info->page->pd[0] = vmalloc_to_mfn(info->mfns);
 	info->page->pd[1] = 0;
+	for ( j = i = 0; i < info->nr_pages; i++) {
+		info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
+		if ( i && i % entries_per_pd == 0 ) {
+			j++;
+			info->page->pd[j] = vmalloc_to_mfn(&info->mfns[i]);
+		}
+	}
 	info->page->width = XENFB_WIDTH;
 	info->page->height = XENFB_HEIGHT;
 	info->page->depth = XENFB_DEPTH;
-	info->page->line_length = (info->page->depth / 8) * info->page->width;
+	if (info->feature_resize)
+		info->page->line_length = (info->page->depth / 8) * XENFB_MAX_WIDTH;
+	else
+		info->page->line_length = (info->page->depth / 8) * XENFB_WIDTH;
 	info->page->mem_length = xenfb_mem_len;
 	info->page->in_cons = info->page->in_prod = 0;
 	info->page->out_cons = info->page->out_prod = 0;
diff -r 61c96456a3e1 include/xen/interface/io/fbif.h
--- a/include/xen/interface/io/fbif.h	Thu Dec 20 16:58:14 2007 +0000
+++ b/include/xen/interface/io/fbif.h	Fri Dec 28 01:26:50 2007 -0700
@@ -50,12 +50,26 @@ struct xenfb_update
     int32_t height; /* rect height */
 };
 
+/*
+ * Framebuffer resize notification event
+ * Capable backend sets feature-resize in xenstore.
+ */
+#define XENFB_TYPE_RESIZE 3
+
+struct xenfb_resize
+{
+    uint8_t type;    /* XENFB_TYPE_RESIZE */
+    int32_t width;   /* xres */
+    int32_t height;  /* yres */
+};
+
 #define XENFB_OUT_EVENT_SIZE 40
 
 union xenfb_out_event
 {
     uint8_t type;
     struct xenfb_update update;
+    struct xenfb_resize resize;
     char pad[XENFB_OUT_EVENT_SIZE];
 };
 
@@ -111,8 +125,12 @@ struct xenfb_page
      * PAGE_SIZE / sizeof(*pd) bytes.  With PAGE_SIZE == 4096 and
      * sizeof(unsigned long) == 4, that's 4 Megs.  Two directory
      * pages should be enough for a while.
+     *
+     * Increased to 3 to support 1280x1024 resolution on a 64bit system
+     *  (1280*1024*4)/PAGE_SIZE = 1280 pages required
+     *  PAGE_SIZE/64bit long = 512 pages per page directory
      */
-    unsigned long pd[2];
+    unsigned long pd[3];
 };
 
 /*

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][LINUX] Dynamic modes support for PV xenfb
  2007-12-28 18:33   ` Pat Campbell
@ 2007-12-28 19:00     ` John Levon
       [not found]       ` <4777A666.3E48.0018.0@novell.com>
  0 siblings, 1 reply; 4+ messages in thread
From: John Levon @ 2007-12-28 19:00 UTC (permalink / raw)
  To: Pat Campbell; +Cc: xen-devel

On Fri, Dec 28, 2007 at 11:33:17AM -0700, Pat Campbell wrote:

> Attached patch adds multiple frame buffer resolution support to 
> the PV xenfb frame buffer driver.

Note this change will need an update to:

http://wiki.xensource.com/xenwiki/APIChangelog

if/when it goes in.

regards
john

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][LINUX] Dynamic modes support for PV xenfb
@ 2007-12-31  3:16 Pat Campbell
  0 siblings, 0 replies; 4+ messages in thread
From: Pat Campbell @ 2007-12-31  3:16 UTC (permalink / raw)
  To: John Levon; +Cc: xen-devel

>>> On Fri, Dec 28, 2007 at 12:00 PM, in message
<20071228190018.GB8404@totally.trollied.org.uk>, John Levon
<levon@movementarian.org> wrote: 
> On Fri, Dec 28, 2007 at 11:33:17AM -   0700, Pat Campbell wrote:
> 
>> Attached patch adds multiple frame buffer resolution support to 
>> the PV xenfb frame buffer driver.
> 
> Note this change will need an update to:
> 
> http://wiki.xensource.com/xenwiki/APIChangelog
> 
> if/when it goes in.
> 
> regards
> john

John,

I read the page at the included wiki link.  This patch is backwards 
compatible and "should not" present any cross-OS compatibility
issues.  Resolution change, if any, is driven by the guest OS.

I am not adversed to documenting the change but not sure
it is an API change.

Pat   

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][LINUX] Dynamic modes support for PV xenfb
       [not found]       ` <4777A666.3E48.0018.0@novell.com>
@ 2007-12-31  3:47         ` John Levon
  0 siblings, 0 replies; 4+ messages in thread
From: John Levon @ 2007-12-31  3:47 UTC (permalink / raw)
  To: Pat Campbell; +Cc: xen-devel

On Sun, Dec 30, 2007 at 02:10:09PM -0700, Pat Campbell wrote:

> >> Attached patch adds multiple frame buffer resolution support to 
> >> the PV xenfb frame buffer driver.
> > 
> > Note this change will need an update to:
> > 
> > http://wiki.xensource.com/xenwiki/APIChangelog
> > 
> > if/when it goes in.
> 
> John,
> 
> I read the page at the included wiki link.  This patch is backwards 
> compatible and "should not" present any cross-OS compatibility
> issues.  Resolution change, if any, is driven by the guest OS.
> 
> I am not adversed to documenting the change but not sure
> it is an API change.

An addition is a change, just not an incompatible one.

regards,
john

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-12-31  3:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-31  3:16 [PATCH][LINUX] Dynamic modes support for PV xenfb Pat Campbell
     [not found] <4774D94A02000018006084D2@sinclair.provo.novell.com>
     [not found] ` <4774DEFD02000018006084F9@sinclair.provo.novell.com>
2007-12-28 18:33   ` Pat Campbell
2007-12-28 19:00     ` John Levon
     [not found]       ` <4777A666.3E48.0018.0@novell.com>
2007-12-31  3:47         ` John Levon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.