1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * RZ/G2L Display Unit CRTCs 4 * 5 * Copyright (C) 2023 Renesas Electronics Corporation 6 * 7 * Based on rcar_du_crtc.c 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/mutex.h> 12 #include <linux/platform_device.h> 13 #include <linux/reset.h> 14 15 #include <drm/drm_atomic.h> 16 #include <drm/drm_atomic_helper.h> 17 #include <drm/drm_bridge.h> 18 #include <drm/drm_crtc.h> 19 #include <drm/drm_device.h> 20 #include <drm/drm_framebuffer.h> 21 #include <drm/drm_gem_dma_helper.h> 22 #include <drm/drm_vblank.h> 23 24 #include "rzg2l_du_crtc.h" 25 #include "rzg2l_du_drv.h" 26 #include "rzg2l_du_encoder.h" 27 #include "rzg2l_du_kms.h" 28 #include "rzg2l_du_vsp.h" 29 30 #define DU_MCR0 0x00 31 #define DU_MCR0_DPI_OE BIT(0) 32 #define DU_MCR0_DI_EN BIT(8) 33 34 #define DU_DITR0 0x10 35 #define DU_DITR0_DEMD_HIGH (BIT(8) | BIT(9)) 36 #define DU_DITR0_VSPOL BIT(16) 37 #define DU_DITR0_HSPOL BIT(17) 38 39 #define DU_DITR1 0x14 40 #define DU_DITR1_VSA(x) ((x) << 0) 41 #define DU_DITR1_VACTIVE(x) ((x) << 16) 42 43 #define DU_DITR2 0x18 44 #define DU_DITR2_VBP(x) ((x) << 0) 45 #define DU_DITR2_VFP(x) ((x) << 16) 46 47 #define DU_DITR3 0x1c 48 #define DU_DITR3_HSA(x) ((x) << 0) 49 #define DU_DITR3_HACTIVE(x) ((x) << 16) 50 51 #define DU_DITR4 0x20 52 #define DU_DITR4_HBP(x) ((x) << 0) 53 #define DU_DITR4_HFP(x) ((x) << 16) 54 55 #define DU_MCR1 0x40 56 #define DU_MCR1_PB_AUTOCLR BIT(16) 57 58 #define DU_PBCR0 0x4c 59 #define DU_PBCR0_PB_DEP(x) ((x) << 0) 60 61 /* ----------------------------------------------------------------------------- 62 * Hardware Setup 63 */ 64 65 static void rzg2l_du_crtc_set_display_timing(struct rzg2l_du_crtc *rcrtc) 66 { 67 const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode; 68 unsigned long mode_clock = mode->clock * 1000; 69 u32 ditr0, ditr1, ditr2, ditr3, ditr4, pbcr0; 70 struct rzg2l_du_device *rcdu = rcrtc->dev; 71 72 clk_prepare_enable(rcrtc->rzg2l_clocks.dclk); 73 clk_set_rate(rcrtc->rzg2l_clocks.dclk, mode_clock); 74 75 ditr0 = (DU_DITR0_DEMD_HIGH 76 | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DU_DITR0_VSPOL : 0) 77 | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DU_DITR0_HSPOL : 0)); 78 79 ditr1 = DU_DITR1_VSA(mode->vsync_end - mode->vsync_start) 80 | DU_DITR1_VACTIVE(mode->vdisplay); 81 82 ditr2 = DU_DITR2_VBP(mode->vtotal - mode->vsync_end) 83 | DU_DITR2_VFP(mode->vsync_start - mode->vdisplay); 84 85 ditr3 = DU_DITR3_HSA(mode->hsync_end - mode->hsync_start) 86 | DU_DITR3_HACTIVE(mode->hdisplay); 87 88 ditr4 = DU_DITR4_HBP(mode->htotal - mode->hsync_end) 89 | DU_DITR4_HFP(mode->hsync_start - mode->hdisplay); 90 91 pbcr0 = DU_PBCR0_PB_DEP(0x1f); 92 93 writel(ditr0, rcdu->mmio + DU_DITR0); 94 writel(ditr1, rcdu->mmio + DU_DITR1); 95 writel(ditr2, rcdu->mmio + DU_DITR2); 96 writel(ditr3, rcdu->mmio + DU_DITR3); 97 writel(ditr4, rcdu->mmio + DU_DITR4); 98 writel(pbcr0, rcdu->mmio + DU_PBCR0); 99 100 /* Enable auto clear */ 101 writel(DU_MCR1_PB_AUTOCLR, rcdu->mmio + DU_MCR1); 102 } 103 104 /* ----------------------------------------------------------------------------- 105 * Page Flip 106 */ 107 108 void rzg2l_du_crtc_finish_page_flip(struct rzg2l_du_crtc *rcrtc) 109 { 110 struct drm_pending_vblank_event *event; 111 struct drm_device *dev = rcrtc->crtc.dev; 112 unsigned long flags; 113 114 spin_lock_irqsave(&dev->event_lock, flags); 115 event = rcrtc->event; 116 rcrtc->event = NULL; 117 spin_unlock_irqrestore(&dev->event_lock, flags); 118 119 if (!event) 120 return; 121 122 spin_lock_irqsave(&dev->event_lock, flags); 123 drm_crtc_send_vblank_event(&rcrtc->crtc, event); 124 wake_up(&rcrtc->flip_wait); 125 spin_unlock_irqrestore(&dev->event_lock, flags); 126 127 drm_crtc_vblank_put(&rcrtc->crtc); 128 } 129 130 static bool rzg2l_du_crtc_page_flip_pending(struct rzg2l_du_crtc *rcrtc) 131 { 132 struct drm_device *dev = rcrtc->crtc.dev; 133 unsigned long flags; 134 bool pending; 135 136 spin_lock_irqsave(&dev->event_lock, flags); 137 pending = rcrtc->event; 138 spin_unlock_irqrestore(&dev->event_lock, flags); 139 140 return pending; 141 } 142 143 static void rzg2l_du_crtc_wait_page_flip(struct rzg2l_du_crtc *rcrtc) 144 { 145 struct rzg2l_du_device *rcdu = rcrtc->dev; 146 147 if (wait_event_timeout(rcrtc->flip_wait, 148 !rzg2l_du_crtc_page_flip_pending(rcrtc), 149 msecs_to_jiffies(50))) 150 return; 151 152 dev_warn(rcdu->dev, "page flip timeout\n"); 153 154 rzg2l_du_crtc_finish_page_flip(rcrtc); 155 } 156 157 /* ----------------------------------------------------------------------------- 158 * Start/Stop and Suspend/Resume 159 */ 160 161 static void rzg2l_du_crtc_setup(struct rzg2l_du_crtc *rcrtc) 162 { 163 /* Configure display timings and output routing */ 164 rzg2l_du_crtc_set_display_timing(rcrtc); 165 166 /* Enable the VSP compositor. */ 167 rzg2l_du_vsp_enable(rcrtc); 168 169 /* Turn vertical blanking interrupt reporting on. */ 170 drm_crtc_vblank_on(&rcrtc->crtc); 171 } 172 173 static int rzg2l_du_crtc_get(struct rzg2l_du_crtc *rcrtc) 174 { 175 int ret; 176 177 /* 178 * Guard against double-get, as the function is called from both the 179 * .atomic_enable() and .atomic_flush() handlers. 180 */ 181 if (rcrtc->initialized) 182 return 0; 183 184 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.aclk); 185 if (ret < 0) 186 return ret; 187 188 ret = clk_prepare_enable(rcrtc->rzg2l_clocks.pclk); 189 if (ret < 0) 190 goto error_bus_clock; 191 192 ret = reset_control_deassert(rcrtc->rstc); 193 if (ret < 0) 194 goto error_peri_clock; 195 196 rzg2l_du_crtc_setup(rcrtc); 197 rcrtc->initialized = true; 198 199 return 0; 200 201 error_peri_clock: 202 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk); 203 error_bus_clock: 204 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk); 205 return ret; 206 } 207 208 static void rzg2l_du_crtc_put(struct rzg2l_du_crtc *rcrtc) 209 { 210 clk_disable_unprepare(rcrtc->rzg2l_clocks.dclk); 211 reset_control_assert(rcrtc->rstc); 212 clk_disable_unprepare(rcrtc->rzg2l_clocks.pclk); 213 clk_disable_unprepare(rcrtc->rzg2l_clocks.aclk); 214 215 rcrtc->initialized = false; 216 } 217 218 static void rzg2l_du_start_stop(struct rzg2l_du_crtc *rcrtc, bool start) 219 { 220 struct rzg2l_du_crtc_state *rstate = to_rzg2l_crtc_state(rcrtc->crtc.state); 221 struct rzg2l_du_device *rcdu = rcrtc->dev; 222 u32 val = DU_MCR0_DI_EN; 223 224 if (rstate->outputs & BIT(RZG2L_DU_OUTPUT_DPAD0)) 225 val |= DU_MCR0_DPI_OE; 226 227 writel(start ? val : 0, rcdu->mmio + DU_MCR0); 228 } 229 230 static void rzg2l_du_crtc_start(struct rzg2l_du_crtc *rcrtc) 231 { 232 rzg2l_du_start_stop(rcrtc, true); 233 } 234 235 static void rzg2l_du_crtc_stop(struct rzg2l_du_crtc *rcrtc) 236 { 237 struct drm_crtc *crtc = &rcrtc->crtc; 238 239 /* 240 * Disable vertical blanking interrupt reporting. We first need to wait 241 * for page flip completion before stopping the CRTC as userspace 242 * expects page flips to eventually complete. 243 */ 244 rzg2l_du_crtc_wait_page_flip(rcrtc); 245 drm_crtc_vblank_off(crtc); 246 247 /* Disable the VSP compositor. */ 248 rzg2l_du_vsp_disable(rcrtc); 249 250 rzg2l_du_start_stop(rcrtc, false); 251 } 252 253 /* ----------------------------------------------------------------------------- 254 * CRTC Functions 255 */ 256 257 static void rzg2l_du_crtc_atomic_enable(struct drm_crtc *crtc, 258 struct drm_atomic_state *state) 259 { 260 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc); 261 262 rzg2l_du_crtc_get(rcrtc); 263 264 rzg2l_du_crtc_start(rcrtc); 265 } 266 267 static void rzg2l_du_crtc_atomic_disable(struct drm_crtc *crtc, 268 struct drm_atomic_state *state) 269 { 270 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc); 271 272 rzg2l_du_crtc_stop(rcrtc); 273 rzg2l_du_crtc_put(rcrtc); 274 275 spin_lock_irq(&crtc->dev->event_lock); 276 if (crtc->state->event) { 277 drm_crtc_send_vblank_event(crtc, crtc->state->event); 278 crtc->state->event = NULL; 279 } 280 spin_unlock_irq(&crtc->dev->event_lock); 281 } 282 283 static void rzg2l_du_crtc_atomic_flush(struct drm_crtc *crtc, 284 struct drm_atomic_state *state) 285 { 286 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc); 287 struct drm_device *dev = rcrtc->crtc.dev; 288 unsigned long flags; 289 290 WARN_ON(!crtc->state->enable); 291 292 if (crtc->state->event) { 293 WARN_ON(drm_crtc_vblank_get(crtc) != 0); 294 295 spin_lock_irqsave(&dev->event_lock, flags); 296 rcrtc->event = crtc->state->event; 297 crtc->state->event = NULL; 298 spin_unlock_irqrestore(&dev->event_lock, flags); 299 } 300 301 rzg2l_du_vsp_atomic_flush(rcrtc); 302 } 303 304 static const struct drm_crtc_helper_funcs crtc_helper_funcs = { 305 .atomic_flush = rzg2l_du_crtc_atomic_flush, 306 .atomic_enable = rzg2l_du_crtc_atomic_enable, 307 .atomic_disable = rzg2l_du_crtc_atomic_disable, 308 }; 309 310 static struct drm_crtc_state * 311 rzg2l_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 312 { 313 struct rzg2l_du_crtc_state *state; 314 struct rzg2l_du_crtc_state *copy; 315 316 if (WARN_ON(!crtc->state)) 317 return NULL; 318 319 state = to_rzg2l_crtc_state(crtc->state); 320 copy = kmemdup(state, sizeof(*state), GFP_KERNEL); 321 if (!copy) 322 return NULL; 323 324 __drm_atomic_helper_crtc_duplicate_state(crtc, ©->state); 325 326 return ©->state; 327 } 328 329 static void rzg2l_du_crtc_atomic_destroy_state(struct drm_crtc *crtc, 330 struct drm_crtc_state *state) 331 { 332 __drm_atomic_helper_crtc_destroy_state(state); 333 kfree(to_rzg2l_crtc_state(state)); 334 } 335 336 static void rzg2l_du_crtc_reset(struct drm_crtc *crtc) 337 { 338 struct rzg2l_du_crtc_state *state; 339 340 if (crtc->state) { 341 rzg2l_du_crtc_atomic_destroy_state(crtc, crtc->state); 342 crtc->state = NULL; 343 } 344 345 state = kzalloc(sizeof(*state), GFP_KERNEL); 346 if (!state) 347 return; 348 349 __drm_atomic_helper_crtc_reset(crtc, &state->state); 350 } 351 352 static int rzg2l_du_crtc_enable_vblank(struct drm_crtc *crtc) 353 { 354 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc); 355 356 rcrtc->vblank_enable = true; 357 358 return 0; 359 } 360 361 static void rzg2l_du_crtc_disable_vblank(struct drm_crtc *crtc) 362 { 363 struct rzg2l_du_crtc *rcrtc = to_rzg2l_crtc(crtc); 364 365 rcrtc->vblank_enable = false; 366 } 367 368 static const struct drm_crtc_funcs crtc_funcs_rz = { 369 .reset = rzg2l_du_crtc_reset, 370 .set_config = drm_atomic_helper_set_config, 371 .page_flip = drm_atomic_helper_page_flip, 372 .atomic_duplicate_state = rzg2l_du_crtc_atomic_duplicate_state, 373 .atomic_destroy_state = rzg2l_du_crtc_atomic_destroy_state, 374 .enable_vblank = rzg2l_du_crtc_enable_vblank, 375 .disable_vblank = rzg2l_du_crtc_disable_vblank, 376 }; 377 378 /* ----------------------------------------------------------------------------- 379 * Initialization 380 */ 381 382 int rzg2l_du_crtc_create(struct rzg2l_du_device *rcdu) 383 { 384 struct rzg2l_du_crtc *rcrtc = &rcdu->crtcs[0]; 385 struct drm_crtc *crtc = &rcrtc->crtc; 386 struct drm_plane *primary; 387 int ret; 388 389 rcrtc->rstc = devm_reset_control_get_shared(rcdu->dev, NULL); 390 if (IS_ERR(rcrtc->rstc)) { 391 dev_err(rcdu->dev, "can't get cpg reset\n"); 392 return PTR_ERR(rcrtc->rstc); 393 } 394 395 rcrtc->rzg2l_clocks.aclk = devm_clk_get(rcdu->dev, "aclk"); 396 if (IS_ERR(rcrtc->rzg2l_clocks.aclk)) { 397 dev_err(rcdu->dev, "no axi clock for DU\n"); 398 return PTR_ERR(rcrtc->rzg2l_clocks.aclk); 399 } 400 401 rcrtc->rzg2l_clocks.pclk = devm_clk_get(rcdu->dev, "pclk"); 402 if (IS_ERR(rcrtc->rzg2l_clocks.pclk)) { 403 dev_err(rcdu->dev, "no peripheral clock for DU\n"); 404 return PTR_ERR(rcrtc->rzg2l_clocks.pclk); 405 } 406 407 rcrtc->rzg2l_clocks.dclk = devm_clk_get(rcdu->dev, "vclk"); 408 if (IS_ERR(rcrtc->rzg2l_clocks.dclk)) { 409 dev_err(rcdu->dev, "no video clock for DU\n"); 410 return PTR_ERR(rcrtc->rzg2l_clocks.dclk); 411 } 412 413 init_waitqueue_head(&rcrtc->flip_wait); 414 rcrtc->dev = rcdu; 415 416 primary = rzg2l_du_vsp_get_drm_plane(rcrtc, rcrtc->vsp_pipe); 417 if (IS_ERR(primary)) 418 return PTR_ERR(primary); 419 420 ret = drmm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL, 421 &crtc_funcs_rz, NULL); 422 if (ret < 0) 423 return ret; 424 425 drm_crtc_helper_add(crtc, &crtc_helper_funcs); 426 427 return 0; 428 } 429