diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile
index 47da848fa3fc1..3107ea9c7bf55 100644
--- a/drivers/gpu/drm/ast/Makefile
+++ b/drivers/gpu/drm/ast/Makefile
@@ -13,6 +13,7 @@ ast-y := \
 	ast_mode.o \
 	ast_post.o \
 	ast_sil164.o \
+	ast_vbios.o \
 	ast_vga.o
 
 obj-$(CONFIG_DRM_AST) := ast.o
diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c
index 2d7482a65f62a..37551c67e6c87 100644
--- a/drivers/gpu/drm/ast/ast_dp.c
+++ b/drivers/gpu/drm/ast/ast_dp.c
@@ -12,6 +12,7 @@
 #include <drm/drm_probe_helper.h>
 
 #include "ast_drv.h"
+#include "ast_vbios.h"
 
 static bool ast_astdp_is_connected(struct ast_device *ast)
 {
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 4e3a88f8a85ca..9309cc5e81b0f 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -39,6 +39,8 @@
 
 #include "ast_reg.h"
 
+struct ast_vbios_enhtable;
+
 #define DRIVER_AUTHOR		"Dave Airlie"
 
 #define DRIVER_NAME		"ast"
@@ -350,22 +352,6 @@ struct ast_vbios_stdtable {
 	u8 gr[9];
 };
 
-struct ast_vbios_enhtable {
-	u32 ht;
-	u32 hde;
-	u32 hfp;
-	u32 hsync;
-	u32 vt;
-	u32 vde;
-	u32 vfp;
-	u32 vsync;
-	u32 dclk_index;
-	u32 flags;
-	u32 refresh_rate;
-	u32 refresh_rate_index;
-	u32 mode_id;
-};
-
 struct ast_vbios_dclk_info {
 	u8 param1;
 	u8 param2;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 3f437f871a357..14c0c281a6834 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -47,6 +47,7 @@
 
 #include "ast_drv.h"
 #include "ast_tables.h"
+#include "ast_vbios.h"
 
 #define AST_LUT_SIZE 256
 
@@ -106,14 +107,12 @@ static void ast_crtc_set_gamma(struct ast_device *ast,
 	}
 }
 
-static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
+static bool ast_get_vbios_mode_info(struct ast_device *ast,
+				    const struct drm_format_info *format,
 				    const struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode,
 				    struct ast_vbios_mode_info *vbios_mode)
 {
-	u32 refresh_rate_index = 0, refresh_rate;
-	const struct ast_vbios_enhtable *best = NULL;
-	const struct ast_vbios_enhtable *loop;
 	u32 hborder, vborder;
 
 	switch (format->cpp[0] * 8) {
@@ -131,73 +130,10 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
 		return false;
 	}
 
-	switch (mode->hdisplay) {
-	case 640:
-		vbios_mode->enh_table = &res_640x480[refresh_rate_index];
-		break;
-	case 800:
-		vbios_mode->enh_table = &res_800x600[refresh_rate_index];
-		break;
-	case 1024:
-		vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
-		break;
-	case 1152:
-		vbios_mode->enh_table = &res_1152x864[refresh_rate_index];
-		break;
-	case 1280:
-		if (mode->vdisplay == 800)
-			vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
-		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 (mode->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];
-		break;
-	case 1920:
-		if (mode->vdisplay == 1080)
-			vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
-		else
-			vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
-		break;
-	default:
-		return false;
-	}
-
-	refresh_rate = drm_mode_vrefresh(mode);
-
-	loop = vbios_mode->enh_table;
-
-	while (ast_vbios_mode_is_valid(loop)) {
-		if (((mode->flags & DRM_MODE_FLAG_NVSYNC) && (loop->flags & PVSync))  ||
-		    ((mode->flags & DRM_MODE_FLAG_PVSYNC) && (loop->flags & NVSync))  ||
-		    ((mode->flags & DRM_MODE_FLAG_NHSYNC) && (loop->flags & PHSync))  ||
-		    ((mode->flags & DRM_MODE_FLAG_PHSYNC) && (loop->flags & NHSync))) {
-			loop++;
-			continue;
-		}
-		if (loop->refresh_rate <= refresh_rate &&
-		    (!best || loop->refresh_rate > best->refresh_rate))
-			best = loop;
-		loop++;
-	}
-
-	if (!best)
+	vbios_mode->enh_table = ast_vbios_find_mode(ast, mode);
+	if (!vbios_mode->enh_table)
 		return false;
 
-	vbios_mode->enh_table = best;
-
 	hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
 	vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
 
@@ -1109,6 +1045,7 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
 	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
 	struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
 	struct drm_device *dev = crtc->dev;
+	struct ast_device *ast = to_ast_device(dev);
 	struct ast_crtc_state *ast_state;
 	const struct drm_format_info *format;
 	bool succ;
@@ -1143,7 +1080,7 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
 		}
 	}
 
-	succ = ast_get_vbios_mode_info(format, &crtc_state->mode,
+	succ = ast_get_vbios_mode_info(ast, format, &crtc_state->mode,
 				       &crtc_state->adjusted_mode,
 				       &ast_state->vbios_mode_info);
 	if (!succ)
diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h
index 4367817b2f806..f1c9f7e1f1fcd 100644
--- a/drivers/gpu/drm/ast/ast_tables.h
+++ b/drivers/gpu/drm/ast/ast_tables.h
@@ -33,54 +33,6 @@
 #define HiCModeIndex		3
 #define TrueCModeIndex		4
 
-#define Charx8Dot               0x00000001
-#define HalfDCLK                0x00000002
-#define DoubleScanMode          0x00000004
-#define LineCompareOff          0x00000008
-#define HBorder                 0x00000020
-#define VBorder                 0x00000010
-#define WideScreenMode		0x00000100
-#define NewModeInfo		0x00000200
-#define NHSync			0x00000400
-#define PHSync			0x00000800
-#define NVSync			0x00001000
-#define PVSync			0x00002000
-#define SyncPP			(PVSync | PHSync)
-#define SyncPN			(PVSync | NHSync)
-#define SyncNP			(NVSync | PHSync)
-#define SyncNN			(NVSync | NHSync)
-#define AST2500PreCatchCRT		0x00004000
-
-/* DCLK Index */
-#define VCLK25_175     		0x00
-#define VCLK28_322     		0x01
-#define VCLK31_5       		0x02
-#define VCLK36         		0x03
-#define VCLK40         		0x04
-#define VCLK49_5       		0x05
-#define VCLK50         		0x06
-#define VCLK56_25      		0x07
-#define VCLK65		 	0x08
-#define VCLK75	        	0x09
-#define VCLK78_75      		0x0A
-#define VCLK94_5       		0x0B
-#define VCLK108        		0x0C
-#define VCLK135        		0x0D
-#define VCLK157_5      		0x0E
-#define VCLK162        		0x0F
-/* #define VCLK193_25     		0x10 */
-#define VCLK154     		0x10
-#define VCLK83_5    		0x11
-#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
-#define VCLK118_25			0x1A
-
 static const struct ast_vbios_dclk_info dclk_table[] = {
 	{0x2C, 0xE7, 0x03},			/* 00: VCLK25_175	*/
 	{0x95, 0x62, 0x03},			/* 01: VCLK28_322	*/
@@ -214,133 +166,4 @@ static const struct ast_vbios_stdtable vbios_stdtable[] = {
 	},
 };
 
-#define AST_VBIOS_INVALID_MODE \
-	{0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}
-
-static inline bool ast_vbios_mode_is_valid(const struct ast_vbios_enhtable *vmode)
-{
-	return vmode->ht && vmode->vt && vmode->refresh_rate;
-}
-
-static const struct ast_vbios_enhtable res_640x480[] = {
-	{ 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175,	/* 60Hz */
-	  (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2E },
-	{ 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5,	/* 72Hz */
-	  (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2E  },
-	{ 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5,	/* 75Hz */
-	  (SyncNN | Charx8Dot) , 75, 3, 0x2E },
-	{ 832, 640, 56, 56, 509, 480, 1, 3, VCLK36,	/* 85Hz */
-	  (SyncNN | Charx8Dot) , 85, 4, 0x2E },
-	AST_VBIOS_INVALID_MODE,				/* end */
-};
-
-static const struct ast_vbios_enhtable res_800x600[] = {
-	{1024, 800, 24, 72, 625, 600, 1, 2, VCLK36,	/* 56Hz */
-	 (SyncPP | Charx8Dot), 56, 1, 0x30 },
-	{1056, 800, 40, 128, 628, 600, 1, 4, VCLK40,	/* 60Hz */
-	 (SyncPP | Charx8Dot), 60, 2, 0x30 },
-	{1040, 800, 56, 120, 666, 600, 37, 6, VCLK50,	/* 72Hz */
-	 (SyncPP | Charx8Dot), 72, 3, 0x30 },
-	{1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5,	/* 75Hz */
-	 (SyncPP | Charx8Dot), 75, 4, 0x30 },
-	{1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25,	/* 85Hz */
-	 (SyncPP | Charx8Dot), 84, 5, 0x30 },
-	AST_VBIOS_INVALID_MODE,				/* end */
-};
-
-
-static const struct ast_vbios_enhtable res_1024x768[] = {
-	{1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65,	/* 60Hz */
-	 (SyncNN | Charx8Dot), 60, 1, 0x31 },
-	{1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75,	/* 70Hz */
-	 (SyncNN | Charx8Dot), 70, 2, 0x31 },
-	{1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75,	/* 75Hz */
-	 (SyncPP | Charx8Dot), 75, 3, 0x31 },
-	{1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5,	/* 85Hz */
-	 (SyncPP | Charx8Dot), 84, 4, 0x31 },
-	AST_VBIOS_INVALID_MODE,				/* end */
-};
-
-static const struct ast_vbios_enhtable res_1280x1024[] = {
-	{1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108,	/* 60Hz */
-	 (SyncPP | Charx8Dot), 60, 1, 0x32 },
-	{1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135,	/* 75Hz */
-	 (SyncPP | Charx8Dot), 75, 2, 0x32 },
-	{1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5,	/* 85Hz */
-	 (SyncPP | Charx8Dot), 85, 3, 0x32 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1600x1200[] = {
-	{2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162,	/* 60Hz */
-	 (SyncPP | Charx8Dot), 60, 1, 0x33 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1152x864[] = {
-	{1600, 1152, 64, 128,  900,  864, 1, 3, VCLK108,	/* 75Hz */
-	 (SyncPP | Charx8Dot | NewModeInfo), 75, 1, 0x3B },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-/* 16:9 */
-static const 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 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1600x900[] = {
-	{1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75,		/* 60Hz CVT RB */
-	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x3A },
-	{2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25,	/* 60Hz CVT */
-	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3A },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1920x1080[] = {
-	{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60Hz */
-	 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x38 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-
-/* 16:10 */
-static const struct ast_vbios_enhtable res_1280x800[] = {
-	{1440, 1280, 48, 32,  823,  800, 3, 6, VCLK71,		/* 60Hz RB */
-	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x35 },
-	{1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,	/* 60Hz */
-	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-
-};
-
-static const struct ast_vbios_enhtable res_1440x900[] = {
-	{1600, 1440, 48, 32,  926,  900, 3, 6, VCLK88_75,	/* 60Hz RB */
-	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x36 },
-	{1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,	/* 60Hz */
-	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1680x1050[] = {
-	{1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119,		/* 60Hz RB */
-	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x37 },
-	{2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,	/* 60Hz */
-	 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
-static const struct ast_vbios_enhtable res_1920x1200[] = {
-	{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,		/* 60Hz RB*/
-	 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
-	  AST2500PreCatchCRT), 60, 1, 0x34 },
-	AST_VBIOS_INVALID_MODE,					/* end */
-};
-
 #endif
diff --git a/drivers/gpu/drm/ast/ast_vbios.c b/drivers/gpu/drm/ast/ast_vbios.c
new file mode 100644
index 0000000000000..0953e6dd39761
--- /dev/null
+++ b/drivers/gpu/drm/ast/ast_vbios.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2005 ASPEED Technology Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ast_drv.h"
+#include "ast_vbios.h"
+
+/* 4:3 */
+
+static const struct ast_vbios_enhtable res_640x480[] = {
+	{ 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175,		/* 60 Hz */
+	  (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2e },
+	{ 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5,		/* 72 Hz */
+	  (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2e  },
+	{ 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5,		/* 75 Hz */
+	  (SyncNN | Charx8Dot), 75, 3, 0x2e },
+	{ 832, 640, 56, 56, 509, 480, 1, 3, VCLK36,		/* 85 Hz */
+	  (SyncNN | Charx8Dot), 85, 4, 0x2e },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_800x600[] = {
+	{ 1024, 800, 24, 72, 625, 600, 1, 2, VCLK36,		/* 56 Hz */
+	  (SyncPP | Charx8Dot), 56, 1, 0x30 },
+	{ 1056, 800, 40, 128, 628, 600, 1, 4, VCLK40,		/* 60 Hz */
+	  (SyncPP | Charx8Dot), 60, 2, 0x30 },
+	{ 1040, 800, 56, 120, 666, 600, 37, 6, VCLK50,		/* 72 Hz */
+	  (SyncPP | Charx8Dot), 72, 3, 0x30 },
+	{ 1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5,		/* 75 Hz */
+	  (SyncPP | Charx8Dot), 75, 4, 0x30 },
+	{ 1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25,		/* 85 Hz */
+	  (SyncPP | Charx8Dot), 84, 5, 0x30 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1024x768[] = {
+	{ 1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65,		/* 60 Hz */
+	  (SyncNN | Charx8Dot), 60, 1, 0x31 },
+	{ 1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75,		/* 70 Hz */
+	  (SyncNN | Charx8Dot), 70, 2, 0x31 },
+	{ 1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75,	/* 75 Hz */
+	  (SyncPP | Charx8Dot), 75, 3, 0x31 },
+	{ 1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5,		/* 85 Hz */
+	  (SyncPP | Charx8Dot), 84, 4, 0x31 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1152x864[] = {
+	{ 1600, 1152, 64, 128,  900,  864, 1, 3, VCLK108,	/* 75 Hz */
+	  (SyncPP | Charx8Dot | NewModeInfo), 75, 1, 0x3b },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1280x1024[] = {
+	{ 1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108,	/* 60 Hz */
+	  (SyncPP | Charx8Dot), 60, 1, 0x32 },
+	{ 1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135,	/* 75 Hz */
+	  (SyncPP | Charx8Dot), 75, 2, 0x32 },
+	{ 1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5,	/* 85 Hz */
+	  (SyncPP | Charx8Dot), 85, 3, 0x32 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1600x1200[] = {
+	{ 2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162,	/* 60 Hz */
+	  (SyncPP | Charx8Dot), 60, 1, 0x33 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+/* 16:9 */
+
+static const struct ast_vbios_enhtable res_1360x768[] = {
+	{ 1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5,	/* 60 Hz */
+	  (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1600x900[] = {
+	{ 1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75,	/* 60 Hz CVT RB */
+	  (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x3a },
+	{ 2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25,	/* 60 Hz CVT */
+	  (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3a },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1920x1080[] = {
+	{ 2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5,	/* 60 Hz */
+	  (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x38 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+/* 16:10 */
+
+static const struct ast_vbios_enhtable res_1280x800[] = {
+	{ 1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71,		/* 60 Hz RB */
+	  (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x35 },
+	{ 1680, 1280, 72, 128, 831, 800, 3, 6, VCLK83_5,	/* 60 Hz */
+	  (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1440x900[] = {
+	{ 1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75,	/* 60 Hz RB */
+	  (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x36 },
+	{ 1904, 1440, 80, 152, 934, 900, 3, 6, VCLK106_5,	/* 60 Hz */
+	  (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1680x1050[] = {
+	{ 1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119,	/* 60 Hz RB */
+	  (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x37 },
+	{ 2240, 1680, 104, 176, 1089, 1050, 3, 6, VCLK146_25,	/* 60 Hz */
+	  (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+static const struct ast_vbios_enhtable res_1920x1200[] = {
+	{ 2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154,	/* 60 Hz RB*/
+	  (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
+	  AST2500PreCatchCRT), 60, 1, 0x34 },
+	AST_VBIOS_INVALID_MODE,					/* end */
+};
+
+/*
+ * VBIOS mode tables
+ */
+
+static const struct ast_vbios_enhtable *res_table_wuxga[] = {
+	&res_1920x1200[0],
+	NULL,
+};
+
+static const struct ast_vbios_enhtable *res_table_fullhd[] = {
+	&res_1920x1080[0],
+	NULL,
+};
+
+static const struct ast_vbios_enhtable *res_table_wsxga_p[] = {
+	&res_1280x800[0],
+	&res_1360x768[0],
+	&res_1440x900[0],
+	&res_1600x900[0],
+	&res_1680x1050[0],
+	NULL,
+};
+
+static const struct ast_vbios_enhtable *res_table[] = {
+	&res_640x480[0],
+	&res_800x600[0],
+	&res_1024x768[0],
+	&res_1152x864[0],
+	&res_1280x1024[0],
+	&res_1600x1200[0],
+	NULL,
+};
+
+static const struct ast_vbios_enhtable *
+__ast_vbios_find_mode_table(const struct ast_vbios_enhtable **vmode_tables,
+			    unsigned int hdisplay,
+			    unsigned int vdisplay)
+{
+	while (*vmode_tables) {
+		if ((*vmode_tables)->hde == hdisplay && (*vmode_tables)->vde == vdisplay)
+			return *vmode_tables;
+		++vmode_tables;
+	}
+
+	return NULL;
+}
+
+static const struct ast_vbios_enhtable *ast_vbios_find_mode_table(const struct ast_device *ast,
+								  unsigned int hdisplay,
+								  unsigned int vdisplay)
+{
+	const struct ast_vbios_enhtable *vmode_table = NULL;
+
+	if (ast->support_wuxga)
+		vmode_table = __ast_vbios_find_mode_table(res_table_wuxga, hdisplay, vdisplay);
+	if (!vmode_table && ast->support_fullhd)
+		vmode_table = __ast_vbios_find_mode_table(res_table_fullhd, hdisplay, vdisplay);
+	if (!vmode_table && ast->support_wsxga_p)
+		vmode_table = __ast_vbios_find_mode_table(res_table_wsxga_p, hdisplay, vdisplay);
+	if (!vmode_table)
+		vmode_table = __ast_vbios_find_mode_table(res_table, hdisplay, vdisplay);
+
+	return vmode_table;
+}
+
+const struct ast_vbios_enhtable *ast_vbios_find_mode(const struct ast_device *ast,
+						     const struct drm_display_mode *mode)
+{
+	const struct ast_vbios_enhtable *best_vmode = NULL;
+	const struct ast_vbios_enhtable *vmode_table;
+	const struct ast_vbios_enhtable *vmode;
+	u32 refresh_rate;
+
+	vmode_table = ast_vbios_find_mode_table(ast, mode->hdisplay, mode->vdisplay);
+	if (!vmode_table)
+		return NULL;
+
+	refresh_rate = drm_mode_vrefresh(mode);
+
+	for (vmode = vmode_table; ast_vbios_mode_is_valid(vmode); ++vmode) {
+		if (((mode->flags & DRM_MODE_FLAG_NVSYNC) && (vmode->flags & PVSync)) ||
+		    ((mode->flags & DRM_MODE_FLAG_PVSYNC) && (vmode->flags & NVSync)) ||
+		    ((mode->flags & DRM_MODE_FLAG_NHSYNC) && (vmode->flags & PHSync)) ||
+		    ((mode->flags & DRM_MODE_FLAG_PHSYNC) && (vmode->flags & NHSync))) {
+			continue;
+		}
+		if (vmode->refresh_rate <= refresh_rate &&
+		    (!best_vmode || vmode->refresh_rate > best_vmode->refresh_rate))
+			best_vmode = vmode;
+	}
+
+	return best_vmode;
+}
diff --git a/drivers/gpu/drm/ast/ast_vbios.h b/drivers/gpu/drm/ast/ast_vbios.h
new file mode 100644
index 0000000000000..8cf025010594c
--- /dev/null
+++ b/drivers/gpu/drm/ast/ast_vbios.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2005 ASPEED Technology Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* Ported from xf86-video-ast driver */
+
+#ifndef AST_VBIOS_H
+#define AST_VBIOS_H
+
+#include <linux/types.h>
+
+struct ast_device;
+struct drm_display_mode;
+
+#define Charx8Dot               0x00000001
+#define HalfDCLK                0x00000002
+#define DoubleScanMode          0x00000004
+#define LineCompareOff          0x00000008
+#define HBorder                 0x00000020
+#define VBorder                 0x00000010
+#define WideScreenMode		0x00000100
+#define NewModeInfo		0x00000200
+#define NHSync			0x00000400
+#define PHSync			0x00000800
+#define NVSync			0x00001000
+#define PVSync			0x00002000
+#define SyncPP			(PVSync | PHSync)
+#define SyncPN			(PVSync | NHSync)
+#define SyncNP			(NVSync | PHSync)
+#define SyncNN			(NVSync | NHSync)
+#define AST2500PreCatchCRT		0x00004000
+
+/* DCLK Index */
+#define VCLK25_175		0x00
+#define VCLK28_322		0x01
+#define VCLK31_5		0x02
+#define VCLK36			0x03
+#define VCLK40			0x04
+#define VCLK49_5		0x05
+#define VCLK50			0x06
+#define VCLK56_25		0x07
+#define VCLK65			0x08
+#define VCLK75			0x09
+#define VCLK78_75		0x0a
+#define VCLK94_5		0x0b
+#define VCLK108			0x0c
+#define VCLK135			0x0d
+#define VCLK157_5		0x0e
+#define VCLK162			0x0f
+/* #define VCLK193_25		0x10 */
+#define VCLK154			0x10
+#define VCLK83_5		0x11
+#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
+#define VCLK118_25		0x1a
+
+struct ast_vbios_enhtable {
+	u32 ht;
+	u32 hde;
+	u32 hfp;
+	u32 hsync;
+	u32 vt;
+	u32 vde;
+	u32 vfp;
+	u32 vsync;
+	u32 dclk_index;
+	u32 flags;
+	u32 refresh_rate;
+	u32 refresh_rate_index;
+	u32 mode_id;
+};
+
+#define AST_VBIOS_INVALID_MODE \
+	{0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}
+
+static inline bool ast_vbios_mode_is_valid(const struct ast_vbios_enhtable *vmode)
+{
+	return vmode->ht && vmode->vt && vmode->refresh_rate;
+}
+
+const struct ast_vbios_enhtable *ast_vbios_find_mode(const struct ast_device *ast,
+						     const struct drm_display_mode *mode);
+
+#endif
