ast_mode.c
1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copied from Linux drivers/gpu/drm/ast/ast_mode.c 4 * Please try to keep as close as possible to the upstream source. 5 */ 6 #include "ast_drv.h" 7 #include "ast_tables.h" 8 9 static inline void ast_load_palette_index(struct ast_private *ast, 10 u8 index, u8 red, u8 green, 11 u8 blue) 12 { 13 ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); 14 ast_io_read8(ast, AST_IO_SEQ_PORT); 15 ast_io_write8(ast, AST_IO_DAC_DATA, red); 16 ast_io_read8(ast, AST_IO_SEQ_PORT); 17 ast_io_write8(ast, AST_IO_DAC_DATA, green); 18 ast_io_read8(ast, AST_IO_SEQ_PORT); 19 ast_io_write8(ast, AST_IO_DAC_DATA, blue); 20 ast_io_read8(ast, AST_IO_SEQ_PORT); 21 } 22 23 static void ast_crtc_load_lut(struct drm_crtc *crtc) 24 { 25 struct ast_private *ast = crtc->dev->dev_private; 26 /* FIXME: Gamma cor 2.6 ? */ 27 for (int i = 0; i < 256; i++) 28 ast_load_palette_index(ast, i, i, i, i); 29 } 30 31 static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode, 32 struct drm_display_mode *adjusted_mode, 33 struct ast_vbios_mode_info *vbios_mode) 34 { 35 struct ast_private *ast = crtc->dev->dev_private; 36 const struct drm_framebuffer *fb = crtc->primary->fb; 37 u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate; 38 const struct ast_vbios_enhtable *best = NULL; 39 u32 hborder, vborder; 40 bool check_sync; 41 42 switch (fb->format->cpp[0] * 8) { 43 case 8: 44 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex]; 45 color_index = VGAModeIndex - 1; 46 break; 47 case 16: 48 vbios_mode->std_table = &vbios_stdtable[HiCModeIndex]; 49 color_index = HiCModeIndex; 50 break; 51 case 24: 52 case 32: 53 vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex]; 54 color_index = TrueCModeIndex; 55 break; 56 default: 57 return false; 58 } 59 60 switch (crtc->mode.crtc_hdisplay) { 61 case 640: 62 vbios_mode->enh_table = &res_640x480[refresh_rate_index]; 63 break; 64 case 800: 65 vbios_mode->enh_table = &res_800x600[refresh_rate_index]; 66 break; 67 case 1024: 68 vbios_mode->enh_table = &res_1024x768[refresh_rate_index]; 69 break; 70 case 1280: 71 if (crtc->mode.crtc_vdisplay == 800) 72 vbios_mode->enh_table = &res_1280x800[refresh_rate_index]; 73 else 74 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; 75 break; 76 case 1360: 77 vbios_mode->enh_table = &res_1360x768[refresh_rate_index]; 78 break; 79 case 1440: 80 vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; 81 break; 82 case 1600: 83 if (crtc->mode.crtc_vdisplay == 900) 84 vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; 85 else 86 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; 87 break; 88 case 1680: 89 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; 90 break; 91 case 1920: 92 if (crtc->mode.crtc_vdisplay == 1080) 93 vbios_mode->enh_table = &res_1920x1080[refresh_rate_index]; 94 else 95 vbios_mode->enh_table = &res_1920x1200[refresh_rate_index]; 96 break; 97 default: 98 return false; 99 } 100 101 refresh_rate = mode->vrefresh; 102 check_sync = vbios_mode->enh_table->flags & WideScreenMode; 103 do { 104 const struct ast_vbios_enhtable *loop = vbios_mode->enh_table; 105 106 while (loop->refresh_rate != 0xff) { 107 if ((check_sync) && 108 (((mode->flags & DRM_MODE_FLAG_NVSYNC) && 109 (loop->flags & PVSync)) || 110 ((mode->flags & DRM_MODE_FLAG_PVSYNC) && 111 (loop->flags & NVSync)) || 112 ((mode->flags & DRM_MODE_FLAG_NHSYNC) && 113 (loop->flags & PHSync)) || 114 ((mode->flags & DRM_MODE_FLAG_PHSYNC) && 115 (loop->flags & NHSync)))) { 116 loop++; 117 continue; 118 } 119 if (loop->refresh_rate <= refresh_rate 120 && (!best || loop->refresh_rate > best->refresh_rate)) 121 best = loop; 122 loop++; 123 } 124 if (best || !check_sync) 125 break; 126 check_sync = 0; 127 } while (1); 128 if (best) 129 vbios_mode->enh_table = best; 130 131 hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; 132 vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; 133 134 adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht; 135 adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder; 136 adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder; 137 adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder + 138 vbios_mode->enh_table->hfp; 139 adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder + 140 vbios_mode->enh_table->hfp + 141 vbios_mode->enh_table->hsync); 142 143 adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt; 144 adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder; 145 adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder; 146 adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder + 147 vbios_mode->enh_table->vfp; 148 adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder + 149 vbios_mode->enh_table->vfp + 150 vbios_mode->enh_table->vsync); 151 152 refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; 153 mode_id = vbios_mode->enh_table->mode_id; 154 155 if (ast->chip == AST1180) { 156 /* TODO 1180 */ 157 } else { 158 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0xf) << 4)); 159 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); 160 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); 161 162 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); 163 if (vbios_mode->enh_table->flags & NewModeInfo) { 164 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 165 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, 166 fb->format->cpp[0] * 8); 167 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, 168 adjusted_mode->clock / 1000); 169 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, 170 adjusted_mode->crtc_hdisplay); 171 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, 172 adjusted_mode->crtc_hdisplay >> 8); 173 174 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, 175 adjusted_mode->crtc_vdisplay); 176 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, 177 adjusted_mode->crtc_vdisplay >> 8); 178 } 179 } 180 181 return true; 182 } 183 184 static void ast_set_std_reg(struct drm_crtc *crtc, struct drm_display_mode *mode, 185 struct ast_vbios_mode_info *vbios_mode) 186 { 187 struct ast_private *ast = crtc->dev->dev_private; 188 const struct drm_framebuffer *fb = crtc->primary->fb; 189 const struct ast_vbios_stdtable *stdtable; 190 u32 i; 191 u8 jreg; 192 193 switch (fb->format->cpp[0] * 8) { 194 case 8: 195 stdtable = &vbios_stdtable[VGAModeIndex]; 196 break; 197 case 16: 198 stdtable = &vbios_stdtable[HiCModeIndex]; 199 break; 200 case 24: 201 case 32: 202 stdtable = &vbios_stdtable[TrueCModeIndex]; 203 break; 204 default: 205 return; 206 } 207 208 jreg = stdtable->misc; 209 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 210 211 /* Set SEQ */ 212 ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); 213 for (i = 0; i < 4; i++) { 214 jreg = stdtable->seq[i]; 215 if (!i) 216 jreg |= 0x20; 217 ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg); 218 } 219 220 /* Set CRTC */ 221 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 222 for (i = 0; i < 25; i++) 223 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 224 225 /* set AR */ 226 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 227 for (i = 0; i < 20; i++) { 228 jreg = stdtable->ar[i]; 229 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); 230 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); 231 } 232 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); 233 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); 234 235 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 236 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); 237 238 /* Set GR */ 239 for (i = 0; i < 9; i++) 240 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); 241 } 242 243 static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mode, 244 struct ast_vbios_mode_info *vbios_mode) 245 { 246 struct ast_private *ast = crtc->dev->dev_private; 247 u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0; 248 u16 temp, precache = 0; 249 250 if ((ast->chip == AST2500 || ast->chip == AST2600) && 251 (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) 252 precache = 40; 253 254 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 255 256 temp = (mode->crtc_htotal >> 3) - 5; 257 if (temp & 0x100) 258 jregAC |= 0x01; /* HT D[8] */ 259 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); 260 261 temp = (mode->crtc_hdisplay >> 3) - 1; 262 if (temp & 0x100) 263 jregAC |= 0x04; /* HDE D[8] */ 264 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); 265 266 temp = (mode->crtc_hblank_start >> 3) - 1; 267 if (temp & 0x100) 268 jregAC |= 0x10; /* HBS D[8] */ 269 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); 270 271 temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; 272 if (temp & 0x20) 273 jreg05 |= 0x80; /* HBE D[5] */ 274 if (temp & 0x40) 275 jregAD |= 0x01; /* HBE D[5] */ 276 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); 277 278 temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; 279 if (temp & 0x100) 280 jregAC |= 0x40; /* HRS D[5] */ 281 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); 282 283 temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; 284 if (temp & 0x20) 285 jregAD |= 0x04; /* HRE D[5] */ 286 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); 287 288 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); 289 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); 290 291 // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); 292 if ((ast->chip == AST2600) && (mode->crtc_vdisplay == 1080)) 293 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); 294 else 295 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); 296 297 /* vert timings */ 298 temp = (mode->crtc_vtotal) - 2; 299 if (temp & 0x100) 300 jreg07 |= 0x01; 301 if (temp & 0x200) 302 jreg07 |= 0x20; 303 if (temp & 0x400) 304 jregAE |= 0x01; 305 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); 306 307 temp = (mode->crtc_vsync_start) - 1; 308 if (temp & 0x100) 309 jreg07 |= 0x04; 310 if (temp & 0x200) 311 jreg07 |= 0x80; 312 if (temp & 0x400) 313 jregAE |= 0x08; 314 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); 315 316 temp = (mode->crtc_vsync_end - 1) & 0x3f; 317 if (temp & 0x10) 318 jregAE |= 0x20; 319 if (temp & 0x20) 320 jregAE |= 0x40; 321 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); 322 323 temp = mode->crtc_vdisplay - 1; 324 if (temp & 0x100) 325 jreg07 |= 0x02; 326 if (temp & 0x200) 327 jreg07 |= 0x40; 328 if (temp & 0x400) 329 jregAE |= 0x02; 330 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); 331 332 temp = mode->crtc_vblank_start - 1; 333 if (temp & 0x100) 334 jreg07 |= 0x08; 335 if (temp & 0x200) 336 jreg09 |= 0x20; 337 if (temp & 0x400) 338 jregAE |= 0x04; 339 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); 340 341 temp = mode->crtc_vblank_end - 1; 342 if (temp & 0x100) 343 jregAE |= 0x10; 344 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); 345 346 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); 347 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); 348 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); 349 350 if (precache) 351 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); 352 else 353 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); 354 355 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); 356 } 357 358 void ast_set_offset_reg(struct drm_crtc *crtc) 359 { 360 struct ast_private *ast = crtc->dev->dev_private; 361 const struct drm_framebuffer *fb = crtc->primary->fb; 362 363 u16 offset; 364 365 offset = fb->pitches[0] >> 3; 366 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); 367 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); 368 } 369 370 static void ast_set_dclk_reg(struct drm_device *dev, struct drm_display_mode *mode, 371 struct ast_vbios_mode_info *vbios_mode) 372 { 373 struct ast_private *ast = dev->dev_private; 374 const struct ast_vbios_dclk_info *clk_info; 375 376 if ((ast->chip == AST2500) || (ast->chip == AST2600)) 377 clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index]; 378 else 379 clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; 380 381 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); 382 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); 383 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, 384 (clk_info->param3 & 0xc0) | 385 ((clk_info->param3 & 0x3) << 4)); 386 } 387 388 static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode, 389 struct ast_vbios_mode_info *vbios_mode) 390 { 391 struct ast_private *ast = crtc->dev->dev_private; 392 const struct drm_framebuffer *fb = crtc->primary->fb; 393 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0; 394 395 switch (fb->format->cpp[0] * 8) { 396 case 8: 397 jregA0 = 0x70; 398 jregA3 = 0x01; 399 jregA8 = 0x00; 400 break; 401 case 15: 402 case 16: 403 jregA0 = 0x70; 404 jregA3 = 0x04; 405 jregA8 = 0x02; 406 break; 407 case 24: 408 case 32: 409 jregA0 = 0x70; 410 jregA3 = 0x08; 411 jregA8 = 0x02; 412 break; 413 } 414 415 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); 416 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); 417 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); 418 419 /* Set Threshold */ 420 if (ast->chip == AST2600) { 421 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); 422 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); 423 } else if (ast->chip == AST2300 || ast->chip == AST2400 || 424 ast->chip == AST2500) { 425 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); 426 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); 427 } else if (ast->chip == AST2100 || 428 ast->chip == AST1100 || 429 ast->chip == AST2200 || 430 ast->chip == AST2150) { 431 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); 432 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); 433 } else { 434 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); 435 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); 436 } 437 } 438 439 static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mode, 440 struct ast_vbios_mode_info *vbios_mode) 441 { 442 struct ast_private *ast = dev->dev_private; 443 u8 jreg; 444 445 jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); 446 jreg &= ~0xC0; 447 if (vbios_mode->enh_table->flags & NVSync) 448 jreg |= 0x80; 449 if (vbios_mode->enh_table->flags & NHSync) 450 jreg |= 0x40; 451 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 452 } 453 454 void ast_set_start_address_crt1(struct ast_private *ast, u32 offset) 455 { 456 u32 addr; 457 458 addr = offset >> 2; 459 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); 460 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); 461 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); 462 } 463 464 void ast_hide_cursor(struct drm_crtc *crtc) 465 { 466 struct ast_private *ast = crtc->dev->dev_private; 467 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); 468 } 469 470 int ast_crtc_mode_set(struct drm_crtc *crtc, 471 struct drm_display_mode *mode, 472 struct drm_display_mode *adjusted_mode) 473 { 474 struct drm_device *dev = crtc->dev; 475 struct ast_private *ast = crtc->dev->dev_private; 476 struct ast_vbios_mode_info vbios_mode; 477 bool ret; 478 int err; 479 480 if (ast->chip == AST1180) { 481 dev_err(dev->pdev, "AST 1180 modesetting not supported\n"); 482 return -EINVAL; 483 } 484 485 /* DPMS, set on */ 486 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0); 487 if (ast->tx_chip_type == AST_TX_DP501) 488 ast_set_dp501_video_output(crtc->dev, 1); 489 ast_crtc_load_lut(crtc); 490 491 /* Get mode */ 492 ret = ast_get_vbios_mode_info(crtc, mode, adjusted_mode, &vbios_mode); 493 if (ret == false) { 494 dev_err(dev->pdev, "Failed to find compatible vbios mode\n"); 495 return -EINVAL; 496 } 497 ast_open_key(ast); 498 499 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); 500 501 ast_set_std_reg(crtc, adjusted_mode, &vbios_mode); 502 ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode); 503 ast_set_offset_reg(crtc); 504 ast_set_dclk_reg(dev, adjusted_mode, &vbios_mode); 505 ast_set_ext_reg(crtc, adjusted_mode, &vbios_mode); 506 ast_set_sync_reg(dev, adjusted_mode, &vbios_mode); 507 508 err = ast_crtc_do_set_base(crtc); 509 if (err) 510 return err; 511 512 /* Commit changes */ 513 514 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0); 515 ast_crtc_load_lut(crtc); 516 517 return 0; 518 } 519 520 enum drm_mode_status ast_mode_valid(struct drm_connector *connector, 521 const unsigned int hdisplay, const unsigned int vdisplay) 522 { 523 struct ast_private *ast = connector->dev->dev_private; 524 int flags = MODE_NOMODE; 525 uint32_t jtemp; 526 527 if (ast->support_wide_screen) { 528 if ((hdisplay == 1680) && (vdisplay == 1050)) 529 return MODE_OK; 530 if ((hdisplay == 1280) && (vdisplay == 800)) 531 return MODE_OK; 532 if ((hdisplay == 1440) && (vdisplay == 900)) 533 return MODE_OK; 534 if ((hdisplay == 1360) && (vdisplay == 768)) 535 return MODE_OK; 536 if ((hdisplay == 1600) && (vdisplay == 900)) 537 return MODE_OK; 538 539 if ((ast->chip == AST2100) || (ast->chip == AST2200) || 540 (ast->chip == AST2300) || (ast->chip == AST2400) || 541 (ast->chip == AST2500) || (ast->chip == AST1180) || 542 (ast->chip == AST2600)) { 543 if ((hdisplay == 1920) && (vdisplay == 1080)) 544 return MODE_OK; 545 546 if ((hdisplay == 1920) && (vdisplay == 1200)) { 547 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 548 0xff); 549 if (jtemp & 0x01) 550 return MODE_NOMODE; 551 else 552 return MODE_OK; 553 } 554 } 555 } 556 switch (hdisplay) { 557 case 640: 558 if (vdisplay == 480) 559 flags = MODE_OK; 560 break; 561 case 800: 562 if (vdisplay == 600) 563 flags = MODE_OK; 564 break; 565 case 1024: 566 if (vdisplay == 768) 567 flags = MODE_OK; 568 break; 569 case 1280: 570 if (vdisplay == 1024) 571 flags = MODE_OK; 572 break; 573 case 1600: 574 if (vdisplay == 1200) 575 flags = MODE_OK; 576 break; 577 default: 578 return flags; 579 } 580 581 return flags; 582 }