buildroot:libdrm: Uploaded DDK patches for libdrm

Uploaded DDK patches for libdrm

Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
This commit is contained in:
shanlong.li
2022-05-05 01:42:30 -07:00
parent beafff9e47
commit 83f94732a9
3 changed files with 531 additions and 0 deletions
@@ -0,0 +1,212 @@
From fef264e0844cfd49be3fdc19a6cea3f2d0f273a8 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 24 Aug 2017 13:28:38 +0100
Subject: [PATCH 4/6] Add sync_fence_info and sync_pt_info
For pre-4.7 kernels, sync_fence_info returns the data from the
SYNC_IOC_FENCE_INFO ioctl. For newer kernels, the SYNC_IOC_FILE_INFO
ioctl is called, and the data converted to SYNC_IOC_FENCE_INFO form.
---
libsync.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/libsync.h b/libsync.h
index c3b8a38..44f7330 100644
--- a/libsync.h
+++ b/libsync.h
@@ -31,6 +31,7 @@
#include <assert.h>
#include <errno.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
@@ -74,6 +75,54 @@ struct sync_legacy_merge_data {
struct sync_legacy_merge_data)
#endif
+#ifndef SYNC_IOC_FILE_INFO
+/* duplicated from linux/sync_file.h to avoid a build-time dependency
+ * on new (v4.7) kernel headers.
+ */
+struct sync_fence_info {
+ char obj_name[32];
+ char driver_name[32];
+ int32_t status;
+ uint32_t flags;
+ uint64_t timestamp_ns;
+};
+
+struct sync_file_info {
+ char name[32];
+ int32_t status;
+ uint32_t flags;
+ uint32_t num_fences;
+ uint32_t pad;
+ uint64_t sync_fence_info;
+};
+
+#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
+#endif
+
+#ifndef SYNC_IOC_LEGACY_FENCE_INFO
+/* the legacy definitions are based on the contents of
+ * drivers/staging/android/uapi/sync.h in the v4.4 kernel.
+ */
+struct sync_pt_info {
+ uint32_t len;
+ char obj_name[32];
+ char driver_name[32];
+ int32_t status;
+ uint64_t timestamp_ns;
+ uint8_t driver_data[0];
+};
+
+struct sync_fence_info_data {
+ uint32_t len;
+ char name[32];
+ int32_t status;
+ uint8_t pt_info[0];
+};
+
+#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2, \
+ struct sync_fence_info_data)
+#endif
+
static inline int sync_wait(int fd, int timeout)
{
struct pollfd fds = {0};
@@ -179,6 +228,129 @@ static inline int sync_accumulate(const char *name, int *fd1, int fd2)
return 0;
}
+static inline struct sync_pt_info *sync_pt_info(
+ struct sync_fence_info_data *info,
+ struct sync_pt_info *pt_info)
+{
+ if (!pt_info)
+ pt_info = (struct sync_pt_info *)info->pt_info;
+ else
+ pt_info = (struct sync_pt_info *)((uint8_t *)pt_info +
+ pt_info->len);
+
+ if ((uint32_t)((uint8_t *)pt_info - (uint8_t *)info) >= info->len)
+ return NULL;
+
+ return pt_info;
+}
+
+static inline struct sync_fence_info_data *sync_legacy_fence_info(int fd)
+{
+ const uint32_t len = 4096;
+ struct sync_fence_info_data *info = malloc(len);
+ int ret;
+
+ if (!info)
+ return NULL;
+
+ info->len = len;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+static inline struct sync_fence_info_data *fence_info_from_file_info(
+ struct sync_file_info *file_info,
+ uint32_t num_fences)
+{
+ struct sync_fence_info_data *info;
+ size_t info_len;
+ struct sync_pt_info *pt_info = NULL;
+ struct sync_fence_info *fence_info;
+ uint32_t i;
+
+ info_len = sizeof(*info) + num_fences * sizeof(*pt_info);
+ info = malloc(info_len);
+ if (!info)
+ return NULL;
+
+ info->len = info_len;
+ strncpy(info->name, file_info->name, sizeof(info->name));
+ info->status = file_info->status;
+
+ fence_info = (struct sync_fence_info *)(uintptr_t)
+ file_info->sync_fence_info;
+ for (i = 0; i < num_fences; i++) {
+ pt_info = sync_pt_info(info, pt_info);
+ assert(pt_info);
+
+ pt_info->len = sizeof(*pt_info);
+ strncpy(pt_info->obj_name, fence_info->obj_name,
+ sizeof(pt_info->obj_name));
+ strncpy(pt_info->driver_name, fence_info->driver_name,
+ sizeof(pt_info->driver_name));
+ pt_info->status = fence_info->status;
+ pt_info->timestamp_ns = fence_info->timestamp_ns;
+
+ fence_info++;
+ }
+
+ return info;
+}
+
+static inline struct sync_fence_info_data *sync_fence_info(int fd)
+{
+ struct sync_fence_info_data *info = NULL;
+ struct sync_file_info initial_info = {""};
+ struct sync_file_info *file_info;
+ int ret;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_fence_info(fd);
+ else
+ return NULL;
+ }
+
+ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences *
+ sizeof(struct sync_fence_info));
+ if (!file_info)
+ return NULL;
+
+ file_info->num_fences = initial_info.num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0)
+ goto free_file_info;
+
+ info = fence_info_from_file_info(file_info, initial_info.num_fences);
+
+free_file_info:
+ free(file_info);
+
+ return info;
+}
+
+static inline void sync_fence_info_free(struct sync_fence_info_data *info)
+{
+ free(info);
+}
#if defined(__cplusplus)
}
#endif
--
2.7.4
@@ -0,0 +1,171 @@
From 001ef51239541dd91f854ea5a5f569f2b338ad82 Mon Sep 17 00:00:00 2001
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
Date: Tue, 24 Sep 2019 13:09:31 +0100
Subject: [PATCH 5/6] xf86drm: add support for populating drm formats
This change lets libdrm take care of allocation and deallocation of
the drmModePlane formats on behalf of clients. Weston, xserver and
others can use this functionaly instead of querying and parsing the
drm blob.
NOTE: this change is based on weston/kms.c
Change-Id: Id318322ee6b8f02442a37797669edd0363a58d88
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
xf86drmMode.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
xf86drmMode.h | 12 +++++++
2 files changed, 120 insertions(+)
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 2399e8e..3a099b2 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -718,6 +718,114 @@ err_allocs:
return r;
}
+static inline uint32_t *
+formats_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (uint32_t *)(((uint8_t *)blob) + blob->formats_offset);
+}
+
+static inline struct drm_format_modifier *
+modifiers_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (struct drm_format_modifier *)(((uint8_t *)blob) +
+ blob->modifiers_offset);
+}
+
+drm_public void
+drmModeFreeFormats(drmModeFormatsPtr drm_mode_fmt)
+{
+ uint32_t i;
+
+ if (!drm_mode_fmt)
+ return;
+
+ for (i = 0; i < drm_mode_fmt->count; i++)
+ drmFree(drm_mode_fmt->formats[i].modifiers);
+
+ drmFree(drm_mode_fmt);
+}
+
+drm_public int
+drmModePopulateFormats(drmModePropertyBlobPtr blob, drmModeFormatsPtr *out_formats)
+{
+ struct drm_format_modifier_blob *fmt_mod_blob;
+ struct drm_format_modifier *blob_modifiers;
+ drmModeFormatsPtr drm_mode_fmt;
+ uint32_t *blob_formats;
+ uint32_t count_formats;
+ uint32_t i;
+
+ if (!blob || !out_formats)
+ return -EINVAL;
+
+ fmt_mod_blob = blob->data;
+ blob_formats = formats_ptr(fmt_mod_blob);
+ blob_modifiers = modifiers_ptr(fmt_mod_blob);
+
+ if (!fmt_mod_blob->count_formats)
+ return -EINVAL;
+
+ /* The drmModeFormats type supports C versions earlier than C99
+ * by explicitly defining an array of length 1. Thus, 1 must be
+ * deducted from the runtime value of fmt_mod_blob->count_formats.
+ */
+ count_formats = fmt_mod_blob->count_formats - 1;
+ drm_mode_fmt = drmMalloc(sizeof(*drm_mode_fmt) +
+ sizeof(drm_mode_fmt->formats[0]) * count_formats);
+ if (!drm_mode_fmt)
+ return -errno;
+
+ drm_mode_fmt->count = 0;
+
+ for (i = 0; i < fmt_mod_blob->count_formats; i++) {
+ uint32_t count_valid_modifiers = 0;
+ uint64_t *modifiers = NULL;
+ unsigned j;
+
+ for (j = 0; j < fmt_mod_blob->count_modifiers; j++) {
+ struct drm_format_modifier *mod = &blob_modifiers[j];
+
+ if ((i < mod->offset) || (i > mod->offset + 63))
+ continue;
+ if (!(mod->formats & (1 << (i - mod->offset))))
+ continue;
+
+ modifiers = realloc(modifiers,
+ (count_valid_modifiers + 1) *
+ sizeof(*modifiers));
+ if (!modifiers)
+ goto err_allocs;
+
+ modifiers[count_valid_modifiers++] = mod->modifier;
+ }
+
+ /* Couldn't find valid modifiers, fallback to use linear */
+ if (count_valid_modifiers == 0) {
+ modifiers = drmMalloc(sizeof(*modifiers));
+ if (!modifiers)
+ goto err_allocs;
+
+ *modifiers = 0; /* as DRM_FORMAT_MOD_LINEAR */
+ count_valid_modifiers = 1;
+ }
+
+ /* If realloc fails, in order to free all previoulsy allocated
+ * modifiers, always update drm_mode_fmt->count.
+ */
+ drm_mode_fmt->count++;
+ drm_mode_fmt->formats[i].format = blob_formats[i];
+ drm_mode_fmt->formats[i].modifiers = modifiers;
+ drm_mode_fmt->formats[i].count_modifiers = count_valid_modifiers;
+ }
+
+ *out_formats = drm_mode_fmt;
+ return 0;
+
+err_allocs:
+ drmModeFreeFormats(drm_mode_fmt);
+ return -errno;
+}
+
drm_public void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
{
if (!ptr)
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 5449320..76e77df 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -334,6 +334,15 @@ typedef struct _drmModeObjectProperties {
uint64_t *prop_values;
} drmModeObjectProperties, *drmModeObjectPropertiesPtr;
+typedef struct _drmModeFormats {
+ uint32_t count;
+ struct {
+ uint32_t format;
+ uint32_t count_modifiers;
+ uint64_t *modifiers;
+ } formats[1];
+} drmModeFormats, *drmModeFormatsPtr;
+
typedef struct _drmModePlane {
uint32_t count_formats;
uint32_t *formats;
@@ -484,6 +493,9 @@ extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
extern void drmModeFreeProperty(drmModePropertyPtr ptr);
extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
+extern int drmModePopulateFormats(drmModePropertyBlobPtr ptr,
+ drmModeFormatsPtr *out_formats);
+extern void drmModeFreeFormats(drmModeFormatsPtr ptr);
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
uint64_t value);
--
2.7.4
@@ -0,0 +1,148 @@
From a12e3b4490c182ed506f59eda01f1bd0919720f1 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 9 Mar 2020 14:52:17 +0000
Subject: [PATCH 6/6] Add sync_file_info and sync_get_fence_info
For pre-4.7 kernels, sync_file_info calls the SYNC_IOC_FENCE_INFO ioctl,
and converts the data to SYNC_IOC_FILE_INFO form. For newer kernels,
sync_file_info returns data from the SYNC_IOC_FILE_INFO ioctl.
This patch depends on patch "Add sync_fence_info and sync_pt_info",
which added legacy sync info support, using the structure and ioctl
definitions at the top of the patch, as well as the sync_pt_info
function.
---
libsync.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/libsync.h b/libsync.h
index 44f7330..54acb6f 100644
--- a/libsync.h
+++ b/libsync.h
@@ -351,6 +351,123 @@ static inline void sync_fence_info_free(struct sync_fence_info_data *info)
{
free(info);
}
+
+static inline struct sync_fence_info *sync_get_fence_info(
+ struct sync_file_info *file_info)
+{
+ return (struct sync_fence_info *)(uintptr_t)file_info->sync_fence_info;
+}
+
+static inline struct sync_file_info *file_info_from_info_data(
+ struct sync_fence_info_data *info)
+{
+ struct sync_pt_info *pt_info = NULL;
+ uint32_t num_fences = 0;
+ struct sync_file_info *file_info;
+ struct sync_fence_info *fence_info;
+ uint32_t i;
+
+ while ((pt_info = sync_pt_info(info, pt_info)) != NULL)
+ num_fences++;
+
+ file_info = calloc(1, sizeof(*file_info) + num_fences *
+ sizeof(*fence_info));
+ if (!file_info)
+ return NULL;
+
+ strncpy(file_info->name, info->name, sizeof(file_info->name));
+ file_info->status = info->status;
+ file_info->num_fences = num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ fence_info = sync_get_fence_info(file_info);
+ for (i = 0; i < num_fences; i++) {
+ pt_info = sync_pt_info(info, pt_info);
+ assert(pt_info);
+
+ strncpy(fence_info->obj_name, pt_info->obj_name,
+ sizeof(fence_info->obj_name));
+ strncpy(fence_info->driver_name, pt_info->driver_name,
+ sizeof(fence_info->driver_name));
+ fence_info->status = pt_info->status;
+ fence_info->timestamp_ns = pt_info->timestamp_ns;
+
+ fence_info++;
+ }
+
+ return file_info;
+}
+
+static inline struct sync_file_info *sync_legacy_file_info(int fd)
+{
+ const uint32_t len = 4096;
+ struct sync_fence_info_data *info = malloc(len);
+ struct sync_file_info *file_info;
+ int ret;
+
+ if (!info)
+ return NULL;
+
+ info->len = len;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ free(info);
+ return NULL;
+ }
+
+ file_info = file_info_from_info_data(info);
+
+ free(info);
+
+ return file_info;
+}
+
+static inline void sync_file_info_free(struct sync_file_info *file_info)
+{
+ free(file_info);
+}
+
+static inline struct sync_file_info *sync_file_info(int fd)
+{
+ struct sync_file_info initial_info = {""};
+ struct sync_file_info *file_info;
+ int ret;
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ if (errno == ENOTTY)
+ return sync_legacy_file_info(fd);
+ else
+ return NULL;
+ }
+
+ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences *
+ sizeof(struct sync_fence_info));
+ if (!file_info)
+ return NULL;
+
+ file_info->num_fences = initial_info.num_fences;
+ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1);
+
+ do {
+ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret < 0) {
+ sync_file_info_free(file_info);
+ return NULL;
+ }
+
+ return file_info;
+}
+
#if defined(__cplusplus)
}
#endif
--
2.7.4