Commit 9c37bf2d authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/drm-misc-2015-05-19' of git://anongit.freedesktop.org/drm-intel into drm-next

Scattering of random drm core patches. Bunch of atomic prep work too, but
the final bits for blob properties, atomic modesets and lifting the
experimental tag on the atomic ioctl are still blocked on Daniel Stone
finalizing and testing the weston support for it. I hope that we can get
it all ready for 4.2 though.

* tag 'topic/drm-misc-2015-05-19' of git://anongit.freedesktop.org/drm-intel: (22 commits)
  drm/atomic: Allow drivers to subclass drm_atomic_state, v3
  drm/atomic: remove duplicated assignment of old_plane_state
  drm/dp: Fix comment in DP helper
  drm/atomic: add drm_atomic_get_existing_*_state helpers
  drm/core: get rid of -Iinclude/drm
  drm/i915: get rid of -Iinclude/drm
  drm/atomic-helpers: Export drm_atomic_helper_update_legacy_modeset_state
  drm/atomic-helpers: Update vblank timestamping constants
  drm/sysfs: remove unnecessary connector type checks
  drm/sysfs: split DVI-I and TV-out attributes
  drm/sysfs: make optional attribute groups per connector type
  drm/sysfs: add a helper for extracting connector type from kobject
  drm/edid: Add CEA modes before inferred modes
  drm/prime: Allow internal imports without import_sg_table
  drm: Add reference counting to blob properties
  drm: Introduce blob_lock
  drm: Introduce helper for replacing blob properties
  drm: Don't leak path blob property when updating
  drm/atomic: Don't open-code CRTC state destroy
  drm/edid: Add DMT modes with ID > 0x50
  ...
