[Intel-gfx] [RFC] VGA hotplug support for i915 kms

Jesse Barnes jbarnes at virtuousgeek.org
Fri Jan 16 02:01:33 CET 2009


On Thursday, January 15, 2009 4:55 pm Keith Packard wrote:
> On Thu, 2009-01-15 at 14:18 -0800, Jesse Barnes wrote:
> > Here's a slightly less revolting version.  I removed all the global
> > variables, and moved to using the system wide work queue rather than an
> > i915 specific one, so things are much cleaner & clearer.
>
> This looks good to me. I can hook up the uevent bits up in the X server
> and see how far that takes us.

Cool, that should be fun.  Here's a WIP KMS buffer resize patch too.  It's
still untested and should share more code with the UXA bits you just added...

And then there's rotation to fix/validate...

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4994251..b06b6a7 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -185,7 +185,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	fb_id = drmmode->fb_id;
 	if (drmmode_crtc->rotate_fb_id)
 		fb_id = drmmode_crtc->rotate_fb_id;
-	ErrorF("fb id is %d\n", fb_id);
+
 	ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 			     fb_id, x, y, output_ids, output_count, &kmode);
 	if (ret)
@@ -323,7 +323,8 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 }
 
 static void
-drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap,
+			    void *data)
 {
 	if (rotate_pixmap)
 		FreeScratchPixmapHeader(rotate_pixmap);
@@ -353,13 +354,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 	.shadow_create = drmmode_crtc_shadow_create,
 	.shadow_allocate = drmmode_crtc_shadow_allocate,
 	.shadow_destroy = drmmode_crtc_shadow_destroy,
-#if 0
-	.gamma_set = i830_crtc_gamma_set,
-	.shadow_create = i830_crtc_shadow_create,
-	.shadow_allocate = i830_crtc_shadow_allocate,
-	.shadow_destroy = i830_crtc_shadow_destroy,
-	.set_cursor_colors = i830_crtc_set_cursor_colors,
-#endif
+
 	.destroy = NULL, /* XXX */
 };
 
@@ -474,26 +469,50 @@ drmmode_output_destroy(xf86OutputPtr output)
 	output->driver_private = NULL;
 }
 
+static drmModePropertyPtr
+drmmode_output_find_dpms_prop(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	drmModePropertyPtr prop;
+	int i;
+
+	/* Find the DPMS property on this output */
+	for (i = 0; i < koutput->count_props; i++) {
+		prop = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (!prop)
+			continue;
+
+		if (!strcmp(prop->name, "DPMS"))
+			return prop;
+		drmModeFreeProperty(prop);
+	}
+
+	return NULL;
+}
+
 static void
 drmmode_output_dpms(xf86OutputPtr output, int mode)
 {
-	return;
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	drmModePropertyPtr prop;
+
+	prop = drmmode_output_find_dpms_prop(output);
+	if (!prop)
+		return;
+
+	drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
+				    prop->prop_id, mode);
+	drmModeFreeProperty(prop);
 }
 
 static const xf86OutputFuncsRec drmmode_output_funcs = {
 	.dpms = drmmode_output_dpms,
-#if 0
-
-	.save = drmmode_crt_save,
-	.restore = drmmode_crt_restore,
-	.mode_fixup = drmmode_crt_mode_fixup,
-	.prepare = drmmode_output_prepare,
-	.mode_set = drmmode_crt_mode_set,
-	.commit = drmmode_output_commit,
-#endif
 	.detect = drmmode_output_detect,
 	.mode_valid = drmmode_output_mode_valid,
-
 	.get_modes = drmmode_output_get_modes,
 	.destroy = drmmode_output_destroy
 };
@@ -544,7 +563,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 	snprintf(name, 32, "%s%d", output_names[koutput->connector_type],
 		 koutput->connector_type_id);
 
-	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+	output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name);
 	if (!output) {
 		drmModeFreeEncoder(kencoder);
 		drmModeFreeConnector(koutput);
@@ -609,19 +628,10 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId,
 	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
 		drmmode_output_init(pScrn, drmmode, i);
 
-	xf86InitialConfiguration(pScrn, FALSE);
-
-	return TRUE;
-}
+	xf86InitialConfiguration(pScrn, TRUE);
 
-#if 0
-Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
-			dri_bufmgr *bufmgr)
-{
-	drmmode->bufmgr = bufmgr;
 	return TRUE;
 }
-#endif
 
 void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 		    int height, int pitch, dri_bo *bo)
