diff -rud xorg-server-1.3.99.0~git20070321/debian/changelog ../xorg-server-1.3.99.0~git20070321/debian/changelog
--- xorg-server-1.3.99.0~git20070321/debian/changelog	2008-09-24 15:02:02.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/debian/changelog	2008-12-30 02:19:44.000000000 +0100
@@ -1,4 +1,4 @@
-xorg-server (1:1.3.99.0~git20070321-0osso20083801) unstable; urgency=low
+xorg-server (1:1.3.99.0~git20070321-0osso20083801rotation) unstable; urgency=low
 
   * Add missed part of fb optimisations (fixes: NB#86182).
 
diff -rud xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.c ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.c
--- xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.c	2008-09-24 15:01:53.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.c	2008-12-30 01:41:32.000000000 +0100
@@ -55,6 +55,9 @@
 #include "scrnintstr.h"
 #include "kdrive.h"
 #include "omap.h"
+#ifdef RANDR
+#include <randrstr.h>
+#endif
 
 static Bool
 omap_card_init(KdCardInfo *card)
@@ -242,6 +245,8 @@
         screen->fb[0].frameBuffer = screen->memory_base;
     }
 
+    omaps->randr = screen->randr;
+
     LEAVE();
 
     return TRUE;
@@ -263,6 +268,181 @@
     return TRUE;
 }
 