parents d0093404 036ef573
......@@ -2,8 +2,6 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_context.o drm_dma.o \
drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
......
......@@ -30,7 +30,15 @@
#include <drm/drm_atomic.h>
#include <drm/drm_plane_helper.h>
static void kfree_state(struct drm_atomic_state *state)
/**
* drm_atomic_state_default_release -
* release memory initialized by drm_atomic_state_init
* @state: atomic state
*
* Free all the memory allocated by drm_atomic_state_init.
* This is useful for drivers that subclass the atomic state.
*/
void drm_atomic_state_default_release(struct drm_atomic_state *state)
{
kfree(state->connectors);
kfree(state->connector_states);
......@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)
kfree(state->crtc_states);
kfree(state->planes);
kfree(state->plane_states);
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_state_default_release);
/**
* drm_atomic_state_alloc - allocate atomic state
* drm_atomic_state_init - init new atomic state
* @dev: DRM device
* @state: atomic state
*
* This allocates an empty atomic state to track updates.
* Default implementation for filling in a new atomic state.
* This is useful for drivers that subclass the atomic state.
*/
struct drm_atomic_state *
drm_atomic_state_alloc(struct drm_device *dev)
int
drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
{
struct drm_atomic_state *state;
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
/* TODO legacy paths should maybe do a better job about
* setting this appropriately?
*/
......@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev)
state->dev = dev;
DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state);
DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
return state;
return 0;
fail:
kfree_state(state);
drm_atomic_state_default_release(state);
return -ENOMEM;
}
EXPORT_SYMBOL(drm_atomic_state_init);
/**
* drm_atomic_state_alloc - allocate atomic state
* @dev: DRM device
*
* This allocates an empty atomic state to track updates.
*/
struct drm_atomic_state *
drm_atomic_state_alloc(struct drm_device *dev)
{
struct drm_mode_config *config = &dev->mode_config;
struct drm_atomic_state *state;
return NULL;
if (!config->funcs->atomic_state_alloc) {
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
if (drm_atomic_state_init(dev, state) < 0) {
kfree(state);
return NULL;
}
return state;
}
return config->funcs->atomic_state_alloc(dev);
}
EXPORT_SYMBOL(drm_atomic_state_alloc);
/**
* drm_atomic_state_clear - clear state object
* drm_atomic_state_default_clear - clear base atomic state
* @state: atomic state
*
* When the w/w mutex algorithm detects a deadlock we need to back off and drop
* all locks. So someone else could sneak in and change the current modeset
* configuration. Which means that all the state assembled in @state is no
* longer an atomic update to the current state, but to some arbitrary earlier
* state. Which could break assumptions the driver's ->atomic_check likely
* relies on.
*
* Hence we must clear all cached state and completely start over, using this
* function.
* Default implementation for clearing atomic state.
* This is useful for drivers that subclass the atomic state.
*/
void drm_atomic_state_clear(struct drm_atomic_state *state)
void drm_atomic_state_default_clear(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_mode_config *config = &dev->mode_config;
......@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
state->plane_states[i] = NULL;
}
}
EXPORT_SYMBOL(drm_atomic_state_default_clear);
/**
* drm_atomic_state_clear - clear state object
* @state: atomic state
*
* When the w/w mutex algorithm detects a deadlock we need to back off and drop
* all locks. So someone else could sneak in and change the current modeset
* configuration. Which means that all the state assembled in @state is no
* longer an atomic update to the current state, but to some arbitrary earlier
* state. Which could break assumptions the driver's ->atomic_check likely
* relies on.
*
* Hence we must clear all cached state and completely start over, using this
* function.
*/
void drm_atomic_state_clear(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_mode_config *config = &dev->mode_config;
if (config->funcs->atomic_state_clear)
config->funcs->atomic_state_clear(state);
else
drm_atomic_state_default_clear(state);
}
EXPORT_SYMBOL(drm_atomic_state_clear);
/**
......@@ -173,14 +222,25 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
*/
void drm_atomic_state_free(struct drm_atomic_state *state)
{
struct drm_device *dev;
struct drm_mode_config *config;
if (!state)
return;
dev = state->dev;
config = &dev->mode_config;
drm_atomic_state_clear(state);
DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
kfree_state(state);
if (config->funcs->atomic_state_free) {
config->funcs->atomic_state_free(state);
} else {
drm_atomic_state_default_release(state);
kfree(state);
}
}
EXPORT_SYMBOL(drm_atomic_state_free);
......@@ -203,13 +263,12 @@ struct drm_crtc_state *
drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc)
{
int ret, index;
int ret, index = drm_crtc_index(crtc);
struct drm_crtc_state *crtc_state;
index = drm_crtc_index(crtc);
if (state->crtc_states[index])
return state->crtc_states[index];
crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
if (crtc_state)
return crtc_state;
ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
if (ret)
......@@ -337,13 +396,12 @@ struct drm_plane_state *
drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane)
{
int ret, index;
int ret, index = drm_plane_index(plane);
struct drm_plane_state *plane_state;
index = drm_plane_index(plane);
if (state->plane_states[index])
return state->plane_states[index];
plane_state = drm_atomic_get_existing_plane_state(state, plane);
if (plane_state)
return plane_state;
ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
if (ret)
......
......@@ -624,8 +624,22 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
}
}
static void
set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state)
/**
* drm_atomic_helper_update_legacy_modeset_state - update legacy modeset state
* @dev: DRM device
* @old_state: atomic state object with old state structures
*
* This function updates all the various legacy modeset state pointers in
* connectors, encoders and crtcs. It also updates the timestamping constants
* used for precise vblank timestamps by calling
* drm_calc_timestamping_constants().
*
* Drivers can use this for building their own atomic commit if they don't have
* a pure helper-based modeset implementation.
*/
void
drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
struct drm_connector *connector;
struct drm_connector_state *old_conn_state;
......@@ -662,8 +676,13 @@ set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state)
crtc->enabled = crtc->state->enable;
crtc->x = crtc->primary->state->src_x >> 16;
crtc->y = crtc->primary->state->src_y >> 16;
if (crtc->state->enable)
drm_calc_timestamping_constants(crtc,
&crtc->state->adjusted_mode);
}
}
EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
static void
crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
......@@ -742,7 +761,9 @@ void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
disable_outputs(dev, old_state);
set_routing_links(dev, old_state);
drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
crtc_set_mode(dev, old_state);
}
EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
......@@ -1135,8 +1156,6 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (!funcs)
continue;
old_plane_state = old_state->plane_states[i];
/*
* Special-case disabling the plane if drivers support it.
*/
......
This diff is collapsed.
......@@ -959,7 +959,12 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
if (crtc_funcs->atomic_check) {
ret = crtc_funcs->atomic_check(crtc, crtc_state);
if (ret) {
kfree(crtc_state);
if (crtc->funcs->atomic_destroy_state) {
crtc->funcs->atomic_destroy_state(crtc,
crtc_state);
} else {
kfree(crtc_state);
}
return ret;
}
......
This diff is collapsed.
......@@ -21,8 +21,8 @@
* SOFTWARE.
*/
#include "drmP.h"
#include "drm_flip_work.h"
#include <drm/drmP.h>
#include <drm/drm_flip_work.h>
/**
* drm_flip_work_allocate_task - allocate a flip-work task
......
......@@ -502,9 +502,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
struct drm_gem_object *obj;
int ret;
if (!dev->driver->gem_prime_import_sg_table)
return ERR_PTR(-EINVAL);
if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
obj = dma_buf->priv;
if (obj->dev == dev) {
......@@ -517,6 +514,9 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
}
}
if (!dev->driver->gem_prime_import_sg_table)
return ERR_PTR(-EINVAL);
attach = dma_buf_attach(dma_buf, dev->dev);
if (IS_ERR(attach))
return ERR_CAST(attach);
......
......@@ -302,35 +302,43 @@ static ssize_t modes_show(struct device *device,
return written;
}
static ssize_t subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
static ssize_t tv_subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev;
struct drm_property *prop = NULL;
struct drm_property *prop;
uint64_t subconnector;
int is_tv = 0;
int ret;
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
prop = dev->mode_config.dvi_i_subconnector_property;
break;
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
prop = dev->mode_config.tv_subconnector_property;
is_tv = 1;
break;
default:
DRM_ERROR("Wrong connector type for this property\n");
return 0;
prop = dev->mode_config.tv_subconnector_property;
if (!prop) {
DRM_ERROR("Unable to find subconnector property\n");
return 0;
}
ret = drm_object_property_get_value(&connector->base, prop, &subconnector);
if (ret)
return 0;
return snprintf(buf, PAGE_SIZE, "%s",
drm_get_tv_subconnector_name((int)subconnector));
}
static ssize_t tv_select_subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev;
struct drm_property *prop;
uint64_t subconnector;
int ret;
prop = dev->mode_config.tv_select_subconnector_property;
if (!prop) {
DRM_ERROR("Unable to find subconnector property\n");
DRM_ERROR("Unable to find select subconnector property\n");
return 0;
}
......@@ -338,38 +346,45 @@ static ssize_t subconnector_show(struct device *device,
if (ret)
return 0;
return snprintf(buf, PAGE_SIZE, "%s", is_tv ?
drm_get_tv_subconnector_name((int)subconnector) :
drm_get_dvi_i_subconnector_name((int)subconnector));
return snprintf(buf, PAGE_SIZE, "%s",
drm_get_tv_select_name((int)subconnector));
}
static ssize_t select_subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
static ssize_t dvii_subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev;
struct drm_property *prop = NULL;
struct drm_property *prop;
uint64_t subconnector;
int is_tv = 0;
int ret;
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
prop = dev->mode_config.dvi_i_select_subconnector_property;
break;
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
prop = dev->mode_config.tv_select_subconnector_property;
is_tv = 1;
break;
default:
DRM_ERROR("Wrong connector type for this property\n");
return 0;
prop = dev->mode_config.dvi_i_subconnector_property;
if (!prop) {
DRM_ERROR("Unable to find subconnector property\n");
return 0;
}
ret = drm_object_property_get_value(&connector->base, prop, &subconnector);
if (ret)
return 0;
return snprintf(buf, PAGE_SIZE, "%s",
drm_get_dvi_i_subconnector_name((int)subconnector));
}
static ssize_t dvii_select_subconnector_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev;
struct drm_property *prop;
uint64_t subconnector;
int ret;
prop = dev->mode_config.dvi_i_select_subconnector_property;
if (!prop) {
DRM_ERROR("Unable to find select subconnector property\n");
return 0;
......@@ -379,8 +394,7 @@ static ssize_t select_subconnector_show(struct device *device,
if (ret)
return 0;
return snprintf(buf, PAGE_SIZE, "%s", is_tv ?
drm_get_tv_select_name((int)subconnector) :
return snprintf(buf, PAGE_SIZE, "%s",
drm_get_dvi_i_select_name((int)subconnector));
}
......@@ -397,28 +411,44 @@ static struct attribute *connector_dev_attrs[] = {
NULL
};
/* These attributes are for both DVI-I connectors and all types of tv-out. */
static DEVICE_ATTR_RO(subconnector);
static DEVICE_ATTR_RO(select_subconnector);
static DEVICE_ATTR_RO(tv_subconnector);
static DEVICE_ATTR_RO(tv_select_subconnector);
static struct attribute *connector_opt_dev_attrs[] = {
&dev_attr_subconnector.attr,
&dev_attr_select_subconnector.attr,
static struct attribute *connector_tv_dev_attrs[] = {
&dev_attr_tv_subconnector.attr,
&dev_attr_tv_select_subconnector.attr,
NULL
};
static umode_t connector_opt_dev_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
static DEVICE_ATTR_RO(dvii_subconnector);
static DEVICE_ATTR_RO(dvii_select_subconnector);
static struct attribute *connector_dvii_dev_attrs[] = {
&dev_attr_dvii_subconnector.attr,
&dev_attr_dvii_select_subconnector.attr,
NULL
};
/* Connector type related helpers */
static int kobj_connector_type(struct kobject *kobj)
{
struct device *dev = kobj_to_dev(kobj);
struct drm_connector *connector = to_drm_connector(dev);
/*
* In the long run it maybe a good idea to make one set of
* optionals per connector type.
*/
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
return connector->connector_type;
}
static umode_t connector_is_dvii(struct kobject *kobj,
struct attribute *attr, int idx)
{
return kobj_connector_type(kobj) == DRM_MODE_CONNECTOR_DVII ?
attr->mode : 0;
}
static umode_t connector_is_tv(struct kobject *kobj,
struct attribute *attr, int idx)
{
switch (kobj_connector_type(kobj)) {
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
......@@ -446,14 +476,20 @@ static const struct attribute_group connector_dev_group = {
.bin_attrs = connector_bin_attrs,
};
static const struct attribute_group connector_opt_dev_group = {
.attrs = connector_opt_dev_attrs,
.is_visible = connector_opt_dev_is_visible,
static const struct attribute_group connector_tv_dev_group = {
.attrs = connector_tv_dev_attrs,
.is_visible = connector_is_tv,
};
static const struct attribute_group connector_dvii_dev_group = {
.attrs = connector_dvii_dev_attrs,
.is_visible = connector_is_dvii,
};
static const struct attribute_group *connector_dev_groups[] = {
&connector_dev_group,
&connector_opt_dev_group,
&connector_tv_dev_group,
&connector_dvii_dev_group,
NULL
};
......
......@@ -2,8 +2,6 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
# Please keep these build lists sorted!
# core driver code
......
......@@ -22,8 +22,8 @@
*
*/
#include "drmP.h"
#include "i915_drm.h"
#include <drm/drmP.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
......
......@@ -35,6 +35,11 @@ drm_atomic_state_alloc(struct drm_device *dev);
void drm_atomic_state_clear(struct drm_atomic_state *state);
void drm_atomic_state_free(struct drm_atomic_state *state);
int __must_check
drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state);
void drm_atomic_state_default_clear(struct drm_atomic_state *state);
void drm_atomic_state_default_release(struct drm_atomic_state *state);
struct drm_crtc_state * __must_check
drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc);
......@@ -54,6 +59,56 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_connector_state *state, struct drm_property *property,
uint64_t val);
/**
* drm_atomic_get_existing_crtc_state - get crtc state, if it exists
* @state: global atomic state object
* @crtc: crtc to grab
*
* This function returns the crtc state for the given crtc, or NULL
* if the crtc is not part of the global atomic state.
*/
static inline struct drm_crtc_state *
drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc)
{
return state->crtc_states[drm_crtc_index(crtc)];
}
/**
* drm_atomic_get_existing_plane_state - get plane state, if it exists
* @state: global atomic state object
* @plane: plane to grab
*
* This function returns the plane state for the given plane, or NULL
* if the plane is not part of the global atomic state.
*/
static inline struct drm_plane_state *
drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane)
{
return state->plane_states[drm_plane_index(plane)];
}
/**
* drm_atomic_get_existing_connector_state - get connector state, if it exists
* @state: global atomic state object
* @connector: connector to grab
*
* This function returns the connector state for the given connector,
* or NULL if the connector is not part of the global atomic state.
*/
static inline struct drm_connector_state *
drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector)
{
int index = drm_connector_index(connector);
if (index >= state->num_connector)
return NULL;
return state->connector_states[index];
}
int __must_check
drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
struct drm_crtc *crtc);
......
......@@ -43,6 +43,10 @@ int drm_atomic_helper_commit(struct drm_device *dev,
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
struct drm_atomic_state *old_state);
void
drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
struct drm_atomic_state *old_state);
void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
......
......@@ -216,6 +216,8 @@ struct drm_framebuffer {
struct drm_property_blob {
struct drm_mode_object base;
struct drm_device *dev;
struct kref refcount;
struct list_head head;
size_t length;
unsigned char data[];
......@@ -983,6 +985,9 @@ struct drm_mode_set {
* @atomic_check: check whether a given atomic state update is possible
* @atomic_commit: commit an atomic state update previously verified with
* atomic_check()
* @atomic_state_alloc: allocate a new atomic state
* @atomic_state_clear: clear the atomic state
* @atomic_state_free: free the atomic state
*
* Some global (i.e. not per-CRTC, connector, etc) mode setting functions that
* involve drivers.
......@@ -998,6 +1003,9 @@ struct drm_mode_config_funcs {
int (*atomic_commit)(struct drm_device *dev,
struct drm_atomic_state *a,
bool async);
struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev);
void (*atomic_state_clear)(struct drm_atomic_state *state);
void (*atomic_state_free)(struct drm_atomic_state *state);
};
/**
......@@ -1054,6 +1062,7 @@ struct drm_mode_group {
* @poll_running: track polling status for this device
* @output_poll_work: delayed work for polling in process context
* @property_blob_list: list of all the blob property objects
* @blob_lock: mutex for blob property allocation and management
* @*_property: core property tracking
* @preferred_depth: preferred RBG pixel depth, used by fb helpers
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering
......@@ -1109,6 +1118,8 @@ struct drm_mode_config {
bool delayed_event;
struct delayed_work output_poll_work;
struct mutex blob_lock;
/* pointers to standard properties */
struct list_head property_blob_list;
struct drm_property *edid_property;
......@@ -1369,6 +1380,13 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
int flags, const char *name, uint32_t type);
struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
const char *name);
struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
size_t length,
const void *data);
struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
uint32_t id);
struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
void drm_property_unreference_blob(struct drm_property_blob *blob);
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
extern int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name);
......@@ -1533,14 +1551,6 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev,
return mo ? obj_to_property(mo) : NULL;
}
static inline struct drm_property_blob *
drm_property_blob_find(struct drm_device *dev, uint32_t id)
{
struct drm_mode_object *mo;
mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
return mo ? obj_to_blob(mo) : NULL;
}
/* Plane list iterator for legacy (overlay only) planes. */
#define drm_for_each_legacy_plane(plane, planelist) \
list_for_each_entry(plane, planelist, head) \
......
......@@ -679,9 +679,9 @@ struct drm_dp_aux_msg {
* An AUX channel can also be used to transport I2C messages to a sink. A
* typical application of that is to access an EDID that's present in the
* sink device. The .transfer() function can also be used to execute such
* transactions. The drm_dp_aux_register_i2c_bus() function registers an
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
* should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
* transactions. The drm_dp_aux_register() function registers an I2C
* adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
* should call drm_dp_aux_unregister() to remove the I2C adapter.
* The I2C adapter uses long transfers by default; if a partial response is
* received, the adapter will drop down to the size given by the partial
* response for this transaction only.
......
Markdown is supported
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