This source file includes following definitions.
- is_switching_user
- komeda_pipeline_get_state
- komeda_pipeline_get_old_state
- komeda_pipeline_get_new_state
- komeda_pipeline_get_state_and_set_crtc
- komeda_component_get_state
- komeda_component_get_old_state
- komeda_component_get_state_and_set_user
- komeda_component_add_input
- komeda_component_check_input
- komeda_component_set_output
- komeda_component_validate_private
- komeda_component_get_avail_scaler
- komeda_rotate_data_flow
- komeda_layer_check_cfg
- komeda_layer_validate
- komeda_wb_layer_validate
- scaling_ratio_valid
- komeda_scaler_check_cfg
- komeda_scaler_validate
- komeda_splitter_validate
- komeda_merger_validate
- pipeline_composition_size
- komeda_compiz_set_input
- komeda_compiz_validate
- komeda_improc_validate
- komeda_timing_ctrlr_validate
- komeda_complete_data_flow_cfg
- merger_is_available
- komeda_build_layer_data_flow
- komeda_split_data_flow
- komeda_build_layer_split_data_flow
- komeda_build_wb_data_flow
- komeda_build_wb_split_data_flow
- komeda_build_display_data_flow
- komeda_pipeline_unbound_components
- komeda_release_unclaimed_resources
- komeda_pipeline_disable
- komeda_pipeline_update
   1 
   2 
   3 
   4 
   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 
  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         
  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 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 
 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         
 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         
 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         
 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         
 193 
 194 
 195 
 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 
 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         
 370         komeda_component_set_output(&dflow->input, &layer->base, 0);
 371 
 372         
 373 
 374 
 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         
 451 
 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_crtc_get_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         
 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_h: %d exceeds the acceptable range.\n",
 568                                  dflow->in_h);
 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         
 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         
 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         
 722 
 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                 
 730 
 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         
 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         
 810         dflow->en_img_enhancement = dflow->out_w >= 2 * w ||
 811                                     dflow->out_h >= 2 * h;
 812 
 813         
 814 
 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         
 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 
 863 
 864 
 865 
 866 
 867 
 868 
 869 
 870 
 871 
 872 
 873 
 874 
 875 
 876 
 877 
 878 
 879 
 880 
 881 
 882 
 883 
 884 
 885 
 886 
 887 
 888 
 889 
 890 
 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         
 914 
 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         
 925         
 926 
 927 
 928         
 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                         
 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                         
 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                 
 944 
 945 
 946 
 947 
 948 
 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                 
 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                 
 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         
 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         
 996         
 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         
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 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 
1030 
1031 
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         
1062         komeda_rotate_data_flow(dflow, dflow->rot);
1063 
1064         
1065 
1066 
1067         if (r_dflow.input.component == l_dflow.input.component)
1068                 return 0;
1069 
1070         
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 
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 
1098 
1099 
1100 
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 
1133 
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; 
1141         struct komeda_data_flow_cfg s_dflow; 
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                 
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         
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 
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         
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 
1241 
1242 
1243 
1244 
1245 
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 }