+#ifdef RANDR
+
+Bool
+omap_map_framebuffer(KdScreenInfo *screen)
+{
+    struct omap_screen_info *omaps = screen->driver;
+    KdPointerMatrix	m;
+    struct omap_card_info *priv = screen->card->driver;
+    int line_length, height;
+
+    omaps->shadowfb = FALSE;
+
+    if (omaps->randr & (RR_Rotate_90|RR_Rotate_270)) {
+        line_length = 2 * screen->height;
+        height = screen->width;
+    }
+    else {
+        line_length = 2 * screen->width;
+        height = screen->height;
+    }
+
+    KdComputePointerMatrix (&m, omaps->randr, screen->width, screen->height);
+    KdSetPointerMatrix (&m);
+
+    screen->width = priv->orig_width;
+    screen->height = priv->orig_height;
+
+    screen->memory_base = (CARD8 *) (omaps->plane->fb);
+    screen->memory_size = priv->planes->fix.smem_len;
+
+    screen->fb[0].byteStride = line_length;
+    screen->fb[0].pixelStride = line_length * 8 / screen->fb[0].bitsPerPixel;
+    screen->fb[0].frameBuffer = (CARD8 *) (omaps->plane->fb);
+    screen->off_screen_base = screen->fb[0].byteStride * height;
+
+    return TRUE;
+}
+
+void
+omap_set_screen_sizes(ScreenPtr pScreen)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    struct omap_screen_info *omaps =  pScreenPriv->screen->driver;
+    struct omap_card_info *priv = screen->card->driver;
+    if (omaps->randr & (RR_Rotate_0|RR_Rotate_180))
+    {
+	pScreen->width = screen->width;
+	pScreen->height = screen->height;
+	pScreen->mmWidth = screen->width_mm;
+	pScreen->mmHeight = screen->height_mm;
+    }
+    else
+    {
+	pScreen->width = screen->height;
+	pScreen->height = screen->width;
+	pScreen->mmWidth = screen->height_mm;
+	pScreen->mmHeight = screen->width_mm;
+    }
+}
+
+Bool
+omap_randr_get_info(ScreenPtr pScreen, Rotation *rotations)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    struct omap_screen_info *omaps = pScreenPriv->screen->driver;
+    RRScreenSizePtr pSize;
+    Rotation randr;
+    int n;
+    *rotations = (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270);
+
+    for (n = 0; n < pScreen->numDepths; n++)
+	if (pScreen->allowedDepths[n].numVids)
+	    break;
+    if (n == pScreen->numDepths)
+	return FALSE;
+
+    pSize = RRRegisterSize (pScreen,
+			    screen->width,
+			    screen->height,
+			    screen->width_mm,
+			    screen->height_mm);
+
+    randr = KdSubRotation (omaps->randr, screen->randr);
+
+    RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+    return TRUE;
+}
+
+Bool
+omap_randr_set_config(ScreenPtr		pScreen,
+		      Rotation		randr,
+		      int 		rate,
+		      RRScreenSizePtr	pSize)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    struct omap_screen_info *omaps =  pScreenPriv->screen->driver;
+    Bool wasEnabled = pScreenPriv->enabled;
+    struct omap_screen_info oldscr;
+    int oldwidth, oldheight;
+    int oldmmwidth, oldmmheight;
+    int newwidth, newheight;
+
+    if (wasEnabled)
+    	KdDisableScreen (pScreen);
+    oldscr = *omaps;
+
+    oldwidth = screen->width;
+    oldheight = screen->height;
+    oldmmwidth = pScreen->mmWidth;
+    oldmmheight = pScreen->mmHeight;
+
+    /*
+     * Set new configuration
+     */
+    omaps->randr = KdAddRotation (screen->randr, randr);
+
+    if (!omap_map_framebuffer(screen))
+    	goto bail4;
+
+    omap_set_screen_sizes (screen->pScreen);
+
+    /*
+     * Set frame buffer mapping
+     */
+    (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+				    pScreen->width,
+				    pScreen->height,
+				    screen->fb[0].depth,
+				    screen->fb[0].bitsPerPixel,
+				    screen->fb[0].byteStride,
+				    screen->fb[0].frameBuffer);
+
+    /* set the subpixel order */
+
+    KdSetSubpixelOrder (pScreen, omaps->randr);
+
+    if (!omap_plane_enable(omaps->plane))
+        FatalError("omap_randr_set_config: couldn't enable base plane\n");
+
+    if (wasEnabled)
+        KdEnableScreen (pScreen);
+
+    return TRUE;
+
+bail4:
+    *omaps = oldscr;
+    (void) omap_map_framebuffer (screen);
+    pScreen->width = oldwidth;
+    pScreen->height = oldheight;
+    pScreen->mmWidth = oldmmwidth;
+    pScreen->mmHeight = oldmmheight;
+    if (wasEnabled)
+    	KdEnableScreen (pScreen);
+    return FALSE;
+}
+
+Bool
+omap_randr_init(ScreenPtr pScreen)
+{
+    rrScrPrivPtr    pScrPriv;
+    if (!RRScreenInit (pScreen))
+	return FALSE;
+
+    pScrPriv = rrGetScrPriv(pScreen);
+    pScrPriv->rrGetInfo = omap_randr_get_info;
+    pScrPriv->rrSetConfig = omap_randr_set_config;
+
+    return TRUE;
+}
+#endif
+
 static Bool
 omap_create_resources(ScreenPtr screen)
 {
@@ -296,6 +476,10 @@
     KdScreenPriv(screen);
     struct omap_screen_info *omaps = pScreenPriv->screen->driver;
 
+#ifdef RANDR
+    omap_randr_init (screen);
+#endif
+
     if (omaps->shadowfb) {
         if (!shadowSetup(screen)) {
             ErrorF("omapFinishInitScreen: couldn't finish shadow init\n");
diff -rud xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.h ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.h
--- xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.h	2008-09-24 15:02:03.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap.h	2008-12-30 01:41:32.000000000 +0100
@@ -45,6 +45,12 @@
 
 #include "omapfb.h"
 
+#ifdef RANDR
+#include "randrstr.h"
+#include <linux/fb.h>
+#include "damage.h"
+#endif
+
 #define ENTER() DebugF("Enter %s\n", __FUNCTION__)
 #define LEAVE() DebugF("Leave %s\n", __FUNCTION__)
 
@@ -94,6 +100,8 @@
     int fd;
     CARD8 *fb;
     int fb_size;
+    struct fb_fix_screeninfo fix;
+    struct fb_var_screeninfo var;
     int pitch, bpp;
     int max_width, max_height;
     unsigned long colors;
@@ -172,6 +180,8 @@
     /* Are we using a shadow framebuffer? */
     int shadowfb;
 
+    Rotation randr;
+
     /* Use for tracking damage for window updates. */
     PixmapPtr pixmap;
     DamagePtr damage;
@@ -270,6 +280,18 @@
 
 void omap_paint_ckey(DrawablePtr drawable, RegionPtr region, Pixel fg);
 
+#ifdef RANDR
+
+Bool omap_randr_get_info(ScreenPtr pScreen, Rotation *rotations);
+
+Bool omap_randr_set_config(ScreenPtr		pScreen,
+	                   Rotation		randr,
+		           int  		rate,
+		           RRScreenSizePtr	pSize);
+
+Bool omap_randr_init(ScreenPtr pScreen);
+
+#endif
 
 extern KdCardFuncs omap_funcs;
 
diff -rud xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap_plane.c ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap_plane.c
--- xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap_plane.c	2008-09-24 15:02:03.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omap_plane.c	2008-12-30 02:16:18.000000000 +0100
@@ -270,8 +270,6 @@
 int
 omap_plane_enable(struct omap_plane_info *plane_info)
 {
-    struct fb_var_screeninfo var;
-    struct fb_fix_screeninfo fix;
     struct omapfb_color_key colorkey;
     struct omapfb_plane_info kplane_info;
     struct omapfb_mem_info mem_info;
@@ -298,41 +296,56 @@
         }
     }
 
-    if (ioctl(plane_info->fd, FBIOGET_VSCREENINFO, &var) != 0) {
+    if (ioctl(plane_info->fd, FBIOGET_VSCREENINFO, &plane_info->var) != 0) {
         ErrorF("omapPlaneEnable: couldn't get var info\n");
         return 0;
     }
 
-    var.xres = plane_info->src_area.width;
-    var.yres = plane_info->src_area.height;
-    var.xres_virtual = 0;
-    var.yres_virtual = 0;
-    var.xoffset = 0;
-    var.yoffset = 0;
-    var.rotate = 0;
-    var.grayscale = 0;
-    var.activate = FB_ACTIVATE_NOW;
+    plane_info->var.xres = plane_info->src_area.width;
+    plane_info->var.yres = plane_info->src_area.height;
+    plane_info->var.xres_virtual = 0;
+    plane_info->var.yres_virtual = 0;
+    plane_info->var.xoffset = 0;
+    plane_info->var.yoffset = 0;
+    plane_info->var.rotate = 0;
+    plane_info->var.grayscale = 0;
+    plane_info->var.activate = FB_ACTIVATE_NOW;
+
+    switch (plane_info->omaps->randr) {
+        case RR_Rotate_0:
+            plane_info->var.rotate = 0;
+            break;
+        case RR_Rotate_90:
+            plane_info->var.rotate = 90;
+            break;
+        case RR_Rotate_180:
+            plane_info->var.rotate = 180;
+            break;
+        case RR_Rotate_270:
+            plane_info->var.rotate = 270;
+            break;
+    }
 
     if (is_migrated) {
-        var.xres &= ~3;
-        var.height &= ~1;
+        plane_info->var.xres &= ~3;
+        plane_info->var.height &= ~1;
     }
 
     if (is_base || is_migrated) {
-        var.bits_per_pixel = bpp;
-        var.nonstd = plane_info->omaps->plane->format;
+        plane_info->var.bits_per_pixel = bpp;
+        plane_info->var.nonstd = plane_info->omaps->plane->format;
     }
     else {
-        var.bits_per_pixel = 0;
-        var.nonstd = plane_info->format;
+        plane_info->var.bits_per_pixel = 0;
+        plane_info->var.nonstd = plane_info->format;
     }
 
     /* Workaround weird processing of color formats in the kernel,
        see 'set_color_mode' function from 'omapfb_main.c' */
-    if (var.nonstd == OMAPFB_COLOR_RGB565)
-        var.bits_per_pixel = 16;
+    if (plane_info->var.nonstd == OMAPFB_COLOR_RGB565)
+        plane_info->var.bits_per_pixel = 16;
 
-    if (ioctl(plane_info->fd, FBIOPUT_VSCREENINFO, &var) != 0) {
+    if (ioctl(plane_info->fd, FBIOPUT_VSCREENINFO, &plane_info->var) != 0) {
         ErrorF("omapPlaneEnable: couldn't update var info\n");
         return 0;
     }
@@ -385,23 +398,23 @@
         }
     }
 
-    if (ioctl(plane_info->fd, FBIOGET_FSCREENINFO, &fix) != 0) {
+    if (ioctl(plane_info->fd, FBIOGET_FSCREENINFO, &plane_info->fix) != 0) {
         ErrorF("omapPlaneEnable: couldn't get fix info\n");
         goto bail;
     }
-    plane_info->fb = mmap(NULL, fix.smem_len, PROT_READ | PROT_WRITE,
+    plane_info->fb = mmap(NULL, plane_info->fix.smem_len, PROT_READ | PROT_WRITE,
                           MAP_SHARED, plane_info->fd, 0L);
     if (!plane_info->fb) {
         ErrorF("omapPlaneEnable: mmaping overlay failed\n");
         goto bail;
     }
-    plane_info->fb += fix.smem_start % getpagesize();
-    plane_info->fb_size = fix.smem_len;
-    plane_info->pitch = fix.line_length;
-    plane_info->fb_size = fix.smem_len;
+    plane_info->fb += plane_info->fix.smem_start % getpagesize();
+    plane_info->fb_size = plane_info->fix.smem_len;
+    plane_info->pitch = plane_info->fix.line_length;
+    plane_info->fb_size = plane_info->fix.smem_len;
 
     DebugF("omapPlaneEnable: enabled plane %d\n", plane_info->id);
-    DebugF("    (%d, %d) to (%d, %d) at (%d, %d)\n", var.xres, var.yres,
+    DebugF("    (%d, %d) to (%d, %d) at (%d, %d)\n", plane_info->var.xres, plane_info->var.yres,
            kplane_info.out_width, kplane_info.out_height,
            kplane_info.pos_x, kplane_info.pos_y);
 
diff -rud xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omapfb.h ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omapfb.h
--- xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omapfb.h	2008-09-24 15:01:53.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/hw/kdrive/omap/omapfb.h	2008-12-30 01:41:32.000000000 +0100
@@ -62,6 +62,7 @@
 #define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE	0x00010000
 #define OMAPFB_CAPS_WINDOW_SCALE	0x00020000
 #define OMAPFB_CAPS_WINDOW_OVERLAY	0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE	0x00080000
 #define OMAPFB_CAPS_SET_BACKLIGHT	0x01000000
 
 /* Values from DSP must map to lower 16-bits */
diff -rud xorg-server-1.3.99.0~git20070321/hw/kdrive/src/kinput.c ../xorg-server-1.3.99.0~git20070321/hw/kdrive/src/kinput.c
--- xorg-server-1.3.99.0~git20070321/hw/kdrive/src/kinput.c	2008-09-24 15:01:53.000000000 +0200
+++ ../xorg-server-1.3.99.0~git20070321/hw/kdrive/src/kinput.c	2008-12-30 01:41:32.000000000 +0100
@@ -654,6 +654,7 @@
 	    if (m->matrix[i][j] < 0)
 		m->matrix[i][2] = size[j] - 1;
     }
+    
 }
 
 static void
@@ -2009,20 +2010,24 @@
     ms = GetTimeInMillis();
 
     /* we don't need to transform z, so we don't. */
-    if (pi->transformCoordinates) {
-        x = matrix[0][0] * rx + matrix[0][1] * ry;
-        y = matrix[1][0] * rx + matrix[1][1] * ry;
-    }
-    else {
-        x = rx;
-        y = ry;
-    }
+    x = rx;
+    y = ry;
     z = rz;
 
-    if (flags & KD_MOUSE_DELTA)
+    if (flags & KD_MOUSE_DELTA) {
         dixflags = POINTER_RELATIVE | POINTER_ACCELERATE;
-    else
+        if (pi->transformCoordinates) {
+            x = matrix[0][0] * rx + matrix[0][1] * ry;
+            y = matrix[1][0] * rx + matrix[1][1] * ry;
+        }
+    }
+    else {
         dixflags = POINTER_ABSOLUTE;
+        if (pi->transformCoordinates) {
+            x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
+            y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
+        }
+    }
 
     _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE);
 
