summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drmmode_display.c40
-rw-r--r--src/nouveau_dri2.c3
-rw-r--r--src/nv_driver.c53
3 files changed, 74 insertions, 22 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 6033a6d..8fd1dd0 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1129,14 +1129,17 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
ScreenPtr screen = xf86ScrnToScreen(scrn);
NVPtr pNv = NVPTR(scrn);
- drmmode_crtc_private_ptr
- drmmode_crtc = xf86_config->crtc[0]->driver_private;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
- uint32_t old_width, old_height, old_pitch, old_fb_id;
+ drmmode_crtc_private_ptr drmmode_crtc = NULL;
+ drmmode_ptr drmmode = NULL;
+ uint32_t old_width, old_height, old_pitch, old_fb_id = 0;
struct nouveau_bo *old_bo = NULL;
int ret, i, pitch;
PixmapPtr ppix;
+ if (xf86_config->num_crtc) {
+ drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ drmmode = drmmode_crtc->drmmode;
+ }
ErrorF("resize called %d %d\n", width, height);
if (scrn->virtualX == width && scrn->virtualY == height)
@@ -1145,7 +1148,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
old_width = scrn->virtualX;
old_height = scrn->virtualY;
old_pitch = scrn->displayWidth;
- old_fb_id = drmmode->fb_id;
+ if (drmmode)
+ old_fb_id = drmmode->fb_id;
nouveau_bo_ref(pNv->scanout, &old_bo);
nouveau_bo_ref(NULL, &pNv->scanout);
@@ -1162,11 +1166,13 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client);
- ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
- scrn->bitsPerPixel, pitch, pNv->scanout->handle,
- &drmmode->fb_id);
- if (ret)
- goto fail;
+ if (drmmode) {
+ ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+ scrn->bitsPerPixel, pitch, pNv->scanout->handle,
+ &drmmode->fb_id);
+ if (ret)
+ goto fail;
+ }
if (pNv->ShadowPtr) {
free(pNv->ShadowPtr);
@@ -1214,7 +1220,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
scrn->virtualX = old_width;
scrn->virtualY = old_height;
scrn->displayWidth = old_pitch;
- drmmode->fb_id = old_fb_id;
+ if (drmmode)
+ drmmode->fb_id = old_fb_id;
return FALSE;
}
@@ -1241,6 +1248,14 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
drmmode->mode_res->max_height);
+
+ if (!drmmode->mode_res->count_connectors ||
+ !drmmode->mode_res->count_crtcs) {
+ drmModeFreeResources(drmmode->mode_res);
+ xfree(drmmode);
+ goto done;
+ }
+
for (i = 0; i < drmmode->mode_res->count_crtcs; i++) {
if (!xf86IsEntityShared(pScrn->entityList[0]) ||
(pScrn->confScreen->device->screen == i))
@@ -1250,6 +1265,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
+done:
#ifdef NOUVEAU_PIXMAP_SHARING
xf86ProviderSetup(pScrn, NULL, "nouveau");
#endif
@@ -1280,7 +1296,7 @@ drmmode_remove_fb(ScrnInfoPtr pScrn)
drmmode_crtc_private_ptr drmmode_crtc;
drmmode_ptr drmmode;
- if (config)
+ if (config && config->num_crtc)
crtc = config->crtc[0];
if (!crtc)
return;
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index e462a86..5511b36 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -266,6 +266,9 @@ can_exchange(DrawablePtr draw, PixmapPtr dst_pix, PixmapPtr src_pix)
NVPtr pNv = NVPTR(scrn);
int i;
+ if (!xf86_config->num_crtc)
+ return FALSE;
+
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
if (crtc->enabled && crtc->rotatedData)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 8a112db..38eddac 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -426,7 +426,7 @@ NVEnterVT(VT_FUNC_ARGS_DECL)
if (ret)
ErrorF("Unable to get master: %s\n", strerror(errno));
- if (!xf86SetDesiredModes(pScrn))
+ if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc && !xf86SetDesiredModes(pScrn))
return FALSE;
if (pNv->overlayAdaptor && pNv->Architecture != NV_ARCH_04)
@@ -559,7 +559,8 @@ NVCloseScreen(CLOSE_SCREEN_ARGS_DECL)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
NVPtr pNv = NVPTR(pScrn);
- drmmode_screen_fini(pScreen);
+ if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc)
+ drmmode_screen_fini(pScreen);
if (!pNv->NoAccel)
nouveau_dri2_fini(pScreen);
@@ -687,6 +688,7 @@ nouveau_setup_capabilities(ScrnInfoPtr pScrn)
{
#ifdef NOUVEAU_PIXMAP_SHARING
NVPtr pNv = NVPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
uint64_t value;
int ret;
@@ -695,8 +697,11 @@ nouveau_setup_capabilities(ScrnInfoPtr pScrn)
if (ret == 0) {
if (value & DRM_PRIME_CAP_EXPORT)
pScrn->capabilities |= RR_Capability_SourceOutput;
- if (value & DRM_PRIME_CAP_IMPORT)
- pScrn->capabilities |= RR_Capability_SourceOffload | RR_Capability_SinkOutput;
+ if (value & DRM_PRIME_CAP_IMPORT) {
+ pScrn->capabilities |= RR_Capability_SourceOffload;
+ if (xf86_config->num_crtc)
+ pScrn->capabilities |= RR_Capability_SinkOutput;
+ }
}
#endif
}
@@ -862,8 +867,6 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
NVPreInitFail("\n");
dev = pNv->dev;
- nouveau_setup_capabilities(pScrn);
-
pScrn->chipset = malloc(sizeof(char) * 25);
sprintf(pScrn->chipset, "NVIDIA NV%02x", dev->chipset);
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset: \"%s\"\n", pScrn->chipset);
@@ -1102,9 +1105,35 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86SetGamma(pScrn, gammazeros))
NVPreInitFail("\n");
- /* No usable mode */
+#ifdef NOUVEAU_PIXMAP_SHARING
+ /*
+ * The driver will not work as gpu screen without acceleration enabled.
+ * To support this usecase modesetting ddx can be used instead.
+ */
+ if (pNv->NoAccel || pNv->ShadowFB) {
+ /*
+ * Optimus mode requires acceleration enabled.
+ * So if no mode is found, or the screen is created
+ * as a gpu screen the pre init should fail.
+ */
+ if (pScrn->is_gpu || !pScrn->modes)
+ return FALSE;
+ }
+
+#else
+ /* No usable mode, no optimus config possible */
if (!pScrn->modes)
return FALSE;
+#endif
+
+ nouveau_setup_capabilities(pScrn);
+
+ if (!pScrn->modes) {
+ pScrn->modes = xf86ModesAdd(pScrn->modes,
+ xf86CVTMode(pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ 60, 0, 0));
+ }
/* Set the current mode to the first in the list */
pScrn->currentMode = pScrn->modes;
@@ -1389,7 +1418,7 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
* Initialize HW cursor layer.
* Must follow software cursor initialization.
*/
- if (pNv->HWCursor) {
+ if (xf86_config->num_crtc && pNv->HWCursor) {
ret = drmmode_cursor_init(pScreen);
if (ret != TRUE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1444,7 +1473,8 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
* Initialize colormap layer.
* Must follow initialization of the default colormap
*/
- if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
+ if (xf86_config->num_crtc &&
+ !xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
NULL, CMAP_PALETTED_TRUECOLOR))
return FALSE;
@@ -1452,7 +1482,10 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- drmmode_screen_init(pScreen);
+ if (xf86_config->num_crtc)
+ drmmode_screen_init(pScreen);
+ else
+ pNv->glx_vblank = FALSE;
return TRUE;
}