Lines Matching +full:hdmi +full:- +full:connector
1 // SPDX-License-Identifier: GPL-2.0-only
10 * DOC: VC4 Falcon HDMI module
12 * The HDMI core has a state machine and a PHY. On BCM2835, most of
16 * HDMI infoframes are kept within a small packet ram, where each
19 * HDMI audio is implemented entirely within the HDMI IP block. A
20 * register in the HDMI encoder takes SPDIF frames from the DMA engine
21 * and transfers them over an internal MAI (multi-channel audio
25 * The driver's HDMI encoder does not yet support power management.
26 * The HDMI encoder's power domain and the HSM/pixel clocks are kept
27 * continuously running, and only the HDMI logic and packet ram are
30 * The driver does not yet support CEC control, though the HDMI
49 #include <sound/hdmi-codec.h>
103 return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK; in vc4_hdmi_mode_needs_scrambling()
108 struct drm_info_node *node = (struct drm_info_node *)m->private; in vc4_hdmi_debugfs_regs()
109 struct vc4_hdmi *vc4_hdmi = node->info_ent->data; in vc4_hdmi_debugfs_regs()
112 drm_print_regset32(&p, &vc4_hdmi->hdmi_regset); in vc4_hdmi_debugfs_regs()
113 drm_print_regset32(&p, &vc4_hdmi->hd_regset); in vc4_hdmi_debugfs_regs()
135 reset_control_reset(vc4_hdmi->reset); in vc5_hdmi_reset()
156 clk_cnt = clk_get_rate(vc4_hdmi->cec_clock) / CEC_CLOCK_FREQ; in vc4_hdmi_cec_update_clk_div()
165 vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) in vc4_hdmi_connector_detect() argument
167 struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); in vc4_hdmi_connector_detect()
170 if (vc4_hdmi->hpd_gpio && in vc4_hdmi_connector_detect()
171 gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) { in vc4_hdmi_connector_detect()
173 } else if (drm_probe_ddc(vc4_hdmi->ddc)) { in vc4_hdmi_connector_detect()
180 if (connector->status != connector_status_connected) { in vc4_hdmi_connector_detect()
181 struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); in vc4_hdmi_connector_detect()
184 cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); in vc4_hdmi_connector_detect()
185 vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid); in vc4_hdmi_connector_detect()
193 cec_phys_addr_invalidate(vc4_hdmi->cec_adap); in vc4_hdmi_connector_detect()
197 static void vc4_hdmi_connector_destroy(struct drm_connector *connector) in vc4_hdmi_connector_destroy() argument
199 drm_connector_unregister(connector); in vc4_hdmi_connector_destroy()
200 drm_connector_cleanup(connector); in vc4_hdmi_connector_destroy()
203 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) in vc4_hdmi_connector_get_modes() argument
205 struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); in vc4_hdmi_connector_get_modes()
206 struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder; in vc4_hdmi_connector_get_modes()
210 edid = drm_get_edid(connector, vc4_hdmi->ddc); in vc4_hdmi_connector_get_modes()
211 cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); in vc4_hdmi_connector_get_modes()
213 return -ENODEV; in vc4_hdmi_connector_get_modes()
215 vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); in vc4_hdmi_connector_get_modes()
217 drm_connector_update_edid_property(connector, edid); in vc4_hdmi_connector_get_modes()
218 ret = drm_add_edid_modes(connector, edid); in vc4_hdmi_connector_get_modes()
221 if (vc4_hdmi->disable_4kp60) { in vc4_hdmi_connector_get_modes()
222 struct drm_device *drm = connector->dev; in vc4_hdmi_connector_get_modes()
225 list_for_each_entry(mode, &connector->probed_modes, head) { in vc4_hdmi_connector_get_modes()
236 static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector, in vc4_hdmi_connector_atomic_check() argument
240 drm_atomic_get_old_connector_state(state, connector); in vc4_hdmi_connector_atomic_check()
242 drm_atomic_get_new_connector_state(state, connector); in vc4_hdmi_connector_atomic_check()
243 struct drm_crtc *crtc = new_state->crtc; in vc4_hdmi_connector_atomic_check()
248 if (old_state->colorspace != new_state->colorspace || in vc4_hdmi_connector_atomic_check()
256 crtc_state->mode_changed = true; in vc4_hdmi_connector_atomic_check()
262 static void vc4_hdmi_connector_reset(struct drm_connector *connector) in vc4_hdmi_connector_reset() argument
265 conn_state_to_vc4_hdmi_conn_state(connector->state); in vc4_hdmi_connector_reset()
269 if (connector->state) in vc4_hdmi_connector_reset()
270 __drm_atomic_helper_connector_destroy_state(connector->state); in vc4_hdmi_connector_reset()
273 __drm_atomic_helper_connector_reset(connector, &new_state->base); in vc4_hdmi_connector_reset()
278 new_state->base.max_bpc = 8; in vc4_hdmi_connector_reset()
279 new_state->base.max_requested_bpc = 8; in vc4_hdmi_connector_reset()
280 drm_atomic_helper_connector_tv_reset(connector); in vc4_hdmi_connector_reset()
284 vc4_hdmi_connector_duplicate_state(struct drm_connector *connector) in vc4_hdmi_connector_duplicate_state() argument
286 struct drm_connector_state *conn_state = connector->state; in vc4_hdmi_connector_duplicate_state()
294 new_state->pixel_rate = vc4_state->pixel_rate; in vc4_hdmi_connector_duplicate_state()
295 __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); in vc4_hdmi_connector_duplicate_state()
297 return &new_state->base; in vc4_hdmi_connector_duplicate_state()
317 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_connector_init() local
318 struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_connector_init()
321 drm_connector_init_with_ddc(dev, connector, in vc4_hdmi_connector_init()
324 vc4_hdmi->ddc); in vc4_hdmi_connector_init()
325 drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs); in vc4_hdmi_connector_init()
329 * Allocate some default initial connector state with our reset helper. in vc4_hdmi_connector_init()
331 if (connector->funcs->reset) in vc4_hdmi_connector_init()
332 connector->funcs->reset(connector); in vc4_hdmi_connector_init()
334 /* Create and attach TV margin props to this connector. */ in vc4_hdmi_connector_init()
339 ret = drm_mode_create_hdmi_colorspace_property(connector); in vc4_hdmi_connector_init()
343 drm_connector_attach_colorspace_property(connector); in vc4_hdmi_connector_init()
344 drm_connector_attach_tv_margin_properties(connector); in vc4_hdmi_connector_init()
345 drm_connector_attach_max_bpc_property(connector, 8, 12); in vc4_hdmi_connector_init()
347 connector->polled = (DRM_CONNECTOR_POLL_CONNECT | in vc4_hdmi_connector_init()
350 connector->interlace_allowed = 1; in vc4_hdmi_connector_init()
351 connector->doublescan_allowed = 0; in vc4_hdmi_connector_init()
353 if (vc4_hdmi->variant->supports_hdr) in vc4_hdmi_connector_init()
354 drm_connector_attach_hdr_output_metadata_property(connector); in vc4_hdmi_connector_init()
356 drm_connector_attach_encoder(connector, encoder); in vc4_hdmi_connector_init()
366 u32 packet_id = type - 0x80; in vc4_hdmi_stop_packet()
382 u32 packet_id = frame->any.type - 0x80; in vc4_hdmi_write_infoframe()
384 &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; in vc4_hdmi_write_infoframe()
385 u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; in vc4_hdmi_write_infoframe()
387 ram_packet_start->reg); in vc4_hdmi_write_infoframe()
400 ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true); in vc4_hdmi_write_infoframe()
433 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_set_avi_infoframe() local
434 struct drm_connector_state *cstate = connector->state; in vc4_hdmi_set_avi_infoframe()
435 struct drm_crtc *crtc = encoder->crtc; in vc4_hdmi_set_avi_infoframe()
436 const struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vc4_hdmi_set_avi_infoframe()
441 connector, mode); in vc4_hdmi_set_avi_infoframe()
448 connector, mode, in vc4_hdmi_set_avi_infoframe()
449 vc4_encoder->limited_rgb_range ? in vc4_hdmi_set_avi_infoframe()
477 struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe; in vc4_hdmi_set_audio_infoframe()
487 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_set_hdr_infoframe() local
488 struct drm_connector_state *conn_state = connector->state; in vc4_hdmi_set_hdr_infoframe()
491 if (!vc4_hdmi->variant->supports_hdr) in vc4_hdmi_set_hdr_infoframe()
494 if (!conn_state->hdr_output_metadata) in vc4_hdmi_set_hdr_infoframe()
513 if (vc4_hdmi->audio.streaming) in vc4_hdmi_set_infoframes()
524 struct drm_display_info *display = &vc4_hdmi->connector.display_info; in vc4_hdmi_supports_scrambling()
526 if (!vc4_encoder->hdmi_monitor) in vc4_hdmi_supports_scrambling()
529 if (!display->hdmi.scdc.supported || in vc4_hdmi_supports_scrambling()
530 !display->hdmi.scdc.scrambling.supported) in vc4_hdmi_supports_scrambling()
540 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; in vc4_hdmi_enable_scrambling()
549 drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); in vc4_hdmi_enable_scrambling()
550 drm_scdc_set_scrambling(vc4_hdmi->ddc, true); in vc4_hdmi_enable_scrambling()
555 queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, in vc4_hdmi_enable_scrambling()
562 struct drm_crtc *crtc = encoder->crtc; in vc4_hdmi_disable_scrambling()
565 * At boot, encoder->crtc will be NULL. Since we don't know the in vc4_hdmi_disable_scrambling()
569 if (crtc && !vc4_hdmi_supports_scrambling(encoder, &crtc->mode)) in vc4_hdmi_disable_scrambling()
572 if (crtc && !vc4_hdmi_mode_needs_scrambling(&crtc->mode)) in vc4_hdmi_disable_scrambling()
575 if (delayed_work_pending(&vc4_hdmi->scrambling_work)) in vc4_hdmi_disable_scrambling()
576 cancel_delayed_work_sync(&vc4_hdmi->scrambling_work); in vc4_hdmi_disable_scrambling()
581 drm_scdc_set_scrambling(vc4_hdmi->ddc, false); in vc4_hdmi_disable_scrambling()
582 drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, false); in vc4_hdmi_disable_scrambling()
591 if (drm_scdc_get_scrambling_status(vc4_hdmi->ddc)) in vc4_hdmi_scrambling_wq()
594 drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); in vc4_hdmi_scrambling_wq()
595 drm_scdc_set_scrambling(vc4_hdmi->ddc, true); in vc4_hdmi_scrambling_wq()
597 queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, in vc4_hdmi_scrambling_wq()
626 if (vc4_hdmi->variant->phy_disable) in vc4_hdmi_encoder_post_crtc_powerdown()
627 vc4_hdmi->variant->phy_disable(vc4_hdmi); in vc4_hdmi_encoder_post_crtc_powerdown()
629 clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_encoder_post_crtc_powerdown()
630 clk_disable_unprepare(vc4_hdmi->hsm_clock); in vc4_hdmi_encoder_post_crtc_powerdown()
631 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_post_crtc_powerdown()
633 ret = pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_encoder_post_crtc_powerdown()
652 * Apply a colorspace conversion to squash 0-255 down in vc4_hdmi_csc_setup()
653 * to 16-235. The matrix here is: in vc4_hdmi_csc_setup()
686 * Apply a colorspace conversion to squash 0-255 down in vc5_hdmi_csc_setup()
687 * to 16-235. The matrix here is: in vc5_hdmi_csc_setup()
720 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc4_hdmi_set_timings()
721 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc4_hdmi_set_timings()
722 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; in vc4_hdmi_set_timings()
723 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; in vc4_hdmi_set_timings()
724 u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, in vc4_hdmi_set_timings()
726 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, in vc4_hdmi_set_timings()
728 VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL)); in vc4_hdmi_set_timings()
730 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, in vc4_hdmi_set_timings()
733 VC4_SET_FIELD(mode->crtc_vtotal - in vc4_hdmi_set_timings()
734 mode->crtc_vsync_end - in vc4_hdmi_set_timings()
741 VC4_SET_FIELD(mode->hdisplay * pixel_rep, in vc4_hdmi_set_timings()
745 VC4_SET_FIELD((mode->htotal - in vc4_hdmi_set_timings()
746 mode->hsync_end) * pixel_rep, in vc4_hdmi_set_timings()
748 VC4_SET_FIELD((mode->hsync_end - in vc4_hdmi_set_timings()
749 mode->hsync_start) * pixel_rep, in vc4_hdmi_set_timings()
751 VC4_SET_FIELD((mode->hsync_start - in vc4_hdmi_set_timings()
752 mode->hdisplay) * pixel_rep, in vc4_hdmi_set_timings()
766 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc5_hdmi_set_timings()
767 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc5_hdmi_set_timings()
768 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; in vc5_hdmi_set_timings()
769 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; in vc5_hdmi_set_timings()
770 u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, in vc5_hdmi_set_timings()
772 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, in vc5_hdmi_set_timings()
774 VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); in vc5_hdmi_set_timings()
776 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, in vc5_hdmi_set_timings()
779 VC4_SET_FIELD(mode->crtc_vtotal - in vc5_hdmi_set_timings()
780 mode->crtc_vsync_end - in vc5_hdmi_set_timings()
791 VC4_SET_FIELD(mode->hdisplay * pixel_rep, in vc5_hdmi_set_timings()
793 VC4_SET_FIELD((mode->hsync_start - in vc5_hdmi_set_timings()
794 mode->hdisplay) * pixel_rep, in vc5_hdmi_set_timings()
798 VC4_SET_FIELD((mode->htotal - in vc5_hdmi_set_timings()
799 mode->hsync_end) * pixel_rep, in vc5_hdmi_set_timings()
801 VC4_SET_FIELD((mode->hsync_end - in vc5_hdmi_set_timings()
802 mode->hsync_start) * pixel_rep, in vc5_hdmi_set_timings()
811 switch (state->max_bpc) { in vc5_hdmi_set_timings()
876 struct drm_connector *connector; in vc4_hdmi_encoder_get_connector_state() local
879 for_each_new_connector_in_state(state, connector, conn_state, i) { in vc4_hdmi_encoder_get_connector_state()
880 if (conn_state->best_encoder == encoder) in vc4_hdmi_encoder_get_connector_state()
894 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; in vc4_hdmi_encoder_pre_crtc_configure()
899 ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); in vc4_hdmi_encoder_pre_crtc_configure()
905 pixel_rate = vc4_conn_state->pixel_rate; in vc4_hdmi_encoder_pre_crtc_configure()
906 ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate); in vc4_hdmi_encoder_pre_crtc_configure()
912 ret = clk_prepare_enable(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
919 * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must in vc4_hdmi_encoder_pre_crtc_configure()
921 * simulation. Otherwise, exact value is unimportant for HDMI in vc4_hdmi_encoder_pre_crtc_configure()
928 * both clocks. Which, for RPi0-3 implies a maximum pixel clock of in vc4_hdmi_encoder_pre_crtc_configure()
935 ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate); in vc4_hdmi_encoder_pre_crtc_configure()
941 ret = clk_prepare_enable(vc4_hdmi->hsm_clock); in vc4_hdmi_encoder_pre_crtc_configure()
944 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
957 ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock, bvb_rate); in vc4_hdmi_encoder_pre_crtc_configure()
960 clk_disable_unprepare(vc4_hdmi->hsm_clock); in vc4_hdmi_encoder_pre_crtc_configure()
961 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
965 ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_encoder_pre_crtc_configure()
968 clk_disable_unprepare(vc4_hdmi->hsm_clock); in vc4_hdmi_encoder_pre_crtc_configure()
969 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
973 if (vc4_hdmi->variant->phy_init) in vc4_hdmi_encoder_pre_crtc_configure()
974 vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state); in vc4_hdmi_encoder_pre_crtc_configure()
981 if (vc4_hdmi->variant->set_timings) in vc4_hdmi_encoder_pre_crtc_configure()
982 vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); in vc4_hdmi_encoder_pre_crtc_configure()
988 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; in vc4_hdmi_encoder_pre_crtc_enable()
992 if (vc4_encoder->hdmi_monitor && in vc4_hdmi_encoder_pre_crtc_enable()
994 if (vc4_hdmi->variant->csc_setup) in vc4_hdmi_encoder_pre_crtc_enable()
995 vc4_hdmi->variant->csc_setup(vc4_hdmi, true); in vc4_hdmi_encoder_pre_crtc_enable()
997 vc4_encoder->limited_rgb_range = true; in vc4_hdmi_encoder_pre_crtc_enable()
999 if (vc4_hdmi->variant->csc_setup) in vc4_hdmi_encoder_pre_crtc_enable()
1000 vc4_hdmi->variant->csc_setup(vc4_hdmi, false); in vc4_hdmi_encoder_pre_crtc_enable()
1002 vc4_encoder->limited_rgb_range = false; in vc4_hdmi_encoder_pre_crtc_enable()
1011 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; in vc4_hdmi_encoder_post_crtc_enable()
1014 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc4_hdmi_encoder_post_crtc_enable()
1015 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc4_hdmi_encoder_post_crtc_enable()
1029 if (vc4_encoder->hdmi_monitor) { in vc4_hdmi_encoder_post_crtc_enable()
1052 if (vc4_encoder->hdmi_monitor) { in vc4_hdmi_encoder_post_crtc_enable()
1081 struct drm_display_mode *mode = &crtc_state->adjusted_mode; in vc4_hdmi_encoder_atomic_check()
1083 unsigned long long pixel_rate = mode->clock * 1000; in vc4_hdmi_encoder_atomic_check()
1086 if (vc4_hdmi->variant->unsupported_odd_h_timings && in vc4_hdmi_encoder_atomic_check()
1087 ((mode->hdisplay % 2) || (mode->hsync_start % 2) || in vc4_hdmi_encoder_atomic_check()
1088 (mode->hsync_end % 2) || (mode->htotal % 2))) in vc4_hdmi_encoder_atomic_check()
1089 return -EINVAL; in vc4_hdmi_encoder_atomic_check()
1098 if (vc4_hdmi->disable_wifi_frequencies && in vc4_hdmi_encoder_atomic_check()
1101 mode->clock = 238560; in vc4_hdmi_encoder_atomic_check()
1102 pixel_rate = mode->clock * 1000; in vc4_hdmi_encoder_atomic_check()
1105 if (conn_state->max_bpc == 12) { in vc4_hdmi_encoder_atomic_check()
1108 } else if (conn_state->max_bpc == 10) { in vc4_hdmi_encoder_atomic_check()
1113 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in vc4_hdmi_encoder_atomic_check()
1116 if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) in vc4_hdmi_encoder_atomic_check()
1117 return -EINVAL; in vc4_hdmi_encoder_atomic_check()
1119 if (vc4_hdmi->disable_4kp60 && (pixel_rate > HDMI_14_MAX_TMDS_CLK)) in vc4_hdmi_encoder_atomic_check()
1120 return -EINVAL; in vc4_hdmi_encoder_atomic_check()
1122 vc4_state->pixel_rate = pixel_rate; in vc4_hdmi_encoder_atomic_check()
1133 if (vc4_hdmi->variant->unsupported_odd_h_timings && in vc4_hdmi_encoder_mode_valid()
1134 ((mode->hdisplay % 2) || (mode->hsync_start % 2) || in vc4_hdmi_encoder_mode_valid()
1135 (mode->hsync_end % 2) || (mode->htotal % 2))) in vc4_hdmi_encoder_mode_valid()
1138 if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) in vc4_hdmi_encoder_mode_valid()
1141 if (vc4_hdmi->disable_4kp60 && vc4_hdmi_mode_needs_scrambling(mode)) in vc4_hdmi_encoder_mode_valid()
1178 /* HDMI audio codec callbacks */
1182 u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock); in vc4_hdmi_audio_set_mai_clock()
1194 VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M)); in vc4_hdmi_audio_set_mai_clock()
1199 struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_set_n_cts()
1200 struct drm_crtc *crtc = encoder->crtc; in vc4_hdmi_set_n_cts()
1201 const struct drm_display_mode *mode = &crtc->state->adjusted_mode; in vc4_hdmi_set_n_cts()
1206 tmp = (u64)(mode->clock * 1000) * n; in vc4_hdmi_set_n_cts()
1233 struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_audio_startup()
1236 * If the HDMI encoder hasn't probed, or the encoder is in vc4_hdmi_audio_startup()
1239 if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & in vc4_hdmi_audio_startup()
1241 return -ENODEV; in vc4_hdmi_audio_startup()
1243 vc4_hdmi->audio.streaming = true; in vc4_hdmi_audio_startup()
1252 if (vc4_hdmi->variant->phy_rng_enable) in vc4_hdmi_audio_startup()
1253 vc4_hdmi->variant->phy_rng_enable(vc4_hdmi); in vc4_hdmi_audio_startup()
1260 struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_audio_reset()
1261 struct device *dev = &vc4_hdmi->pdev->dev; in vc4_hdmi_audio_reset()
1264 vc4_hdmi->audio.streaming = false; in vc4_hdmi_audio_reset()
1283 if (vc4_hdmi->variant->phy_rng_disable) in vc4_hdmi_audio_shutdown()
1284 vc4_hdmi->variant->phy_rng_disable(vc4_hdmi); in vc4_hdmi_audio_shutdown()
1286 vc4_hdmi->audio.streaming = false; in vc4_hdmi_audio_shutdown()
1328 /* HDMI audio codec callbacks */
1334 struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_audio_prepare()
1335 unsigned int sample_rate = params->sample_rate; in vc4_hdmi_audio_prepare()
1336 unsigned int channels = params->channels; in vc4_hdmi_audio_prepare()
1343 sample_rate, params->sample_width, channels); in vc4_hdmi_audio_prepare()
1354 if (params->iec.status[0] & IEC958_AES0_NONAUDIO && in vc4_hdmi_audio_prepare()
1355 params->channels == 8) in vc4_hdmi_audio_prepare()
1365 /* The B frame identifier should match the value used by alsa-lib (8) */ in vc4_hdmi_audio_prepare()
1371 channel_mask = GENMASK(channels - 1, 0); in vc4_hdmi_audio_prepare()
1387 channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask); in vc4_hdmi_audio_prepare()
1392 memcpy(&vc4_hdmi->audio.infoframe, ¶ms->cea, sizeof(params->cea)); in vc4_hdmi_audio_prepare()
1399 .name = "vc4-hdmi-cpu-dai-component",
1406 snd_soc_dai_init_dma_data(dai, &vc4_hdmi->audio.dma_data, NULL); in vc4_hdmi_audio_cpu_dai_probe()
1412 .name = "vc4-hdmi-cpu-dai",
1427 .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-rx",
1435 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_audio_get_eld() local
1437 memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); in vc4_hdmi_audio_get_eld()
1458 &vc4_hdmi->variant->registers[HDMI_MAI_DATA]; in vc4_hdmi_audio_init()
1459 struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; in vc4_hdmi_audio_init()
1460 struct snd_soc_card *card = &vc4_hdmi->audio.card; in vc4_hdmi_audio_init()
1461 struct device *dev = &vc4_hdmi->pdev->dev; in vc4_hdmi_audio_init()
1467 if (!of_find_property(dev->of_node, "dmas", NULL)) { in vc4_hdmi_audio_init()
1469 "'dmas' DT property is missing, no HDMI audio\n"); in vc4_hdmi_audio_init()
1473 if (mai_data->reg != VC4_HD) { in vc4_hdmi_audio_init()
1475 return -EINVAL; in vc4_hdmi_audio_init()
1485 index = of_property_match_string(dev->of_node, "reg-names", "hd"); in vc4_hdmi_audio_init()
1490 addr = of_get_address(dev->of_node, index, NULL, NULL); in vc4_hdmi_audio_init()
1492 vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset; in vc4_hdmi_audio_init()
1493 vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in vc4_hdmi_audio_init()
1494 vc4_hdmi->audio.dma_data.maxburst = 2; in vc4_hdmi_audio_init()
1514 dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev)); in vc4_hdmi_audio_init()
1518 dai_link->cpus = &vc4_hdmi->audio.cpu; in vc4_hdmi_audio_init()
1519 dai_link->codecs = &vc4_hdmi->audio.codec; in vc4_hdmi_audio_init()
1520 dai_link->platforms = &vc4_hdmi->audio.platform; in vc4_hdmi_audio_init()
1522 dai_link->num_cpus = 1; in vc4_hdmi_audio_init()
1523 dai_link->num_codecs = 1; in vc4_hdmi_audio_init()
1524 dai_link->num_platforms = 1; in vc4_hdmi_audio_init()
1526 dai_link->name = "MAI"; in vc4_hdmi_audio_init()
1527 dai_link->stream_name = "MAI PCM"; in vc4_hdmi_audio_init()
1528 dai_link->codecs->dai_name = "i2s-hifi"; in vc4_hdmi_audio_init()
1529 dai_link->cpus->dai_name = dev_name(dev); in vc4_hdmi_audio_init()
1530 dai_link->codecs->name = dev_name(&codec_pdev->dev); in vc4_hdmi_audio_init()
1531 dai_link->platforms->name = dev_name(dev); in vc4_hdmi_audio_init()
1533 card->dai_link = dai_link; in vc4_hdmi_audio_init()
1534 card->num_links = 1; in vc4_hdmi_audio_init()
1535 card->name = vc4_hdmi->variant->card_name; in vc4_hdmi_audio_init()
1536 card->driver_name = "vc4-hdmi"; in vc4_hdmi_audio_init()
1537 card->dev = dev; in vc4_hdmi_audio_init()
1538 card->owner = THIS_MODULE; in vc4_hdmi_audio_init()
1542 * stores a pointer to the snd card object in dev->driver_data. This in vc4_hdmi_audio_init()
1543 * means we cannot use it for something else. The hdmi back-pointer is in vc4_hdmi_audio_init()
1544 * now stored in card->drvdata and should be retrieved with in vc4_hdmi_audio_init()
1559 struct drm_device *dev = vc4_hdmi->connector.dev; in vc4_hdmi_hpd_irq_thread()
1561 if (dev && dev->registered) in vc4_hdmi_hpd_irq_thread()
1569 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_hotplug_init() local
1570 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_hotplug_init()
1573 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_hotplug_init()
1574 unsigned int hpd_con = platform_get_irq_byname(pdev, "hpd-connected"); in vc4_hdmi_hotplug_init()
1575 unsigned int hpd_rm = platform_get_irq_byname(pdev, "hpd-removed"); in vc4_hdmi_hotplug_init()
1580 "vc4 hdmi hpd connected", vc4_hdmi); in vc4_hdmi_hotplug_init()
1587 "vc4 hdmi hpd disconnected", vc4_hdmi); in vc4_hdmi_hotplug_init()
1593 connector->polled = DRM_CONNECTOR_POLL_HPD; in vc4_hdmi_hotplug_init()
1601 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_hotplug_exit()
1603 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_hotplug_exit()
1604 free_irq(platform_get_irq_byname(pdev, "hpd-connected"), vc4_hdmi); in vc4_hdmi_hotplug_exit()
1605 free_irq(platform_get_irq_byname(pdev, "hpd-removed"), vc4_hdmi); in vc4_hdmi_hotplug_exit()
1614 if (vc4_hdmi->cec_rx_msg.len) in vc4_cec_irq_handler_rx_thread()
1615 cec_received_msg(vc4_hdmi->cec_adap, in vc4_cec_irq_handler_rx_thread()
1616 &vc4_hdmi->cec_rx_msg); in vc4_cec_irq_handler_rx_thread()
1625 if (vc4_hdmi->cec_tx_ok) { in vc4_cec_irq_handler_tx_thread()
1626 cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK, in vc4_cec_irq_handler_tx_thread()
1633 cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_NACK, in vc4_cec_irq_handler_tx_thread()
1644 if (vc4_hdmi->cec_irq_was_rx) in vc4_cec_irq_handler_thread()
1654 struct drm_device *dev = vc4_hdmi->connector.dev; in vc4_cec_read_msg()
1655 struct cec_msg *msg = &vc4_hdmi->cec_rx_msg; in vc4_cec_read_msg()
1658 msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >> in vc4_cec_read_msg()
1661 if (msg->len > 16) { in vc4_cec_read_msg()
1662 drm_err(dev, "Attempting to read too much data (%d)\n", msg->len); in vc4_cec_read_msg()
1666 for (i = 0; i < msg->len; i += 4) { in vc4_cec_read_msg()
1669 msg->msg[i] = val & 0xff; in vc4_cec_read_msg()
1670 msg->msg[i + 1] = (val >> 8) & 0xff; in vc4_cec_read_msg()
1671 msg->msg[i + 2] = (val >> 16) & 0xff; in vc4_cec_read_msg()
1672 msg->msg[i + 3] = (val >> 24) & 0xff; in vc4_cec_read_msg()
1682 vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD; in vc4_cec_irq_handler_tx_bare()
1694 vc4_hdmi->cec_rx_msg.len = 0; in vc4_cec_irq_handler_rx_bare()
1717 vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT; in vc4_cec_irq_handler()
1718 if (vc4_hdmi->cec_irq_was_rx) in vc4_cec_irq_handler()
1761 if (!vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_adap_enable()
1764 if (!vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_adap_enable()
1786 struct drm_device *dev = vc4_hdmi->connector.dev; in vc4_hdmi_cec_adap_transmit()
1790 if (msg->len > 16) { in vc4_hdmi_cec_adap_transmit()
1791 drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len); in vc4_hdmi_cec_adap_transmit()
1792 return -ENOMEM; in vc4_hdmi_cec_adap_transmit()
1795 for (i = 0; i < msg->len; i += 4) in vc4_hdmi_cec_adap_transmit()
1797 (msg->msg[i]) | in vc4_hdmi_cec_adap_transmit()
1798 (msg->msg[i + 1] << 8) | in vc4_hdmi_cec_adap_transmit()
1799 (msg->msg[i + 2] << 16) | in vc4_hdmi_cec_adap_transmit()
1800 (msg->msg[i + 3] << 24)); in vc4_hdmi_cec_adap_transmit()
1806 val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT; in vc4_hdmi_cec_adap_transmit()
1822 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_cec_init()
1823 struct device *dev = &pdev->dev; in vc4_hdmi_cec_init()
1827 if (!of_find_property(dev->of_node, "interrupts", NULL)) { in vc4_hdmi_cec_init()
1832 vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops, in vc4_hdmi_cec_init()
1836 ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap); in vc4_hdmi_cec_init()
1840 cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector); in vc4_hdmi_cec_init()
1841 cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info); in vc4_hdmi_cec_init()
1850 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_cec_init()
1851 ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"), in vc4_hdmi_cec_init()
1854 "vc4 hdmi cec rx", vc4_hdmi); in vc4_hdmi_cec_init()
1858 ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-tx"), in vc4_hdmi_cec_init()
1861 "vc4 hdmi cec tx", vc4_hdmi); in vc4_hdmi_cec_init()
1870 "vc4 hdmi cec", vc4_hdmi); in vc4_hdmi_cec_init()
1875 ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev); in vc4_hdmi_cec_init()
1882 if (vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_init()
1883 free_irq(platform_get_irq_byname(pdev, "cec-tx"), vc4_hdmi); in vc4_hdmi_cec_init()
1888 if (vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_init()
1889 free_irq(platform_get_irq_byname(pdev, "cec-rx"), vc4_hdmi); in vc4_hdmi_cec_init()
1892 cec_delete_adapter(vc4_hdmi->cec_adap); in vc4_hdmi_cec_init()
1899 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_cec_exit()
1901 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_cec_exit()
1902 free_irq(platform_get_irq_byname(pdev, "cec-rx"), vc4_hdmi); in vc4_hdmi_cec_exit()
1903 free_irq(platform_get_irq_byname(pdev, "cec-tx"), vc4_hdmi); in vc4_hdmi_cec_exit()
1908 cec_unregister_adapter(vc4_hdmi->cec_adap); in vc4_hdmi_cec_exit()
1924 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; in vc4_hdmi_build_regset()
1929 regs = kcalloc(variant->num_registers, sizeof(*regs), in vc4_hdmi_build_regset()
1932 return -ENOMEM; in vc4_hdmi_build_regset()
1934 for (i = 0; i < variant->num_registers; i++) { in vc4_hdmi_build_regset()
1935 const struct vc4_hdmi_register *field = &variant->registers[i]; in vc4_hdmi_build_regset()
1937 if (field->reg != reg) in vc4_hdmi_build_regset()
1940 regs[count].name = field->name; in vc4_hdmi_build_regset()
1941 regs[count].offset = field->offset; in vc4_hdmi_build_regset()
1947 return -ENOMEM; in vc4_hdmi_build_regset()
1949 regset->base = __vc4_hdmi_get_field_base(vc4_hdmi, reg); in vc4_hdmi_build_regset()
1950 regset->regs = new_regs; in vc4_hdmi_build_regset()
1951 regset->nregs = count; in vc4_hdmi_build_regset()
1958 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_init_resources()
1959 struct device *dev = &pdev->dev; in vc4_hdmi_init_resources()
1962 vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0); in vc4_hdmi_init_resources()
1963 if (IS_ERR(vc4_hdmi->hdmicore_regs)) in vc4_hdmi_init_resources()
1964 return PTR_ERR(vc4_hdmi->hdmicore_regs); in vc4_hdmi_init_resources()
1966 vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1); in vc4_hdmi_init_resources()
1967 if (IS_ERR(vc4_hdmi->hd_regs)) in vc4_hdmi_init_resources()
1968 return PTR_ERR(vc4_hdmi->hd_regs); in vc4_hdmi_init_resources()
1970 ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD); in vc4_hdmi_init_resources()
1974 ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI); in vc4_hdmi_init_resources()
1978 vc4_hdmi->pixel_clock = devm_clk_get(dev, "pixel"); in vc4_hdmi_init_resources()
1979 if (IS_ERR(vc4_hdmi->pixel_clock)) { in vc4_hdmi_init_resources()
1980 ret = PTR_ERR(vc4_hdmi->pixel_clock); in vc4_hdmi_init_resources()
1981 if (ret != -EPROBE_DEFER) in vc4_hdmi_init_resources()
1986 vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi"); in vc4_hdmi_init_resources()
1987 if (IS_ERR(vc4_hdmi->hsm_clock)) { in vc4_hdmi_init_resources()
1988 DRM_ERROR("Failed to get HDMI state machine clock\n"); in vc4_hdmi_init_resources()
1989 return PTR_ERR(vc4_hdmi->hsm_clock); in vc4_hdmi_init_resources()
1991 vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock; in vc4_hdmi_init_resources()
1992 vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock; in vc4_hdmi_init_resources()
1999 struct platform_device *pdev = vc4_hdmi->pdev; in vc5_hdmi_init_resources()
2000 struct device *dev = &pdev->dev; in vc5_hdmi_init_resources()
2003 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi"); in vc5_hdmi_init_resources()
2005 return -ENODEV; in vc5_hdmi_init_resources()
2007 vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start, in vc5_hdmi_init_resources()
2009 if (!vc4_hdmi->hdmicore_regs) in vc5_hdmi_init_resources()
2010 return -ENOMEM; in vc5_hdmi_init_resources()
2014 return -ENODEV; in vc5_hdmi_init_resources()
2016 vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2017 if (!vc4_hdmi->hd_regs) in vc5_hdmi_init_resources()
2018 return -ENOMEM; in vc5_hdmi_init_resources()
2022 return -ENODEV; in vc5_hdmi_init_resources()
2024 vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2025 if (!vc4_hdmi->cec_regs) in vc5_hdmi_init_resources()
2026 return -ENOMEM; in vc5_hdmi_init_resources()
2030 return -ENODEV; in vc5_hdmi_init_resources()
2032 vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2033 if (!vc4_hdmi->csc_regs) in vc5_hdmi_init_resources()
2034 return -ENOMEM; in vc5_hdmi_init_resources()
2038 return -ENODEV; in vc5_hdmi_init_resources()
2040 vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2041 if (!vc4_hdmi->dvp_regs) in vc5_hdmi_init_resources()
2042 return -ENOMEM; in vc5_hdmi_init_resources()
2046 return -ENODEV; in vc5_hdmi_init_resources()
2048 vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2049 if (!vc4_hdmi->phy_regs) in vc5_hdmi_init_resources()
2050 return -ENOMEM; in vc5_hdmi_init_resources()
2054 return -ENODEV; in vc5_hdmi_init_resources()
2056 vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2057 if (!vc4_hdmi->ram_regs) in vc5_hdmi_init_resources()
2058 return -ENOMEM; in vc5_hdmi_init_resources()
2062 return -ENODEV; in vc5_hdmi_init_resources()
2064 vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
2065 if (!vc4_hdmi->rm_regs) in vc5_hdmi_init_resources()
2066 return -ENOMEM; in vc5_hdmi_init_resources()
2068 vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi"); in vc5_hdmi_init_resources()
2069 if (IS_ERR(vc4_hdmi->hsm_clock)) { in vc5_hdmi_init_resources()
2070 DRM_ERROR("Failed to get HDMI state machine clock\n"); in vc5_hdmi_init_resources()
2071 return PTR_ERR(vc4_hdmi->hsm_clock); in vc5_hdmi_init_resources()
2074 vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb"); in vc5_hdmi_init_resources()
2075 if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) { in vc5_hdmi_init_resources()
2077 return PTR_ERR(vc4_hdmi->pixel_bvb_clock); in vc5_hdmi_init_resources()
2080 vc4_hdmi->audio_clock = devm_clk_get(dev, "audio"); in vc5_hdmi_init_resources()
2081 if (IS_ERR(vc4_hdmi->audio_clock)) { in vc5_hdmi_init_resources()
2083 return PTR_ERR(vc4_hdmi->audio_clock); in vc5_hdmi_init_resources()
2086 vc4_hdmi->cec_clock = devm_clk_get(dev, "cec"); in vc5_hdmi_init_resources()
2087 if (IS_ERR(vc4_hdmi->cec_clock)) { in vc5_hdmi_init_resources()
2089 return PTR_ERR(vc4_hdmi->cec_clock); in vc5_hdmi_init_resources()
2092 vc4_hdmi->reset = devm_reset_control_get(dev, NULL); in vc5_hdmi_init_resources()
2093 if (IS_ERR(vc4_hdmi->reset)) { in vc5_hdmi_init_resources()
2094 DRM_ERROR("Failed to get HDMI reset line\n"); in vc5_hdmi_init_resources()
2095 return PTR_ERR(vc4_hdmi->reset); in vc5_hdmi_init_resources()
2113 return -ENOMEM; in vc4_hdmi_bind()
2114 INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); in vc4_hdmi_bind()
2117 encoder = &vc4_hdmi->encoder.base.base; in vc4_hdmi_bind()
2118 vc4_hdmi->encoder.base.type = variant->encoder_type; in vc4_hdmi_bind()
2119 vc4_hdmi->encoder.base.pre_crtc_configure = vc4_hdmi_encoder_pre_crtc_configure; in vc4_hdmi_bind()
2120 vc4_hdmi->encoder.base.pre_crtc_enable = vc4_hdmi_encoder_pre_crtc_enable; in vc4_hdmi_bind()
2121 vc4_hdmi->encoder.base.post_crtc_enable = vc4_hdmi_encoder_post_crtc_enable; in vc4_hdmi_bind()
2122 vc4_hdmi->encoder.base.post_crtc_disable = vc4_hdmi_encoder_post_crtc_disable; in vc4_hdmi_bind()
2123 vc4_hdmi->encoder.base.post_crtc_powerdown = vc4_hdmi_encoder_post_crtc_powerdown; in vc4_hdmi_bind()
2124 vc4_hdmi->pdev = pdev; in vc4_hdmi_bind()
2125 vc4_hdmi->variant = variant; in vc4_hdmi_bind()
2127 ret = variant->init_resources(vc4_hdmi); in vc4_hdmi_bind()
2131 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); in vc4_hdmi_bind()
2134 return -ENODEV; in vc4_hdmi_bind()
2137 vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); in vc4_hdmi_bind()
2139 if (!vc4_hdmi->ddc) { in vc4_hdmi_bind()
2141 return -EPROBE_DEFER; in vc4_hdmi_bind()
2145 * we'll use the HDMI core's register. in vc4_hdmi_bind()
2147 vc4_hdmi->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); in vc4_hdmi_bind()
2148 if (IS_ERR(vc4_hdmi->hpd_gpio)) { in vc4_hdmi_bind()
2149 ret = PTR_ERR(vc4_hdmi->hpd_gpio); in vc4_hdmi_bind()
2153 vc4_hdmi->disable_wifi_frequencies = in vc4_hdmi_bind()
2154 of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence"); in vc4_hdmi_bind()
2156 if (variant->max_pixel_clock == 600000000) { in vc4_hdmi_bind()
2158 long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000); in vc4_hdmi_bind()
2161 vc4_hdmi->disable_4kp60 = true; in vc4_hdmi_bind()
2164 if (vc4_hdmi->variant->reset) in vc4_hdmi_bind()
2165 vc4_hdmi->variant->reset(vc4_hdmi); in vc4_hdmi_bind()
2167 if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") || in vc4_hdmi_bind()
2168 of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) && in vc4_hdmi_bind()
2170 clk_prepare_enable(vc4_hdmi->pixel_clock); in vc4_hdmi_bind()
2171 clk_prepare_enable(vc4_hdmi->hsm_clock); in vc4_hdmi_bind()
2172 clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_bind()
2196 vc4_debugfs_add_file(drm, variant->debugfs_name, in vc4_hdmi_bind()
2207 vc4_hdmi_connector_destroy(&vc4_hdmi->connector); in vc4_hdmi_bind()
2212 put_device(&vc4_hdmi->ddc->dev); in vc4_hdmi_bind()
2243 kfree(vc4_hdmi->hdmi_regset.regs); in vc4_hdmi_unbind()
2244 kfree(vc4_hdmi->hd_regset.regs); in vc4_hdmi_unbind()
2248 vc4_hdmi_connector_destroy(&vc4_hdmi->connector); in vc4_hdmi_unbind()
2249 drm_encoder_cleanup(&vc4_hdmi->encoder.base.base); in vc4_hdmi_unbind()
2253 put_device(&vc4_hdmi->ddc->dev); in vc4_hdmi_unbind()
2263 return component_add(&pdev->dev, &vc4_hdmi_ops); in vc4_hdmi_dev_probe()
2268 component_del(&pdev->dev, &vc4_hdmi_ops); in vc4_hdmi_dev_remove()
2275 .card_name = "vc4-hdmi",
2295 .card_name = "vc4-hdmi-0",
2323 .card_name = "vc4-hdmi-1",
2349 { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
2350 { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
2351 { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },