Lines Matching +full:double +full:- +full:phase
1 // SPDX-License-Identifier: GPL-2.0-only
276 return state->fb && !WARN_ON(!state->crtc); in plane_enabled()
281 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_duplicate_state()
282 struct vc4_hvs *hvs = vc4->hvs; in vc4_plane_duplicate_state()
286 if (WARN_ON(!plane->state)) in vc4_plane_duplicate_state()
289 vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL); in vc4_plane_duplicate_state()
293 memset(&vc4_state->lbm, 0, sizeof(vc4_state->lbm)); in vc4_plane_duplicate_state()
296 if (vc4_state->upm_handle[i]) in vc4_plane_duplicate_state()
297 refcount_inc(&hvs->upm_refcounts[vc4_state->upm_handle[i]].refcount); in vc4_plane_duplicate_state()
300 vc4_state->dlist_initialized = 0; in vc4_plane_duplicate_state()
302 __drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base); in vc4_plane_duplicate_state()
304 if (vc4_state->dlist) { in vc4_plane_duplicate_state()
305 vc4_state->dlist = kmemdup(vc4_state->dlist, in vc4_plane_duplicate_state()
306 vc4_state->dlist_count * 4, in vc4_plane_duplicate_state()
308 if (!vc4_state->dlist) { in vc4_plane_duplicate_state()
312 vc4_state->dlist_size = vc4_state->dlist_count; in vc4_plane_duplicate_state()
315 return &vc4_state->base; in vc4_plane_duplicate_state()
320 struct vc4_upm_refcounts *refcount = &hvs->upm_refcounts[upm_handle]; in vc4_plane_release_upm_ida()
323 spin_lock_irqsave(&hvs->mm_lock, irqflags); in vc4_plane_release_upm_ida()
324 drm_mm_remove_node(&refcount->upm); in vc4_plane_release_upm_ida()
325 spin_unlock_irqrestore(&hvs->mm_lock, irqflags); in vc4_plane_release_upm_ida()
326 refcount->upm.start = 0; in vc4_plane_release_upm_ida()
327 refcount->upm.size = 0; in vc4_plane_release_upm_ida()
328 refcount->size = 0; in vc4_plane_release_upm_ida()
330 ida_free(&hvs->upm_handles, upm_handle); in vc4_plane_release_upm_ida()
336 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_destroy_state()
337 struct vc4_hvs *hvs = vc4->hvs; in vc4_plane_destroy_state()
341 if (drm_mm_node_allocated(&vc4_state->lbm)) { in vc4_plane_destroy_state()
344 spin_lock_irqsave(&hvs->mm_lock, irqflags); in vc4_plane_destroy_state()
345 drm_mm_remove_node(&vc4_state->lbm); in vc4_plane_destroy_state()
346 spin_unlock_irqrestore(&hvs->mm_lock, irqflags); in vc4_plane_destroy_state()
352 if (!vc4_state->upm_handle[i]) in vc4_plane_destroy_state()
355 refcount = &hvs->upm_refcounts[vc4_state->upm_handle[i]]; in vc4_plane_destroy_state()
357 if (refcount_dec_and_test(&refcount->refcount)) in vc4_plane_destroy_state()
358 vc4_plane_release_upm_ida(hvs, vc4_state->upm_handle[i]); in vc4_plane_destroy_state()
361 kfree(vc4_state->dlist); in vc4_plane_destroy_state()
362 __drm_atomic_helper_plane_destroy_state(&vc4_state->base); in vc4_plane_destroy_state()
371 if (plane->state) in vc4_plane_reset()
372 __drm_atomic_helper_plane_destroy_state(plane->state); in vc4_plane_reset()
374 kfree(plane->state); in vc4_plane_reset()
380 __drm_atomic_helper_plane_reset(plane, &vc4_state->base); in vc4_plane_reset()
385 if (vc4_state->dlist_count == vc4_state->dlist_size) { in vc4_dlist_counter_increment()
386 u32 new_size = max(4u, vc4_state->dlist_count * 2); in vc4_dlist_counter_increment()
391 memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4); in vc4_dlist_counter_increment()
393 kfree(vc4_state->dlist); in vc4_dlist_counter_increment()
394 vc4_state->dlist = new_dlist; in vc4_dlist_counter_increment()
395 vc4_state->dlist_size = new_size; in vc4_dlist_counter_increment()
398 vc4_state->dlist_count++; in vc4_dlist_counter_increment()
403 unsigned int idx = vc4_state->dlist_count; in vc4_dlist_write()
406 vc4_state->dlist[idx] = val; in vc4_dlist_write()
410 * be up/down/non-scaled.
418 switch (vc4_state->x_scaling[plane] << 2 | vc4_state->y_scaling[plane]) { in vc4_get_scl_field()
450 crtc_state = drm_atomic_get_new_crtc_state(pstate->state, in vc4_plane_margins_adj()
451 pstate->crtc); in vc4_plane_margins_adj()
457 if (left + right >= crtc_state->mode.hdisplay || in vc4_plane_margins_adj()
458 top + bottom >= crtc_state->mode.vdisplay) in vc4_plane_margins_adj()
459 return -EINVAL; in vc4_plane_margins_adj()
461 adjhdisplay = crtc_state->mode.hdisplay - (left + right); in vc4_plane_margins_adj()
462 vc4_pstate->crtc_x = DIV_ROUND_CLOSEST(vc4_pstate->crtc_x * in vc4_plane_margins_adj()
464 crtc_state->mode.hdisplay); in vc4_plane_margins_adj()
465 vc4_pstate->crtc_x += left; in vc4_plane_margins_adj()
466 if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right) in vc4_plane_margins_adj()
467 vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right; in vc4_plane_margins_adj()
469 adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); in vc4_plane_margins_adj()
470 vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * in vc4_plane_margins_adj()
472 crtc_state->mode.vdisplay); in vc4_plane_margins_adj()
473 vc4_pstate->crtc_y += top; in vc4_plane_margins_adj()
474 if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom) in vc4_plane_margins_adj()
475 vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom; in vc4_plane_margins_adj()
477 vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * in vc4_plane_margins_adj()
479 crtc_state->mode.hdisplay); in vc4_plane_margins_adj()
480 vc4_pstate->crtc_h = DIV_ROUND_CLOSEST(vc4_pstate->crtc_h * in vc4_plane_margins_adj()
482 crtc_state->mode.vdisplay); in vc4_plane_margins_adj()
484 if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h) in vc4_plane_margins_adj()
485 return -EINVAL; in vc4_plane_margins_adj()
493 struct drm_framebuffer *fb = state->fb; in vc4_plane_setup_clipping_and_scaling()
494 int num_planes = fb->format->num_planes; in vc4_plane_setup_clipping_and_scaling()
496 u32 h_subsample = fb->format->hsub; in vc4_plane_setup_clipping_and_scaling()
497 u32 v_subsample = fb->format->vsub; in vc4_plane_setup_clipping_and_scaling()
500 crtc_state = drm_atomic_get_existing_crtc_state(state->state, in vc4_plane_setup_clipping_and_scaling()
501 state->crtc); in vc4_plane_setup_clipping_and_scaling()
504 return -EINVAL; in vc4_plane_setup_clipping_and_scaling()
512 vc4_state->src_x = state->src.x1; in vc4_plane_setup_clipping_and_scaling()
513 vc4_state->src_y = state->src.y1; in vc4_plane_setup_clipping_and_scaling()
514 vc4_state->src_w[0] = state->src.x2 - vc4_state->src_x; in vc4_plane_setup_clipping_and_scaling()
515 vc4_state->src_h[0] = state->src.y2 - vc4_state->src_y; in vc4_plane_setup_clipping_and_scaling()
517 vc4_state->crtc_x = state->dst.x1; in vc4_plane_setup_clipping_and_scaling()
518 vc4_state->crtc_y = state->dst.y1; in vc4_plane_setup_clipping_and_scaling()
519 vc4_state->crtc_w = state->dst.x2 - state->dst.x1; in vc4_plane_setup_clipping_and_scaling()
520 vc4_state->crtc_h = state->dst.y2 - state->dst.y1; in vc4_plane_setup_clipping_and_scaling()
526 vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0], in vc4_plane_setup_clipping_and_scaling()
527 vc4_state->crtc_w); in vc4_plane_setup_clipping_and_scaling()
528 vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0], in vc4_plane_setup_clipping_and_scaling()
529 vc4_state->crtc_h); in vc4_plane_setup_clipping_and_scaling()
531 vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE && in vc4_plane_setup_clipping_and_scaling()
532 vc4_state->y_scaling[0] == VC4_SCALING_NONE); in vc4_plane_setup_clipping_and_scaling()
535 vc4_state->is_yuv = true; in vc4_plane_setup_clipping_and_scaling()
537 vc4_state->src_w[1] = vc4_state->src_w[0] / h_subsample; in vc4_plane_setup_clipping_and_scaling()
538 vc4_state->src_h[1] = vc4_state->src_h[0] / v_subsample; in vc4_plane_setup_clipping_and_scaling()
540 vc4_state->x_scaling[1] = in vc4_plane_setup_clipping_and_scaling()
541 vc4_get_scaling_mode(vc4_state->src_w[1], in vc4_plane_setup_clipping_and_scaling()
542 vc4_state->crtc_w); in vc4_plane_setup_clipping_and_scaling()
543 vc4_state->y_scaling[1] = in vc4_plane_setup_clipping_and_scaling()
544 vc4_get_scaling_mode(vc4_state->src_h[1], in vc4_plane_setup_clipping_and_scaling()
545 vc4_state->crtc_h); in vc4_plane_setup_clipping_and_scaling()
549 * VC4_SCALING_NONE (which can happen when the down-scaling in vc4_plane_setup_clipping_and_scaling()
553 if (vc4_state->x_scaling[1] == VC4_SCALING_NONE) in vc4_plane_setup_clipping_and_scaling()
554 vc4_state->x_scaling[1] = VC4_SCALING_PPF; in vc4_plane_setup_clipping_and_scaling()
559 if (vc4_state->y_scaling[1] == VC4_SCALING_NONE) in vc4_plane_setup_clipping_and_scaling()
560 vc4_state->y_scaling[1] = VC4_SCALING_PPF; in vc4_plane_setup_clipping_and_scaling()
562 vc4_state->is_yuv = false; in vc4_plane_setup_clipping_and_scaling()
563 vc4_state->x_scaling[1] = VC4_SCALING_NONE; in vc4_plane_setup_clipping_and_scaling()
564 vc4_state->y_scaling[1] = VC4_SCALING_NONE; in vc4_plane_setup_clipping_and_scaling()
572 struct vc4_dev *vc4 = to_vc4_dev(vc4_state->base.plane->dev); in vc4_write_tpz()
575 WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D); in vc4_write_tpz()
596 /* phase magnitude bits */
602 struct vc4_dev *vc4 = to_vc4_dev(vc4_state->base.plane->dev); in vc4_write_ppf()
605 s32 phase; in vc4_write_ppf() local
607 WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D); in vc4_write_ppf()
610 * Start the phase at 1/2 pixel from the 1st pixel at src_x. in vc4_write_ppf()
615 * The phase is relative to scale_src->x, so shift it for in vc4_write_ppf()
618 offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1; in vc4_write_ppf()
619 offset += -(1 << PHASE_BITS >> 2); in vc4_write_ppf()
622 * The phase is relative to scale_src->x, so shift it for in vc4_write_ppf()
625 offset = (xy & 0xffff) >> (16 - PHASE_BITS); in vc4_write_ppf()
626 offset += -(1 << PHASE_BITS >> 1); in vc4_write_ppf()
630 * consistent with YUV's luma scaling. We lose 1-bit precision in vc4_write_ppf()
640 offset2 = src - dst * scale; in vc4_write_ppf()
641 offset2 >>= 16 - PHASE_BITS; in vc4_write_ppf()
642 phase = offset + (offset2 >> 1); in vc4_write_ppf()
645 if (phase >= 1 << PHASE_BITS) in vc4_write_ppf()
646 phase = (1 << PHASE_BITS) - 1; in vc4_write_ppf()
648 phase &= SCALER_PPF_IPHASE_MASK; in vc4_write_ppf()
655 * different to setup the phase in the BCM2712, in vc4_write_ppf()
658 VC4_SET_FIELD(phase, SCALER_PPF_IPHASE)); in vc4_write_ppf()
664 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in __vc4_lbm_size()
669 if (vc4_state->y_scaling[0] == VC4_SCALING_NONE && in __vc4_lbm_size()
670 vc4_state->y_scaling[1] == VC4_SCALING_NONE) in __vc4_lbm_size()
680 if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ) in __vc4_lbm_size()
681 pix_per_line = vc4_state->crtc_w; in __vc4_lbm_size()
683 pix_per_line = vc4_state->src_w[0] >> 16; in __vc4_lbm_size()
685 if (!vc4_state->is_yuv) { in __vc4_lbm_size()
686 if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ) in __vc4_lbm_size()
701 lbm = roundup(lbm, vc4->gen == VC4_GEN_5 ? 128 : 64); in __vc4_lbm_size()
704 lbm /= vc4->gen == VC4_GEN_5 ? 4 : 2; in __vc4_lbm_size()
714 switch (vc4_state->y_scaling[channel]) { in vc4_lbm_words_per_component()
729 const struct drm_format_info *info = state->fb->format; in vc4_lbm_components()
732 if (vc4_state->y_scaling[channel] == VC4_SCALING_NONE) in vc4_lbm_components()
735 if (info->is_yuv) in vc4_lbm_components()
738 if (info->has_alpha) in vc4_lbm_components()
747 const struct drm_format_info *info = state->fb->format; in vc4_lbm_channel_size()
758 if (info->hsub > 1 && channel == 1) in vc4_lbm_channel_size()
759 width = state->src_w >> 16; in vc4_lbm_channel_size()
761 width = min(state->src_w >> 16, state->crtc_w); in vc4_lbm_channel_size()
762 width = round_up(width / info->hsub, 4); in vc4_lbm_channel_size()
772 if (state->alpha != DRM_BLEND_ALPHA_OPAQUE && info->has_alpha) in vc4_lbm_channel_size()
773 components -= 1; in vc4_lbm_channel_size()
777 lines = DIV_ROUND_UP(words, 128 / info->hsub); in vc4_lbm_channel_size()
780 if (vc4_state->y_scaling[channel] != VC4_SCALING_NONE) in vc4_lbm_channel_size()
791 const struct drm_format_info *info = state->fb->format; in __vc6_lbm_size()
793 if (info->hsub > 1) in __vc6_lbm_size()
803 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in vc4_lbm_size()
806 if (vc4_state->y_scaling[0] == VC4_SCALING_NONE && in vc4_lbm_size()
807 vc4_state->y_scaling[1] == VC4_SCALING_NONE) in vc4_lbm_size()
810 if (vc4->gen >= VC4_GEN_6_C) in vc4_lbm_size()
820 unsigned int stride = state->fb->pitches[plane]; in vc6_upm_size()
823 * TODO: This only works for raster formats, and is sub-optimal in vc6_upm_size()
828 unsigned int buffer_lines = 2 << vc4_state->upm_buffer_lines; in vc6_upm_size()
837 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in vc4_write_scaling_parameters()
840 WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D); in vc4_write_scaling_parameters()
842 /* Ch0 H-PPF Word 0: Scaling Parameters */ in vc4_write_scaling_parameters()
843 if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) { in vc4_write_scaling_parameters()
844 vc4_write_ppf(vc4_state, vc4_state->src_w[channel], in vc4_write_scaling_parameters()
845 vc4_state->crtc_w, vc4_state->src_x, channel); in vc4_write_scaling_parameters()
848 /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */ in vc4_write_scaling_parameters()
849 if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) { in vc4_write_scaling_parameters()
850 vc4_write_ppf(vc4_state, vc4_state->src_h[channel], in vc4_write_scaling_parameters()
851 vc4_state->crtc_h, vc4_state->src_y, channel); in vc4_write_scaling_parameters()
855 /* Ch0 H-TPZ Words 0-1: Scaling Parameters, Recip */ in vc4_write_scaling_parameters()
856 if (vc4_state->x_scaling[channel] == VC4_SCALING_TPZ) { in vc4_write_scaling_parameters()
857 vc4_write_tpz(vc4_state, vc4_state->src_w[channel], in vc4_write_scaling_parameters()
858 vc4_state->crtc_w); in vc4_write_scaling_parameters()
861 /* Ch0 V-TPZ Words 0-2: Scaling Parameters, Recip, Context */ in vc4_write_scaling_parameters()
862 if (vc4_state->y_scaling[channel] == VC4_SCALING_TPZ) { in vc4_write_scaling_parameters()
863 vc4_write_tpz(vc4_state, vc4_state->src_h[channel], in vc4_write_scaling_parameters()
864 vc4_state->crtc_h); in vc4_write_scaling_parameters()
872 struct drm_framebuffer *fb = state->fb; in vc4_plane_calc_load()
878 crtc_state = drm_atomic_get_existing_crtc_state(state->state, in vc4_plane_calc_load()
879 state->crtc); in vc4_plane_calc_load()
880 vrefresh = drm_mode_vrefresh(&crtc_state->adjusted_mode); in vc4_plane_calc_load()
887 * HVS load is expressed in clk-cycles/sec (AKA Hz). in vc4_plane_calc_load()
889 if (vc4_state->x_scaling[0] != VC4_SCALING_NONE || in vc4_plane_calc_load()
890 vc4_state->x_scaling[1] != VC4_SCALING_NONE || in vc4_plane_calc_load()
891 vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_calc_load()
892 vc4_state->y_scaling[1] != VC4_SCALING_NONE) in vc4_plane_calc_load()
897 vc4_state->membus_load = 0; in vc4_plane_calc_load()
898 vc4_state->hvs_load = 0; in vc4_plane_calc_load()
899 for (i = 0; i < fb->format->num_planes; i++) { in vc4_plane_calc_load()
902 * (vc4_state->src_w[i] >> 16) * (vc4_state->src_h[i] >> 16) * in vc4_plane_calc_load()
908 * calculate the down-scaling factor and multiply the plane in vc4_plane_calc_load()
909 * load by this number. We're likely over-estimating the read in vc4_plane_calc_load()
910 * demand, but that's better than under-estimating it. in vc4_plane_calc_load()
912 vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i] >> 16, in vc4_plane_calc_load()
913 vc4_state->crtc_h); in vc4_plane_calc_load()
914 vc4_state->membus_load += (vc4_state->src_w[i] >> 16) * in vc4_plane_calc_load()
915 (vc4_state->src_h[i] >> 16) * in vc4_plane_calc_load()
916 vscale_factor * fb->format->cpp[i]; in vc4_plane_calc_load()
917 vc4_state->hvs_load += vc4_state->crtc_h * vc4_state->crtc_w; in vc4_plane_calc_load()
920 vc4_state->hvs_load *= vrefresh; in vc4_plane_calc_load()
921 vc4_state->hvs_load >>= hvs_load_shift; in vc4_plane_calc_load()
922 vc4_state->membus_load *= vrefresh; in vc4_plane_calc_load()
927 struct drm_device *drm = state->plane->dev; in vc4_plane_allocate_lbm()
929 struct drm_plane *plane = state->plane; in vc4_plane_allocate_lbm()
942 if (vc4->gen == VC4_GEN_5) in vc4_plane_allocate_lbm()
944 else if (vc4->gen == VC4_GEN_4) in vc4_plane_allocate_lbm()
948 plane->base.id, plane->name, lbm_size); in vc4_plane_allocate_lbm()
950 if (WARN_ON(!vc4_state->lbm_offset)) in vc4_plane_allocate_lbm()
951 return -EINVAL; in vc4_plane_allocate_lbm()
956 if (!drm_mm_node_allocated(&vc4_state->lbm)) { in vc4_plane_allocate_lbm()
959 spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags); in vc4_plane_allocate_lbm()
960 ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, in vc4_plane_allocate_lbm()
961 &vc4_state->lbm, in vc4_plane_allocate_lbm()
964 spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); in vc4_plane_allocate_lbm()
971 WARN_ON_ONCE(lbm_size != vc4_state->lbm.size); in vc4_plane_allocate_lbm()
974 vc4_state->dlist[vc4_state->lbm_offset] = vc4_state->lbm.start; in vc4_plane_allocate_lbm()
981 const struct drm_format_info *info = state->fb->format; in vc6_plane_allocate_upm()
982 struct drm_device *drm = state->plane->dev; in vc6_plane_allocate_upm()
984 struct vc4_hvs *hvs = vc4->hvs; in vc6_plane_allocate_upm()
989 WARN_ON_ONCE(vc4->gen < VC4_GEN_6_C); in vc6_plane_allocate_upm()
991 vc4_state->upm_buffer_lines = SCALER6_PTR0_UPM_BUFF_SIZE_2_LINES; in vc6_plane_allocate_upm()
993 for (i = 0; i < info->num_planes; i++) { in vc6_plane_allocate_upm()
1001 return -EINVAL; in vc6_plane_allocate_upm()
1002 upm_handle = vc4_state->upm_handle[i]; in vc6_plane_allocate_upm()
1005 hvs->upm_refcounts[upm_handle].size == upm_size) { in vc6_plane_allocate_upm()
1009 vc4_state->upm_handle[i] = upm_handle; in vc6_plane_allocate_upm()
1012 refcount_dec_and_test(&hvs->upm_refcounts[upm_handle].refcount)) { in vc6_plane_allocate_upm()
1014 vc4_state->upm_handle[i] = 0; in vc6_plane_allocate_upm()
1017 upm_handle = ida_alloc_range(&hvs->upm_handles, 1, in vc6_plane_allocate_upm()
1024 vc4_state->upm_handle[i] = upm_handle; in vc6_plane_allocate_upm()
1026 refcount = &hvs->upm_refcounts[upm_handle]; in vc6_plane_allocate_upm()
1027 refcount_set(&refcount->refcount, 1); in vc6_plane_allocate_upm()
1028 refcount->size = upm_size; in vc6_plane_allocate_upm()
1030 spin_lock_irqsave(&hvs->mm_lock, irqflags); in vc6_plane_allocate_upm()
1031 ret = drm_mm_insert_node_generic(&hvs->upm_mm, in vc6_plane_allocate_upm()
1032 &refcount->upm, in vc6_plane_allocate_upm()
1035 spin_unlock_irqrestore(&hvs->mm_lock, irqflags); in vc6_plane_allocate_upm()
1038 refcount_set(&refcount->refcount, 0); in vc6_plane_allocate_upm()
1039 ida_free(&hvs->upm_handles, upm_handle); in vc6_plane_allocate_upm()
1040 vc4_state->upm_handle[i] = 0; in vc6_plane_allocate_upm()
1045 refcount = &hvs->upm_refcounts[upm_handle]; in vc6_plane_allocate_upm()
1046 vc4_state->dlist[vc4_state->ptr0_offset[i]] |= in vc6_plane_allocate_upm()
1047 VC4_SET_FIELD(refcount->upm.start / HVS_UBM_WORD_SIZE, in vc6_plane_allocate_upm()
1049 VC4_SET_FIELD(vc4_state->upm_handle[i] - 1, in vc6_plane_allocate_upm()
1051 VC4_SET_FIELD(vc4_state->upm_buffer_lines, in vc6_plane_allocate_upm()
1061 struct drm_device *drm = state->plane->dev; in vc6_plane_free_upm()
1063 struct vc4_hvs *hvs = vc4->hvs; in vc6_plane_free_upm()
1066 WARN_ON_ONCE(vc4->gen < VC4_GEN_6_C); in vc6_plane_free_upm()
1071 upm_handle = vc4_state->upm_handle[i]; in vc6_plane_free_upm()
1075 if (refcount_dec_and_test(&hvs->upm_refcounts[upm_handle].refcount)) in vc6_plane_free_upm()
1077 vc4_state->upm_handle[i] = 0; in vc6_plane_free_upm()
1128 struct drm_device *dev = state->state->dev; in vc4_hvs4_get_alpha_blend_mode()
1131 WARN_ON_ONCE(vc4->gen != VC4_GEN_4); in vc4_hvs4_get_alpha_blend_mode()
1133 if (!state->fb->format->has_alpha) in vc4_hvs4_get_alpha_blend_mode()
1137 switch (state->pixel_blend_mode) { in vc4_hvs4_get_alpha_blend_mode()
1154 struct drm_device *dev = state->state->dev; in vc4_hvs5_get_alpha_blend_mode()
1157 WARN_ON_ONCE(vc4->gen != VC4_GEN_5 && vc4->gen != VC4_GEN_6_C && in vc4_hvs5_get_alpha_blend_mode()
1158 vc4->gen != VC4_GEN_6_D); in vc4_hvs5_get_alpha_blend_mode()
1160 switch (vc4->gen) { in vc4_hvs5_get_alpha_blend_mode()
1164 if (!state->fb->format->has_alpha) in vc4_hvs5_get_alpha_blend_mode()
1168 switch (state->pixel_blend_mode) { in vc4_hvs5_get_alpha_blend_mode()
1182 /* 2712-D configures fixed alpha mode in CTL0 */ in vc4_hvs5_get_alpha_blend_mode()
1183 return state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ? in vc4_hvs5_get_alpha_blend_mode()
1190 struct drm_device *dev = state->state->dev; in vc4_hvs6_get_alpha_mask_mode()
1193 WARN_ON_ONCE(vc4->gen != VC4_GEN_6_C && vc4->gen != VC4_GEN_6_D); in vc4_hvs6_get_alpha_mask_mode()
1195 if (vc4->gen == VC4_GEN_6_D && in vc4_hvs6_get_alpha_mask_mode()
1196 (!state->fb->format->has_alpha || in vc4_hvs6_get_alpha_mask_mode()
1197 state->pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE)) in vc4_hvs6_get_alpha_mask_mode()
1210 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_mode_set()
1212 struct drm_framebuffer *fb = state->fb; in vc4_plane_mode_set()
1213 u32 ctl0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1214 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); in vc4_plane_mode_set()
1215 u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); in vc4_plane_mode_set()
1216 int num_planes = fb->format->num_planes; in vc4_plane_mode_set()
1217 u32 h_subsample = fb->format->hsub; in vc4_plane_mode_set()
1218 u32 v_subsample = fb->format->vsub; in vc4_plane_mode_set()
1224 u32 hvs_format = format->hvs; in vc4_plane_mode_set()
1229 if (vc4_state->dlist_initialized) in vc4_plane_mode_set()
1236 if (!vc4_state->src_w[0] || !vc4_state->src_h[0] || in vc4_plane_mode_set()
1237 !vc4_state->crtc_w || !vc4_state->crtc_h) { in vc4_plane_mode_set()
1239 vc4_state->dlist_initialized = 1; in vc4_plane_mode_set()
1243 width = vc4_state->src_w[0] >> 16; in vc4_plane_mode_set()
1244 height = vc4_state->src_h[0] >> 16; in vc4_plane_mode_set()
1260 rotation = drm_rotation_simplify(state->rotation, in vc4_plane_mode_set()
1266 src_y = vc4_state->src_y >> 16; in vc4_plane_mode_set()
1268 src_y += height - 1; in vc4_plane_mode_set()
1270 src_x = vc4_state->src_x >> 16; in vc4_plane_mode_set()
1275 pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); in vc4_plane_mode_set()
1281 offsets[i] += src_y / (i ? v_subsample : 1) * fb->pitches[i]; in vc4_plane_mode_set()
1282 offsets[i] += src_x / (i ? h_subsample : 1) * fb->format->cpp[i]; in vc4_plane_mode_set()
1289 /* Whole-tile offsets, mostly for setting the pitch. */ in vc4_plane_mode_set()
1290 u32 tile_w_shift = fb->format->cpp[0] == 2 ? 6 : 5; in vc4_plane_mode_set()
1292 u32 tile_w_mask = (1 << tile_w_shift) - 1; in vc4_plane_mode_set()
1293 /* The height mask on 32-bit-per-pixel tiles is 63, i.e. twice in vc4_plane_mode_set()
1296 u32 tile_h_mask = (2 << tile_h_shift) - 1; in vc4_plane_mode_set()
1297 /* For T-tiled, the FB pitch is "how many bytes from one row to in vc4_plane_mode_set()
1302 u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift); in vc4_plane_mode_set()
1304 u32 tiles_r = tiles_w - tiles_l; in vc4_plane_mode_set()
1306 /* Intra-tile offsets, which modify the base address (the in vc4_plane_mode_set()
1321 * Don't know why we need y_off = max_y_off - y_off, but it's in vc4_plane_mode_set()
1326 y_off = tile_h_mask - y_off; in vc4_plane_mode_set()
1341 /* Rows of tiles alternate left-to-right and right-to-left. */ in vc4_plane_mode_set()
1344 offsets[0] += (tiles_w - tiles_l) << tile_size_shift; in vc4_plane_mode_set()
1345 offsets[0] -= (1 + !tile_y) << 10; in vc4_plane_mode_set()
1357 uint32_t param = fourcc_mod_broadcom_param(fb->modifier); in vc4_plane_mode_set()
1362 return -EINVAL; in vc4_plane_mode_set()
1365 if (fb->format->format == DRM_FORMAT_P030) { in vc4_plane_mode_set()
1382 return -EINVAL; in vc4_plane_mode_set()
1390 * y_ptr [3:0] is the pixel (0-11) contained within that 128bit in vc4_plane_mode_set()
1399 if (fb->format->format == DRM_FORMAT_P030) { in vc4_plane_mode_set()
1402 * should point to the 128-bit word containing in vc4_plane_mode_set()
1405 * of the 12-pixels in that 128-bit word is the in vc4_plane_mode_set()
1427 return -EINVAL; in vc4_plane_mode_set()
1429 pix_per_tile = tile_w / fb->format->cpp[0]; in vc4_plane_mode_set()
1432 fb->format->cpp[i]; in vc4_plane_mode_set()
1448 (long long)fb->modifier); in vc4_plane_mode_set()
1449 return -EINVAL; in vc4_plane_mode_set()
1453 if ((vc4_state->src_x & 0xffff) && vc4_state->src_x < (state->fb->width << 16)) in vc4_plane_mode_set()
1457 if (((vc4_state->src_x + vc4_state->src_w[0]) & 0xffff) && in vc4_plane_mode_set()
1458 vc4_state->src_x + vc4_state->src_w[0] < (state->fb->width << 16)) in vc4_plane_mode_set()
1462 if ((vc4_state->src_y & 0xffff) && vc4_state->src_y < (state->fb->height << 16)) in vc4_plane_mode_set()
1466 if (((vc4_state->src_y + vc4_state->src_h[0]) & 0xffff) && in vc4_plane_mode_set()
1467 vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16)) in vc4_plane_mode_set()
1470 /* For YUV444 the hardware wants double the width, otherwise it doesn't in vc4_plane_mode_set()
1473 if (format->drm == DRM_FORMAT_YUV444 || format->drm == DRM_FORMAT_YVU444) in vc4_plane_mode_set()
1477 * is opaque or there is no per-pixel alpha information. in vc4_plane_mode_set()
1480 mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && in vc4_plane_mode_set()
1481 fb->format->has_alpha; in vc4_plane_mode_set()
1483 if (vc4->gen == VC4_GEN_4) { in vc4_plane_mode_set()
1490 (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | in vc4_plane_mode_set()
1493 (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) | in vc4_plane_mode_set()
1498 vc4_state->pos0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1500 VC4_SET_FIELD(state->alpha >> 8, SCALER_POS0_FIXED_ALPHA) | in vc4_plane_mode_set()
1501 VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) | in vc4_plane_mode_set()
1502 VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y)); in vc4_plane_mode_set()
1505 if (!vc4_state->is_unity) { in vc4_plane_mode_set()
1507 VC4_SET_FIELD(vc4_state->crtc_w, in vc4_plane_mode_set()
1509 VC4_SET_FIELD(vc4_state->crtc_h, in vc4_plane_mode_set()
1514 vc4_state->pos2_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1528 (format->pixel_order_hvs5 << SCALER_CTL0_ORDER_SHIFT) | in vc4_plane_mode_set()
1531 (vc4_state->is_unity ? in vc4_plane_mode_set()
1539 vc4_state->pos0_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1543 VC4_SET_FIELD(vc4_state->crtc_x, in vc4_plane_mode_set()
1547 VC4_SET_FIELD(vc4_state->crtc_y, in vc4_plane_mode_set()
1553 VC4_SET_FIELD(state->alpha >> 4, in vc4_plane_mode_set()
1561 if (!vc4_state->is_unity) { in vc4_plane_mode_set()
1563 VC4_SET_FIELD(vc4_state->crtc_w, in vc4_plane_mode_set()
1565 VC4_SET_FIELD(vc4_state->crtc_h, in vc4_plane_mode_set()
1570 vc4_state->pos2_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1584 vc4_state->ptr0_offset[0] = vc4_state->dlist_count; in vc4_plane_mode_set()
1589 vc4_dlist_write(vc4_state, bo->dma_addr + fb->offsets[i] + offsets[i]); in vc4_plane_mode_set()
1604 VC4_SET_FIELD(fb->pitches[i], in vc4_plane_mode_set()
1612 if (vc4_state->is_yuv) { in vc4_plane_mode_set()
1613 enum drm_color_encoding color_encoding = state->color_encoding; in vc4_plane_mode_set()
1614 enum drm_color_range color_range = state->color_range; in vc4_plane_mode_set()
1629 vc4_state->lbm_offset = 0; in vc4_plane_mode_set()
1631 if (vc4_state->x_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1632 vc4_state->x_scaling[1] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1633 vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1634 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc4_plane_mode_set()
1638 if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc4_plane_mode_set()
1639 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc4_plane_mode_set()
1640 vc4_state->lbm_offset = vc4_state->dlist_count; in vc4_plane_mode_set()
1656 if (vc4_state->x_scaling[0] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1657 vc4_state->y_scaling[0] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1658 vc4_state->x_scaling[1] == VC4_SCALING_PPF || in vc4_plane_mode_set()
1659 vc4_state->y_scaling[1] == VC4_SCALING_PPF) { in vc4_plane_mode_set()
1660 u32 kernel = VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start, in vc4_plane_mode_set()
1674 vc4_state->dlist[ctl0_offset] |= in vc4_plane_mode_set()
1675 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE); in vc4_plane_mode_set()
1678 covers_screen = vc4_state->crtc_x == 0 && vc4_state->crtc_y == 0 && in vc4_plane_mode_set()
1679 vc4_state->crtc_w == state->crtc->mode.hdisplay && in vc4_plane_mode_set()
1680 vc4_state->crtc_h == state->crtc->mode.vdisplay; in vc4_plane_mode_set()
1681 /* Background fill might be necessary when the plane has per-pixel in vc4_plane_mode_set()
1682 * alpha content or a non-opaque plane alpha and could blend from the in vc4_plane_mode_set()
1685 vc4_state->needs_bg_fill = fb->format->has_alpha || !covers_screen || in vc4_plane_mode_set()
1686 state->alpha != DRM_BLEND_ALPHA_OPAQUE; in vc4_plane_mode_set()
1693 vc4_state->dlist_initialized = 1; in vc4_plane_mode_set()
1702 struct drm_plane_state *state = &vc4_state->base; in vc6_plane_get_csc_mode()
1703 struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); in vc6_plane_get_csc_mode()
1706 if (vc4_state->is_yuv) { in vc6_plane_get_csc_mode()
1707 enum drm_color_encoding color_encoding = state->color_encoding; in vc6_plane_get_csc_mode()
1708 enum drm_color_range color_range = state->color_range; in vc6_plane_get_csc_mode()
1710 /* CSC pre-loaded with: in vc6_plane_get_csc_mode()
1723 if (vc4->gen == VC4_GEN_6_C) { in vc6_plane_get_csc_mode()
1740 struct drm_device *drm = plane->dev; in vc6_plane_mode_set()
1743 struct drm_framebuffer *fb = state->fb; in vc6_plane_mode_set()
1744 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); in vc6_plane_mode_set()
1745 u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); in vc6_plane_mode_set()
1746 int num_planes = fb->format->num_planes; in vc6_plane_mode_set()
1747 u32 h_subsample = fb->format->hsub; in vc6_plane_mode_set()
1748 u32 v_subsample = fb->format->vsub; in vc6_plane_mode_set()
1754 u32 hvs_format = format->hvs; in vc6_plane_mode_set()
1759 if (vc4_state->dlist_initialized) in vc6_plane_mode_set()
1766 if (!vc4_state->src_w[0] || !vc4_state->src_h[0] || in vc6_plane_mode_set()
1767 !vc4_state->crtc_w || !vc4_state->crtc_h) { in vc6_plane_mode_set()
1771 vc4_state->dlist_initialized = 1; in vc6_plane_mode_set()
1775 width = vc4_state->src_w[0] >> 16; in vc6_plane_mode_set()
1776 height = vc4_state->src_h[0] >> 16; in vc6_plane_mode_set()
1792 rotation = drm_rotation_simplify(state->rotation, in vc6_plane_mode_set()
1798 src_y = vc4_state->src_y >> 16; in vc6_plane_mode_set()
1800 src_y += height - 1; in vc6_plane_mode_set()
1802 src_x = vc4_state->src_x >> 16; in vc6_plane_mode_set()
1812 offsets[i] += src_y / (i ? v_subsample : 1) * fb->pitches[i]; in vc6_plane_mode_set()
1813 offsets[i] += src_x / (i ? h_subsample : 1) * fb->format->cpp[i]; in vc6_plane_mode_set()
1820 uint32_t param = fourcc_mod_broadcom_param(fb->modifier); in vc6_plane_mode_set()
1828 return -EINVAL; in vc6_plane_mode_set()
1831 if (fb->format->format == DRM_FORMAT_P030) { in vc6_plane_mode_set()
1845 return -EINVAL; in vc6_plane_mode_set()
1853 * y_ptr [3:0] is the pixel (0-11) contained within that 128bit in vc6_plane_mode_set()
1862 if (fb->format->format == DRM_FORMAT_P030) { in vc6_plane_mode_set()
1865 * should point to the 128-bit word containing in vc6_plane_mode_set()
1868 * of the 12-pixels in that 128-bit word is the in vc6_plane_mode_set()
1887 return -EINVAL; in vc6_plane_mode_set()
1889 pix_per_tile = tile_w / fb->format->cpp[0]; in vc6_plane_mode_set()
1892 fb->format->cpp[i]; in vc6_plane_mode_set()
1902 components_per_word = fb->format->format == DRM_FORMAT_P030 ? 24 : 32; in vc6_plane_mode_set()
1904 fetch_count = (width + starting_offset + components_per_word - 1) / in vc6_plane_mode_set()
1908 VC4_SET_FIELD(fetch_count - 1, SCALER6_PTR2_FETCH_COUNT); in vc6_plane_mode_set()
1914 (long long)fb->modifier); in vc6_plane_mode_set()
1915 return -EINVAL; in vc6_plane_mode_set()
1919 if ((vc4_state->src_x & 0xffff) && vc4_state->src_x < (state->fb->width << 16)) in vc6_plane_mode_set()
1923 if (((vc4_state->src_x + vc4_state->src_w[0]) & 0xffff) && in vc6_plane_mode_set()
1924 vc4_state->src_x + vc4_state->src_w[0] < (state->fb->width << 16)) in vc6_plane_mode_set()
1928 if ((vc4_state->src_y & 0xffff) && vc4_state->src_y < (state->fb->height << 16)) in vc6_plane_mode_set()
1932 if (((vc4_state->src_y + vc4_state->src_h[0]) & 0xffff) && in vc6_plane_mode_set()
1933 vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16)) in vc6_plane_mode_set()
1936 /* for YUV444 hardware wants double the width, otherwise it doesn't in vc6_plane_mode_set()
1939 if (format->drm == DRM_FORMAT_YUV444 || format->drm == DRM_FORMAT_YVU444) in vc6_plane_mode_set()
1943 * is opaque or there is no per-pixel alpha information. in vc6_plane_mode_set()
1946 mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && in vc6_plane_mode_set()
1947 fb->format->has_alpha; in vc6_plane_mode_set()
1954 (vc4_state->is_unity ? SCALER6_CTL0_UNITY : 0) | in vc6_plane_mode_set()
1955 VC4_SET_FIELD(format->pixel_order_hvs5, SCALER6_CTL0_ORDERRGBA) | in vc6_plane_mode_set()
1961 vc4_state->pos0_offset = vc4_state->dlist_count; in vc6_plane_mode_set()
1963 VC4_SET_FIELD(vc4_state->crtc_y, SCALER6_POS0_START_Y) | in vc6_plane_mode_set()
1965 VC4_SET_FIELD(vc4_state->crtc_x, SCALER6_POS0_START_X)); in vc6_plane_mode_set()
1972 VC4_SET_FIELD(state->alpha >> 4, SCALER5_CTL2_ALPHA)); in vc6_plane_mode_set()
1975 if (!vc4_state->is_unity) in vc6_plane_mode_set()
1977 VC4_SET_FIELD(vc4_state->crtc_h - 1, in vc6_plane_mode_set()
1979 VC4_SET_FIELD(vc4_state->crtc_w - 1, in vc6_plane_mode_set()
1983 vc4_state->pos2_offset = vc4_state->dlist_count; in vc6_plane_mode_set()
1985 VC4_SET_FIELD(height - 1, in vc6_plane_mode_set()
1987 VC4_SET_FIELD(width - 1, in vc6_plane_mode_set()
1998 dma_addr_t paddr = bo->dma_addr + fb->offsets[i] + offsets[i]; in vc6_plane_mode_set()
2001 vc4_state->ptr0_offset[i] = vc4_state->dlist_count; in vc6_plane_mode_set()
2018 VC4_SET_FIELD(fb->pitches[i], in vc6_plane_mode_set()
2036 vc4_state->lbm_offset = 0; in vc6_plane_mode_set()
2038 if (!vc4_state->is_unity || fb->format->is_yuv) { in vc6_plane_mode_set()
2043 if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc6_plane_mode_set()
2044 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc6_plane_mode_set()
2045 vc4_state->lbm_offset = vc4_state->dlist_count; in vc6_plane_mode_set()
2049 if (vc4_state->x_scaling[0] != VC4_SCALING_NONE || in vc6_plane_mode_set()
2050 vc4_state->x_scaling[1] != VC4_SCALING_NONE || in vc6_plane_mode_set()
2051 vc4_state->y_scaling[0] != VC4_SCALING_NONE || in vc6_plane_mode_set()
2052 vc4_state->y_scaling[1] != VC4_SCALING_NONE) { in vc6_plane_mode_set()
2068 if (vc4_state->x_scaling[0] == VC4_SCALING_PPF || in vc6_plane_mode_set()
2069 vc4_state->y_scaling[0] == VC4_SCALING_PPF || in vc6_plane_mode_set()
2070 vc4_state->x_scaling[1] == VC4_SCALING_PPF || in vc6_plane_mode_set()
2071 vc4_state->y_scaling[1] == VC4_SCALING_PPF) { in vc6_plane_mode_set()
2073 VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start, in vc6_plane_mode_set()
2089 vc4_state->dlist[0] |= in vc6_plane_mode_set()
2090 VC4_SET_FIELD(vc4_state->dlist_count, SCALER6_CTL0_NEXT); in vc6_plane_mode_set()
2093 covers_screen = vc4_state->crtc_x == 0 && vc4_state->crtc_y == 0 && in vc6_plane_mode_set()
2094 vc4_state->crtc_w == state->crtc->mode.hdisplay && in vc6_plane_mode_set()
2095 vc4_state->crtc_h == state->crtc->mode.vdisplay; in vc6_plane_mode_set()
2098 * Background fill might be necessary when the plane has per-pixel in vc6_plane_mode_set()
2099 * alpha content or a non-opaque plane alpha and could blend from the in vc6_plane_mode_set()
2102 vc4_state->needs_bg_fill = fb->format->has_alpha || !covers_screen || in vc6_plane_mode_set()
2103 state->alpha != DRM_BLEND_ALPHA_OPAQUE; in vc6_plane_mode_set()
2111 vc4_state->dlist_initialized = 1; in vc6_plane_mode_set()
2116 plane->base.id, plane->name, vc4_state->dlist_count); in vc6_plane_mode_set()
2131 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_atomic_check()
2137 vc4_state->dlist_count = 0; in vc4_plane_atomic_check()
2143 if (vc4->gen >= VC4_GEN_6_C && old_plane_state && in vc4_plane_atomic_check()
2150 if (vc4->gen >= VC4_GEN_6_C) in vc4_plane_atomic_check()
2157 if (!vc4_state->src_w[0] || !vc4_state->src_h[0] || in vc4_plane_atomic_check()
2158 !vc4_state->crtc_w || !vc4_state->crtc_h) in vc4_plane_atomic_check()
2165 if (vc4->gen >= VC4_GEN_6_C) { in vc4_plane_atomic_check()
2186 struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_write_dlist()
2190 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_write_dlist()
2193 vc4_state->hw_dlist = dlist; in vc4_plane_write_dlist()
2195 /* Can't memcpy_toio() because it needs to be 32-bit writes. */ in vc4_plane_write_dlist()
2196 for (i = 0; i < vc4_state->dlist_count; i++) in vc4_plane_write_dlist()
2197 writel(vc4_state->dlist[i], &dlist[i]); in vc4_plane_write_dlist()
2202 return vc4_state->dlist_count; in vc4_plane_write_dlist()
2209 return vc4_state->dlist_count; in vc4_plane_dlist_size()
2217 struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_async_set_fb()
2219 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_async_set_fb()
2220 dma_addr_t dma_addr = bo->dma_addr + fb->offsets[0]; in vc4_plane_async_set_fb()
2223 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_async_set_fb()
2229 WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); in vc4_plane_async_set_fb()
2231 if (vc4->gen == VC4_GEN_6_C) { in vc4_plane_async_set_fb()
2234 value = vc4_state->dlist[vc4_state->ptr0_offset[0]] & in vc4_plane_async_set_fb()
2239 writel(value, &vc4_state->hw_dlist[vc4_state->ptr0_offset[0]]); in vc4_plane_async_set_fb()
2240 vc4_state->dlist[vc4_state->ptr0_offset[0]] = value; in vc4_plane_async_set_fb()
2243 writel(value, &vc4_state->hw_dlist[vc4_state->ptr0_offset[0] + 1]); in vc4_plane_async_set_fb()
2244 vc4_state->dlist[vc4_state->ptr0_offset[0] + 1] = value; in vc4_plane_async_set_fb()
2254 writel(addr, &vc4_state->hw_dlist[vc4_state->ptr0_offset[0]]); in vc4_plane_async_set_fb()
2256 /* Also update the CPU-side dlist copy, so that any later in vc4_plane_async_set_fb()
2260 vc4_state->dlist[vc4_state->ptr0_offset[0]] = addr; in vc4_plane_async_set_fb()
2274 if (!drm_dev_enter(plane->dev, &idx)) in vc4_plane_atomic_async_update()
2277 swap(plane->state->fb, new_plane_state->fb); in vc4_plane_atomic_async_update()
2278 plane->state->crtc_x = new_plane_state->crtc_x; in vc4_plane_atomic_async_update()
2279 plane->state->crtc_y = new_plane_state->crtc_y; in vc4_plane_atomic_async_update()
2280 plane->state->crtc_w = new_plane_state->crtc_w; in vc4_plane_atomic_async_update()
2281 plane->state->crtc_h = new_plane_state->crtc_h; in vc4_plane_atomic_async_update()
2282 plane->state->src_x = new_plane_state->src_x; in vc4_plane_atomic_async_update()
2283 plane->state->src_y = new_plane_state->src_y; in vc4_plane_atomic_async_update()
2284 plane->state->src_w = new_plane_state->src_w; in vc4_plane_atomic_async_update()
2285 plane->state->src_h = new_plane_state->src_h; in vc4_plane_atomic_async_update()
2286 plane->state->alpha = new_plane_state->alpha; in vc4_plane_atomic_async_update()
2287 plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode; in vc4_plane_atomic_async_update()
2288 plane->state->rotation = new_plane_state->rotation; in vc4_plane_atomic_async_update()
2289 plane->state->zpos = new_plane_state->zpos; in vc4_plane_atomic_async_update()
2290 plane->state->normalized_zpos = new_plane_state->normalized_zpos; in vc4_plane_atomic_async_update()
2291 plane->state->color_encoding = new_plane_state->color_encoding; in vc4_plane_atomic_async_update()
2292 plane->state->color_range = new_plane_state->color_range; in vc4_plane_atomic_async_update()
2293 plane->state->src = new_plane_state->src; in vc4_plane_atomic_async_update()
2294 plane->state->dst = new_plane_state->dst; in vc4_plane_atomic_async_update()
2295 plane->state->visible = new_plane_state->visible; in vc4_plane_atomic_async_update()
2298 vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_atomic_async_update()
2300 vc4_state->crtc_x = new_vc4_state->crtc_x; in vc4_plane_atomic_async_update()
2301 vc4_state->crtc_y = new_vc4_state->crtc_y; in vc4_plane_atomic_async_update()
2302 vc4_state->crtc_h = new_vc4_state->crtc_h; in vc4_plane_atomic_async_update()
2303 vc4_state->crtc_w = new_vc4_state->crtc_w; in vc4_plane_atomic_async_update()
2304 vc4_state->src_x = new_vc4_state->src_x; in vc4_plane_atomic_async_update()
2305 vc4_state->src_y = new_vc4_state->src_y; in vc4_plane_atomic_async_update()
2306 memcpy(vc4_state->src_w, new_vc4_state->src_w, in vc4_plane_atomic_async_update()
2307 sizeof(vc4_state->src_w)); in vc4_plane_atomic_async_update()
2308 memcpy(vc4_state->src_h, new_vc4_state->src_h, in vc4_plane_atomic_async_update()
2309 sizeof(vc4_state->src_h)); in vc4_plane_atomic_async_update()
2310 memcpy(vc4_state->x_scaling, new_vc4_state->x_scaling, in vc4_plane_atomic_async_update()
2311 sizeof(vc4_state->x_scaling)); in vc4_plane_atomic_async_update()
2312 memcpy(vc4_state->y_scaling, new_vc4_state->y_scaling, in vc4_plane_atomic_async_update()
2313 sizeof(vc4_state->y_scaling)); in vc4_plane_atomic_async_update()
2314 vc4_state->is_unity = new_vc4_state->is_unity; in vc4_plane_atomic_async_update()
2315 vc4_state->is_yuv = new_vc4_state->is_yuv; in vc4_plane_atomic_async_update()
2316 vc4_state->needs_bg_fill = new_vc4_state->needs_bg_fill; in vc4_plane_atomic_async_update()
2319 vc4_state->dlist[vc4_state->pos0_offset] = in vc4_plane_atomic_async_update()
2320 new_vc4_state->dlist[vc4_state->pos0_offset]; in vc4_plane_atomic_async_update()
2321 vc4_state->dlist[vc4_state->pos2_offset] = in vc4_plane_atomic_async_update()
2322 new_vc4_state->dlist[vc4_state->pos2_offset]; in vc4_plane_atomic_async_update()
2323 vc4_state->dlist[vc4_state->ptr0_offset[0]] = in vc4_plane_atomic_async_update()
2324 new_vc4_state->dlist[vc4_state->ptr0_offset[0]]; in vc4_plane_atomic_async_update()
2330 writel(vc4_state->dlist[vc4_state->pos0_offset], in vc4_plane_atomic_async_update()
2331 &vc4_state->hw_dlist[vc4_state->pos0_offset]); in vc4_plane_atomic_async_update()
2332 writel(vc4_state->dlist[vc4_state->pos2_offset], in vc4_plane_atomic_async_update()
2333 &vc4_state->hw_dlist[vc4_state->pos2_offset]); in vc4_plane_atomic_async_update()
2334 writel(vc4_state->dlist[vc4_state->ptr0_offset[0]], in vc4_plane_atomic_async_update()
2335 &vc4_state->hw_dlist[vc4_state->ptr0_offset[0]]); in vc4_plane_atomic_async_update()
2343 struct vc4_dev *vc4 = to_vc4_dev(plane->dev); in vc4_plane_atomic_async_check()
2350 if (vc4->gen <= VC4_GEN_5) in vc4_plane_atomic_async_check()
2357 old_vc4_state = to_vc4_plane_state(plane->state); in vc4_plane_atomic_async_check()
2360 if (!new_vc4_state->hw_dlist) in vc4_plane_atomic_async_check()
2361 return -EINVAL; in vc4_plane_atomic_async_check()
2363 if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || in vc4_plane_atomic_async_check()
2364 old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || in vc4_plane_atomic_async_check()
2365 old_vc4_state->pos2_offset != new_vc4_state->pos2_offset || in vc4_plane_atomic_async_check()
2366 old_vc4_state->ptr0_offset[0] != new_vc4_state->ptr0_offset[0] || in vc4_plane_atomic_async_check()
2367 vc4_lbm_size(plane->state) != vc4_lbm_size(new_plane_state)) in vc4_plane_atomic_async_check()
2368 return -EINVAL; in vc4_plane_atomic_async_check()
2373 for (i = 0; i < new_vc4_state->dlist_count; i++) { in vc4_plane_atomic_async_check()
2374 if (i == new_vc4_state->pos0_offset || in vc4_plane_atomic_async_check()
2375 i == new_vc4_state->pos2_offset || in vc4_plane_atomic_async_check()
2376 i == new_vc4_state->ptr0_offset[0] || in vc4_plane_atomic_async_check()
2377 (new_vc4_state->lbm_offset && in vc4_plane_atomic_async_check()
2378 i == new_vc4_state->lbm_offset)) in vc4_plane_atomic_async_check()
2381 if (new_vc4_state->dlist[i] != old_vc4_state->dlist[i]) in vc4_plane_atomic_async_check()
2382 return -EINVAL; in vc4_plane_atomic_async_check()
2394 if (!state->fb) in vc4_prepare_fb()
2397 bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); in vc4_prepare_fb()
2411 if (!state->fb) in vc4_cleanup_fb()
2414 bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); in vc4_cleanup_fb()
2527 if (!hvs_formats[i].hvs5_only || vc4->gen >= VC4_GEN_5) { in vc4_plane_init()
2540 plane = &vc4_plane->base; in vc4_plane_init()
2542 if (vc4->gen >= VC4_GEN_5) in vc4_plane_init()
2593 GENMASK(drm->mode_config.num_crtc - 1, 0)); in vc4_plane_create_additional_planes()
2613 crtc->cursor = cursor_plane; in vc4_plane_create_additional_planes()