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