Lines Matching +full:assigned +full:- +full:resolution +full:- +full:bits
1 // SPDX-License-Identifier: GPL-2.0-only
49 struct drm_device *dev = state->dev; in vc4_get_ctm_state()
54 ret = drm_modeset_lock(&vc4->ctm_state_lock, state->acquire_ctx); in vc4_get_ctm_state()
70 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); in vc4_ctm_duplicate_state()
74 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_ctm_duplicate_state()
76 return &state->base; in vc4_ctm_duplicate_state()
96 drm_atomic_private_obj_fini(&vc4->ctm_manager); in vc4_ctm_obj_fini()
103 drm_modeset_lock_init(&vc4->ctm_state_lock); in vc4_ctm_obj_init()
107 return -ENOMEM; in vc4_ctm_obj_init()
109 drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base, in vc4_ctm_obj_init()
112 return drmm_add_action_or_reset(&vc4->base, vc4_ctm_obj_fini, NULL); in vc4_ctm_obj_init()
124 /* We have zero integer bits so we can only saturate here. */ in vc4_ctm_s31_32_to_s0_9()
127 /* Otherwise take the 9 most important fractional bits. */ in vc4_ctm_s31_32_to_s0_9()
137 struct vc4_hvs *hvs = vc4->hvs; in vc4_ctm_commit()
138 struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state); in vc4_ctm_commit()
139 struct drm_color_ctm *ctm = ctm_state->ctm; in vc4_ctm_commit()
141 WARN_ON_ONCE(vc4->gen > VC4_GEN_5); in vc4_ctm_commit()
143 if (ctm_state->fifo) { in vc4_ctm_commit()
145 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[0]), in vc4_ctm_commit()
147 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[3]), in vc4_ctm_commit()
149 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[6]), in vc4_ctm_commit()
152 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[1]), in vc4_ctm_commit()
154 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[4]), in vc4_ctm_commit()
156 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[7]), in vc4_ctm_commit()
159 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[2]), in vc4_ctm_commit()
161 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[5]), in vc4_ctm_commit()
163 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[8]), in vc4_ctm_commit()
168 VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO)); in vc4_ctm_commit()
174 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_new_global_state()
177 priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_new_global_state()
179 return ERR_PTR(-EINVAL); in vc4_hvs_get_new_global_state()
187 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_old_global_state()
190 priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_old_global_state()
192 return ERR_PTR(-EINVAL); in vc4_hvs_get_old_global_state()
200 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_global_state()
203 priv_state = drm_atomic_get_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_global_state()
213 struct vc4_hvs *hvs = vc4->hvs; in vc4_hvs_pv_muxing_commit()
218 WARN_ON_ONCE(vc4->gen != VC4_GEN_4); in vc4_hvs_pv_muxing_commit()
226 if (!crtc_state->active) in vc4_hvs_pv_muxing_commit()
229 if (vc4_state->assigned_channel != 2) in vc4_hvs_pv_muxing_commit()
239 * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 in vc4_hvs_pv_muxing_commit()
242 if (vc4_crtc->feeds_txp) in vc4_hvs_pv_muxing_commit()
256 struct vc4_hvs *hvs = vc4->hvs; in vc5_hvs_pv_muxing_commit()
263 WARN_ON_ONCE(vc4->gen != VC4_GEN_5); in vc5_hvs_pv_muxing_commit()
268 unsigned int channel = vc4_state->assigned_channel; in vc5_hvs_pv_muxing_commit()
270 if (!vc4_state->update_muxing) in vc5_hvs_pv_muxing_commit()
273 switch (vc4_crtc->data->hvs_output) { in vc5_hvs_pv_muxing_commit()
275 drm_WARN_ON(&vc4->base, in vc5_hvs_pv_muxing_commit()
332 struct vc4_hvs *hvs = vc4->hvs; in vc6_hvs_pv_muxing_commit()
337 WARN_ON_ONCE(vc4->gen != VC4_GEN_6_C && vc4->gen != VC4_GEN_6_D); in vc6_hvs_pv_muxing_commit()
346 if (!vc4_state->update_muxing) in vc6_hvs_pv_muxing_commit()
349 if (vc4_state->assigned_channel != 1) in vc6_hvs_pv_muxing_commit()
354 switch (vc4_encoder->type) { in vc6_hvs_pv_muxing_commit()
364 drm_err(&vc4->base, "Unhandled encoder type for PV muxing %d", in vc6_hvs_pv_muxing_commit()
365 vc4_encoder->type); in vc6_hvs_pv_muxing_commit()
379 struct drm_device *dev = state->dev; in vc4_atomic_commit_tail()
381 struct vc4_hvs *hvs = vc4->hvs; in vc4_atomic_commit_tail()
394 if (vc4->gen < VC4_GEN_6_C) { in vc4_atomic_commit_tail()
402 if (!new_crtc_state->commit) in vc4_atomic_commit_tail()
406 vc4_hvs_mask_underrun(hvs, vc4_crtc_state->assigned_channel); in vc4_atomic_commit_tail()
414 if (!old_hvs_state->fifo_state[channel].in_use) in vc4_atomic_commit_tail()
417 commit = old_hvs_state->fifo_state[channel].pending_commit; in vc4_atomic_commit_tail()
426 old_hvs_state->fifo_state[channel].pending_commit = NULL; in vc4_atomic_commit_tail()
429 if (vc4->gen == VC4_GEN_5) { in vc4_atomic_commit_tail()
430 unsigned long state_rate = max(old_hvs_state->core_clock_rate, in vc4_atomic_commit_tail()
431 new_hvs_state->core_clock_rate); in vc4_atomic_commit_tail()
433 500000000, hvs->max_core_rate); in vc4_atomic_commit_tail()
441 WARN_ON(clk_set_min_rate(hvs->core_clk, core_rate)); in vc4_atomic_commit_tail()
442 WARN_ON(clk_set_min_rate(hvs->disp_clk, core_rate)); in vc4_atomic_commit_tail()
447 if (vc4->gen <= VC4_GEN_5) in vc4_atomic_commit_tail()
450 switch (vc4->gen) { in vc4_atomic_commit_tail()
465 drm_err(dev, "Unknown VC4 generation: %d", vc4->gen); in vc4_atomic_commit_tail()
482 if (vc4->gen == VC4_GEN_5) { in vc4_atomic_commit_tail()
484 hvs->max_core_rate, in vc4_atomic_commit_tail()
485 new_hvs_state->core_clock_rate); in vc4_atomic_commit_tail()
493 WARN_ON(clk_set_min_rate(hvs->core_clk, core_rate)); in vc4_atomic_commit_tail()
494 WARN_ON(clk_set_min_rate(hvs->disp_clk, core_rate)); in vc4_atomic_commit_tail()
497 clk_get_rate(hvs->core_clk)); in vc4_atomic_commit_tail()
516 vc4_crtc_state->assigned_channel; in vc4_atomic_commit_setup()
521 if (!hvs_state->fifo_state[channel].in_use) in vc4_atomic_commit_setup()
524 hvs_state->fifo_state[channel].pending_commit = in vc4_atomic_commit_setup()
525 drm_crtc_commit_get(crtc_state->commit); in vc4_atomic_commit_setup()
539 if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) in vc4_fb_create()
540 return ERR_PTR(-ENODEV); in vc4_fb_create()
545 if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) { in vc4_fb_create()
550 mode_cmd->handles[0]); in vc4_fb_create()
553 mode_cmd->handles[0]); in vc4_fb_create()
554 return ERR_PTR(-ENOENT); in vc4_fb_create()
560 if (bo->t_format) { in vc4_fb_create()
591 if (!new_crtc_state->ctm && old_crtc_state->ctm) { in vc4_ctm_atomic_check()
592 ctm_state = vc4_get_ctm_state(state, &vc4->ctm_manager); in vc4_ctm_atomic_check()
595 ctm_state->fifo = 0; in vc4_ctm_atomic_check()
600 if (new_crtc_state->ctm == old_crtc_state->ctm) in vc4_ctm_atomic_check()
604 ctm_state = vc4_get_ctm_state(state, &vc4->ctm_manager); in vc4_ctm_atomic_check()
610 if (new_crtc_state->ctm) { in vc4_ctm_atomic_check()
614 /* fifo is 1-based since 0 disables CTM. */ in vc4_ctm_atomic_check()
615 int fifo = vc4_crtc_state->assigned_channel + 1; in vc4_ctm_atomic_check()
620 if (ctm_state->fifo && ctm_state->fifo != fifo) { in vc4_ctm_atomic_check()
622 return -EINVAL; in vc4_ctm_atomic_check()
627 * no integer bits. in vc4_ctm_atomic_check()
629 ctm = new_crtc_state->ctm->data; in vc4_ctm_atomic_check()
630 for (i = 0; i < ARRAY_SIZE(ctm->matrix); i++) { in vc4_ctm_atomic_check()
631 u64 val = ctm->matrix[i]; in vc4_ctm_atomic_check()
635 return -EINVAL; in vc4_ctm_atomic_check()
638 ctm_state->fifo = fifo; in vc4_ctm_atomic_check()
639 ctm_state->ctm = ctm; in vc4_ctm_atomic_check()
649 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_load_tracker_atomic_check()
656 &vc4->load_tracker); in vc4_load_tracker_atomic_check()
665 if (old_plane_state->fb && old_plane_state->crtc) { in vc4_load_tracker_atomic_check()
667 load_state->membus_load -= vc4_plane_state->membus_load; in vc4_load_tracker_atomic_check()
668 load_state->hvs_load -= vc4_plane_state->hvs_load; in vc4_load_tracker_atomic_check()
671 if (new_plane_state->fb && new_plane_state->crtc) { in vc4_load_tracker_atomic_check()
673 load_state->membus_load += vc4_plane_state->membus_load; in vc4_load_tracker_atomic_check()
674 load_state->hvs_load += vc4_plane_state->hvs_load; in vc4_load_tracker_atomic_check()
679 if (!vc4->load_tracker_enabled) in vc4_load_tracker_atomic_check()
685 if (load_state->membus_load > SZ_1G + SZ_512M) in vc4_load_tracker_atomic_check()
686 return -ENOSPC; in vc4_load_tracker_atomic_check()
691 if (load_state->hvs_load > 240000000ULL) in vc4_load_tracker_atomic_check()
692 return -ENOSPC; in vc4_load_tracker_atomic_check()
702 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); in vc4_load_tracker_duplicate_state()
706 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_load_tracker_duplicate_state()
708 return &state->base; in vc4_load_tracker_duplicate_state()
729 drm_atomic_private_obj_fini(&vc4->load_tracker); in vc4_load_tracker_obj_fini()
738 return -ENOMEM; in vc4_load_tracker_obj_init()
740 drm_atomic_private_obj_init(&vc4->base, &vc4->load_tracker, in vc4_load_tracker_obj_init()
741 &load_state->base, in vc4_load_tracker_obj_init()
744 return drmm_add_action_or_reset(&vc4->base, vc4_load_tracker_obj_fini, NULL); in vc4_load_tracker_obj_init()
750 struct vc4_hvs_state *old_state = to_vc4_hvs_state(obj->state); in vc4_hvs_channels_duplicate_state()
758 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_hvs_channels_duplicate_state()
761 state->fifo_state[i].in_use = old_state->fifo_state[i].in_use; in vc4_hvs_channels_duplicate_state()
762 state->fifo_state[i].fifo_load = old_state->fifo_state[i].fifo_load; in vc4_hvs_channels_duplicate_state()
765 state->core_clock_rate = old_state->core_clock_rate; in vc4_hvs_channels_duplicate_state()
767 return &state->base; in vc4_hvs_channels_duplicate_state()
777 if (!hvs_state->fifo_state[i].pending_commit) in vc4_hvs_channels_destroy_state()
780 drm_crtc_commit_put(hvs_state->fifo_state[i].pending_commit); in vc4_hvs_channels_destroy_state()
793 drm_printf(p, "\tCore Clock Rate: %lu\n", hvs_state->core_clock_rate); in vc4_hvs_channels_print_state()
797 drm_printf(p, "\t\tin use=%d\n", hvs_state->fifo_state[i].in_use); in vc4_hvs_channels_print_state()
798 drm_printf(p, "\t\tload=%lu\n", hvs_state->fifo_state[i].fifo_load); in vc4_hvs_channels_print_state()
812 drm_atomic_private_obj_fini(&vc4->hvs_channels); in vc4_hvs_channels_obj_fini()
821 return -ENOMEM; in vc4_hvs_channels_obj_init()
823 drm_atomic_private_obj_init(&vc4->base, &vc4->hvs_channels, in vc4_hvs_channels_obj_init()
824 &state->base, in vc4_hvs_channels_obj_init()
827 return drmm_add_action_or_reset(&vc4->base, vc4_hvs_channels_obj_fini, NULL); in vc4_hvs_channels_obj_init()
841 return data_a->hvs_output - data_b->hvs_output; in cmp_vc4_crtc_hvs_output()
853 * - When running in a dual-display setup (so with two CRTCs involved),
860 * - To fix the above, we can't use drm_atomic_get_crtc_state on all
866 * doing a modetest -v first on HDMI1 and then on HDMI0.
868 * - Since we need the pixelvalve to be disabled and enabled back when
869 * the FIFO is changed, we should keep the FIFO assigned for as long
872 * single display, and changing the resolution down and then back up.
888 for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++) in vc4_pv_muxing_atomic_check()
889 if (!hvs_new_state->fifo_state[i].in_use) in vc4_pv_muxing_atomic_check()
907 * multiple routes is assigned one that was the only option for in vc4_pv_muxing_atomic_check()
913 sorted_crtcs = kmalloc_array(dev->num_crtcs, sizeof(*sorted_crtcs), GFP_KERNEL); in vc4_pv_muxing_atomic_check()
915 return -ENOMEM; in vc4_pv_muxing_atomic_check()
923 for (i = 0; i < dev->num_crtcs; i++) { in vc4_pv_muxing_atomic_check()
945 drm_dbg(dev, "%s: Trying to find a channel.\n", crtc->name); in vc4_pv_muxing_atomic_check()
948 if (old_crtc_state->enable == new_crtc_state->enable) { in vc4_pv_muxing_atomic_check()
949 if (new_crtc_state->enable) in vc4_pv_muxing_atomic_check()
951 crtc->name, new_vc4_crtc_state->assigned_channel); in vc4_pv_muxing_atomic_check()
953 drm_dbg(dev, "%s: Disabled, ignoring.\n", crtc->name); in vc4_pv_muxing_atomic_check()
959 new_vc4_crtc_state->update_muxing = true; in vc4_pv_muxing_atomic_check()
962 if (!new_crtc_state->enable) { in vc4_pv_muxing_atomic_check()
963 channel = old_vc4_crtc_state->assigned_channel; in vc4_pv_muxing_atomic_check()
966 crtc->name, channel); in vc4_pv_muxing_atomic_check()
968 hvs_new_state->fifo_state[channel].in_use = false; in vc4_pv_muxing_atomic_check()
969 new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; in vc4_pv_muxing_atomic_check()
973 matching_channels = unassigned_channels & vc4_crtc->data->hvs_available_channels; in vc4_pv_muxing_atomic_check()
975 ret = -EINVAL; in vc4_pv_muxing_atomic_check()
979 channel = ffs(matching_channels) - 1; in vc4_pv_muxing_atomic_check()
981 drm_dbg(dev, "Assigned HVS channel %d to CRTC %s\n", channel, crtc->name); in vc4_pv_muxing_atomic_check()
982 new_vc4_crtc_state->assigned_channel = channel; in vc4_pv_muxing_atomic_check()
984 hvs_new_state->fifo_state[channel].in_use = true; in vc4_pv_muxing_atomic_check()
998 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_core_clock_atomic_check()
1010 &vc4->load_tracker); in vc4_core_clock_atomic_check()
1024 if (old_crtc_state->active) { in vc4_core_clock_atomic_check()
1027 unsigned int channel = old_vc4_state->assigned_channel; in vc4_core_clock_atomic_check()
1029 hvs_new_state->fifo_state[channel].fifo_load = 0; in vc4_core_clock_atomic_check()
1032 if (new_crtc_state->active) { in vc4_core_clock_atomic_check()
1035 unsigned int channel = new_vc4_state->assigned_channel; in vc4_core_clock_atomic_check()
1037 hvs_new_state->fifo_state[channel].fifo_load = in vc4_core_clock_atomic_check()
1038 new_vc4_state->hvs_load; in vc4_core_clock_atomic_check()
1045 if (!hvs_new_state->fifo_state[i].in_use) in vc4_core_clock_atomic_check()
1050 hvs_new_state->fifo_state[i].fifo_load, in vc4_core_clock_atomic_check()
1054 pixel_rate = load_state->hvs_load; in vc4_core_clock_atomic_check()
1061 hvs_new_state->core_clock_rate = max(cob_rate, pixel_rate); in vc4_core_clock_atomic_check()
1118 if (vc4->gen == VC4_GEN_4) { in vc4_kms_load()
1122 vc4->load_tracker_enabled = true; in vc4_kms_load()
1126 dev->vblank_disable_immediate = true; in vc4_kms_load()
1128 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); in vc4_kms_load()
1130 dev_err(dev->dev, "failed to initialize vblank\n"); in vc4_kms_load()
1134 if (vc4->gen >= VC4_GEN_6_C) { in vc4_kms_load()
1135 dev->mode_config.max_width = 8192; in vc4_kms_load()
1136 dev->mode_config.max_height = 8192; in vc4_kms_load()
1137 } else if (vc4->gen >= VC4_GEN_5) { in vc4_kms_load()
1138 dev->mode_config.max_width = 7680; in vc4_kms_load()
1139 dev->mode_config.max_height = 7680; in vc4_kms_load()
1141 dev->mode_config.max_width = 2048; in vc4_kms_load()
1142 dev->mode_config.max_height = 2048; in vc4_kms_load()
1145 dev->mode_config.funcs = (vc4->gen > VC4_GEN_4) ? &vc5_mode_funcs : &vc4_mode_funcs; in vc4_kms_load()
1146 dev->mode_config.helper_private = &vc4_mode_config_helpers; in vc4_kms_load()
1147 dev->mode_config.preferred_depth = 24; in vc4_kms_load()
1148 dev->mode_config.async_page_flip = true; in vc4_kms_load()
1149 dev->mode_config.normalize_zpos = true; in vc4_kms_load()