1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2023 Loongson Technology Corporation Limited 4 */ 5 6 #include <linux/debugfs.h> 7 #include <linux/delay.h> 8 9 #include <drm/drm_atomic.h> 10 #include <drm/drm_atomic_helper.h> 11 #include <drm/drm_debugfs.h> 12 #include <drm/drm_print.h> 13 #include <drm/drm_vblank.h> 14 15 #include "lsdc_drv.h" 16 17 /* 18 * After the CRTC soft reset, the vblank counter would be reset to zero. 19 * But the address and other settings in the CRTC register remain the same 20 * as before. 21 */ 22 23 static void lsdc_crtc0_soft_reset(struct lsdc_crtc *lcrtc) 24 { 25 struct lsdc_device *ldev = lcrtc->ldev; 26 u32 val; 27 28 val = lsdc_rreg32(ldev, LSDC_CRTC0_CFG_REG); 29 30 val &= CFG_VALID_BITS_MASK; 31 32 /* Soft reset bit, active low */ 33 val &= ~CFG_RESET_N; 34 35 val &= ~CFG_PIX_FMT_MASK; 36 37 lsdc_wreg32(ldev, LSDC_CRTC0_CFG_REG, val); 38 39 udelay(1); 40 41 val |= CFG_RESET_N | LSDC_PF_XRGB8888 | CFG_OUTPUT_ENABLE; 42 43 lsdc_wreg32(ldev, LSDC_CRTC0_CFG_REG, val); 44 45 /* Wait about a vblank time */ 46 mdelay(20); 47 } 48 49 static void lsdc_crtc1_soft_reset(struct lsdc_crtc *lcrtc) 50 { 51 struct lsdc_device *ldev = lcrtc->ldev; 52 u32 val; 53 54 val = lsdc_rreg32(ldev, LSDC_CRTC1_CFG_REG); 55 56 val &= CFG_VALID_BITS_MASK; 57 58 /* Soft reset bit, active low */ 59 val &= ~CFG_RESET_N; 60 61 val &= ~CFG_PIX_FMT_MASK; 62 63 lsdc_wreg32(ldev, LSDC_CRTC1_CFG_REG, val); 64 65 udelay(1); 66 67 val |= CFG_RESET_N | LSDC_PF_XRGB8888 | CFG_OUTPUT_ENABLE; 68 69 lsdc_wreg32(ldev, LSDC_CRTC1_CFG_REG, val); 70 71 /* Wait about a vblank time */ 72 msleep(20); 73 } 74 75 static void lsdc_crtc0_enable(struct lsdc_crtc *lcrtc) 76 { 77 struct lsdc_device *ldev = lcrtc->ldev; 78 u32 val; 79 80 val = lsdc_rreg32(ldev, LSDC_CRTC0_CFG_REG); 81 82 /* 83 * This may happen in extremely rare cases, but a soft reset can 84 * bring it back to normal. We add a warning here, hoping to catch 85 * something if it happens. 86 */ 87 if (val & CRTC_ANCHORED) { 88 drm_warn(&ldev->base, "%s stall\n", lcrtc->base.name); 89 return lsdc_crtc0_soft_reset(lcrtc); 90 } 91 92 lsdc_wreg32(ldev, LSDC_CRTC0_CFG_REG, val | CFG_OUTPUT_ENABLE); 93 } 94 95 static void lsdc_crtc0_disable(struct lsdc_crtc *lcrtc) 96 { 97 struct lsdc_device *ldev = lcrtc->ldev; 98 99 lsdc_ureg32_clr(ldev, LSDC_CRTC0_CFG_REG, CFG_OUTPUT_ENABLE); 100 101 udelay(9); 102 } 103 104 static void lsdc_crtc1_enable(struct lsdc_crtc *lcrtc) 105 { 106 struct lsdc_device *ldev = lcrtc->ldev; 107 u32 val; 108 109 /* 110 * This may happen in extremely rare cases, but a soft reset can 111 * bring it back to normal. We add a warning here, hoping to catch 112 * something if it happens. 113 */ 114 val = lsdc_rreg32(ldev, LSDC_CRTC1_CFG_REG); 115 if (val & CRTC_ANCHORED) { 116 drm_warn(&ldev->base, "%s stall\n", lcrtc->base.name); 117 return lsdc_crtc1_soft_reset(lcrtc); 118 } 119 120 lsdc_wreg32(ldev, LSDC_CRTC1_CFG_REG, val | CFG_OUTPUT_ENABLE); 121 } 122 123 static void lsdc_crtc1_disable(struct lsdc_crtc *lcrtc) 124 { 125 struct lsdc_device *ldev = lcrtc->ldev; 126 127 lsdc_ureg32_clr(ldev, LSDC_CRTC1_CFG_REG, CFG_OUTPUT_ENABLE); 128 129 udelay(9); 130 } 131 132 /* All Loongson display controllers have hardware scanout position recoders */ 133 134 static void lsdc_crtc0_scan_pos(struct lsdc_crtc *lcrtc, int *hpos, int *vpos) 135 { 136 struct lsdc_device *ldev = lcrtc->ldev; 137 u32 val; 138 139 val = lsdc_rreg32(ldev, LSDC_CRTC0_SCAN_POS_REG); 140 141 *hpos = val >> 16; 142 *vpos = val & 0xffff; 143 } 144 145 static void lsdc_crtc1_scan_pos(struct lsdc_crtc *lcrtc, int *hpos, int *vpos) 146 { 147 struct lsdc_device *ldev = lcrtc->ldev; 148 u32 val; 149 150 val = lsdc_rreg32(ldev, LSDC_CRTC1_SCAN_POS_REG); 151 152 *hpos = val >> 16; 153 *vpos = val & 0xffff; 154 } 155 156 static void lsdc_crtc0_enable_vblank(struct lsdc_crtc *lcrtc) 157 { 158 struct lsdc_device *ldev = lcrtc->ldev; 159 160 lsdc_ureg32_set(ldev, LSDC_INT_REG, INT_CRTC0_VSYNC_EN); 161 } 162 163 static void lsdc_crtc0_disable_vblank(struct lsdc_crtc *lcrtc) 164 { 165 struct lsdc_device *ldev = lcrtc->ldev; 166 167 lsdc_ureg32_clr(ldev, LSDC_INT_REG, INT_CRTC0_VSYNC_EN); 168 } 169 170 static void lsdc_crtc1_enable_vblank(struct lsdc_crtc *lcrtc) 171 { 172 struct lsdc_device *ldev = lcrtc->ldev; 173 174 lsdc_ureg32_set(ldev, LSDC_INT_REG, INT_CRTC1_VSYNC_EN); 175 } 176 177 static void lsdc_crtc1_disable_vblank(struct lsdc_crtc *lcrtc) 178 { 179 struct lsdc_device *ldev = lcrtc->ldev; 180 181 lsdc_ureg32_clr(ldev, LSDC_INT_REG, INT_CRTC1_VSYNC_EN); 182 } 183 184 static void lsdc_crtc0_flip(struct lsdc_crtc *lcrtc) 185 { 186 struct lsdc_device *ldev = lcrtc->ldev; 187 188 lsdc_ureg32_set(ldev, LSDC_CRTC0_CFG_REG, CFG_PAGE_FLIP); 189 } 190 191 static void lsdc_crtc1_flip(struct lsdc_crtc *lcrtc) 192 { 193 struct lsdc_device *ldev = lcrtc->ldev; 194 195 lsdc_ureg32_set(ldev, LSDC_CRTC1_CFG_REG, CFG_PAGE_FLIP); 196 } 197 198 /* 199 * CRTC0 clone from CRTC1 or CRTC1 clone from CRTC0 using hardware logic 200 * This may be useful for custom cloning (TWIN) applications. Saving the 201 * bandwidth compared with the clone (mirroring) display mode provided by 202 * drm core. 203 */ 204 205 static void lsdc_crtc0_clone(struct lsdc_crtc *lcrtc) 206 { 207 struct lsdc_device *ldev = lcrtc->ldev; 208 209 lsdc_ureg32_set(ldev, LSDC_CRTC0_CFG_REG, CFG_HW_CLONE); 210 } 211 212 static void lsdc_crtc1_clone(struct lsdc_crtc *lcrtc) 213 { 214 struct lsdc_device *ldev = lcrtc->ldev; 215 216 lsdc_ureg32_set(ldev, LSDC_CRTC1_CFG_REG, CFG_HW_CLONE); 217 } 218 219 static void lsdc_crtc0_set_mode(struct lsdc_crtc *lcrtc, 220 const struct drm_display_mode *mode) 221 { 222 struct lsdc_device *ldev = lcrtc->ldev; 223 224 lsdc_wreg32(ldev, LSDC_CRTC0_HDISPLAY_REG, 225 (mode->crtc_htotal << 16) | mode->crtc_hdisplay); 226 227 lsdc_wreg32(ldev, LSDC_CRTC0_VDISPLAY_REG, 228 (mode->crtc_vtotal << 16) | mode->crtc_vdisplay); 229 230 lsdc_wreg32(ldev, LSDC_CRTC0_HSYNC_REG, 231 (mode->crtc_hsync_end << 16) | mode->crtc_hsync_start | HSYNC_EN); 232 233 lsdc_wreg32(ldev, LSDC_CRTC0_VSYNC_REG, 234 (mode->crtc_vsync_end << 16) | mode->crtc_vsync_start | VSYNC_EN); 235 } 236 237 static void lsdc_crtc1_set_mode(struct lsdc_crtc *lcrtc, 238 const struct drm_display_mode *mode) 239 { 240 struct lsdc_device *ldev = lcrtc->ldev; 241 242 lsdc_wreg32(ldev, LSDC_CRTC1_HDISPLAY_REG, 243 (mode->crtc_htotal << 16) | mode->crtc_hdisplay); 244 245 lsdc_wreg32(ldev, LSDC_CRTC1_VDISPLAY_REG, 246 (mode->crtc_vtotal << 16) | mode->crtc_vdisplay); 247 248 lsdc_wreg32(ldev, LSDC_CRTC1_HSYNC_REG, 249 (mode->crtc_hsync_end << 16) | mode->crtc_hsync_start | HSYNC_EN); 250 251 lsdc_wreg32(ldev, LSDC_CRTC1_VSYNC_REG, 252 (mode->crtc_vsync_end << 16) | mode->crtc_vsync_start | VSYNC_EN); 253 } 254 255 /* 256 * This is required for S3 support. 257 * After resuming from suspend, LSDC_CRTCx_CFG_REG (x = 0 or 1) is filled 258 * with garbage value, which causes the CRTC hang there. 259 * 260 * This function provides minimal settings for the affected registers. 261 * This overrides the firmware's settings on startup, making the CRTC work 262 * on our own, similar to the functional of GPU POST (Power On Self Test). 263 * Only touch CRTC hardware-related parts. 264 */ 265 266 static void lsdc_crtc0_reset(struct lsdc_crtc *lcrtc) 267 { 268 struct lsdc_device *ldev = lcrtc->ldev; 269 270 lsdc_wreg32(ldev, LSDC_CRTC0_CFG_REG, CFG_RESET_N | LSDC_PF_XRGB8888); 271 } 272 273 static void lsdc_crtc1_reset(struct lsdc_crtc *lcrtc) 274 { 275 struct lsdc_device *ldev = lcrtc->ldev; 276 277 lsdc_wreg32(ldev, LSDC_CRTC1_CFG_REG, CFG_RESET_N | LSDC_PF_XRGB8888); 278 } 279 280 static const struct lsdc_crtc_hw_ops ls7a1000_crtc_hw_ops[2] = { 281 { 282 .enable = lsdc_crtc0_enable, 283 .disable = lsdc_crtc0_disable, 284 .enable_vblank = lsdc_crtc0_enable_vblank, 285 .disable_vblank = lsdc_crtc0_disable_vblank, 286 .flip = lsdc_crtc0_flip, 287 .clone = lsdc_crtc0_clone, 288 .set_mode = lsdc_crtc0_set_mode, 289 .get_scan_pos = lsdc_crtc0_scan_pos, 290 .soft_reset = lsdc_crtc0_soft_reset, 291 .reset = lsdc_crtc0_reset, 292 }, 293 { 294 .enable = lsdc_crtc1_enable, 295 .disable = lsdc_crtc1_disable, 296 .enable_vblank = lsdc_crtc1_enable_vblank, 297 .disable_vblank = lsdc_crtc1_disable_vblank, 298 .flip = lsdc_crtc1_flip, 299 .clone = lsdc_crtc1_clone, 300 .set_mode = lsdc_crtc1_set_mode, 301 .get_scan_pos = lsdc_crtc1_scan_pos, 302 .soft_reset = lsdc_crtc1_soft_reset, 303 .reset = lsdc_crtc1_reset, 304 }, 305 }; 306 307 /* 308 * The 32-bit hardware vblank counter has been available since LS7A2000 309 * and LS2K2000. The counter increases even though the CRTC is disabled, 310 * it will be reset only if the CRTC is being soft reset. 311 * Those registers are also readable for ls7a1000, but its value does not 312 * change. 313 */ 314 315 static u32 lsdc_crtc0_get_vblank_count(struct lsdc_crtc *lcrtc) 316 { 317 struct lsdc_device *ldev = lcrtc->ldev; 318 319 return lsdc_rreg32(ldev, LSDC_CRTC0_VSYNC_COUNTER_REG); 320 } 321 322 static u32 lsdc_crtc1_get_vblank_count(struct lsdc_crtc *lcrtc) 323 { 324 struct lsdc_device *ldev = lcrtc->ldev; 325 326 return lsdc_rreg32(ldev, LSDC_CRTC1_VSYNC_COUNTER_REG); 327 } 328 329 /* 330 * The DMA step bit fields are available since LS7A2000/LS2K2000, for 331 * supporting odd resolutions. But a large DMA step save the bandwidth. 332 * The larger, the better. Behavior of writing those bits on LS7A1000 333 * or LS2K1000 is underfined. 334 */ 335 336 static void lsdc_crtc0_set_dma_step(struct lsdc_crtc *lcrtc, 337 enum lsdc_dma_steps dma_step) 338 { 339 struct lsdc_device *ldev = lcrtc->ldev; 340 u32 val = lsdc_rreg32(ldev, LSDC_CRTC0_CFG_REG); 341 342 val &= ~CFG_DMA_STEP_MASK; 343 val |= dma_step << CFG_DMA_STEP_SHIFT; 344 345 lsdc_wreg32(ldev, LSDC_CRTC0_CFG_REG, val); 346 } 347 348 static void lsdc_crtc1_set_dma_step(struct lsdc_crtc *lcrtc, 349 enum lsdc_dma_steps dma_step) 350 { 351 struct lsdc_device *ldev = lcrtc->ldev; 352 u32 val = lsdc_rreg32(ldev, LSDC_CRTC1_CFG_REG); 353 354 val &= ~CFG_DMA_STEP_MASK; 355 val |= dma_step << CFG_DMA_STEP_SHIFT; 356 357 lsdc_wreg32(ldev, LSDC_CRTC1_CFG_REG, val); 358 } 359 360 static const struct lsdc_crtc_hw_ops ls7a2000_crtc_hw_ops[2] = { 361 { 362 .enable = lsdc_crtc0_enable, 363 .disable = lsdc_crtc0_disable, 364 .enable_vblank = lsdc_crtc0_enable_vblank, 365 .disable_vblank = lsdc_crtc0_disable_vblank, 366 .flip = lsdc_crtc0_flip, 367 .clone = lsdc_crtc0_clone, 368 .set_mode = lsdc_crtc0_set_mode, 369 .soft_reset = lsdc_crtc0_soft_reset, 370 .get_scan_pos = lsdc_crtc0_scan_pos, 371 .set_dma_step = lsdc_crtc0_set_dma_step, 372 .get_vblank_counter = lsdc_crtc0_get_vblank_count, 373 .reset = lsdc_crtc0_reset, 374 }, 375 { 376 .enable = lsdc_crtc1_enable, 377 .disable = lsdc_crtc1_disable, 378 .enable_vblank = lsdc_crtc1_enable_vblank, 379 .disable_vblank = lsdc_crtc1_disable_vblank, 380 .flip = lsdc_crtc1_flip, 381 .clone = lsdc_crtc1_clone, 382 .set_mode = lsdc_crtc1_set_mode, 383 .get_scan_pos = lsdc_crtc1_scan_pos, 384 .soft_reset = lsdc_crtc1_soft_reset, 385 .set_dma_step = lsdc_crtc1_set_dma_step, 386 .get_vblank_counter = lsdc_crtc1_get_vblank_count, 387 .reset = lsdc_crtc1_reset, 388 }, 389 }; 390 391 static void lsdc_crtc_reset(struct drm_crtc *crtc) 392 { 393 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 394 const struct lsdc_crtc_hw_ops *ops = lcrtc->hw_ops; 395 struct lsdc_crtc_state *priv_crtc_state; 396 397 if (crtc->state) 398 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 399 400 priv_crtc_state = kzalloc(sizeof(*priv_crtc_state), GFP_KERNEL); 401 402 if (!priv_crtc_state) 403 __drm_atomic_helper_crtc_reset(crtc, NULL); 404 else 405 __drm_atomic_helper_crtc_reset(crtc, &priv_crtc_state->base); 406 407 /* Reset the CRTC hardware, this is required for S3 support */ 408 ops->reset(lcrtc); 409 } 410 411 static void lsdc_crtc_atomic_destroy_state(struct drm_crtc *crtc, 412 struct drm_crtc_state *state) 413 { 414 struct lsdc_crtc_state *priv_state = to_lsdc_crtc_state(state); 415 416 __drm_atomic_helper_crtc_destroy_state(&priv_state->base); 417 418 kfree(priv_state); 419 } 420 421 static struct drm_crtc_state * 422 lsdc_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 423 { 424 struct lsdc_crtc_state *new_priv_state; 425 struct lsdc_crtc_state *old_priv_state; 426 427 new_priv_state = kzalloc(sizeof(*new_priv_state), GFP_KERNEL); 428 if (!new_priv_state) 429 return NULL; 430 431 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_priv_state->base); 432 433 old_priv_state = to_lsdc_crtc_state(crtc->state); 434 435 memcpy(&new_priv_state->pparms, &old_priv_state->pparms, 436 sizeof(new_priv_state->pparms)); 437 438 return &new_priv_state->base; 439 } 440 441 static u32 lsdc_crtc_get_vblank_counter(struct drm_crtc *crtc) 442 { 443 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 444 445 /* 32-bit hardware vblank counter */ 446 return lcrtc->hw_ops->get_vblank_counter(lcrtc); 447 } 448 449 static int lsdc_crtc_enable_vblank(struct drm_crtc *crtc) 450 { 451 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 452 453 if (!lcrtc->has_vblank) 454 return -EINVAL; 455 456 lcrtc->hw_ops->enable_vblank(lcrtc); 457 458 return 0; 459 } 460 461 static void lsdc_crtc_disable_vblank(struct drm_crtc *crtc) 462 { 463 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 464 465 if (!lcrtc->has_vblank) 466 return; 467 468 lcrtc->hw_ops->disable_vblank(lcrtc); 469 } 470 471 /* 472 * CRTC related debugfs 473 * Primary planes and cursor planes belong to the CRTC as well. 474 * For the sake of convenience, plane-related registers are also add here. 475 */ 476 477 #define REG_DEF(reg) { \ 478 .name = __stringify_1(LSDC_##reg##_REG), \ 479 .offset = LSDC_##reg##_REG, \ 480 } 481 482 static const struct lsdc_reg32 lsdc_crtc_regs_array[2][21] = { 483 [0] = { 484 REG_DEF(CRTC0_CFG), 485 REG_DEF(CRTC0_FB_ORIGIN), 486 REG_DEF(CRTC0_DVO_CONF), 487 REG_DEF(CRTC0_HDISPLAY), 488 REG_DEF(CRTC0_HSYNC), 489 REG_DEF(CRTC0_VDISPLAY), 490 REG_DEF(CRTC0_VSYNC), 491 REG_DEF(CRTC0_GAMMA_INDEX), 492 REG_DEF(CRTC0_GAMMA_DATA), 493 REG_DEF(CRTC0_SYNC_DEVIATION), 494 REG_DEF(CRTC0_VSYNC_COUNTER), 495 REG_DEF(CRTC0_SCAN_POS), 496 REG_DEF(CRTC0_STRIDE), 497 REG_DEF(CRTC0_FB1_ADDR_HI), 498 REG_DEF(CRTC0_FB1_ADDR_LO), 499 REG_DEF(CRTC0_FB0_ADDR_HI), 500 REG_DEF(CRTC0_FB0_ADDR_LO), 501 REG_DEF(CURSOR0_CFG), 502 REG_DEF(CURSOR0_POSITION), 503 REG_DEF(CURSOR0_BG_COLOR), 504 REG_DEF(CURSOR0_FG_COLOR), 505 }, 506 [1] = { 507 REG_DEF(CRTC1_CFG), 508 REG_DEF(CRTC1_FB_ORIGIN), 509 REG_DEF(CRTC1_DVO_CONF), 510 REG_DEF(CRTC1_HDISPLAY), 511 REG_DEF(CRTC1_HSYNC), 512 REG_DEF(CRTC1_VDISPLAY), 513 REG_DEF(CRTC1_VSYNC), 514 REG_DEF(CRTC1_GAMMA_INDEX), 515 REG_DEF(CRTC1_GAMMA_DATA), 516 REG_DEF(CRTC1_SYNC_DEVIATION), 517 REG_DEF(CRTC1_VSYNC_COUNTER), 518 REG_DEF(CRTC1_SCAN_POS), 519 REG_DEF(CRTC1_STRIDE), 520 REG_DEF(CRTC1_FB1_ADDR_HI), 521 REG_DEF(CRTC1_FB1_ADDR_LO), 522 REG_DEF(CRTC1_FB0_ADDR_HI), 523 REG_DEF(CRTC1_FB0_ADDR_LO), 524 REG_DEF(CURSOR1_CFG), 525 REG_DEF(CURSOR1_POSITION), 526 REG_DEF(CURSOR1_BG_COLOR), 527 REG_DEF(CURSOR1_FG_COLOR), 528 }, 529 }; 530 531 static int lsdc_crtc_show_regs(struct seq_file *m, void *arg) 532 { 533 struct drm_info_node *node = (struct drm_info_node *)m->private; 534 struct lsdc_crtc *lcrtc = (struct lsdc_crtc *)node->info_ent->data; 535 struct lsdc_device *ldev = lcrtc->ldev; 536 unsigned int i; 537 538 for (i = 0; i < lcrtc->nreg; i++) { 539 const struct lsdc_reg32 *preg = &lcrtc->preg[i]; 540 u32 offset = preg->offset; 541 542 seq_printf(m, "%s (0x%04x): 0x%08x\n", 543 preg->name, offset, lsdc_rreg32(ldev, offset)); 544 } 545 546 return 0; 547 } 548 549 static int lsdc_crtc_show_scan_position(struct seq_file *m, void *arg) 550 { 551 struct drm_info_node *node = (struct drm_info_node *)m->private; 552 struct lsdc_crtc *lcrtc = (struct lsdc_crtc *)node->info_ent->data; 553 int x, y; 554 555 lcrtc->hw_ops->get_scan_pos(lcrtc, &x, &y); 556 seq_printf(m, "Scanout position: x: %08u, y: %08u\n", x, y); 557 558 return 0; 559 } 560 561 static int lsdc_crtc_show_vblank_counter(struct seq_file *m, void *arg) 562 { 563 struct drm_info_node *node = (struct drm_info_node *)m->private; 564 struct lsdc_crtc *lcrtc = (struct lsdc_crtc *)node->info_ent->data; 565 566 if (lcrtc->hw_ops->get_vblank_counter) 567 seq_printf(m, "%s vblank counter: %08u\n\n", lcrtc->base.name, 568 lcrtc->hw_ops->get_vblank_counter(lcrtc)); 569 570 return 0; 571 } 572 573 static int lsdc_pixpll_show_clock(struct seq_file *m, void *arg) 574 { 575 struct drm_info_node *node = (struct drm_info_node *)m->private; 576 struct lsdc_crtc *lcrtc = (struct lsdc_crtc *)node->info_ent->data; 577 struct lsdc_pixpll *pixpll = &lcrtc->pixpll; 578 const struct lsdc_pixpll_funcs *funcs = pixpll->funcs; 579 struct drm_crtc *crtc = &lcrtc->base; 580 struct drm_display_mode *mode = &crtc->state->mode; 581 struct drm_printer printer = drm_seq_file_printer(m); 582 unsigned int out_khz; 583 584 out_khz = funcs->get_rate(pixpll); 585 586 seq_printf(m, "%s: %dx%d@%d\n", crtc->name, 587 mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode)); 588 589 seq_printf(m, "Pixel clock required: %d kHz\n", mode->clock); 590 seq_printf(m, "Actual frequency output: %u kHz\n", out_khz); 591 seq_printf(m, "Diff: %d kHz\n", out_khz - mode->clock); 592 593 funcs->print(pixpll, &printer); 594 595 return 0; 596 } 597 598 static struct drm_info_list lsdc_crtc_debugfs_list[2][4] = { 599 [0] = { 600 { "regs", lsdc_crtc_show_regs, 0, NULL }, 601 { "pixclk", lsdc_pixpll_show_clock, 0, NULL }, 602 { "scanpos", lsdc_crtc_show_scan_position, 0, NULL }, 603 { "vblanks", lsdc_crtc_show_vblank_counter, 0, NULL }, 604 }, 605 [1] = { 606 { "regs", lsdc_crtc_show_regs, 0, NULL }, 607 { "pixclk", lsdc_pixpll_show_clock, 0, NULL }, 608 { "scanpos", lsdc_crtc_show_scan_position, 0, NULL }, 609 { "vblanks", lsdc_crtc_show_vblank_counter, 0, NULL }, 610 }, 611 }; 612 613 /* operate manually */ 614 615 static int lsdc_crtc_man_op_show(struct seq_file *m, void *data) 616 { 617 seq_puts(m, "soft_reset: soft reset this CRTC\n"); 618 seq_puts(m, "enable: enable this CRTC\n"); 619 seq_puts(m, "disable: disable this CRTC\n"); 620 seq_puts(m, "flip: trigger the page flip\n"); 621 seq_puts(m, "clone: clone the another crtc with hardware logic\n"); 622 623 return 0; 624 } 625 626 static int lsdc_crtc_man_op_open(struct inode *inode, struct file *file) 627 { 628 struct drm_crtc *crtc = inode->i_private; 629 630 return single_open(file, lsdc_crtc_man_op_show, crtc); 631 } 632 633 static ssize_t lsdc_crtc_man_op_write(struct file *file, 634 const char __user *ubuf, 635 size_t len, 636 loff_t *offp) 637 { 638 struct seq_file *m = file->private_data; 639 struct lsdc_crtc *lcrtc = m->private; 640 const struct lsdc_crtc_hw_ops *ops = lcrtc->hw_ops; 641 char buf[16]; 642 643 if (len > sizeof(buf) - 1) 644 return -EINVAL; 645 646 if (copy_from_user(buf, ubuf, len)) 647 return -EFAULT; 648 649 buf[len] = '\0'; 650 651 if (sysfs_streq(buf, "soft_reset")) 652 ops->soft_reset(lcrtc); 653 else if (sysfs_streq(buf, "enable")) 654 ops->enable(lcrtc); 655 else if (sysfs_streq(buf, "disable")) 656 ops->disable(lcrtc); 657 else if (sysfs_streq(buf, "flip")) 658 ops->flip(lcrtc); 659 else if (sysfs_streq(buf, "clone")) 660 ops->clone(lcrtc); 661 662 return len; 663 } 664 665 static const struct file_operations lsdc_crtc_man_op_fops = { 666 .owner = THIS_MODULE, 667 .open = lsdc_crtc_man_op_open, 668 .read = seq_read, 669 .llseek = seq_lseek, 670 .release = single_release, 671 .write = lsdc_crtc_man_op_write, 672 }; 673 674 static int lsdc_crtc_late_register(struct drm_crtc *crtc) 675 { 676 struct lsdc_display_pipe *dispipe = crtc_to_display_pipe(crtc); 677 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 678 struct drm_minor *minor = crtc->dev->primary; 679 unsigned int index = dispipe->index; 680 unsigned int i; 681 682 lcrtc->preg = lsdc_crtc_regs_array[index]; 683 lcrtc->nreg = ARRAY_SIZE(lsdc_crtc_regs_array[index]); 684 lcrtc->p_info_list = lsdc_crtc_debugfs_list[index]; 685 lcrtc->n_info_list = ARRAY_SIZE(lsdc_crtc_debugfs_list[index]); 686 687 for (i = 0; i < lcrtc->n_info_list; ++i) 688 lcrtc->p_info_list[i].data = lcrtc; 689 690 drm_debugfs_create_files(lcrtc->p_info_list, lcrtc->n_info_list, 691 crtc->debugfs_entry, minor); 692 693 /* Manual operations supported */ 694 debugfs_create_file("ops", 0644, crtc->debugfs_entry, lcrtc, 695 &lsdc_crtc_man_op_fops); 696 697 return 0; 698 } 699 700 static void lsdc_crtc_atomic_print_state(struct drm_printer *p, 701 const struct drm_crtc_state *state) 702 { 703 const struct lsdc_crtc_state *priv_state; 704 const struct lsdc_pixpll_parms *pparms; 705 706 priv_state = container_of_const(state, struct lsdc_crtc_state, base); 707 pparms = &priv_state->pparms; 708 709 drm_printf(p, "\tInput clock divider = %u\n", pparms->div_ref); 710 drm_printf(p, "\tMedium clock multiplier = %u\n", pparms->loopc); 711 drm_printf(p, "\tOutput clock divider = %u\n", pparms->div_out); 712 } 713 714 static const struct drm_crtc_funcs ls7a1000_crtc_funcs = { 715 .reset = lsdc_crtc_reset, 716 .destroy = drm_crtc_cleanup, 717 .set_config = drm_atomic_helper_set_config, 718 .page_flip = drm_atomic_helper_page_flip, 719 .atomic_duplicate_state = lsdc_crtc_atomic_duplicate_state, 720 .atomic_destroy_state = lsdc_crtc_atomic_destroy_state, 721 .late_register = lsdc_crtc_late_register, 722 .enable_vblank = lsdc_crtc_enable_vblank, 723 .disable_vblank = lsdc_crtc_disable_vblank, 724 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, 725 .atomic_print_state = lsdc_crtc_atomic_print_state, 726 }; 727 728 static const struct drm_crtc_funcs ls7a2000_crtc_funcs = { 729 .reset = lsdc_crtc_reset, 730 .destroy = drm_crtc_cleanup, 731 .set_config = drm_atomic_helper_set_config, 732 .page_flip = drm_atomic_helper_page_flip, 733 .atomic_duplicate_state = lsdc_crtc_atomic_duplicate_state, 734 .atomic_destroy_state = lsdc_crtc_atomic_destroy_state, 735 .late_register = lsdc_crtc_late_register, 736 .get_vblank_counter = lsdc_crtc_get_vblank_counter, 737 .enable_vblank = lsdc_crtc_enable_vblank, 738 .disable_vblank = lsdc_crtc_disable_vblank, 739 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, 740 .atomic_print_state = lsdc_crtc_atomic_print_state, 741 }; 742 743 static enum drm_mode_status 744 lsdc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 745 { 746 struct drm_device *ddev = crtc->dev; 747 struct lsdc_device *ldev = to_lsdc(ddev); 748 const struct lsdc_desc *descp = ldev->descp; 749 unsigned int pitch; 750 751 if (mode->hdisplay > descp->max_width) 752 return MODE_BAD_HVALUE; 753 754 if (mode->vdisplay > descp->max_height) 755 return MODE_BAD_VVALUE; 756 757 if (mode->clock > descp->max_pixel_clk) { 758 drm_dbg_kms(ddev, "mode %dx%d, pixel clock=%d is too high\n", 759 mode->hdisplay, mode->vdisplay, mode->clock); 760 return MODE_CLOCK_HIGH; 761 } 762 763 /* 4 for DRM_FORMAT_XRGB8888 */ 764 pitch = mode->hdisplay * 4; 765 766 if (pitch % descp->pitch_align) { 767 drm_dbg_kms(ddev, "align to %u bytes is required: %u\n", 768 descp->pitch_align, pitch); 769 return MODE_BAD_WIDTH; 770 } 771 772 return MODE_OK; 773 } 774 775 static int lsdc_pixpll_atomic_check(struct drm_crtc *crtc, 776 struct drm_crtc_state *state) 777 { 778 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 779 struct lsdc_pixpll *pixpll = &lcrtc->pixpll; 780 const struct lsdc_pixpll_funcs *pfuncs = pixpll->funcs; 781 struct lsdc_crtc_state *priv_state = to_lsdc_crtc_state(state); 782 unsigned int clock = state->mode.clock; 783 int ret; 784 785 ret = pfuncs->compute(pixpll, clock, &priv_state->pparms); 786 if (ret) { 787 drm_warn(crtc->dev, "Failed to find PLL params for %ukHz\n", 788 clock); 789 return -EINVAL; 790 } 791 792 return 0; 793 } 794 795 static int lsdc_crtc_helper_atomic_check(struct drm_crtc *crtc, 796 struct drm_atomic_state *state) 797 { 798 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 799 800 if (!crtc_state->enable) 801 return 0; 802 803 return lsdc_pixpll_atomic_check(crtc, crtc_state); 804 } 805 806 static void lsdc_crtc_mode_set_nofb(struct drm_crtc *crtc) 807 { 808 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 809 const struct lsdc_crtc_hw_ops *crtc_hw_ops = lcrtc->hw_ops; 810 struct lsdc_pixpll *pixpll = &lcrtc->pixpll; 811 const struct lsdc_pixpll_funcs *pixpll_funcs = pixpll->funcs; 812 struct drm_crtc_state *state = crtc->state; 813 struct drm_display_mode *mode = &state->mode; 814 struct lsdc_crtc_state *priv_state = to_lsdc_crtc_state(state); 815 816 pixpll_funcs->update(pixpll, &priv_state->pparms); 817 818 if (crtc_hw_ops->set_dma_step) { 819 unsigned int width_in_bytes = mode->hdisplay * 4; 820 enum lsdc_dma_steps dma_step; 821 822 /* 823 * Using DMA step as large as possible, for improving 824 * hardware DMA efficiency. 825 */ 826 if (width_in_bytes % 256 == 0) 827 dma_step = LSDC_DMA_STEP_256_BYTES; 828 else if (width_in_bytes % 128 == 0) 829 dma_step = LSDC_DMA_STEP_128_BYTES; 830 else if (width_in_bytes % 64 == 0) 831 dma_step = LSDC_DMA_STEP_64_BYTES; 832 else /* width_in_bytes % 32 == 0 */ 833 dma_step = LSDC_DMA_STEP_32_BYTES; 834 835 crtc_hw_ops->set_dma_step(lcrtc, dma_step); 836 } 837 838 crtc_hw_ops->set_mode(lcrtc, mode); 839 } 840 841 static void lsdc_crtc_send_vblank(struct drm_crtc *crtc) 842 { 843 struct drm_device *ddev = crtc->dev; 844 unsigned long flags; 845 846 if (!crtc->state || !crtc->state->event) 847 return; 848 849 drm_dbg(ddev, "Send vblank manually\n"); 850 851 spin_lock_irqsave(&ddev->event_lock, flags); 852 drm_crtc_send_vblank_event(crtc, crtc->state->event); 853 crtc->state->event = NULL; 854 spin_unlock_irqrestore(&ddev->event_lock, flags); 855 } 856 857 static void lsdc_crtc_atomic_enable(struct drm_crtc *crtc, 858 struct drm_atomic_state *state) 859 { 860 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 861 862 if (lcrtc->has_vblank) 863 drm_crtc_vblank_on(crtc); 864 865 lcrtc->hw_ops->enable(lcrtc); 866 } 867 868 static void lsdc_crtc_atomic_disable(struct drm_crtc *crtc, 869 struct drm_atomic_state *state) 870 { 871 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 872 873 if (lcrtc->has_vblank) 874 drm_crtc_vblank_off(crtc); 875 876 lcrtc->hw_ops->disable(lcrtc); 877 878 /* 879 * Make sure we issue a vblank event after disabling the CRTC if 880 * someone was waiting it. 881 */ 882 lsdc_crtc_send_vblank(crtc); 883 } 884 885 static void lsdc_crtc_atomic_flush(struct drm_crtc *crtc, 886 struct drm_atomic_state *state) 887 { 888 spin_lock_irq(&crtc->dev->event_lock); 889 if (crtc->state->event) { 890 if (drm_crtc_vblank_get(crtc) == 0) 891 drm_crtc_arm_vblank_event(crtc, crtc->state->event); 892 else 893 drm_crtc_send_vblank_event(crtc, crtc->state->event); 894 crtc->state->event = NULL; 895 } 896 spin_unlock_irq(&crtc->dev->event_lock); 897 } 898 899 static bool lsdc_crtc_get_scanout_position(struct drm_crtc *crtc, 900 bool in_vblank_irq, 901 int *vpos, 902 int *hpos, 903 ktime_t *stime, 904 ktime_t *etime, 905 const struct drm_display_mode *mode) 906 { 907 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 908 const struct lsdc_crtc_hw_ops *ops = lcrtc->hw_ops; 909 int vsw, vbp, vactive_start, vactive_end, vfp_end; 910 int x, y; 911 912 vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; 913 vbp = mode->crtc_vtotal - mode->crtc_vsync_end; 914 915 vactive_start = vsw + vbp + 1; 916 vactive_end = vactive_start + mode->crtc_vdisplay; 917 918 /* last scan line before VSYNC */ 919 vfp_end = mode->crtc_vtotal; 920 921 if (stime) 922 *stime = ktime_get(); 923 924 ops->get_scan_pos(lcrtc, &x, &y); 925 926 if (y > vactive_end) 927 y = y - vfp_end - vactive_start; 928 else 929 y -= vactive_start; 930 931 *vpos = y; 932 *hpos = 0; 933 934 if (etime) 935 *etime = ktime_get(); 936 937 return true; 938 } 939 940 static const struct drm_crtc_helper_funcs lsdc_crtc_helper_funcs = { 941 .mode_valid = lsdc_crtc_mode_valid, 942 .mode_set_nofb = lsdc_crtc_mode_set_nofb, 943 .atomic_enable = lsdc_crtc_atomic_enable, 944 .atomic_disable = lsdc_crtc_atomic_disable, 945 .atomic_check = lsdc_crtc_helper_atomic_check, 946 .atomic_flush = lsdc_crtc_atomic_flush, 947 .get_scanout_position = lsdc_crtc_get_scanout_position, 948 }; 949 950 int ls7a1000_crtc_init(struct drm_device *ddev, 951 struct drm_crtc *crtc, 952 struct drm_plane *primary, 953 struct drm_plane *cursor, 954 unsigned int index, 955 bool has_vblank) 956 { 957 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 958 int ret; 959 960 ret = lsdc_pixpll_init(&lcrtc->pixpll, ddev, index); 961 if (ret) { 962 drm_err(ddev, "pixel pll init failed: %d\n", ret); 963 return ret; 964 } 965 966 lcrtc->ldev = to_lsdc(ddev); 967 lcrtc->has_vblank = has_vblank; 968 lcrtc->hw_ops = &ls7a1000_crtc_hw_ops[index]; 969 970 ret = drm_crtc_init_with_planes(ddev, crtc, primary, cursor, 971 &ls7a1000_crtc_funcs, 972 "LS-CRTC-%d", index); 973 if (ret) { 974 drm_err(ddev, "crtc init with planes failed: %d\n", ret); 975 return ret; 976 } 977 978 drm_crtc_helper_add(crtc, &lsdc_crtc_helper_funcs); 979 980 ret = drm_mode_crtc_set_gamma_size(crtc, 256); 981 if (ret) 982 return ret; 983 984 drm_crtc_enable_color_mgmt(crtc, 0, false, 256); 985 986 return 0; 987 } 988 989 int ls7a2000_crtc_init(struct drm_device *ddev, 990 struct drm_crtc *crtc, 991 struct drm_plane *primary, 992 struct drm_plane *cursor, 993 unsigned int index, 994 bool has_vblank) 995 { 996 struct lsdc_crtc *lcrtc = to_lsdc_crtc(crtc); 997 int ret; 998 999 ret = lsdc_pixpll_init(&lcrtc->pixpll, ddev, index); 1000 if (ret) { 1001 drm_err(ddev, "crtc init with pll failed: %d\n", ret); 1002 return ret; 1003 } 1004 1005 lcrtc->ldev = to_lsdc(ddev); 1006 lcrtc->has_vblank = has_vblank; 1007 lcrtc->hw_ops = &ls7a2000_crtc_hw_ops[index]; 1008 1009 ret = drm_crtc_init_with_planes(ddev, crtc, primary, cursor, 1010 &ls7a2000_crtc_funcs, 1011 "LS-CRTC-%u", index); 1012 if (ret) { 1013 drm_err(ddev, "crtc init with planes failed: %d\n", ret); 1014 return ret; 1015 } 1016 1017 drm_crtc_helper_add(crtc, &lsdc_crtc_helper_funcs); 1018 1019 ret = drm_mode_crtc_set_gamma_size(crtc, 256); 1020 if (ret) 1021 return ret; 1022 1023 drm_crtc_enable_color_mgmt(crtc, 0, false, 256); 1024 1025 return 0; 1026 } 1027