@@ -78,6 +78,13 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
{ DRM_PLANE_TYPE_CURSOR, "Cursor" },
};
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+ { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+ { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+};
+
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
/*
* Optional properties
*/
@@ -1470,6 +1477,20 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_mode_id = prop;
+ prop = drm_property_create_enum(dev, 0,
+ "Content Protection", drm_cp_enum_list,
+ ARRAY_SIZE(drm_cp_enum_list));
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.content_protection_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE,
+ "Content Protection KSV", 0,
+ 0xFFFFFFFFFF);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.content_protection_ksv_property = prop;
+
return 0;
}
@@ -248,6 +248,48 @@ static ssize_t enabled_show(struct device *device,
"disabled");
}
+static ssize_t content_protection_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 cp;
+ int ret;
+
+ prop = dev->mode_config.content_protection_property;
+ if (!prop)
+ return 0;
+
+ ret = drm_object_property_get_value(&connector->base, prop, &cp);
+ if (ret)
+ return 0;
+
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ drm_get_content_protection_name((int)cp));
+}
+
+static ssize_t content_protection_ksv_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 ksv;
+ int ret;
+
+ prop = dev->mode_config.content_protection_ksv_property;
+ if (!prop)
+ return 0;
+
+ ret = drm_object_property_get_value(&connector->base, prop, &ksv);
+ if (ret)
+ return 0;
+
+ return snprintf(buf, PAGE_SIZE, "%llx\n", ksv);
+}
+
static ssize_t edid_show(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t off,
size_t count)
@@ -399,12 +441,16 @@ static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(enabled);
static DEVICE_ATTR_RO(dpms);
static DEVICE_ATTR_RO(modes);
+static DEVICE_ATTR_RO(content_protection);
+static DEVICE_ATTR_RO(content_protection_ksv);
static struct attribute *connector_dev_attrs[] = {
&dev_attr_status.attr,
&dev_attr_enabled.attr,
&dev_attr_dpms.attr,
&dev_attr_modes.attr,
+ &dev_attr_content_protection.attr,
+ &dev_attr_content_protection_ksv.attr,
NULL
};
@@ -1118,6 +1118,8 @@ struct drm_mode_config {
struct drm_property *prop_crtc_id;
struct drm_property *prop_active;
struct drm_property *prop_mode_id;
+ struct drm_property *content_protection_property;
+ struct drm_property *content_protection_ksv_property;
/* DVI-I properties */
struct drm_property *dvi_i_subconnector_property;
@@ -1286,6 +1288,7 @@ extern void drm_encoder_cleanup(struct drm_encoder *encoder);
extern const char *drm_get_connector_status_name(enum drm_connector_status status);
extern const char *drm_get_subpixel_order_name(enum subpixel_order order);
extern const char *drm_get_dpms_name(int val);
+extern const char *drm_get_content_protection_name(int val);
extern const char *drm_get_dvi_i_subconnector_name(int val);
extern const char *drm_get_dvi_i_select_name(int val);
extern const char *drm_get_tv_subconnector_name(int val);
@@ -81,6 +81,10 @@
#define DRM_MODE_DPMS_SUSPEND 2
#define DRM_MODE_DPMS_OFF 3
+/* Content Protection Flags */
+#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
+#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1
+
/* Scaling mode options */
#define DRM_MODE_SCALE_NONE 0 /* Unmodified timing (display or
software can still scale) */