@@ -90,6 +90,14 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
+static int drm_mode_set_obj_prop(struct drm_mode_object *obj,
+ void *state, struct drm_property *property,
+ uint64_t value, void *blob_data);
+static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
+ int length, void *data);
+static void drm_property_destroy_blob(struct drm_device *dev,
+ struct drm_property_blob *blob);
+
/* Avoid boilerplate. I'm tired of typing. */
#define DRM_ENUM_NAME_FN(fnname, list) \
const char *fnname(int val) \
@@ -644,6 +652,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
goto out;
crtc->base.properties = &crtc->properties;
+ crtc->base.propvals = &crtc->propvals;
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
dev->mode_config.num_crtc++;
@@ -733,6 +742,7 @@ int drm_connector_init(struct drm_device *dev,
goto out;
connector->base.properties = &connector->properties;
+ connector->base.propvals = &connector->propvals;
connector->dev = dev;
connector->funcs = funcs;
connector->connector_type = connector_type;
@@ -906,6 +916,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
goto out;
plane->base.properties = &plane->properties;
+ plane->base.propvals = &plane->propvals;
plane->dev = dev;
plane->funcs = funcs;
plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
@@ -1712,7 +1723,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
goto out;
}
- if (put_user(connector->properties.values[i],
+ if (put_user(connector->propvals.values[i],
prop_values + copied)) {
ret = -EFAULT;
goto out;
@@ -3021,19 +3032,33 @@ void drm_object_attach_property(struct drm_mode_object *obj,
}
obj->properties->ids[count] = property->base.id;
- obj->properties->values[count] = init_val;
+ obj->propvals->values[count] = init_val;
obj->properties->count++;
}
EXPORT_SYMBOL(drm_object_attach_property);
int drm_object_property_set_value(struct drm_mode_object *obj,
- struct drm_property *property, uint64_t val)
+ struct drm_object_property_values *propvals,
+ struct drm_property *property, uint64_t val,
+ void *blob_data)
{
int i;
for (i = 0; i < obj->properties->count; i++) {
if (obj->properties->ids[i] == property->base.id) {
- obj->properties->values[i] = val;
+ struct drm_device *dev = property->dev;
+ if (property->flags & DRM_MODE_PROP_BLOB) {
+ struct drm_property_blob *blob, *old_blob = NULL;
+ old_blob = drm_property_blob_find(dev, propvals->values[i]);
+ blob = drm_property_create_blob(dev, val, blob_data);
+ if (!blob)
+ return -ENOMEM;
+ propvals->values[i] = blob->base.id;
+ if (old_blob)
+ drm_property_destroy_blob(dev, old_blob);
+ } else {
+ propvals->values[i] = val;
+ }
return 0;
}
}
@@ -3049,7 +3074,7 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
for (i = 0; i < obj->properties->count; i++) {
if (obj->properties->ids[i] == property->base.id) {
- *val = obj->properties->values[i];
+ *val = obj->propvals->values[i];
return 0;
}
}
@@ -3234,27 +3259,35 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct edid *edid)
{
struct drm_device *dev = connector->dev;
- int ret, size;
+ struct drm_mode_object *obj = &connector->base;
+ struct drm_property *edid_prop = dev->mode_config.edid_property;
+ int i, ret, size;
- if (connector->edid_blob_ptr)
- drm_property_destroy_blob(dev, connector->edid_blob_ptr);
+ /* property_blob will be recreated by drm_object_property_set_value(): */
+ connector->edid_blob_ptr = NULL;
/* Delete edid, when there is none. */
if (!edid) {
- connector->edid_blob_ptr = NULL;
- ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
+ ret = drm_object_property_set_value(obj,
+ &connector->propvals, edid_prop, 0, NULL);
return ret;
}
size = EDID_LENGTH * (1 + edid->extensions);
- connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
- size, edid);
- if (!connector->edid_blob_ptr)
- return -EINVAL;
- ret = drm_object_property_set_value(&connector->base,
- dev->mode_config.edid_property,
- connector->edid_blob_ptr->base.id);
+ ret = drm_object_property_set_value(obj,
+ &connector->propvals, edid_prop, size, edid);
+ if (ret)
+ return ret;
+
+ /* find the blob object created for us by drm_object_property_set_value(): */
+ for (i = 0; i < obj->properties->count; i++) {
+ if (obj->properties->ids[i] == edid_prop->base.id) {
+ connector->edid_blob_ptr = drm_property_blob_find(dev,
+ connector->propvals.values[i]);
+ break;
+ }
+ }
return ret;
}
@@ -3332,7 +3365,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_connector *connector,
/* store the property value if successful */
if (!ret)
- drm_object_property_set_value(&connector->base, property, value);
+ drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, value, blob_data);
+
return ret;
}
@@ -3346,7 +3381,8 @@ static int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc,
ret = crtc->funcs->set_property(crtc, state, property,
value, blob_data);
if (!ret)
- drm_object_property_set_value(&crtc->base, property, value);
+ drm_object_property_set_value(&crtc->base, &crtc->propvals,
+ property, value, NULL);
return ret;
}
@@ -3361,7 +3397,8 @@ static int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
ret = plane->funcs->set_property(plane, state, property,
value, blob_data);
if (!ret)
- drm_object_property_set_value(&plane->base, property, value);
+ drm_object_property_set_value(&plane->base, &plane->propvals,
+ property, value, NULL);
return ret;
}
@@ -3464,7 +3501,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
ret = -EFAULT;
goto out;
}
- if (put_user(obj->properties->values[i],
+ if (put_user(obj->propvals->values[i],
prop_values_ptr + copied)) {
ret = -EFAULT;
goto out;
@@ -431,7 +431,8 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
connector = fb_helper->connector_info[j]->connector;
connector->funcs->dpms(connector, dpms_mode);
drm_object_property_set_value(&connector->base,
- dev->mode_config.dpms_property, dpms_mode);
+ &connector->propvals,
+ dev->mode_config.dpms_property, dpms_mode, NULL);
}
}
drm_modeset_unlock_all(dev);
@@ -1654,7 +1654,8 @@ cdv_intel_dp_set_property(struct drm_connector *connector,
struct cdv_intel_dp *intel_dp = encoder->dev_priv;
int ret;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret)
return ret;
@@ -191,7 +191,8 @@ static int cdv_hdmi_set_property(struct drm_connector *connector,
return 0;
if (drm_object_property_set_value(&connector->base,
- property, value))
+ &connector->propvals,
+ property, value, blob_data))
return -1;
centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
@@ -486,8 +486,9 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
return 0;
if (drm_object_property_set_value(&connector->base,
+ &connector->propvals,
property,
- value))
+ value, blob_data))
return -1;
if (crtc->saved_mode.hdisplay != 0 &&
@@ -501,8 +502,9 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
}
} else if (!strcmp(property->name, "backlight") && encoder) {
if (drm_object_property_set_value(&connector->base,
+ &connector->propvals,
property,
- value))
+ value, blob_data))
return -1;
else
gma_backlight_set(encoder->dev, value);
@@ -276,7 +276,8 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
goto set_prop_done;
if (drm_object_property_set_value(&connector->base,
- property, value))
+ &connector->propvals,
+ property, value, blob_data))
goto set_prop_error;
centerechange = (val == DRM_MODE_SCALE_NO_SCALE) ||
@@ -300,8 +301,9 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
}
}
} else if (!strcmp(property->name, "backlight") && encoder) {
- if (drm_object_property_set_value(&connector->base, property,
- value))
+ if (drm_object_property_set_value(&connector->base,
+ &connector->propvals,
+ property, value, blob_data))
goto set_prop_error;
else
gma_backlight_set(encoder->dev, value);
@@ -606,8 +606,9 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
goto set_prop_done;
if (drm_object_property_set_value(&connector->base,
+ &connector->propvals,
property,
- value))
+ value, blob_data))
goto set_prop_error;
if (crtc->saved_mode.hdisplay != 0 &&
@@ -621,8 +622,9 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
}
} else if (!strcmp(property->name, "backlight")) {
if (drm_object_property_set_value(&connector->base,
+ &connector->propvals,
property,
- value))
+ value, blob_data))
goto set_prop_error;
else
gma_backlight_set(encoder->dev, value);
@@ -1717,7 +1717,8 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
uint8_t cmd;
int ret;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret)
return ret;
@@ -1773,7 +1774,9 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
temp_value = val;
if (psb_intel_sdvo_connector->left == property) {
drm_object_property_set_value(&connector->base,
- psb_intel_sdvo_connector->right, val);
+ &connector->propvals,
+ psb_intel_sdvo_connector->right,
+ val, blob_data);
if (psb_intel_sdvo_connector->left_margin == temp_value)
return 0;
@@ -1785,7 +1788,9 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (psb_intel_sdvo_connector->right == property) {
drm_object_property_set_value(&connector->base,
- psb_intel_sdvo_connector->left, val);
+ &connector->propvals,
+ psb_intel_sdvo_connector->left,
+ val, blob_data);
if (psb_intel_sdvo_connector->right_margin == temp_value)
return 0;
@@ -1797,7 +1802,9 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (psb_intel_sdvo_connector->top == property) {
drm_object_property_set_value(&connector->base,
- psb_intel_sdvo_connector->bottom, val);
+ &connector->propvals,
+ psb_intel_sdvo_connector->bottom,
+ val, blob_data);
if (psb_intel_sdvo_connector->top_margin == temp_value)
return 0;
@@ -1809,7 +1816,9 @@ psb_intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (psb_intel_sdvo_connector->bottom == property) {
drm_object_property_set_value(&connector->base,
- psb_intel_sdvo_connector->top, val);
+ &connector->propvals,
+ psb_intel_sdvo_connector->top,
+ val, blob_data);
if (psb_intel_sdvo_connector->bottom_margin == temp_value)
return 0;
@@ -214,9 +214,9 @@ static enum drm_connector_status ch7006_encoder_detect(struct drm_encoder *encod
else
priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
- drm_object_property_set_value(&connector->base,
+ drm_object_property_set_value(&connector->base, &connector->propvals,
encoder->dev->mode_config.tv_subconnector_property,
- priv->subconnector);
+ priv->subconnector, NULL);
return priv->subconnector ? connector_status_connected :
connector_status_disconnected;
@@ -8959,8 +8959,9 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
connector->dpms = DRM_MODE_DPMS_ON;
drm_object_property_set_value(&connector->base,
+ &connector->propvals,
dpms_property,
- DRM_MODE_DPMS_ON);
+ DRM_MODE_DPMS_ON, NULL);
intel_encoder = to_intel_encoder(connector->encoder);
intel_encoder->connectors_active = true;
@@ -3171,7 +3171,8 @@ intel_dp_set_property(struct drm_connector *connector,
struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
int ret;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret)
return ret;
@@ -1015,7 +1015,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
struct drm_i915_private *dev_priv = connector->dev->dev_private;
int ret;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret)
return ret;
@@ -2044,7 +2044,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
uint8_t cmd;
int ret;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret)
return ret;
@@ -2121,7 +2122,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
temp_value = val;
if (intel_sdvo_connector->left == property) {
drm_object_property_set_value(&connector->base,
- intel_sdvo_connector->right, val);
+ &connector->propvals,
+ intel_sdvo_connector->right,
+ val, blob_data);
if (intel_sdvo_connector->left_margin == temp_value)
return 0;
@@ -2133,7 +2136,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (intel_sdvo_connector->right == property) {
drm_object_property_set_value(&connector->base,
- intel_sdvo_connector->left, val);
+ &connector->propvals,
+ intel_sdvo_connector->left,
+ val, blob_data);
if (intel_sdvo_connector->right_margin == temp_value)
return 0;
@@ -2145,7 +2150,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (intel_sdvo_connector->top == property) {
drm_object_property_set_value(&connector->base,
- intel_sdvo_connector->bottom, val);
+ &connector->propvals,
+ intel_sdvo_connector->bottom,
+ val, blob_data);
if (intel_sdvo_connector->top_margin == temp_value)
return 0;
@@ -2157,7 +2164,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
goto set_value;
} else if (intel_sdvo_connector->bottom == property) {
drm_object_property_set_value(&connector->base,
- intel_sdvo_connector->top, val);
+ &connector->propvals,
+ intel_sdvo_connector->top,
+ val, blob_data);
if (intel_sdvo_connector->bottom_margin == temp_value)
return 0;
@@ -1292,7 +1292,8 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
intel_tv->tv_format = tv_mode->name;
drm_object_property_set_value(&connector->base,
- connector->dev->mode_config.tv_mode_property, i);
+ &connector->propvals,
+ connector->dev->mode_config.tv_mode_property, i, NULL);
}
/**
@@ -1449,7 +1450,8 @@ intel_tv_set_property(struct drm_connector *connector, void *state,
int ret = 0;
bool changed = false;
- ret = drm_object_property_set_value(&connector->base, property, val);
+ ret = drm_object_property_set_value(&connector->base,
+ &connector->propvals, property, val, blob_data);
if (ret < 0)
goto out;
@@ -196,8 +196,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
}
drm_object_property_set_value(&connector->base,
+ &connector->propvals,
conf->tv_subconnector_property,
- tv_enc->subconnector);
+ tv_enc->subconnector, NULL);
if (!reliable) {
return connector_status_unknown;
@@ -227,10 +227,12 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
drm_object_property_set_value(&connector->base,
+ &connector->propvals,
dev->mode_config.dvi_i_subconnector_property,
nv_encoder->dcb->type == DCB_OUTPUT_TMDS ?
DRM_MODE_SUBCONNECTOR_DVID :
- DRM_MODE_SUBCONNECTOR_DVIA);
+ DRM_MODE_SUBCONNECTOR_DVIA,
+ NULL);
}
}
@@ -553,12 +553,14 @@ static void dev_lastclose(struct drm_device *dev)
*/
for (i = 0; i < priv->num_crtcs; i++) {
drm_object_property_set_value(&priv->crtcs[i]->base,
- priv->rotation_prop, 0);
+ &priv->crtcs[i]->propvals,
+ priv->rotation_prop, 0, NULL);
}
for (i = 0; i < priv->num_planes; i++) {
drm_object_property_set_value(&priv->planes[i]->base,
- priv->rotation_prop, 0);
+ &priv->planes[i]->propvals,
+ priv->rotation_prop, 0, NULL);
}
}
@@ -118,7 +118,8 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
drm_object_property_set_value(&connector->base,
- rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ &connector->propvals,
+ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF, NULL);
ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
if (ret < 0)
@@ -83,7 +83,8 @@ int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
drm_object_property_set_value(&connector->base,
- rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ &connector->propvals,
+ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF, NULL);
ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
if (ret < 0)
@@ -738,8 +738,8 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
connector->encoder = encoder;
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
- drm_object_property_set_value(&connector->base,
- sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ drm_object_property_set_value(&connector->base, &connector->propvals,
+ sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF, NULL);
return 0;
@@ -41,6 +41,7 @@ struct drm_framebuffer;
struct drm_object_properties;
struct drm_file;
struct drm_clip_rect;
+struct drm_object_property_values;
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
@@ -56,12 +57,16 @@ struct drm_mode_object {
uint32_t id;
uint32_t type;
struct drm_object_properties *properties;
+ struct drm_object_property_values *propvals;
};
#define DRM_OBJECT_MAX_PROPERTY 24
struct drm_object_properties {
int count;
uint32_t ids[DRM_OBJECT_MAX_PROPERTY];
+};
+
+struct drm_object_property_values {
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};
@@ -465,6 +470,7 @@ struct drm_crtc {
void *helper_private;
struct drm_object_properties properties;
+ struct drm_object_property_values propvals;
};
@@ -630,6 +636,7 @@ struct drm_connector {
struct drm_property_blob *edid_blob_ptr;
struct drm_object_properties properties;
+ struct drm_object_property_values propvals;
uint8_t polled; /* DRM_CONNECTOR_POLL_* */
@@ -705,6 +712,7 @@ struct drm_plane {
const struct drm_plane_funcs *funcs;
struct drm_object_properties properties;
+ struct drm_object_property_values propvals;
};
/**
@@ -1019,8 +1027,9 @@ extern void drm_mode_connector_list_update(struct drm_connector *connector);
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct edid *edid);
extern int drm_object_property_set_value(struct drm_mode_object *obj,
+ struct drm_object_property_values *propvals,
struct drm_property *property,
- uint64_t val);
+ uint64_t val, void *blob_data);
extern int drm_object_property_get_value(struct drm_mode_object *obj,
struct drm_property *property,
uint64_t *value);