NV50: delay changing gpu<->non-gpu scaling modes until next modeset

This commit is contained in:
Maarten Maathuis 2008-07-20 15:40:40 +02:00
parent e51cd78cac
commit 685bca02fe
5 changed files with 31 additions and 9 deletions

View file

@ -185,9 +185,9 @@ int nv50_connector_create(struct drm_device *dev, int bus, int i2c_index, int ty
/* some reasonable defaults */
if (type == CONNECTOR_DVI_D || type == CONNECTOR_DVI_I || type == CONNECTOR_LVDS)
connector->scaling_mode = SCALE_FULLSCREEN;
connector->requested_scaling_mode = SCALE_FULLSCREEN;
else
connector->scaling_mode = SCALE_NON_GPU;
connector->requested_scaling_mode = SCALE_NON_GPU;
connector->use_dithering = false;

View file

@ -47,7 +47,8 @@ struct nv50_connector {
struct nv50_i2c_channel *i2c_chan;
struct nv50_output *output;
int scaling_mode;
int requested_scaling_mode;
bool use_dithering;
bool (*detect) (struct nv50_connector *connector);

View file

@ -255,7 +255,7 @@ static int nv50_crtc_set_scale(struct nv50_crtc *crtc)
NV50_DEBUG("\n");
switch (crtc->scaling_mode) {
switch (crtc->requested_scaling_mode) {
case SCALE_ASPECT:
nv50_crtc_calc_scale(crtc, &outX, &outY);
break;
@ -283,6 +283,9 @@ static int nv50_crtc_set_scale(struct nv50_crtc *crtc)
OUT_MODE(NV50_CRTC0_SCALE_RES1 + offset, outY << 16 | outX);
OUT_MODE(NV50_CRTC0_SCALE_RES2 + offset, outY << 16 | outX);
/* processed */
crtc->scaling_mode = crtc->requested_scaling_mode;
return 0;
}
@ -492,6 +495,9 @@ int nv50_crtc_create(struct drm_device *dev, int index)
crtc->mode = kzalloc(sizeof(struct nouveau_hw_mode), GFP_KERNEL);
crtc->native_mode = kzalloc(sizeof(struct nouveau_hw_mode), GFP_KERNEL);
crtc->requested_scaling_mode = SCALE_INVALID;
crtc->scaling_mode = SCALE_INVALID;
if (!crtc->mode || !crtc->native_mode) {
rval = -ENOMEM;
goto out;

View file

@ -46,6 +46,10 @@ struct nv50_crtc {
bool use_native_mode;
bool use_dithering;
/* Changing scaling modes requires a modeset sometimes. */
/* We need to know the currently active hw mode, as well as the requested one by the user. */
int requested_scaling_mode;
int scaling_mode;
struct nv50_cursor *cursor;

View file

@ -635,12 +635,12 @@ int nv50_kms_crtc_set_config(struct drm_mode_set *set)
if (connector->output != output)
continue;
crtc->scaling_mode = connector->scaling_mode;
crtc->requested_scaling_mode = connector->requested_scaling_mode;
crtc->use_dithering = connector->use_dithering;
break;
}
if (crtc->scaling_mode == SCALE_NON_GPU)
if (crtc->requested_scaling_mode == SCALE_NON_GPU)
crtc->use_native_mode = false;
else
crtc->use_native_mode = true;
@ -1086,6 +1086,7 @@ static int nv50_kms_connector_set_property(struct drm_connector *drm_connector,
struct drm_device *dev = drm_connector->dev;
struct nv50_connector *connector = to_nv50_connector(drm_connector);
int rval = 0;
bool delay_change = false;
/* DPMS */
if (property == dev->mode_config.dpms_property && drm_connector->encoder) {
@ -1123,7 +1124,7 @@ static int nv50_kms_connector_set_property(struct drm_connector *drm_connector,
if (connector->type == CONNECTOR_LVDS && internal_value == SCALE_NON_GPU)
return -EINVAL;
connector->scaling_mode = internal_value;
connector->requested_scaling_mode = internal_value;
if (drm_connector->encoder && drm_connector->encoder->crtc)
crtc = to_nv50_crtc(drm_connector->encoder->crtc);
@ -1131,7 +1132,17 @@ static int nv50_kms_connector_set_property(struct drm_connector *drm_connector,
if (!crtc)
return 0;
crtc->scaling_mode = connector->scaling_mode;
crtc->requested_scaling_mode = connector->requested_scaling_mode;
/* going from and to a gpu scaled regime requires a modesetting, so wait until next modeset */
if (crtc->scaling_mode == SCALE_NON_GPU || internal_value == SCALE_NON_GPU) {
DRM_INFO("Moving from or to a non-gpu scaled mode, this will be processed upon next modeset.");
delay_change = true;
}
if (delay_change)
return 0;
rval = crtc->set_scale(crtc);
if (rval)
return rval;
@ -1194,7 +1205,7 @@ static int nv50_kms_get_scaling_mode(struct drm_connector *drm_connector)
connector = to_nv50_connector(drm_connector);
switch (connector->scaling_mode) {
switch (connector->requested_scaling_mode) {
case SCALE_NON_GPU:
drm_mode = DRM_MODE_SCALE_NON_GPU;
break;