Lines Matching +full:decimation +full:- +full:ratio
1 // SPDX-License-Identifier: GPL-2.0-only
264 return state->fb && !WARN_ON(!state->crtc); in plane_enabled()
271 if (WARN_ON(!plane->state)) in vc4_plane_duplicate_state()
274 vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL); in vc4_plane_duplicate_state()
278 memset(&vc4_state->lbm, 0, sizeof(vc4_state->lbm)); in vc4_plane_duplicate_state()
279 vc4_state->dlist_initialized = 0; in vc4_plane_duplicate_state()
281 __drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base); in vc4_plane_duplicate_state()
283 if (vc4_state->dlist) { in vc4_plane_duplicate_state()
284 vc4_state->dlist = kmemdup(vc4_state->dlist, in vc4_plane_duplicate_state()
285 vc4_state->dlist_count * 4, in vc4_plane_duplicate_state()
287 if (!vc4_state->dlist) { in vc4_plane_duplicate_state()
291 vc4_state->dlist_size = vc4_state->dlist_count; in vc4_plane_duplicate_state()
294 return &vc4_state->base; in vc4_plane_duplicate_state()
300 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_destroy_state()
303 if (drm_mm_node_allocated(&vc4_state->lbm)) { in vc4_plane_destroy_state()
306 spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags); in vc4_plane_destroy_state()
307 drm_mm_remove_node(&vc4_state->lbm); in vc4_plane_destroy_state()
308 spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); in vc4_plane_destroy_state()
311 kfree(vc4_state->dlist); in vc4_plane_destroy_state()
312 __drm_atomic_helper_plane_destroy_state(&vc4_state->base); in vc4_plane_destroy_state()
321 WARN_ON(plane->state); in vc4_plane_reset()
327 __drm_atomic_helper_plane_reset(plane, &vc4_state->base); in vc4_plane_reset()
332 if (vc4_state->dlist_count == vc4_state->dlist_size) { in vc4_dlist_counter_increment()
333 u32 new_size = max(4u, vc4_state->dlist_count * 2); in vc4_dlist_counter_increment()
338 memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4); in vc4_dlist_counter_increment()
340 kfree(vc4_state->dlist); in vc4_dlist_counter_increment()
341 vc4_state->dlist = new_dlist; in vc4_dlist_counter_increment()
342 vc4_state->dlist_size = new_size; in vc4_dlist_counter_increment()
345 vc4_state->dlist_count++; in vc4_dlist_counter_increment()
350 unsigned int idx = vc4_state->dlist_count; in vc4_dlist_write()
353 vc4_state->dlist[idx] = val; in vc4_dlist_write()
357 * be up/down/non-scaled.
365 switch (vc4_state->x_scaling[plane] << 2 | vc4_state->y_scaling[plane]) { in vc4_get_scl_field()
397 crtc_state = drm_atomic_get_new_crtc_state(pstate->state, in vc4_plane_margins_adj()
398 pstate->crtc); in vc4_plane_margins_adj()
404 if (left + right >= crtc_state->mode.hdisplay || in vc4_plane_margins_adj()
405 top + bottom >= crtc_state->mode.vdisplay) in vc4_plane_margins_adj()
406 return -EINVAL; in vc4_plane_margins_adj()
408 adjhdisplay = crtc_state->mode.hdisplay - (left + right); in vc4_plane_margins_adj()
409 vc4_pstate->crtc_x = DIV_ROUND_CLOSEST(vc4_pstate->crtc_x * in vc4_plane_margins_adj()
411 crtc_state->mode.hdisplay); in vc4_plane_margins_adj()
412 vc4_pstate->crtc_x += left; in vc4_plane_margins_adj()
413 if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right) in vc4_plane_margins_adj()
414 vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right; in vc4_plane_margins_adj()
416 adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); in vc4_plane_margins_adj()
417 vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * in vc4_plane_margins_adj()
419 crtc_state->mode.vdisplay); in vc4_plane_margins_adj()
420 vc4_pstate->crtc_y += top; in vc4_plane_margins_adj()
421 if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom) in vc4_plane_margins_adj()
422 vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom; in vc4_plane_margins_adj()
424 vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * in vc4_plane_margins_adj()
426 crtc_state->mode.hdisplay); in vc4_plane_margins_adj()
427 vc4_pstate->crtc_h = DIV_ROUND_CLOSEST(vc4_pstate->crtc_h * in vc4_plane_margins_adj()
429 crtc_state->mode.vdisplay); in vc4_plane_margins_adj()
431 if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h) in vc4_plane_margins_adj()
432 return -EINVAL; in vc4_plane_margins_adj()
440 struct drm_framebuffer *fb = state->fb; in vc4_plane_setup_clipping_and_scaling()
442 int num_planes = fb->format->num_planes; in vc4_plane_setup_clipping_and_scaling()
444 u32 h_subsample = fb->format->hsub; in vc4_plane_setup_clipping_and_scaling()
445 u32 v_subsample = fb->format->vsub; in vc4_plane_setup_clipping_and_scaling()
448 crtc_state = drm_atomic_get_existing_crtc_state(state->state, in vc4_plane_setup_clipping_and_scaling()
449 state->crtc); in vc4_plane_setup_clipping_and_scaling()
452 return -EINVAL; in vc4_plane_setup_clipping_and_scaling()
462 vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i]; in vc4_plane_setup_clipping_and_scaling()
470 vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16); in vc4_plane_setup_clipping_and_scaling()
471 vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16); in vc4_plane_setup_clipping_and_scaling()
472 vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x; in vc4_plane_setup_clipping_and_scaling()
473 vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y; in vc4_plane_setup_clipping_and_scaling()
475 vc4_state->crtc_x = state->dst.x1; in vc4_plane_setup_clipping_and_scaling()
476 vc4_state->crtc_y = state->dst.y1; in vc4_plane_setup_clipping_and_scaling()
477 vc4_state->crtc_w = state->dst.x2 - state->dst.x1; in vc4_plane_setup_clipping_and_scaling()
478 vc4_state->crtc_h = state->dst.y2 - state->dst.y1; in vc4_plane_setup_clipping_and_scaling()
484 vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0], in vc4_plane_setup_clipping_and_scaling()
485 vc4_state->crtc_w); in vc4_plane_setup_clipping_and_scaling()
486 vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0], in vc4_plane_setup_clipping_and_scaling()
487 vc4_state->crtc_h); in vc4_plane_setup_clipping_and_scaling()
489 vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE && in vc4_plane_setup_clipping_and_scaling()
490 vc4_state->y_scaling[0] == VC4_SCALING_NONE); in vc4_plane_setup_clipping_and_scaling()
493 vc4_state->is_yuv = true; in vc4_plane_setup_clipping_and_scaling()
495 vc4_state->src_w[1] = vc4_state->src_w[0] / h_subsample; in vc4_plane_setup_clipping_and_scaling()
496 vc4_state->src_h[1] = vc4_state->src_h[0] / v_subsample; in vc4_plane_setup_clipping_and_scaling()
498 vc4_state->x_scaling[1] = in vc4_plane_setup_clipping_and_scaling()
499 vc4_get_scaling_mode(vc4_state->src_w[1], in vc4_plane_setup_clipping_and_scaling()
500 vc4_state->crtc_w); in vc4_plane_setup_clipping_and_scaling()
501 vc4_state->y_scaling[1] = in vc4_plane_setup_clipping_and_scaling()
502 vc4_get_scaling_mode(vc4_state->src_h[1], in vc4_plane_setup_clipping_and_scaling()
503 vc4_state->crtc_h); in vc4_plane_setup_clipping_and_scaling()
507 * VC4_SCALING_NONE (which can happen when the down-scaling in vc4_plane_setup_clipping_and_scaling()
508 * ratio is 0.5). Let's force it to VC4_SCALING_PPF in this in vc4_plane_setup_clipping_and_scaling()
511 if (vc4_state->x_scaling[1] == VC4_SCALING_NONE) in vc4_plane_setup_clipping_and_scaling()
512 vc4_state->x_scaling[1] = VC4_SCALING_PPF; in vc4_plane_setup_clipping_and_scaling()
514 vc4_state->is_yuv = false; in vc4_plane_setup_clipping_and_scaling()
515 vc4_state->x_scaling[1] = VC4_SCALING_NONE; in vc4_plane_setup_clipping_and_scaling()
516 vc4_state->y_scaling[1] = VC4_SCALING_NONE; in vc4_plane_setup_clipping_and_scaling()
553 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in vc4_lbm_size()
558 if (vc4_state->y_scaling[0] == VC4_SCALING_NONE && in vc4_lbm_size()
559 vc4_state->y_scaling[1] == VC4_SCALING_NONE) in vc4_lbm_size()
564 * decimation factor is between 0.5 and 1.0 by using crtc_w. in vc4_lbm_size()
569 if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ) in vc4_lbm_size()
570 pix_per_line = vc4_state->crtc_w; in vc4_lbm_size()
572 pix_per_line = vc4_state->src_w[0]; in vc4_lbm_size()
574 if (!vc4_state->is_yuv) { in vc4_lbm_size()
575 if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ) in vc4_lbm_size()
590 lbm = roundup(lbm, vc4->is_vc5 ? 128 : 64); in vc4_lbm_size()
593 lbm /= vc4->is_vc5 ? 4 : 2; in vc4_lbm_size()
603 /* Ch0 H-PPF Word 0: Scaling Parameters */ in vc4_write_scaling_parameters()
604 if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) { in vc4_write_scaling_parameters()
606 vc4_state->src_w[channel], vc4_state->crtc_w); in vc4_write_scaling_parameters()
609 /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */ in vc4_write_scaling_parameters()
610 if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) { in vc4_write_scaling_parameters()
612 vc4_state->src_h[channel], vc4_state->crtc_h); in vc4_write_scaling_parameters()
616 /* Ch0 H-TPZ Words 0-1: Scaling Parameters, Recip */ in vc4_write_scaling_parameters()
617 if (vc4_state->x_scaling[channel] == VC4_SCALING_TPZ) { in vc4_write_scaling_parameters()
619 vc4_state->src_w[channel], vc4_state->crtc_w); in vc4_write_scaling_parameters()
622 /* Ch0 V-TPZ Words 0-2: Scaling Parameters, Recip, Context */ in vc4_write_scaling_parameters()
623 if (vc4_state->y_scaling[channel] == VC4_SCALING_TPZ) { in vc4_write_scaling_parameters()
625 vc4_state->src_h[channel], vc4_state->crtc_h); in vc4_write_scaling_parameters()
633 struct drm_framebuffer *fb = state->fb; in vc4_plane_calc_load()
639 crtc_state = drm_atomic_get_existing_crtc_state(state->state, in vc4_plane_calc_load()
640 state->crtc); in vc4_plane_calc_load()
641 vrefresh = drm_mode_vrefresh(&crtc_state->adjusted_mode); in vc4_plane_calc_load()
648 * HVS load is expressed in clk-cycles/sec (AKA Hz). in vc4_plane_calc_load()
650 if (vc4_state->x_scaling[0] != VC4_SCALING_NONE || in vc4_plane_calc_load()
651 vc4_state->x_scaling[1] != VC4_SCALING_NONE || in vc4_plane_calc_load()
652 vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_calc_load()
653 vc4_state->y_scaling[1] != VC4_SCALING_NONE) in vc4_plane_calc_load()
658 vc4_state->membus_load = 0; in vc4_plane_calc_load()
659 vc4_state->hvs_load = 0; in vc4_plane_calc_load()
660 for (i = 0; i < fb->format->num_planes; i++) { in vc4_plane_calc_load()
663 * vc4_state->src_w[i] * vc4_state->src_h[i] * cpp * vrefresh in vc4_plane_calc_load()
668 * calculate the down-scaling factor and multiply the plane in vc4_plane_calc_load()
669 * load by this number. We're likely over-estimating the read in vc4_plane_calc_load()
670 * demand, but that's better than under-estimating it. in vc4_plane_calc_load()
672 vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i], in vc4_plane_calc_load()
673 vc4_state->crtc_h); in vc4_plane_calc_load()
674 vc4_state->membus_load += vc4_state->src_w[i] * in vc4_plane_calc_load()
675 vc4_state->src_h[i] * vscale_factor * in vc4_plane_calc_load()
676 fb->format->cpp[i]; in vc4_plane_calc_load()
677 vc4_state->hvs_load += vc4_state->crtc_h * vc4_state->crtc_w; in vc4_plane_calc_load()
680 vc4_state->hvs_load *= vrefresh; in vc4_plane_calc_load()
681 vc4_state->hvs_load >>= hvs_load_shift; in vc4_plane_calc_load()
682 vc4_state->membus_load *= vrefresh; in vc4_plane_calc_load()
687 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in vc4_plane_allocate_lbm()
696 if (WARN_ON(!vc4_state->lbm_offset)) in vc4_plane_allocate_lbm()
697 return -EINVAL; in vc4_plane_allocate_lbm()
702 if (!drm_mm_node_allocated(&vc4_state->lbm)) { in vc4_plane_allocate_lbm()
705 spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags); in vc4_plane_allocate_lbm()
706 ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, in vc4_plane_allocate_lbm()
707 &vc4_state->lbm, in vc4_plane_allocate_lbm()
709 vc4->is_vc5 ? 64 : 32, in vc4_plane_allocate_lbm()
711 spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); in vc4_plane_allocate_lbm()
716 WARN_ON_ONCE(lbm_size != vc4_state->lbm.size); in vc4_plane_allocate_lbm()
719 vc4_state->dlist[vc4_state->lbm_offset] = vc4_state->lbm.start; in vc4_plane_allocate_lbm()
771 if (!state->fb->format->has_alpha) in vc4_hvs4_get_alpha_blend_mode()
775 switch (state->pixel_blend_mode) { in vc4_hvs4_get_alpha_blend_mode()
792 if (!state->fb->format->has_alpha) in vc4_hvs5_get_alpha_blend_mode()
796 switch (state->pixel_blend_mode) { in vc4_hvs5_get_alpha_blend_mode()
817 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_mode_set()
819 struct drm_framebuffer *fb = state->fb; in vc4_plane_mode_set()
820 u32 ctl0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
821 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); in vc4_plane_mode_set()
822 u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); in vc4_plane_mode_set()
823 int num_planes = fb->format->num_planes; in vc4_plane_mode_set()
824 u32 h_subsample = fb->format->hsub; in vc4_plane_mode_set()
825 u32 v_subsample = fb->format->vsub; in vc4_plane_mode_set()
830 u32 hvs_format = format->hvs; in vc4_plane_mode_set()
834 if (vc4_state->dlist_initialized) in vc4_plane_mode_set()
855 rotation = drm_rotation_simplify(state->rotation, in vc4_plane_mode_set()
861 src_y = vc4_state->src_y; in vc4_plane_mode_set()
863 src_y += vc4_state->src_h[0] - 1; in vc4_plane_mode_set()
868 pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); in vc4_plane_mode_set()
874 vc4_state->offsets[i] += src_y / in vc4_plane_mode_set()
876 fb->pitches[i]; in vc4_plane_mode_set()
878 vc4_state->offsets[i] += vc4_state->src_x / in vc4_plane_mode_set()
880 fb->format->cpp[i]; in vc4_plane_mode_set()
887 /* Whole-tile offsets, mostly for setting the pitch. */ in vc4_plane_mode_set()
888 u32 tile_w_shift = fb->format->cpp[0] == 2 ? 6 : 5; in vc4_plane_mode_set()
890 u32 tile_w_mask = (1 << tile_w_shift) - 1; in vc4_plane_mode_set()
891 /* The height mask on 32-bit-per-pixel tiles is 63, i.e. twice in vc4_plane_mode_set()
894 u32 tile_h_mask = (2 << tile_h_shift) - 1; in vc4_plane_mode_set()
895 /* For T-tiled, the FB pitch is "how many bytes from one row to in vc4_plane_mode_set()
900 u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift); in vc4_plane_mode_set()
901 u32 tiles_l = vc4_state->src_x >> tile_w_shift; in vc4_plane_mode_set()
902 u32 tiles_r = tiles_w - tiles_l; in vc4_plane_mode_set()
904 /* Intra-tile offsets, which modify the base address (the in vc4_plane_mode_set()
911 u32 x_off = vc4_state->src_x & tile_w_mask; in vc4_plane_mode_set()
919 * Don't know why we need y_off = max_y_off - y_off, but it's in vc4_plane_mode_set()
924 y_off = tile_h_mask - y_off; in vc4_plane_mode_set()
935 vc4_state->offsets[0] += tiles_t * (tiles_w << tile_size_shift); in vc4_plane_mode_set()
936 vc4_state->offsets[0] += subtile_y << 8; in vc4_plane_mode_set()
937 vc4_state->offsets[0] += utile_y << 4; in vc4_plane_mode_set()
939 /* Rows of tiles alternate left-to-right and right-to-left. */ in vc4_plane_mode_set()
942 vc4_state->offsets[0] += (tiles_w - tiles_l) << in vc4_plane_mode_set()
944 vc4_state->offsets[0] -= (1 + !tile_y) << 10; in vc4_plane_mode_set()
946 vc4_state->offsets[0] += tiles_l << tile_size_shift; in vc4_plane_mode_set()
947 vc4_state->offsets[0] += tile_y << 10; in vc4_plane_mode_set()
956 uint32_t param = fourcc_mod_broadcom_param(fb->modifier); in vc4_plane_mode_set()
961 return -EINVAL; in vc4_plane_mode_set()
964 if (fb->format->format == DRM_FORMAT_P030) { in vc4_plane_mode_set()
981 return -EINVAL; in vc4_plane_mode_set()
989 * y_ptr [3:0] is the pixel (0-11) contained within that 128bit in vc4_plane_mode_set()
998 if (fb->format->format == DRM_FORMAT_P030) { in vc4_plane_mode_set()
1001 * should point to the 128-bit word containing in vc4_plane_mode_set()
1004 * of the 12-pixels in that 128-bit word is the in vc4_plane_mode_set()
1007 u32 remaining_pixels = vc4_state->src_x % 96; in vc4_plane_mode_set()
1026 return -EINVAL; in vc4_plane_mode_set()
1028 pix_per_tile = tile_w / fb->format->cpp[0]; in vc4_plane_mode_set()
1029 x_off = (vc4_state->src_x % pix_per_tile) / in vc4_plane_mode_set()
1031 fb->format->cpp[i]; in vc4_plane_mode_set()
1034 tile = vc4_state->src_x / pix_per_tile; in vc4_plane_mode_set()
1036 vc4_state->offsets[i] += param * tile_w * tile; in vc4_plane_mode_set()
1037 vc4_state->offsets[i] += src_y / in vc4_plane_mode_set()
1040 vc4_state->offsets[i] += x_off & ~(i ? 1 : 0); in vc4_plane_mode_set()
1049 (long long)fb->modifier); in vc4_plane_mode_set()
1050 return -EINVAL; in vc4_plane_mode_set()
1054 * is opaque or there is no per-pixel alpha information. in vc4_plane_mode_set()
1057 mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && in vc4_plane_mode_set()
1058 fb->format->has_alpha; in vc4_plane_mode_set()
1060 if (!vc4->is_vc5) { in vc4_plane_mode_set()
1067 (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | in vc4_plane_mode_set()
1070 (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) | in vc4_plane_mode_set()
1075 vc4_state->pos0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1077 VC4_SET_FIELD(state->alpha >> 8, SCALER_POS0_FIXED_ALPHA) | in vc4_plane_mode_set()
1078 VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) | in vc4_plane_mode_set()
1079 VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y)); in vc4_plane_mode_set()
1082 if (!vc4_state->is_unity) { in vc4_plane_mode_set()
1084 VC4_SET_FIELD(vc4_state->crtc_w, in vc4_plane_mode_set()
1086 VC4_SET_FIELD(vc4_state->crtc_h, in vc4_plane_mode_set()
1091 vc4_state->pos2_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1095 VC4_SET_FIELD(vc4_state->src_w[0], in vc4_plane_mode_set()
1097 VC4_SET_FIELD(vc4_state->src_h[0], in vc4_plane_mode_set()
1107 (format->pixel_order_hvs5 << SCALER_CTL0_ORDER_SHIFT) | in vc4_plane_mode_set()
1110 (vc4_state->is_unity ? in vc4_plane_mode_set()
1118 vc4_state->pos0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1122 VC4_SET_FIELD(vc4_state->crtc_x, in vc4_plane_mode_set()
1126 VC4_SET_FIELD(vc4_state->crtc_y, in vc4_plane_mode_set()
1132 VC4_SET_FIELD(state->alpha >> 4, in vc4_plane_mode_set()
1140 if (!vc4_state->is_unity) { in vc4_plane_mode_set()
1142 VC4_SET_FIELD(vc4_state->crtc_w, in vc4_plane_mode_set()
1144 VC4_SET_FIELD(vc4_state->crtc_h, in vc4_plane_mode_set()
1149 vc4_state->pos2_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1151 VC4_SET_FIELD(vc4_state->src_w[0], in vc4_plane_mode_set()
1153 VC4_SET_FIELD(vc4_state->src_h[0], in vc4_plane_mode_set()
1165 vc4_state->ptr0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1167 vc4_dlist_write(vc4_state, vc4_state->offsets[i]); in vc4_plane_mode_set()
1181 VC4_SET_FIELD(fb->pitches[i], in vc4_plane_mode_set()
1189 if (vc4_state->is_yuv) { in vc4_plane_mode_set()
1190 enum drm_color_encoding color_encoding = state->color_encoding; in vc4_plane_mode_set()
1191 enum drm_color_range color_range = state->color_range; in vc4_plane_mode_set()
1206 vc4_state->lbm_offset = 0; in vc4_plane_mode_set()
1208 if (vc4_state->x_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1209 vc4_state->x_scaling[1] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1210 vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1211 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc4_plane_mode_set()
1215 if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1216 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc4_plane_mode_set()
1217 vc4_state->lbm_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1233 if (vc4_state->x_scaling[0] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1234 vc4_state->y_scaling[0] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1235 vc4_state->x_scaling[1] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1236 vc4_state->y_scaling[1] == VC4_SCALING_PPF) { in vc4_plane_mode_set()
1237 u32 kernel = VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start, in vc4_plane_mode_set()
1251 vc4_state->dlist[ctl0_offset] |= in vc4_plane_mode_set()
1252 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE); in vc4_plane_mode_set()
1255 covers_screen = vc4_state->crtc_x == 0 && vc4_state->crtc_y == 0 && in vc4_plane_mode_set()
1256 vc4_state->crtc_w == state->crtc->mode.hdisplay && in vc4_plane_mode_set()
1257 vc4_state->crtc_h == state->crtc->mode.vdisplay; in vc4_plane_mode_set()
1258 /* Background fill might be necessary when the plane has per-pixel in vc4_plane_mode_set()
1259 * alpha content or a non-opaque plane alpha and could blend from the in vc4_plane_mode_set()
1262 vc4_state->needs_bg_fill = fb->format->has_alpha || !covers_screen || in vc4_plane_mode_set()
1263 state->alpha != DRM_BLEND_ALPHA_OPAQUE; in vc4_plane_mode_set()
1270 vc4_state->dlist_initialized = 1; in vc4_plane_mode_set()
1292 vc4_state->dlist_count = 0; in vc4_plane_atomic_check()
1316 struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_write_dlist()
1320 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_write_dlist()
1323 vc4_state->hw_dlist = dlist; in vc4_plane_write_dlist()
1325 /* Can't memcpy_toio() because it needs to be 32-bit writes. */ in vc4_plane_write_dlist()
1326 for (i = 0; i < vc4_state->dlist_count; i++) in vc4_plane_write_dlist()
1327 writel(vc4_state->dlist[i], &dlist[i]); in vc4_plane_write_dlist()
1332 return vc4_state->dlist_count; in vc4_plane_write_dlist()
1339 return vc4_state->dlist_count; in vc4_plane_dlist_size()
1347 struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_async_set_fb()
1352 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_async_set_fb()
1358 WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); in vc4_plane_async_set_fb()
1359 addr = bo->dma_addr + fb->offsets[0]; in vc4_plane_async_set_fb()
1365 writel(addr, &vc4_state->hw_dlist[vc4_state->ptr0_offset]); in vc4_plane_async_set_fb()
1367 /* Also update the CPU-side dlist copy, so that any later in vc4_plane_async_set_fb()
1371 vc4_state->dlist[vc4_state->ptr0_offset] = addr; in vc4_plane_async_set_fb()
1384 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_atomic_async_update()
1387 swap(plane->state->fb, new_plane_state->fb); in vc4_plane_atomic_async_update()
1388 plane->state->crtc_x = new_plane_state->crtc_x; in vc4_plane_atomic_async_update()
1389 plane->state->crtc_y = new_plane_state->crtc_y; in vc4_plane_atomic_async_update()
1390 plane->state->crtc_w = new_plane_state->crtc_w; in vc4_plane_atomic_async_update()
1391 plane->state->crtc_h = new_plane_state->crtc_h; in vc4_plane_atomic_async_update()
1392 plane->state->src_x = new_plane_state->src_x; in vc4_plane_atomic_async_update()
1393 plane->state->src_y = new_plane_state->src_y; in vc4_plane_atomic_async_update()
1394 plane->state->src_w = new_plane_state->src_w; in vc4_plane_atomic_async_update()
1395 plane->state->src_h = new_plane_state->src_h; in vc4_plane_atomic_async_update()
1396 plane->state->alpha = new_plane_state->alpha; in vc4_plane_atomic_async_update()
1397 plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode; in vc4_plane_atomic_async_update()
1398 plane->state->rotation = new_plane_state->rotation; in vc4_plane_atomic_async_update()
1399 plane->state->zpos = new_plane_state->zpos; in vc4_plane_atomic_async_update()
1400 plane->state->normalized_zpos = new_plane_state->normalized_zpos; in vc4_plane_atomic_async_update()
1401 plane->state->color_encoding = new_plane_state->color_encoding; in vc4_plane_atomic_async_update()
1402 plane->state->color_range = new_plane_state->color_range; in vc4_plane_atomic_async_update()
1403 plane->state->src = new_plane_state->src; in vc4_plane_atomic_async_update()
1404 plane->state->dst = new_plane_state->dst; in vc4_plane_atomic_async_update()
1405 plane->state->visible = new_plane_state->visible; in vc4_plane_atomic_async_update()
1408 vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_atomic_async_update()
1410 vc4_state->crtc_x = new_vc4_state->crtc_x; in vc4_plane_atomic_async_update()
1411 vc4_state->crtc_y = new_vc4_state->crtc_y; in vc4_plane_atomic_async_update()
1412 vc4_state->crtc_h = new_vc4_state->crtc_h; in vc4_plane_atomic_async_update()
1413 vc4_state->crtc_w = new_vc4_state->crtc_w; in vc4_plane_atomic_async_update()
1414 vc4_state->src_x = new_vc4_state->src_x; in vc4_plane_atomic_async_update()
1415 vc4_state->src_y = new_vc4_state->src_y; in vc4_plane_atomic_async_update()
1416 memcpy(vc4_state->src_w, new_vc4_state->src_w, in vc4_plane_atomic_async_update()
1417 sizeof(vc4_state->src_w)); in vc4_plane_atomic_async_update()
1418 memcpy(vc4_state->src_h, new_vc4_state->src_h, in vc4_plane_atomic_async_update()
1419 sizeof(vc4_state->src_h)); in vc4_plane_atomic_async_update()
1420 memcpy(vc4_state->x_scaling, new_vc4_state->x_scaling, in vc4_plane_atomic_async_update()
1421 sizeof(vc4_state->x_scaling)); in vc4_plane_atomic_async_update()
1422 memcpy(vc4_state->y_scaling, new_vc4_state->y_scaling, in vc4_plane_atomic_async_update()
1423 sizeof(vc4_state->y_scaling)); in vc4_plane_atomic_async_update()
1424 vc4_state->is_unity = new_vc4_state->is_unity; in vc4_plane_atomic_async_update()
1425 vc4_state->is_yuv = new_vc4_state->is_yuv; in vc4_plane_atomic_async_update()
1426 memcpy(vc4_state->offsets, new_vc4_state->offsets, in vc4_plane_atomic_async_update()
1427 sizeof(vc4_state->offsets)); in vc4_plane_atomic_async_update()
1428 vc4_state->needs_bg_fill = new_vc4_state->needs_bg_fill; in vc4_plane_atomic_async_update()
1431 vc4_state->dlist[vc4_state->pos0_offset] = in vc4_plane_atomic_async_update()
1432 new_vc4_state->dlist[vc4_state->pos0_offset]; in vc4_plane_atomic_async_update()
1433 vc4_state->dlist[vc4_state->pos2_offset] = in vc4_plane_atomic_async_update()
1434 new_vc4_state->dlist[vc4_state->pos2_offset]; in vc4_plane_atomic_async_update()
1435 vc4_state->dlist[vc4_state->ptr0_offset] = in vc4_plane_atomic_async_update()
1436 new_vc4_state->dlist[vc4_state->ptr0_offset]; in vc4_plane_atomic_async_update()
1442 writel(vc4_state->dlist[vc4_state->pos0_offset], in vc4_plane_atomic_async_update()
1443 &vc4_state->hw_dlist[vc4_state->pos0_offset]); in vc4_plane_atomic_async_update()
1444 writel(vc4_state->dlist[vc4_state->pos2_offset], in vc4_plane_atomic_async_update()
1445 &vc4_state->hw_dlist[vc4_state->pos2_offset]); in vc4_plane_atomic_async_update()
1446 writel(vc4_state->dlist[vc4_state->ptr0_offset], in vc4_plane_atomic_async_update()
1447 &vc4_state->hw_dlist[vc4_state->ptr0_offset]); in vc4_plane_atomic_async_update()
1465 old_vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_atomic_async_check()
1468 if (!new_vc4_state->hw_dlist) in vc4_plane_atomic_async_check()
1469 return -EINVAL; in vc4_plane_atomic_async_check()
1471 if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || in vc4_plane_atomic_async_check()
1472 old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || in vc4_plane_atomic_async_check()
1473 old_vc4_state->pos2_offset != new_vc4_state->pos2_offset || in vc4_plane_atomic_async_check()
1474 old_vc4_state->ptr0_offset != new_vc4_state->ptr0_offset || in vc4_plane_atomic_async_check()
1475 vc4_lbm_size(plane->state) != vc4_lbm_size(new_plane_state)) in vc4_plane_atomic_async_check()
1476 return -EINVAL; in vc4_plane_atomic_async_check()
1481 for (i = 0; i < new_vc4_state->dlist_count; i++) { in vc4_plane_atomic_async_check()
1482 if (i == new_vc4_state->pos0_offset || in vc4_plane_atomic_async_check()
1483 i == new_vc4_state->pos2_offset || in vc4_plane_atomic_async_check()
1484 i == new_vc4_state->ptr0_offset || in vc4_plane_atomic_async_check()
1485 (new_vc4_state->lbm_offset && in vc4_plane_atomic_async_check()
1486 i == new_vc4_state->lbm_offset)) in vc4_plane_atomic_async_check()
1489 if (new_vc4_state->dlist[i] != old_vc4_state->dlist[i]) in vc4_plane_atomic_async_check()
1490 return -EINVAL; in vc4_plane_atomic_async_check()
1502 if (!state->fb) in vc4_prepare_fb()
1505 bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); in vc4_prepare_fb()
1519 if (!state->fb) in vc4_cleanup_fb()
1522 bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); in vc4_cleanup_fb()
1635 if (!hvs_formats[i].hvs5_only || vc4->is_vc5) { in vc4_plane_init()
1648 plane = &vc4_plane->base; in vc4_plane_init()
1650 if (vc4->is_vc5) in vc4_plane_init()
1701 GENMASK(drm->mode_config.num_crtc - 1, 0)); in vc4_plane_create_additional_planes()
1721 crtc->cursor = cursor_plane; in vc4_plane_create_additional_planes()