[PATCH 5/9] drm/ast: Split ast_set_vbios_mode_info()

Gerd Hoffmann kraxel at redhat.com
Tue Nov 5 09:47:25 UTC 2019


On Mon, Oct 28, 2019 at 04:49:24PM +0100, Thomas Zimmermann wrote:
> The implementation of ast_set_vbios_mode() converts a DRM display mode
> and framebuffer into an adjusted mode and stores information for the
> video BIOS to several scratch regsiters.
> 
> Here we split the function into individual functions that do the
> conversion, set the VBIOS mode information and format information.
> This makes it compatible with support for primary planes and atomic
> modesetting.

Acked-by: Gerd Hoffmann <kraxel at redhat.com>

> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
>  drivers/gpu/drm/ast/ast_mode.c | 111 +++++++++++++++++++++------------
>  1 file changed, 72 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
> index 5feb687191e0..c4c9fca0f00c 100644
> --- a/drivers/gpu/drm/ast/ast_mode.c
> +++ b/drivers/gpu/drm/ast/ast_mode.c
> @@ -82,13 +82,12 @@ static void ast_crtc_load_lut(struct drm_crtc *crtc)
>  		ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
>  }
>  
> -static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
> +static bool ast_get_vbios_mode_info(const struct drm_framebuffer *fb,
> +				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode,
>  				    struct ast_vbios_mode_info *vbios_mode)
>  {
> -	struct ast_private *ast = crtc->dev->dev_private;
> -	const struct drm_framebuffer *fb = crtc->primary->fb;
> -	u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
> +	u32 refresh_rate_index = 0, refresh_rate;
>  	const struct ast_vbios_enhtable *best = NULL;
>  	u32 hborder, vborder;
>  	bool check_sync;
> @@ -96,22 +95,19 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  	switch (fb->format->cpp[0] * 8) {
>  	case 8:
>  		vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
> -		color_index = VGAModeIndex - 1;
>  		break;
>  	case 16:
>  		vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
> -		color_index = HiCModeIndex;
>  		break;
>  	case 24:
>  	case 32:
>  		vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
> -		color_index = TrueCModeIndex;
>  		break;
>  	default:
>  		return false;
>  	}
>  
> -	switch (crtc->mode.crtc_hdisplay) {
> +	switch (mode->crtc_hdisplay) {
>  	case 640:
>  		vbios_mode->enh_table = &res_640x480[refresh_rate_index];
>  		break;
> @@ -122,7 +118,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  		vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
>  		break;
>  	case 1280:
> -		if (crtc->mode.crtc_vdisplay == 800)
> +		if (mode->crtc_vdisplay == 800)
>  			vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
>  		else
>  			vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
> @@ -134,7 +130,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  		vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
>  		break;
>  	case 1600:
> -		if (crtc->mode.crtc_vdisplay == 900)
> +		if (mode->crtc_vdisplay == 900)
>  			vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
>  		else
>  			vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
> @@ -143,7 +139,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  		vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
>  		break;
>  	case 1920:
> -		if (crtc->mode.crtc_vdisplay == 1080)
> +		if (mode->crtc_vdisplay == 1080)
>  			vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
>  		else
>  			vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
> @@ -154,7 +150,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  
>  	refresh_rate = drm_mode_vrefresh(mode);
>  	check_sync = vbios_mode->enh_table->flags & WideScreenMode;
> -	do {
> +
> +	while (1) {
>  		const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
>  
>  		while (loop->refresh_rate != 0xff) {
> @@ -178,7 +175,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  		if (best || !check_sync)
>  			break;
>  		check_sync = 0;
> -	} while (1);
> +	}
> +
>  	if (best)
>  		vbios_mode->enh_table = best;
>  
> @@ -203,34 +201,65 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
>  					 vbios_mode->enh_table->vfp +
>  					 vbios_mode->enh_table->vsync);
>  
> -	refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
> -	mode_id = vbios_mode->enh_table->mode_id;
> +	return true;
> +}
>  
> -	if (ast->chip == AST1180) {
> -		/* TODO 1180 */
> -	} else {
> -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0xf) << 4));
> -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
> -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
> -
> -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
> -		if (vbios_mode->enh_table->flags & NewModeInfo) {
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92,
> -					  fb->format->cpp[0] * 8);
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
> -
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
> -			ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
> -		}
> +static void ast_set_vbios_color_reg(struct drm_crtc *crtc,
> +				    const struct drm_framebuffer *fb,
> +				    const struct ast_vbios_mode_info *vbios_mode)
> +{
> +	struct ast_private *ast = crtc->dev->dev_private;
> +	u32 color_index;
> +
> +	switch (fb->format->cpp[0]) {
> +	case 1:
> +		color_index = VGAModeIndex - 1;
> +		break;
> +	case 2:
> +		color_index = HiCModeIndex;
> +		break;
> +	case 3:
> +	case 4:
> +		color_index = TrueCModeIndex;
> +	default:
> +		return;
>  	}
>  
> -	return true;
> +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
> +
> +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
> +
> +	if (vbios_mode->enh_table->flags & NewModeInfo) {
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, fb->format->cpp[0] * 8);
> +	}
> +}
> +
> +static void ast_set_vbios_mode_reg(struct drm_crtc *crtc,
> +				   const struct drm_display_mode *adjusted_mode,
> +				   const struct ast_vbios_mode_info *vbios_mode)
> +{
> +	struct ast_private *ast = crtc->dev->dev_private;
> +	u32 refresh_rate_index, mode_id;
> +
> +	refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
> +	mode_id = vbios_mode->enh_table->mode_id;
> +
> +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
> +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
>  
> +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
>  
> +	if (vbios_mode->enh_table->flags & NewModeInfo) {
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
> +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
> +	}
>  }
> +
>  static void ast_set_std_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
>  			    struct ast_vbios_mode_info *vbios_mode)
>  {
> @@ -581,20 +610,24 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct ast_private *ast = crtc->dev->dev_private;
> +	const struct drm_framebuffer *fb = crtc->primary->fb;
>  	struct ast_vbios_mode_info vbios_mode;
> -	bool ret;
> +	bool succ;
> +
>  	if (ast->chip == AST1180) {
>  		DRM_ERROR("AST 1180 modesetting not supported\n");
>  		return -EINVAL;
>  	}
>  
> -	ret = ast_get_vbios_mode_info(crtc, mode, adjusted_mode, &vbios_mode);
> -	if (ret == false)
> +	succ = ast_get_vbios_mode_info(fb, mode, adjusted_mode, &vbios_mode);
> +	if (!succ)
>  		return -EINVAL;
> +
>  	ast_open_key(ast);
>  
> +	ast_set_vbios_color_reg(crtc, fb, &vbios_mode);
> +	ast_set_vbios_mode_reg(crtc, adjusted_mode, &vbios_mode);
>  	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
> -
>  	ast_set_std_reg(crtc, adjusted_mode, &vbios_mode);
>  	ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode);
>  	ast_set_offset_reg(crtc);
> -- 
> 2.23.0
> 



More information about the dri-devel mailing list