1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. 4 * Author: James.Qian.Wang <james.qian.wang@arm.com> 5 * 6 */ 7 8 #include <drm/drm_print.h> 9 #include <linux/clk.h> 10 #include "komeda_dev.h" 11 #include "komeda_kms.h" 12 #include "komeda_pipeline.h" 13 #include "komeda_framebuffer.h" 14 15 static inline bool is_switching_user(void *old, void *new) 16 { 17 if (!old || !new) 18 return false; 19 20 return old != new; 21 } 22 23 static struct komeda_pipeline_state * 24 komeda_pipeline_get_state(struct komeda_pipeline *pipe, 25 struct drm_atomic_state *state) 26 { 27 struct drm_private_state *priv_st; 28 29 priv_st = drm_atomic_get_private_obj_state(state, &pipe->obj); 30 if (IS_ERR(priv_st)) 31 return ERR_CAST(priv_st); 32 33 return priv_to_pipe_st(priv_st); 34 } 35 36 struct komeda_pipeline_state * 37 komeda_pipeline_get_old_state(struct komeda_pipeline *pipe, 38 struct drm_atomic_state *state) 39 { 40 struct drm_private_state *priv_st; 41 42 priv_st = drm_atomic_get_old_private_obj_state(state, &pipe->obj); 43 if (priv_st) 44 return priv_to_pipe_st(priv_st); 45 return NULL; 46 } 47 48 static struct komeda_pipeline_state * 49 komeda_pipeline_get_new_state(struct komeda_pipeline *pipe, 50 struct drm_atomic_state *state) 51 { 52 struct drm_private_state *priv_st; 53 54 priv_st = drm_atomic_get_new_private_obj_state(state, &pipe->obj); 55 if (priv_st) 56 return priv_to_pipe_st(priv_st); 57 return NULL; 58 } 59 60 /* Assign pipeline for crtc */ 61 static struct komeda_pipeline_state * 62 komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe, 63 struct drm_atomic_state *state, 64 struct drm_crtc *crtc) 65 { 66 struct komeda_pipeline_state *st; 67 68 st = komeda_pipeline_get_state(pipe, state); 69 if (IS_ERR(st)) 70 return st; 71 72 if (is_switching_user(crtc, st->crtc)) { 73 DRM_DEBUG_ATOMIC("CRTC%d required pipeline%d is busy.\n", 74 drm_crtc_index(crtc), pipe->id); 75 return ERR_PTR(-EBUSY); 76 } 77 78 /* pipeline only can be disabled when the it is free or unused */ 79 if (!crtc && st->active_comps) { 80 DRM_DEBUG_ATOMIC("Disabling a busy pipeline:%d.\n", pipe->id); 81 return ERR_PTR(-EBUSY); 82 } 83 84 st->crtc = crtc; 85 86 if (crtc) { 87 struct komeda_crtc_state *kcrtc_st; 88 89 kcrtc_st = to_kcrtc_st(drm_atomic_get_new_crtc_state(state, 90 crtc)); 91 92 kcrtc_st->active_pipes |= BIT(pipe->id); 93 kcrtc_st->affected_pipes |= BIT(pipe->id); 94 } 95 return st; 96 } 97 98 static struct komeda_component_state * 99 komeda_component_get_state(struct komeda_component *c, 100 struct drm_atomic_state *state) 101 { 102 struct drm_private_state *priv_st; 103 104 WARN_ON(!drm_modeset_is_locked(&c->pipeline->obj.lock)); 105 106 priv_st = drm_atomic_get_private_obj_state(state, &c->obj); 107 if (IS_ERR(priv_st)) 108 return ERR_CAST(priv_st); 109 110 return priv_to_comp_st(priv_st); 111 } 112 113 static struct komeda_component_state * 114 komeda_component_get_old_state(struct komeda_component *c, 115 struct drm_atomic_state *state) 116 { 117 struct drm_private_state *priv_st; 118 119 priv_st = drm_atomic_get_old_private_obj_state(state, &c->obj); 120 if (priv_st) 121 return priv_to_comp_st(priv_st); 122 return NULL; 123 } 124 125 /** 126 * komeda_component_get_state_and_set_user() 127 * 128 * @c: component to get state and set user 129 * @state: global atomic state 130 * @user: direct user, the binding user 131 * @crtc: the CRTC user, the big boss :) 132 * 133 * This function accepts two users: 134 * - The direct user: can be plane/crtc/wb_connector depends on component 135 * - The big boss (CRTC) 136 * CRTC is the big boss (the final user), because all component resources 137 * eventually will be assigned to CRTC, like the layer will be binding to 138 * kms_plane, but kms plane will be binding to a CRTC eventually. 139 * 140 * The big boss (CRTC) is for pipeline assignment, since &komeda_component isn't 141 * independent and can be assigned to CRTC freely, but belongs to a specific 142 * pipeline, only pipeline can be shared between crtc, and pipeline as a whole 143 * (include all the internal components) assigned to a specific CRTC. 144 * 145 * So when set a user to komeda_component, need first to check the status of 146 * component->pipeline to see if the pipeline is available on this specific 147 * CRTC. if the pipeline is busy (assigned to another CRTC), even the required 148 * component is free, the component still cannot be assigned to the direct user. 149 */ 150 static struct komeda_component_state * 151 komeda_component_get_state_and_set_user(struct komeda_component *c, 152 struct drm_atomic_state *state, 153 void *user, 154 struct drm_crtc *crtc) 155 { 156 struct komeda_pipeline_state *pipe_st; 157 struct komeda_component_state *st; 158 159 /* First check if the pipeline is available */ 160 pipe_st = komeda_pipeline_get_state_and_set_crtc(c->pipeline, 161 state, crtc); 162 if (IS_ERR(pipe_st)) 163 return ERR_CAST(pipe_st); 164 165 st = komeda_component_get_state(c, state); 166 if (IS_ERR(st)) 167 return st; 168 169 /* check if the component has been occupied */ 170 if (is_switching_user(user, st->binding_user)) { 171 DRM_DEBUG_ATOMIC("required %s is busy.\n", c->name); 172 return ERR_PTR(-EBUSY); 173 } 174 175 st->binding_user = user; 176 /* mark the component as active if user is valid */ 177 if (st->binding_user) 178 pipe_st->active_comps |= BIT(c->id); 179 180 return st; 181 } 182 183 static void 184 komeda_component_add_input(struct komeda_component_state *state, 185 struct komeda_component_output *input, 186 int idx) 187 { 188 struct komeda_component *c = state->component; 189 190 WARN_ON((idx < 0 || idx >= c->max_active_inputs)); 191 192 /* since the inputs[i] is only valid when it is active. So if a input[i] 193 * is a newly enabled input which switches from disable to enable, then 194 * the old inputs[i] is undefined (NOT zeroed), we can not rely on 195 * memcmp, but directly mark it changed 196 */ 197 if (!has_bit(idx, state->affected_inputs) || 198 memcmp(&state->inputs[idx], input, sizeof(*input))) { 199 memcpy(&state->inputs[idx], input, sizeof(*input)); 200 state->changed_active_inputs |= BIT(idx); 201 } 202 state->active_inputs |= BIT(idx); 203 state->affected_inputs |= BIT(idx); 204 } 205 206 static int 207 komeda_component_check_input(struct komeda_component_state *state, 208 struct komeda_component_output *input, 209 int idx) 210 { 211 struct komeda_component *c = state->component; 212 213 if ((idx < 0) || (idx >= c->max_active_inputs)) { 214 DRM_DEBUG_ATOMIC("%s invalid input id: %d.\n", c->name, idx); 215 return -EINVAL; 216 } 217 218 if (has_bit(idx, state->active_inputs)) { 219 DRM_DEBUG_ATOMIC("%s required input_id: %d has been occupied already.\n", 220 c->name, idx); 221 return -EINVAL; 222 } 223 224 return 0; 225 } 226 227 static void 228 komeda_component_set_output(struct komeda_component_output *output, 229 struct komeda_component *comp, 230 u8 output_port) 231 { 232 output->component = comp; 233 output->output_port = output_port; 234 } 235 236 static int 237 komeda_component_validate_private(struct komeda_component *c, 238 struct komeda_component_state *st) 239 { 240 int err; 241 242 if (!c->funcs->validate) 243 return 0; 244 245 err = c->funcs->validate(c, st); 246 if (err) 247 DRM_DEBUG_ATOMIC("%s validate private failed.\n", c->name); 248 249 return err; 250 } 251 252 static int 253 komeda_layer_check_cfg(struct komeda_layer *layer, 254 struct komeda_plane_state *kplane_st, 255 struct komeda_data_flow_cfg *dflow) 256 { 257 if (!in_range(&layer->hsize_in, dflow->in_w)) { 258 DRM_DEBUG_ATOMIC("src_w: %d is out of range.\n", dflow->in_w); 259 return -EINVAL; 260 } 261 262 if (!in_range(&layer->vsize_in, dflow->in_h)) { 263 DRM_DEBUG_ATOMIC("src_h: %d is out of range.\n", dflow->in_h); 264 return -EINVAL; 265 } 266 267 return 0; 268 } 269 270 static int 271 komeda_layer_validate(struct komeda_layer *layer, 272 struct komeda_plane_state *kplane_st, 273 struct komeda_data_flow_cfg *dflow) 274 { 275 struct drm_plane_state *plane_st = &kplane_st->base; 276 struct drm_framebuffer *fb = plane_st->fb; 277 struct komeda_fb *kfb = to_kfb(fb); 278 struct komeda_component_state *c_st; 279 struct komeda_layer_state *st; 280 int i, err; 281 282 err = komeda_layer_check_cfg(layer, kplane_st, dflow); 283 if (err) 284 return err; 285 286 c_st = komeda_component_get_state_and_set_user(&layer->base, 287 plane_st->state, plane_st->plane, plane_st->crtc); 288 if (IS_ERR(c_st)) 289 return PTR_ERR(c_st); 290 291 st = to_layer_st(c_st); 292 293 st->rot = dflow->rot; 294 st->hsize = kfb->aligned_w; 295 st->vsize = kfb->aligned_h; 296 297 for (i = 0; i < fb->format->num_planes; i++) 298 st->addr[i] = komeda_fb_get_pixel_addr(kfb, dflow->in_x, 299 dflow->in_y, i); 300 301 err = komeda_component_validate_private(&layer->base, c_st); 302 if (err) 303 return err; 304 305 /* update the data flow for the next stage */ 306 komeda_component_set_output(&dflow->input, &layer->base, 0); 307 308 return 0; 309 } 310 311 static void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st, 312 u16 *hsize, u16 *vsize) 313 { 314 struct drm_display_mode *m = &kcrtc_st->base.adjusted_mode; 315 316 if (hsize) 317 *hsize = m->hdisplay; 318 if (vsize) 319 *vsize = m->vdisplay; 320 } 321 322 static int 323 komeda_compiz_set_input(struct komeda_compiz *compiz, 324 struct komeda_crtc_state *kcrtc_st, 325 struct komeda_data_flow_cfg *dflow) 326 { 327 struct drm_atomic_state *drm_st = kcrtc_st->base.state; 328 struct komeda_component_state *c_st, *old_st; 329 struct komeda_compiz_input_cfg *cin; 330 u16 compiz_w, compiz_h; 331 int idx = dflow->blending_zorder; 332 333 pipeline_composition_size(kcrtc_st, &compiz_w, &compiz_h); 334 /* check display rect */ 335 if ((dflow->out_x + dflow->out_w > compiz_w) || 336 (dflow->out_y + dflow->out_h > compiz_h) || 337 dflow->out_w == 0 || dflow->out_h == 0) { 338 DRM_DEBUG_ATOMIC("invalid disp rect [x=%d, y=%d, w=%d, h=%d]\n", 339 dflow->out_x, dflow->out_y, 340 dflow->out_w, dflow->out_h); 341 return -EINVAL; 342 } 343 344 c_st = komeda_component_get_state_and_set_user(&compiz->base, drm_st, 345 kcrtc_st->base.crtc, kcrtc_st->base.crtc); 346 if (IS_ERR(c_st)) 347 return PTR_ERR(c_st); 348 349 if (komeda_component_check_input(c_st, &dflow->input, idx)) 350 return -EINVAL; 351 352 cin = &(to_compiz_st(c_st)->cins[idx]); 353 354 cin->hsize = dflow->out_w; 355 cin->vsize = dflow->out_h; 356 cin->hoffset = dflow->out_x; 357 cin->voffset = dflow->out_y; 358 cin->pixel_blend_mode = dflow->pixel_blend_mode; 359 cin->layer_alpha = dflow->layer_alpha; 360 361 old_st = komeda_component_get_old_state(&compiz->base, drm_st); 362 WARN_ON(!old_st); 363 364 /* compare with old to check if this input has been changed */ 365 if (memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin))) 366 c_st->changed_active_inputs |= BIT(idx); 367 368 komeda_component_add_input(c_st, &dflow->input, idx); 369 370 return 0; 371 } 372 373 static int 374 komeda_compiz_validate(struct komeda_compiz *compiz, 375 struct komeda_crtc_state *state, 376 struct komeda_data_flow_cfg *dflow) 377 { 378 struct komeda_component_state *c_st; 379 struct komeda_compiz_state *st; 380 381 c_st = komeda_component_get_state_and_set_user(&compiz->base, 382 state->base.state, state->base.crtc, state->base.crtc); 383 if (IS_ERR(c_st)) 384 return PTR_ERR(c_st); 385 386 st = to_compiz_st(c_st); 387 388 pipeline_composition_size(state, &st->hsize, &st->vsize); 389 390 komeda_component_set_output(&dflow->input, &compiz->base, 0); 391 392 /* compiz output dflow will be fed to the next pipeline stage, prepare 393 * the data flow configuration for the next stage 394 */ 395 if (dflow) { 396 dflow->in_w = st->hsize; 397 dflow->in_h = st->vsize; 398 dflow->out_w = dflow->in_w; 399 dflow->out_h = dflow->in_h; 400 /* the output data of compiz doesn't have alpha, it only can be 401 * used as bottom layer when blend it with master layers 402 */ 403 dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE; 404 dflow->layer_alpha = 0xFF; 405 dflow->blending_zorder = 0; 406 } 407 408 return 0; 409 } 410 411 static int 412 komeda_improc_validate(struct komeda_improc *improc, 413 struct komeda_crtc_state *kcrtc_st, 414 struct komeda_data_flow_cfg *dflow) 415 { 416 struct drm_crtc *crtc = kcrtc_st->base.crtc; 417 struct komeda_component_state *c_st; 418 struct komeda_improc_state *st; 419 420 c_st = komeda_component_get_state_and_set_user(&improc->base, 421 kcrtc_st->base.state, crtc, crtc); 422 if (IS_ERR(c_st)) 423 return PTR_ERR(c_st); 424 425 st = to_improc_st(c_st); 426 427 st->hsize = dflow->in_w; 428 st->vsize = dflow->in_h; 429 430 komeda_component_add_input(&st->base, &dflow->input, 0); 431 komeda_component_set_output(&dflow->input, &improc->base, 0); 432 433 return 0; 434 } 435 436 static int 437 komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr, 438 struct komeda_crtc_state *kcrtc_st, 439 struct komeda_data_flow_cfg *dflow) 440 { 441 struct drm_crtc *crtc = kcrtc_st->base.crtc; 442 struct komeda_timing_ctrlr_state *st; 443 struct komeda_component_state *c_st; 444 445 c_st = komeda_component_get_state_and_set_user(&ctrlr->base, 446 kcrtc_st->base.state, crtc, crtc); 447 if (IS_ERR(c_st)) 448 return PTR_ERR(c_st); 449 450 st = to_ctrlr_st(c_st); 451 452 komeda_component_add_input(&st->base, &dflow->input, 0); 453 komeda_component_set_output(&dflow->input, &ctrlr->base, 0); 454 455 return 0; 456 } 457 458 int komeda_build_layer_data_flow(struct komeda_layer *layer, 459 struct komeda_plane_state *kplane_st, 460 struct komeda_crtc_state *kcrtc_st, 461 struct komeda_data_flow_cfg *dflow) 462 { 463 struct drm_plane *plane = kplane_st->base.plane; 464 struct komeda_pipeline *pipe = layer->base.pipeline; 465 int err; 466 467 DRM_DEBUG_ATOMIC("%s handling [PLANE:%d:%s]: src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]", 468 layer->base.name, plane->base.id, plane->name, 469 dflow->in_x, dflow->in_y, dflow->in_w, dflow->in_h, 470 dflow->out_x, dflow->out_y, dflow->out_w, dflow->out_h); 471 472 err = komeda_layer_validate(layer, kplane_st, dflow); 473 if (err) 474 return err; 475 476 err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow); 477 478 return err; 479 } 480 481 /* build display output data flow, the data path is: 482 * compiz -> improc -> timing_ctrlr 483 */ 484 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, 485 struct komeda_crtc_state *kcrtc_st) 486 { 487 struct komeda_pipeline *master = kcrtc->master; 488 struct komeda_data_flow_cfg m_dflow; /* master data flow */ 489 int err; 490 491 memset(&m_dflow, 0, sizeof(m_dflow)); 492 493 err = komeda_compiz_validate(master->compiz, kcrtc_st, &m_dflow); 494 if (err) 495 return err; 496 497 err = komeda_improc_validate(master->improc, kcrtc_st, &m_dflow); 498 if (err) 499 return err; 500 501 err = komeda_timing_ctrlr_validate(master->ctrlr, kcrtc_st, &m_dflow); 502 if (err) 503 return err; 504 505 return 0; 506 } 507 508 static void 509 komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, 510 struct komeda_pipeline_state *new) 511 { 512 struct drm_atomic_state *drm_st = new->obj.state; 513 struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); 514 struct komeda_component_state *c_st; 515 struct komeda_component *c; 516 u32 disabling_comps, id; 517 518 WARN_ON(!old); 519 520 disabling_comps = (~new->active_comps) & old->active_comps; 521 522 /* unbound all disabling component */ 523 dp_for_each_set_bit(id, disabling_comps) { 524 c = komeda_pipeline_get_component(pipe, id); 525 c_st = komeda_component_get_state_and_set_user(c, 526 drm_st, NULL, new->crtc); 527 WARN_ON(IS_ERR(c_st)); 528 } 529 } 530 531 /* release unclaimed pipeline resource */ 532 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, 533 struct komeda_crtc_state *kcrtc_st) 534 { 535 struct drm_atomic_state *drm_st = kcrtc_st->base.state; 536 struct komeda_pipeline_state *st; 537 538 /* ignore the pipeline which is not affected */ 539 if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes)) 540 return 0; 541 542 if (has_bit(pipe->id, kcrtc_st->active_pipes)) 543 st = komeda_pipeline_get_new_state(pipe, drm_st); 544 else 545 st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL); 546 547 if (WARN_ON(IS_ERR_OR_NULL(st))) 548 return -EINVAL; 549 550 komeda_pipeline_unbound_components(pipe, st); 551 552 return 0; 553 } 554 555 void komeda_pipeline_disable(struct komeda_pipeline *pipe, 556 struct drm_atomic_state *old_state) 557 { 558 struct komeda_pipeline_state *old; 559 struct komeda_component *c; 560 struct komeda_component_state *c_st; 561 u32 id, disabling_comps = 0; 562 563 old = komeda_pipeline_get_old_state(pipe, old_state); 564 565 disabling_comps = old->active_comps; 566 DRM_DEBUG_ATOMIC("PIPE%d: disabling_comps: 0x%x.\n", 567 pipe->id, disabling_comps); 568 569 dp_for_each_set_bit(id, disabling_comps) { 570 c = komeda_pipeline_get_component(pipe, id); 571 c_st = priv_to_comp_st(c->obj.state); 572 573 /* 574 * If we disabled a component then all active_inputs should be 575 * put in the list of changed_active_inputs, so they get 576 * re-enabled. 577 * This usually happens during a modeset when the pipeline is 578 * first disabled and then the actual state gets committed 579 * again. 580 */ 581 c_st->changed_active_inputs |= c_st->active_inputs; 582 583 c->funcs->disable(c); 584 } 585 } 586 587 void komeda_pipeline_update(struct komeda_pipeline *pipe, 588 struct drm_atomic_state *old_state) 589 { 590 struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state); 591 struct komeda_pipeline_state *old; 592 struct komeda_component *c; 593 u32 id, changed_comps = 0; 594 595 old = komeda_pipeline_get_old_state(pipe, old_state); 596 597 changed_comps = new->active_comps | old->active_comps; 598 599 DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n", 600 pipe->id, new->active_comps, changed_comps); 601 602 dp_for_each_set_bit(id, changed_comps) { 603 c = komeda_pipeline_get_component(pipe, id); 604 605 if (new->active_comps & BIT(c->id)) 606 c->funcs->update(c, priv_to_comp_st(c->obj.state)); 607 else 608 c->funcs->disable(c); 609 } 610 } 611