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:
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
*/
if (!m)
continue;
- m->type |= DRM_MODE_TYPE_DRIVER;
-
drm_mode_probed_add(connector, m);
modes++;
}
* 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;
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;