aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c650
1 files changed, 406 insertions, 244 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5213da499d39..6b6b07ff720b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
38#include <drm/drm_edid.h> 38#include <drm/drm_edid.h>
39#include <drm/drm_fourcc.h> 39#include <drm/drm_fourcc.h>
40#include <drm/drm_modeset_lock.h> 40#include <drm/drm_modeset_lock.h>
41#include <drm/drm_atomic.h>
41 42
42#include "drm_crtc_internal.h" 43#include "drm_crtc_internal.h"
43#include "drm_internal.h" 44#include "drm_internal.h"
@@ -61,8 +62,8 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
61/* 62/*
62 * Global properties 63 * Global properties
63 */ 64 */
64static const struct drm_prop_enum_list drm_dpms_enum_list[] = 65static const struct drm_prop_enum_list drm_dpms_enum_list[] = {
65{ { DRM_MODE_DPMS_ON, "On" }, 66 { DRM_MODE_DPMS_ON, "On" },
66 { DRM_MODE_DPMS_STANDBY, "Standby" }, 67 { DRM_MODE_DPMS_STANDBY, "Standby" },
67 { DRM_MODE_DPMS_SUSPEND, "Suspend" }, 68 { DRM_MODE_DPMS_SUSPEND, "Suspend" },
68 { DRM_MODE_DPMS_OFF, "Off" } 69 { DRM_MODE_DPMS_OFF, "Off" }
@@ -70,8 +71,7 @@ static const struct drm_prop_enum_list drm_dpms_enum_list[] =
70 71
71DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) 72DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
72 73
73static const struct drm_prop_enum_list drm_plane_type_enum_list[] = 74static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
74{
75 { DRM_PLANE_TYPE_OVERLAY, "Overlay" }, 75 { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
76 { DRM_PLANE_TYPE_PRIMARY, "Primary" }, 76 { DRM_PLANE_TYPE_PRIMARY, "Primary" },
77 { DRM_PLANE_TYPE_CURSOR, "Cursor" }, 77 { DRM_PLANE_TYPE_CURSOR, "Cursor" },
@@ -80,8 +80,7 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] =
80/* 80/*
81 * Optional properties 81 * Optional properties
82 */ 82 */
83static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = 83static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {
84{
85 { DRM_MODE_SCALE_NONE, "None" }, 84 { DRM_MODE_SCALE_NONE, "None" },
86 { DRM_MODE_SCALE_FULLSCREEN, "Full" }, 85 { DRM_MODE_SCALE_FULLSCREEN, "Full" },
87 { DRM_MODE_SCALE_CENTER, "Center" }, 86 { DRM_MODE_SCALE_CENTER, "Center" },
@@ -97,8 +96,7 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
97/* 96/*
98 * Non-global properties, but "required" for certain connectors. 97 * Non-global properties, but "required" for certain connectors.
99 */ 98 */
100static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = 99static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
101{
102 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 100 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
103 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 101 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
104 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 102 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
@@ -106,8 +104,7 @@ static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
106 104
107DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) 105DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
108 106
109static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = 107static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
110{
111 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 108 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
112 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ 109 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
113 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ 110 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
@@ -116,8 +113,7 @@ static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
116DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, 113DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
117 drm_dvi_i_subconnector_enum_list) 114 drm_dvi_i_subconnector_enum_list)
118 115
119static const struct drm_prop_enum_list drm_tv_select_enum_list[] = 116static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {
120{
121 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 117 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
122 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 118 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
123 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 119 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
@@ -127,8 +123,7 @@ static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
127 123
128DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) 124DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
129 125
130static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = 126static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
131{
132 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ 127 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
133 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 128 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
134 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 129 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
@@ -154,8 +149,8 @@ struct drm_conn_prop_enum_list {
154/* 149/*
155 * Connector and encoder types. 150 * Connector and encoder types.
156 */ 151 */
157static struct drm_conn_prop_enum_list drm_connector_enum_list[] = 152static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
158{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, 153 { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
159 { DRM_MODE_CONNECTOR_VGA, "VGA" }, 154 { DRM_MODE_CONNECTOR_VGA, "VGA" },
160 { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, 155 { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
161 { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, 156 { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
@@ -174,8 +169,8 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
174 { DRM_MODE_CONNECTOR_DSI, "DSI" }, 169 { DRM_MODE_CONNECTOR_DSI, "DSI" },
175}; 170};
176 171
177static const struct drm_prop_enum_list drm_encoder_enum_list[] = 172static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
178{ { DRM_MODE_ENCODER_NONE, "None" }, 173 { DRM_MODE_ENCODER_NONE, "None" },
179 { DRM_MODE_ENCODER_DAC, "DAC" }, 174 { DRM_MODE_ENCODER_DAC, "DAC" },
180 { DRM_MODE_ENCODER_TMDS, "TMDS" }, 175 { DRM_MODE_ENCODER_TMDS, "TMDS" },
181 { DRM_MODE_ENCODER_LVDS, "LVDS" }, 176 { DRM_MODE_ENCODER_LVDS, "LVDS" },
@@ -185,8 +180,7 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] =
185 { DRM_MODE_ENCODER_DPMST, "DP MST" }, 180 { DRM_MODE_ENCODER_DPMST, "DP MST" },
186}; 181};
187 182
188static const struct drm_prop_enum_list drm_subpixel_enum_list[] = 183static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
189{
190 { SubPixelUnknown, "Unknown" }, 184 { SubPixelUnknown, "Unknown" },
191 { SubPixelHorizontalRGB, "Horizontal RGB" }, 185 { SubPixelHorizontalRGB, "Horizontal RGB" },
192 { SubPixelHorizontalBGR, "Horizontal BGR" }, 186 { SubPixelHorizontalBGR, "Horizontal BGR" },
@@ -697,6 +691,10 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
697 if (cursor) 691 if (cursor)
698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc); 692 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
699 693
694 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
695 drm_object_attach_property(&crtc->base, config->prop_active, 0);
696 }
697
700 return 0; 698 return 0;
701} 699}
702EXPORT_SYMBOL(drm_crtc_init_with_planes); 700EXPORT_SYMBOL(drm_crtc_init_with_planes);
@@ -768,6 +766,40 @@ static void drm_mode_remove(struct drm_connector *connector,
768} 766}
769 767
770/** 768/**
769 * drm_display_info_set_bus_formats - set the supported bus formats
770 * @info: display info to store bus formats in
771 * @formats: array containing the supported bus formats
772 * @num_formats: the number of entries in the fmts array
773 *
774 * Store the supported bus formats in display info structure.
775 * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
776 * a full list of available formats.
777 */
778int drm_display_info_set_bus_formats(struct drm_display_info *info,
779 const u32 *formats,
780 unsigned int num_formats)
781{
782 u32 *fmts = NULL;
783
784 if (!formats && num_formats)
785 return -EINVAL;
786
787 if (formats && num_formats) {
788 fmts = kmemdup(formats, sizeof(*formats) * num_formats,
789 GFP_KERNEL);
790 if (!fmts)
791 return -ENOMEM;
792 }
793
794 kfree(info->bus_formats);
795 info->bus_formats = fmts;
796 info->num_bus_formats = num_formats;
797
798 return 0;
799}
800EXPORT_SYMBOL(drm_display_info_set_bus_formats);
801
802/**
771 * drm_connector_get_cmdline_mode - reads the user's cmdline mode 803 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
772 * @connector: connector to quwery 804 * @connector: connector to quwery
773 * 805 *
@@ -837,6 +869,7 @@ int drm_connector_init(struct drm_device *dev,
837 const struct drm_connector_funcs *funcs, 869 const struct drm_connector_funcs *funcs,
838 int connector_type) 870 int connector_type)
839{ 871{
872 struct drm_mode_config *config = &dev->mode_config;
840 int ret; 873 int ret;
841 struct ida *connector_ida = 874 struct ida *connector_ida =
842 &drm_connector_enum_list[connector_type].ida; 875 &drm_connector_enum_list[connector_type].ida;
@@ -875,16 +908,20 @@ int drm_connector_init(struct drm_device *dev,
875 908
876 /* We should add connectors at the end to avoid upsetting the connector 909 /* We should add connectors at the end to avoid upsetting the connector
877 * index too much. */ 910 * index too much. */
878 list_add_tail(&connector->head, &dev->mode_config.connector_list); 911 list_add_tail(&connector->head, &config->connector_list);
879 dev->mode_config.num_connector++; 912 config->num_connector++;
880 913
881 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) 914 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
882 drm_object_attach_property(&connector->base, 915 drm_object_attach_property(&connector->base,
883 dev->mode_config.edid_property, 916 config->edid_property,
884 0); 917 0);
885 918
886 drm_object_attach_property(&connector->base, 919 drm_object_attach_property(&connector->base,
887 dev->mode_config.dpms_property, 0); 920 config->dpms_property, 0);
921
922 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
923 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
924 }
888 925
889 connector->debugfs_entry = NULL; 926 connector->debugfs_entry = NULL;
890 927
@@ -924,6 +961,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
924 ida_remove(&drm_connector_enum_list[connector->connector_type].ida, 961 ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
925 connector->connector_type_id); 962 connector->connector_type_id);
926 963
964 kfree(connector->display_info.bus_formats);
927 drm_mode_object_put(dev, &connector->base); 965 drm_mode_object_put(dev, &connector->base);
928 kfree(connector->name); 966 kfree(connector->name);
929 connector->name = NULL; 967 connector->name = NULL;
@@ -1028,61 +1066,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
1028EXPORT_SYMBOL(drm_connector_unplug_all); 1066EXPORT_SYMBOL(drm_connector_unplug_all);
1029 1067
1030/** 1068/**
1031 * drm_bridge_init - initialize a drm transcoder/bridge
1032 * @dev: drm device
1033 * @bridge: transcoder/bridge to set up
1034 * @funcs: bridge function table
1035 *
1036 * Initialises a preallocated bridge. Bridges should be
1037 * subclassed as part of driver connector objects.
1038 *
1039 * Returns:
1040 * Zero on success, error code on failure.
1041 */
1042int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
1043 const struct drm_bridge_funcs *funcs)
1044{
1045 int ret;
1046
1047 drm_modeset_lock_all(dev);
1048
1049 ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
1050 if (ret)
1051 goto out;
1052
1053 bridge->dev = dev;
1054 bridge->funcs = funcs;
1055
1056 list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
1057 dev->mode_config.num_bridge++;
1058
1059 out:
1060 drm_modeset_unlock_all(dev);
1061 return ret;
1062}
1063EXPORT_SYMBOL(drm_bridge_init);
1064
1065/**
1066 * drm_bridge_cleanup - cleans up an initialised bridge
1067 * @bridge: bridge to cleanup
1068 *
1069 * Cleans up the bridge but doesn't free the object.
1070 */
1071void drm_bridge_cleanup(struct drm_bridge *bridge)
1072{
1073 struct drm_device *dev = bridge->dev;
1074
1075 drm_modeset_lock_all(dev);
1076 drm_mode_object_put(dev, &bridge->base);
1077 list_del(&bridge->head);
1078 dev->mode_config.num_bridge--;
1079 drm_modeset_unlock_all(dev);
1080
1081 memset(bridge, 0, sizeof(*bridge));
1082}
1083EXPORT_SYMBOL(drm_bridge_cleanup);
1084
1085/**
1086 * drm_encoder_init - Init a preallocated encoder 1069 * drm_encoder_init - Init a preallocated encoder
1087 * @dev: drm device 1070 * @dev: drm device
1088 * @encoder: the encoder to init 1071 * @encoder: the encoder to init
@@ -1142,6 +1125,7 @@ EXPORT_SYMBOL(drm_encoder_init);
1142void drm_encoder_cleanup(struct drm_encoder *encoder) 1125void drm_encoder_cleanup(struct drm_encoder *encoder)
1143{ 1126{
1144 struct drm_device *dev = encoder->dev; 1127 struct drm_device *dev = encoder->dev;
1128
1145 drm_modeset_lock_all(dev); 1129 drm_modeset_lock_all(dev);
1146 drm_mode_object_put(dev, &encoder->base); 1130 drm_mode_object_put(dev, &encoder->base);
1147 kfree(encoder->name); 1131 kfree(encoder->name);
@@ -1174,6 +1158,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1174 const uint32_t *formats, uint32_t format_count, 1158 const uint32_t *formats, uint32_t format_count,
1175 enum drm_plane_type type) 1159 enum drm_plane_type type)
1176{ 1160{
1161 struct drm_mode_config *config = &dev->mode_config;
1177 int ret; 1162 int ret;
1178 1163
1179 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 1164 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -1185,8 +1170,8 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1185 plane->base.properties = &plane->properties; 1170 plane->base.properties = &plane->properties;
1186 plane->dev = dev; 1171 plane->dev = dev;
1187 plane->funcs = funcs; 1172 plane->funcs = funcs;
1188 plane->format_types = kmalloc(sizeof(uint32_t) * format_count, 1173 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
1189 GFP_KERNEL); 1174 GFP_KERNEL);
1190 if (!plane->format_types) { 1175 if (!plane->format_types) {
1191 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 1176 DRM_DEBUG_KMS("out of memory when allocating plane\n");
1192 drm_mode_object_put(dev, &plane->base); 1177 drm_mode_object_put(dev, &plane->base);
@@ -1198,15 +1183,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1198 plane->possible_crtcs = possible_crtcs; 1183 plane->possible_crtcs = possible_crtcs;
1199 plane->type = type; 1184 plane->type = type;
1200 1185
1201 list_add_tail(&plane->head, &dev->mode_config.plane_list); 1186 list_add_tail(&plane->head, &config->plane_list);
1202 dev->mode_config.num_total_plane++; 1187 config->num_total_plane++;
1203 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1188 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1204 dev->mode_config.num_overlay_plane++; 1189 config->num_overlay_plane++;
1205 1190
1206 drm_object_attach_property(&plane->base, 1191 drm_object_attach_property(&plane->base,
1207 dev->mode_config.plane_type_property, 1192 config->plane_type_property,
1208 plane->type); 1193 plane->type);
1209 1194
1195 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
1196 drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
1197 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
1198 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
1199 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
1200 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
1201 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
1202 drm_object_attach_property(&plane->base, config->prop_src_x, 0);
1203 drm_object_attach_property(&plane->base, config->prop_src_y, 0);
1204 drm_object_attach_property(&plane->base, config->prop_src_w, 0);
1205 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
1206 }
1207
1210 return 0; 1208 return 0;
1211} 1209}
1212EXPORT_SYMBOL(drm_universal_plane_init); 1210EXPORT_SYMBOL(drm_universal_plane_init);
@@ -1328,50 +1326,115 @@ void drm_plane_force_disable(struct drm_plane *plane)
1328} 1326}
1329EXPORT_SYMBOL(drm_plane_force_disable); 1327EXPORT_SYMBOL(drm_plane_force_disable);
1330 1328
1331static int drm_mode_create_standard_connector_properties(struct drm_device *dev) 1329static int drm_mode_create_standard_properties(struct drm_device *dev)
1332{ 1330{
1333 struct drm_property *edid; 1331 struct drm_property *prop;
1334 struct drm_property *dpms;
1335 struct drm_property *dev_path;
1336 1332
1337 /* 1333 /*
1338 * Standard properties (apply to all connectors) 1334 * Standard properties (apply to all connectors)
1339 */ 1335 */
1340 edid = drm_property_create(dev, DRM_MODE_PROP_BLOB | 1336 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
1341 DRM_MODE_PROP_IMMUTABLE, 1337 DRM_MODE_PROP_IMMUTABLE,
1342 "EDID", 0); 1338 "EDID", 0);
1343 dev->mode_config.edid_property = edid; 1339 if (!prop)
1340 return -ENOMEM;
1341 dev->mode_config.edid_property = prop;
1344 1342
1345 dpms = drm_property_create_enum(dev, 0, 1343 prop = drm_property_create_enum(dev, 0,
1346 "DPMS", drm_dpms_enum_list, 1344 "DPMS", drm_dpms_enum_list,
1347 ARRAY_SIZE(drm_dpms_enum_list)); 1345 ARRAY_SIZE(drm_dpms_enum_list));
1348 dev->mode_config.dpms_property = dpms; 1346 if (!prop)
1349 1347 return -ENOMEM;
1350 dev_path = drm_property_create(dev, 1348 dev->mode_config.dpms_property = prop;
1351 DRM_MODE_PROP_BLOB |
1352 DRM_MODE_PROP_IMMUTABLE,
1353 "PATH", 0);
1354 dev->mode_config.path_property = dev_path;
1355
1356 dev->mode_config.tile_property = drm_property_create(dev,
1357 DRM_MODE_PROP_BLOB |
1358 DRM_MODE_PROP_IMMUTABLE,
1359 "TILE", 0);
1360 1349
1361 return 0; 1350 prop = drm_property_create(dev,
1362} 1351 DRM_MODE_PROP_BLOB |
1352 DRM_MODE_PROP_IMMUTABLE,
1353 "PATH", 0);
1354 if (!prop)
1355 return -ENOMEM;
1356 dev->mode_config.path_property = prop;
1363 1357
1364static int drm_mode_create_standard_plane_properties(struct drm_device *dev) 1358 prop = drm_property_create(dev,
1365{ 1359 DRM_MODE_PROP_BLOB |
1366 struct drm_property *type; 1360 DRM_MODE_PROP_IMMUTABLE,
1361 "TILE", 0);
1362 if (!prop)
1363 return -ENOMEM;
1364 dev->mode_config.tile_property = prop;
1367 1365
1368 /* 1366 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1369 * Standard properties (apply to all planes)
1370 */
1371 type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1372 "type", drm_plane_type_enum_list, 1367 "type", drm_plane_type_enum_list,
1373 ARRAY_SIZE(drm_plane_type_enum_list)); 1368 ARRAY_SIZE(drm_plane_type_enum_list));
1374 dev->mode_config.plane_type_property = type; 1369 if (!prop)
1370 return -ENOMEM;
1371 dev->mode_config.plane_type_property = prop;
1372
1373 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1374 "SRC_X", 0, UINT_MAX);
1375 if (!prop)
1376 return -ENOMEM;
1377 dev->mode_config.prop_src_x = prop;
1378
1379 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1380 "SRC_Y", 0, UINT_MAX);
1381 if (!prop)
1382 return -ENOMEM;
1383 dev->mode_config.prop_src_y = prop;
1384
1385 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1386 "SRC_W", 0, UINT_MAX);
1387 if (!prop)
1388 return -ENOMEM;
1389 dev->mode_config.prop_src_w = prop;
1390
1391 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1392 "SRC_H", 0, UINT_MAX);
1393 if (!prop)
1394 return -ENOMEM;
1395 dev->mode_config.prop_src_h = prop;
1396
1397 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1398 "CRTC_X", INT_MIN, INT_MAX);
1399 if (!prop)
1400 return -ENOMEM;
1401 dev->mode_config.prop_crtc_x = prop;
1402
1403 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1404 "CRTC_Y", INT_MIN, INT_MAX);
1405 if (!prop)
1406 return -ENOMEM;
1407 dev->mode_config.prop_crtc_y = prop;
1408
1409 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1410 "CRTC_W", 0, INT_MAX);
1411 if (!prop)
1412 return -ENOMEM;
1413 dev->mode_config.prop_crtc_w = prop;
1414
1415 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1416 "CRTC_H", 0, INT_MAX);
1417 if (!prop)
1418 return -ENOMEM;
1419 dev->mode_config.prop_crtc_h = prop;
1420
1421 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1422 "FB_ID", DRM_MODE_OBJECT_FB);
1423 if (!prop)
1424 return -ENOMEM;
1425 dev->mode_config.prop_fb_id = prop;
1426
1427 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1428 "CRTC_ID", DRM_MODE_OBJECT_CRTC);
1429 if (!prop)
1430 return -ENOMEM;
1431 dev->mode_config.prop_crtc_id = prop;
1432
1433 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
1434 "ACTIVE");
1435 if (!prop)
1436 return -ENOMEM;
1437 dev->mode_config.prop_active = prop;
1375 1438
1376 return 0; 1439 return 0;
1377} 1440}
@@ -1597,16 +1660,14 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
1597 total_objects += dev->mode_config.num_crtc; 1660 total_objects += dev->mode_config.num_crtc;
1598 total_objects += dev->mode_config.num_connector; 1661 total_objects += dev->mode_config.num_connector;
1599 total_objects += dev->mode_config.num_encoder; 1662 total_objects += dev->mode_config.num_encoder;
1600 total_objects += dev->mode_config.num_bridge;
1601 1663
1602 group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); 1664 group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL);
1603 if (!group->id_list) 1665 if (!group->id_list)
1604 return -ENOMEM; 1666 return -ENOMEM;
1605 1667
1606 group->num_crtcs = 0; 1668 group->num_crtcs = 0;
1607 group->num_connectors = 0; 1669 group->num_connectors = 0;
1608 group->num_encoders = 0; 1670 group->num_encoders = 0;
1609 group->num_bridges = 0;
1610 return 0; 1671 return 0;
1611} 1672}
1612 1673
@@ -1626,10 +1687,10 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1626 struct drm_crtc *crtc; 1687 struct drm_crtc *crtc;
1627 struct drm_encoder *encoder; 1688 struct drm_encoder *encoder;
1628 struct drm_connector *connector; 1689 struct drm_connector *connector;
1629 struct drm_bridge *bridge;
1630 int ret; 1690 int ret;
1631 1691
1632 if ((ret = drm_mode_group_init(dev, group))) 1692 ret = drm_mode_group_init(dev, group);
1693 if (ret)
1633 return ret; 1694 return ret;
1634 1695
1635 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 1696 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
@@ -1643,11 +1704,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1643 group->id_list[group->num_crtcs + group->num_encoders + 1704 group->id_list[group->num_crtcs + group->num_encoders +
1644 group->num_connectors++] = connector->base.id; 1705 group->num_connectors++] = connector->base.id;
1645 1706
1646 list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
1647 group->id_list[group->num_crtcs + group->num_encoders +
1648 group->num_connectors + group->num_bridges++] =
1649 bridge->base.id;
1650
1651 return 0; 1707 return 0;
1652} 1708}
1653EXPORT_SYMBOL(drm_mode_group_init_legacy_group); 1709EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
@@ -1996,6 +2052,44 @@ static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *conne
1996 return connector->encoder; 2052 return connector->encoder;
1997} 2053}
1998 2054
2055/* helper for getconnector and getproperties ioctls */
2056static int get_properties(struct drm_mode_object *obj, bool atomic,
2057 uint32_t __user *prop_ptr, uint64_t __user *prop_values,
2058 uint32_t *arg_count_props)
2059{
2060 int props_count;
2061 int i, ret, copied;
2062
2063 props_count = obj->properties->count;
2064 if (!atomic)
2065 props_count -= obj->properties->atomic_count;
2066
2067 if ((*arg_count_props >= props_count) && props_count) {
2068 for (i = 0, copied = 0; copied < props_count; i++) {
2069 struct drm_property *prop = obj->properties->properties[i];
2070 uint64_t val;
2071
2072 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
2073 continue;
2074
2075 ret = drm_object_property_get_value(obj, prop, &val);
2076 if (ret)
2077 return ret;
2078
2079 if (put_user(prop->base.id, prop_ptr + copied))
2080 return -EFAULT;
2081
2082 if (put_user(val, prop_values + copied))
2083 return -EFAULT;
2084
2085 copied++;
2086 }
2087 }
2088 *arg_count_props = props_count;
2089
2090 return 0;
2091}
2092
1999/** 2093/**
2000 * drm_mode_getconnector - get connector configuration 2094 * drm_mode_getconnector - get connector configuration
2001 * @dev: drm device for the ioctl 2095 * @dev: drm device for the ioctl
@@ -2017,15 +2111,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2017 struct drm_encoder *encoder; 2111 struct drm_encoder *encoder;
2018 struct drm_display_mode *mode; 2112 struct drm_display_mode *mode;
2019 int mode_count = 0; 2113 int mode_count = 0;
2020 int props_count = 0;
2021 int encoders_count = 0; 2114 int encoders_count = 0;
2022 int ret = 0; 2115 int ret = 0;
2023 int copied = 0; 2116 int copied = 0;
2024 int i; 2117 int i;
2025 struct drm_mode_modeinfo u_mode; 2118 struct drm_mode_modeinfo u_mode;
2026 struct drm_mode_modeinfo __user *mode_ptr; 2119 struct drm_mode_modeinfo __user *mode_ptr;
2027 uint32_t __user *prop_ptr;
2028 uint64_t __user *prop_values;
2029 uint32_t __user *encoder_ptr; 2120 uint32_t __user *encoder_ptr;
2030 2121
2031 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2122 if (!drm_core_check_feature(dev, DRIVER_MODESET))
@@ -2043,13 +2134,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2043 goto out; 2134 goto out;
2044 } 2135 }
2045 2136
2046 props_count = connector->properties.count; 2137 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
2047 2138 if (connector->encoder_ids[i] != 0)
2048 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2049 if (connector->encoder_ids[i] != 0) {
2050 encoders_count++; 2139 encoders_count++;
2051 }
2052 }
2053 2140
2054 if (out_resp->count_modes == 0) { 2141 if (out_resp->count_modes == 0) {
2055 connector->funcs->fill_modes(connector, 2142 connector->funcs->fill_modes(connector,
@@ -2069,14 +2156,13 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2069 out_resp->mm_height = connector->display_info.height_mm; 2156 out_resp->mm_height = connector->display_info.height_mm;
2070 out_resp->subpixel = connector->display_info.subpixel_order; 2157 out_resp->subpixel = connector->display_info.subpixel_order;
2071 out_resp->connection = connector->status; 2158 out_resp->connection = connector->status;
2072 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2073 2159
2160 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2074 encoder = drm_connector_get_encoder(connector); 2161 encoder = drm_connector_get_encoder(connector);
2075 if (encoder) 2162 if (encoder)
2076 out_resp->encoder_id = encoder->base.id; 2163 out_resp->encoder_id = encoder->base.id;
2077 else 2164 else
2078 out_resp->encoder_id = 0; 2165 out_resp->encoder_id = 0;
2079 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2080 2166
2081 /* 2167 /*
2082 * This ioctl is called twice, once to determine how much space is 2168 * This ioctl is called twice, once to determine how much space is
@@ -2100,26 +2186,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2100 } 2186 }
2101 out_resp->count_modes = mode_count; 2187 out_resp->count_modes = mode_count;
2102 2188
2103 if ((out_resp->count_props >= props_count) && props_count) { 2189 ret = get_properties(&connector->base, file_priv->atomic,
2104 copied = 0; 2190 (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
2105 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr); 2191 (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
2106 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr); 2192 &out_resp->count_props);
2107 for (i = 0; i < connector->properties.count; i++) { 2193 if (ret)
2108 if (put_user(connector->properties.ids[i], 2194 goto out;
2109 prop_ptr + copied)) {
2110 ret = -EFAULT;
2111 goto out;
2112 }
2113
2114 if (put_user(connector->properties.values[i],
2115 prop_values + copied)) {
2116 ret = -EFAULT;
2117 goto out;
2118 }
2119 copied++;
2120 }
2121 }
2122 out_resp->count_props = props_count;
2123 2195
2124 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 2196 if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
2125 copied = 0; 2197 copied = 0;
@@ -2138,6 +2210,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2138 out_resp->count_encoders = encoders_count; 2210 out_resp->count_encoders = encoders_count;
2139 2211
2140out: 2212out:
2213 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2141 mutex_unlock(&dev->mode_config.mutex); 2214 mutex_unlock(&dev->mode_config.mutex);
2142 2215
2143 return ret; 2216 return ret;
@@ -2529,7 +2602,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
2529 * 2602 *
2530 * This is a little helper to wrap internal calls to the ->set_config driver 2603 * This is a little helper to wrap internal calls to the ->set_config driver
2531 * interface. The only thing it adds is correct refcounting dance. 2604 * interface. The only thing it adds is correct refcounting dance.
2532 * 2605 *
2533 * Returns: 2606 * Returns:
2534 * Zero on success, negative errno on failure. 2607 * Zero on success, negative errno on failure.
2535 */ 2608 */
@@ -2569,6 +2642,27 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
2569EXPORT_SYMBOL(drm_mode_set_config_internal); 2642EXPORT_SYMBOL(drm_mode_set_config_internal);
2570 2643
2571/** 2644/**
2645 * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
2646 * @mode: mode to query
2647 * @hdisplay: hdisplay value to fill in
2648 * @vdisplay: vdisplay value to fill in
2649 *
2650 * The vdisplay value will be doubled if the specified mode is a stereo mode of
2651 * the appropriate layout.
2652 */
2653void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
2654 int *hdisplay, int *vdisplay)
2655{
2656 struct drm_display_mode adjusted;
2657
2658 drm_mode_copy(&adjusted, mode);
2659 drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
2660 *hdisplay = adjusted.crtc_hdisplay;
2661 *vdisplay = adjusted.crtc_vdisplay;
2662}
2663EXPORT_SYMBOL(drm_crtc_get_hv_timing);
2664
2665/**
2572 * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the 2666 * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
2573 * CRTC viewport 2667 * CRTC viewport
2574 * @crtc: CRTC that framebuffer will be displayed on 2668 * @crtc: CRTC that framebuffer will be displayed on
@@ -2585,16 +2679,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
2585{ 2679{
2586 int hdisplay, vdisplay; 2680 int hdisplay, vdisplay;
2587 2681
2588 hdisplay = mode->hdisplay; 2682 drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
2589 vdisplay = mode->vdisplay;
2590
2591 if (drm_mode_is_stereo(mode)) {
2592 struct drm_display_mode adjusted = *mode;
2593
2594 drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE);
2595 hdisplay = adjusted.crtc_hdisplay;
2596 vdisplay = adjusted.crtc_vdisplay;
2597 }
2598 2683
2599 if (crtc->invert_dimensions) 2684 if (crtc->invert_dimensions)
2600 swap(hdisplay, vdisplay); 2685 swap(hdisplay, vdisplay);
@@ -2690,6 +2775,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
2690 goto out; 2775 goto out;
2691 } 2776 }
2692 2777
2778 mode->status = drm_mode_validate_basic(mode);
2779 if (mode->status != MODE_OK) {
2780 ret = -EINVAL;
2781 goto out;
2782 }
2783
2693 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 2784 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
2694 2785
2695 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y, 2786 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
@@ -2721,9 +2812,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
2721 goto out; 2812 goto out;
2722 } 2813 }
2723 2814
2724 connector_set = kmalloc(crtc_req->count_connectors * 2815 connector_set = kmalloc_array(crtc_req->count_connectors,
2725 sizeof(struct drm_connector *), 2816 sizeof(struct drm_connector *),
2726 GFP_KERNEL); 2817 GFP_KERNEL);
2727 if (!connector_set) { 2818 if (!connector_set) {
2728 ret = -ENOMEM; 2819 ret = -ENOMEM;
2729 goto out; 2820 goto out;
@@ -2968,6 +3059,7 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev,
2968 void *data, struct drm_file *file_priv) 3059 void *data, struct drm_file *file_priv)
2969{ 3060{
2970 struct drm_mode_cursor2 *req = data; 3061 struct drm_mode_cursor2 *req = data;
3062
2971 return drm_mode_cursor_common(dev, req, file_priv); 3063 return drm_mode_cursor_common(dev, req, file_priv);
2972} 3064}
2973 3065
@@ -3415,7 +3507,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
3415 ret = -EINVAL; 3507 ret = -EINVAL;
3416 goto out_err1; 3508 goto out_err1;
3417 } 3509 }
3418 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); 3510 clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
3419 if (!clips) { 3511 if (!clips) {
3420 ret = -ENOMEM; 3512 ret = -ENOMEM;
3421 goto out_err1; 3513 goto out_err1;
@@ -3516,7 +3608,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3516 property->dev = dev; 3608 property->dev = dev;
3517 3609
3518 if (num_values) { 3610 if (num_values) {
3519 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); 3611 property->values = kcalloc(num_values, sizeof(uint64_t),
3612 GFP_KERNEL);
3520 if (!property->values) 3613 if (!property->values)
3521 goto fail; 3614 goto fail;
3522 } 3615 }
@@ -3665,7 +3758,7 @@ static struct drm_property *property_create_range(struct drm_device *dev,
3665} 3758}
3666 3759
3667/** 3760/**
3668 * drm_property_create_range - create a new ranged property type 3761 * drm_property_create_range - create a new unsigned ranged property type
3669 * @dev: drm device 3762 * @dev: drm device
3670 * @flags: flags specifying the property type 3763 * @flags: flags specifying the property type
3671 * @name: name of the property 3764 * @name: name of the property
@@ -3676,8 +3769,8 @@ static struct drm_property *property_create_range(struct drm_device *dev,
3676 * object with drm_object_attach_property. The returned property object must be 3769 * object with drm_object_attach_property. The returned property object must be
3677 * freed with drm_property_destroy. 3770 * freed with drm_property_destroy.
3678 * 3771 *
3679 * Userspace is allowed to set any integer value in the (min, max) range 3772 * Userspace is allowed to set any unsigned integer value in the (min, max)
3680 * inclusive. 3773 * range inclusive.
3681 * 3774 *
3682 * Returns: 3775 * Returns:
3683 * A pointer to the newly created property on success, NULL on failure. 3776 * A pointer to the newly created property on success, NULL on failure.
@@ -3691,6 +3784,24 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags
3691} 3784}
3692EXPORT_SYMBOL(drm_property_create_range); 3785EXPORT_SYMBOL(drm_property_create_range);
3693 3786
3787/**
3788 * drm_property_create_signed_range - create a new signed ranged property type
3789 * @dev: drm device
3790 * @flags: flags specifying the property type
3791 * @name: name of the property
3792 * @min: minimum value of the property
3793 * @max: maximum value of the property
3794 *
3795 * This creates a new generic drm property which can then be attached to a drm
3796 * object with drm_object_attach_property. The returned property object must be
3797 * freed with drm_property_destroy.
3798 *
3799 * Userspace is allowed to set any signed integer value in the (min, max)
3800 * range inclusive.
3801 *
3802 * Returns:
3803 * A pointer to the newly created property on success, NULL on failure.
3804 */
3694struct drm_property *drm_property_create_signed_range(struct drm_device *dev, 3805struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
3695 int flags, const char *name, 3806 int flags, const char *name,
3696 int64_t min, int64_t max) 3807 int64_t min, int64_t max)
@@ -3700,6 +3811,23 @@ struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
3700} 3811}
3701EXPORT_SYMBOL(drm_property_create_signed_range); 3812EXPORT_SYMBOL(drm_property_create_signed_range);
3702 3813
3814/**
3815 * drm_property_create_object - create a new object property type
3816 * @dev: drm device
3817 * @flags: flags specifying the property type
3818 * @name: name of the property
3819 * @type: object type from DRM_MODE_OBJECT_* defines
3820 *
3821 * This creates a new generic drm property which can then be attached to a drm
3822 * object with drm_object_attach_property. The returned property object must be
3823 * freed with drm_property_destroy.
3824 *
3825 * Userspace is only allowed to set this to any property value of the given
3826 * @type. Only useful for atomic properties, which is enforced.
3827 *
3828 * Returns:
3829 * A pointer to the newly created property on success, NULL on failure.
3830 */
3703struct drm_property *drm_property_create_object(struct drm_device *dev, 3831struct drm_property *drm_property_create_object(struct drm_device *dev,
3704 int flags, const char *name, uint32_t type) 3832 int flags, const char *name, uint32_t type)
3705{ 3833{
@@ -3707,6 +3835,9 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
3707 3835
3708 flags |= DRM_MODE_PROP_OBJECT; 3836 flags |= DRM_MODE_PROP_OBJECT;
3709 3837
3838 if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC)))
3839 return NULL;
3840
3710 property = drm_property_create(dev, flags, name, 1); 3841 property = drm_property_create(dev, flags, name, 1);
3711 if (!property) 3842 if (!property)
3712 return NULL; 3843 return NULL;
@@ -3718,6 +3849,28 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
3718EXPORT_SYMBOL(drm_property_create_object); 3849EXPORT_SYMBOL(drm_property_create_object);
3719 3850
3720/** 3851/**
3852 * drm_property_create_bool - create a new boolean property type
3853 * @dev: drm device
3854 * @flags: flags specifying the property type
3855 * @name: name of the property
3856 *
3857 * This creates a new generic drm property which can then be attached to a drm
3858 * object with drm_object_attach_property. The returned property object must be
3859 * freed with drm_property_destroy.
3860 *
3861 * This is implemented as a ranged property with only {0, 1} as valid values.
3862 *
3863 * Returns:
3864 * A pointer to the newly created property on success, NULL on failure.
3865 */
3866struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
3867 const char *name)
3868{
3869 return drm_property_create_range(dev, flags, name, 0, 1);
3870}
3871EXPORT_SYMBOL(drm_property_create_bool);
3872
3873/**
3721 * drm_property_add_enum - add a possible value to an enumeration property 3874 * drm_property_add_enum - add a possible value to an enumeration property
3722 * @property: enumeration property to change 3875 * @property: enumeration property to change
3723 * @index: index of the new enumeration 3876 * @index: index of the new enumeration
@@ -3822,9 +3975,11 @@ void drm_object_attach_property(struct drm_mode_object *obj,
3822 return; 3975 return;
3823 } 3976 }
3824 3977
3825 obj->properties->ids[count] = property->base.id; 3978 obj->properties->properties[count] = property;
3826 obj->properties->values[count] = init_val; 3979 obj->properties->values[count] = init_val;
3827 obj->properties->count++; 3980 obj->properties->count++;
3981 if (property->flags & DRM_MODE_PROP_ATOMIC)
3982 obj->properties->atomic_count++;
3828} 3983}
3829EXPORT_SYMBOL(drm_object_attach_property); 3984EXPORT_SYMBOL(drm_object_attach_property);
3830 3985
@@ -3847,7 +4002,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
3847 int i; 4002 int i;
3848 4003
3849 for (i = 0; i < obj->properties->count; i++) { 4004 for (i = 0; i < obj->properties->count; i++) {
3850 if (obj->properties->ids[i] == property->base.id) { 4005 if (obj->properties->properties[i] == property) {
3851 obj->properties->values[i] = val; 4006 obj->properties->values[i] = val;
3852 return 0; 4007 return 0;
3853 } 4008 }
@@ -3876,8 +4031,16 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
3876{ 4031{
3877 int i; 4032 int i;
3878 4033
4034 /* read-only properties bypass atomic mechanism and still store
4035 * their value in obj->properties->values[].. mostly to avoid
4036 * having to deal w/ EDID and similar props in atomic paths:
4037 */
4038 if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
4039 !(property->flags & DRM_MODE_PROP_IMMUTABLE))
4040 return drm_atomic_get_property(obj, property, val);
4041
3879 for (i = 0; i < obj->properties->count; i++) { 4042 for (i = 0; i < obj->properties->count; i++) {
3880 if (obj->properties->ids[i] == property->base.id) { 4043 if (obj->properties->properties[i] == property) {
3881 *val = obj->properties->values[i]; 4044 *val = obj->properties->values[i];
3882 return 0; 4045 return 0;
3883 } 4046 }
@@ -4057,7 +4220,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
4057 4220
4058 if (out_resp->length == blob->length) { 4221 if (out_resp->length == blob->length) {
4059 blob_ptr = (void __user *)(unsigned long)out_resp->data; 4222 blob_ptr = (void __user *)(unsigned long)out_resp->data;
4060 if (copy_to_user(blob_ptr, blob->data, blob->length)){ 4223 if (copy_to_user(blob_ptr, blob->data, blob->length)) {
4061 ret = -EFAULT; 4224 ret = -EFAULT;
4062 goto done; 4225 goto done;
4063 } 4226 }
@@ -4193,25 +4356,38 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4193} 4356}
4194EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 4357EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
4195 4358
4196static bool drm_property_change_is_valid(struct drm_property *property, 4359/* Some properties could refer to dynamic refcnt'd objects, or things that
4197 uint64_t value) 4360 * need special locking to handle lifetime issues (ie. to ensure the prop
4361 * value doesn't become invalid part way through the property update due to
4362 * race). The value returned by reference via 'obj' should be passed back
4363 * to drm_property_change_valid_put() after the property is set (and the
4364 * object to which the property is attached has a chance to take it's own
4365 * reference).
4366 */
4367bool drm_property_change_valid_get(struct drm_property *property,
4368 uint64_t value, struct drm_mode_object **ref)
4198{ 4369{
4370 int i;
4371
4199 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 4372 if (property->flags & DRM_MODE_PROP_IMMUTABLE)
4200 return false; 4373 return false;
4201 4374
4375 *ref = NULL;
4376
4202 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) { 4377 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
4203 if (value < property->values[0] || value > property->values[1]) 4378 if (value < property->values[0] || value > property->values[1])
4204 return false; 4379 return false;
4205 return true; 4380 return true;
4206 } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) { 4381 } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) {
4207 int64_t svalue = U642I64(value); 4382 int64_t svalue = U642I64(value);
4383
4208 if (svalue < U642I64(property->values[0]) || 4384 if (svalue < U642I64(property->values[0]) ||
4209 svalue > U642I64(property->values[1])) 4385 svalue > U642I64(property->values[1]))
4210 return false; 4386 return false;
4211 return true; 4387 return true;
4212 } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 4388 } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
4213 int i;
4214 uint64_t valid_mask = 0; 4389 uint64_t valid_mask = 0;
4390
4215 for (i = 0; i < property->num_values; i++) 4391 for (i = 0; i < property->num_values; i++)
4216 valid_mask |= (1ULL << property->values[i]); 4392 valid_mask |= (1ULL << property->values[i]);
4217 return !(value & ~valid_mask); 4393 return !(value & ~valid_mask);
@@ -4219,25 +4395,40 @@ static bool drm_property_change_is_valid(struct drm_property *property,
4219 /* Only the driver knows */ 4395 /* Only the driver knows */
4220 return true; 4396 return true;
4221 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 4397 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4222 struct drm_mode_object *obj;
4223 /* a zero value for an object property translates to null: */ 4398 /* a zero value for an object property translates to null: */
4224 if (value == 0) 4399 if (value == 0)
4225 return true; 4400 return true;
4226 /* 4401
4227 * NOTE: use _object_find() directly to bypass restriction on 4402 /* handle refcnt'd objects specially: */
4228 * looking up refcnt'd objects (ie. fb's). For a refcnt'd 4403 if (property->values[0] == DRM_MODE_OBJECT_FB) {
4229 * object this could race against object finalization, so it 4404 struct drm_framebuffer *fb;
4230 * simply tells us that the object *was* valid. Which is good 4405 fb = drm_framebuffer_lookup(property->dev, value);
4231 * enough. 4406 if (fb) {
4232 */ 4407 *ref = &fb->base;
4233 obj = _object_find(property->dev, value, property->values[0]);
4234 return obj != NULL;
4235 } else {
4236 int i;
4237 for (i = 0; i < property->num_values; i++)
4238 if (property->values[i] == value)
4239 return true; 4408 return true;
4240 return false; 4409 } else {
4410 return false;
4411 }
4412 } else {
4413 return _object_find(property->dev, value, property->values[0]) != NULL;
4414 }
4415 }
4416
4417 for (i = 0; i < property->num_values; i++)
4418 if (property->values[i] == value)
4419 return true;
4420 return false;
4421}
4422
4423void drm_property_change_valid_put(struct drm_property *property,
4424 struct drm_mode_object *ref)
4425{
4426 if (!ref)
4427 return;
4428
4429 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4430 if (property->values[0] == DRM_MODE_OBJECT_FB)
4431 drm_framebuffer_unreference(obj_to_fb(ref));
4241 } 4432 }
4242} 4433}
4243 4434
@@ -4356,11 +4547,6 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4356 struct drm_mode_obj_get_properties *arg = data; 4547 struct drm_mode_obj_get_properties *arg = data;
4357 struct drm_mode_object *obj; 4548 struct drm_mode_object *obj;
4358 int ret = 0; 4549 int ret = 0;
4359 int i;
4360 int copied = 0;
4361 int props_count = 0;
4362 uint32_t __user *props_ptr;
4363 uint64_t __user *prop_values_ptr;
4364 4550
4365 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4551 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4366 return -EINVAL; 4552 return -EINVAL;
@@ -4377,30 +4563,11 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4377 goto out; 4563 goto out;
4378 } 4564 }
4379 4565
4380 props_count = obj->properties->count; 4566 ret = get_properties(obj, file_priv->atomic,
4567 (uint32_t __user *)(unsigned long)(arg->props_ptr),
4568 (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
4569 &arg->count_props);
4381 4570
4382 /* This ioctl is called twice, once to determine how much space is
4383 * needed, and the 2nd time to fill it. */
4384 if ((arg->count_props >= props_count) && props_count) {
4385 copied = 0;
4386 props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
4387 prop_values_ptr = (uint64_t __user *)(unsigned long)
4388 (arg->prop_values_ptr);
4389 for (i = 0; i < props_count; i++) {
4390 if (put_user(obj->properties->ids[i],
4391 props_ptr + copied)) {
4392 ret = -EFAULT;
4393 goto out;
4394 }
4395 if (put_user(obj->properties->values[i],
4396 prop_values_ptr + copied)) {
4397 ret = -EFAULT;
4398 goto out;
4399 }
4400 copied++;
4401 }
4402 }
4403 arg->count_props = props_count;
4404out: 4571out:
4405 drm_modeset_unlock_all(dev); 4572 drm_modeset_unlock_all(dev);
4406 return ret; 4573 return ret;
@@ -4429,8 +4596,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4429 struct drm_mode_object *arg_obj; 4596 struct drm_mode_object *arg_obj;
4430 struct drm_mode_object *prop_obj; 4597 struct drm_mode_object *prop_obj;
4431 struct drm_property *property; 4598 struct drm_property *property;
4432 int ret = -EINVAL; 4599 int i, ret = -EINVAL;
4433 int i; 4600 struct drm_mode_object *ref;
4434 4601
4435 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4602 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4436 return -EINVAL; 4603 return -EINVAL;
@@ -4446,7 +4613,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4446 goto out; 4613 goto out;
4447 4614
4448 for (i = 0; i < arg_obj->properties->count; i++) 4615 for (i = 0; i < arg_obj->properties->count; i++)
4449 if (arg_obj->properties->ids[i] == arg->prop_id) 4616 if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
4450 break; 4617 break;
4451 4618
4452 if (i == arg_obj->properties->count) 4619 if (i == arg_obj->properties->count)
@@ -4460,7 +4627,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4460 } 4627 }
4461 property = obj_to_property(prop_obj); 4628 property = obj_to_property(prop_obj);
4462 4629
4463 if (!drm_property_change_is_valid(property, arg->value)) 4630 if (!drm_property_change_valid_get(property, arg->value, &ref))
4464 goto out; 4631 goto out;
4465 4632
4466 switch (arg_obj->type) { 4633 switch (arg_obj->type) {
@@ -4477,6 +4644,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4477 break; 4644 break;
4478 } 4645 }
4479 4646
4647 drm_property_change_valid_put(property, ref);
4648
4480out: 4649out:
4481 drm_modeset_unlock_all(dev); 4650 drm_modeset_unlock_all(dev);
4482 return ret; 4651 return ret;
@@ -4526,7 +4695,8 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
4526{ 4695{
4527 crtc->gamma_size = gamma_size; 4696 crtc->gamma_size = gamma_size;
4528 4697
4529 crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); 4698 crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3,
4699 GFP_KERNEL);
4530 if (!crtc->gamma_store) { 4700 if (!crtc->gamma_store) {
4531 crtc->gamma_size = 0; 4701 crtc->gamma_size = 0;
4532 return -ENOMEM; 4702 return -ENOMEM;
@@ -4741,23 +4911,23 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
4741 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 4911 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
4742 ret = -ENOMEM; 4912 ret = -ENOMEM;
4743 spin_lock_irqsave(&dev->event_lock, flags); 4913 spin_lock_irqsave(&dev->event_lock, flags);
4744 if (file_priv->event_space < sizeof e->event) { 4914 if (file_priv->event_space < sizeof(e->event)) {
4745 spin_unlock_irqrestore(&dev->event_lock, flags); 4915 spin_unlock_irqrestore(&dev->event_lock, flags);
4746 goto out; 4916 goto out;
4747 } 4917 }
4748 file_priv->event_space -= sizeof e->event; 4918 file_priv->event_space -= sizeof(e->event);
4749 spin_unlock_irqrestore(&dev->event_lock, flags); 4919 spin_unlock_irqrestore(&dev->event_lock, flags);
4750 4920
4751 e = kzalloc(sizeof *e, GFP_KERNEL); 4921 e = kzalloc(sizeof(*e), GFP_KERNEL);
4752 if (e == NULL) { 4922 if (e == NULL) {
4753 spin_lock_irqsave(&dev->event_lock, flags); 4923 spin_lock_irqsave(&dev->event_lock, flags);
4754 file_priv->event_space += sizeof e->event; 4924 file_priv->event_space += sizeof(e->event);
4755 spin_unlock_irqrestore(&dev->event_lock, flags); 4925 spin_unlock_irqrestore(&dev->event_lock, flags);
4756 goto out; 4926 goto out;
4757 } 4927 }
4758 4928
4759 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 4929 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
4760 e->event.base.length = sizeof e->event; 4930 e->event.base.length = sizeof(e->event);
4761 e->event.user_data = page_flip->user_data; 4931 e->event.user_data = page_flip->user_data;
4762 e->base.event = &e->event.base; 4932 e->base.event = &e->event.base;
4763 e->base.file_priv = file_priv; 4933 e->base.file_priv = file_priv;
@@ -4770,7 +4940,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
4770 if (ret) { 4940 if (ret) {
4771 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 4941 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
4772 spin_lock_irqsave(&dev->event_lock, flags); 4942 spin_lock_irqsave(&dev->event_lock, flags);
4773 file_priv->event_space += sizeof e->event; 4943 file_priv->event_space += sizeof(e->event);
4774 spin_unlock_irqrestore(&dev->event_lock, flags); 4944 spin_unlock_irqrestore(&dev->event_lock, flags);
4775 kfree(e); 4945 kfree(e);
4776 } 4946 }
@@ -5211,7 +5381,6 @@ void drm_mode_config_init(struct drm_device *dev)
5211 INIT_LIST_HEAD(&dev->mode_config.fb_list); 5381 INIT_LIST_HEAD(&dev->mode_config.fb_list);
5212 INIT_LIST_HEAD(&dev->mode_config.crtc_list); 5382 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
5213 INIT_LIST_HEAD(&dev->mode_config.connector_list); 5383 INIT_LIST_HEAD(&dev->mode_config.connector_list);
5214 INIT_LIST_HEAD(&dev->mode_config.bridge_list);
5215 INIT_LIST_HEAD(&dev->mode_config.encoder_list); 5384 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
5216 INIT_LIST_HEAD(&dev->mode_config.property_list); 5385 INIT_LIST_HEAD(&dev->mode_config.property_list);
5217 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 5386 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
@@ -5220,8 +5389,7 @@ void drm_mode_config_init(struct drm_device *dev)
5220 idr_init(&dev->mode_config.tile_idr); 5389 idr_init(&dev->mode_config.tile_idr);
5221 5390
5222 drm_modeset_lock_all(dev); 5391 drm_modeset_lock_all(dev);
5223 drm_mode_create_standard_connector_properties(dev); 5392 drm_mode_create_standard_properties(dev);
5224 drm_mode_create_standard_plane_properties(dev);
5225 drm_modeset_unlock_all(dev); 5393 drm_modeset_unlock_all(dev);
5226 5394
5227 /* Just to be sure */ 5395 /* Just to be sure */
@@ -5252,7 +5420,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5252 struct drm_connector *connector, *ot; 5420 struct drm_connector *connector, *ot;
5253 struct drm_crtc *crtc, *ct; 5421 struct drm_crtc *crtc, *ct;
5254 struct drm_encoder *encoder, *enct; 5422 struct drm_encoder *encoder, *enct;
5255 struct drm_bridge *bridge, *brt;
5256 struct drm_framebuffer *fb, *fbt; 5423 struct drm_framebuffer *fb, *fbt;
5257 struct drm_property *property, *pt; 5424 struct drm_property *property, *pt;
5258 struct drm_property_blob *blob, *bt; 5425 struct drm_property_blob *blob, *bt;
@@ -5263,11 +5430,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5263 encoder->funcs->destroy(encoder); 5430 encoder->funcs->destroy(encoder);
5264 } 5431 }
5265 5432
5266 list_for_each_entry_safe(bridge, brt,
5267 &dev->mode_config.bridge_list, head) {
5268 bridge->funcs->destroy(bridge);
5269 }
5270
5271 list_for_each_entry_safe(connector, ot, 5433 list_for_each_entry_safe(connector, ot,
5272 &dev->mode_config.connector_list, head) { 5434 &dev->mode_config.connector_list, head) {
5273 connector->funcs->destroy(connector); 5435 connector->funcs->destroy(connector);