mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Add RandR leases support
Signed-off-by: Keith Packard <keithp@keithp.com> (Ported from xserver commit e4e3447603b5fd3a38a92c3f972396d1f81168ad) Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> (Ported from amdgpu commit 61040bdfa360975614fb47aa7ea1b3a1abac3427) Acked-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
b4f0f44a9f
commit
f533b1f654
@@ -70,7 +70,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
|
||||
XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
|
||||
|
||||
# Checks for libraries.
|
||||
PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78])
|
||||
PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.89])
|
||||
PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon])
|
||||
|
||||
# Obtain compiler/linker options for the driver dependencies
|
||||
|
||||
@@ -2400,8 +2400,159 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
drmmode_validate_leases(ScrnInfoPtr scrn)
|
||||
{
|
||||
#ifdef XF86_LEASE_VERSION
|
||||
ScreenPtr screen = scrn->pScreen;
|
||||
rrScrPrivPtr scr_priv = rrGetScrPriv(screen);
|
||||
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
|
||||
drmModeLesseeListPtr lessees;
|
||||
RRLeasePtr lease, next;
|
||||
int l;
|
||||
|
||||
/* We can't talk to the kernel about leases when VT switched */
|
||||
if (!scrn->vtSema)
|
||||
return;
|
||||
|
||||
lessees = drmModeListLessees(pRADEONEnt->fd);
|
||||
if (!lessees)
|
||||
return;
|
||||
|
||||
xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) {
|
||||
drmmode_lease_private_ptr lease_private = lease->devPrivate;
|
||||
|
||||
for (l = 0; l < lessees->count; l++) {
|
||||
if (lessees->lessees[l] == lease_private->lessee_id)
|
||||
break;
|
||||
}
|
||||
|
||||
/* check to see if the lease has gone away */
|
||||
if (l == lessees->count) {
|
||||
free(lease_private);
|
||||
lease->devPrivate = NULL;
|
||||
xf86CrtcLeaseTerminated(lease);
|
||||
}
|
||||
}
|
||||
|
||||
free(lessees);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XF86_LEASE_VERSION
|
||||
|
||||
static int
|
||||
drmmode_create_lease(RRLeasePtr lease, int *fd)
|
||||
{
|
||||
ScreenPtr screen = lease->screen;
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
|
||||
drmmode_lease_private_ptr lease_private;
|
||||
int noutput = lease->numOutputs;
|
||||
int ncrtc = lease->numCrtcs;
|
||||
uint32_t *objects;
|
||||
size_t nobjects;
|
||||
int lease_fd;
|
||||
int c, o;
|
||||
int i;
|
||||
|
||||
nobjects = ncrtc + noutput;
|
||||
if (nobjects == 0 || nobjects > (SIZE_MAX / 4) ||
|
||||
ncrtc > (SIZE_MAX - noutput))
|
||||
return BadValue;
|
||||
|
||||
lease_private = calloc(1, sizeof (drmmode_lease_private_rec));
|
||||
if (!lease_private)
|
||||
return BadAlloc;
|
||||
|
||||
objects = malloc(nobjects * 4);
|
||||
if (!objects) {
|
||||
free(lease_private);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
/* Add CRTC ids */
|
||||
for (c = 0; c < ncrtc; c++) {
|
||||
xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate;
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
|
||||
objects[i++] = drmmode_crtc->mode_crtc->crtc_id;
|
||||
}
|
||||
|
||||
/* Add connector ids */
|
||||
for (o = 0; o < noutput; o++) {
|
||||
xf86OutputPtr output = lease->outputs[o]->devPrivate;
|
||||
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
||||
|
||||
objects[i++] = drmmode_output->mode_output->connector_id;
|
||||
}
|
||||
|
||||
/* call kernel to create lease */
|
||||
assert (i == nobjects);
|
||||
|
||||
lease_fd = drmModeCreateLease(pRADEONEnt->fd, objects, nobjects, 0,
|
||||
&lease_private->lessee_id);
|
||||
|
||||
free(objects);
|
||||
|
||||
if (lease_fd < 0) {
|
||||
free(lease_private);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
lease->devPrivate = lease_private;
|
||||
|
||||
xf86CrtcLeaseStarted(lease);
|
||||
|
||||
*fd = lease_fd;
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
drmmode_terminate_lease(RRLeasePtr lease)
|
||||
{
|
||||
drmmode_lease_private_ptr lease_private = lease->devPrivate;
|
||||
ScreenPtr screen = lease->screen;
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
|
||||
|
||||
if (drmModeRevokeLease(pRADEONEnt->fd, lease_private->lessee_id) == 0) {
|
||||
free(lease_private);
|
||||
lease->devPrivate = NULL;
|
||||
xf86CrtcLeaseTerminated(lease);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // XF86_LEASE_VERSION
|
||||
|
||||
void
|
||||
drmmode_terminate_leases(ScrnInfoPtr pScrn)
|
||||
{
|
||||
#ifdef XF86_LEASE_VERSION
|
||||
ScreenPtr screen = xf86ScrnToScreen(pScrn);
|
||||
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
|
||||
rrScrPrivPtr scr_priv = rrGetScrPriv(screen);
|
||||
RRLeasePtr lease, next;
|
||||
|
||||
xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) {
|
||||
drmmode_lease_private_ptr lease_private = lease->devPrivate;
|
||||
drmModeRevokeLease(pRADEONEnt->fd, lease_private->lessee_id);
|
||||
free(lease_private);
|
||||
lease->devPrivate = NULL;
|
||||
RRLeaseTerminated(lease);
|
||||
RRLeaseFree(lease);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
|
||||
drmmode_xf86crtc_resize
|
||||
.resize = drmmode_xf86crtc_resize,
|
||||
#ifdef XF86_LEASE_VERSION
|
||||
.create_lease = drmmode_create_lease,
|
||||
.terminate_lease = drmmode_terminate_lease
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -2888,6 +3039,9 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Validate leases on VT re-entry */
|
||||
drmmode_validate_leases(pScrn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3055,6 +3209,9 @@ restart_destroy:
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if a lessee has disappeared */
|
||||
drmmode_validate_leases(scrn);
|
||||
|
||||
if (changed && dixPrivateKeyRegistered(rrPrivKey)) {
|
||||
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
|
||||
RRSetChanged(xf86ScrnToScreen(scrn));
|
||||
|
||||
@@ -139,6 +139,10 @@ typedef struct {
|
||||
int tear_free;
|
||||
} drmmode_output_private_rec, *drmmode_output_private_ptr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t lessee_id;
|
||||
} drmmode_lease_private_rec, *drmmode_lease_private_ptr;
|
||||
|
||||
|
||||
enum drmmode_flip_sync {
|
||||
FLIP_VSYNC,
|
||||
@@ -223,6 +227,8 @@ PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
|
||||
extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
|
||||
extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
|
||||
|
||||
extern void drmmode_terminate_leases(ScrnInfoPtr scrn);
|
||||
|
||||
Bool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb,
|
||||
DisplayModePtr mode, int x, int y);
|
||||
|
||||
|
||||
@@ -2154,6 +2154,7 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen)
|
||||
/* Clear mask of assigned crtc's in this generation */
|
||||
pRADEONEnt->assigned_crtcs = 0;
|
||||
|
||||
drmmode_terminate_leases(pScrn);
|
||||
drmmode_uevent_fini(pScrn, &info->drmmode);
|
||||
radeon_drm_queue_close(pScrn);
|
||||
radeon_cs_flush_indirect(pScrn);
|
||||
|
||||
Reference in New Issue
Block a user