summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2012-07-24 18:48:56 +0300
committerAlon Levy <alevy@redhat.com>2012-10-23 18:46:58 +0200
commit0dbb62d61ba8a3bd03da83ac8155e53242128e52 (patch)
tree91ed781a03e1b9cea3b04b82c2cbabae7d0ea789
parentf9a35e911bc770f905a126601333c7bd4632a94c (diff)
qxl(kms): fails on primary surface creation alloc because of kernel. ums no regression
-rw-r--r--src/qxl.h2
-rw-r--r--src/qxl_driver.c309
-rw-r--r--src/qxl_surface.c2
3 files changed, 197 insertions, 116 deletions
diff --git a/src/qxl.h b/src/qxl.h
index f25ad4f..cd555e5 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -181,6 +181,8 @@ struct _qxl_screen_t
long vram_size;
long ram_size;
+ int n_surfaces;
+
DisplayModePtr x_modes;
int virtual_x;
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index ee9f736..9aac8f3 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -293,6 +293,9 @@ qxl_kms_create_primary_surface(qxl_screen_t *qxl, QXLMode *mode)
uint32_t handle = qxl_kms_alloc_resource(qxl, size,
QXL_ALLOC_TYPE_SURFACE_PRIMARY);
+ if (handle == 0) {
+ return NULL;
+ }
// NB: we may be repeatedly mapping here. should be cached.
qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED;
qxl->primary_handle = handle;
@@ -784,7 +787,7 @@ qxl_dump_ring_stat (qxl_screen_t *qxl)
* This is done via already known code, so use that by default now.
*/
static int
-qxl_resize_surface0 (qxl_screen_t *qxl, long surface0_size)
+qxl_ums_resize_surface0 (qxl_screen_t *qxl, long surface0_size)
{
long ram_header_size = qxl->ram_size - qxl->rom->ram_header_offset;
long new_mem_size = qxl->ram_size -
@@ -858,11 +861,14 @@ qxl_map_memory (qxl_screen_t *qxl, int scrnIndex)
qxl->surface0_area = qxl->ram;
qxl->surface0_size = 0;
qxl->mem = NULL;
- if (!qxl_resize_surface0 (qxl, qxl->rom->surface0_area_size))
- return FALSE;
- qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size);
+ if (!is_kms (qxl)) {
+ if (!qxl_ums_resize_surface0 (qxl, qxl->rom->surface0_area_size))
+ return FALSE;
+ qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram),
+ qxl->vram_size);
+ }
qxl_allocate_monitors_config (qxl);
-
+
return TRUE;
}
@@ -882,7 +888,10 @@ static void
qxl_save_state (ScrnInfoPtr pScrn)
{
qxl_screen_t *qxl = pScrn->driverPrivate;
-
+
+ if (is_kms (qxl)) {
+ return;
+ }
if (xf86IsPrimaryPci (qxl->pci))
vgaHWSaveFonts (pScrn, &qxl->vgaRegs);
}
@@ -891,9 +900,12 @@ static void
qxl_restore_state (ScrnInfoPtr pScrn)
{
qxl_screen_t *qxl = pScrn->driverPrivate;
-
+
+ if (is_kms(qxl)) {
+ return;
+ }
if (xf86IsPrimaryPci (qxl->pci))
- vgaHWRestoreFonts (pScrn, &qxl->vgaRegs);
+ vgaHWRestoreFonts (pScrn, &qxl->vgaRegs);
}
#endif /* XSPICE */
@@ -1029,12 +1041,15 @@ qxl_close_screen (CLOSE_SCREEN_ARGS_DECL)
if (!xf86IsPrimaryPci(qxl->pci) && qxl->primary)
qxl->reset_and_create_mem_slots(qxl);
#endif
-
- if (pScrn->vtSema)
- {
- qxl_restore_state (pScrn);
- qxl_mark_mem_unverifiable (qxl);
- qxl_unmap_memory (qxl);
+
+ if (pScrn->vtSema) {
+ qxl_restore_state (pScrn);
+ if (is_kms (qxl)) {
+ // TODO: relinquish drm master, close device.
+ } else {
+ qxl_mark_mem_unverifiable (qxl);
+ qxl_unmap_memory (qxl);
+ }
}
pScrn->vtSema = FALSE;
@@ -1069,30 +1084,38 @@ set_screen_pixmap_header (ScreenPtr pScreen)
}
static Bool
-qxl_resize_primary_to_virtual (qxl_screen_t *qxl)
+qxl_kms_resize_primary_to_virtual (qxl_screen_t *qxl)
+{
+ struct QXLMode *pm = &qxl->primary_mode;
+
+ ErrorF("unimplemented kms resize to %dx%d\n",
+ qxl->virtual_x, qxl->virtual_y);
+ pm->id = 0x435;
+ pm->x_res = qxl->virtual_x;
+ pm->y_res = qxl->virtual_y;
+ pm->bits = qxl->pScrn->bitsPerPixel;
+ pm->stride = qxl->virtual_x * pm->bits / 8;
+ pm->x_mili = 0; // TODO
+ pm->y_mili = 0; // TODO
+ pm->orientation = 0; // ? supported by us for single head usage? more TODO
+ return TRUE;
+}
+
+static Bool
+qxl_ums_resize_primary_to_virtual (qxl_screen_t *qxl)
{
- ScreenPtr pScreen;
long new_surface0_size;
-
- if ((qxl->primary_mode.x_res == qxl->virtual_x &&
- qxl->primary_mode.y_res == qxl->virtual_y) &&
- qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED)
- {
- return TRUE; /* empty Success */
- }
-
- ErrorF ("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y);
-
+
new_surface0_size =
qxl->virtual_x * qxl->pScrn->bitsPerPixel / 8 * qxl->virtual_y;
-
+
if (new_surface0_size > qxl->surface0_size)
{
- if (!qxl_resize_surface0 (qxl, new_surface0_size))
+ if (is_kms(qxl) || !qxl_ums_resize_surface0(qxl, new_surface0_size))
{
- ErrorF ("not resizing primary to virtual, leaving old virtual\n");
- return FALSE;
- }
+ ErrorF ("not resizing primary to virtual, leaving old virtual\n");
+ return FALSE;
+ }
}
if (qxl->primary)
@@ -1113,7 +1136,34 @@ qxl_resize_primary_to_virtual (qxl_screen_t *qxl)
pm->y_mili = 0; // TODO
pm->orientation = 0; // ? supported by us for single head usage? more TODO
}
- qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache, &qxl->primary_mode);
+ return TRUE;
+}
+
+static Bool
+qxl_resize_primary_to_virtual(qxl_screen_t *qxl)
+{
+ ScreenPtr pScreen;
+ Bool ret;
+
+ if ((qxl->primary_mode.x_res == qxl->virtual_x &&
+ qxl->primary_mode.y_res == qxl->virtual_y) &&
+ qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED) {
+ return TRUE; /* empty Success */
+ }
+
+ ErrorF("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y);
+
+ if (is_kms(qxl)) {
+ ret = qxl_kms_resize_primary_to_virtual(qxl);
+ } else {
+ ret = qxl_ums_resize_primary_to_virtual(qxl);
+ }
+ if (!ret)
+ return ret;
+ qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache,
+ &qxl->primary_mode);
+ if (!qxl->primary)
+ return FALSE;
qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8;
pScreen = qxl->pScrn->pScreen;
@@ -1868,40 +1918,86 @@ qxl_fb_init (qxl_screen_t *qxl, ScreenPtr pScreen)
return TRUE;
}
+#ifdef XSPICE
+static Bool
+open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
+{
+ return FALSE;
+}
+#else // not Xspice
+static Bool
+open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
+{
+ char *BusID;
+
+ if (qxl->drm_fd >= 0) {
+ return TRUE;
+ }
+ BusID = malloc(64);
+ sprintf(BusID, "PCI:%d:%d:%d",
+#if XSERVER_LIBPCIACCESS
+ ((qxl->pci->domain << 8) | qxl->pci->bus),
+ qxl->pci->dev, qxl->pci->func
+#else
+ ((pciConfigPtr) qxl->pci->thisCard)->busnum,
+ ((pciConfigPtr) qxl->pci->thisCard)->devnum,
+ ((pciConfigPtr) qxl->pci->thisCard)->funcnum
+#endif
+ );
+
+ qxl->drm_fd = drmOpen(NULL, BusID);
+ free(BusID);
+ if (qxl->drm_fd < 0)
+ return FALSE;
+ return TRUE;
+}
+#endif
+
static Bool
qxl_screen_init (SCREEN_INIT_ARGS_DECL)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen);
qxl_screen_t * qxl = pScrn->driverPrivate;
struct QXLRam *ram_header;
- VisualPtr visual;
-
+ VisualPtr visual;
+
CHECK_POINT ();
-
+
assert (qxl->pScrn == pScrn);
-
- if (!qxl_map_memory (qxl, pScrn->scrnIndex))
- return FALSE;
-
+
+ if (!open_drm (qxl, pScrn)) {
+ if (!qxl_map_memory (qxl, pScrn->scrnIndex))
+ return FALSE;
+ } else {
+ ErrorF("KMS HACK: setting screen to 640x480");
+ pScrn->currentMode->HDisplay = 640;
+ pScrn->currentMode->VDisplay = 480;
+ pScrn->virtualY = 480;
+ pScrn->displayWidth = 640;
+ }
+
#ifdef XSPICE
spiceqxl_screen_init (pScrn, qxl);
#endif
- ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
-
- printf ("ram_header at %d\n", qxl->rom->ram_header_offset);
- printf ("surf0 size: %d\n", qxl->rom->surface0_area_size);
-
+ if (!is_kms(qxl)) {
+ ram_header = (void *)((unsigned long)qxl->ram +
+ (unsigned long)qxl->rom->ram_header_offset);
+
+ printf ("ram_header at %d\n", qxl->rom->ram_header_offset);
+ printf ("surf0 size: %d\n", qxl->rom->surface0_area_size);
+ }
+
qxl_save_state (pScrn);
qxl_blank_screen (pScreen, SCREEN_SAVER_ON);
-
+
miClearVisualTypes ();
- if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask (pScrn->depth),
+ if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
- goto out;
+ goto out;
if (!miSetPixmapDepths ())
- goto out;
+ goto out;
pScrn->displayWidth = pScrn->virtualX;
-
+
qxl->fb = calloc (pScrn->virtualY * pScrn->displayWidth, 4);
if (!qxl->fb)
goto out;
@@ -1936,25 +2032,25 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
qxl->reset_and_create_mem_slots(qxl);
ErrorF("done reset\n");
+ if (!is_kms(qxl)) {
#ifndef XSPICE
- qxl->io_pages = (void *)((unsigned long)qxl->ram);
- qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
-#endif
-
- qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring),
- sizeof (struct QXLCommand),
- QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl);
- qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring),
- sizeof (struct QXLCommand),
- QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl);
- qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring),
- sizeof (uint64_t),
- QXL_RELEASE_RING_SIZE, 0, qxl);
-
+ qxl->io_pages = (void *)((unsigned long)qxl->ram);
+ qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
+#endif
+ qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring),
+ sizeof (struct QXLCommand),
+ QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl);
+ qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring),
+ sizeof (struct QXLCommand),
+ QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl);
+ qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring),
+ sizeof (uint64_t),
+ QXL_RELEASE_RING_SIZE, 0, qxl);
+ }
qxl->surface_cache = qxl_surface_cache_create (qxl);
-
- /* xf86DPMSInit (pScreen, xf86DPMSSet, 0); */
-
+
+ /* xf86DPMSInit(pScreen, xf86DPMSSet, 0); */
+
pScreen->SaveScreen = qxl_blank_screen;
setup_uxa (qxl, pScreen);
@@ -2030,19 +2126,21 @@ qxl_enter_vt (VT_FUNC_ARGS_DECL)
if (!qxl_resize_primary_to_virtual(qxl))
return FALSE;
- if (qxl->mem) {
- qxl_mem_free_all(qxl->mem);
- qxl_drop_image_cache(qxl);
+ if (is_kms(qxl)) {
+ xf86DrvMsg(qxl->pScrn->scrnIndex, X_INFO,
+ "KMS qxl_enter_vt (empty)\n");
+ } else {
+ if (qxl->mem) {
+ qxl_mem_free_all (qxl->mem);
+ qxl_drop_image_cache (qxl);
+ }
+ if (qxl->surf_mem)
+ qxl_mem_free_all (qxl->surf_mem);
}
-
- if (qxl->surf_mem)
- qxl_mem_free_all (qxl->surf_mem);
-
- if (qxl->vt_surfaces)
- {
- qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);
-
- qxl->vt_surfaces = NULL;
+ if (qxl->vt_surfaces) {
+ qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);
+
+ qxl->vt_surfaces = NULL;
}
qxl_create_desired_modes (qxl);
@@ -2118,33 +2216,6 @@ print_modes (qxl_screen_t *qxl, int scrnIndex)
#ifndef XSPICE
static Bool
-open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
-{
- char *BusID;
-
- if (qxl->drm_fd >= 0) {
- return TRUE;
- }
- BusID = malloc(64);
- sprintf(BusID, "PCI:%d:%d:%d",
-#if XSERVER_LIBPCIACCESS
- ((qxl->pci->domain << 8) | qxl->pci->bus),
- qxl->pci->dev, qxl->pci->func
-#else
- ((pciConfigPtr) qxl->pci->thisCard)->busnum,
- ((pciConfigPtr) qxl->pci->thisCard)->devnum,
- ((pciConfigPtr) qxl->pci->thisCard)->funcnum
-#endif
- );
-
- qxl->drm_fd = drmOpen(NULL, BusID);
- free(BusID);
- if (qxl->drm_fd < 0)
- return FALSE;
- return TRUE;
-}
-
-static Bool
qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
{
int scrnIndex = pScrn->scrnIndex;
@@ -2807,13 +2878,12 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags)
xf86DrvMsg (scrnIndex, X_INFO, "Fallback Cache: %s\n",
qxl->enable_fallback_cache? "Enabled" : "Disabled");
- if (!qxl_map_memory (qxl, scrnIndex))
- goto out;
-
qxl->drm_fd = -1;
#ifndef XSPICE
open_drm(qxl, pScrn);
if (!is_kms(qxl)) {
+ if (!qxl_map_memory(qxl, scrnIndex))
+ goto out;
if (!qxl_check_device(pScrn, qxl))
goto out;
set_callbacks_to_ums(qxl);
@@ -2824,10 +2894,18 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags)
set_callbacks_to_ums(qxl);
xspice_init_qxl_ram(qxl); /* initialize the rings */
#endif
- pScrn->videoRam = (qxl->rom->num_pages * 4096) / 1024;
- xf86DrvMsg (scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam);
- xf86DrvMsg (scrnIndex, X_INFO, "%d surfaces\n", qxl->rom->n_surfaces);
-
+
+ if (is_kms(qxl)) {
+ xf86DrvMsg(scrnIndex, X_ERROR, "kms guessing videoRam & n_surfaces\n");
+ pScrn->videoRam = 1024; // TODO?? who uses this anyway?
+ qxl->n_surfaces = 1024; // TODO - read from kernel (or let kernel virtualize this?)
+ } else {
+ pScrn->videoRam = (qxl->rom->num_pages * 4096) / 1024;
+ qxl->n_surfaces = qxl->rom->n_surfaces;
+ }
+ xf86DrvMsg(scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam);
+ xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", qxl->n_surfaces);
+
/* ddc stuff here */
clockRanges = xnfcalloc (sizeof (ClockRange), 1);
@@ -2919,10 +2997,11 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags)
#endif
/* hate */
- qxl_unmap_memory (qxl);
-
+ if (!is_kms(qxl))
+ qxl_unmap_memory (qxl);
+
CHECK_POINT ();
-
+
xf86DrvMsg (scrnIndex, X_INFO, "PreInit complete\n");
#ifdef GIT_VERSION
xf86DrvMsg (scrnIndex, X_INFO, "git commit %s\n", GIT_VERSION);
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 00d8b05..13f193b 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -182,7 +182,7 @@ static void debug_surface_log(surface_cache_t *cache)
static Bool
surface_cache_init (surface_cache_t *cache, qxl_screen_t *qxl)
{
- int n_surfaces = qxl->rom->n_surfaces;
+ int n_surfaces = qxl->n_surfaces;
int i;
if (!cache->all_surfaces)