Commit c9d43c1d authored by Michel Dänzer's avatar Michel Dänzer Committed by Michel Dänzer
Browse files

Allow up to six instances in Zaphod mode

Corresponding to up to six CRTCs being available in the hardware.

v2:
* Move instance overflow check from PreInit to the probe hooks, in
  order to further minimize wasted effort.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com> # v1
parent aa572683
Pipeline #5617 passed with stage
in 2 minutes and 2 seconds
......@@ -285,7 +285,7 @@ typedef struct {
/* Number of SW cursors currently visible on this screen */
int sprites_visible;
Bool IsSecondary;
int instance_id;
Bool shadow_fb;
void *fb_shadow;
......
......@@ -123,17 +123,18 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
if (!pScrn)
return;
pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
pPriv = xf86GetEntityPrivate(pEnt->index, gAMDGPUEntityIndex);
pAMDGPUEnt = pPriv->ptr;
info = AMDGPUPTR(pScrn);
if (info) {
pEnt = info->pEnt;
pAMDGPUEnt->scrn[info->instance_id] = NULL;
pAMDGPUEnt->num_scrns--;
free(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
} else {
pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
}
pPriv = xf86GetEntityPrivate(pEnt->index, gAMDGPUEntityIndex);
pAMDGPUEnt = pPriv->ptr;
if (pAMDGPUEnt->fd > 0) {
DevUnion *pPriv;
AMDGPUEntPtr pAMDGPUEnt;
......@@ -1317,7 +1318,6 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
AMDGPUEntPtr pAMDGPUEnt;
struct amdgpu_gpu_info gpu_info;
MessageType from;
DevUnion *pPriv;
Gamma zeros = { 0.0, 0.0, 0.0 };
int cpp;
uint64_t heap_size = 0;
......@@ -1331,11 +1331,17 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
"AMDGPUPreInit_KMS\n");
if (pScrn->numEntities != 1)
return FALSE;
pAMDGPUEnt = xf86GetEntityPrivate(pScrn->entityList[0],
getAMDGPUEntityIndex())->ptr;
if (!AMDGPUGetRec(pScrn))
return FALSE;
info = AMDGPUPTR(pScrn);
info->IsSecondary = FALSE;
info->instance_id = pAMDGPUEnt->num_scrns++;
pAMDGPUEnt->scrn[info->instance_id] = pScrn;
info->pEnt =
xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
if (info->pEnt->location.type != BUS_PCI
......@@ -1345,23 +1351,11 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
)
return FALSE;
pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
getAMDGPUEntityIndex());
pAMDGPUEnt = pPriv->ptr;
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
info->IsSecondary = TRUE;
} else {
xf86SetPrimInitDone(pScrn->entityList[0]);
}
if (xf86IsEntityShared(pScrn->entityList[0]) &&
info->instance_id == 0) {
xf86SetPrimInitDone(pScrn->entityList[0]);
}
if (info->IsSecondary)
pAMDGPUEnt->secondary_scrn = pScrn;
else
pAMDGPUEnt->primary_scrn = pScrn;
info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
pScrn->monitor = pScrn->confScreen->monitor;
......
......@@ -252,6 +252,14 @@ static Bool amdgpu_get_scrninfo(int entity_num, struct pci_device *pci_dev)
}
} else {
pAMDGPUEnt = pPriv->ptr;
if (pAMDGPUEnt->fd_ref == ARRAY_SIZE(pAMDGPUEnt->scrn)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Only up to %u Zaphod instances supported\n",
(unsigned)ARRAY_SIZE(pAMDGPUEnt->scrn));
goto error;
}
pAMDGPUEnt->fd_ref++;
}
......@@ -366,6 +374,14 @@ amdgpu_platform_probe(DriverPtr pDriver,
}
} else {
pAMDGPUEnt = pPriv->ptr;
if (pAMDGPUEnt->fd_ref == ARRAY_SIZE(pAMDGPUEnt->scrn)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Only up to %u Zaphod instances supported\n",
(unsigned)ARRAY_SIZE(pAMDGPUEnt->scrn));
goto error;
}
pAMDGPUEnt->fd_ref++;
}
......
......@@ -65,8 +65,8 @@ typedef struct {
unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
int fd_wakeup_ref;
unsigned int assigned_crtcs;
ScrnInfoPtr primary_scrn;
ScrnInfoPtr secondary_scrn;
unsigned int num_scrns;
ScrnInfoPtr scrn[6];
struct xf86_platform_device *platform_dev;
char *render_node;
} AMDGPUEntRec, *AMDGPUEntPtr;
......
......@@ -2669,9 +2669,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
if (!AMDGPUZaphodStringMatches(pScrn, s, name))
goto out_free_encoders;
} else {
if (!info->IsSecondary && (num != 0))
goto out_free_encoders;
else if (info->IsSecondary && (num != 1))
if (info->instance_id != num)
goto out_free_encoders;
}
}
......@@ -3267,6 +3265,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
int i, num_dvi = 0, num_hdmi = 0;
unsigned int crtcs_needed = 0;
unsigned int crtcs_got = 0;
drmModeResPtr mode_res;
char *bus_id_string, *provider_name;
......@@ -3307,16 +3306,26 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
if (pScrn->depth == 30 && !drmmode_cm_enabled(drmmode))
info->drmmode_crtc_funcs.gamma_set = NULL;
for (i = 0; i < mode_res->count_crtcs; i++)
for (i = 0; i < mode_res->count_crtcs; i++) {
if (!xf86IsEntityShared(pScrn->entityList[0]) ||
(crtcs_needed && !(pAMDGPUEnt->assigned_crtcs & (1 << i))))
crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
(crtcs_got < crtcs_needed &&
!(pAMDGPUEnt->assigned_crtcs & (1 << i))))
crtcs_got += drmmode_crtc_init(pScrn, drmmode, mode_res, i);
}
/* All ZaphodHeads outputs provided with matching crtcs? */
if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
if (crtcs_got < crtcs_needed) {
if (crtcs_got == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No ZaphodHeads CRTC available, needed %u\n",
crtcs_needed);
return FALSE;
}
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);
......@@ -3769,13 +3778,14 @@ restart_destroy:
/* find new output ids we don't have outputs for */
for (i = 0; i < mode_res->count_connectors; i++) {
if (drmmode_find_output(pAMDGPUEnt->primary_scrn,
mode_res->connectors[i],
&num_dvi, &num_hdmi) ||
(pAMDGPUEnt->secondary_scrn &&
drmmode_find_output(pAMDGPUEnt->secondary_scrn,
mode_res->connectors[i],
&num_dvi, &num_hdmi)))
for (j = 0; j < pAMDGPUEnt->num_scrns; j++) {
if (drmmode_find_output(pAMDGPUEnt->scrn[j],
mode_res->connectors[i],
&num_dvi, &num_hdmi))
break;
}
if (j < pAMDGPUEnt->num_scrns)
continue;
if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment