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