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) Signed-off-by: Mario Kleiner <[email protected]> Cc: Michel Dänzer <[email protected]> --- src/amdgpu_kms.c | 4 ++++ src/amdgpu_probe.h | 1 + src/drmmode_display.c | 44 ++++++++++++++++++++++++++++++++------------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index 2019155..fb60310 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -924,10 +924,14 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, "AMDGPUCloseScreen\n"); + /* Clear mask of assigned crtc's in this generation */ + pAMDGPUEnt->assigned_crtcs = 0; + drmmode_uevent_fini(pScrn, &info->drmmode); amdgpu_drm_queue_close(pScrn); diff --git a/src/amdgpu_probe.h b/src/amdgpu_probe.h index 1f760ac..4af7f48 100644 --- a/src/amdgpu_probe.h +++ b/src/amdgpu_probe.h @@ -80,6 +80,7 @@ typedef struct { int fd_ref; unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */ int fd_wakeup_ref; + unsigned int assigned_crtcs; } AMDGPUEntRec, *AMDGPUEntPtr; extern const OptionInfoRec *AMDGPUOptionsWeak(void); diff --git a/src/drmmode_display.c b/src/drmmode_display.c index bce6774..8c2df13 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -846,14 +846,15 @@ void drmmode_crtc_hw_id(xf86CrtcPtr crtc) drmmode_crtc->hw_id = -1; } -static void drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +static unsigned int drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) { xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(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 = @@ -862,7 +863,12 @@ static void drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) crtc->driver_private = drmmode_crtc; drmmode_crtc_hw_id(crtc); - return; + /* Mark num'th crtc as in use on this device. */ + pAMDGPUEnt->assigned_crtcs |= (1 << num); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, + "Allocated crtc nr. %d to this screen.\n", num); + + return 1; } static xf86OutputStatus drmmode_output_detect(xf86OutputPtr output) @@ -1222,7 +1228,7 @@ const char *output_names[] = { "None", #define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0])) -static void +static unsigned int drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) { AMDGPUInfoPtr info = AMDGPUPTR(pScrn); @@ -1239,7 +1245,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); if (!koutput) - return; + return 0; kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); if (!kencoders) { @@ -1325,7 +1331,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) } } - return; + return 1; out_free_encoders: if (kencoders) { for (i = 0; i < koutput->count_encoders; i++) @@ -1333,7 +1339,7 @@ out_free_encoders: free(kencoders); } drmModeFreeConnector(koutput); - + return 0; } uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) @@ -1600,7 +1606,9 @@ static void drm_wakeup_handler(pointer data, int err, pointer p) Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); int i; + unsigned int crtcs_needed = 0; xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -1612,13 +1620,25 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height); - for (i = 0; i < drmmode->mode_res->count_crtcs; i++) - if (!xf86IsEntityShared(pScrn->entityList[0]) - || pScrn->confScreen->device->screen == i) - drmmode_crtc_init(pScrn, drmmode, i); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, + "Initializing outputs ...\n"); for (i = 0; i < drmmode->mode_res->count_connectors; i++) - drmmode_output_init(pScrn, drmmode, i); + crtcs_needed += drmmode_output_init(pScrn, drmmode, i); + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, + "%d crtcs needed for screen.\n", crtcs_needed); + + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + if (!xf86IsEntityShared(pScrn->entityList[0]) || + (crtcs_needed && !(pAMDGPUEnt->assigned_crtcs & (1 << i)))) + crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, 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); -- 1.9.1 _______________________________________________ xorg-driver-ati mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-ati
