diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 447db50e683817c0f94e04cd7892b641460d9e8b..5785336695ca5330641e4362940b16a8dfe0483b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2798,6 +2798,23 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 
 		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
+		 * default formats list provided by the DRM core which doesn't
+		 * match real hardware capabilities. Skip the check in that
+		 * case.
+		 */
+		if (!crtc->primary->format_default) {
+			ret = drm_plane_check_pixel_format(crtc->primary,
+							   fb->pixel_format);
+			if (ret) {
+				DRM_DEBUG_KMS("Invalid pixel format %s\n",
+					drm_get_format_name(fb->pixel_format));
+				goto out;
+			}
+		}
+
 		ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
 					      mode, fb);
 		if (ret)
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 8e56783265e1a678072310a93a8917eed8aae55c..b62b036350503c8eb70dee380342b097b796c2c7 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -353,6 +353,11 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
 	if (primary == NULL) {
 		DRM_DEBUG_KMS("Failed to allocate primary plane\n");
 		return NULL;
+		/*
+		 * Remove the format_default field from drm_plane when dropping
+		 * this helper.
+		 */
+		primary->format_default = true;
 	}
 
 	/* possible_crtc's will be filled in later by crtc_init */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index da83d39e37d46d86e966c32ebb7922d5d6d039dc..adc9ea5acf02ea45437268c16298a4dbbd9fe35a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -830,6 +830,7 @@ enum drm_plane_type {
  * @possible_crtcs: pipes this plane can be bound to
  * @format_types: array of formats supported by this plane
  * @format_count: number of formats supported
+ * @format_default: driver hasn't supplied supported formats for the plane
  * @crtc: currently bound CRTC
  * @fb: currently bound fb
  * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by
@@ -850,6 +851,7 @@ struct drm_plane {
 	uint32_t possible_crtcs;
 	uint32_t *format_types;
 	uint32_t format_count;
+	bool format_default;
 
 	struct drm_crtc *crtc;
 	struct drm_framebuffer *fb;