1 /* 2 * Copyright 2012 Red Hat Inc. 3 * Parts based on xf86-video-ast 4 * Copyright (c) 2005 ASPEED Technology Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 */ 27 /* 28 * Authors: Dave Airlie <airlied@redhat.com> 29 */ 30 31 #include <linux/export.h> 32 #include <linux/pci.h> 33 34 #include <drm/drm_atomic.h> 35 #include <drm/drm_atomic_helper.h> 36 #include <drm/drm_atomic_state_helper.h> 37 #include <drm/drm_crtc.h> 38 #include <drm/drm_crtc_helper.h> 39 #include <drm/drm_edid.h> 40 #include <drm/drm_fourcc.h> 41 #include <drm/drm_gem_atomic_helper.h> 42 #include <drm/drm_gem_framebuffer_helper.h> 43 #include <drm/drm_gem_vram_helper.h> 44 #include <drm/drm_managed.h> 45 #include <drm/drm_probe_helper.h> 46 #include <drm/drm_simple_kms_helper.h> 47 48 #include "ast_drv.h" 49 #include "ast_tables.h" 50 51 static inline void ast_load_palette_index(struct ast_private *ast, 52 u8 index, u8 red, u8 green, 53 u8 blue) 54 { 55 ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); 56 ast_io_read8(ast, AST_IO_SEQ_PORT); 57 ast_io_write8(ast, AST_IO_DAC_DATA, red); 58 ast_io_read8(ast, AST_IO_SEQ_PORT); 59 ast_io_write8(ast, AST_IO_DAC_DATA, green); 60 ast_io_read8(ast, AST_IO_SEQ_PORT); 61 ast_io_write8(ast, AST_IO_DAC_DATA, blue); 62 ast_io_read8(ast, AST_IO_SEQ_PORT); 63 } 64 65 static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc) 66 { 67 u16 *r, *g, *b; 68 int i; 69 70 if (!crtc->enabled) 71 return; 72 73 r = crtc->gamma_store; 74 g = r + crtc->gamma_size; 75 b = g + crtc->gamma_size; 76 77 for (i = 0; i < 256; i++) 78 ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8); 79 } 80 81 static bool ast_get_vbios_mode_info(const struct drm_format_info *format, 82 const struct drm_display_mode *mode, 83 struct drm_display_mode *adjusted_mode, 84 struct ast_vbios_mode_info *vbios_mode) 85 { 86 u32 refresh_rate_index = 0, refresh_rate; 87 const struct ast_vbios_enhtable *best = NULL; 88 u32 hborder, vborder; 89 bool check_sync; 90 91 switch (format->cpp[0] * 8) { 92 case 8: 93 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex]; 94 break; 95 case 16: 96 vbios_mode->std_table = &vbios_stdtable[HiCModeIndex]; 97 break; 98 case 24: 99 case 32: 100 vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex]; 101 break; 102 default: 103 return false; 104 } 105 106 switch (mode->crtc_hdisplay) { 107 case 640: 108 vbios_mode->enh_table = &res_640x480[refresh_rate_index]; 109 break; 110 case 800: 111 vbios_mode->enh_table = &res_800x600[refresh_rate_index]; 112 break; 113 case 1024: 114 vbios_mode->enh_table = &res_1024x768[refresh_rate_index]; 115 break; 116 case 1152: 117 vbios_mode->enh_table = &res_1152x864[refresh_rate_index]; 118 break; 119 case 1280: 120 if (mode->crtc_vdisplay == 800) 121 vbios_mode->enh_table = &res_1280x800[refresh_rate_index]; 122 else 123 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; 124 break; 125 case 1360: 126 vbios_mode->enh_table = &res_1360x768[refresh_rate_index]; 127 break; 128 case 1440: 129 vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; 130 break; 131 case 1600: 132 if (mode->crtc_vdisplay == 900) 133 vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; 134 else 135 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; 136 break; 137 case 1680: 138 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; 139 break; 140 case 1920: 141 if (mode->crtc_vdisplay == 1080) 142 vbios_mode->enh_table = &res_1920x1080[refresh_rate_index]; 143 else 144 vbios_mode->enh_table = &res_1920x1200[refresh_rate_index]; 145 break; 146 default: 147 return false; 148 } 149 150 refresh_rate = drm_mode_vrefresh(mode); 151 check_sync = vbios_mode->enh_table->flags & WideScreenMode; 152 153 while (1) { 154 const struct ast_vbios_enhtable *loop = vbios_mode->enh_table; 155 156 while (loop->refresh_rate != 0xff) { 157 if ((check_sync) && 158 (((mode->flags & DRM_MODE_FLAG_NVSYNC) && 159 (loop->flags & PVSync)) || 160 ((mode->flags & DRM_MODE_FLAG_PVSYNC) && 161 (loop->flags & NVSync)) || 162 ((mode->flags & DRM_MODE_FLAG_NHSYNC) && 163 (loop->flags & PHSync)) || 164 ((mode->flags & DRM_MODE_FLAG_PHSYNC) && 165 (loop->flags & NHSync)))) { 166 loop++; 167 continue; 168 } 169 if (loop->refresh_rate <= refresh_rate 170 && (!best || loop->refresh_rate > best->refresh_rate)) 171 best = loop; 172 loop++; 173 } 174 if (best || !check_sync) 175 break; 176 check_sync = 0; 177 } 178 179 if (best) 180 vbios_mode->enh_table = best; 181 182 hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; 183 vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; 184 185 adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht; 186 adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder; 187 adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder; 188 adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder + 189 vbios_mode->enh_table->hfp; 190 adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder + 191 vbios_mode->enh_table->hfp + 192 vbios_mode->enh_table->hsync); 193 194 adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt; 195 adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder; 196 adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder; 197 adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder + 198 vbios_mode->enh_table->vfp; 199 adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder + 200 vbios_mode->enh_table->vfp + 201 vbios_mode->enh_table->vsync); 202 203 return true; 204 } 205 206 static void ast_set_vbios_color_reg(struct ast_private *ast, 207 const struct drm_format_info *format, 208 const struct ast_vbios_mode_info *vbios_mode) 209 { 210 u32 color_index; 211 212 switch (format->cpp[0]) { 213 case 1: 214 color_index = VGAModeIndex - 1; 215 break; 216 case 2: 217 color_index = HiCModeIndex; 218 break; 219 case 3: 220 case 4: 221 color_index = TrueCModeIndex; 222 break; 223 default: 224 return; 225 } 226 227 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4)); 228 229 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); 230 231 if (vbios_mode->enh_table->flags & NewModeInfo) { 232 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 233 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8); 234 } 235 } 236 237 static void ast_set_vbios_mode_reg(struct ast_private *ast, 238 const struct drm_display_mode *adjusted_mode, 239 const struct ast_vbios_mode_info *vbios_mode) 240 { 241 u32 refresh_rate_index, mode_id; 242 243 refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; 244 mode_id = vbios_mode->enh_table->mode_id; 245 246 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); 247 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); 248 249 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); 250 251 if (vbios_mode->enh_table->flags & NewModeInfo) { 252 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 253 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); 254 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); 255 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); 256 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); 257 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); 258 } 259 } 260 261 static void ast_set_std_reg(struct ast_private *ast, 262 struct drm_display_mode *mode, 263 struct ast_vbios_mode_info *vbios_mode) 264 { 265 const struct ast_vbios_stdtable *stdtable; 266 u32 i; 267 u8 jreg; 268 269 stdtable = vbios_mode->std_table; 270 271 jreg = stdtable->misc; 272 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 273 274 /* Set SEQ; except Screen Disable field */ 275 ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); 276 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]); 277 for (i = 1; i < 4; i++) { 278 jreg = stdtable->seq[i]; 279 ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg); 280 } 281 282 /* Set CRTC; except base address and offset */ 283 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 284 for (i = 0; i < 12; i++) 285 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 286 for (i = 14; i < 19; i++) 287 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 288 for (i = 20; i < 25; i++) 289 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 290 291 /* set AR */ 292 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 293 for (i = 0; i < 20; i++) { 294 jreg = stdtable->ar[i]; 295 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); 296 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); 297 } 298 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); 299 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); 300 301 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 302 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); 303 304 /* Set GR */ 305 for (i = 0; i < 9; i++) 306 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); 307 } 308 309 static void ast_set_crtc_reg(struct ast_private *ast, 310 struct drm_display_mode *mode, 311 struct ast_vbios_mode_info *vbios_mode) 312 { 313 u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0; 314 u16 temp, precache = 0; 315 316 if ((ast->chip == AST2500 || ast->chip == AST2600) && 317 (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) 318 precache = 40; 319 320 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 321 322 temp = (mode->crtc_htotal >> 3) - 5; 323 if (temp & 0x100) 324 jregAC |= 0x01; /* HT D[8] */ 325 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); 326 327 temp = (mode->crtc_hdisplay >> 3) - 1; 328 if (temp & 0x100) 329 jregAC |= 0x04; /* HDE D[8] */ 330 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); 331 332 temp = (mode->crtc_hblank_start >> 3) - 1; 333 if (temp & 0x100) 334 jregAC |= 0x10; /* HBS D[8] */ 335 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); 336 337 temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; 338 if (temp & 0x20) 339 jreg05 |= 0x80; /* HBE D[5] */ 340 if (temp & 0x40) 341 jregAD |= 0x01; /* HBE D[5] */ 342 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); 343 344 temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; 345 if (temp & 0x100) 346 jregAC |= 0x40; /* HRS D[5] */ 347 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); 348 349 temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; 350 if (temp & 0x20) 351 jregAD |= 0x04; /* HRE D[5] */ 352 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); 353 354 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); 355 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); 356 357 // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); 358 if ((ast->chip == AST2600) && (mode->crtc_vdisplay == 1080)) 359 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); 360 else 361 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); 362 363 /* vert timings */ 364 temp = (mode->crtc_vtotal) - 2; 365 if (temp & 0x100) 366 jreg07 |= 0x01; 367 if (temp & 0x200) 368 jreg07 |= 0x20; 369 if (temp & 0x400) 370 jregAE |= 0x01; 371 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); 372 373 temp = (mode->crtc_vsync_start) - 1; 374 if (temp & 0x100) 375 jreg07 |= 0x04; 376 if (temp & 0x200) 377 jreg07 |= 0x80; 378 if (temp & 0x400) 379 jregAE |= 0x08; 380 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); 381 382 temp = (mode->crtc_vsync_end - 1) & 0x3f; 383 if (temp & 0x10) 384 jregAE |= 0x20; 385 if (temp & 0x20) 386 jregAE |= 0x40; 387 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); 388 389 temp = mode->crtc_vdisplay - 1; 390 if (temp & 0x100) 391 jreg07 |= 0x02; 392 if (temp & 0x200) 393 jreg07 |= 0x40; 394 if (temp & 0x400) 395 jregAE |= 0x02; 396 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); 397 398 temp = mode->crtc_vblank_start - 1; 399 if (temp & 0x100) 400 jreg07 |= 0x08; 401 if (temp & 0x200) 402 jreg09 |= 0x20; 403 if (temp & 0x400) 404 jregAE |= 0x04; 405 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); 406 407 temp = mode->crtc_vblank_end - 1; 408 if (temp & 0x100) 409 jregAE |= 0x10; 410 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); 411 412 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); 413 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); 414 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); 415 416 if (precache) 417 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); 418 else 419 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); 420 421 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); 422 } 423 424 static void ast_set_offset_reg(struct ast_private *ast, 425 struct drm_framebuffer *fb) 426 { 427 u16 offset; 428 429 offset = fb->pitches[0] >> 3; 430 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); 431 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); 432 } 433 434 static void ast_set_dclk_reg(struct ast_private *ast, 435 struct drm_display_mode *mode, 436 struct ast_vbios_mode_info *vbios_mode) 437 { 438 const struct ast_vbios_dclk_info *clk_info; 439 440 if ((ast->chip == AST2500) || (ast->chip == AST2600)) 441 clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index]; 442 else 443 clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; 444 445 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); 446 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); 447 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, 448 (clk_info->param3 & 0xc0) | 449 ((clk_info->param3 & 0x3) << 4)); 450 } 451 452 static void ast_set_color_reg(struct ast_private *ast, 453 const struct drm_format_info *format) 454 { 455 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0; 456 457 switch (format->cpp[0] * 8) { 458 case 8: 459 jregA0 = 0x70; 460 jregA3 = 0x01; 461 jregA8 = 0x00; 462 break; 463 case 15: 464 case 16: 465 jregA0 = 0x70; 466 jregA3 = 0x04; 467 jregA8 = 0x02; 468 break; 469 case 32: 470 jregA0 = 0x70; 471 jregA3 = 0x08; 472 jregA8 = 0x02; 473 break; 474 } 475 476 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); 477 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); 478 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); 479 } 480 481 static void ast_set_crtthd_reg(struct ast_private *ast) 482 { 483 /* Set Threshold */ 484 if (ast->chip == AST2600) { 485 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); 486 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); 487 } else if (ast->chip == AST2300 || ast->chip == AST2400 || 488 ast->chip == AST2500) { 489 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); 490 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); 491 } else if (ast->chip == AST2100 || 492 ast->chip == AST1100 || 493 ast->chip == AST2200 || 494 ast->chip == AST2150) { 495 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); 496 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); 497 } else { 498 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); 499 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); 500 } 501 } 502 503 static void ast_set_sync_reg(struct ast_private *ast, 504 struct drm_display_mode *mode, 505 struct ast_vbios_mode_info *vbios_mode) 506 { 507 u8 jreg; 508 509 jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); 510 jreg &= ~0xC0; 511 if (vbios_mode->enh_table->flags & NVSync) 512 jreg |= 0x80; 513 if (vbios_mode->enh_table->flags & NHSync) 514 jreg |= 0x40; 515 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 516 } 517 518 static void ast_set_start_address_crt1(struct ast_private *ast, 519 unsigned int offset) 520 { 521 u32 addr; 522 523 addr = offset >> 2; 524 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); 525 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); 526 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); 527 528 } 529 530 static void ast_wait_for_vretrace(struct ast_private *ast) 531 { 532 unsigned long timeout = jiffies + HZ; 533 u8 vgair1; 534 535 do { 536 vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 537 } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout)); 538 } 539 540 /* 541 * Primary plane 542 */ 543 544 static const uint32_t ast_primary_plane_formats[] = { 545 DRM_FORMAT_XRGB8888, 546 DRM_FORMAT_RGB565, 547 DRM_FORMAT_C8, 548 }; 549 550 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane, 551 struct drm_atomic_state *state) 552 { 553 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 554 plane); 555 struct drm_crtc_state *crtc_state; 556 struct ast_crtc_state *ast_crtc_state; 557 int ret; 558 559 if (!new_plane_state->crtc) 560 return 0; 561 562 crtc_state = drm_atomic_get_new_crtc_state(state, 563 new_plane_state->crtc); 564 565 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, 566 DRM_PLANE_NO_SCALING, 567 DRM_PLANE_NO_SCALING, 568 false, true); 569 if (ret) 570 return ret; 571 572 if (!new_plane_state->visible) 573 return 0; 574 575 ast_crtc_state = to_ast_crtc_state(crtc_state); 576 577 ast_crtc_state->format = new_plane_state->fb->format; 578 579 return 0; 580 } 581 582 static void 583 ast_primary_plane_helper_atomic_update(struct drm_plane *plane, 584 struct drm_atomic_state *state) 585 { 586 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, 587 plane); 588 struct drm_device *dev = plane->dev; 589 struct ast_private *ast = to_ast_private(dev); 590 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 591 plane); 592 struct drm_gem_vram_object *gbo; 593 s64 gpu_addr; 594 struct drm_framebuffer *fb = new_state->fb; 595 struct drm_framebuffer *old_fb = old_state->fb; 596 597 if (!old_fb || (fb->format != old_fb->format)) { 598 struct drm_crtc_state *crtc_state = new_state->crtc->state; 599 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 600 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 601 602 ast_set_color_reg(ast, fb->format); 603 ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info); 604 } 605 606 gbo = drm_gem_vram_of_gem(fb->obj[0]); 607 gpu_addr = drm_gem_vram_offset(gbo); 608 if (drm_WARN_ON_ONCE(dev, gpu_addr < 0)) 609 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ 610 611 ast_set_offset_reg(ast, fb); 612 ast_set_start_address_crt1(ast, (u32)gpu_addr); 613 614 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); 615 } 616 617 static void 618 ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, 619 struct drm_atomic_state *state) 620 { 621 struct ast_private *ast = to_ast_private(plane->dev); 622 623 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); 624 } 625 626 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { 627 DRM_GEM_VRAM_PLANE_HELPER_FUNCS, 628 .atomic_check = ast_primary_plane_helper_atomic_check, 629 .atomic_update = ast_primary_plane_helper_atomic_update, 630 .atomic_disable = ast_primary_plane_helper_atomic_disable, 631 }; 632 633 static const struct drm_plane_funcs ast_primary_plane_funcs = { 634 .update_plane = drm_atomic_helper_update_plane, 635 .disable_plane = drm_atomic_helper_disable_plane, 636 .destroy = drm_plane_cleanup, 637 .reset = drm_atomic_helper_plane_reset, 638 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 639 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 640 }; 641 642 static int ast_primary_plane_init(struct ast_private *ast) 643 { 644 struct drm_device *dev = &ast->base; 645 struct drm_plane *primary_plane = &ast->primary_plane; 646 int ret; 647 648 ret = drm_universal_plane_init(dev, primary_plane, 0x01, 649 &ast_primary_plane_funcs, 650 ast_primary_plane_formats, 651 ARRAY_SIZE(ast_primary_plane_formats), 652 NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 653 if (ret) { 654 drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret); 655 return ret; 656 } 657 drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs); 658 659 return 0; 660 } 661 662 /* 663 * Cursor plane 664 */ 665 666 static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height) 667 { 668 union { 669 u32 ul; 670 u8 b[4]; 671 } srcdata32[2], data32; 672 union { 673 u16 us; 674 u8 b[2]; 675 } data16; 676 u32 csum = 0; 677 s32 alpha_dst_delta, last_alpha_dst_delta; 678 u8 __iomem *dstxor; 679 const u8 *srcxor; 680 int i, j; 681 u32 per_pixel_copy, two_pixel_copy; 682 683 alpha_dst_delta = AST_MAX_HWC_WIDTH << 1; 684 last_alpha_dst_delta = alpha_dst_delta - (width << 1); 685 686 srcxor = src; 687 dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta; 688 per_pixel_copy = width & 1; 689 two_pixel_copy = width >> 1; 690 691 for (j = 0; j < height; j++) { 692 for (i = 0; i < two_pixel_copy; i++) { 693 srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 694 srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; 695 data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 696 data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 697 data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); 698 data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); 699 700 writel(data32.ul, dstxor); 701 csum += data32.ul; 702 703 dstxor += 4; 704 srcxor += 8; 705 706 } 707 708 for (i = 0; i < per_pixel_copy; i++) { 709 srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 710 data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 711 data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 712 writew(data16.us, dstxor); 713 csum += (u32)data16.us; 714 715 dstxor += 2; 716 srcxor += 4; 717 } 718 dstxor += last_alpha_dst_delta; 719 } 720 721 /* write checksum + signature */ 722 dst += AST_HWC_SIZE; 723 writel(csum, dst); 724 writel(width, dst + AST_HWC_SIGNATURE_SizeX); 725 writel(height, dst + AST_HWC_SIGNATURE_SizeY); 726 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); 727 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); 728 } 729 730 static void ast_set_cursor_base(struct ast_private *ast, u64 address) 731 { 732 u8 addr0 = (address >> 3) & 0xff; 733 u8 addr1 = (address >> 11) & 0xff; 734 u8 addr2 = (address >> 19) & 0xff; 735 736 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); 737 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); 738 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); 739 } 740 741 static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y, 742 u8 x_offset, u8 y_offset) 743 { 744 u8 x0 = (x & 0x00ff); 745 u8 x1 = (x & 0x0f00) >> 8; 746 u8 y0 = (y & 0x00ff); 747 u8 y1 = (y & 0x0700) >> 8; 748 749 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); 750 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); 751 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); 752 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); 753 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); 754 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); 755 } 756 757 static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled) 758 { 759 static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP | 760 AST_IO_VGACRCB_HWC_ENABLED); 761 762 u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP; 763 764 if (enabled) 765 vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED; 766 767 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb); 768 } 769 770 static const uint32_t ast_cursor_plane_formats[] = { 771 DRM_FORMAT_ARGB8888, 772 }; 773 774 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, 775 struct drm_atomic_state *state) 776 { 777 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 778 plane); 779 struct drm_framebuffer *fb = new_plane_state->fb; 780 struct drm_crtc_state *crtc_state; 781 int ret; 782 783 if (!new_plane_state->crtc) 784 return 0; 785 786 crtc_state = drm_atomic_get_new_crtc_state(state, 787 new_plane_state->crtc); 788 789 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, 790 DRM_PLANE_NO_SCALING, 791 DRM_PLANE_NO_SCALING, 792 true, true); 793 if (ret) 794 return ret; 795 796 if (!new_plane_state->visible) 797 return 0; 798 799 if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) 800 return -EINVAL; 801 802 return 0; 803 } 804 805 static void 806 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, 807 struct drm_atomic_state *state) 808 { 809 struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane); 810 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, 811 plane); 812 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 813 plane); 814 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state); 815 struct drm_framebuffer *fb = new_state->fb; 816 struct ast_private *ast = to_ast_private(plane->dev); 817 struct iosys_map dst_map = 818 ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map; 819 u64 dst_off = 820 ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off; 821 struct iosys_map src_map = shadow_plane_state->data[0]; 822 unsigned int offset_x, offset_y; 823 u16 x, y; 824 u8 x_offset, y_offset; 825 u8 __iomem *dst; 826 u8 __iomem *sig; 827 const u8 *src; 828 829 src = src_map.vaddr; /* TODO: Use mapping abstraction properly */ 830 dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */ 831 sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */ 832 833 /* 834 * Do data transfer to HW cursor BO. If a new cursor image was installed, 835 * point the scanout engine to dst_gbo's offset and page-flip the HWC buffers. 836 */ 837 838 ast_update_cursor_image(dst, src, fb->width, fb->height); 839 840 if (new_state->fb != old_state->fb) { 841 ast_set_cursor_base(ast, dst_off); 842 843 ++ast_cursor_plane->next_hwc_index; 844 ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc); 845 } 846 847 /* 848 * Update location in HWC signature and registers. 849 */ 850 851 writel(new_state->crtc_x, sig + AST_HWC_SIGNATURE_X); 852 writel(new_state->crtc_y, sig + AST_HWC_SIGNATURE_Y); 853 854 offset_x = AST_MAX_HWC_WIDTH - fb->width; 855 offset_y = AST_MAX_HWC_HEIGHT - fb->height; 856 857 if (new_state->crtc_x < 0) { 858 x_offset = (-new_state->crtc_x) + offset_x; 859 x = 0; 860 } else { 861 x_offset = offset_x; 862 x = new_state->crtc_x; 863 } 864 if (new_state->crtc_y < 0) { 865 y_offset = (-new_state->crtc_y) + offset_y; 866 y = 0; 867 } else { 868 y_offset = offset_y; 869 y = new_state->crtc_y; 870 } 871 872 ast_set_cursor_location(ast, x, y, x_offset, y_offset); 873 874 /* Dummy write to enable HWC and make the HW pick-up the changes. */ 875 ast_set_cursor_enabled(ast, true); 876 } 877 878 static void 879 ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane, 880 struct drm_atomic_state *state) 881 { 882 struct ast_private *ast = to_ast_private(plane->dev); 883 884 ast_set_cursor_enabled(ast, false); 885 } 886 887 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { 888 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 889 .atomic_check = ast_cursor_plane_helper_atomic_check, 890 .atomic_update = ast_cursor_plane_helper_atomic_update, 891 .atomic_disable = ast_cursor_plane_helper_atomic_disable, 892 }; 893 894 static void ast_cursor_plane_destroy(struct drm_plane *plane) 895 { 896 struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane); 897 size_t i; 898 struct drm_gem_vram_object *gbo; 899 struct iosys_map map; 900 901 for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) { 902 gbo = ast_cursor_plane->hwc[i].gbo; 903 map = ast_cursor_plane->hwc[i].map; 904 drm_gem_vram_vunmap(gbo, &map); 905 drm_gem_vram_unpin(gbo); 906 drm_gem_vram_put(gbo); 907 } 908 909 drm_plane_cleanup(plane); 910 } 911 912 static const struct drm_plane_funcs ast_cursor_plane_funcs = { 913 .update_plane = drm_atomic_helper_update_plane, 914 .disable_plane = drm_atomic_helper_disable_plane, 915 .destroy = ast_cursor_plane_destroy, 916 DRM_GEM_SHADOW_PLANE_FUNCS, 917 }; 918 919 static int ast_cursor_plane_init(struct ast_private *ast) 920 { 921 struct drm_device *dev = &ast->base; 922 struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane; 923 struct drm_plane *cursor_plane = &ast_cursor_plane->base; 924 size_t size, i; 925 struct drm_gem_vram_object *gbo; 926 struct iosys_map map; 927 int ret; 928 s64 off; 929 930 /* 931 * Allocate backing storage for cursors. The BOs are permanently 932 * pinned to the top end of the VRAM. 933 */ 934 935 size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); 936 937 for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) { 938 gbo = drm_gem_vram_create(dev, size, 0); 939 if (IS_ERR(gbo)) { 940 ret = PTR_ERR(gbo); 941 goto err_hwc; 942 } 943 ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | 944 DRM_GEM_VRAM_PL_FLAG_TOPDOWN); 945 if (ret) 946 goto err_drm_gem_vram_put; 947 ret = drm_gem_vram_vmap(gbo, &map); 948 if (ret) 949 goto err_drm_gem_vram_unpin; 950 off = drm_gem_vram_offset(gbo); 951 if (off < 0) { 952 ret = off; 953 goto err_drm_gem_vram_vunmap; 954 } 955 ast_cursor_plane->hwc[i].gbo = gbo; 956 ast_cursor_plane->hwc[i].map = map; 957 ast_cursor_plane->hwc[i].off = off; 958 } 959 960 /* 961 * Create the cursor plane. The plane's destroy callback will release 962 * the backing storages' BO memory. 963 */ 964 965 ret = drm_universal_plane_init(dev, cursor_plane, 0x01, 966 &ast_cursor_plane_funcs, 967 ast_cursor_plane_formats, 968 ARRAY_SIZE(ast_cursor_plane_formats), 969 NULL, DRM_PLANE_TYPE_CURSOR, NULL); 970 if (ret) { 971 drm_err(dev, "drm_universal_plane failed(): %d\n", ret); 972 goto err_hwc; 973 } 974 drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs); 975 976 return 0; 977 978 err_hwc: 979 while (i) { 980 --i; 981 gbo = ast_cursor_plane->hwc[i].gbo; 982 map = ast_cursor_plane->hwc[i].map; 983 err_drm_gem_vram_vunmap: 984 drm_gem_vram_vunmap(gbo, &map); 985 err_drm_gem_vram_unpin: 986 drm_gem_vram_unpin(gbo); 987 err_drm_gem_vram_put: 988 drm_gem_vram_put(gbo); 989 } 990 return ret; 991 } 992 993 /* 994 * CRTC 995 */ 996 997 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) 998 { 999 struct ast_private *ast = to_ast_private(crtc->dev); 1000 u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF; 1001 struct ast_crtc_state *ast_state; 1002 const struct drm_format_info *format; 1003 struct ast_vbios_mode_info *vbios_mode_info; 1004 1005 /* TODO: Maybe control display signal generation with 1006 * Sync Enable (bit CR17.7). 1007 */ 1008 switch (mode) { 1009 case DRM_MODE_DPMS_ON: 1010 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0); 1011 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); 1012 if (ast->tx_chip_types & AST_TX_DP501_BIT) 1013 ast_set_dp501_video_output(crtc->dev, 1); 1014 1015 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1016 ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON); 1017 ast_wait_for_vretrace(ast); 1018 ast_dp_set_on_off(crtc->dev, 1); 1019 } 1020 1021 ast_state = to_ast_crtc_state(crtc->state); 1022 format = ast_state->format; 1023 1024 if (format) { 1025 vbios_mode_info = &ast_state->vbios_mode_info; 1026 1027 ast_set_color_reg(ast, format); 1028 ast_set_vbios_color_reg(ast, format, vbios_mode_info); 1029 } 1030 1031 ast_crtc_load_lut(ast, crtc); 1032 break; 1033 case DRM_MODE_DPMS_STANDBY: 1034 case DRM_MODE_DPMS_SUSPEND: 1035 case DRM_MODE_DPMS_OFF: 1036 ch = mode; 1037 if (ast->tx_chip_types & AST_TX_DP501_BIT) 1038 ast_set_dp501_video_output(crtc->dev, 0); 1039 1040 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1041 ast_dp_set_on_off(crtc->dev, 0); 1042 ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); 1043 } 1044 1045 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20); 1046 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); 1047 break; 1048 } 1049 } 1050 1051 static enum drm_mode_status 1052 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 1053 { 1054 struct ast_private *ast = to_ast_private(crtc->dev); 1055 enum drm_mode_status status; 1056 uint32_t jtemp; 1057 1058 if (ast->support_wide_screen) { 1059 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) 1060 return MODE_OK; 1061 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) 1062 return MODE_OK; 1063 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) 1064 return MODE_OK; 1065 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) 1066 return MODE_OK; 1067 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) 1068 return MODE_OK; 1069 if ((mode->hdisplay == 1152) && (mode->vdisplay == 864)) 1070 return MODE_OK; 1071 1072 if ((ast->chip == AST2100) || (ast->chip == AST2200) || 1073 (ast->chip == AST2300) || (ast->chip == AST2400) || 1074 (ast->chip == AST2500) || (ast->chip == AST2600)) { 1075 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) 1076 return MODE_OK; 1077 1078 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { 1079 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); 1080 if (jtemp & 0x01) 1081 return MODE_NOMODE; 1082 else 1083 return MODE_OK; 1084 } 1085 } 1086 } 1087 1088 status = MODE_NOMODE; 1089 1090 switch (mode->hdisplay) { 1091 case 640: 1092 if (mode->vdisplay == 480) 1093 status = MODE_OK; 1094 break; 1095 case 800: 1096 if (mode->vdisplay == 600) 1097 status = MODE_OK; 1098 break; 1099 case 1024: 1100 if (mode->vdisplay == 768) 1101 status = MODE_OK; 1102 break; 1103 case 1152: 1104 if (mode->vdisplay == 864) 1105 status = MODE_OK; 1106 break; 1107 case 1280: 1108 if (mode->vdisplay == 1024) 1109 status = MODE_OK; 1110 break; 1111 case 1600: 1112 if (mode->vdisplay == 1200) 1113 status = MODE_OK; 1114 break; 1115 default: 1116 break; 1117 } 1118 1119 return status; 1120 } 1121 1122 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 1123 struct drm_atomic_state *state) 1124 { 1125 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1126 struct drm_device *dev = crtc->dev; 1127 struct ast_crtc_state *ast_state; 1128 const struct drm_format_info *format; 1129 bool succ; 1130 int ret; 1131 1132 ret = drm_atomic_helper_check_crtc_state(crtc_state, false); 1133 if (ret) 1134 return ret; 1135 1136 if (!crtc_state->enable) 1137 goto out; 1138 1139 ast_state = to_ast_crtc_state(crtc_state); 1140 1141 format = ast_state->format; 1142 if (drm_WARN_ON_ONCE(dev, !format)) 1143 return -EINVAL; /* BUG: We didn't set format in primary check(). */ 1144 1145 succ = ast_get_vbios_mode_info(format, &crtc_state->mode, 1146 &crtc_state->adjusted_mode, 1147 &ast_state->vbios_mode_info); 1148 if (!succ) 1149 return -EINVAL; 1150 1151 out: 1152 return drm_atomic_add_affected_planes(state, crtc); 1153 } 1154 1155 static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) 1156 { 1157 struct drm_device *dev = crtc->dev; 1158 struct ast_private *ast = to_ast_private(dev); 1159 1160 /* 1161 * Concurrent operations could possibly trigger a call to 1162 * drm_connector_helper_funcs.get_modes by trying to read the 1163 * display modes. Protect access to I/O registers by acquiring 1164 * the I/O-register lock. Released in atomic_flush(). 1165 */ 1166 mutex_lock(&ast->ioregs_lock); 1167 } 1168 1169 static void 1170 ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, 1171 struct drm_atomic_state *state) 1172 { 1173 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, 1174 crtc); 1175 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, 1176 crtc); 1177 struct drm_device *dev = crtc->dev; 1178 struct ast_private *ast = to_ast_private(dev); 1179 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1180 struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); 1181 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 1182 1183 /* 1184 * The gamma LUT has to be reloaded after changing the primary 1185 * plane's color format. 1186 */ 1187 if (old_ast_crtc_state->format != ast_crtc_state->format) 1188 ast_crtc_load_lut(ast, crtc); 1189 1190 //Set Aspeed Display-Port 1191 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) 1192 ast_dp_set_mode(crtc, vbios_mode_info); 1193 1194 mutex_unlock(&ast->ioregs_lock); 1195 } 1196 1197 static void 1198 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, 1199 struct drm_atomic_state *state) 1200 { 1201 struct drm_device *dev = crtc->dev; 1202 struct ast_private *ast = to_ast_private(dev); 1203 struct drm_crtc_state *crtc_state = crtc->state; 1204 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1205 struct ast_vbios_mode_info *vbios_mode_info = 1206 &ast_crtc_state->vbios_mode_info; 1207 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1208 1209 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 1210 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); 1211 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 1212 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 1213 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 1214 ast_set_crtthd_reg(ast); 1215 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 1216 1217 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 1218 } 1219 1220 static void 1221 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, 1222 struct drm_atomic_state *state) 1223 { 1224 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, 1225 crtc); 1226 struct drm_device *dev = crtc->dev; 1227 struct ast_private *ast = to_ast_private(dev); 1228 1229 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1230 1231 /* 1232 * HW cursors require the underlying primary plane and CRTC to 1233 * display a valid mode and image. This is not the case during 1234 * full modeset operations. So we temporarily disable any active 1235 * plane, including the HW cursor. Each plane's atomic_update() 1236 * helper will re-enable it if necessary. 1237 * 1238 * We only do this during *full* modesets. It does not affect 1239 * simple pageflips on the planes. 1240 */ 1241 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 1242 1243 /* 1244 * Ensure that no scanout takes place before reprogramming mode 1245 * and format registers. 1246 */ 1247 ast_wait_for_vretrace(ast); 1248 } 1249 1250 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 1251 .mode_valid = ast_crtc_helper_mode_valid, 1252 .atomic_check = ast_crtc_helper_atomic_check, 1253 .atomic_begin = ast_crtc_helper_atomic_begin, 1254 .atomic_flush = ast_crtc_helper_atomic_flush, 1255 .atomic_enable = ast_crtc_helper_atomic_enable, 1256 .atomic_disable = ast_crtc_helper_atomic_disable, 1257 }; 1258 1259 static void ast_crtc_reset(struct drm_crtc *crtc) 1260 { 1261 struct ast_crtc_state *ast_state = 1262 kzalloc(sizeof(*ast_state), GFP_KERNEL); 1263 1264 if (crtc->state) 1265 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 1266 1267 if (ast_state) 1268 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); 1269 else 1270 __drm_atomic_helper_crtc_reset(crtc, NULL); 1271 } 1272 1273 static struct drm_crtc_state * 1274 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 1275 { 1276 struct ast_crtc_state *new_ast_state, *ast_state; 1277 struct drm_device *dev = crtc->dev; 1278 1279 if (drm_WARN_ON(dev, !crtc->state)) 1280 return NULL; 1281 1282 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); 1283 if (!new_ast_state) 1284 return NULL; 1285 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); 1286 1287 ast_state = to_ast_crtc_state(crtc->state); 1288 1289 new_ast_state->format = ast_state->format; 1290 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, 1291 sizeof(new_ast_state->vbios_mode_info)); 1292 1293 return &new_ast_state->base; 1294 } 1295 1296 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, 1297 struct drm_crtc_state *state) 1298 { 1299 struct ast_crtc_state *ast_state = to_ast_crtc_state(state); 1300 1301 __drm_atomic_helper_crtc_destroy_state(&ast_state->base); 1302 kfree(ast_state); 1303 } 1304 1305 static const struct drm_crtc_funcs ast_crtc_funcs = { 1306 .reset = ast_crtc_reset, 1307 .destroy = drm_crtc_cleanup, 1308 .set_config = drm_atomic_helper_set_config, 1309 .page_flip = drm_atomic_helper_page_flip, 1310 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state, 1311 .atomic_destroy_state = ast_crtc_atomic_destroy_state, 1312 }; 1313 1314 static int ast_crtc_init(struct drm_device *dev) 1315 { 1316 struct ast_private *ast = to_ast_private(dev); 1317 struct drm_crtc *crtc = &ast->crtc; 1318 int ret; 1319 1320 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane, 1321 &ast->cursor_plane.base, &ast_crtc_funcs, 1322 NULL); 1323 if (ret) 1324 return ret; 1325 1326 drm_mode_crtc_set_gamma_size(crtc, 256); 1327 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 1328 1329 return 0; 1330 } 1331 1332 /* 1333 * VGA Connector 1334 */ 1335 1336 static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) 1337 { 1338 struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector); 1339 struct drm_device *dev = connector->dev; 1340 struct ast_private *ast = to_ast_private(dev); 1341 struct edid *edid; 1342 int count; 1343 1344 if (!ast_vga_connector->i2c) 1345 goto err_drm_connector_update_edid_property; 1346 1347 /* 1348 * Protect access to I/O registers from concurrent modesetting 1349 * by acquiring the I/O-register lock. 1350 */ 1351 mutex_lock(&ast->ioregs_lock); 1352 1353 edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter); 1354 if (!edid) 1355 goto err_mutex_unlock; 1356 1357 mutex_unlock(&ast->ioregs_lock); 1358 1359 count = drm_add_edid_modes(connector, edid); 1360 kfree(edid); 1361 1362 return count; 1363 1364 err_mutex_unlock: 1365 mutex_unlock(&ast->ioregs_lock); 1366 err_drm_connector_update_edid_property: 1367 drm_connector_update_edid_property(connector, NULL); 1368 return 0; 1369 } 1370 1371 static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = { 1372 .get_modes = ast_vga_connector_helper_get_modes, 1373 }; 1374 1375 static const struct drm_connector_funcs ast_vga_connector_funcs = { 1376 .reset = drm_atomic_helper_connector_reset, 1377 .fill_modes = drm_helper_probe_single_connector_modes, 1378 .destroy = drm_connector_cleanup, 1379 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1380 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1381 }; 1382 1383 static int ast_vga_connector_init(struct drm_device *dev, 1384 struct ast_vga_connector *ast_vga_connector) 1385 { 1386 struct drm_connector *connector = &ast_vga_connector->base; 1387 int ret; 1388 1389 ast_vga_connector->i2c = ast_i2c_create(dev); 1390 if (!ast_vga_connector->i2c) 1391 drm_err(dev, "failed to add ddc bus for connector\n"); 1392 1393 if (ast_vga_connector->i2c) 1394 ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs, 1395 DRM_MODE_CONNECTOR_VGA, 1396 &ast_vga_connector->i2c->adapter); 1397 else 1398 ret = drm_connector_init(dev, connector, &ast_vga_connector_funcs, 1399 DRM_MODE_CONNECTOR_VGA); 1400 if (ret) 1401 return ret; 1402 1403 drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs); 1404 1405 connector->interlace_allowed = 0; 1406 connector->doublescan_allowed = 0; 1407 1408 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1409 1410 return 0; 1411 } 1412 1413 static int ast_vga_output_init(struct ast_private *ast) 1414 { 1415 struct drm_device *dev = &ast->base; 1416 struct drm_crtc *crtc = &ast->crtc; 1417 struct drm_encoder *encoder = &ast->output.vga.encoder; 1418 struct ast_vga_connector *ast_vga_connector = &ast->output.vga.vga_connector; 1419 struct drm_connector *connector = &ast_vga_connector->base; 1420 int ret; 1421 1422 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); 1423 if (ret) 1424 return ret; 1425 encoder->possible_crtcs = drm_crtc_mask(crtc); 1426 1427 ret = ast_vga_connector_init(dev, ast_vga_connector); 1428 if (ret) 1429 return ret; 1430 1431 ret = drm_connector_attach_encoder(connector, encoder); 1432 if (ret) 1433 return ret; 1434 1435 return 0; 1436 } 1437 1438 /* 1439 * SIL164 Connector 1440 */ 1441 1442 static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector) 1443 { 1444 struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector); 1445 struct drm_device *dev = connector->dev; 1446 struct ast_private *ast = to_ast_private(dev); 1447 struct edid *edid; 1448 int count; 1449 1450 if (!ast_sil164_connector->i2c) 1451 goto err_drm_connector_update_edid_property; 1452 1453 /* 1454 * Protect access to I/O registers from concurrent modesetting 1455 * by acquiring the I/O-register lock. 1456 */ 1457 mutex_lock(&ast->ioregs_lock); 1458 1459 edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter); 1460 if (!edid) 1461 goto err_mutex_unlock; 1462 1463 mutex_unlock(&ast->ioregs_lock); 1464 1465 count = drm_add_edid_modes(connector, edid); 1466 kfree(edid); 1467 1468 return count; 1469 1470 err_mutex_unlock: 1471 mutex_unlock(&ast->ioregs_lock); 1472 err_drm_connector_update_edid_property: 1473 drm_connector_update_edid_property(connector, NULL); 1474 return 0; 1475 } 1476 1477 static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = { 1478 .get_modes = ast_sil164_connector_helper_get_modes, 1479 }; 1480 1481 static const struct drm_connector_funcs ast_sil164_connector_funcs = { 1482 .reset = drm_atomic_helper_connector_reset, 1483 .fill_modes = drm_helper_probe_single_connector_modes, 1484 .destroy = drm_connector_cleanup, 1485 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1486 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1487 }; 1488 1489 static int ast_sil164_connector_init(struct drm_device *dev, 1490 struct ast_sil164_connector *ast_sil164_connector) 1491 { 1492 struct drm_connector *connector = &ast_sil164_connector->base; 1493 int ret; 1494 1495 ast_sil164_connector->i2c = ast_i2c_create(dev); 1496 if (!ast_sil164_connector->i2c) 1497 drm_err(dev, "failed to add ddc bus for connector\n"); 1498 1499 if (ast_sil164_connector->i2c) 1500 ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs, 1501 DRM_MODE_CONNECTOR_DVII, 1502 &ast_sil164_connector->i2c->adapter); 1503 else 1504 ret = drm_connector_init(dev, connector, &ast_sil164_connector_funcs, 1505 DRM_MODE_CONNECTOR_DVII); 1506 if (ret) 1507 return ret; 1508 1509 drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs); 1510 1511 connector->interlace_allowed = 0; 1512 connector->doublescan_allowed = 0; 1513 1514 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1515 1516 return 0; 1517 } 1518 1519 static int ast_sil164_output_init(struct ast_private *ast) 1520 { 1521 struct drm_device *dev = &ast->base; 1522 struct drm_crtc *crtc = &ast->crtc; 1523 struct drm_encoder *encoder = &ast->output.sil164.encoder; 1524 struct ast_sil164_connector *ast_sil164_connector = &ast->output.sil164.sil164_connector; 1525 struct drm_connector *connector = &ast_sil164_connector->base; 1526 int ret; 1527 1528 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS); 1529 if (ret) 1530 return ret; 1531 encoder->possible_crtcs = drm_crtc_mask(crtc); 1532 1533 ret = ast_sil164_connector_init(dev, ast_sil164_connector); 1534 if (ret) 1535 return ret; 1536 1537 ret = drm_connector_attach_encoder(connector, encoder); 1538 if (ret) 1539 return ret; 1540 1541 return 0; 1542 } 1543 1544 /* 1545 * DP501 Connector 1546 */ 1547 1548 static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector) 1549 { 1550 void *edid; 1551 bool succ; 1552 int count; 1553 1554 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 1555 if (!edid) 1556 goto err_drm_connector_update_edid_property; 1557 1558 succ = ast_dp501_read_edid(connector->dev, edid); 1559 if (!succ) 1560 goto err_kfree; 1561 1562 drm_connector_update_edid_property(connector, edid); 1563 count = drm_add_edid_modes(connector, edid); 1564 kfree(edid); 1565 1566 return count; 1567 1568 err_kfree: 1569 kfree(edid); 1570 err_drm_connector_update_edid_property: 1571 drm_connector_update_edid_property(connector, NULL); 1572 return 0; 1573 } 1574 1575 static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = { 1576 .get_modes = ast_dp501_connector_helper_get_modes, 1577 }; 1578 1579 static const struct drm_connector_funcs ast_dp501_connector_funcs = { 1580 .reset = drm_atomic_helper_connector_reset, 1581 .fill_modes = drm_helper_probe_single_connector_modes, 1582 .destroy = drm_connector_cleanup, 1583 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1584 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1585 }; 1586 1587 static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector) 1588 { 1589 int ret; 1590 1591 ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, 1592 DRM_MODE_CONNECTOR_DisplayPort); 1593 if (ret) 1594 return ret; 1595 1596 drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); 1597 1598 connector->interlace_allowed = 0; 1599 connector->doublescan_allowed = 0; 1600 1601 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1602 1603 return 0; 1604 } 1605 1606 static int ast_dp501_output_init(struct ast_private *ast) 1607 { 1608 struct drm_device *dev = &ast->base; 1609 struct drm_crtc *crtc = &ast->crtc; 1610 struct drm_encoder *encoder = &ast->output.dp501.encoder; 1611 struct drm_connector *connector = &ast->output.dp501.connector; 1612 int ret; 1613 1614 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS); 1615 if (ret) 1616 return ret; 1617 encoder->possible_crtcs = drm_crtc_mask(crtc); 1618 1619 ret = ast_dp501_connector_init(dev, connector); 1620 if (ret) 1621 return ret; 1622 1623 ret = drm_connector_attach_encoder(connector, encoder); 1624 if (ret) 1625 return ret; 1626 1627 return 0; 1628 } 1629 1630 /* 1631 * ASPEED Display-Port Connector 1632 */ 1633 1634 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector) 1635 { 1636 void *edid; 1637 1638 int succ; 1639 int count; 1640 1641 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 1642 if (!edid) 1643 goto err_drm_connector_update_edid_property; 1644 1645 succ = ast_astdp_read_edid(connector->dev, edid); 1646 if (succ < 0) 1647 goto err_kfree; 1648 1649 drm_connector_update_edid_property(connector, edid); 1650 count = drm_add_edid_modes(connector, edid); 1651 kfree(edid); 1652 1653 return count; 1654 1655 err_kfree: 1656 kfree(edid); 1657 err_drm_connector_update_edid_property: 1658 drm_connector_update_edid_property(connector, NULL); 1659 return 0; 1660 } 1661 1662 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = { 1663 .get_modes = ast_astdp_connector_helper_get_modes, 1664 }; 1665 1666 static const struct drm_connector_funcs ast_astdp_connector_funcs = { 1667 .reset = drm_atomic_helper_connector_reset, 1668 .fill_modes = drm_helper_probe_single_connector_modes, 1669 .destroy = drm_connector_cleanup, 1670 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1671 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1672 }; 1673 1674 static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector) 1675 { 1676 int ret; 1677 1678 ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, 1679 DRM_MODE_CONNECTOR_DisplayPort); 1680 if (ret) 1681 return ret; 1682 1683 drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); 1684 1685 connector->interlace_allowed = 0; 1686 connector->doublescan_allowed = 0; 1687 1688 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1689 1690 return 0; 1691 } 1692 1693 static int ast_astdp_output_init(struct ast_private *ast) 1694 { 1695 struct drm_device *dev = &ast->base; 1696 struct drm_crtc *crtc = &ast->crtc; 1697 struct drm_encoder *encoder = &ast->output.astdp.encoder; 1698 struct drm_connector *connector = &ast->output.astdp.connector; 1699 int ret; 1700 1701 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS); 1702 if (ret) 1703 return ret; 1704 encoder->possible_crtcs = drm_crtc_mask(crtc); 1705 1706 ret = ast_astdp_connector_init(dev, connector); 1707 if (ret) 1708 return ret; 1709 1710 ret = drm_connector_attach_encoder(connector, encoder); 1711 if (ret) 1712 return ret; 1713 1714 return 0; 1715 } 1716 1717 /* 1718 * Mode config 1719 */ 1720 1721 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = { 1722 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, 1723 }; 1724 1725 static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1726 .fb_create = drm_gem_fb_create, 1727 .mode_valid = drm_vram_helper_mode_valid, 1728 .atomic_check = drm_atomic_helper_check, 1729 .atomic_commit = drm_atomic_helper_commit, 1730 }; 1731 1732 int ast_mode_config_init(struct ast_private *ast) 1733 { 1734 struct drm_device *dev = &ast->base; 1735 struct pci_dev *pdev = to_pci_dev(dev->dev); 1736 int ret; 1737 1738 ret = drmm_mode_config_init(dev); 1739 if (ret) 1740 return ret; 1741 1742 dev->mode_config.funcs = &ast_mode_config_funcs; 1743 dev->mode_config.min_width = 0; 1744 dev->mode_config.min_height = 0; 1745 dev->mode_config.preferred_depth = 24; 1746 dev->mode_config.prefer_shadow = 1; 1747 dev->mode_config.fb_base = pci_resource_start(pdev, 0); 1748 1749 if (ast->chip == AST2100 || 1750 ast->chip == AST2200 || 1751 ast->chip == AST2300 || 1752 ast->chip == AST2400 || 1753 ast->chip == AST2500 || 1754 ast->chip == AST2600) { 1755 dev->mode_config.max_width = 1920; 1756 dev->mode_config.max_height = 2048; 1757 } else { 1758 dev->mode_config.max_width = 1600; 1759 dev->mode_config.max_height = 1200; 1760 } 1761 1762 dev->mode_config.helper_private = &ast_mode_config_helper_funcs; 1763 1764 1765 ret = ast_primary_plane_init(ast); 1766 if (ret) 1767 return ret; 1768 1769 ret = ast_cursor_plane_init(ast); 1770 if (ret) 1771 return ret; 1772 1773 ast_crtc_init(dev); 1774 1775 if (ast->tx_chip_types & AST_TX_NONE_BIT) { 1776 ret = ast_vga_output_init(ast); 1777 if (ret) 1778 return ret; 1779 } 1780 if (ast->tx_chip_types & AST_TX_SIL164_BIT) { 1781 ret = ast_sil164_output_init(ast); 1782 if (ret) 1783 return ret; 1784 } 1785 if (ast->tx_chip_types & AST_TX_DP501_BIT) { 1786 ret = ast_dp501_output_init(ast); 1787 if (ret) 1788 return ret; 1789 } 1790 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1791 ret = ast_astdp_output_init(ast); 1792 if (ret) 1793 return ret; 1794 } 1795 1796 drm_mode_config_reset(dev); 1797 1798 return 0; 1799 } 1800