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