Lines Matching +full:matrix +full:- +full:connected
1 // SPDX-License-Identifier: GPL-2.0-only
70 struct drm_device *dev = state->dev; in vc4_get_ctm_state()
75 ret = drm_modeset_lock(&vc4->ctm_state_lock, state->acquire_ctx); in vc4_get_ctm_state()
91 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); in vc4_ctm_duplicate_state()
95 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_ctm_duplicate_state()
97 return &state->base; in vc4_ctm_duplicate_state()
117 drm_atomic_private_obj_fini(&vc4->ctm_manager); in vc4_ctm_obj_fini()
124 drm_modeset_lock_init(&vc4->ctm_state_lock); in vc4_ctm_obj_init()
128 return -ENOMEM; in vc4_ctm_obj_init()
130 drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base, in vc4_ctm_obj_init()
133 return drmm_add_action_or_reset(&vc4->base, vc4_ctm_obj_fini, NULL); in vc4_ctm_obj_init()
158 struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state); in vc4_ctm_commit()
159 struct drm_color_ctm *ctm = ctm_state->ctm; in vc4_ctm_commit()
161 if (ctm_state->fifo) { in vc4_ctm_commit()
163 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[0]), in vc4_ctm_commit()
165 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[3]), in vc4_ctm_commit()
167 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[6]), in vc4_ctm_commit()
170 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[1]), in vc4_ctm_commit()
172 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[4]), in vc4_ctm_commit()
174 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[7]), in vc4_ctm_commit()
177 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[2]), in vc4_ctm_commit()
179 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[5]), in vc4_ctm_commit()
181 VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[8]), in vc4_ctm_commit()
186 VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO)); in vc4_ctm_commit()
192 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_new_global_state()
195 priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_new_global_state()
205 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_old_global_state()
208 priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_old_global_state()
218 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_hvs_get_global_state()
221 priv_state = drm_atomic_get_private_obj_state(state, &vc4->hvs_channels); in vc4_hvs_get_global_state()
240 if (!crtc_state->active) in vc4_hvs_pv_muxing_commit()
243 if (vc4_state->assigned_channel != 2) in vc4_hvs_pv_muxing_commit()
251 * DSP3 is connected to FIFO2 unless the transposer is in vc4_hvs_pv_muxing_commit()
253 * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 in vc4_hvs_pv_muxing_commit()
256 if (vc4_state->feed_txp) in vc4_hvs_pv_muxing_commit()
280 if (!vc4_state->update_muxing) in vc5_hvs_pv_muxing_commit()
283 switch (vc4_crtc->data->hvs_output) { in vc5_hvs_pv_muxing_commit()
285 mux = (vc4_state->assigned_channel == 2) ? 0 : 1; in vc5_hvs_pv_muxing_commit()
293 if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) in vc5_hvs_pv_muxing_commit()
296 mux = vc4_state->assigned_channel; in vc5_hvs_pv_muxing_commit()
305 if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) in vc5_hvs_pv_muxing_commit()
308 mux = vc4_state->assigned_channel; in vc5_hvs_pv_muxing_commit()
318 if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) in vc5_hvs_pv_muxing_commit()
321 mux = vc4_state->assigned_channel; in vc5_hvs_pv_muxing_commit()
337 struct drm_device *dev = state->dev; in vc4_atomic_commit_tail()
339 struct vc4_hvs *hvs = vc4->hvs; in vc4_atomic_commit_tail()
349 if (!new_crtc_state->commit) in vc4_atomic_commit_tail()
353 vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel); in vc4_atomic_commit_tail()
356 if (vc4->hvs->hvs5) in vc4_atomic_commit_tail()
357 clk_set_min_rate(hvs->core_clk, 500000000); in vc4_atomic_commit_tail()
366 unsigned int channel = vc4_crtc_state->assigned_channel; in vc4_atomic_commit_tail()
372 if (!old_hvs_state->fifo_state[channel].in_use) in vc4_atomic_commit_tail()
375 ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit); in vc4_atomic_commit_tail()
384 if (vc4->hvs->hvs5) in vc4_atomic_commit_tail()
401 if (vc4->hvs->hvs5) in vc4_atomic_commit_tail()
402 clk_set_min_rate(hvs->core_clk, 0); in vc4_atomic_commit_tail()
414 return -EINVAL; in vc4_atomic_commit_setup()
420 vc4_crtc_state->assigned_channel; in vc4_atomic_commit_setup()
425 if (!hvs_state->fifo_state[channel].in_use) in vc4_atomic_commit_setup()
428 hvs_state->fifo_state[channel].pending_commit = in vc4_atomic_commit_setup()
429 drm_crtc_commit_get(crtc_state->commit); in vc4_atomic_commit_setup()
444 if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) { in vc4_fb_create()
449 mode_cmd->handles[0]); in vc4_fb_create()
452 mode_cmd->handles[0]); in vc4_fb_create()
453 return ERR_PTR(-ENOENT); in vc4_fb_create()
459 if (bo->t_format) { in vc4_fb_create()
490 if (!new_crtc_state->ctm && old_crtc_state->ctm) { in vc4_ctm_atomic_check()
491 ctm_state = vc4_get_ctm_state(state, &vc4->ctm_manager); in vc4_ctm_atomic_check()
494 ctm_state->fifo = 0; in vc4_ctm_atomic_check()
499 if (new_crtc_state->ctm == old_crtc_state->ctm) in vc4_ctm_atomic_check()
503 ctm_state = vc4_get_ctm_state(state, &vc4->ctm_manager); in vc4_ctm_atomic_check()
508 /* CTM is being enabled or the matrix changed. */ in vc4_ctm_atomic_check()
509 if (new_crtc_state->ctm) { in vc4_ctm_atomic_check()
513 /* fifo is 1-based since 0 disables CTM. */ in vc4_ctm_atomic_check()
514 int fifo = vc4_crtc_state->assigned_channel + 1; in vc4_ctm_atomic_check()
519 if (ctm_state->fifo && ctm_state->fifo != fifo) { in vc4_ctm_atomic_check()
521 return -EINVAL; in vc4_ctm_atomic_check()
528 ctm = new_crtc_state->ctm->data; in vc4_ctm_atomic_check()
529 for (i = 0; i < ARRAY_SIZE(ctm->matrix); i++) { in vc4_ctm_atomic_check()
530 u64 val = ctm->matrix[i]; in vc4_ctm_atomic_check()
534 return -EINVAL; in vc4_ctm_atomic_check()
537 ctm_state->fifo = fifo; in vc4_ctm_atomic_check()
538 ctm_state->ctm = ctm; in vc4_ctm_atomic_check()
548 struct vc4_dev *vc4 = to_vc4_dev(state->dev); in vc4_load_tracker_atomic_check()
554 if (!vc4->load_tracker_available) in vc4_load_tracker_atomic_check()
558 &vc4->load_tracker); in vc4_load_tracker_atomic_check()
567 if (old_plane_state->fb && old_plane_state->crtc) { in vc4_load_tracker_atomic_check()
569 load_state->membus_load -= vc4_plane_state->membus_load; in vc4_load_tracker_atomic_check()
570 load_state->hvs_load -= vc4_plane_state->hvs_load; in vc4_load_tracker_atomic_check()
573 if (new_plane_state->fb && new_plane_state->crtc) { in vc4_load_tracker_atomic_check()
575 load_state->membus_load += vc4_plane_state->membus_load; in vc4_load_tracker_atomic_check()
576 load_state->hvs_load += vc4_plane_state->hvs_load; in vc4_load_tracker_atomic_check()
581 if (!vc4->load_tracker_enabled) in vc4_load_tracker_atomic_check()
587 if (load_state->membus_load > SZ_1G + SZ_512M) in vc4_load_tracker_atomic_check()
588 return -ENOSPC; in vc4_load_tracker_atomic_check()
593 if (load_state->hvs_load > 240000000ULL) in vc4_load_tracker_atomic_check()
594 return -ENOSPC; in vc4_load_tracker_atomic_check()
604 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); in vc4_load_tracker_duplicate_state()
608 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_load_tracker_duplicate_state()
610 return &state->base; in vc4_load_tracker_duplicate_state()
631 if (!vc4->load_tracker_available) in vc4_load_tracker_obj_fini()
634 drm_atomic_private_obj_fini(&vc4->load_tracker); in vc4_load_tracker_obj_fini()
641 if (!vc4->load_tracker_available) in vc4_load_tracker_obj_init()
646 return -ENOMEM; in vc4_load_tracker_obj_init()
648 drm_atomic_private_obj_init(&vc4->base, &vc4->load_tracker, in vc4_load_tracker_obj_init()
649 &load_state->base, in vc4_load_tracker_obj_init()
652 return drmm_add_action_or_reset(&vc4->base, vc4_load_tracker_obj_fini, NULL); in vc4_load_tracker_obj_init()
658 struct vc4_hvs_state *old_state = to_vc4_hvs_state(obj->state); in vc4_hvs_channels_duplicate_state()
666 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); in vc4_hvs_channels_duplicate_state()
670 state->fifo_state[i].in_use = old_state->fifo_state[i].in_use; in vc4_hvs_channels_duplicate_state()
672 if (!old_state->fifo_state[i].pending_commit) in vc4_hvs_channels_duplicate_state()
675 state->fifo_state[i].pending_commit = in vc4_hvs_channels_duplicate_state()
676 drm_crtc_commit_get(old_state->fifo_state[i].pending_commit); in vc4_hvs_channels_duplicate_state()
679 return &state->base; in vc4_hvs_channels_duplicate_state()
689 if (!hvs_state->fifo_state[i].pending_commit) in vc4_hvs_channels_destroy_state()
692 drm_crtc_commit_put(hvs_state->fifo_state[i].pending_commit); in vc4_hvs_channels_destroy_state()
707 drm_atomic_private_obj_fini(&vc4->hvs_channels); in vc4_hvs_channels_obj_fini()
716 return -ENOMEM; in vc4_hvs_channels_obj_init()
718 drm_atomic_private_obj_init(&vc4->base, &vc4->hvs_channels, in vc4_hvs_channels_obj_init()
719 &state->base, in vc4_hvs_channels_obj_init()
722 return drmm_add_action_or_reset(&vc4->base, vc4_hvs_channels_obj_fini, NULL); in vc4_hvs_channels_obj_init()
726 * The BCM2711 HVS has up to 7 outputs connected to the pixelvalves and
734 * - When running in a dual-display setup (so with two CRTCs involved),
741 * - To fix the above, we can't use drm_atomic_get_crtc_state on all
747 * doing a modetest -v first on HDMI1 and then on HDMI0.
749 * - Since we need the pixelvalve to be disabled and enabled back when
766 return -EINVAL; in vc4_pv_muxing_atomic_check()
768 for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++) in vc4_pv_muxing_atomic_check()
769 if (!hvs_new_state->fifo_state[i].in_use) in vc4_pv_muxing_atomic_check()
782 if (old_crtc_state->enable == new_crtc_state->enable) in vc4_pv_muxing_atomic_check()
786 new_vc4_crtc_state->update_muxing = true; in vc4_pv_muxing_atomic_check()
789 if (!new_crtc_state->enable) { in vc4_pv_muxing_atomic_check()
790 channel = old_vc4_crtc_state->assigned_channel; in vc4_pv_muxing_atomic_check()
791 hvs_new_state->fifo_state[channel].in_use = false; in vc4_pv_muxing_atomic_check()
792 new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; in vc4_pv_muxing_atomic_check()
798 * up to 7 encoders, connected to up to 6 CRTCs. in vc4_pv_muxing_atomic_check()
820 matching_channels = unassigned_channels & vc4_crtc->data->hvs_available_channels; in vc4_pv_muxing_atomic_check()
822 return -EINVAL; in vc4_pv_muxing_atomic_check()
824 channel = ffs(matching_channels) - 1; in vc4_pv_muxing_atomic_check()
825 new_vc4_crtc_state->assigned_channel = channel; in vc4_pv_muxing_atomic_check()
827 hvs_new_state->fifo_state[channel].in_use = true; in vc4_pv_muxing_atomic_check()
867 bool is_vc5 = of_device_is_compatible(dev->dev->of_node, in vc4_kms_load()
868 "brcm,bcm2711-vc5"); in vc4_kms_load()
872 vc4->load_tracker_available = true; in vc4_kms_load()
877 vc4->load_tracker_enabled = true; in vc4_kms_load()
881 dev->vblank_disable_immediate = true; in vc4_kms_load()
883 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); in vc4_kms_load()
885 dev_err(dev->dev, "failed to initialize vblank\n"); in vc4_kms_load()
890 dev->mode_config.max_width = 7680; in vc4_kms_load()
891 dev->mode_config.max_height = 7680; in vc4_kms_load()
893 dev->mode_config.max_width = 2048; in vc4_kms_load()
894 dev->mode_config.max_height = 2048; in vc4_kms_load()
897 dev->mode_config.funcs = &vc4_mode_funcs; in vc4_kms_load()
898 dev->mode_config.helper_private = &vc4_mode_config_helpers; in vc4_kms_load()
899 dev->mode_config.preferred_depth = 24; in vc4_kms_load()
900 dev->mode_config.async_page_flip = true; in vc4_kms_load()