[Intel-gfx] [PATCH 3/3 V3] drm/i915: adjust mode line to fit our requirement

Ma Ling ling_ma at linux.intel.com
Mon Jun 8 13:40:25 CEST 2009


Sorry, please ignore this duplicate one, which is delayed by mail server
and I misunderstood it failed to send out, so re-send one.

Thanks
Ma Ling
On Mon, 2009-06-08 at 19:21 +0800, Ma Ling wrote:
> According to fixed mode line, adjust input mode to fit our requirement
> 
> Signed-off-by: Ma Ling <ling.ma at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_sdvo.c |   76 ++++++++++++++++++++++++++++++++-----
>  1 files changed, 66 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index b062473..37f3990 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -73,6 +73,10 @@ struct intel_sdvo_priv {
>  	 * This is set if we detect output of sdvo device as LVDS.
>  	 */
>  	bool is_lvds;
> +	/**
> +	 * This is sdvo flags for input timing.
> +	 */
> +	uint8_t sdvo_flags;
>  
>  	struct drm_display_mode *sdvo_lvds_fixed_mode;
>  
> @@ -593,6 +597,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
>  					 uint16_t height)
>  {
>  	struct intel_sdvo_preferred_input_timing_args args;
> +	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
>  	uint8_t status;
>  
>  	memset(&args, 0, sizeof(args));
> @@ -600,7 +605,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
>  	args.width = width;
>  	args.height = height;
>  	args.interlace = 0;
> -	args.scaled = 0;
> +
> +	if (sdvo_priv->is_lvds &&
> +	   (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width ||
> +	    sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
> +		args.scaled = 1;
> +
>  	intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
>  			     &args, sizeof(args));
>  	status = intel_sdvo_read_response(output, NULL, 0);
> @@ -945,12 +955,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
>  	struct intel_output *output = enc_to_intel_output(encoder);
>  	struct intel_sdvo_priv *dev_priv = output->dev_priv;
>  
> -	if (!dev_priv->is_tv) {
> -		/* Make the CRTC code factor in the SDVO pixel multiplier.  The
> -		 * SDVO device will be told of the multiplier during mode_set.
> -		 */
> -		adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
> -	} else {
> +	if (dev_priv->is_tv) {
>  		struct intel_sdvo_dtd output_dtd;
>  		bool success;
>  
> @@ -981,6 +986,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
>  			intel_sdvo_get_preferred_input_timing(output,
>  							     &input_dtd);
>  			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
> +			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
>  
>  			drm_mode_set_crtcinfo(adjusted_mode, 0);
>  
> @@ -991,10 +997,57 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
>  		} else {
>  			return false;
>  		}
> +	} else if (dev_priv->is_lvds) {
> +		struct intel_sdvo_dtd output_dtd;
> +		bool success;
> +
> +		drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0);
> +		/* Set output timings */
> +		intel_sdvo_get_dtd_from_mode(&output_dtd,
> +				dev_priv->sdvo_lvds_fixed_mode);
> +
> +		intel_sdvo_set_target_output(output,
> +					     dev_priv->controlled_output);
> +		intel_sdvo_set_output_timing(output, &output_dtd);
> +
> +		/* Set the input timing to the screen. Assume always input 0. */
> +		intel_sdvo_set_target_input(output, true, false);
> +
> +
> +		success = intel_sdvo_create_preferred_input_timing(
> +				output,
> +				mode->clock / 10,
> +				mode->hdisplay,
> +				mode->vdisplay);
> +
> +		if (success) {
> +			struct intel_sdvo_dtd input_dtd;
> +
> +			intel_sdvo_get_preferred_input_timing(output,
> +							     &input_dtd);
> +			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
> +			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
> +
> +			drm_mode_set_crtcinfo(adjusted_mode, 0);
> +
> +			mode->clock = adjusted_mode->clock;
> +
> +			adjusted_mode->clock *=
> +				intel_sdvo_get_pixel_multiplier(mode);
> +		} else {
> +			return false;
> +		}
> +
> +	} else {
> +		/* Make the CRTC code factor in the SDVO pixel multiplier.  The
> +		 * SDVO device will be told of the multiplier during mode_set.
> +		 */
> +		adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
>  	}
>  	return true;
>  }
>  
> +#define SDVO_NEED_TO_STALL  (1 << 7)
>  static void intel_sdvo_mode_set(struct drm_encoder *encoder,
>  				struct drm_display_mode *mode,
>  				struct drm_display_mode *adjusted_mode)
> @@ -1034,15 +1087,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
>  
>  	/* We have tried to get input timing in mode_fixup, and filled into
>  	   adjusted_mode */
> -	if (sdvo_priv->is_tv)
> +	if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
>  		intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
> -	else
> +		input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags;
> +	} else
>  		intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
>  
>  	/* If it's a TV, we already set the output timing in mode_fixup.
>  	 * Otherwise, the output timing is equal to the input timing.
>  	 */
> -	if (!sdvo_priv->is_tv) {
> +	if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
>  		/* Set the output timing to the screen */
>  		intel_sdvo_set_target_output(output,
>  					     sdvo_priv->controlled_output);
> @@ -1117,6 +1171,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
>  		sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
>  	}
>  
> +	if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
> +		sdvox |= SDVO_STALL_SELECT;
>  	intel_sdvo_write_sdvox(output, sdvox);
>  }
>  




More information about the Intel-gfx mailing list