Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1f62f2c authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarEgbert Eich <eich@suse.de>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bf21d605
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ struct ast_private {
	 * we have. */
	struct ttm_bo_kmap_obj cache_kmap;
	int next_cursor;
	bool support_wide_screen;
};

int ast_driver_load(struct drm_device *dev, unsigned long flags);
+28 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
static int ast_detect_chip(struct drm_device *dev)
{
	struct ast_private *ast = dev->dev_private;
	uint32_t data, jreg;

	if (dev->pdev->device == PCI_CHIP_AST1180) {
		ast->chip = AST1100;
@@ -104,6 +105,33 @@ static int ast_detect_chip(struct drm_device *dev)
			DRM_INFO("AST 2000 detected\n");
		}
	}

	switch (ast->chip) {
	case AST1180:
		ast->support_wide_screen = true;
		break;
	case AST2000:
		ast->support_wide_screen = false;
		break;
	default:
		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
		if (!(jreg & 0x80))
			ast->support_wide_screen = true;
		else if (jreg & 0x01)
			ast->support_wide_screen = true;
		else {
			ast->support_wide_screen = false;
			if (ast->chip == AST2300) {
				ast_write32(ast, 0xf004, 0x1e6e0000);
				ast_write32(ast, 0xf000, 0x1);
				data = ast_read32(ast, 0x1207c);
				if ((data & 0x300) == 0) /* ast1300 */
					ast->support_wide_screen = true;
			}
		}
		break;
	}

	return 0;
}

+67 −9
Original line number Diff line number Diff line
@@ -115,10 +115,16 @@ 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:
		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:
@@ -175,6 +181,8 @@ 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, 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);
@@ -184,6 +192,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
			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)
{
	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)
+49 −18
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@
#define HBorder                 0x00000020
#define VBorder                 0x00000010
#define WideScreenMode		0x00000100

#define NewModeInfo		0x00000200

/* DCLK Index */
#define VCLK25_175     		0x00
@@ -67,6 +67,11 @@
#define VCLK106_5   		0x12
#define VCLK146_25  		0x13
#define VCLK148_5   		0x14
#define VCLK71      		0x15
#define VCLK88_75   		0x16
#define VCLK119     		0x17
#define VCLK85_5     		0x18
#define VCLK97_75     		0x19

static struct ast_vbios_dclk_info dclk_table[] = {
	{0x2C, 0xE7, 0x03},					/* 00: VCLK25_175	*/
@@ -90,6 +95,10 @@ static struct ast_vbios_dclk_info dclk_table[] = {
	{0x28, 0x49, 0x80},					/* 12: VCLK106.5        */
	{0x37, 0x49, 0x80},					/* 13: VCLK146.25       */
	{0x1f, 0x45, 0x80},					/* 14: VCLK148.5        */
	{0x47, 0x6c, 0x80},					/* 15: VCLK71       */
	{0x25, 0x65, 0x80},					/* 16: VCLK88.75    */
	{0x77, 0x58, 0x80},					/* 17: VCLK119      */
	{0x32, 0x67, 0x80},				    /* 18: VCLK85_5     */
};

static struct ast_vbios_stdtable vbios_stdtable[] = {
@@ -225,41 +234,63 @@ static struct ast_vbios_enhtable res_1600x1200[] = {
	 (SyncPP | Charx8Dot), 0xFF, 1, 0x33 },
};

static struct ast_vbios_enhtable res_1920x1200[] = {
	{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,	/* 60Hz */
	 (SyncNP | Charx8Dot), 60, 1, 0x34 },
	{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,	/* 60Hz */
	 (SyncNP | Charx8Dot), 0xFF, 1, 0x34 },
/* 16:9 */
static struct ast_vbios_enhtable res_1360x768[] = {
	{1792, 1360, 64,112, 795,  768, 3, 6, VCLK85_5,	         /* 60Hz */
	 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
	{1792, 1360, 64,112, 795,  768, 3, 6, VCLK85_5,	         /* end */
	 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 },
};

static struct ast_vbios_enhtable res_1600x900[] = {
	{1760, 1600, 48, 32, 926,  900, 3, 5, VCLK97_75,	/* 60Hz CVT RB */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A },
	{1760, 1600, 48, 32, 926,  900, 3, 5, VCLK97_75,	/* end */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x3A }
};

static struct ast_vbios_enhtable res_1920x1080[] = {
	{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 },
	{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 },
};


/* 16:10 */
static struct ast_vbios_enhtable res_1280x800[] = {
	{1440, 1280, 48, 32,  823,  800, 3, 6, VCLK71,	/* 60Hz RB */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 35 },
	{1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x35 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 },
	{1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x35 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x35 },

};

static struct ast_vbios_enhtable res_1440x900[] = {
	{1600, 1440, 48, 32,  926,  900, 3, 6, VCLK88_75,	/* 60Hz RB */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
	{1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x36 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
	{1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x36 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x36 },
};

static struct ast_vbios_enhtable res_1680x1050[] = {
	{1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119,	/* 60Hz RB */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
	{2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x37 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
	{2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,	/* 60Hz */
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x37 },
	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x37 },
};

/* HDTV */
static struct ast_vbios_enhtable res_1920x1080[] = {
	{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x38 },
	{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x38 },
static struct ast_vbios_enhtable res_1920x1200[] = {
	{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 },
	{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,	/* 60Hz */
	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 },
};

#endif