X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=drm-lease-manager%2Flease-manager.c;h=51a4613f84b5b94e17eb175d0bebd101548caeca;hb=HEAD;hp=177a241631861091cec522949eb65853de496eda;hpb=84bd108e702b753bc1f7b232c94baa5b84295b5f;p=src%2Fdrm-lease-manager.git diff --git a/drm-lease-manager/lease-manager.c b/drm-lease-manager/lease-manager.c index 177a241..7147078 100644 --- a/drm-lease-manager/lease-manager.c +++ b/drm-lease-manager/lease-manager.c @@ -216,17 +216,48 @@ static bool drm_find_connector(struct lm *lm, char *name, uint32_t *id) return false; } -static bool lease_add_planes(struct lm *lm, struct lease *lease, int crtc_index) +static void config_get_planes(struct lm *lm, + const struct connector_config *config, + int *nplanes, uint32_t **planes) { - for (uint32_t i = 0; i < lm->drm_plane_resource->count_planes; i++) { - uint32_t plane_id = lm->drm_plane_resource->planes[i]; + if (config && config->planes) { + *nplanes = config->nplanes; + *planes = config->planes; + } else { + *nplanes = (int)lm->drm_plane_resource->count_planes; + *planes = lm->drm_plane_resource->planes; + } +} + +static bool lease_add_planes(struct lm *lm, struct lease *lease, + uint32_t crtc_index, + const struct connector_config *con_config) +{ + int nplanes; + uint32_t *planes; + uint32_t crtc_mask = (1 << crtc_index); + + /* Only allow shared planes when plane list is explicitly set */ + bool allow_shared = con_config && con_config->planes; + + config_get_planes(lm, con_config, &nplanes, &planes); + + for (int i = 0; i < nplanes; i++) { + uint32_t plane_id = planes[i]; drmModePlanePtr plane = drmModeGetPlane(lm->drm_fd, plane_id); - assert(plane); + if (!plane) { + ERROR_LOG( + "Unknown plane id %d configured in lease: %s\n", + plane_id, lease->base.name); + return false; + } - // Exclude planes that can be used with multiple CRTCs for now - if (plane->possible_crtcs == (1u << crtc_index)) { - lease->object_ids[lease->nobject_ids++] = plane_id; + if (plane->possible_crtcs & crtc_mask) { + bool shared_plane = plane->possible_crtcs != crtc_mask; + if (allow_shared || !shared_plane) + lease->object_ids[lease->nobject_ids++] = + plane_id; } drmModeFreePlane(plane); } @@ -356,11 +387,27 @@ static struct lease *lease_create(struct lm *lm, for (int i = 0; i < nconnectors; i++) { uint32_t cid; + struct connector_config *con_config = NULL; + + if (config->nconnectors > 0) + con_config = &config->connectors[i]; + + if (con_config) { + char *connector_name = con_config->name; + bool optional = con_config->optional; - if (config->nconnectors > 0) { - char *connector_name = config->connectors[i].name; + bool found = + drm_find_connector(lm, connector_name, &cid); - if (!drm_find_connector(lm, connector_name, &cid)) { + bool missing_mandatory = !found && !optional; + bool missing_optional = !found && optional; + + if (missing_mandatory) { + ERROR_LOG("Lease: %s, " + "mandatory connector %s not found\n", + config->lease_name, connector_name); + goto err; + } else if (missing_optional) { WARN_LOG("Lease: %s, " "unknown DRM connector: %s\n", config->lease_name, connector_name); @@ -388,7 +435,7 @@ static struct lease *lease_create(struct lm *lm, goto err; } - if (!lease_add_planes(lm, lease, crtc_index)) + if (!lease_add_planes(lm, lease, crtc_index, con_config)) goto err; uint32_t crtc_id = lm->drm_resource->crtcs[crtc_index]; @@ -457,9 +504,12 @@ err: return -1; } -static struct lm *drm_device_get_resources(const char *device) +static struct lm *drm_device_get_resources(const char *device, + bool universal_plane) { struct lm *lm = calloc(1, sizeof(struct lm)); + uint64_t value = 0; + if (!lm) { DEBUG_LOG("Memory allocation failed: %s\n", strerror(errno)); return NULL; @@ -471,6 +521,20 @@ static struct lm *drm_device_get_resources(const char *device) goto err; } + /* When -u option set at args. Enable universal planes so that ALL + planes, even primary and cursor planes can be assigned from lease + configurations. */ + if (universal_plane == true) { + DEBUG_LOG("Enable universal plean mode.\n"); + value = 1; + } + + if (drmSetClientCap(lm->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, + value)) { + DEBUG_LOG("drmSetClientCap failed\n"); + goto err; + } + lm->drm_resource = drmModeGetResources(lm->drm_fd); if (!lm->drm_resource) { ERROR_LOG("Invalid DRM device(%s)\n", device); @@ -478,6 +542,13 @@ static struct lm *drm_device_get_resources(const char *device) goto err; } + if (lm->drm_resource->count_connectors <= 0 || + lm->drm_resource->count_crtcs <= 0 || + lm->drm_resource->count_encoders <= 0) { + DEBUG_LOG("Insufficient DRM resources on device(%s)\n", device); + goto err; + } + lm->drm_plane_resource = drmModeGetPlaneResources(lm->drm_fd); if (!lm->drm_plane_resource) { DEBUG_LOG("drmModeGetPlaneResources failed: %s\n", @@ -516,20 +587,20 @@ err: return NULL; } -static struct lm *drm_find_drm_device(const char *device) +static struct lm *drm_find_drm_device(const char *device, bool universal_plane) { drmDevicePtr devices[64]; int ndevs; struct lm *lm = NULL; if (device) - return drm_device_get_resources(device); + return drm_device_get_resources(device, universal_plane); ndevs = drmGetDevices2(0, devices, 64); for (int i = 0; i < ndevs; i++) { lm = drm_device_get_resources( - devices[i]->nodes[DRM_NODE_PRIMARY]); + devices[i]->nodes[DRM_NODE_PRIMARY], universal_plane); if (lm) break; } @@ -565,10 +636,11 @@ static int lm_create_leases(struct lm *lm, int num_leases, } struct lm *lm_create_with_config(const char *device, int num_leases, - struct lease_config *configs) + struct lease_config *configs, + bool universal_plane) { struct lease_config *default_configs = NULL; - struct lm *lm = drm_find_drm_device(device); + struct lm *lm = drm_find_drm_device(device, universal_plane); if (!lm) { ERROR_LOG("No available DRM device found\n"); @@ -597,7 +669,7 @@ struct lm *lm_create_with_config(const char *device, int num_leases, struct lm *lm_create(const char *device) { - return lm_create_with_config(device, 0, NULL); + return lm_create_with_config(device, 0, NULL, false); } void lm_destroy(struct lm *lm)