mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-29 01:00:13 +01:00
add property blobs and edid reporting support
This commit is contained in:
parent
c9cda51af5
commit
67f6eb1eb8
9 changed files with 134 additions and 18 deletions
|
|
@ -470,3 +470,44 @@ void drmModeFreeProperty(drmModePropertyPtr ptr)
|
|||
drmFree(ptr->enums);
|
||||
drmFree(ptr);
|
||||
}
|
||||
|
||||
drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
|
||||
{
|
||||
struct drm_mode_get_blob blob;
|
||||
drmModePropertyBlobPtr r;
|
||||
|
||||
blob.length = 0;
|
||||
blob.data = 0;
|
||||
blob.blob_id = blob_id;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
|
||||
return NULL;
|
||||
|
||||
if (blob.length)
|
||||
blob.data = VOID2U64(drmMalloc(blob.length));
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
|
||||
r = NULL;
|
||||
goto err_allocs;
|
||||
}
|
||||
|
||||
if (!(r = drmMalloc(sizeof(*r))))
|
||||
return NULL;
|
||||
|
||||
r->id = blob.blob_id;
|
||||
r->length = blob.length;
|
||||
r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length);
|
||||
|
||||
err_allocs:
|
||||
drmFree(U642VOID(blob.data));
|
||||
return r;
|
||||
}
|
||||
|
||||
void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
drmFree(ptr->data);
|
||||
drmFree(ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,3 +220,6 @@ extern int drmModeDetachMode(int fd, uint32_t outputId, struct drm_mode_modeinfo
|
|||
|
||||
extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
|
||||
extern void drmModeFreeProperty(drmModePropertyPtr ptr);
|
||||
|
||||
extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
|
||||
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
|
||||
|
|
|
|||
|
|
@ -590,6 +590,8 @@ struct drm_output *drm_output_create(struct drm_device *dev,
|
|||
list_add_tail(&output->head, &dev->mode_config.output_list);
|
||||
dev->mode_config.num_output++;
|
||||
|
||||
drm_output_attach_property(output, dev->mode_config.edid_property, 0);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
return output;
|
||||
|
|
@ -1935,7 +1937,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_property_destroy);
|
||||
|
||||
|
||||
int drm_output_attach_property(struct drm_output *output,
|
||||
struct drm_property *property, uint64_t init_val)
|
||||
{
|
||||
|
|
@ -1955,6 +1956,24 @@ int drm_output_attach_property(struct drm_output *output,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_output_attach_property);
|
||||
|
||||
int drm_output_property_set_value(struct drm_output *output,
|
||||
struct drm_property *property, uint64_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
|
||||
if (output->property_ids[i] == property->id) {
|
||||
output->property_values[i] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == DRM_OUTPUT_MAX_PROPERTY)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_output_property_set_value);
|
||||
|
||||
int drm_mode_getproperty_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
|
|
@ -2052,17 +2071,17 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int drm_property_create_blob(struct drm_device *dev, int length,
|
||||
void *data)
|
||||
static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
|
||||
void *data)
|
||||
{
|
||||
struct drm_property_blob *blob;
|
||||
|
||||
if (!length || !data)
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
|
||||
blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
|
||||
if (!blob)
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
|
||||
blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
|
||||
blob->length = length;
|
||||
|
|
@ -2072,7 +2091,7 @@ static int drm_property_create_blob(struct drm_device *dev, int length,
|
|||
blob->id = drm_idr_get(dev, blob);
|
||||
|
||||
list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
|
||||
return blob->id;
|
||||
return blob;
|
||||
}
|
||||
|
||||
static void drm_property_destroy_blob(struct drm_device *dev,
|
||||
|
|
@ -2082,3 +2101,47 @@ static void drm_property_destroy_blob(struct drm_device *dev,
|
|||
list_del(&blob->head);
|
||||
kfree(blob);
|
||||
}
|
||||
|
||||
int drm_mode_getblob_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_mode_get_blob *out_resp = data;
|
||||
struct drm_property_blob *blob;
|
||||
int ret = 0;
|
||||
void *blob_ptr;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
blob = idr_find(&dev->mode_config.crtc_idr, out_resp->blob_id);
|
||||
if (!blob || (blob->id != out_resp->blob_id)) {
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (out_resp->length == blob->length) {
|
||||
blob_ptr = (void *)(unsigned long)out_resp->data;
|
||||
if (copy_to_user(blob_ptr, blob->data, blob->length)){
|
||||
ret = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
out_resp->length = blob->length;
|
||||
|
||||
done:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_mode_output_update_edid_property(struct drm_output *output, unsigned char *edid)
|
||||
{
|
||||
struct drm_device *dev = output->dev;
|
||||
int ret = 0;
|
||||
if (output->edid_blob_ptr)
|
||||
drm_property_destroy_blob(dev, output->edid_blob_ptr);
|
||||
|
||||
output->edid_blob_ptr = drm_property_create_blob(output->dev, 128, edid);
|
||||
|
||||
ret = drm_output_property_set_value(output, dev->mode_config.edid_property, output->edid_blob_ptr->id);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_output_update_edid_property);
|
||||
|
|
|
|||
|
|
@ -236,8 +236,8 @@ struct drm_framebuffer {
|
|||
|
||||
struct drm_property_blob {
|
||||
struct list_head head;
|
||||
unsigned int id;
|
||||
unsigned int length;
|
||||
unsigned int id;
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
|
@ -456,7 +456,7 @@ struct drm_output {
|
|||
void *driver_private;
|
||||
|
||||
struct list_head user_modes;
|
||||
|
||||
struct drm_property_blob *edid_blob_ptr;
|
||||
u32 property_ids[DRM_OUTPUT_MAX_PROPERTY];
|
||||
uint64_t property_values[DRM_OUTPUT_MAX_PROPERTY];
|
||||
};
|
||||
|
|
@ -547,7 +547,7 @@ extern int drm_mode_vrefresh(struct drm_display_mode *mode);
|
|||
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
|
||||
int adjust_flags);
|
||||
extern void drm_mode_output_list_update(struct drm_output *output);
|
||||
|
||||
extern int drm_mode_output_update_edid_property(struct drm_output *output, unsigned char *edid);
|
||||
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
|
||||
extern bool drm_initial_config(struct drm_device *dev, bool cangrow);
|
||||
extern void drm_framebuffer_set_object(struct drm_device *dev,
|
||||
|
|
@ -594,5 +594,7 @@ extern int drm_mode_detachmode_ioctl(struct drm_device *dev,
|
|||
|
||||
extern int drm_mode_getproperty_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_getblob_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
#endif /* __DRM_CRTC_H__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY),
|
||||
|
|
|
|||
|
|
@ -246,5 +246,4 @@ void intel_crt_init(struct drm_device *dev)
|
|||
output->interlace_allowed = 0;
|
||||
output->doublescan_allowed = 0;
|
||||
|
||||
drm_output_attach_property(output, dev->mode_config.edid_property, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ int intel_ddc_get_modes(struct drm_output *output)
|
|||
|
||||
edid = drm_get_edid(output, &intel_output->ddc_bus->adapter);
|
||||
if (edid) {
|
||||
drm_mode_output_update_edid_property(output, edid);
|
||||
ret = drm_add_edid_modes(output, edid);
|
||||
kfree(edid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -980,11 +980,6 @@ struct drm_mode_property_enum {
|
|||
unsigned char name[DRM_PROP_NAME_LEN];
|
||||
};
|
||||
|
||||
struct drm_mode_property_blob {
|
||||
uint64_t data_ptr;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct drm_mode_get_property {
|
||||
uint64_t values_ptr; /* values and blob lengths */
|
||||
uint64_t enum_blob_ptr; /* enum and blob id ptrs */
|
||||
|
|
@ -997,6 +992,12 @@ struct drm_mode_get_property {
|
|||
int count_enum_blobs;
|
||||
};
|
||||
|
||||
struct drm_mode_get_blob {
|
||||
uint32_t blob_id;
|
||||
uint32_t length;
|
||||
uint64_t data;
|
||||
};
|
||||
|
||||
struct drm_mode_fb_cmd {
|
||||
unsigned int buffer_id;
|
||||
unsigned int width, height;
|
||||
|
|
@ -1111,7 +1112,7 @@ struct drm_mode_mode_cmd {
|
|||
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int)
|
||||
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
|
||||
|
||||
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_propblob)
|
||||
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_blob)
|
||||
#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
|
||||
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
|
||||
|
||||
|
|
|
|||
|
|
@ -75,9 +75,14 @@ int printOutput(int fd, drmModeResPtr res, drmModeOutputPtr output, uint32_t id)
|
|||
printf("%d ", props->values[j]);
|
||||
|
||||
printf("\n\tenums %d: \n", props->count_enums);
|
||||
|
||||
if (props->flags & DRM_MODE_PROP_BLOB) {
|
||||
drmModePropertyBlobPtr blob;
|
||||
|
||||
if (prop->flags & DRM_MODE_PROP_BLOB) {
|
||||
|
||||
blob = drmModeGetPropertyBlob(fd, output->prop_values[i]);
|
||||
|
||||
printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data);
|
||||
drmModeFreePropertyBlob(blob);
|
||||
|
||||
} else {
|
||||
for (j = 0; j < props->count_enums; j++) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue