Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/ast: Add helpers for VBIOS mode lookup

Mode lines are independent from hardware Gen or TX chip, so hide all
VBIOS mode tables in ast_vbios.c.

Move the look-up code for VBIOS modes from ast_vbios_get_mode_info()
to ast_vbios_find_mode(). The new look-up function respects the
supported-mode flags in struct ast_device. For example, if a device
does not have struct ast_device.support_fullhd set, the helper does
not return a valid mode for 1920x1080. Taking the supported-mode flags
into account allows for making the VBIOS tables the single reference
for validating and setting display modes against hardware capabilities.

v2:
- replace mode switch with look-up table (Jocelyn)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250131092257.115596-11-tzimmermann@suse.de

+360 -263
+1
drivers/gpu/drm/ast/Makefile
··· 13 13 ast_mode.o \ 14 14 ast_post.o \ 15 15 ast_sil164.o \ 16 + ast_vbios.o \ 16 17 ast_vga.o 17 18 18 19 obj-$(CONFIG_DRM_AST) := ast.o
+1
drivers/gpu/drm/ast/ast_dp.c
··· 12 12 #include <drm/drm_probe_helper.h> 13 13 14 14 #include "ast_drv.h" 15 + #include "ast_vbios.h" 15 16 16 17 static bool ast_astdp_is_connected(struct ast_device *ast) 17 18 {
+2 -16
drivers/gpu/drm/ast/ast_drv.h
··· 39 39 40 40 #include "ast_reg.h" 41 41 42 + struct ast_vbios_enhtable; 43 + 42 44 #define DRIVER_AUTHOR "Dave Airlie" 43 45 44 46 #define DRIVER_NAME "ast" ··· 350 348 u8 crtc[25]; 351 349 u8 ar[20]; 352 350 u8 gr[9]; 353 - }; 354 - 355 - struct ast_vbios_enhtable { 356 - u32 ht; 357 - u32 hde; 358 - u32 hfp; 359 - u32 hsync; 360 - u32 vt; 361 - u32 vde; 362 - u32 vfp; 363 - u32 vsync; 364 - u32 dclk_index; 365 - u32 flags; 366 - u32 refresh_rate; 367 - u32 refresh_rate_index; 368 - u32 mode_id; 369 351 }; 370 352 371 353 struct ast_vbios_dclk_info {
+7 -70
drivers/gpu/drm/ast/ast_mode.c
··· 47 47 48 48 #include "ast_drv.h" 49 49 #include "ast_tables.h" 50 + #include "ast_vbios.h" 50 51 51 52 #define AST_LUT_SIZE 256 52 53 ··· 107 106 } 108 107 } 109 108 110 - static bool ast_get_vbios_mode_info(const struct drm_format_info *format, 109 + static bool ast_get_vbios_mode_info(struct ast_device *ast, 110 + const struct drm_format_info *format, 111 111 const struct drm_display_mode *mode, 112 112 struct drm_display_mode *adjusted_mode, 113 113 struct ast_vbios_mode_info *vbios_mode) 114 114 { 115 - u32 refresh_rate_index = 0, refresh_rate; 116 - const struct ast_vbios_enhtable *best = NULL; 117 - const struct ast_vbios_enhtable *loop; 118 115 u32 hborder, vborder; 119 116 120 117 switch (format->cpp[0] * 8) { ··· 130 131 return false; 131 132 } 132 133 133 - switch (mode->hdisplay) { 134 - case 640: 135 - vbios_mode->enh_table = &res_640x480[refresh_rate_index]; 136 - break; 137 - case 800: 138 - vbios_mode->enh_table = &res_800x600[refresh_rate_index]; 139 - break; 140 - case 1024: 141 - vbios_mode->enh_table = &res_1024x768[refresh_rate_index]; 142 - break; 143 - case 1152: 144 - vbios_mode->enh_table = &res_1152x864[refresh_rate_index]; 145 - break; 146 - case 1280: 147 - if (mode->vdisplay == 800) 148 - vbios_mode->enh_table = &res_1280x800[refresh_rate_index]; 149 - else 150 - vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; 151 - break; 152 - case 1360: 153 - vbios_mode->enh_table = &res_1360x768[refresh_rate_index]; 154 - break; 155 - case 1440: 156 - vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; 157 - break; 158 - case 1600: 159 - if (mode->vdisplay == 900) 160 - vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; 161 - else 162 - vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; 163 - break; 164 - case 1680: 165 - vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; 166 - break; 167 - case 1920: 168 - if (mode->vdisplay == 1080) 169 - vbios_mode->enh_table = &res_1920x1080[refresh_rate_index]; 170 - else 171 - vbios_mode->enh_table = &res_1920x1200[refresh_rate_index]; 172 - break; 173 - default: 134 + vbios_mode->enh_table = ast_vbios_find_mode(ast, mode); 135 + if (!vbios_mode->enh_table) 174 136 return false; 175 - } 176 - 177 - refresh_rate = drm_mode_vrefresh(mode); 178 - 179 - loop = vbios_mode->enh_table; 180 - 181 - while (ast_vbios_mode_is_valid(loop)) { 182 - if (((mode->flags & DRM_MODE_FLAG_NVSYNC) && (loop->flags & PVSync)) || 183 - ((mode->flags & DRM_MODE_FLAG_PVSYNC) && (loop->flags & NVSync)) || 184 - ((mode->flags & DRM_MODE_FLAG_NHSYNC) && (loop->flags & PHSync)) || 185 - ((mode->flags & DRM_MODE_FLAG_PHSYNC) && (loop->flags & NHSync))) { 186 - loop++; 187 - continue; 188 - } 189 - if (loop->refresh_rate <= refresh_rate && 190 - (!best || loop->refresh_rate > best->refresh_rate)) 191 - best = loop; 192 - loop++; 193 - } 194 - 195 - if (!best) 196 - return false; 197 - 198 - vbios_mode->enh_table = best; 199 137 200 138 hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; 201 139 vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; ··· 1045 1109 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1046 1110 struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); 1047 1111 struct drm_device *dev = crtc->dev; 1112 + struct ast_device *ast = to_ast_device(dev); 1048 1113 struct ast_crtc_state *ast_state; 1049 1114 const struct drm_format_info *format; 1050 1115 bool succ; ··· 1080 1143 } 1081 1144 } 1082 1145 1083 - succ = ast_get_vbios_mode_info(format, &crtc_state->mode, 1146 + succ = ast_get_vbios_mode_info(ast, format, &crtc_state->mode, 1084 1147 &crtc_state->adjusted_mode, 1085 1148 &ast_state->vbios_mode_info); 1086 1149 if (!succ)
-177
drivers/gpu/drm/ast/ast_tables.h
··· 33 33 #define HiCModeIndex 3 34 34 #define TrueCModeIndex 4 35 35 36 - #define Charx8Dot 0x00000001 37 - #define HalfDCLK 0x00000002 38 - #define DoubleScanMode 0x00000004 39 - #define LineCompareOff 0x00000008 40 - #define HBorder 0x00000020 41 - #define VBorder 0x00000010 42 - #define WideScreenMode 0x00000100 43 - #define NewModeInfo 0x00000200 44 - #define NHSync 0x00000400 45 - #define PHSync 0x00000800 46 - #define NVSync 0x00001000 47 - #define PVSync 0x00002000 48 - #define SyncPP (PVSync | PHSync) 49 - #define SyncPN (PVSync | NHSync) 50 - #define SyncNP (NVSync | PHSync) 51 - #define SyncNN (NVSync | NHSync) 52 - #define AST2500PreCatchCRT 0x00004000 53 - 54 - /* DCLK Index */ 55 - #define VCLK25_175 0x00 56 - #define VCLK28_322 0x01 57 - #define VCLK31_5 0x02 58 - #define VCLK36 0x03 59 - #define VCLK40 0x04 60 - #define VCLK49_5 0x05 61 - #define VCLK50 0x06 62 - #define VCLK56_25 0x07 63 - #define VCLK65 0x08 64 - #define VCLK75 0x09 65 - #define VCLK78_75 0x0A 66 - #define VCLK94_5 0x0B 67 - #define VCLK108 0x0C 68 - #define VCLK135 0x0D 69 - #define VCLK157_5 0x0E 70 - #define VCLK162 0x0F 71 - /* #define VCLK193_25 0x10 */ 72 - #define VCLK154 0x10 73 - #define VCLK83_5 0x11 74 - #define VCLK106_5 0x12 75 - #define VCLK146_25 0x13 76 - #define VCLK148_5 0x14 77 - #define VCLK71 0x15 78 - #define VCLK88_75 0x16 79 - #define VCLK119 0x17 80 - #define VCLK85_5 0x18 81 - #define VCLK97_75 0x19 82 - #define VCLK118_25 0x1A 83 - 84 36 static const struct ast_vbios_dclk_info dclk_table[] = { 85 37 {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ 86 38 {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */ ··· 164 212 {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, 165 213 0xff} 166 214 }, 167 - }; 168 - 169 - #define AST_VBIOS_INVALID_MODE \ 170 - {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u} 171 - 172 - static inline bool ast_vbios_mode_is_valid(const struct ast_vbios_enhtable *vmode) 173 - { 174 - return vmode->ht && vmode->vt && vmode->refresh_rate; 175 - } 176 - 177 - static const struct ast_vbios_enhtable res_640x480[] = { 178 - { 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175, /* 60Hz */ 179 - (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2E }, 180 - { 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5, /* 72Hz */ 181 - (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2E }, 182 - { 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5, /* 75Hz */ 183 - (SyncNN | Charx8Dot) , 75, 3, 0x2E }, 184 - { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* 85Hz */ 185 - (SyncNN | Charx8Dot) , 85, 4, 0x2E }, 186 - AST_VBIOS_INVALID_MODE, /* end */ 187 - }; 188 - 189 - static const struct ast_vbios_enhtable res_800x600[] = { 190 - {1024, 800, 24, 72, 625, 600, 1, 2, VCLK36, /* 56Hz */ 191 - (SyncPP | Charx8Dot), 56, 1, 0x30 }, 192 - {1056, 800, 40, 128, 628, 600, 1, 4, VCLK40, /* 60Hz */ 193 - (SyncPP | Charx8Dot), 60, 2, 0x30 }, 194 - {1040, 800, 56, 120, 666, 600, 37, 6, VCLK50, /* 72Hz */ 195 - (SyncPP | Charx8Dot), 72, 3, 0x30 }, 196 - {1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5, /* 75Hz */ 197 - (SyncPP | Charx8Dot), 75, 4, 0x30 }, 198 - {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* 85Hz */ 199 - (SyncPP | Charx8Dot), 84, 5, 0x30 }, 200 - AST_VBIOS_INVALID_MODE, /* end */ 201 - }; 202 - 203 - 204 - static const struct ast_vbios_enhtable res_1024x768[] = { 205 - {1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65, /* 60Hz */ 206 - (SyncNN | Charx8Dot), 60, 1, 0x31 }, 207 - {1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75, /* 70Hz */ 208 - (SyncNN | Charx8Dot), 70, 2, 0x31 }, 209 - {1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75, /* 75Hz */ 210 - (SyncPP | Charx8Dot), 75, 3, 0x31 }, 211 - {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* 85Hz */ 212 - (SyncPP | Charx8Dot), 84, 4, 0x31 }, 213 - AST_VBIOS_INVALID_MODE, /* end */ 214 - }; 215 - 216 - static const struct ast_vbios_enhtable res_1280x1024[] = { 217 - {1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108, /* 60Hz */ 218 - (SyncPP | Charx8Dot), 60, 1, 0x32 }, 219 - {1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135, /* 75Hz */ 220 - (SyncPP | Charx8Dot), 75, 2, 0x32 }, 221 - {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* 85Hz */ 222 - (SyncPP | Charx8Dot), 85, 3, 0x32 }, 223 - AST_VBIOS_INVALID_MODE, /* end */ 224 - }; 225 - 226 - static const struct ast_vbios_enhtable res_1600x1200[] = { 227 - {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* 60Hz */ 228 - (SyncPP | Charx8Dot), 60, 1, 0x33 }, 229 - AST_VBIOS_INVALID_MODE, /* end */ 230 - }; 231 - 232 - static const struct ast_vbios_enhtable res_1152x864[] = { 233 - {1600, 1152, 64, 128, 900, 864, 1, 3, VCLK108, /* 75Hz */ 234 - (SyncPP | Charx8Dot | NewModeInfo), 75, 1, 0x3B }, 235 - AST_VBIOS_INVALID_MODE, /* end */ 236 - }; 237 - 238 - /* 16:9 */ 239 - static const struct ast_vbios_enhtable res_1360x768[] = { 240 - {1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */ 241 - (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 }, 242 - AST_VBIOS_INVALID_MODE, /* end */ 243 - }; 244 - 245 - static const struct ast_vbios_enhtable res_1600x900[] = { 246 - {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ 247 - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 248 - AST2500PreCatchCRT), 60, 1, 0x3A }, 249 - {2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */ 250 - (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3A }, 251 - AST_VBIOS_INVALID_MODE, /* end */ 252 - }; 253 - 254 - static const struct ast_vbios_enhtable res_1920x1080[] = { 255 - {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ 256 - (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 257 - AST2500PreCatchCRT), 60, 1, 0x38 }, 258 - AST_VBIOS_INVALID_MODE, /* end */ 259 - }; 260 - 261 - 262 - /* 16:10 */ 263 - static const struct ast_vbios_enhtable res_1280x800[] = { 264 - {1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */ 265 - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 266 - AST2500PreCatchCRT), 60, 1, 0x35 }, 267 - {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ 268 - (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 }, 269 - AST_VBIOS_INVALID_MODE, /* end */ 270 - 271 - }; 272 - 273 - static const struct ast_vbios_enhtable res_1440x900[] = { 274 - {1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */ 275 - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 276 - AST2500PreCatchCRT), 60, 1, 0x36 }, 277 - {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ 278 - (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 }, 279 - AST_VBIOS_INVALID_MODE, /* end */ 280 - }; 281 - 282 - static const struct ast_vbios_enhtable res_1680x1050[] = { 283 - {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */ 284 - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 285 - AST2500PreCatchCRT), 60, 1, 0x37 }, 286 - {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ 287 - (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 }, 288 - AST_VBIOS_INVALID_MODE, /* end */ 289 - }; 290 - 291 - static const struct ast_vbios_enhtable res_1920x1200[] = { 292 - {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB*/ 293 - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 294 - AST2500PreCatchCRT), 60, 1, 0x34 }, 295 - AST_VBIOS_INVALID_MODE, /* end */ 296 215 }; 297 216 298 217 #endif
+241
drivers/gpu/drm/ast/ast_vbios.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright (c) 2005 ASPEED Technology Inc. 4 + * 5 + * Permission to use, copy, modify, distribute, and sell this software and its 6 + * documentation for any purpose is hereby granted without fee, provided that 7 + * the above copyright notice appear in all copies and that both that 8 + * copyright notice and this permission notice appear in supporting 9 + * documentation, and that the name of the authors not be used in 10 + * advertising or publicity pertaining to distribution of the software without 11 + * specific, written prior permission. The authors makes no representations 12 + * about the suitability of this software for any purpose. It is provided 13 + * "as is" without express or implied warranty. 14 + * 15 + * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 + * PERFORMANCE OF THIS SOFTWARE. 22 + */ 23 + 24 + #include "ast_drv.h" 25 + #include "ast_vbios.h" 26 + 27 + /* 4:3 */ 28 + 29 + static const struct ast_vbios_enhtable res_640x480[] = { 30 + { 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175, /* 60 Hz */ 31 + (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2e }, 32 + { 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5, /* 72 Hz */ 33 + (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2e }, 34 + { 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5, /* 75 Hz */ 35 + (SyncNN | Charx8Dot), 75, 3, 0x2e }, 36 + { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* 85 Hz */ 37 + (SyncNN | Charx8Dot), 85, 4, 0x2e }, 38 + AST_VBIOS_INVALID_MODE, /* end */ 39 + }; 40 + 41 + static const struct ast_vbios_enhtable res_800x600[] = { 42 + { 1024, 800, 24, 72, 625, 600, 1, 2, VCLK36, /* 56 Hz */ 43 + (SyncPP | Charx8Dot), 56, 1, 0x30 }, 44 + { 1056, 800, 40, 128, 628, 600, 1, 4, VCLK40, /* 60 Hz */ 45 + (SyncPP | Charx8Dot), 60, 2, 0x30 }, 46 + { 1040, 800, 56, 120, 666, 600, 37, 6, VCLK50, /* 72 Hz */ 47 + (SyncPP | Charx8Dot), 72, 3, 0x30 }, 48 + { 1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5, /* 75 Hz */ 49 + (SyncPP | Charx8Dot), 75, 4, 0x30 }, 50 + { 1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* 85 Hz */ 51 + (SyncPP | Charx8Dot), 84, 5, 0x30 }, 52 + AST_VBIOS_INVALID_MODE, /* end */ 53 + }; 54 + 55 + static const struct ast_vbios_enhtable res_1024x768[] = { 56 + { 1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65, /* 60 Hz */ 57 + (SyncNN | Charx8Dot), 60, 1, 0x31 }, 58 + { 1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75, /* 70 Hz */ 59 + (SyncNN | Charx8Dot), 70, 2, 0x31 }, 60 + { 1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75, /* 75 Hz */ 61 + (SyncPP | Charx8Dot), 75, 3, 0x31 }, 62 + { 1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* 85 Hz */ 63 + (SyncPP | Charx8Dot), 84, 4, 0x31 }, 64 + AST_VBIOS_INVALID_MODE, /* end */ 65 + }; 66 + 67 + static const struct ast_vbios_enhtable res_1152x864[] = { 68 + { 1600, 1152, 64, 128, 900, 864, 1, 3, VCLK108, /* 75 Hz */ 69 + (SyncPP | Charx8Dot | NewModeInfo), 75, 1, 0x3b }, 70 + AST_VBIOS_INVALID_MODE, /* end */ 71 + }; 72 + 73 + static const struct ast_vbios_enhtable res_1280x1024[] = { 74 + { 1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108, /* 60 Hz */ 75 + (SyncPP | Charx8Dot), 60, 1, 0x32 }, 76 + { 1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135, /* 75 Hz */ 77 + (SyncPP | Charx8Dot), 75, 2, 0x32 }, 78 + { 1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* 85 Hz */ 79 + (SyncPP | Charx8Dot), 85, 3, 0x32 }, 80 + AST_VBIOS_INVALID_MODE, /* end */ 81 + }; 82 + 83 + static const struct ast_vbios_enhtable res_1600x1200[] = { 84 + { 2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* 60 Hz */ 85 + (SyncPP | Charx8Dot), 60, 1, 0x33 }, 86 + AST_VBIOS_INVALID_MODE, /* end */ 87 + }; 88 + 89 + /* 16:9 */ 90 + 91 + static const struct ast_vbios_enhtable res_1360x768[] = { 92 + { 1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5, /* 60 Hz */ 93 + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 }, 94 + AST_VBIOS_INVALID_MODE, /* end */ 95 + }; 96 + 97 + static const struct ast_vbios_enhtable res_1600x900[] = { 98 + { 1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60 Hz CVT RB */ 99 + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 100 + AST2500PreCatchCRT), 60, 1, 0x3a }, 101 + { 2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25, /* 60 Hz CVT */ 102 + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3a }, 103 + AST_VBIOS_INVALID_MODE, /* end */ 104 + }; 105 + 106 + static const struct ast_vbios_enhtable res_1920x1080[] = { 107 + { 2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60 Hz */ 108 + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 109 + AST2500PreCatchCRT), 60, 1, 0x38 }, 110 + AST_VBIOS_INVALID_MODE, /* end */ 111 + }; 112 + 113 + /* 16:10 */ 114 + 115 + static const struct ast_vbios_enhtable res_1280x800[] = { 116 + { 1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60 Hz RB */ 117 + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 118 + AST2500PreCatchCRT), 60, 1, 0x35 }, 119 + { 1680, 1280, 72, 128, 831, 800, 3, 6, VCLK83_5, /* 60 Hz */ 120 + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 }, 121 + AST_VBIOS_INVALID_MODE, /* end */ 122 + }; 123 + 124 + static const struct ast_vbios_enhtable res_1440x900[] = { 125 + { 1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60 Hz RB */ 126 + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 127 + AST2500PreCatchCRT), 60, 1, 0x36 }, 128 + { 1904, 1440, 80, 152, 934, 900, 3, 6, VCLK106_5, /* 60 Hz */ 129 + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 }, 130 + AST_VBIOS_INVALID_MODE, /* end */ 131 + }; 132 + 133 + static const struct ast_vbios_enhtable res_1680x1050[] = { 134 + { 1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60 Hz RB */ 135 + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 136 + AST2500PreCatchCRT), 60, 1, 0x37 }, 137 + { 2240, 1680, 104, 176, 1089, 1050, 3, 6, VCLK146_25, /* 60 Hz */ 138 + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 }, 139 + AST_VBIOS_INVALID_MODE, /* end */ 140 + }; 141 + 142 + static const struct ast_vbios_enhtable res_1920x1200[] = { 143 + { 2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60 Hz RB*/ 144 + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | 145 + AST2500PreCatchCRT), 60, 1, 0x34 }, 146 + AST_VBIOS_INVALID_MODE, /* end */ 147 + }; 148 + 149 + /* 150 + * VBIOS mode tables 151 + */ 152 + 153 + static const struct ast_vbios_enhtable *res_table_wuxga[] = { 154 + &res_1920x1200[0], 155 + NULL, 156 + }; 157 + 158 + static const struct ast_vbios_enhtable *res_table_fullhd[] = { 159 + &res_1920x1080[0], 160 + NULL, 161 + }; 162 + 163 + static const struct ast_vbios_enhtable *res_table_wsxga_p[] = { 164 + &res_1280x800[0], 165 + &res_1360x768[0], 166 + &res_1440x900[0], 167 + &res_1600x900[0], 168 + &res_1680x1050[0], 169 + NULL, 170 + }; 171 + 172 + static const struct ast_vbios_enhtable *res_table[] = { 173 + &res_640x480[0], 174 + &res_800x600[0], 175 + &res_1024x768[0], 176 + &res_1152x864[0], 177 + &res_1280x1024[0], 178 + &res_1600x1200[0], 179 + NULL, 180 + }; 181 + 182 + static const struct ast_vbios_enhtable * 183 + __ast_vbios_find_mode_table(const struct ast_vbios_enhtable **vmode_tables, 184 + unsigned int hdisplay, 185 + unsigned int vdisplay) 186 + { 187 + while (*vmode_tables) { 188 + if ((*vmode_tables)->hde == hdisplay && (*vmode_tables)->vde == vdisplay) 189 + return *vmode_tables; 190 + ++vmode_tables; 191 + } 192 + 193 + return NULL; 194 + } 195 + 196 + static const struct ast_vbios_enhtable *ast_vbios_find_mode_table(const struct ast_device *ast, 197 + unsigned int hdisplay, 198 + unsigned int vdisplay) 199 + { 200 + const struct ast_vbios_enhtable *vmode_table = NULL; 201 + 202 + if (ast->support_wuxga) 203 + vmode_table = __ast_vbios_find_mode_table(res_table_wuxga, hdisplay, vdisplay); 204 + if (!vmode_table && ast->support_fullhd) 205 + vmode_table = __ast_vbios_find_mode_table(res_table_fullhd, hdisplay, vdisplay); 206 + if (!vmode_table && ast->support_wsxga_p) 207 + vmode_table = __ast_vbios_find_mode_table(res_table_wsxga_p, hdisplay, vdisplay); 208 + if (!vmode_table) 209 + vmode_table = __ast_vbios_find_mode_table(res_table, hdisplay, vdisplay); 210 + 211 + return vmode_table; 212 + } 213 + 214 + const struct ast_vbios_enhtable *ast_vbios_find_mode(const struct ast_device *ast, 215 + const struct drm_display_mode *mode) 216 + { 217 + const struct ast_vbios_enhtable *best_vmode = NULL; 218 + const struct ast_vbios_enhtable *vmode_table; 219 + const struct ast_vbios_enhtable *vmode; 220 + u32 refresh_rate; 221 + 222 + vmode_table = ast_vbios_find_mode_table(ast, mode->hdisplay, mode->vdisplay); 223 + if (!vmode_table) 224 + return NULL; 225 + 226 + refresh_rate = drm_mode_vrefresh(mode); 227 + 228 + for (vmode = vmode_table; ast_vbios_mode_is_valid(vmode); ++vmode) { 229 + if (((mode->flags & DRM_MODE_FLAG_NVSYNC) && (vmode->flags & PVSync)) || 230 + ((mode->flags & DRM_MODE_FLAG_PVSYNC) && (vmode->flags & NVSync)) || 231 + ((mode->flags & DRM_MODE_FLAG_NHSYNC) && (vmode->flags & PHSync)) || 232 + ((mode->flags & DRM_MODE_FLAG_PHSYNC) && (vmode->flags & NHSync))) { 233 + continue; 234 + } 235 + if (vmode->refresh_rate <= refresh_rate && 236 + (!best_vmode || vmode->refresh_rate > best_vmode->refresh_rate)) 237 + best_vmode = vmode; 238 + } 239 + 240 + return best_vmode; 241 + }
+108
drivers/gpu/drm/ast/ast_vbios.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright (c) 2005 ASPEED Technology Inc. 4 + * 5 + * Permission to use, copy, modify, distribute, and sell this software and its 6 + * documentation for any purpose is hereby granted without fee, provided that 7 + * the above copyright notice appear in all copies and that both that 8 + * copyright notice and this permission notice appear in supporting 9 + * documentation, and that the name of the authors not be used in 10 + * advertising or publicity pertaining to distribution of the software without 11 + * specific, written prior permission. The authors makes no representations 12 + * about the suitability of this software for any purpose. It is provided 13 + * "as is" without express or implied warranty. 14 + * 15 + * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 + * PERFORMANCE OF THIS SOFTWARE. 22 + */ 23 + /* Ported from xf86-video-ast driver */ 24 + 25 + #ifndef AST_VBIOS_H 26 + #define AST_VBIOS_H 27 + 28 + #include <linux/types.h> 29 + 30 + struct ast_device; 31 + struct drm_display_mode; 32 + 33 + #define Charx8Dot 0x00000001 34 + #define HalfDCLK 0x00000002 35 + #define DoubleScanMode 0x00000004 36 + #define LineCompareOff 0x00000008 37 + #define HBorder 0x00000020 38 + #define VBorder 0x00000010 39 + #define WideScreenMode 0x00000100 40 + #define NewModeInfo 0x00000200 41 + #define NHSync 0x00000400 42 + #define PHSync 0x00000800 43 + #define NVSync 0x00001000 44 + #define PVSync 0x00002000 45 + #define SyncPP (PVSync | PHSync) 46 + #define SyncPN (PVSync | NHSync) 47 + #define SyncNP (NVSync | PHSync) 48 + #define SyncNN (NVSync | NHSync) 49 + #define AST2500PreCatchCRT 0x00004000 50 + 51 + /* DCLK Index */ 52 + #define VCLK25_175 0x00 53 + #define VCLK28_322 0x01 54 + #define VCLK31_5 0x02 55 + #define VCLK36 0x03 56 + #define VCLK40 0x04 57 + #define VCLK49_5 0x05 58 + #define VCLK50 0x06 59 + #define VCLK56_25 0x07 60 + #define VCLK65 0x08 61 + #define VCLK75 0x09 62 + #define VCLK78_75 0x0a 63 + #define VCLK94_5 0x0b 64 + #define VCLK108 0x0c 65 + #define VCLK135 0x0d 66 + #define VCLK157_5 0x0e 67 + #define VCLK162 0x0f 68 + /* #define VCLK193_25 0x10 */ 69 + #define VCLK154 0x10 70 + #define VCLK83_5 0x11 71 + #define VCLK106_5 0x12 72 + #define VCLK146_25 0x13 73 + #define VCLK148_5 0x14 74 + #define VCLK71 0x15 75 + #define VCLK88_75 0x16 76 + #define VCLK119 0x17 77 + #define VCLK85_5 0x18 78 + #define VCLK97_75 0x19 79 + #define VCLK118_25 0x1a 80 + 81 + struct ast_vbios_enhtable { 82 + u32 ht; 83 + u32 hde; 84 + u32 hfp; 85 + u32 hsync; 86 + u32 vt; 87 + u32 vde; 88 + u32 vfp; 89 + u32 vsync; 90 + u32 dclk_index; 91 + u32 flags; 92 + u32 refresh_rate; 93 + u32 refresh_rate_index; 94 + u32 mode_id; 95 + }; 96 + 97 + #define AST_VBIOS_INVALID_MODE \ 98 + {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u} 99 + 100 + static inline bool ast_vbios_mode_is_valid(const struct ast_vbios_enhtable *vmode) 101 + { 102 + return vmode->ht && vmode->vt && vmode->refresh_rate; 103 + } 104 + 105 + const struct ast_vbios_enhtable *ast_vbios_find_mode(const struct ast_device *ast, 106 + const struct drm_display_mode *mode); 107 + 108 + #endif