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