1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/ 4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 5 */ 6 7 #include <drm/drm_atomic.h> 8 #include <drm/drm_atomic_helper.h> 9 #include <drm/drm_crtc.h> 10 #include <drm/drm_crtc_helper.h> 11 #include <drm/drm_gem_dma_helper.h> 12 #include <drm/drm_vblank.h> 13 14 #include "tidss_crtc.h" 15 #include "tidss_dispc.h" 16 #include "tidss_drv.h" 17 #include "tidss_irq.h" 18 #include "tidss_plane.h" 19 20 /* Page flip and frame done IRQs */ 21 22 static void tidss_crtc_finish_page_flip(struct tidss_crtc *tcrtc) 23 { 24 struct drm_device *ddev = tcrtc->crtc.dev; 25 struct tidss_device *tidss = to_tidss(ddev); 26 struct drm_pending_vblank_event *event; 27 unsigned long flags; 28 bool busy; 29 30 spin_lock_irqsave(&ddev->event_lock, flags); 31 32 /* 33 * New settings are taken into use at VFP, and GO bit is cleared at 34 * the same time. This happens before the vertical blank interrupt. 35 * So there is a small change that the driver sets GO bit after VFP, but 36 * before vblank, and we have to check for that case here. 37 */ 38 busy = dispc_vp_go_busy(tidss->dispc, tcrtc->hw_videoport); 39 if (busy) { 40 spin_unlock_irqrestore(&ddev->event_lock, flags); 41 return; 42 } 43 44 event = tcrtc->event; 45 tcrtc->event = NULL; 46 47 if (!event) { 48 spin_unlock_irqrestore(&ddev->event_lock, flags); 49 return; 50 } 51 52 drm_crtc_send_vblank_event(&tcrtc->crtc, event); 53 54 spin_unlock_irqrestore(&ddev->event_lock, flags); 55 56 drm_crtc_vblank_put(&tcrtc->crtc); 57 } 58 59 void tidss_crtc_vblank_irq(struct drm_crtc *crtc) 60 { 61 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 62 63 drm_crtc_handle_vblank(crtc); 64 65 tidss_crtc_finish_page_flip(tcrtc); 66 } 67 68 void tidss_crtc_framedone_irq(struct drm_crtc *crtc) 69 { 70 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 71 72 complete(&tcrtc->framedone_completion); 73 } 74 75 void tidss_crtc_error_irq(struct drm_crtc *crtc, u64 irqstatus) 76 { 77 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 78 79 dev_err_ratelimited(crtc->dev->dev, "CRTC%u SYNC LOST: (irq %llx)\n", 80 tcrtc->hw_videoport, irqstatus); 81 } 82 83 /* drm_crtc_helper_funcs */ 84 85 static int tidss_crtc_atomic_check(struct drm_crtc *crtc, 86 struct drm_atomic_state *state) 87 { 88 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, 89 crtc); 90 struct drm_device *ddev = crtc->dev; 91 struct tidss_device *tidss = to_tidss(ddev); 92 struct dispc_device *dispc = tidss->dispc; 93 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 94 u32 hw_videoport = tcrtc->hw_videoport; 95 const struct drm_display_mode *mode; 96 enum drm_mode_status ok; 97 98 dev_dbg(ddev->dev, "%s\n", __func__); 99 100 if (!crtc_state->enable) 101 return 0; 102 103 mode = &crtc_state->adjusted_mode; 104 105 ok = dispc_vp_mode_valid(dispc, hw_videoport, mode); 106 if (ok != MODE_OK) { 107 dev_dbg(ddev->dev, "%s: bad mode: %ux%u pclk %u kHz\n", 108 __func__, mode->hdisplay, mode->vdisplay, mode->clock); 109 return -EINVAL; 110 } 111 112 return dispc_vp_bus_check(dispc, hw_videoport, crtc_state); 113 } 114 115 /* 116 * This needs all affected planes to be present in the atomic 117 * state. The untouched planes are added to the state in 118 * tidss_atomic_check(). 119 */ 120 static void tidss_crtc_position_planes(struct tidss_device *tidss, 121 struct drm_crtc *crtc, 122 struct drm_crtc_state *old_state, 123 bool newmodeset) 124 { 125 struct drm_atomic_state *ostate = old_state->state; 126 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 127 struct drm_crtc_state *cstate = crtc->state; 128 int layer; 129 130 if (!newmodeset && !cstate->zpos_changed && 131 !to_tidss_crtc_state(cstate)->plane_pos_changed) 132 return; 133 134 for (layer = 0; layer < tidss->feat->num_planes; layer++) { 135 struct drm_plane_state *pstate; 136 struct drm_plane *plane; 137 bool layer_active = false; 138 int i; 139 140 for_each_new_plane_in_state(ostate, plane, pstate, i) { 141 if (pstate->crtc != crtc || !pstate->visible) 142 continue; 143 144 if (pstate->normalized_zpos == layer) { 145 layer_active = true; 146 break; 147 } 148 } 149 150 if (layer_active) { 151 struct tidss_plane *tplane = to_tidss_plane(plane); 152 153 dispc_ovr_set_plane(tidss->dispc, tplane->hw_plane_id, 154 tcrtc->hw_videoport, 155 pstate->crtc_x, pstate->crtc_y, 156 layer); 157 } 158 dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer, 159 layer_active); 160 } 161 } 162 163 static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, 164 struct drm_atomic_state *state) 165 { 166 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, 167 crtc); 168 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 169 struct drm_device *ddev = crtc->dev; 170 struct tidss_device *tidss = to_tidss(ddev); 171 unsigned long flags; 172 173 dev_dbg(ddev->dev, 174 "%s: %s enabled %d, needs modeset %d, event %p\n", __func__, 175 crtc->name, drm_atomic_crtc_needs_modeset(crtc->state), 176 crtc->state->enable, crtc->state->event); 177 178 /* There is nothing to do if CRTC is not going to be enabled. */ 179 if (!crtc->state->enable) 180 return; 181 182 /* 183 * Flush CRTC changes with go bit only if new modeset is not 184 * coming, so CRTC is enabled trough out the commit. 185 */ 186 if (drm_atomic_crtc_needs_modeset(crtc->state)) 187 return; 188 189 /* If the GO bit is stuck we better quit here. */ 190 if (WARN_ON(dispc_vp_go_busy(tidss->dispc, tcrtc->hw_videoport))) 191 return; 192 193 /* We should have event if CRTC is enabled through out this commit. */ 194 if (WARN_ON(!crtc->state->event)) 195 return; 196 197 /* Write vp properties to HW if needed. */ 198 dispc_vp_setup(tidss->dispc, tcrtc->hw_videoport, crtc->state, false); 199 200 /* Update plane positions if needed. */ 201 tidss_crtc_position_planes(tidss, crtc, old_crtc_state, false); 202 203 WARN_ON(drm_crtc_vblank_get(crtc) != 0); 204 205 spin_lock_irqsave(&ddev->event_lock, flags); 206 dispc_vp_go(tidss->dispc, tcrtc->hw_videoport); 207 208 WARN_ON(tcrtc->event); 209 210 tcrtc->event = crtc->state->event; 211 crtc->state->event = NULL; 212 213 spin_unlock_irqrestore(&ddev->event_lock, flags); 214 } 215 216 static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, 217 struct drm_atomic_state *state) 218 { 219 struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, 220 crtc); 221 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 222 struct drm_device *ddev = crtc->dev; 223 struct tidss_device *tidss = to_tidss(ddev); 224 const struct drm_display_mode *mode = &crtc->state->adjusted_mode; 225 unsigned long flags; 226 int r; 227 228 dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event); 229 230 tidss_runtime_get(tidss); 231 232 r = dispc_vp_set_clk_rate(tidss->dispc, tcrtc->hw_videoport, 233 mode->clock * 1000); 234 if (r != 0) 235 return; 236 237 r = dispc_vp_enable_clk(tidss->dispc, tcrtc->hw_videoport); 238 if (r != 0) 239 return; 240 241 dispc_vp_setup(tidss->dispc, tcrtc->hw_videoport, crtc->state, true); 242 tidss_crtc_position_planes(tidss, crtc, old_state, true); 243 244 /* Turn vertical blanking interrupt reporting on. */ 245 drm_crtc_vblank_on(crtc); 246 247 dispc_vp_prepare(tidss->dispc, tcrtc->hw_videoport, crtc->state); 248 249 dispc_vp_enable(tidss->dispc, tcrtc->hw_videoport, crtc->state); 250 251 spin_lock_irqsave(&ddev->event_lock, flags); 252 253 if (crtc->state->event) { 254 drm_crtc_send_vblank_event(crtc, crtc->state->event); 255 crtc->state->event = NULL; 256 } 257 258 spin_unlock_irqrestore(&ddev->event_lock, flags); 259 } 260 261 static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, 262 struct drm_atomic_state *state) 263 { 264 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 265 struct drm_device *ddev = crtc->dev; 266 struct tidss_device *tidss = to_tidss(ddev); 267 unsigned long flags; 268 269 dev_dbg(ddev->dev, "%s, event %p\n", __func__, crtc->state->event); 270 271 reinit_completion(&tcrtc->framedone_completion); 272 273 dispc_vp_disable(tidss->dispc, tcrtc->hw_videoport); 274 275 if (!wait_for_completion_timeout(&tcrtc->framedone_completion, 276 msecs_to_jiffies(500))) 277 dev_err(tidss->dev, "Timeout waiting for framedone on crtc %d", 278 tcrtc->hw_videoport); 279 280 dispc_vp_unprepare(tidss->dispc, tcrtc->hw_videoport); 281 282 spin_lock_irqsave(&ddev->event_lock, flags); 283 if (crtc->state->event) { 284 drm_crtc_send_vblank_event(crtc, crtc->state->event); 285 crtc->state->event = NULL; 286 } 287 spin_unlock_irqrestore(&ddev->event_lock, flags); 288 289 drm_crtc_vblank_off(crtc); 290 291 dispc_vp_disable_clk(tidss->dispc, tcrtc->hw_videoport); 292 293 tidss_runtime_put(tidss); 294 } 295 296 static 297 enum drm_mode_status tidss_crtc_mode_valid(struct drm_crtc *crtc, 298 const struct drm_display_mode *mode) 299 { 300 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 301 struct drm_device *ddev = crtc->dev; 302 struct tidss_device *tidss = to_tidss(ddev); 303 304 return dispc_vp_mode_valid(tidss->dispc, tcrtc->hw_videoport, mode); 305 } 306 307 static const struct drm_crtc_helper_funcs tidss_crtc_helper_funcs = { 308 .atomic_check = tidss_crtc_atomic_check, 309 .atomic_flush = tidss_crtc_atomic_flush, 310 .atomic_enable = tidss_crtc_atomic_enable, 311 .atomic_disable = tidss_crtc_atomic_disable, 312 313 .mode_valid = tidss_crtc_mode_valid, 314 }; 315 316 /* drm_crtc_funcs */ 317 318 static int tidss_crtc_enable_vblank(struct drm_crtc *crtc) 319 { 320 struct drm_device *ddev = crtc->dev; 321 struct tidss_device *tidss = to_tidss(ddev); 322 323 dev_dbg(ddev->dev, "%s\n", __func__); 324 325 tidss_runtime_get(tidss); 326 327 tidss_irq_enable_vblank(crtc); 328 329 return 0; 330 } 331 332 static void tidss_crtc_disable_vblank(struct drm_crtc *crtc) 333 { 334 struct drm_device *ddev = crtc->dev; 335 struct tidss_device *tidss = to_tidss(ddev); 336 337 dev_dbg(ddev->dev, "%s\n", __func__); 338 339 tidss_irq_disable_vblank(crtc); 340 341 tidss_runtime_put(tidss); 342 } 343 344 static void tidss_crtc_reset(struct drm_crtc *crtc) 345 { 346 struct tidss_crtc_state *tcrtc; 347 348 if (crtc->state) 349 __drm_atomic_helper_crtc_destroy_state(crtc->state); 350 351 kfree(crtc->state); 352 353 tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL); 354 if (!tcrtc) { 355 crtc->state = NULL; 356 return; 357 } 358 359 __drm_atomic_helper_crtc_reset(crtc, &tcrtc->base); 360 } 361 362 static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc) 363 { 364 struct tidss_crtc_state *state, *current_state; 365 366 if (WARN_ON(!crtc->state)) 367 return NULL; 368 369 current_state = to_tidss_crtc_state(crtc->state); 370 371 state = kmalloc(sizeof(*state), GFP_KERNEL); 372 if (!state) 373 return NULL; 374 375 __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); 376 377 state->plane_pos_changed = false; 378 379 state->bus_format = current_state->bus_format; 380 state->bus_flags = current_state->bus_flags; 381 382 return &state->base; 383 } 384 385 static void tidss_crtc_destroy(struct drm_crtc *crtc) 386 { 387 struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); 388 389 drm_crtc_cleanup(crtc); 390 kfree(tcrtc); 391 } 392 393 static const struct drm_crtc_funcs tidss_crtc_funcs = { 394 .reset = tidss_crtc_reset, 395 .destroy = tidss_crtc_destroy, 396 .set_config = drm_atomic_helper_set_config, 397 .page_flip = drm_atomic_helper_page_flip, 398 .atomic_duplicate_state = tidss_crtc_duplicate_state, 399 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 400 .enable_vblank = tidss_crtc_enable_vblank, 401 .disable_vblank = tidss_crtc_disable_vblank, 402 }; 403 404 struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss, 405 u32 hw_videoport, 406 struct drm_plane *primary) 407 { 408 struct tidss_crtc *tcrtc; 409 struct drm_crtc *crtc; 410 unsigned int gamma_lut_size = 0; 411 bool has_ctm = tidss->feat->vp_feat.color.has_ctm; 412 int ret; 413 414 tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL); 415 if (!tcrtc) 416 return ERR_PTR(-ENOMEM); 417 418 tcrtc->hw_videoport = hw_videoport; 419 init_completion(&tcrtc->framedone_completion); 420 421 crtc = &tcrtc->crtc; 422 423 ret = drm_crtc_init_with_planes(&tidss->ddev, crtc, primary, 424 NULL, &tidss_crtc_funcs, NULL); 425 if (ret < 0) { 426 kfree(tcrtc); 427 return ERR_PTR(ret); 428 } 429 430 drm_crtc_helper_add(crtc, &tidss_crtc_helper_funcs); 431 432 /* 433 * The dispc gamma functions adapt to what ever size we ask 434 * from it no matter what HW supports. X-server assumes 256 435 * element gamma tables so lets use that. 436 */ 437 if (tidss->feat->vp_feat.color.gamma_size) 438 gamma_lut_size = 256; 439 440 drm_crtc_enable_color_mgmt(crtc, 0, has_ctm, gamma_lut_size); 441 if (gamma_lut_size) 442 drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size); 443 444 return tcrtc; 445 } 446