diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 7bb3845..688ca75 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -415,6 +415,8 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
 
 	if (property == config->prop_active)
 		state->active = val;
+	else if (property == config->prop_background_color)
+		state->background_color.v = val;
 	else if (property == config->prop_mode_id) {
 		struct drm_property_blob *mode =
 			drm_property_lookup_blob(dev, val);
@@ -450,6 +452,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
 		*val = state->active;
 	else if (property == config->prop_mode_id)
 		*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
+	else if (property == config->prop_background_color)
+		*val = state->background_color.v;
 	else if (crtc->funcs->atomic_get_property)
 		return crtc->funcs->atomic_get_property(crtc, state, property, val);
 	else
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e54660a..1e0dd09 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3807,6 +3807,30 @@ struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
 EXPORT_SYMBOL(drm_property_create_bool);
 
 /**
+ * drm_property_create_rgba - create a new RGBA property type
+ * @dev: drm device
+ * @flags: flags specifying the property type
+ * @name: name of the property
+ *
+ * This creates a new generic drm property which can then be attached to a drm
+ * object with drm_object_attach_property. The returned property object must be
+ * freed with drm_property_destroy.
+ *
+ * Userspace should use the DRM_RGBA() macro to build values with the proper
+ * bit layout.
+ *
+ * Returns:
+ * A pointer to the newly created property on success, NULL on failure.
+ */
+struct drm_property *drm_property_create_rgba(struct drm_device *dev, int flags,
+					      const char *name)
+{
+	return drm_property_create_range(dev, flags, name,
+					 0, GENMASK_ULL(63, 0));
+}
+EXPORT_SYMBOL(drm_property_create_rgba);
+
+/**
  * drm_property_add_enum - add a possible value to an enumeration property
  * @property: enumeration property to change
  * @index: index of the new enumeration
@@ -5778,6 +5802,15 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_mode_create_rotation_property);
 
+struct drm_property
+*drm_mode_create_background_color_property(struct drm_device *dev)
+{
+	return drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+					 "background_color",
+					 0, GENMASK_ULL(63, 0));
+}
+EXPORT_SYMBOL(drm_mode_create_background_color_property);
+
 /**
  * DOC: Tile group
  *
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3f0c690..64f3e62 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -251,6 +251,45 @@ struct drm_bridge;
 struct drm_atomic_state;
 
 /**
+ * drm_rgba_t - RGBA property value type
+ *
+ * Structure to abstract away the representation of RGBA values with precision
+ * up to 16 bits per color component.  This is primarily intended for use with
+ * DRM properties that need to take a color value since we don't want userspace
+ * to have to worry about the bit layout expected by the underlying hardware.
+ *
+ * We wrap the value in a structure here so that the compiler will flag any
+ * accidental attempts by driver code to directly attempt bitwise operations
+ * that could potentially misinterpret the value.  Drivers should instead use
+ * the DRM_RGBA_{RED,GREEN,BLUE,ALPHA}BITS() macros to obtain the component
+ * bits and then build values in the format their hardware expects.
+ */
+typedef struct {
+	uint64_t v;
+} drm_rgba_t;
+
+static inline uint16_t
+drm_rgba_bits(drm_rgba_t c, unsigned compshift, unsigned bits) {
+	uint64_t val;
+
+	if (WARN_ON(bits > 16))
+		bits = 16;
+
+	val = c.v & GENMASK_ULL(compshift + 15, compshift);
+	return val >> (compshift + 16 - bits);
+}
+
+/*
+ * Macros to access the individual color components of an RGBA property value.
+ * If the requested number of bits is less than 16, only the most significant
+ * bits of the color component will be returned.
+ */
+#define DRM_RGBA_REDBITS(c, bits)   drm_rgba_bits(c, 48, bits)
+#define DRM_RGBA_GREENBITS(c, bits) drm_rgba_bits(c, 32, bits)
+#define DRM_RGBA_BLUEBITS(c, bits)  drm_rgba_bits(c, 16, bits)
+#define DRM_RGBA_ALPHABITS(c, bits) drm_rgba_bits(c, 0, bits)
+
+/**
  * struct drm_crtc_state - mutable CRTC state
  * @crtc: backpointer to the CRTC
  * @enable: whether the CRTC should be enabled, gates all other state
@@ -264,6 +303,7 @@ struct drm_atomic_state;
  * 	update to ensure framebuffer cleanup isn't done too early
  * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
  * @mode: current mode timings
+ * @background_color: background color of regions not covered by planes
  * @event: optional pointer to a DRM event to signal upon completion of the
  * 	state update
  * @state: backpointer to global drm_atomic_state
@@ -304,6 +344,9 @@ struct drm_crtc_state {
 	/* blob property to expose current mode to atomic userspace */
 	struct drm_property_blob *mode_blob;
 
+	/* CRTC background color */
+	drm_rgba_t background_color;
+
 	struct drm_pending_vblank_event *event;
 
 	struct drm_atomic_state *state;
@@ -1115,6 +1158,9 @@ struct drm_mode_config {
 	struct drm_property *prop_active;
 	struct drm_property *prop_mode_id;
 
+	/* crtc properties */
+	struct drm_property *prop_background_color;
+
 	/* DVI-I properties */
 	struct drm_property *dvi_i_subconnector_property;
 	struct drm_property *dvi_i_select_subconnector_property;
@@ -1365,6 +1411,8 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
 					 int flags, const char *name, uint32_t type);
 struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
 					 const char *name);
+struct drm_property *drm_property_create_rgba(struct drm_device *dev,
+					      int flags, const char *name);
 struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
                                                    size_t length,
                                                    const void *data);
@@ -1495,6 +1543,7 @@ extern int drm_format_vert_chroma_subsampling(uint32_t format);
 extern const char *drm_get_format_name(uint32_t format);
 extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
 							      unsigned int supported_rotations);
+extern struct drm_property *drm_mode_create_background_color_property(struct drm_device *dev);
 extern unsigned int drm_rotation_simplify(unsigned int rotation,
 					  unsigned int supported_rotations);
 
