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 @@ ...@@ -2,8 +2,6 @@
# Makefile for the drm device driver. This driver provides support for the # Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # 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-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_context.o drm_dma.o \ drm_context.o drm_dma.o \
drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
......
...@@ -30,7 +30,15 @@ ...@@ -30,7 +30,15 @@
#include <drm/drm_atomic.h> #include <drm/drm_atomic.h>
#include <drm/drm_plane_helper.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->connectors);
kfree(state->connector_states); kfree(state->connector_states);
...@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state) ...@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)
kfree(state->crtc_states); kfree(state->crtc_states);
kfree(state->planes); kfree(state->planes);
kfree(state->plane_states); 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 * @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 * int
drm_atomic_state_alloc(struct drm_device *dev) 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 /* TODO legacy paths should maybe do a better job about
* setting this appropriately? * setting this appropriately?
*/ */
...@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev) ...@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev)
state->dev = 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: 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); 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 * @state: atomic state
* *
* When the w/w mutex algorithm detects a deadlock we need to back off and drop * Default implementation for clearing atomic state.
* all locks. So someone else could sneak in and change the current modeset * This is useful for drivers that subclass the atomic state.
* 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) void drm_atomic_state_default_clear(struct drm_atomic_state *state)
{ {
struct drm_device *dev = state->dev; struct drm_device *dev = state->dev;
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
...@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) ...@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
state->plane_states[i] = NULL; 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); EXPORT_SYMBOL(drm_atomic_state_clear);
/** /**
...@@ -173,14 +222,25 @@ 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) void drm_atomic_state_free(struct drm_atomic_state *state)
{ {
struct drm_device *dev;
struct drm_mode_config *config;
if (!state) if (!state)
return; return;
dev = state->dev;
config = &dev->mode_config;
drm_atomic_state_clear(state); drm_atomic_state_clear(state);
DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", 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); EXPORT_SYMBOL(drm_atomic_state_free);
...@@ -203,13 +263,12 @@ struct drm_crtc_state * ...@@ -203,13 +263,12 @@ struct drm_crtc_state *
drm_atomic_get_crtc_state(struct drm_atomic_state *state, drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc) struct drm_crtc *crtc)
{ {
int ret, index; int ret, index = drm_crtc_index(crtc);
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
index = drm_crtc_index(crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
if (crtc_state)
if (state->crtc_states[index]) return crtc_state;
return state->crtc_states[index];
ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx); ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
if (ret) if (ret)
...@@ -337,13 +396,12 @@ struct drm_plane_state * ...@@ -337,13 +396,12 @@ struct drm_plane_state *
drm_atomic_get_plane_state(struct drm_atomic_state *state, drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane) struct drm_plane *plane)
{ {
int ret, index; int ret, index = drm_plane_index(plane);
struct drm_plane_state *plane_state; struct drm_plane_state *plane_state;
index = drm_plane_index(plane); plane_state = drm_atomic_get_existing_plane_state(state, plane);
if (plane_state)
if (state->plane_states[index]) return plane_state;
return state->plane_states[index];
ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx); ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
if (ret) if (ret)
......
...@@ -624,8 +624,22 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -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 *connector;
struct drm_connector_state *old_conn_state; struct drm_connector_state *old_conn_state;
...@@ -662,8 +676,13 @@ set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -662,8 +676,13 @@ set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state)
crtc->enabled = crtc->state->enable; crtc->enabled = crtc->state->enable;
crtc->x = crtc->primary->state->src_x >> 16; crtc->x = crtc->primary->state->src_x >> 16;
crtc->y = crtc->primary->state->src_y >> 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 static void
crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) 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, ...@@ -742,7 +761,9 @@ void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
disable_outputs(dev, 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); crtc_set_mode(dev, old_state);
} }
EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables); EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
...@@ -1135,8 +1156,6 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1135,8 +1156,6 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (!funcs) if (!funcs)
continue; continue;
old_plane_state = old_state->plane_states[i];
/* /*
* Special-case disabling the plane if drivers support it. * 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 ...@@ -959,7 +959,12 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
if (crtc_funcs->atomic_check) { if (crtc_funcs->atomic_check) {
ret = crtc_funcs->atomic_check(crtc, crtc_state); ret = crtc_funcs->atomic_check(crtc, crtc_state);
if (ret) { 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; return ret;
} }
......
This diff is collapsed.
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include "drmP.h" #include <drm/drmP.h>
#include "drm_flip_work.h" #include <drm/drm_flip_work.h>
/** /**
* drm_flip_work_allocate_task - allocate a flip-work task * 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, ...@@ -502,9 +502,6 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
struct drm_gem_object *obj; struct drm_gem_object *obj;
int ret; int ret;
if (!dev->driver->gem_prime_import_sg_table)
return ERR_PTR(-EINVAL);
if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) { if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
obj = dma_buf->priv; obj = dma_buf->priv;
if (obj->dev == dev) { if (obj->dev == dev) {
...@@ -517,6 +514,9 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *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); attach = dma_buf_attach(dma_buf, dev->dev);
if (IS_ERR(attach)) if (IS_ERR(attach))
return ERR_CAST(attach); return ERR_CAST(attach);
......
...@@ -302,35 +302,43 @@ static ssize_t modes_show(struct device *device, ...@@ -302,35 +302,43 @@ static ssize_t modes_show(struct device *device,
return written; return written;
} }
static ssize_t subconnector_show(struct device *device, static ssize_t tv_subconnector_show(struct device *device,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct drm_connector *connector = to_drm_connector(device); struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_property *prop = NULL; struct drm_property *prop;
uint64_t subconnector; uint64_t subconnector;
int is_tv = 0;
int ret; int ret;
switch (connector->connector_type) { prop = dev->mode_config.tv_subconnector_property;
case DRM_MODE_CONNECTOR_DVII: if (!prop) {
prop = dev->mode_config.dvi_i_subconnector_property; DRM_ERROR("Unable to find subconnector property\n");
break; return 0;
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;
} }
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) { if (!prop) {
DRM_ERROR("Unable to find subconnector property\n"); DRM_ERROR("Unable to find select subconnector property\n");
return 0; return 0;
} }
...@@ -338,38 +346,45 @@ static ssize_t subconnector_show(struct device *device, ...@@ -338,38 +346,45 @@ static ssize_t subconnector_show(struct device *device,
if (ret) if (ret)
return 0; return 0;
return snprintf(buf, PAGE_SIZE, "%s", is_tv ? return snprintf(buf, PAGE_SIZE, "%s",
drm_get_tv_subconnector_name((int)subconnector) : drm_get_tv_select_name((int)subconnector));
drm_get_dvi_i_subconnector_name((int)subconnector));
} }
static ssize_t select_subconnector_show(struct device *device, static ssize_t dvii_subconnector_show(struct device *device,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct drm_connector *connector = to_drm_connector(device); struct drm_connector *connector = to_drm_connector(device);
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_property *prop = NULL; struct drm_property *prop;
uint64_t subconnector; uint64_t subconnector;
int is_tv = 0;
int ret; int ret;
switch (connector->connector_type) { prop = dev->mode_config.dvi_i_subconnector_property;
case DRM_MODE_CONNECTOR_DVII: if (!prop) {
prop = dev->mode_config.dvi_i_select_subconnector_property; DRM_ERROR("Unable to find subconnector property\n");
break; return 0;
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;
} }
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) { if (!prop) {
DRM_ERROR("Unable to find select subconnector property\n"); DRM_ERROR("Unable to find select subconnector property\n");
return 0; return 0;
...@@ -379,8 +394,7 @@ static ssize_t select_subconnector_show(struct device *device, ...@@ -379,8 +394,7 @@ static ssize_t select_subconnector_show(struct device *device,
if (ret) if (ret)
return 0; return 0;
return snprintf(buf, PAGE_SIZE, "%s", is_tv ? return snprintf(buf, PAGE_SIZE, "%s",
drm_get_tv_select_name((int)subconnector) :
drm_get_dvi_i_select_name((int)subconnector)); drm_get_dvi_i_select_name((int)subconnector));
} }
...@@ -397,28 +411,44 @@ static struct attribute *connector_dev_attrs[] = { ...@@ -397,28 +411,44 @@ static struct attribute *connector_dev_attrs[] = {
NULL NULL
}; };
/* These attributes are for both DVI-I connectors and all types of tv-out. */ static DEVICE_ATTR_RO(tv_subconnector);
static DEVICE_ATTR_RO(subconnector); static DEVICE_ATTR_RO(tv_select_subconnector);
static DEVICE_ATTR_RO(select_subconnector);
static struct attribute *connector_opt_dev_attrs[] = { static struct attribute *connector_tv_dev_attrs[] = {
&dev_attr_subconnector.attr, &dev_attr_tv_subconnector.attr,
&dev_attr_select_subconnector.attr, &dev_attr_tv_select_subconnector.attr,
NULL NULL
}; };
static umode_t connector_opt_dev_is_visible(struct kobject *kobj, static DEVICE_ATTR_RO(dvii_subconnector);
struct attribute *attr, int idx) 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 device *dev = kobj_to_dev(kobj);
struct drm_connector *connector = to_drm_connector(dev); struct drm_connector *connector = to_drm_connector(dev);
/* return connector->connector_type;
* In the long run it maybe a good idea to make one set of }
* optionals per connector type.
*/ static umode_t connector_is_dvii(struct kobject *kobj,
switch (connector->connector_type) { struct attribute *attr, int idx)
case DRM_MODE_CONNECTOR_DVII: {
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_Composite:
case DRM_MODE_CONNECTOR_SVIDEO: case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component: case DRM_MODE_CONNECTOR_Component:
...@@ -446,14 +476,20 @@ static const struct attribute_group connector_dev_group = { ...@@ -446,14 +476,20 @@ static const struct attribute_group connector_dev_group = {
.bin_attrs = connector_bin_attrs, .bin_attrs = connector_bin_attrs,
}; };
static const struct attribute_group connector_opt_dev_group = { static const struct attribute_group connector_tv_dev_group = {
.attrs = connector_opt_dev_attrs, .attrs = connector_tv_dev_attrs,
.is_visible = connector_opt_dev_is_visible, .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[] = { static const struct attribute_group *connector_dev_groups[] = {
&connector_dev_group, &connector_dev_group,
&connector_opt_dev_group, &connector_tv_dev_group,
&connector_dvii_dev_group,
NULL NULL
}; };
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
# Makefile for the drm device driver. This driver provides support for the # Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
# Please keep these build lists sorted! # Please keep these build lists sorted!
# core driver code # core driver code
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
* *
*/ */
#include "drmP.h" #include <drm/drmP.h>
#include "i915_drm.h" #include <drm/i915_drm.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h" #include "i915_trace.h"
#include "intel_drv.h" #include "intel_drv.h"
......
...@@ -35,6 +35,11 @@ drm_atomic_state_alloc(struct drm_device *dev); ...@@ -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_clear(struct drm_atomic_state *state);
void drm_atomic_state_free(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 struct drm_crtc_state * __must_check
drm_atomic_get_crtc_state(struct drm_atomic_state *state, drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc); struct drm_crtc *crtc);
...@@ -54,6 +59,56 @@ int drm_atomic_connector_set_property(struct drm_connector *connector, ...@@ -54,6 +59,56 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_connector_state *state, struct drm_property *property, struct drm_connector_state *state, struct drm_property *property,
uint64_t val); 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 int __must_check
drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
struct drm_crtc *crtc); struct drm_crtc *crtc);
......
...@@ -43,6 +43,10 @@ int drm_atomic_helper_commit(struct drm_device *dev, ...@@ -43,6 +43,10 @@ int drm_atomic_helper_commit(struct drm_device *dev,
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
struct drm_atomic_state *old_state); 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, void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
struct drm_atomic_state *state); struct drm_atomic_state *state);
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
......
...@@ -216,6 +216,8 @@ struct drm_framebuffer { ...@@ -216,6 +216,8 @@ struct drm_framebuffer {
struct drm_property_blob { struct drm_property_blob {
struct drm_mode_object base; struct drm_mode_object base;
struct drm_device *dev;
struct kref refcount;
struct list_head head; struct list_head head;
size_t length; size_t length;
unsigned char data[]; unsigned char data[];
...@@ -983,6 +985,9 @@ struct drm_mode_set { ...@@ -983,6 +985,9 @@ struct drm_mode_set {
* @atomic_check: check whether a given atomic state update is possible * @atomic_check: check whether a given atomic state update is possible
* @atomic_commit: commit an atomic state update previously verified with * @atomic_commit: commit an atomic state update previously verified with
* atomic_check() * 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 * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that
* involve drivers. * involve drivers.
...@@ -998,6 +1003,9 @@ struct drm_mode_config_funcs { ...@@ -998,6 +1003,9 @@ struct drm_mode_config_funcs {
int (*atomic_commit)(struct drm_device *dev, int (*atomic_commit)(struct drm_device *dev,
struct drm_atomic_state *a, struct drm_atomic_state *a,
bool async); 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 { ...@@ -1054,6 +1062,7 @@ struct drm_mode_group {
* @poll_running: track polling status for this device * @poll_running: track polling status for this device
* @output_poll_work: delayed work for polling in process context * @output_poll_work: delayed work for polling in process context
* @property_blob_list: list of all the blob property objects * @property_blob_list: list of all the blob property objects
* @blob_lock: mutex for blob property allocation and management
* @*_property: core property tracking * @*_property: core property tracking
* @preferred_depth: preferred RBG pixel depth, used by fb helpers * @preferred_depth: preferred RBG pixel depth, used by fb helpers
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
...@@ -1109,6 +1118,8 @@ struct drm_mode_config { ...@@ -1109,6 +1118,8 @@ struct drm_mode_config {
bool delayed_event; bool delayed_event;
struct delayed_work output_poll_work; struct delayed_work output_poll_work;
struct mutex blob_lock;
/* pointers to standard properties */ /* pointers to standard properties */
struct list_head property_blob_list; struct list_head property_blob_list;
struct drm_property *edid_property; struct drm_property *edid_property;
...@@ -1369,6 +1380,13 @@ struct drm_property *drm_property_create_object(struct drm_device *dev, ...@@ -1369,6 +1380,13 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
int flags, const char *name, uint32_t type); int flags, const char *name, uint32_t type);
struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
const char *name); 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 void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
extern int drm_property_add_enum(struct drm_property *property, int index, extern int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name); uint64_t value, const char *name);
...@@ -1533,14 +1551,6 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev, ...@@ -1533,14 +1551,6 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev,
return mo ? obj_to_property(mo) : NULL; 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. */ /* Plane list iterator for legacy (overlay only) planes. */
#define drm_for_each_legacy_plane(plane, planelist) \ #define drm_for_each_legacy_plane(plane, planelist) \
list_for_each_entry(plane, planelist, head) \ list_for_each_entry(plane, planelist, head) \
......
...@@ -679,9 +679,9 @@ struct drm_dp_aux_msg { ...@@ -679,9 +679,9 @@ struct drm_dp_aux_msg {
* An AUX channel can also be used to transport I2C messages to a sink. A * 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 * 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 * sink device. The .transfer() function can also be used to execute such
* transactions. The drm_dp_aux_register_i2c_bus() function registers an * transactions. The drm_dp_aux_register() function registers an I2C
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers * 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. * should call drm_dp_aux_unregister() to remove the I2C adapter.
* The I2C adapter uses long transfers by default; if a partial response is * 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 * received, the adapter will drop down to the size given by the partial
* response for this transaction only. * 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