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/delay.h> 32 #include <linux/export.h> 33 #include <linux/pci.h> 34 35 #include <drm/drm_atomic.h> 36 #include <drm/drm_atomic_helper.h> 37 #include <drm/drm_atomic_state_helper.h> 38 #include <drm/drm_crtc.h> 39 #include <drm/drm_damage_helper.h> 40 #include <drm/drm_edid.h> 41 #include <drm/drm_format_helper.h> 42 #include <drm/drm_fourcc.h> 43 #include <drm/drm_gem_atomic_helper.h> 44 #include <drm/drm_gem_framebuffer_helper.h> 45 #include <drm/drm_gem_shmem_helper.h> 46 #include <drm/drm_managed.h> 47 #include <drm/drm_panic.h> 48 #include <drm/drm_probe_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, 0x20, 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_crtc *crtc = plane_state->crtc; 654 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 655 struct drm_rect damage; 656 struct drm_atomic_helper_damage_iter iter; 657 658 if (!old_fb || (fb->format != old_fb->format) || crtc_state->mode_changed) { 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 } 695 696 static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, 697 struct drm_atomic_state *state) 698 { 699 /* 700 * Keep this empty function to avoid calling 701 * atomic_update when disabling the plane. 702 */ 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 enum drm_mode_status 1024 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 1025 { 1026 struct ast_device *ast = to_ast_device(crtc->dev); 1027 enum drm_mode_status status; 1028 uint32_t jtemp; 1029 1030 if (ast->support_wide_screen) { 1031 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) 1032 return MODE_OK; 1033 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) 1034 return MODE_OK; 1035 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) 1036 return MODE_OK; 1037 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) 1038 return MODE_OK; 1039 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) 1040 return MODE_OK; 1041 if ((mode->hdisplay == 1152) && (mode->vdisplay == 864)) 1042 return MODE_OK; 1043 1044 if ((ast->chip == AST2100) || // GEN2, but not AST1100 (?) 1045 (ast->chip == AST2200) || // GEN3, but not AST2150 (?) 1046 IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || 1047 IS_AST_GEN6(ast) || IS_AST_GEN7(ast)) { 1048 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) 1049 return MODE_OK; 1050 1051 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { 1052 jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); 1053 if (jtemp & 0x01) 1054 return MODE_NOMODE; 1055 else 1056 return MODE_OK; 1057 } 1058 } 1059 } 1060 1061 status = MODE_NOMODE; 1062 1063 switch (mode->hdisplay) { 1064 case 640: 1065 if (mode->vdisplay == 480) 1066 status = MODE_OK; 1067 break; 1068 case 800: 1069 if (mode->vdisplay == 600) 1070 status = MODE_OK; 1071 break; 1072 case 1024: 1073 if (mode->vdisplay == 768) 1074 status = MODE_OK; 1075 break; 1076 case 1152: 1077 if (mode->vdisplay == 864) 1078 status = MODE_OK; 1079 break; 1080 case 1280: 1081 if (mode->vdisplay == 1024) 1082 status = MODE_OK; 1083 break; 1084 case 1600: 1085 if (mode->vdisplay == 1200) 1086 status = MODE_OK; 1087 break; 1088 default: 1089 break; 1090 } 1091 1092 return status; 1093 } 1094 1095 static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc) 1096 { 1097 struct drm_device *dev = crtc->dev; 1098 struct ast_device *ast = to_ast_device(dev); 1099 struct drm_crtc_state *crtc_state = crtc->state; 1100 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1101 struct ast_vbios_mode_info *vbios_mode_info = 1102 &ast_crtc_state->vbios_mode_info; 1103 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1104 1105 /* 1106 * Ensure that no scanout takes place before reprogramming mode 1107 * and format registers. 1108 * 1109 * TODO: Get vblank interrupts working and remove this line. 1110 */ 1111 ast_wait_for_vretrace(ast); 1112 1113 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 1114 ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); 1115 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 1116 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 1117 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 1118 ast_set_crtthd_reg(ast); 1119 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 1120 } 1121 1122 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 1123 struct drm_atomic_state *state) 1124 { 1125 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 1126 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1127 struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); 1128 struct drm_device *dev = crtc->dev; 1129 struct ast_crtc_state *ast_state; 1130 const struct drm_format_info *format; 1131 bool succ; 1132 int ret; 1133 1134 if (!crtc_state->enable) 1135 return 0; 1136 1137 ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state); 1138 if (ret) 1139 return ret; 1140 1141 ast_state = to_ast_crtc_state(crtc_state); 1142 1143 format = ast_state->format; 1144 if (drm_WARN_ON_ONCE(dev, !format)) 1145 return -EINVAL; /* BUG: We didn't set format in primary check(). */ 1146 1147 /* 1148 * The gamma LUT has to be reloaded after changing the primary 1149 * plane's color format. 1150 */ 1151 if (old_ast_crtc_state->format != format) 1152 crtc_state->color_mgmt_changed = true; 1153 1154 if (crtc_state->color_mgmt_changed && crtc_state->gamma_lut) { 1155 if (crtc_state->gamma_lut->length != 1156 AST_LUT_SIZE * sizeof(struct drm_color_lut)) { 1157 drm_err(dev, "Wrong size for gamma_lut %zu\n", 1158 crtc_state->gamma_lut->length); 1159 return -EINVAL; 1160 } 1161 } 1162 1163 succ = ast_get_vbios_mode_info(format, &crtc_state->mode, 1164 &crtc_state->adjusted_mode, 1165 &ast_state->vbios_mode_info); 1166 if (!succ) 1167 return -EINVAL; 1168 1169 return 0; 1170 } 1171 1172 static void 1173 ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, 1174 struct drm_atomic_state *state) 1175 { 1176 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, 1177 crtc); 1178 struct drm_device *dev = crtc->dev; 1179 struct ast_device *ast = to_ast_device(dev); 1180 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1181 1182 /* 1183 * The gamma LUT has to be reloaded after changing the primary 1184 * plane's color format. 1185 */ 1186 if (crtc_state->enable && crtc_state->color_mgmt_changed) { 1187 if (crtc_state->gamma_lut) 1188 ast_crtc_set_gamma(ast, 1189 ast_crtc_state->format, 1190 crtc_state->gamma_lut->data); 1191 else 1192 ast_crtc_set_gamma_linear(ast, ast_crtc_state->format); 1193 } 1194 } 1195 1196 static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) 1197 { 1198 struct ast_device *ast = to_ast_device(crtc->dev); 1199 1200 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0x00); 1201 ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x00); 1202 } 1203 1204 static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state) 1205 { 1206 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); 1207 struct ast_device *ast = to_ast_device(crtc->dev); 1208 u8 vgacrb6; 1209 1210 ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, AST_IO_VGASR1_SD); 1211 1212 vgacrb6 = AST_IO_VGACRB6_VSYNC_OFF | 1213 AST_IO_VGACRB6_HSYNC_OFF; 1214 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6); 1215 1216 /* 1217 * HW cursors require the underlying primary plane and CRTC to 1218 * display a valid mode and image. This is not the case during 1219 * full modeset operations. So we temporarily disable any active 1220 * plane, including the HW cursor. Each plane's atomic_update() 1221 * helper will re-enable it if necessary. 1222 * 1223 * We only do this during *full* modesets. It does not affect 1224 * simple pageflips on the planes. 1225 */ 1226 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 1227 } 1228 1229 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 1230 .mode_valid = ast_crtc_helper_mode_valid, 1231 .mode_set_nofb = ast_crtc_helper_mode_set_nofb, 1232 .atomic_check = ast_crtc_helper_atomic_check, 1233 .atomic_flush = ast_crtc_helper_atomic_flush, 1234 .atomic_enable = ast_crtc_helper_atomic_enable, 1235 .atomic_disable = ast_crtc_helper_atomic_disable, 1236 }; 1237 1238 static void ast_crtc_reset(struct drm_crtc *crtc) 1239 { 1240 struct ast_crtc_state *ast_state = 1241 kzalloc(sizeof(*ast_state), GFP_KERNEL); 1242 1243 if (crtc->state) 1244 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 1245 1246 if (ast_state) 1247 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); 1248 else 1249 __drm_atomic_helper_crtc_reset(crtc, NULL); 1250 } 1251 1252 static struct drm_crtc_state * 1253 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 1254 { 1255 struct ast_crtc_state *new_ast_state, *ast_state; 1256 struct drm_device *dev = crtc->dev; 1257 1258 if (drm_WARN_ON(dev, !crtc->state)) 1259 return NULL; 1260 1261 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); 1262 if (!new_ast_state) 1263 return NULL; 1264 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); 1265 1266 ast_state = to_ast_crtc_state(crtc->state); 1267 1268 new_ast_state->format = ast_state->format; 1269 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, 1270 sizeof(new_ast_state->vbios_mode_info)); 1271 1272 return &new_ast_state->base; 1273 } 1274 1275 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, 1276 struct drm_crtc_state *state) 1277 { 1278 struct ast_crtc_state *ast_state = to_ast_crtc_state(state); 1279 1280 __drm_atomic_helper_crtc_destroy_state(&ast_state->base); 1281 kfree(ast_state); 1282 } 1283 1284 static const struct drm_crtc_funcs ast_crtc_funcs = { 1285 .reset = ast_crtc_reset, 1286 .destroy = drm_crtc_cleanup, 1287 .set_config = drm_atomic_helper_set_config, 1288 .page_flip = drm_atomic_helper_page_flip, 1289 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state, 1290 .atomic_destroy_state = ast_crtc_atomic_destroy_state, 1291 }; 1292 1293 static int ast_crtc_init(struct drm_device *dev) 1294 { 1295 struct ast_device *ast = to_ast_device(dev); 1296 struct drm_crtc *crtc = &ast->crtc; 1297 int ret; 1298 1299 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane.base, 1300 &ast->cursor_plane.base, &ast_crtc_funcs, 1301 NULL); 1302 if (ret) 1303 return ret; 1304 1305 drm_mode_crtc_set_gamma_size(crtc, AST_LUT_SIZE); 1306 drm_crtc_enable_color_mgmt(crtc, 0, false, AST_LUT_SIZE); 1307 1308 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 1309 1310 return 0; 1311 } 1312 1313 /* 1314 * VGA Encoder 1315 */ 1316 1317 static const struct drm_encoder_funcs ast_vga_encoder_funcs = { 1318 .destroy = drm_encoder_cleanup, 1319 }; 1320 1321 /* 1322 * VGA Connector 1323 */ 1324 1325 static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = { 1326 .get_modes = drm_connector_helper_get_modes, 1327 .detect_ctx = drm_connector_helper_detect_from_ddc, 1328 }; 1329 1330 static const struct drm_connector_funcs ast_vga_connector_funcs = { 1331 .reset = drm_atomic_helper_connector_reset, 1332 .fill_modes = drm_helper_probe_single_connector_modes, 1333 .destroy = drm_connector_cleanup, 1334 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1335 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1336 }; 1337 1338 static int ast_vga_connector_init(struct drm_device *dev, struct drm_connector *connector) 1339 { 1340 struct ast_device *ast = to_ast_device(dev); 1341 struct i2c_adapter *ddc; 1342 int ret; 1343 1344 ddc = ast_ddc_create(ast); 1345 if (IS_ERR(ddc)) { 1346 ret = PTR_ERR(ddc); 1347 drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); 1348 return ret; 1349 } 1350 1351 ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs, 1352 DRM_MODE_CONNECTOR_VGA, ddc); 1353 if (ret) 1354 return ret; 1355 1356 drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs); 1357 1358 connector->interlace_allowed = 0; 1359 connector->doublescan_allowed = 0; 1360 1361 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1362 1363 return 0; 1364 } 1365 1366 static int ast_vga_output_init(struct ast_device *ast) 1367 { 1368 struct drm_device *dev = &ast->base; 1369 struct drm_crtc *crtc = &ast->crtc; 1370 struct drm_encoder *encoder = &ast->output.vga.encoder; 1371 struct drm_connector *connector = &ast->output.vga.connector; 1372 int ret; 1373 1374 ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, 1375 DRM_MODE_ENCODER_DAC, NULL); 1376 if (ret) 1377 return ret; 1378 encoder->possible_crtcs = drm_crtc_mask(crtc); 1379 1380 ret = ast_vga_connector_init(dev, connector); 1381 if (ret) 1382 return ret; 1383 1384 ret = drm_connector_attach_encoder(connector, encoder); 1385 if (ret) 1386 return ret; 1387 1388 return 0; 1389 } 1390 1391 /* 1392 * SIL164 Encoder 1393 */ 1394 1395 static const struct drm_encoder_funcs ast_sil164_encoder_funcs = { 1396 .destroy = drm_encoder_cleanup, 1397 }; 1398 1399 /* 1400 * SIL164 Connector 1401 */ 1402 1403 static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = { 1404 .get_modes = drm_connector_helper_get_modes, 1405 .detect_ctx = drm_connector_helper_detect_from_ddc, 1406 }; 1407 1408 static const struct drm_connector_funcs ast_sil164_connector_funcs = { 1409 .reset = drm_atomic_helper_connector_reset, 1410 .fill_modes = drm_helper_probe_single_connector_modes, 1411 .destroy = drm_connector_cleanup, 1412 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1413 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1414 }; 1415 1416 static int ast_sil164_connector_init(struct drm_device *dev, struct drm_connector *connector) 1417 { 1418 struct ast_device *ast = to_ast_device(dev); 1419 struct i2c_adapter *ddc; 1420 int ret; 1421 1422 ddc = ast_ddc_create(ast); 1423 if (IS_ERR(ddc)) { 1424 ret = PTR_ERR(ddc); 1425 drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); 1426 return ret; 1427 } 1428 1429 ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs, 1430 DRM_MODE_CONNECTOR_DVII, ddc); 1431 if (ret) 1432 return ret; 1433 1434 drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs); 1435 1436 connector->interlace_allowed = 0; 1437 connector->doublescan_allowed = 0; 1438 1439 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1440 1441 return 0; 1442 } 1443 1444 static int ast_sil164_output_init(struct ast_device *ast) 1445 { 1446 struct drm_device *dev = &ast->base; 1447 struct drm_crtc *crtc = &ast->crtc; 1448 struct drm_encoder *encoder = &ast->output.sil164.encoder; 1449 struct drm_connector *connector = &ast->output.sil164.connector; 1450 int ret; 1451 1452 ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs, 1453 DRM_MODE_ENCODER_TMDS, NULL); 1454 if (ret) 1455 return ret; 1456 encoder->possible_crtcs = drm_crtc_mask(crtc); 1457 1458 ret = ast_sil164_connector_init(dev, connector); 1459 if (ret) 1460 return ret; 1461 1462 ret = drm_connector_attach_encoder(connector, encoder); 1463 if (ret) 1464 return ret; 1465 1466 return 0; 1467 } 1468 1469 /* 1470 * DP501 Encoder 1471 */ 1472 1473 static const struct drm_encoder_funcs ast_dp501_encoder_funcs = { 1474 .destroy = drm_encoder_cleanup, 1475 }; 1476 1477 static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder, 1478 struct drm_atomic_state *state) 1479 { 1480 struct drm_device *dev = encoder->dev; 1481 1482 ast_set_dp501_video_output(dev, 1); 1483 } 1484 1485 static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder, 1486 struct drm_atomic_state *state) 1487 { 1488 struct drm_device *dev = encoder->dev; 1489 1490 ast_set_dp501_video_output(dev, 0); 1491 } 1492 1493 static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = { 1494 .atomic_enable = ast_dp501_encoder_helper_atomic_enable, 1495 .atomic_disable = ast_dp501_encoder_helper_atomic_disable, 1496 }; 1497 1498 /* 1499 * DP501 Connector 1500 */ 1501 1502 static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector) 1503 { 1504 void *edid; 1505 bool succ; 1506 int count; 1507 1508 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 1509 if (!edid) 1510 goto err_drm_connector_update_edid_property; 1511 1512 succ = ast_dp501_read_edid(connector->dev, edid); 1513 if (!succ) 1514 goto err_kfree; 1515 1516 drm_connector_update_edid_property(connector, edid); 1517 count = drm_add_edid_modes(connector, edid); 1518 kfree(edid); 1519 1520 return count; 1521 1522 err_kfree: 1523 kfree(edid); 1524 err_drm_connector_update_edid_property: 1525 drm_connector_update_edid_property(connector, NULL); 1526 return 0; 1527 } 1528 1529 static int ast_dp501_connector_helper_detect_ctx(struct drm_connector *connector, 1530 struct drm_modeset_acquire_ctx *ctx, 1531 bool force) 1532 { 1533 struct ast_device *ast = to_ast_device(connector->dev); 1534 1535 if (ast_dp501_is_connected(ast)) 1536 return connector_status_connected; 1537 return connector_status_disconnected; 1538 } 1539 1540 static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = { 1541 .get_modes = ast_dp501_connector_helper_get_modes, 1542 .detect_ctx = ast_dp501_connector_helper_detect_ctx, 1543 }; 1544 1545 static const struct drm_connector_funcs ast_dp501_connector_funcs = { 1546 .reset = drm_atomic_helper_connector_reset, 1547 .fill_modes = drm_helper_probe_single_connector_modes, 1548 .destroy = drm_connector_cleanup, 1549 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1550 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1551 }; 1552 1553 static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector) 1554 { 1555 int ret; 1556 1557 ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, 1558 DRM_MODE_CONNECTOR_DisplayPort); 1559 if (ret) 1560 return ret; 1561 1562 drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); 1563 1564 connector->interlace_allowed = 0; 1565 connector->doublescan_allowed = 0; 1566 1567 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1568 1569 return 0; 1570 } 1571 1572 static int ast_dp501_output_init(struct ast_device *ast) 1573 { 1574 struct drm_device *dev = &ast->base; 1575 struct drm_crtc *crtc = &ast->crtc; 1576 struct drm_encoder *encoder = &ast->output.dp501.encoder; 1577 struct drm_connector *connector = &ast->output.dp501.connector; 1578 int ret; 1579 1580 ret = drm_encoder_init(dev, encoder, &ast_dp501_encoder_funcs, 1581 DRM_MODE_ENCODER_TMDS, NULL); 1582 if (ret) 1583 return ret; 1584 drm_encoder_helper_add(encoder, &ast_dp501_encoder_helper_funcs); 1585 1586 encoder->possible_crtcs = drm_crtc_mask(crtc); 1587 1588 ret = ast_dp501_connector_init(dev, connector); 1589 if (ret) 1590 return ret; 1591 1592 ret = drm_connector_attach_encoder(connector, encoder); 1593 if (ret) 1594 return ret; 1595 1596 return 0; 1597 } 1598 1599 /* 1600 * ASPEED Display-Port Encoder 1601 */ 1602 1603 static const struct drm_encoder_funcs ast_astdp_encoder_funcs = { 1604 .destroy = drm_encoder_cleanup, 1605 }; 1606 1607 static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder, 1608 struct drm_crtc_state *crtc_state, 1609 struct drm_connector_state *conn_state) 1610 { 1611 struct drm_crtc *crtc = crtc_state->crtc; 1612 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 1613 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 1614 1615 ast_dp_set_mode(crtc, vbios_mode_info); 1616 } 1617 1618 static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, 1619 struct drm_atomic_state *state) 1620 { 1621 struct drm_device *dev = encoder->dev; 1622 struct ast_device *ast = to_ast_device(dev); 1623 1624 ast_dp_power_on_off(dev, AST_DP_POWER_ON); 1625 ast_wait_for_vretrace(ast); 1626 ast_dp_set_on_off(dev, 1); 1627 } 1628 1629 static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, 1630 struct drm_atomic_state *state) 1631 { 1632 struct drm_device *dev = encoder->dev; 1633 1634 ast_dp_set_on_off(dev, 0); 1635 ast_dp_power_on_off(dev, AST_DP_POWER_OFF); 1636 } 1637 1638 static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = { 1639 .atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set, 1640 .atomic_enable = ast_astdp_encoder_helper_atomic_enable, 1641 .atomic_disable = ast_astdp_encoder_helper_atomic_disable, 1642 }; 1643 1644 /* 1645 * ASPEED Display-Port Connector 1646 */ 1647 1648 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector) 1649 { 1650 void *edid; 1651 struct drm_device *dev = connector->dev; 1652 struct ast_device *ast = to_ast_device(dev); 1653 1654 int succ; 1655 int count; 1656 1657 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 1658 if (!edid) 1659 goto err_drm_connector_update_edid_property; 1660 1661 /* 1662 * Protect access to I/O registers from concurrent modesetting 1663 * by acquiring the I/O-register lock. 1664 */ 1665 mutex_lock(&ast->modeset_lock); 1666 1667 succ = ast_astdp_read_edid(connector->dev, edid); 1668 if (succ < 0) 1669 goto err_mutex_unlock; 1670 1671 mutex_unlock(&ast->modeset_lock); 1672 1673 drm_connector_update_edid_property(connector, edid); 1674 count = drm_add_edid_modes(connector, edid); 1675 kfree(edid); 1676 1677 return count; 1678 1679 err_mutex_unlock: 1680 mutex_unlock(&ast->modeset_lock); 1681 kfree(edid); 1682 err_drm_connector_update_edid_property: 1683 drm_connector_update_edid_property(connector, NULL); 1684 return 0; 1685 } 1686 1687 static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector, 1688 struct drm_modeset_acquire_ctx *ctx, 1689 bool force) 1690 { 1691 struct drm_device *dev = connector->dev; 1692 struct ast_device *ast = to_ast_device(connector->dev); 1693 enum drm_connector_status status = connector_status_disconnected; 1694 struct drm_connector_state *connector_state = connector->state; 1695 bool is_active = false; 1696 1697 mutex_lock(&ast->modeset_lock); 1698 1699 if (connector_state && connector_state->crtc) { 1700 struct drm_crtc_state *crtc_state = connector_state->crtc->state; 1701 1702 if (crtc_state && crtc_state->active) 1703 is_active = true; 1704 } 1705 1706 if (!is_active && !ast_dp_power_is_on(ast)) { 1707 ast_dp_power_on_off(dev, true); 1708 msleep(50); 1709 } 1710 1711 if (ast_astdp_is_connected(ast)) 1712 status = connector_status_connected; 1713 1714 if (!is_active && status == connector_status_disconnected) 1715 ast_dp_power_on_off(dev, false); 1716 1717 mutex_unlock(&ast->modeset_lock); 1718 1719 return status; 1720 } 1721 1722 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = { 1723 .get_modes = ast_astdp_connector_helper_get_modes, 1724 .detect_ctx = ast_astdp_connector_helper_detect_ctx, 1725 }; 1726 1727 static const struct drm_connector_funcs ast_astdp_connector_funcs = { 1728 .reset = drm_atomic_helper_connector_reset, 1729 .fill_modes = drm_helper_probe_single_connector_modes, 1730 .destroy = drm_connector_cleanup, 1731 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1732 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1733 }; 1734 1735 static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector) 1736 { 1737 int ret; 1738 1739 ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, 1740 DRM_MODE_CONNECTOR_DisplayPort); 1741 if (ret) 1742 return ret; 1743 1744 drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); 1745 1746 connector->interlace_allowed = 0; 1747 connector->doublescan_allowed = 0; 1748 1749 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1750 1751 return 0; 1752 } 1753 1754 static int ast_astdp_output_init(struct ast_device *ast) 1755 { 1756 struct drm_device *dev = &ast->base; 1757 struct drm_crtc *crtc = &ast->crtc; 1758 struct drm_encoder *encoder = &ast->output.astdp.encoder; 1759 struct drm_connector *connector = &ast->output.astdp.connector; 1760 int ret; 1761 1762 ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs, 1763 DRM_MODE_ENCODER_TMDS, NULL); 1764 if (ret) 1765 return ret; 1766 drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs); 1767 1768 encoder->possible_crtcs = drm_crtc_mask(crtc); 1769 1770 ret = ast_astdp_connector_init(dev, connector); 1771 if (ret) 1772 return ret; 1773 1774 ret = drm_connector_attach_encoder(connector, encoder); 1775 if (ret) 1776 return ret; 1777 1778 return 0; 1779 } 1780 1781 /* 1782 * BMC virtual Connector 1783 */ 1784 1785 static const struct drm_encoder_funcs ast_bmc_encoder_funcs = { 1786 .destroy = drm_encoder_cleanup, 1787 }; 1788 1789 static int ast_bmc_connector_helper_detect_ctx(struct drm_connector *connector, 1790 struct drm_modeset_acquire_ctx *ctx, 1791 bool force) 1792 { 1793 struct ast_bmc_connector *bmc_connector = to_ast_bmc_connector(connector); 1794 struct drm_connector *physical_connector = bmc_connector->physical_connector; 1795 1796 /* 1797 * Most user-space compositors cannot handle more than one connected 1798 * connector per CRTC. Hence, we only mark the BMC as connected if the 1799 * physical connector is disconnected. If the physical connector's status 1800 * is connected or unknown, the BMC remains disconnected. This has no 1801 * effect on the output of the BMC. 1802 * 1803 * FIXME: Remove this logic once user-space compositors can handle more 1804 * than one connector per CRTC. The BMC should always be connected. 1805 */ 1806 1807 if (physical_connector && physical_connector->status == connector_status_disconnected) 1808 return connector_status_connected; 1809 1810 return connector_status_disconnected; 1811 } 1812 1813 static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector) 1814 { 1815 return drm_add_modes_noedid(connector, 4096, 4096); 1816 } 1817 1818 static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = { 1819 .get_modes = ast_bmc_connector_helper_get_modes, 1820 .detect_ctx = ast_bmc_connector_helper_detect_ctx, 1821 }; 1822 1823 static const struct drm_connector_funcs ast_bmc_connector_funcs = { 1824 .reset = drm_atomic_helper_connector_reset, 1825 .fill_modes = drm_helper_probe_single_connector_modes, 1826 .destroy = drm_connector_cleanup, 1827 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1828 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1829 }; 1830 1831 static int ast_bmc_connector_init(struct drm_device *dev, 1832 struct ast_bmc_connector *bmc_connector, 1833 struct drm_connector *physical_connector) 1834 { 1835 struct drm_connector *connector = &bmc_connector->base; 1836 int ret; 1837 1838 ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs, 1839 DRM_MODE_CONNECTOR_VIRTUAL); 1840 if (ret) 1841 return ret; 1842 1843 drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs); 1844 1845 bmc_connector->physical_connector = physical_connector; 1846 1847 return 0; 1848 } 1849 1850 static int ast_bmc_output_init(struct ast_device *ast, 1851 struct drm_connector *physical_connector) 1852 { 1853 struct drm_device *dev = &ast->base; 1854 struct drm_crtc *crtc = &ast->crtc; 1855 struct drm_encoder *encoder = &ast->output.bmc.encoder; 1856 struct ast_bmc_connector *bmc_connector = &ast->output.bmc.bmc_connector; 1857 struct drm_connector *connector = &bmc_connector->base; 1858 int ret; 1859 1860 ret = drm_encoder_init(dev, encoder, 1861 &ast_bmc_encoder_funcs, 1862 DRM_MODE_ENCODER_VIRTUAL, "ast_bmc"); 1863 if (ret) 1864 return ret; 1865 encoder->possible_crtcs = drm_crtc_mask(crtc); 1866 1867 ret = ast_bmc_connector_init(dev, bmc_connector, physical_connector); 1868 if (ret) 1869 return ret; 1870 1871 ret = drm_connector_attach_encoder(connector, encoder); 1872 if (ret) 1873 return ret; 1874 1875 return 0; 1876 } 1877 1878 /* 1879 * Mode config 1880 */ 1881 1882 static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *state) 1883 { 1884 struct ast_device *ast = to_ast_device(state->dev); 1885 1886 /* 1887 * Concurrent operations could possibly trigger a call to 1888 * drm_connector_helper_funcs.get_modes by trying to read the 1889 * display modes. Protect access to I/O registers by acquiring 1890 * the I/O-register lock. Released in atomic_flush(). 1891 */ 1892 mutex_lock(&ast->modeset_lock); 1893 drm_atomic_helper_commit_tail(state); 1894 mutex_unlock(&ast->modeset_lock); 1895 } 1896 1897 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = { 1898 .atomic_commit_tail = ast_mode_config_helper_atomic_commit_tail, 1899 }; 1900 1901 static enum drm_mode_status ast_mode_config_mode_valid(struct drm_device *dev, 1902 const struct drm_display_mode *mode) 1903 { 1904 static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */ 1905 struct ast_device *ast = to_ast_device(dev); 1906 unsigned long fbsize, fbpages, max_fbpages; 1907 1908 max_fbpages = (ast->vram_fb_available) >> PAGE_SHIFT; 1909 1910 fbsize = mode->hdisplay * mode->vdisplay * max_bpp; 1911 fbpages = DIV_ROUND_UP(fbsize, PAGE_SIZE); 1912 1913 if (fbpages > max_fbpages) 1914 return MODE_MEM; 1915 1916 return MODE_OK; 1917 } 1918 1919 static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1920 .fb_create = drm_gem_fb_create_with_dirty, 1921 .mode_valid = ast_mode_config_mode_valid, 1922 .atomic_check = drm_atomic_helper_check, 1923 .atomic_commit = drm_atomic_helper_commit, 1924 }; 1925 1926 int ast_mode_config_init(struct ast_device *ast) 1927 { 1928 struct drm_device *dev = &ast->base; 1929 struct drm_connector *physical_connector = NULL; 1930 int ret; 1931 1932 ret = drmm_mutex_init(dev, &ast->modeset_lock); 1933 if (ret) 1934 return ret; 1935 1936 ret = drmm_mode_config_init(dev); 1937 if (ret) 1938 return ret; 1939 1940 dev->mode_config.funcs = &ast_mode_config_funcs; 1941 dev->mode_config.min_width = 0; 1942 dev->mode_config.min_height = 0; 1943 dev->mode_config.preferred_depth = 24; 1944 1945 if (ast->chip == AST2100 || // GEN2, but not AST1100 (?) 1946 ast->chip == AST2200 || // GEN3, but not AST2150 (?) 1947 IS_AST_GEN7(ast) || 1948 IS_AST_GEN6(ast) || 1949 IS_AST_GEN5(ast) || 1950 IS_AST_GEN4(ast)) { 1951 dev->mode_config.max_width = 1920; 1952 dev->mode_config.max_height = 2048; 1953 } else { 1954 dev->mode_config.max_width = 1600; 1955 dev->mode_config.max_height = 1200; 1956 } 1957 1958 dev->mode_config.helper_private = &ast_mode_config_helper_funcs; 1959 1960 ret = ast_primary_plane_init(ast); 1961 if (ret) 1962 return ret; 1963 1964 ret = ast_cursor_plane_init(ast); 1965 if (ret) 1966 return ret; 1967 1968 ast_crtc_init(dev); 1969 1970 if (ast->tx_chip_types & AST_TX_NONE_BIT) { 1971 ret = ast_vga_output_init(ast); 1972 if (ret) 1973 return ret; 1974 physical_connector = &ast->output.vga.connector; 1975 } 1976 if (ast->tx_chip_types & AST_TX_SIL164_BIT) { 1977 ret = ast_sil164_output_init(ast); 1978 if (ret) 1979 return ret; 1980 physical_connector = &ast->output.sil164.connector; 1981 } 1982 if (ast->tx_chip_types & AST_TX_DP501_BIT) { 1983 ret = ast_dp501_output_init(ast); 1984 if (ret) 1985 return ret; 1986 physical_connector = &ast->output.dp501.connector; 1987 } 1988 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { 1989 ret = ast_astdp_output_init(ast); 1990 if (ret) 1991 return ret; 1992 physical_connector = &ast->output.astdp.connector; 1993 } 1994 ret = ast_bmc_output_init(ast, physical_connector); 1995 if (ret) 1996 return ret; 1997 1998 drm_mode_config_reset(dev); 1999 2000 ret = drmm_kms_helper_poll_init(dev); 2001 if (ret) 2002 return ret; 2003 2004 return 0; 2005 } 2006