[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