diff options
author | James Simmons <jsimmons@infradead.org> | 2013-05-19 17:18:39 -0400 |
---|---|---|
committer | James Simmons <jsimmons@infradead.org> | 2013-05-19 17:18:39 -0400 |
commit | cee0a1fab9cade87e6de16c67cd34c84cf697531 (patch) | |
tree | e8e63634e33f746d7aa6e307d2ae8c53026b675f | |
parent | 42d7ac70e3e9735619690a86482954827936d169 (diff) |
Fix the problems with UMS multiple screen handling. KMS still has problems
-rw-r--r-- | src/via_display.c | 19 | ||||
-rw-r--r-- | src/via_driver.c | 77 | ||||
-rw-r--r-- | src/via_ums.h | 4 |
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); |