Separate modeset fallbacks are retained for each crtc
Change-Id: I51d6e27f3bf961dae72d580220e895c3b49ce326
diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
index e69430b..59aafbd 100644
--- a/src/armsoc_driver.c
+++ b/src/armsoc_driver.c
@@ -70,8 +70,6 @@
static void ARMSOCLeaveVT(VT_FUNC_ARGS_DECL);
static void ARMSOCFreeScreen(FREE_SCREEN_ARGS_DECL);
-
-
/**
* A structure used by the XFree86 code when loading this driver, so that it
* can access the Probe() function, and other functions/info that it uses
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index a6edfa8..216195e 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -72,6 +72,11 @@
struct drmmode_rec *drmmode;
drmModeCrtcPtr mode_crtc;
int cursor_visible;
+ /* settings retained on last good modeset */
+ int last_good_x;
+ int last_good_y;
+ Rotation last_good_rotation;
+ DisplayModePtr last_good_mode;
};
struct drmmode_prop_rec {
@@ -96,7 +101,7 @@
};
static void drmmode_output_dpms(xf86OutputPtr output, int mode);
-static Bool drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height);
+static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height);
static struct drmmode_rec *
drmmode_from_scrn(ScrnInfoPtr pScrn)
@@ -190,12 +195,6 @@
uint32_t fb_id;
drmModeModeInfo kmode;
drmModeCrtcPtr newcrtc = NULL;
- static int got_last_good = -1;
- static int last_good_x;
- static int last_good_y;
- static Rotation last_good_rotation;
- static DisplayModeRec last_good_mode;
-
TRACE_ENTER();
@@ -277,10 +276,6 @@
if (kmode.hdisplay != newcrtc->mode.hdisplay ||
kmode.vdisplay != newcrtc->mode.vdisplay) {
- xf86CrtcConfigPtr xf86_config;
- int i;
- Bool *enables;
-
ret = FALSE;
ERROR_MSG(
"drm did not set requested mode! (requested %dx%d, actual %dx%d)",
@@ -288,37 +283,29 @@
newcrtc->mode.hdisplay,
newcrtc->mode.vdisplay);
- if (got_last_good < 0) {
+ if (!drmmode_crtc->last_good_mode) {
DEBUG_MSG("No last good values to use");
goto done;
}
- DEBUG_MSG("Reverting to last_good values");
- /* disable crtcs to prevent resize calling back here */
- xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- enables = malloc(xf86_config->num_crtc * sizeof(Bool));
- for (i = 0; i < xf86_config->num_crtc; i++) {
- xf86CrtcPtr crtc = xf86_config->crtc[i];
- enables[i] = crtc->enabled;
- crtc->enabled = 0;
- }
/* revert to last good settings */
- drmmode_xf86crtc_resize(pScrn,
- last_good_mode.HDisplay,
- last_good_mode.VDisplay);
+ DEBUG_MSG("Reverting to last_good values");
+ if (!resize_scanout_bo(pScrn,
+ drmmode_crtc->last_good_mode->HDisplay,
+ drmmode_crtc->last_good_mode->VDisplay)) {
+ ERROR_MSG("Could not revert to last good mode");
+ goto done;
+ }
+
fb_id = armsoc_bo_get_fb(pARMSOC->scanout);
drmmode_ConvertToKMode(crtc->scrn, &kmode,
- &last_good_mode);
+ drmmode_crtc->last_good_mode);
drmModeSetCrtc(drmmode->fd,
drmmode_crtc->mode_crtc->crtc_id,
- fb_id, last_good_x, last_good_y,
+ fb_id,
+ drmmode_crtc->last_good_x,
+ drmmode_crtc->last_good_y,
output_ids, output_count, &kmode);
- /* re-enable crtcs */
- for (i = 0; i < xf86_config->num_crtc; i++) {
- xf86CrtcPtr crtc = xf86_config->crtc[i];
- crtc->enabled = enables[i];
- }
- free(enables);
/* let RandR know we changed things */
xf86RandR12TellChanged(pScrn->pScreen);
@@ -331,11 +318,16 @@
* that on failure.
*/
DEBUG_MSG("Setting last good values");
- got_last_good = 1;
- last_good_x = crtc->x;
- last_good_y = crtc->y;
- last_good_rotation = crtc->rotation;
- last_good_mode = crtc->mode;
+ drmmode_crtc->last_good_x = crtc->x;
+ drmmode_crtc->last_good_y = crtc->y;
+ drmmode_crtc->last_good_rotation = crtc->rotation;
+ if (drmmode_crtc->last_good_mode) {
+ if (drmmode_crtc->last_good_mode->name) {
+ free(drmmode_crtc->last_good_mode->name);
+ }
+ free(drmmode_crtc->last_good_mode);
+ }
+ drmmode_crtc->last_good_mode = xf86DuplicateMode(&crtc->mode);
ret = TRUE;
}
@@ -361,12 +353,12 @@
if (output_ids)
free(output_ids);
- if (!ret && got_last_good > 0) {
+ if (!ret && !drmmode_crtc->last_good_mode) {
/* If there was a problem, restore the last good mode: */
- crtc->x = last_good_x;
- crtc->y = last_good_y;
- crtc->rotation = last_good_rotation;
- crtc->mode = last_good_mode;
+ crtc->x = drmmode_crtc->last_good_x;
+ crtc->y = drmmode_crtc->last_good_y;
+ crtc->rotation = drmmode_crtc->last_good_rotation;
+ crtc->mode = *drmmode_crtc->last_good_mode;
}
TRACE_EXIT();
@@ -680,8 +672,10 @@
drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
drmmode->mode_res->crtcs[num]);
drmmode_crtc->drmmode = drmmode;
- INFO_MSG("Got CRTC: %d", num);
+ drmmode_crtc->last_good_mode = NULL;
+ INFO_MSG("Got CRTC: %d (id: %d)",
+ num, drmmode_crtc->mode_crtc->crtc_id);
crtc->driver_private = drmmode_crtc;
TRACE_EXIT();
@@ -1186,14 +1180,11 @@
pARMSOC->scanout = bo;
}
-static Bool
-drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
{
struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
ScreenPtr pScreen = pScrn->pScreen;
uint32_t pitch;
- int i;
- xf86CrtcConfigPtr xf86_config;
TRACE_ENTER();
DEBUG_MSG("Resize: %dx%d", width, height);
@@ -1300,6 +1291,20 @@
*/
rootPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
+ TRACE_EXIT();
+ return TRUE;
+}
+
+static Bool
+drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+{
+ int i;
+ xf86CrtcConfigPtr xf86_config;
+
+ TRACE_ENTER();
+
+ if (!resize_scanout_bo(pScrn, width, height))
+ return FALSE;
/* Framebuffer needs to be reset on all CRTCs, not just
* those that have repositioned */
diff --git a/src/drmmode_pl111/drmmode_pl111.c b/src/drmmode_pl111/drmmode_pl111.c
index 2346112..14d9624 100644
--- a/src/drmmode_pl111/drmmode_pl111.c
+++ b/src/drmmode_pl111/drmmode_pl111.c
@@ -136,7 +136,8 @@
}
}
-/* TODO MIDEGL-1718: this should be included from kernel headers when pl111 is mainline */
+/* TODO MIDEGL-1718: this should be included
+ * from kernel headers when pl111 is mainline */
struct drm_pl111_gem_create {
uint32_t height;
uint32_t width;