diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index c8ac9482cf2ed12de114636b004bdd66813bc4ba..d13f50db765d8f4a2c05c841828175c10e1c7ebb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -458,6 +458,28 @@ nouveau_connector_set_property(struct drm_connector *connector,
 
 		switch (value) {
 		case DRM_MODE_SCALE_NONE:
+			/* We allow 'None' for EDID modes, even on a fixed
+			 * panel (some exist with support for lower refresh
+			 * rates, which people might want to use for power
+			 * saving purposes).
+			 *
+			 * Non-EDID modes will force the use of GPU scaling
+			 * to the native mode regardless of this setting.
+			 */
+			switch (nv_connector->type) {
+			case DCB_CONNECTOR_LVDS:
+			case DCB_CONNECTOR_LVDS_SPWG:
+			case DCB_CONNECTOR_eDP:
+				/* ... except prior to G80, where the code
+				 * doesn't support such things.
+				 */
+				if (disp->disp.oclass < NV50_DISP)
+					return -EINVAL;
+				break;
+			default:
+				break;
+			}
+			break;
 		case DRM_MODE_SCALE_FULLSCREEN:
 		case DRM_MODE_SCALE_CENTER:
 		case DRM_MODE_SCALE_ASPECT:
@@ -466,11 +488,6 @@ nouveau_connector_set_property(struct drm_connector *connector,
 			return -EINVAL;
 		}
 
-		/* LVDS always needs gpu scaling */
-		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
-		    value == DRM_MODE_SCALE_NONE)
-			return -EINVAL;
-
 		/* Changing between GPU and panel scaling requires a full
 		 * modeset
 		 */
@@ -662,8 +679,6 @@ nouveau_connector_scaler_modes_add(struct drm_connector *connector)
 			if (!m)
 				continue;
 
-			m->type |= DRM_MODE_TYPE_DRIVER;
-
 			drm_mode_probed_add(connector, m);
 			modes++;
 		}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 629a380c708555b26522987036b458a01fb2983f..a2d099142d96cb159211d173e4cf8a6cbe038a30 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -72,6 +72,7 @@ struct nouveau_connector {
 	int dithering_mode;
 	int dithering_depth;
 	int scaling_mode;
+	bool scaling_full;
 	enum nouveau_underscan_type underscan;
 	u32 underscan_hborder;
 	u32 underscan_vborder;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 4f544f3683db44374196ec5dd53db29b0724d46b..85cc667cfb0f0311143ad4cfff03b8e6fa6987e3 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -729,8 +729,11 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
 	 * effectively handles NONE/FULL scaling
 	 */
 	nv_connector = nouveau_crtc_connector_get(nv_crtc);
-	if (nv_connector && nv_connector->native_mode)
+	if (nv_connector && nv_connector->native_mode) {
 		mode = nv_connector->scaling_mode;
+		if (nv_connector->scaling_full) /* non-EDID LVDS/eDP mode */
+			mode = DRM_MODE_SCALE_FULLSCREEN;
+	}
 
 	if (mode != DRM_MODE_SCALE_NONE)
 		omode = nv_connector->native_mode;
@@ -1478,8 +1481,23 @@ nv50_encoder_mode_fixup(struct drm_encoder *encoder,
 
 	nv_connector = nouveau_encoder_connector_get(nv_encoder);
 	if (nv_connector && nv_connector->native_mode) {
-		if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE)
-			drm_mode_copy(adjusted_mode, nv_connector->native_mode);
+		nv_connector->scaling_full = false;
+		if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) {
+			switch (nv_connector->type) {
+			case DCB_CONNECTOR_LVDS:
+			case DCB_CONNECTOR_LVDS_SPWG:
+			case DCB_CONNECTOR_eDP:
+				/* force use of scaler for non-edid modes */
+				if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER)
+					return true;
+				nv_connector->scaling_full = true;
+				break;
+			default:
+				return true;
+			}
+		}
+
+		drm_mode_copy(adjusted_mode, nv_connector->native_mode);
 	}
 
 	return true;