Allow/Fix use of multiple ZaphodHead outputs per x-screen.

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 <mario.kleiner.de@gmail.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Mario Kleiner
2015-07-15 09:54:59 +02:00
committed by Michel Dänzer
parent 159c5d460a
commit 3010d3259d
3 changed files with 37 additions and 12 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);