45,7 → 45,7 |
|
static struct drm_framebuffer * |
internal_framebuffer_create(struct drm_device *dev, |
struct drm_mode_fb_cmd2 *r, |
const struct drm_mode_fb_cmd2 *r, |
struct drm_file *file_priv); |
|
/* Avoid boilerplate. I'm tired of typing. */ |
649,6 → 649,18 |
|
DEFINE_WW_CLASS(crtc_ww_class); |
|
static unsigned int drm_num_crtcs(struct drm_device *dev) |
{ |
unsigned int num = 0; |
struct drm_crtc *tmp; |
|
drm_for_each_crtc(tmp, dev) { |
num++; |
} |
|
return num; |
} |
|
/** |
* drm_crtc_init_with_planes - Initialise a new CRTC object with |
* specified primary and cursor planes. |
657,6 → 669,7 |
* @primary: Primary plane for CRTC |
* @cursor: Cursor plane for CRTC |
* @funcs: callbacks for the new CRTC |
* @name: printf style format string for the CRTC name, or NULL for default name |
* |
* Inits a new object created as base part of a driver crtc object. |
* |
666,7 → 679,8 |
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, |
struct drm_plane *primary, |
struct drm_plane *cursor, |
const struct drm_crtc_funcs *funcs) |
const struct drm_crtc_funcs *funcs, |
const char *name, ...) |
{ |
struct drm_mode_config *config = &dev->mode_config; |
int ret; |
682,6 → 696,21 |
if (ret) |
return ret; |
|
if (name) { |
va_list ap; |
|
va_start(ap, name); |
crtc->name = kvasprintf(GFP_KERNEL, name, ap); |
va_end(ap); |
} else { |
crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", |
drm_num_crtcs(dev)); |
} |
if (!crtc->name) { |
drm_mode_object_put(dev, &crtc->base); |
return -ENOMEM; |
} |
|
crtc->base.properties = &crtc->properties; |
|
list_add_tail(&crtc->head, &config->crtc_list); |
728,6 → 757,8 |
if (crtc->state && crtc->funcs->atomic_destroy_state) |
crtc->funcs->atomic_destroy_state(crtc, crtc->state); |
|
kfree(crtc->name); |
|
memset(crtc, 0, sizeof(*crtc)); |
} |
EXPORT_SYMBOL(drm_crtc_cleanup); |
887,12 → 918,19 |
connector->base.properties = &connector->properties; |
connector->dev = dev; |
connector->funcs = funcs; |
|
connector->connector_id = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL); |
if (connector->connector_id < 0) { |
ret = connector->connector_id; |
goto out_put; |
} |
|
connector->connector_type = connector_type; |
connector->connector_type_id = |
ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); |
if (connector->connector_type_id < 0) { |
ret = connector->connector_type_id; |
goto out_put; |
goto out_put_id; |
} |
connector->name = |
kasprintf(GFP_KERNEL, "%s-%d", |
900,7 → 938,7 |
connector->connector_type_id); |
if (!connector->name) { |
ret = -ENOMEM; |
goto out_put; |
goto out_put_type_id; |
} |
|
INIT_LIST_HEAD(&connector->probed_modes); |
928,7 → 966,12 |
} |
|
connector->debugfs_entry = NULL; |
|
out_put_type_id: |
if (ret) |
ida_remove(connector_ida, connector->connector_type_id); |
out_put_id: |
if (ret) |
ida_remove(&config->connector_ida, connector->connector_id); |
out_put: |
if (ret) |
drm_mode_object_put(dev, &connector->base); |
965,6 → 1008,9 |
ida_remove(&drm_connector_enum_list[connector->connector_type].ida, |
connector->connector_type_id); |
|
ida_remove(&dev->mode_config.connector_ida, |
connector->connector_id); |
|
kfree(connector->display_info.bus_formats); |
drm_mode_object_put(dev, &connector->base); |
kfree(connector->name); |
982,32 → 1028,6 |
EXPORT_SYMBOL(drm_connector_cleanup); |
|
/** |
* drm_connector_index - find the index of a registered connector |
* @connector: connector to find index for |
* |
* Given a registered connector, return the index of that connector within a DRM |
* device's list of connectors. |
*/ |
unsigned int drm_connector_index(struct drm_connector *connector) |
{ |
unsigned int index = 0; |
struct drm_connector *tmp; |
struct drm_mode_config *config = &connector->dev->mode_config; |
|
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); |
|
drm_for_each_connector(tmp, connector->dev) { |
if (tmp == connector) |
return index; |
|
index++; |
} |
|
BUG(); |
} |
EXPORT_SYMBOL(drm_connector_index); |
|
/** |
* drm_connector_register - register a connector |
* @connector: the connector to register |
* |
1075,6 → 1095,7 |
* @encoder: the encoder to init |
* @funcs: callbacks for this encoder |
* @encoder_type: user visible type of the encoder |
* @name: printf style format string for the encoder name, or NULL for default name |
* |
* Initialises a preallocated encoder. Encoder should be |
* subclassed as part of driver encoder objects. |
1085,7 → 1106,7 |
int drm_encoder_init(struct drm_device *dev, |
struct drm_encoder *encoder, |
const struct drm_encoder_funcs *funcs, |
int encoder_type) |
int encoder_type, const char *name, ...) |
{ |
int ret; |
|
1098,9 → 1119,17 |
encoder->dev = dev; |
encoder->encoder_type = encoder_type; |
encoder->funcs = funcs; |
if (name) { |
va_list ap; |
|
va_start(ap, name); |
encoder->name = kvasprintf(GFP_KERNEL, name, ap); |
va_end(ap); |
} else { |
encoder->name = kasprintf(GFP_KERNEL, "%s-%d", |
drm_encoder_enum_list[encoder_type].name, |
encoder->base.id); |
} |
if (!encoder->name) { |
ret = -ENOMEM; |
goto out_put; |
1141,6 → 1170,18 |
} |
EXPORT_SYMBOL(drm_encoder_cleanup); |
|
static unsigned int drm_num_planes(struct drm_device *dev) |
{ |
unsigned int num = 0; |
struct drm_plane *tmp; |
|
drm_for_each_plane(tmp, dev) { |
num++; |
} |
|
return num; |
} |
|
/** |
* drm_universal_plane_init - Initialize a new universal plane object |
* @dev: DRM device |
1150,6 → 1191,7 |
* @formats: array of supported formats (%DRM_FORMAT_*) |
* @format_count: number of elements in @formats |
* @type: type of plane (overlay, primary, cursor) |
* @name: printf style format string for the plane name, or NULL for default name |
* |
* Initializes a plane object of type @type. |
* |
1160,7 → 1202,8 |
unsigned long possible_crtcs, |
const struct drm_plane_funcs *funcs, |
const uint32_t *formats, unsigned int format_count, |
enum drm_plane_type type) |
enum drm_plane_type type, |
const char *name, ...) |
{ |
struct drm_mode_config *config = &dev->mode_config; |
int ret; |
1182,6 → 1225,22 |
return -ENOMEM; |
} |
|
if (name) { |
va_list ap; |
|
va_start(ap, name); |
plane->name = kvasprintf(GFP_KERNEL, name, ap); |
va_end(ap); |
} else { |
plane->name = kasprintf(GFP_KERNEL, "plane-%d", |
drm_num_planes(dev)); |
} |
if (!plane->name) { |
kfree(plane->format_types); |
drm_mode_object_put(dev, &plane->base); |
return -ENOMEM; |
} |
|
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); |
plane->format_count = format_count; |
plane->possible_crtcs = possible_crtcs; |
1240,7 → 1299,7 |
|
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; |
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, |
formats, format_count, type); |
formats, format_count, type, NULL); |
} |
EXPORT_SYMBOL(drm_plane_init); |
|
1272,6 → 1331,8 |
if (plane->state && plane->funcs->atomic_destroy_state) |
plane->funcs->atomic_destroy_state(plane, plane->state); |
|
kfree(plane->name); |
|
memset(plane, 0, sizeof(*plane)); |
} |
EXPORT_SYMBOL(drm_plane_cleanup); |
1802,7 → 1863,8 |
copied = 0; |
crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; |
drm_for_each_crtc(crtc, dev) { |
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); |
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", |
crtc->base.id, crtc->name); |
if (put_user(crtc->base.id, crtc_id + copied)) { |
ret = -EFAULT; |
goto out; |
2649,7 → 2711,7 |
ret = -ENOENT; |
goto out; |
} |
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); |
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); |
|
if (crtc_req->mode_valid) { |
/* If we have a mode we need a framebuffer. */ |
2685,6 → 2747,8 |
goto out; |
} |
|
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
|
/* |
* Check whether the primary plane supports the fb pixel format. |
* Drivers not implementing the universal planes API use a |
3144,7 → 3208,7 |
|
static struct drm_framebuffer * |
internal_framebuffer_create(struct drm_device *dev, |
struct drm_mode_fb_cmd2 *r, |
const struct drm_mode_fb_cmd2 *r, |
struct drm_file *file_priv) |
{ |
struct drm_mode_config *config = &dev->mode_config; |
3418,6 → 3482,7 |
return ret; |
} |
|
|
/** |
* drm_fb_release - remove and free the FBs on this file |
* @priv: drm file for the ioctl |
4565,8 → 4630,6 |
|
/* Do DPMS ourselves */ |
if (property == connector->dev->mode_config.dpms_property) { |
ret = 0; |
if (connector->funcs->dpms) |
ret = (*connector->funcs->dpms)(connector, (int)value); |
} else if (connector->funcs->set_property) |
ret = connector->funcs->set_property(connector, property, value); |
4765,6 → 4828,20 |
{ |
int i; |
|
/* |
* In the past, drivers have attempted to model the static association |
* of connector to encoder in simple connector/encoder devices using a |
* direct assignment of connector->encoder = encoder. This connection |
* is a logical one and the responsibility of the core, so drivers are |
* expected not to mess with this. |
* |
* Note that the error return should've been enough here, but a large |
* majority of drivers ignores the return value, so add in a big WARN |
* to get people's attention. |
*/ |
if (WARN_ON(connector->encoder)) |
return -EINVAL; |
|
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
if (connector->encoder_ids[i] == 0) { |
connector->encoder_ids[i] = encoder->base.id; |
5245,6 → 5322,7 |
INIT_LIST_HEAD(&dev->mode_config.plane_list); |
idr_init(&dev->mode_config.crtc_idr); |
idr_init(&dev->mode_config.tile_idr); |
ida_init(&dev->mode_config.connector_ida); |
|
drm_modeset_lock_all(dev); |
drm_mode_create_standard_properties(dev); |
5325,6 → 5403,7 |
crtc->funcs->destroy(crtc); |
} |
|
ida_destroy(&dev->mode_config.connector_ida); |
idr_destroy(&dev->mode_config.tile_idr); |
idr_destroy(&dev->mode_config.crtc_idr); |
drm_modeset_lock_fini(&dev->mode_config.connection_mutex); |