summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@infradead.org>2013-05-19 17:18:39 -0400
committerJames Simmons <jsimmons@infradead.org>2013-05-19 17:18:39 -0400
commitcee0a1fab9cade87e6de16c67cd34c84cf697531 (patch)
treee8e63634e33f746d7aa6e307d2ae8c53026b675f
parent42d7ac70e3e9735619690a86482954827936d169 (diff)
Fix the problems with UMS multiple screen handling. KMS still has problems
-rw-r--r--src/via_display.c19
-rw-r--r--src/via_driver.c77
-rw-r--r--src/via_ums.h4
3 files changed, 61 insertions, 39 deletions
diff --git a/src/via_display.c b/src/via_display.c
index 82cd8b2..d9b6db5 100644
--- a/src/via_display.c
+++ b/src/via_display.c
@@ -470,8 +470,11 @@ ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
void
-ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
+ViaFirstCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y)
{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ ScrnInfoPtr pScrn = crtc->scrn;
VIAPtr pVia = VIAPTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
CARD32 Base;
@@ -479,7 +482,7 @@ ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetStartingAddress\n"));
Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
- Base = (Base + pVia->drmmode.front_bo->offset) >> 1;
+ Base = (Base + drmmode->front_bo->offset) >> 1;
hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
@@ -491,14 +494,16 @@ ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
}
void
-ViaSecondCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
+ViaSecondCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y)
{
- VIAPtr pVia = VIAPTR(pScrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ ScrnInfoPtr pScrn = crtc->scrn;
vgaHWPtr hwp = VGAHWPTR(pScrn);
CARD32 Base, tmp;
Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
- Base = (Base + pVia->drmmode.front_bo->offset) >> 3;
+ Base = (Base + drmmode->front_bo->offset) >> 3;
tmp = hwp->readCrtc(hwp, 0x62) & 0x01;
tmp |= (Base & 0x7F) << 1;
@@ -954,7 +959,7 @@ iga1_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
if (pVia->pVbe) {
ViaVbeAdjustFrame(pScrn, x, y);
} else {
- ViaFirstCRTCSetStartingAddress(pScrn, x, y);
+ ViaFirstCRTCSetStartingAddress(crtc, x, y);
}
VIAVidAdjustFrame(pScrn, x, y);
}
@@ -1365,7 +1370,7 @@ iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
if (pVia->pVbe) {
ViaVbeAdjustFrame(pScrn, x, y);
} else {
- ViaSecondCRTCSetStartingAddress(pScrn, x, y);
+ ViaSecondCRTCSetStartingAddress(crtc, x, y);
}
VIAVidAdjustFrame(pScrn, x, y);
}
diff --git a/src/via_driver.c b/src/via_driver.c
index 52a5bea..1d3b78e 100644
--- a/src/via_driver.c
+++ b/src/via_driver.c
@@ -805,54 +805,44 @@ static Bool
via_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ struct buffer_object *old_front = NULL, *new_front = NULL;
int old_width, old_height, old_dwidth, format;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
- int cpp = (scrn->bitsPerPixel + 7) >> 3;
- struct buffer_object *old_front = NULL;
+ int cpp = (scrn->bitsPerPixel + 7) >> 3, i;
ScreenPtr screen = scrn->pScreen;
VIAPtr pVia = VIAPTR(scrn);
void *new_pixels = NULL;
uint32_t old_fb_id;
+ Bool ret = FALSE;
PixmapPtr ppix;
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
- old_width = scrn->virtualX;
- old_height = scrn->virtualY;
- old_dwidth = scrn->displayWidth;
- old_fb_id = drmmode->fb_id;
- old_front = drmmode->front_bo;
-
format = map_legacy_formats(scrn->bitsPerPixel, scrn->depth);
- drmmode->front_bo = drm_bo_alloc_surface(scrn, width, height, format,
+ new_front = drm_bo_alloc_surface(scrn, width, height, format,
16, TTM_PL_FLAG_VRAM);
- if (!drmmode->front_bo)
+ if (!new_front)
goto fail;
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Allocate new frame buffer %dx%d stride %d\n",
- width, height, drmmode->front_bo->pitch);
+ width, height, new_front->pitch);
- new_pixels = drm_bo_map(scrn, drmmode->front_bo);
+ new_pixels = drm_bo_map(scrn, new_front);
if (!new_pixels)
goto fail;
if (pVia->shadowFB) {
- new_pixels = malloc(height * drmmode->front_bo->pitch);
+ new_pixels = malloc(height * new_front->pitch);
if (!new_pixels)
goto fail;
free(pVia->ShadowPtr);
pVia->ShadowPtr = new_pixels;
}
- scrn->virtualX = width;
- scrn->virtualY = height;
- scrn->displayWidth = drmmode->front_bo->pitch / cpp;
ppix = screen->GetScreenPixmap(screen);
if (!screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
- drmmode->front_bo->pitch,
+ new_front->pitch,
new_pixels))
goto fail;
@@ -860,25 +850,52 @@ via_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
#endif
- if (xf86SetDesiredModes(scrn)) {
- if (old_front) {
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+ scrn->displayWidth = new_front->pitch / cpp;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ drmmode_crtc_private_ptr drmmode_crtc;
+ drmmode_ptr drmmode;
+
+ if (!crtc->enabled || !crtc->driver_private)
+ continue;
+
+ drmmode_crtc = crtc->driver_private;
+ drmmode = drmmode_crtc->drmmode;
+
+ old_front = drmmode->front_bo;
+ old_fb_id = drmmode->fb_id;
+
+ drmmode->front_bo = new_front;
+ drmmode->fb_id = 0;
+
+ ret = xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ if (!ret) {
+ drmmode->front_bo = old_front;
+ drmmode->fb_id = old_fb_id;
+ break;
#ifdef HAVE_DRI
- if (old_fb_id && pVia->KMS)
+ } else {
+ if (pVia->KMS && old_fb_id)
drmModeRmFB(drmmode->fd, old_fb_id);
#endif
- drm_bo_unmap(scrn, old_front);
- drm_bo_free(scrn, old_front);
}
- return TRUE;
+ }
+
+ if (ret) {
+ drm_bo_unmap(scrn, old_front);
+ drm_bo_free(scrn, old_front);
+ return ret;
}
fail:
- if (drmmode->front_bo) {
- drm_bo_unmap(scrn, drmmode->front_bo);
- drm_bo_free(scrn, drmmode->front_bo);
+ if (new_front) {
+ drm_bo_unmap(scrn, new_front);
+ drm_bo_free(scrn, new_front);
}
- drmmode->front_bo = old_front;
- drmmode->fb_id = old_fb_id;
scrn->virtualY = old_height;
scrn->virtualX = old_width;
scrn->displayWidth = old_dwidth;
diff --git a/src/via_ums.h b/src/via_ums.h
index 411d52d..dee43fa 100644
--- a/src/via_ums.h
+++ b/src/via_ums.h
@@ -222,9 +222,9 @@ void ViaSetUseExternalClock(vgaHWPtr hwp);
/* via_display.c */
Bool UMSCrtcInit(ScrnInfoPtr pScrn);
void ViaCRTCInit(ScrnInfoPtr pScrn);
-void ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pSCrn, int x, int y);
+void ViaFirstCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y);
void ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
-void ViaSecondCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y);
+void ViaSecondCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y);
void ViaSecondCRTCHorizontalOffset(ScrnInfoPtr pScrn);
void ViaSecondCRTCHorizontalQWCount(ScrnInfoPtr pScrn, int width);
void ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);