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 required an invalid %s-input[%d].\n", 215 input->component->name, c->name, idx); 216 return -EINVAL; 217 } 218 219 if (has_bit(idx, state->active_inputs)) { 220 DRM_DEBUG_ATOMIC("%s required %s-input[%d] has been occupied already.\n", 221 input->component->name, c->name, idx); 222 return -EINVAL; 223 } 224 225 return 0; 226 } 227 228 static void 229 komeda_component_set_output(struct komeda_component_output *output, 230 struct komeda_component *comp, 231 u8 output_port) 232 { 233 output->component = comp; 234 output->output_port = output_port; 235 } 236 237 static int 238 komeda_component_validate_private(struct komeda_component *c, 239 struct komeda_component_state *st) 240 { 241 int err; 242 243 if (!c->funcs->validate) 244 return 0; 245 246 err = c->funcs->validate(c, st); 247 if (err) 248 DRM_DEBUG_ATOMIC("%s validate private failed.\n", c->name); 249 250 return err; 251 } 252 253 /* Get current available scaler from the component->supported_outputs */ 254 static struct komeda_scaler * 255 komeda_component_get_avail_scaler(struct komeda_component *c, 256 struct drm_atomic_state *state) 257 { 258 struct komeda_pipeline_state *pipe_st; 259 u32 avail_scalers; 260 261 pipe_st = komeda_pipeline_get_state(c->pipeline, state); 262 if (!pipe_st) 263 return NULL; 264 265 avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^ 266 KOMEDA_PIPELINE_SCALERS; 267 268 c = komeda_component_pickup_output(c, avail_scalers); 269 270 return to_scaler(c); 271 } 272 273 static void 274 komeda_rotate_data_flow(struct komeda_data_flow_cfg *dflow, u32 rot) 275 { 276 if (drm_rotation_90_or_270(rot)) { 277 swap(dflow->in_h, dflow->in_w); 278 swap(dflow->total_in_h, dflow->total_in_w); 279 } 280 } 281 282 static int 283 komeda_layer_check_cfg(struct komeda_layer *layer, 284 struct komeda_fb *kfb, 285 struct komeda_data_flow_cfg *dflow) 286 { 287 u32 src_x, src_y, src_w, src_h; 288 289 if (!komeda_fb_is_layer_supported(kfb, layer->layer_type, dflow->rot)) 290 return -EINVAL; 291 292 if (layer->base.id == KOMEDA_COMPONENT_WB_LAYER) { 293 src_x = dflow->out_x; 294 src_y = dflow->out_y; 295 src_w = dflow->out_w; 296 src_h = dflow->out_h; 297 } else { 298 src_x = dflow->in_x; 299 src_y = dflow->in_y; 300 src_w = dflow->in_w; 301 src_h = dflow->in_h; 302 } 303 304 if (komeda_fb_check_src_coords(kfb, src_x, src_y, src_w, src_h)) 305 return -EINVAL; 306 307 if (!in_range(&layer->hsize_in, src_w)) { 308 DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", src_w); 309 return -EINVAL; 310 } 311 312 if (!in_range(&layer->vsize_in, src_h)) { 313 DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", src_h); 314 return -EINVAL; 315 } 316 317 return 0; 318 } 319 320 static int 321 komeda_layer_validate(struct komeda_layer *layer, 322 struct komeda_plane_state *kplane_st, 323 struct komeda_data_flow_cfg *dflow) 324 { 325 struct drm_plane_state *plane_st = &kplane_st->base; 326 struct drm_framebuffer *fb = plane_st->fb; 327 struct komeda_fb *kfb = to_kfb(fb); 328 struct komeda_component_state *c_st; 329 struct komeda_layer_state *st; 330 int i, err; 331 332 err = komeda_layer_check_cfg(layer, kfb, dflow); 333 if (err) 334 return err; 335 336 c_st = komeda_component_get_state_and_set_user(&layer->base, 337 plane_st->state, plane_st->plane, plane_st->crtc); 338 if (IS_ERR(c_st)) 339 return PTR_ERR(c_st); 340 341 st = to_layer_st(c_st); 342 343 st->rot = dflow->rot; 344 345 if (fb->modifier) { 346 st->hsize = kfb->aligned_w; 347 st->vsize = kfb->aligned_h; 348 st->afbc_crop_l = dflow->in_x; 349 st->afbc_crop_r = kfb->aligned_w - dflow->in_x - dflow->in_w; 350 st->afbc_crop_t = dflow->in_y; 351 st->afbc_crop_b = kfb->aligned_h - dflow->in_y - dflow->in_h; 352 } else { 353 st->hsize = dflow->in_w; 354 st->vsize = dflow->in_h; 355 st->afbc_crop_l = 0; 356 st->afbc_crop_r = 0; 357 st->afbc_crop_t = 0; 358 st->afbc_crop_b = 0; 359 } 360 361 for (i = 0; i < fb->format->num_planes; i++) 362 st->addr[i] = komeda_fb_get_pixel_addr(kfb, dflow->in_x, 363 dflow->in_y, i); 364 365 err = komeda_component_validate_private(&layer->base, c_st); 366 if (err) 367 return err; 368 369 /* update the data flow for the next stage */ 370 komeda_component_set_output(&dflow->input, &layer->base, 0); 371 372 /* 373 * The rotation has been handled by layer, so adjusted the data flow for 374 * the next stage. 375 */ 376 komeda_rotate_data_flow(dflow, st->rot); 377 378 return 0; 379 } 380 381 static int 382 komeda_wb_layer_validate(struct komeda_layer *wb_layer, 383 struct drm_connector_state *conn_st, 384 struct komeda_data_flow_cfg *dflow) 385 { 386 struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb); 387 struct komeda_component_state *c_st; 388 struct komeda_layer_state *st; 389 int i, err; 390 391 err = komeda_layer_check_cfg(wb_layer, kfb, dflow); 392 if (err) 393 return err; 394 395 c_st = komeda_component_get_state_and_set_user(&wb_layer->base, 396 conn_st->state, conn_st->connector, conn_st->crtc); 397 if (IS_ERR(c_st)) 398 return PTR_ERR(c_st); 399 400 st = to_layer_st(c_st); 401 402 st->hsize = dflow->out_w; 403 st->vsize = dflow->out_h; 404 405 for (i = 0; i < kfb->base.format->num_planes; i++) 406 st->addr[i] = komeda_fb_get_pixel_addr(kfb, dflow->out_x, 407 dflow->out_y, i); 408 409 komeda_component_add_input(&st->base, &dflow->input, 0); 410 komeda_component_set_output(&dflow->input, &wb_layer->base, 0); 411 412 return 0; 413 } 414 415 static bool scaling_ratio_valid(u32 size_in, u32 size_out, 416 u32 max_upscaling, u32 max_downscaling) 417 { 418 if (size_out > size_in * max_upscaling) 419 return false; 420 else if (size_in > size_out * max_downscaling) 421 return false; 422 return true; 423 } 424 425 static int 426 komeda_scaler_check_cfg(struct komeda_scaler *scaler, 427 struct komeda_crtc_state *kcrtc_st, 428 struct komeda_data_flow_cfg *dflow) 429 { 430 u32 hsize_in, vsize_in, hsize_out, vsize_out; 431 u32 max_upscaling; 432 433 hsize_in = dflow->in_w; 434 vsize_in = dflow->in_h; 435 hsize_out = dflow->out_w; 436 vsize_out = dflow->out_h; 437 438 if (!in_range(&scaler->hsize, hsize_in) || 439 !in_range(&scaler->hsize, hsize_out)) { 440 DRM_DEBUG_ATOMIC("Invalid horizontal sizes"); 441 return -EINVAL; 442 } 443 444 if (!in_range(&scaler->vsize, vsize_in) || 445 !in_range(&scaler->vsize, vsize_out)) { 446 DRM_DEBUG_ATOMIC("Invalid vertical sizes"); 447 return -EINVAL; 448 } 449 450 /* If input comes from compiz that means the scaling is for writeback 451 * and scaler can not do upscaling for writeback 452 */ 453 if (has_bit(dflow->input.component->id, KOMEDA_PIPELINE_COMPIZS)) 454 max_upscaling = 1; 455 else 456 max_upscaling = scaler->max_upscaling; 457 458 if (!scaling_ratio_valid(hsize_in, hsize_out, max_upscaling, 459 scaler->max_downscaling)) { 460 DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio"); 461 return -EINVAL; 462 } 463 464 if (!scaling_ratio_valid(vsize_in, vsize_out, max_upscaling, 465 scaler->max_downscaling)) { 466 DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio"); 467 return -EINVAL; 468 } 469 470 if (hsize_in > hsize_out || vsize_in > vsize_out) { 471 struct komeda_pipeline *pipe = scaler->base.pipeline; 472 int err; 473 474 err = pipe->funcs->downscaling_clk_check(pipe, 475 &kcrtc_st->base.adjusted_mode, 476 komeda_calc_aclk(kcrtc_st), dflow); 477 if (err) { 478 DRM_DEBUG_ATOMIC("aclk can't satisfy the clock requirement of the downscaling\n"); 479 return err; 480 } 481 } 482 483 return 0; 484 } 485 486 static int 487 komeda_scaler_validate(void *user, 488 struct komeda_crtc_state *kcrtc_st, 489 struct komeda_data_flow_cfg *dflow) 490 { 491 struct drm_atomic_state *drm_st = kcrtc_st->base.state; 492 struct komeda_component_state *c_st; 493 struct komeda_scaler_state *st; 494 struct komeda_scaler *scaler; 495 int err = 0; 496 497 if (!(dflow->en_scaling || dflow->en_img_enhancement)) 498 return 0; 499 500 scaler = komeda_component_get_avail_scaler(dflow->input.component, 501 drm_st); 502 if (!scaler) { 503 DRM_DEBUG_ATOMIC("No scaler available"); 504 return -EINVAL; 505 } 506 507 err = komeda_scaler_check_cfg(scaler, kcrtc_st, dflow); 508 if (err) 509 return err; 510 511 c_st = komeda_component_get_state_and_set_user(&scaler->base, 512 drm_st, user, kcrtc_st->base.crtc); 513 if (IS_ERR(c_st)) 514 return PTR_ERR(c_st); 515 516 st = to_scaler_st(c_st); 517 518 st->hsize_in = dflow->in_w; 519 st->vsize_in = dflow->in_h; 520 st->hsize_out = dflow->out_w; 521 st->vsize_out = dflow->out_h; 522 st->right_crop = dflow->right_crop; 523 st->left_crop = dflow->left_crop; 524 st->total_vsize_in = dflow->total_in_h; 525 st->total_hsize_in = dflow->total_in_w; 526 st->total_hsize_out = dflow->total_out_w; 527 528 /* Enable alpha processing if the next stage needs the pixel alpha */ 529 st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE; 530 st->en_scaling = dflow->en_scaling; 531 st->en_img_enhancement = dflow->en_img_enhancement; 532 st->en_split = dflow->en_split; 533 st->right_part = dflow->right_part; 534 535 komeda_component_add_input(&st->base, &dflow->input, 0); 536 komeda_component_set_output(&dflow->input, &scaler->base, 0); 537 return err; 538 } 539 540 static void komeda_split_data_flow(struct komeda_scaler *scaler, 541 struct komeda_data_flow_cfg *dflow, 542 struct komeda_data_flow_cfg *l_dflow, 543 struct komeda_data_flow_cfg *r_dflow); 544 545 static int 546 komeda_splitter_validate(struct komeda_splitter *splitter, 547 struct drm_connector_state *conn_st, 548 struct komeda_data_flow_cfg *dflow, 549 struct komeda_data_flow_cfg *l_output, 550 struct komeda_data_flow_cfg *r_output) 551 { 552 struct komeda_component_state *c_st; 553 struct komeda_splitter_state *st; 554 555 if (!splitter) { 556 DRM_DEBUG_ATOMIC("Current HW doesn't support splitter.\n"); 557 return -EINVAL; 558 } 559 560 if (!in_range(&splitter->hsize, dflow->in_w)) { 561 DRM_DEBUG_ATOMIC("split in_w:%d is out of the acceptable range.\n", 562 dflow->in_w); 563 return -EINVAL; 564 } 565 566 if (!in_range(&splitter->vsize, dflow->in_h)) { 567 DRM_DEBUG_ATOMIC("split in_in: %d exceed the acceptable range.\n", 568 dflow->in_w); 569 return -EINVAL; 570 } 571 572 c_st = komeda_component_get_state_and_set_user(&splitter->base, 573 conn_st->state, conn_st->connector, conn_st->crtc); 574 575 if (IS_ERR(c_st)) 576 return PTR_ERR(c_st); 577 578 komeda_split_data_flow(splitter->base.pipeline->scalers[0], 579 dflow, l_output, r_output); 580 581 st = to_splitter_st(c_st); 582 st->hsize = dflow->in_w; 583 st->vsize = dflow->in_h; 584 st->overlap = dflow->overlap; 585 586 komeda_component_add_input(&st->base, &dflow->input, 0); 587 komeda_component_set_output(&l_output->input, &splitter->base, 0); 588 komeda_component_set_output(&r_output->input, &splitter->base, 1); 589 590 return 0; 591 } 592 593 static int 594 komeda_merger_validate(struct komeda_merger *merger, 595 void *user, 596 struct komeda_crtc_state *kcrtc_st, 597 struct komeda_data_flow_cfg *left_input, 598 struct komeda_data_flow_cfg *right_input, 599 struct komeda_data_flow_cfg *output) 600 { 601 struct komeda_component_state *c_st; 602 struct komeda_merger_state *st; 603 int err = 0; 604 605 if (!merger) { 606 DRM_DEBUG_ATOMIC("No merger is available"); 607 return -EINVAL; 608 } 609 610 if (!in_range(&merger->hsize_merged, output->out_w)) { 611 DRM_DEBUG_ATOMIC("merged_w: %d is out of the accepted range.\n", 612 output->out_w); 613 return -EINVAL; 614 } 615 616 if (!in_range(&merger->vsize_merged, output->out_h)) { 617 DRM_DEBUG_ATOMIC("merged_h: %d is out of the accepted range.\n", 618 output->out_h); 619 return -EINVAL; 620 } 621 622 c_st = komeda_component_get_state_and_set_user(&merger->base, 623 kcrtc_st->base.state, kcrtc_st->base.crtc, kcrtc_st->base.crtc); 624 625 if (IS_ERR(c_st)) 626 return PTR_ERR(c_st); 627 628 st = to_merger_st(c_st); 629 st->hsize_merged = output->out_w; 630 st->vsize_merged = output->out_h; 631 632 komeda_component_add_input(c_st, &left_input->input, 0); 633 komeda_component_add_input(c_st, &right_input->input, 1); 634 komeda_component_set_output(&output->input, &merger->base, 0); 635 636 return err; 637 } 638 639 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st, 640 u16 *hsize, u16 *vsize) 641 { 642 struct drm_display_mode *m = &kcrtc_st->base.adjusted_mode; 643 644 if (hsize) 645 *hsize = m->hdisplay; 646 if (vsize) 647 *vsize = m->vdisplay; 648 } 649 650 static int 651 komeda_compiz_set_input(struct komeda_compiz *compiz, 652 struct komeda_crtc_state *kcrtc_st, 653 struct komeda_data_flow_cfg *dflow) 654 { 655 struct drm_atomic_state *drm_st = kcrtc_st->base.state; 656 struct komeda_component_state *c_st, *old_st; 657 struct komeda_compiz_input_cfg *cin; 658 u16 compiz_w, compiz_h; 659 int idx = dflow->blending_zorder; 660 661 pipeline_composition_size(kcrtc_st, &compiz_w, &compiz_h); 662 /* check display rect */ 663 if ((dflow->out_x + dflow->out_w > compiz_w) || 664 (dflow->out_y + dflow->out_h > compiz_h) || 665 dflow->out_w == 0 || dflow->out_h == 0) { 666 DRM_DEBUG_ATOMIC("invalid disp rect [x=%d, y=%d, w=%d, h=%d]\n", 667 dflow->out_x, dflow->out_y, 668 dflow->out_w, dflow->out_h); 669 return -EINVAL; 670 } 671 672 c_st = komeda_component_get_state_and_set_user(&compiz->base, drm_st, 673 kcrtc_st->base.crtc, kcrtc_st->base.crtc); 674 if (IS_ERR(c_st)) 675 return PTR_ERR(c_st); 676 677 if (komeda_component_check_input(c_st, &dflow->input, idx)) 678 return -EINVAL; 679 680 cin = &(to_compiz_st(c_st)->cins[idx]); 681 682 cin->hsize = dflow->out_w; 683 cin->vsize = dflow->out_h; 684 cin->hoffset = dflow->out_x; 685 cin->voffset = dflow->out_y; 686 cin->pixel_blend_mode = dflow->pixel_blend_mode; 687 cin->layer_alpha = dflow->layer_alpha; 688 689 old_st = komeda_component_get_old_state(&compiz->base, drm_st); 690 WARN_ON(!old_st); 691 692 /* compare with old to check if this input has been changed */ 693 if (memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin))) 694 c_st->changed_active_inputs |= BIT(idx); 695 696 komeda_component_add_input(c_st, &dflow->input, idx); 697 komeda_component_set_output(&dflow->input, &compiz->base, 0); 698 699 return 0; 700 } 701 702 static int 703 komeda_compiz_validate(struct komeda_compiz *compiz, 704 struct komeda_crtc_state *state, 705 struct komeda_data_flow_cfg *dflow) 706 { 707 struct komeda_component_state *c_st; 708 struct komeda_compiz_state *st; 709 710 c_st = komeda_component_get_state_and_set_user(&compiz->base, 711 state->base.state, state->base.crtc, state->base.crtc); 712 if (IS_ERR(c_st)) 713 return PTR_ERR(c_st); 714 715 st = to_compiz_st(c_st); 716 717 pipeline_composition_size(state, &st->hsize, &st->vsize); 718 719 komeda_component_set_output(&dflow->input, &compiz->base, 0); 720 721 /* compiz output dflow will be fed to the next pipeline stage, prepare 722 * the data flow configuration for the next stage 723 */ 724 if (dflow) { 725 dflow->in_w = st->hsize; 726 dflow->in_h = st->vsize; 727 dflow->out_w = dflow->in_w; 728 dflow->out_h = dflow->in_h; 729 /* the output data of compiz doesn't have alpha, it only can be 730 * used as bottom layer when blend it with master layers 731 */ 732 dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE; 733 dflow->layer_alpha = 0xFF; 734 dflow->blending_zorder = 0; 735 } 736 737 return 0; 738 } 739 740 static int 741 komeda_improc_validate(struct komeda_improc *improc, 742 struct komeda_crtc_state *kcrtc_st, 743 struct komeda_data_flow_cfg *dflow) 744 { 745 struct drm_crtc *crtc = kcrtc_st->base.crtc; 746 struct komeda_component_state *c_st; 747 struct komeda_improc_state *st; 748 749 c_st = komeda_component_get_state_and_set_user(&improc->base, 750 kcrtc_st->base.state, crtc, crtc); 751 if (IS_ERR(c_st)) 752 return PTR_ERR(c_st); 753 754 st = to_improc_st(c_st); 755 756 st->hsize = dflow->in_w; 757 st->vsize = dflow->in_h; 758 759 komeda_component_add_input(&st->base, &dflow->input, 0); 760 komeda_component_set_output(&dflow->input, &improc->base, 0); 761 762 return 0; 763 } 764 765 static int 766 komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr, 767 struct komeda_crtc_state *kcrtc_st, 768 struct komeda_data_flow_cfg *dflow) 769 { 770 struct drm_crtc *crtc = kcrtc_st->base.crtc; 771 struct komeda_timing_ctrlr_state *st; 772 struct komeda_component_state *c_st; 773 774 c_st = komeda_component_get_state_and_set_user(&ctrlr->base, 775 kcrtc_st->base.state, crtc, crtc); 776 if (IS_ERR(c_st)) 777 return PTR_ERR(c_st); 778 779 st = to_ctrlr_st(c_st); 780 781 komeda_component_add_input(&st->base, &dflow->input, 0); 782 komeda_component_set_output(&dflow->input, &ctrlr->base, 0); 783 784 return 0; 785 } 786 787 void komeda_complete_data_flow_cfg(struct komeda_layer *layer, 788 struct komeda_data_flow_cfg *dflow, 789 struct drm_framebuffer *fb) 790 { 791 struct komeda_scaler *scaler = layer->base.pipeline->scalers[0]; 792 u32 w = dflow->in_w; 793 u32 h = dflow->in_h; 794 795 dflow->total_in_w = dflow->in_w; 796 dflow->total_in_h = dflow->in_h; 797 dflow->total_out_w = dflow->out_w; 798 799 /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */ 800 if (!fb->format->has_alpha) 801 dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE; 802 803 if (drm_rotation_90_or_270(dflow->rot)) 804 swap(w, h); 805 806 dflow->en_scaling = (w != dflow->out_w) || (h != dflow->out_h); 807 dflow->is_yuv = fb->format->is_yuv; 808 809 /* try to enable image enhancer if data flow is a 2x+ upscaling */ 810 dflow->en_img_enhancement = dflow->out_w >= 2 * w || 811 dflow->out_h >= 2 * h; 812 813 /* try to enable split if scaling exceed the scaler's acceptable 814 * input/output range. 815 */ 816 if (dflow->en_scaling && scaler) 817 dflow->en_split = !in_range(&scaler->hsize, dflow->in_w) || 818 !in_range(&scaler->hsize, dflow->out_w); 819 } 820 821 static bool merger_is_available(struct komeda_pipeline *pipe, 822 struct komeda_data_flow_cfg *dflow) 823 { 824 u32 avail_inputs = pipe->merger ? 825 pipe->merger->base.supported_inputs : 0; 826 827 return has_bit(dflow->input.component->id, avail_inputs); 828 } 829 830 int komeda_build_layer_data_flow(struct komeda_layer *layer, 831 struct komeda_plane_state *kplane_st, 832 struct komeda_crtc_state *kcrtc_st, 833 struct komeda_data_flow_cfg *dflow) 834 { 835 struct drm_plane *plane = kplane_st->base.plane; 836 struct komeda_pipeline *pipe = layer->base.pipeline; 837 int err; 838 839 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]", 840 layer->base.name, plane->base.id, plane->name, 841 dflow->in_x, dflow->in_y, dflow->in_w, dflow->in_h, 842 dflow->out_x, dflow->out_y, dflow->out_w, dflow->out_h); 843 844 err = komeda_layer_validate(layer, kplane_st, dflow); 845 if (err) 846 return err; 847 848 err = komeda_scaler_validate(plane, kcrtc_st, dflow); 849 if (err) 850 return err; 851 852 /* if split, check if can put the data flow into merger */ 853 if (dflow->en_split && merger_is_available(pipe, dflow)) 854 return 0; 855 856 err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow); 857 858 return err; 859 } 860 861 /* 862 * Split is introduced for workaround scaler's input/output size limitation. 863 * The idea is simple, if one scaler can not fit the requirement, use two. 864 * So split splits the big source image to two half parts (left/right) and do 865 * the scaling by two scaler separately and independently. 866 * But split also imports an edge problem in the middle of the image when 867 * scaling, to avoid it, split isn't a simple half-and-half, but add an extra 868 * pixels (overlap) to both side, after split the left/right will be: 869 * - left: [0, src_length/2 + overlap] 870 * - right: [src_length/2 - overlap, src_length] 871 * The extra overlap do eliminate the edge problem, but which may also generates 872 * unnecessary pixels when scaling, we need to crop them before scaler output 873 * the result to the next stage. and for the how to crop, it depends on the 874 * unneeded pixels, another words the position where overlay has been added. 875 * - left: crop the right 876 * - right: crop the left 877 * 878 * The diagram for how to do the split 879 * 880 * <---------------------left->out_w ----------------> 881 * |--------------------------------|---right_crop-----| <- left after split 882 * \ \ / 883 * \ \<--overlap--->/ 884 * |-----------------|-------------|(Middle)------|-----------------| <- src 885 * /<---overlap--->\ \ 886 * / \ \ 887 * right after split->|-----left_crop---|--------------------------------| 888 * ^<------------------- right->out_w --------------->^ 889 * 890 * NOTE: To consistent with HW the output_w always contains the crop size. 891 */ 892 893 static void komeda_split_data_flow(struct komeda_scaler *scaler, 894 struct komeda_data_flow_cfg *dflow, 895 struct komeda_data_flow_cfg *l_dflow, 896 struct komeda_data_flow_cfg *r_dflow) 897 { 898 bool r90 = drm_rotation_90_or_270(dflow->rot); 899 bool flip_h = has_flip_h(dflow->rot); 900 u32 l_out, r_out, overlap; 901 902 memcpy(l_dflow, dflow, sizeof(*dflow)); 903 memcpy(r_dflow, dflow, sizeof(*dflow)); 904 905 l_dflow->right_part = false; 906 r_dflow->right_part = true; 907 r_dflow->blending_zorder = dflow->blending_zorder + 1; 908 909 overlap = 0; 910 if (dflow->en_scaling && scaler) 911 overlap += scaler->scaling_split_overlap; 912 913 /* original dflow may fed into splitter, and which doesn't need 914 * enhancement overlap 915 */ 916 dflow->overlap = overlap; 917 918 if (dflow->en_img_enhancement && scaler) 919 overlap += scaler->enh_split_overlap; 920 921 l_dflow->overlap = overlap; 922 r_dflow->overlap = overlap; 923 924 /* split the origin content */ 925 /* left/right here always means the left/right part of display image, 926 * not the source Image 927 */ 928 /* DRM rotation is anti-clockwise */ 929 if (r90) { 930 if (dflow->en_scaling) { 931 l_dflow->in_h = ALIGN(dflow->in_h, 2) / 2 + l_dflow->overlap; 932 r_dflow->in_h = l_dflow->in_h; 933 } else if (dflow->en_img_enhancement) { 934 /* enhancer only */ 935 l_dflow->in_h = ALIGN(dflow->in_h, 2) / 2 + l_dflow->overlap; 936 r_dflow->in_h = dflow->in_h / 2 + r_dflow->overlap; 937 } else { 938 /* split without scaler, no overlap */ 939 l_dflow->in_h = ALIGN(((dflow->in_h + 1) >> 1), 2); 940 r_dflow->in_h = dflow->in_h - l_dflow->in_h; 941 } 942 943 /* Consider YUV format, after split, the split source w/h 944 * may not aligned to 2. we have two choices for such case. 945 * 1. scaler is enabled (overlap != 0), we can do a alignment 946 * both left/right and crop the extra data by scaler. 947 * 2. scaler is not enabled, only align the split left 948 * src/disp, and the rest part assign to right 949 */ 950 if ((overlap != 0) && dflow->is_yuv) { 951 l_dflow->in_h = ALIGN(l_dflow->in_h, 2); 952 r_dflow->in_h = ALIGN(r_dflow->in_h, 2); 953 } 954 955 if (flip_h) 956 l_dflow->in_y = dflow->in_y + dflow->in_h - l_dflow->in_h; 957 else 958 r_dflow->in_y = dflow->in_y + dflow->in_h - r_dflow->in_h; 959 } else { 960 if (dflow->en_scaling) { 961 l_dflow->in_w = ALIGN(dflow->in_w, 2) / 2 + l_dflow->overlap; 962 r_dflow->in_w = l_dflow->in_w; 963 } else if (dflow->en_img_enhancement) { 964 l_dflow->in_w = ALIGN(dflow->in_w, 2) / 2 + l_dflow->overlap; 965 r_dflow->in_w = dflow->in_w / 2 + r_dflow->overlap; 966 } else { 967 l_dflow->in_w = ALIGN(((dflow->in_w + 1) >> 1), 2); 968 r_dflow->in_w = dflow->in_w - l_dflow->in_w; 969 } 970 971 /* do YUV alignment when scaler enabled */ 972 if ((overlap != 0) && dflow->is_yuv) { 973 l_dflow->in_w = ALIGN(l_dflow->in_w, 2); 974 r_dflow->in_w = ALIGN(r_dflow->in_w, 2); 975 } 976 977 /* on flip_h, the left display content from the right-source */ 978 if (flip_h) 979 l_dflow->in_x = dflow->in_w + dflow->in_x - l_dflow->in_w; 980 else 981 r_dflow->in_x = dflow->in_w + dflow->in_x - r_dflow->in_w; 982 } 983 984 /* split the disp_rect */ 985 if (dflow->en_scaling || dflow->en_img_enhancement) 986 l_dflow->out_w = ((dflow->out_w + 1) >> 1); 987 else 988 l_dflow->out_w = ALIGN(((dflow->out_w + 1) >> 1), 2); 989 990 r_dflow->out_w = dflow->out_w - l_dflow->out_w; 991 992 l_dflow->out_x = dflow->out_x; 993 r_dflow->out_x = l_dflow->out_w + l_dflow->out_x; 994 995 /* calculate the scaling crop */ 996 /* left scaler output more data and do crop */ 997 if (r90) { 998 l_out = (dflow->out_w * l_dflow->in_h) / dflow->in_h; 999 r_out = (dflow->out_w * r_dflow->in_h) / dflow->in_h; 1000 } else { 1001 l_out = (dflow->out_w * l_dflow->in_w) / dflow->in_w; 1002 r_out = (dflow->out_w * r_dflow->in_w) / dflow->in_w; 1003 } 1004 1005 l_dflow->left_crop = 0; 1006 l_dflow->right_crop = l_out - l_dflow->out_w; 1007 r_dflow->left_crop = r_out - r_dflow->out_w; 1008 r_dflow->right_crop = 0; 1009 1010 /* out_w includes the crop length */ 1011 l_dflow->out_w += l_dflow->right_crop + l_dflow->left_crop; 1012 r_dflow->out_w += r_dflow->right_crop + r_dflow->left_crop; 1013 } 1014 1015 /* For layer split, a plane state will be split to two data flows and handled 1016 * by two separated komeda layer input pipelines. komeda supports two types of 1017 * layer split: 1018 * - none-scaling split: 1019 * / layer-left -> \ 1020 * plane_state compiz-> ... 1021 * \ layer-right-> / 1022 * 1023 * - scaling split: 1024 * / layer-left -> scaler->\ 1025 * plane_state merger -> compiz-> ... 1026 * \ layer-right-> scaler->/ 1027 * 1028 * Since merger only supports scaler as input, so for none-scaling split, two 1029 * layer data flows will be output to compiz directly. for scaling_split, two 1030 * data flow will be merged by merger firstly, then merger outputs one merged 1031 * data flow to compiz. 1032 */ 1033 int komeda_build_layer_split_data_flow(struct komeda_layer *left, 1034 struct komeda_plane_state *kplane_st, 1035 struct komeda_crtc_state *kcrtc_st, 1036 struct komeda_data_flow_cfg *dflow) 1037 { 1038 struct drm_plane *plane = kplane_st->base.plane; 1039 struct komeda_pipeline *pipe = left->base.pipeline; 1040 struct komeda_layer *right = left->right; 1041 struct komeda_data_flow_cfg l_dflow, r_dflow; 1042 int err; 1043 1044 komeda_split_data_flow(pipe->scalers[0], dflow, &l_dflow, &r_dflow); 1045 1046 DRM_DEBUG_ATOMIC("Assign %s + %s to [PLANE:%d:%s]: " 1047 "src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]", 1048 left->base.name, right->base.name, 1049 plane->base.id, plane->name, 1050 dflow->in_x, dflow->in_y, dflow->in_w, dflow->in_h, 1051 dflow->out_x, dflow->out_y, dflow->out_w, dflow->out_h); 1052 1053 err = komeda_build_layer_data_flow(left, kplane_st, kcrtc_st, &l_dflow); 1054 if (err) 1055 return err; 1056 1057 err = komeda_build_layer_data_flow(right, kplane_st, kcrtc_st, &r_dflow); 1058 if (err) 1059 return err; 1060 1061 /* The rotation has been handled by layer, so adjusted the data flow */ 1062 komeda_rotate_data_flow(dflow, dflow->rot); 1063 1064 /* left and right dflow has been merged to compiz already, 1065 * no need merger to merge them anymore. 1066 */ 1067 if (r_dflow.input.component == l_dflow.input.component) 1068 return 0; 1069 1070 /* line merger path */ 1071 err = komeda_merger_validate(pipe->merger, plane, kcrtc_st, 1072 &l_dflow, &r_dflow, dflow); 1073 if (err) 1074 return err; 1075 1076 err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow); 1077 1078 return err; 1079 } 1080 1081 /* writeback data path: compiz -> scaler -> wb_layer -> memory */ 1082 int komeda_build_wb_data_flow(struct komeda_layer *wb_layer, 1083 struct drm_connector_state *conn_st, 1084 struct komeda_crtc_state *kcrtc_st, 1085 struct komeda_data_flow_cfg *dflow) 1086 { 1087 struct drm_connector *conn = conn_st->connector; 1088 int err; 1089 1090 err = komeda_scaler_validate(conn, kcrtc_st, dflow); 1091 if (err) 1092 return err; 1093 1094 return komeda_wb_layer_validate(wb_layer, conn_st, dflow); 1095 } 1096 1097 /* writeback scaling split data path: 1098 * /-> scaler ->\ 1099 * compiz -> splitter merger -> wb_layer -> memory 1100 * \-> scaler ->/ 1101 */ 1102 int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer, 1103 struct drm_connector_state *conn_st, 1104 struct komeda_crtc_state *kcrtc_st, 1105 struct komeda_data_flow_cfg *dflow) 1106 { 1107 struct komeda_pipeline *pipe = wb_layer->base.pipeline; 1108 struct drm_connector *conn = conn_st->connector; 1109 struct komeda_data_flow_cfg l_dflow, r_dflow; 1110 int err; 1111 1112 err = komeda_splitter_validate(pipe->splitter, conn_st, 1113 dflow, &l_dflow, &r_dflow); 1114 if (err) 1115 return err; 1116 err = komeda_scaler_validate(conn, kcrtc_st, &l_dflow); 1117 if (err) 1118 return err; 1119 1120 err = komeda_scaler_validate(conn, kcrtc_st, &r_dflow); 1121 if (err) 1122 return err; 1123 1124 err = komeda_merger_validate(pipe->merger, conn_st, kcrtc_st, 1125 &l_dflow, &r_dflow, dflow); 1126 if (err) 1127 return err; 1128 1129 return komeda_wb_layer_validate(wb_layer, conn_st, dflow); 1130 } 1131 1132 /* build display output data flow, the data path is: 1133 * compiz -> improc -> timing_ctrlr 1134 */ 1135 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, 1136 struct komeda_crtc_state *kcrtc_st) 1137 { 1138 struct komeda_pipeline *master = kcrtc->master; 1139 struct komeda_pipeline *slave = kcrtc->slave; 1140 struct komeda_data_flow_cfg m_dflow; /* master data flow */ 1141 struct komeda_data_flow_cfg s_dflow; /* slave data flow */ 1142 int err; 1143 1144 memset(&m_dflow, 0, sizeof(m_dflow)); 1145 memset(&s_dflow, 0, sizeof(s_dflow)); 1146 1147 if (slave && has_bit(slave->id, kcrtc_st->active_pipes)) { 1148 err = komeda_compiz_validate(slave->compiz, kcrtc_st, &s_dflow); 1149 if (err) 1150 return err; 1151 1152 /* merge the slave dflow into master pipeline */ 1153 err = komeda_compiz_set_input(master->compiz, kcrtc_st, 1154 &s_dflow); 1155 if (err) 1156 return err; 1157 } 1158 1159 err = komeda_compiz_validate(master->compiz, kcrtc_st, &m_dflow); 1160 if (err) 1161 return err; 1162 1163 err = komeda_improc_validate(master->improc, kcrtc_st, &m_dflow); 1164 if (err) 1165 return err; 1166 1167 err = komeda_timing_ctrlr_validate(master->ctrlr, kcrtc_st, &m_dflow); 1168 if (err) 1169 return err; 1170 1171 return 0; 1172 } 1173 1174 static void 1175 komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, 1176 struct komeda_pipeline_state *new) 1177 { 1178 struct drm_atomic_state *drm_st = new->obj.state; 1179 struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); 1180 struct komeda_component_state *c_st; 1181 struct komeda_component *c; 1182 u32 disabling_comps, id; 1183 1184 WARN_ON(!old); 1185 1186 disabling_comps = (~new->active_comps) & old->active_comps; 1187 1188 /* unbound all disabling component */ 1189 dp_for_each_set_bit(id, disabling_comps) { 1190 c = komeda_pipeline_get_component(pipe, id); 1191 c_st = komeda_component_get_state_and_set_user(c, 1192 drm_st, NULL, new->crtc); 1193 WARN_ON(IS_ERR(c_st)); 1194 } 1195 } 1196 1197 /* release unclaimed pipeline resource */ 1198 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, 1199 struct komeda_crtc_state *kcrtc_st) 1200 { 1201 struct drm_atomic_state *drm_st = kcrtc_st->base.state; 1202 struct komeda_pipeline_state *st; 1203 1204 /* ignore the pipeline which is not affected */ 1205 if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes)) 1206 return 0; 1207 1208 if (has_bit(pipe->id, kcrtc_st->active_pipes)) 1209 st = komeda_pipeline_get_new_state(pipe, drm_st); 1210 else 1211 st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL); 1212 1213 if (WARN_ON(IS_ERR_OR_NULL(st))) 1214 return -EINVAL; 1215 1216 komeda_pipeline_unbound_components(pipe, st); 1217 1218 return 0; 1219 } 1220 1221 void komeda_pipeline_disable(struct komeda_pipeline *pipe, 1222 struct drm_atomic_state *old_state) 1223 { 1224 struct komeda_pipeline_state *old; 1225 struct komeda_component *c; 1226 struct komeda_component_state *c_st; 1227 u32 id, disabling_comps = 0; 1228 1229 old = komeda_pipeline_get_old_state(pipe, old_state); 1230 1231 disabling_comps = old->active_comps; 1232 DRM_DEBUG_ATOMIC("PIPE%d: disabling_comps: 0x%x.\n", 1233 pipe->id, disabling_comps); 1234 1235 dp_for_each_set_bit(id, disabling_comps) { 1236 c = komeda_pipeline_get_component(pipe, id); 1237 c_st = priv_to_comp_st(c->obj.state); 1238 1239 /* 1240 * If we disabled a component then all active_inputs should be 1241 * put in the list of changed_active_inputs, so they get 1242 * re-enabled. 1243 * This usually happens during a modeset when the pipeline is 1244 * first disabled and then the actual state gets committed 1245 * again. 1246 */ 1247 c_st->changed_active_inputs |= c_st->active_inputs; 1248 1249 c->funcs->disable(c); 1250 } 1251 } 1252 1253 void komeda_pipeline_update(struct komeda_pipeline *pipe, 1254 struct drm_atomic_state *old_state) 1255 { 1256 struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state); 1257 struct komeda_pipeline_state *old; 1258 struct komeda_component *c; 1259 u32 id, changed_comps = 0; 1260 1261 old = komeda_pipeline_get_old_state(pipe, old_state); 1262 1263 changed_comps = new->active_comps | old->active_comps; 1264 1265 DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n", 1266 pipe->id, new->active_comps, changed_comps); 1267 1268 dp_for_each_set_bit(id, changed_comps) { 1269 c = komeda_pipeline_get_component(pipe, id); 1270 1271 if (new->active_comps & BIT(c->id)) 1272 c->funcs->update(c, priv_to_comp_st(c->obj.state)); 1273 else 1274 c->funcs->disable(c); 1275 } 1276 } 1277