diff options
| author | Dave Airlie <airlied@redhat.com> | 2014-01-17 10:56:09 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2014-05-19 11:13:55 +1000 | 
| commit | f1f62f2ccba0967c493ac9ad31c9b04d29688aaa (patch) | |
| tree | 18549684b758fdfca521cc95ff3c289c6f54149f /drivers/gpu/drm/ast/ast_mode.c | |
| parent | bf21d605bf7d18d2b3cdb1c19fc1b2a1549c1f11 (diff) | |
drm/ast: add widescreen + rb modes from X.org driver (v2)
This syncs up the mode code from the X.org driver upstream,
and adds the mode validation step for hw that doesn't have
widescreen.
v2: (from Egbert Eich <eich@suse.de)
squash drm/ast: Use correct structure member for mode validation
to avoid bisect regression.
In struct drm_display_mode crtc_hdisplay and crtc_vdisplay are holding
the crtc parameters after mode fixup. For validation we need hdisplay and
vdisplay.
Signed-off-by: Egbert Eich <eich@suse.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/ast/ast_mode.c')
| -rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 76 | 
1 files changed, 67 insertions, 9 deletions
| diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index cca063b1108..72bec23b66f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -115,11 +115,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo  		else  			vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];  		break; +	case 1360: +		vbios_mode->enh_table = &res_1360x768[refresh_rate_index]; +		break;  	case 1440:  		vbios_mode->enh_table = &res_1440x900[refresh_rate_index];  		break;  	case 1600: -		vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; +		if (crtc->mode.crtc_vdisplay == 900) +			vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; +		else +			vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];  		break;  	case 1680:  		vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; @@ -175,14 +181,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo  		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, 0xa8); -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel); -		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, 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, crtc->fb->bits_per_pixel); +			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); +			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); +		}  	}  	return true; @@ -746,7 +755,56 @@ static int ast_get_modes(struct drm_connector *connector)  static int ast_mode_valid(struct drm_connector *connector,  			  struct drm_display_mode *mode)  { -	return MODE_OK; +	struct ast_private *ast = connector->dev->dev_private; +	int flags = MODE_NOMODE; +	uint32_t jtemp; + +	if (ast->support_wide_screen) { +		if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) +			return MODE_OK; +		if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) +			return MODE_OK; +		if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) +			return MODE_OK; +		if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) +			return MODE_OK; +		if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) +			return MODE_OK; + +		if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST1180)) { +			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) +				return MODE_OK; + +			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { +				jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); +				if (jtemp & 0x01) +					return MODE_NOMODE; +				else +					return MODE_OK; +			} +		} +	} +	switch (mode->hdisplay) { +	case 640: +		if (mode->vdisplay == 480) flags = MODE_OK; +		break; +	case 800: +		if (mode->vdisplay == 600) flags = MODE_OK; +		break; +	case 1024: +		if (mode->vdisplay == 768) flags = MODE_OK; +		break; +	case 1280: +		if (mode->vdisplay == 1024) flags = MODE_OK; +		break; +	case 1600: +		if (mode->vdisplay == 1200) flags = MODE_OK; +		break; +	default: +		return flags; +	} + +	return flags;  }  static void ast_connector_destroy(struct drm_connector *connector) | 
