Defining multiple ZaphodHead outputs per x-screen in a multiple x-screen's per gpu configuration caused all outputs except one per x-screen to go dark, because there was a fixed mapping x-screen number -> crtc number, limiting the number of crtc's per x-screen to one.
On a ZaphodHead's setup, be more clever and assign as many crtc's to a given x-screen as there are ZaphodHeads defined for that screen, assuming there are enough unused crtc's available. (Ported from radeon commit afab7839fc15722dbaa7203d00fe7f6ce5336b9d) Tested on a triple display AMD setup with different combos of one, two or three ZaphodHeads per one, two or three x-screens. Also tested on nouveau and intel dual-display setups with one or two x-screens. Signed-off-by: Mario Kleiner <mario.kleiner...@gmail.com> --- hw/xfree86/drivers/modesetting/driver.c | 4 +++ hw/xfree86/drivers/modesetting/driver.h | 1 + hw/xfree86/drivers/modesetting/drmmode_display.c | 43 ++++++++++++++++++------ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 5dcc6a0..fd41ccd 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1328,6 +1328,10 @@ CloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); + modesettingEntPtr ms_ent = ms_ent_priv(pScrn); + + /* Clear mask of assigned crtc's in this generation */ + ms_ent->assigned_crtcs = 0; #ifdef GLAMOR if (ms->drmmode.glamor) { diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index 1166165..14137c1 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -43,6 +43,7 @@ #include "drmmode_display.h" #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); +#define MS_LOGLEVEL_DEBUG 4 typedef enum { OPTION_SW_CURSOR, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index ad9c062..60c35be 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -821,15 +821,16 @@ drmmode_crtc_vblank_pipe(int crtc_id) return 0; } -static void +static unsigned int drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) { xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; + modesettingEntPtr ms_ent = ms_ent_priv(pScrn); crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); if (crtc == NULL) - return; + return 0; drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); drmmode_crtc->mode_crtc = @@ -837,6 +838,13 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res drmmode_crtc->drmmode = drmmode; drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); crtc->driver_private = drmmode_crtc; + + /* Mark num'th crtc as in use on this device. */ + ms_ent->assigned_crtcs |= (1 << num); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, + "Allocated crtc nr. %d to this screen.\n", num); + + return 1; } static xf86OutputStatus @@ -1378,7 +1386,7 @@ drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); } -static void +static unsigned int drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic) { xf86OutputPtr output; @@ -1394,7 +1402,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r koutput = drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); if (!koutput) - return; + return 0; for (i = 0; i < koutput->count_props; i++) { props = drmModeGetProperty(drmmode->fd, koutput->props[i]); @@ -1425,7 +1433,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmmode_output = output->driver_private; drmmode_output->output_id = mode_res->connectors[num]; drmmode_output->mode_output = koutput; - return; + return 1; } } @@ -1497,7 +1505,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r if (dynamic) output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); - return; + return 1; + out_free_encoders: if (kencoders) { for (i = 0; i < koutput->count_encoders; i++) @@ -1506,6 +1515,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r } drmModeFreeConnector(koutput); + return 0; } static uint32_t @@ -1727,9 +1737,11 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { + modesettingEntPtr ms_ent = ms_ent_priv(pScrn); int i; int ret; uint64_t value = 0; + unsigned int crtcs_needed = 0; drmModeResPtr mode_res; /* check for dumb capability */ @@ -1748,15 +1760,24 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) if (!mode_res) return FALSE; + for (i = 0; i < mode_res->count_connectors; i++) + crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE); + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, + "Up to %d crtcs needed for screen.\n", crtcs_needed); + xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height); for (i = 0; i < mode_res->count_crtcs; i++) if (!xf86IsEntityShared(pScrn->entityList[0]) || - pScrn->confScreen->device->screen == i) - drmmode_crtc_init(pScrn, drmmode, mode_res, i); - - for (i = 0; i < mode_res->count_connectors; i++) - drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE); + (crtcs_needed && !(ms_ent->assigned_crtcs & (1 << i)))) + crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i); + + /* All ZaphodHeads outputs provided with matching crtcs? */ + if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n", + crtcs_needed); /* workout clones */ drmmode_clones_init(pScrn, drmmode, mode_res); -- 2.1.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel