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

Reply via email to