@@ -632,23 +642,17 @@ void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 			   scrn->bitsPerPixel, pitch, bo->handle,
 			   &drmmode->fb_id);
 
-	if (ret) {
-		ErrorF("Failed to add fb: %s\n", strerror(-ret));
-	}
+	if (ret)
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to add fb: %s\n", strerror(-ret));
 
 	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
 	if (!drmmode->mode_fb)
 		return;
-
-
-	ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
 }
 
 Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
 {
-	return FALSE;
-
-#if 0
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
 	int i;
 
@@ -665,7 +669,6 @@ Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
 		}
 	}
 	return FALSE;
-#endif
 }
 
 static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
@@ -675,8 +678,6 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 	int pitch;
 	int ret;
 
-	return FALSE;
-
 	if (drmmode->mode_fb->width == width &&
 	    drmmode->mode_fb->height == height)
 		return TRUE;
@@ -688,11 +689,8 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 	if (handle == 0)
 		return FALSE;
 
-	ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
-			       width, height,
-			       scrn->depth, scrn->bitsPerPixel, pitch,
-			       handle);
-
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch, handle, &drmmode->fb_id);
 	if (ret)
 		return FALSE;
 
@@ -704,5 +702,5 @@ static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
 	return TRUE;
 }
 
-#endif
+#endif /* XF86DRM_MODE */
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index ee51c95..e72bd4b 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -43,7 +43,6 @@ typedef struct {
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
-
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     dri_bo *cursor;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3e27b07..ae9fd54 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1228,7 +1228,6 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
  * DRM mode setting Linux only at this point... later on we could
  * add a wrapper here.
  */
-#include <linux/kd.h>
 
 static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn)
 {
@@ -1254,8 +1253,6 @@ static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn)
     if (ret)
 	return FALSE;
 
-    ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);
-
     return TRUE;
 }
 #else
@@ -3614,7 +3611,6 @@ I830LeaveVT(int scrnIndex, int flags)
 	*/
        if (!pI830->memory_manager)
 	   intel_bufmgr_fake_evict_all(pI830->bufmgr);
-       intel_batch_teardown(pScrn);
 
        if (!pI830->memory_manager)
 	   i830_stop_ring(pScrn, TRUE);
@@ -3625,6 +3621,8 @@ I830LeaveVT(int scrnIndex, int flags)
        }
    }
 
+   intel_batch_teardown(pScrn);
+
    if (I830IsPrimary(pScrn))
       i830_unbind_all_memory(pScrn);
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index b6d8026..ceb92f9 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -107,6 +107,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "xf86_OSproc.h"
 
 #include "i830.h"
+#include "i830_display.h"
 #include "i810_reg.h"
 #ifdef XF86DRI
 #include "i915_drm.h"
@@ -2122,5 +2123,44 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
 uint32_t
 i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
 {
-    return 0;
+    I830Ptr pI830 = I830PTR(pScrn);
+    i830_memory *new_front, *old_front;
+    int		old_x = pScrn->virtualX;
+    int		old_y = pScrn->virtualY;
+    int		old_width = pScrn->displayWidth;
+    BoxRec      mem_box;
+    Bool        tiled;
+    ScreenPtr   screen = screenInfo.screens[pScrn->scrnIndex];
+
+    pScrn->displayWidth = i830_pad_drawable_width(width, pI830->cpp);
+    tiled = i830_tiled_width(pI830, &pScrn->displayWidth, pI830->cpp);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Allocate new frame buffer %dx%d stride %d\n",
+	       width, height, pScrn->displayWidth);
+    I830Sync(pScrn);
+    i830WaitForVblank(pScrn);
+    new_front = i830_allocate_framebuffer(pScrn, pI830, &mem_box, FALSE);
+    if (!new_front) {
+	pScrn->virtualX = old_x;
+	pScrn->virtualY = old_y;
+	pScrn->displayWidth = old_width;
+	return FALSE;
+    }
+    old_front = pI830->front_buffer;
+    pI830->front_buffer = new_front;
+    i830_set_pixmap_bo(screen->GetScreenPixmap(screen),
+		       new_front->bo);
+    pScrn->fbOffset = pI830->front_buffer->offset;
+    screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+			       width, height, -1, -1,
+			       pScrn->displayWidth * pI830->cpp,
+			       NULL);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
+	       pI830->front_buffer->offset);
+    i830_set_new_crtc_bo(pScrn);
+    I830Sync(pScrn);
+    i830WaitForVblank(pScrn);
+    i830_free_memory(pScrn, old_front);
+
+    return new_front->bo->handle;
 }



More information about the Intel-gfx mailing list