Lines Matching +full:ddc +full:- +full:rx
1 // SPDX-License-Identifier: GPL-2.0-only
21 * and transfers them over an internal MAI (multi-channel audio
52 #include <sound/hdmi-codec.h>
116 struct drm_display_info *display = &vc4_hdmi->connector.display_info; in vc4_hdmi_supports_scrambling()
118 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_supports_scrambling()
120 if (!display->is_hdmi) in vc4_hdmi_supports_scrambling()
123 if (!display->hdmi.scdc.supported || in vc4_hdmi_supports_scrambling()
124 !display->hdmi.scdc.scrambling.supported) in vc4_hdmi_supports_scrambling()
141 struct drm_debugfs_entry *entry = m->private; in vc4_hdmi_debugfs_regs()
142 struct vc4_hdmi *vc4_hdmi = entry->file.data; in vc4_hdmi_debugfs_regs()
143 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_debugfs_regs()
148 return -ENODEV; in vc4_hdmi_debugfs_regs()
150 WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); in vc4_hdmi_debugfs_regs()
152 drm_print_regset32(&p, &vc4_hdmi->hdmi_regset); in vc4_hdmi_debugfs_regs()
153 drm_print_regset32(&p, &vc4_hdmi->hd_regset); in vc4_hdmi_debugfs_regs()
154 drm_print_regset32(&p, &vc4_hdmi->cec_regset); in vc4_hdmi_debugfs_regs()
155 drm_print_regset32(&p, &vc4_hdmi->csc_regset); in vc4_hdmi_debugfs_regs()
156 drm_print_regset32(&p, &vc4_hdmi->dvp_regset); in vc4_hdmi_debugfs_regs()
157 drm_print_regset32(&p, &vc4_hdmi->phy_regset); in vc4_hdmi_debugfs_regs()
158 drm_print_regset32(&p, &vc4_hdmi->ram_regset); in vc4_hdmi_debugfs_regs()
159 drm_print_regset32(&p, &vc4_hdmi->rm_regset); in vc4_hdmi_debugfs_regs()
161 pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_debugfs_regs()
170 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_reset()
176 * connector->dev pointer might not be initialised yet. in vc4_hdmi_reset()
181 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_reset()
195 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_reset()
203 struct drm_device *drm = vc4_hdmi->connector.dev; in vc5_hdmi_reset()
209 * connector->dev pointer might not be initialised yet. in vc5_hdmi_reset()
214 reset_control_reset(vc4_hdmi->reset); in vc5_hdmi_reset()
216 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_reset()
223 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_reset()
232 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_cec_update_clk_div()
248 cec_rate = clk_get_rate(vc4_hdmi->cec_clock); in vc4_hdmi_cec_update_clk_div()
250 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_update_clk_div()
263 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_update_clk_div()
279 state = drm_atomic_state_alloc(crtc->dev); in reset_pipe()
281 return -ENOMEM; in reset_pipe()
283 state->acquire_ctx = ctx; in reset_pipe()
291 crtc_state->connectors_changed = true; in reset_pipe()
315 drm = connector->dev; in vc4_hdmi_reset_link()
316 ret = drm_modeset_lock(&drm->mode_config.connection_mutex, ctx); in vc4_hdmi_reset_link()
320 conn_state = connector->state; in vc4_hdmi_reset_link()
321 crtc = conn_state->crtc; in vc4_hdmi_reset_link()
325 ret = drm_modeset_lock(&crtc->mutex, ctx); in vc4_hdmi_reset_link()
329 crtc_state = crtc->state; in vc4_hdmi_reset_link()
330 if (!crtc_state->active) in vc4_hdmi_reset_link()
334 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
337 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
341 scrambling_needed = vc4_hdmi_mode_needs_scrambling(&vc4_hdmi->saved_adjusted_mode, in vc4_hdmi_reset_link()
342 vc4_hdmi->output_bpc, in vc4_hdmi_reset_link()
343 vc4_hdmi->output_format); in vc4_hdmi_reset_link()
345 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
349 if (conn_state->commit && in vc4_hdmi_reset_link()
350 !try_wait_for_completion(&conn_state->commit->hw_done)) { in vc4_hdmi_reset_link()
351 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
355 ret = drm_scdc_readb(connector->ddc, SCDC_TMDS_CONFIG, &config); in vc4_hdmi_reset_link()
358 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
363 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
367 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_reset_link()
385 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_handle_hotplug()
390 * NOTE: This function should really be called with vc4_hdmi->mutex in vc4_hdmi_handle_hotplug()
404 cec_phys_addr_invalidate(vc4_hdmi->cec_adap); in vc4_hdmi_handle_hotplug()
408 drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc); in vc4_hdmi_handle_hotplug()
411 cec_s_phys_addr(vc4_hdmi->cec_adap, in vc4_hdmi_handle_hotplug()
412 connector->display_info.source_physical_address, false); in vc4_hdmi_handle_hotplug()
421 if (ret == -EDEADLK) { in vc4_hdmi_handle_hotplug()
439 * NOTE: This function should really take vc4_hdmi->mutex, but in vc4_hdmi_connector_detect_ctx()
449 ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); in vc4_hdmi_connector_detect_ctx()
451 drm_err_once(connector->dev, "Failed to retain HDMI power domain: %d\n", in vc4_hdmi_connector_detect_ctx()
456 if (vc4_hdmi->hpd_gpio) { in vc4_hdmi_connector_detect_ctx()
457 if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) in vc4_hdmi_connector_detect_ctx()
460 if (vc4_hdmi->variant->hp_detect && in vc4_hdmi_connector_detect_ctx()
461 vc4_hdmi->variant->hp_detect(vc4_hdmi)) in vc4_hdmi_connector_detect_ctx()
466 pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_connector_detect_ctx()
474 struct vc4_dev *vc4 = to_vc4_dev(connector->dev); in vc4_hdmi_connector_get_modes()
479 * NOTE: This function should really take vc4_hdmi->mutex, but doing so in vc4_hdmi_connector_get_modes()
489 drm_edid = drm_edid_read_ddc(connector, vc4_hdmi->ddc); in vc4_hdmi_connector_get_modes()
491 cec_s_phys_addr(vc4_hdmi->cec_adap, in vc4_hdmi_connector_get_modes()
492 connector->display_info.source_physical_address, false); in vc4_hdmi_connector_get_modes()
499 if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) { in vc4_hdmi_connector_get_modes()
500 struct drm_device *drm = connector->dev; in vc4_hdmi_connector_get_modes()
503 list_for_each_entry(mode, &connector->probed_modes, head) { in vc4_hdmi_connector_get_modes()
521 struct drm_crtc *crtc = new_state->crtc; in vc4_hdmi_connector_atomic_check()
526 if (old_state->tv.margins.left != new_state->tv.margins.left || in vc4_hdmi_connector_atomic_check()
527 old_state->tv.margins.right != new_state->tv.margins.right || in vc4_hdmi_connector_atomic_check()
528 old_state->tv.margins.top != new_state->tv.margins.top || in vc4_hdmi_connector_atomic_check()
529 old_state->tv.margins.bottom != new_state->tv.margins.bottom) { in vc4_hdmi_connector_atomic_check()
552 if (old_state->colorspace != new_state->colorspace) { in vc4_hdmi_connector_atomic_check()
559 crtc_state->mode_changed = true; in vc4_hdmi_connector_atomic_check()
568 __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); in vc4_hdmi_connector_reset()
590 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_connector_init()
591 struct drm_encoder *encoder = &vc4_hdmi->encoder.base; in vc4_hdmi_connector_init()
595 if (vc4_hdmi->variant->supports_hdr) in vc4_hdmi_connector_init()
603 vc4_hdmi->ddc, in vc4_hdmi_connector_init()
617 if (connector->funcs->reset) in vc4_hdmi_connector_init()
618 connector->funcs->reset(connector); in vc4_hdmi_connector_init()
632 connector->polled = (DRM_CONNECTOR_POLL_CONNECT | in vc4_hdmi_connector_init()
635 connector->interlace_allowed = 1; in vc4_hdmi_connector_init()
636 connector->doublescan_allowed = 0; in vc4_hdmi_connector_init()
637 connector->stereo_allowed = 1; in vc4_hdmi_connector_init()
652 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_stop_packet()
653 u32 packet_id = type - 0x80; in vc4_hdmi_stop_packet()
659 return -ENODEV; in vc4_hdmi_stop_packet()
661 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_stop_packet()
664 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_stop_packet()
680 struct drm_device *drm = connector->dev; in vc4_hdmi_write_infoframe()
681 u32 packet_id = type - 0x80; in vc4_hdmi_write_infoframe()
683 &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; in vc4_hdmi_write_infoframe()
684 u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; in vc4_hdmi_write_infoframe()
685 u32 packet_reg_next = ram_packet_start->offset + in vc4_hdmi_write_infoframe()
688 ram_packet_start->reg); in vc4_hdmi_write_infoframe()
699 ret = -ENOMEM; in vc4_hdmi_write_infoframe()
715 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_write_infoframe()
742 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_write_infoframe()
759 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_enable_scrambling()
760 struct drm_device *drm = connector->dev; in vc4_hdmi_enable_scrambling()
761 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; in vc4_hdmi_enable_scrambling()
765 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_enable_scrambling()
771 vc4_hdmi->output_bpc, in vc4_hdmi_enable_scrambling()
772 vc4_hdmi->output_format)) in vc4_hdmi_enable_scrambling()
781 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_enable_scrambling()
784 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_enable_scrambling()
788 vc4_hdmi->scdc_enabled = true; in vc4_hdmi_enable_scrambling()
790 queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, in vc4_hdmi_enable_scrambling()
797 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_disable_scrambling()
798 struct drm_device *drm = connector->dev; in vc4_hdmi_disable_scrambling()
802 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_disable_scrambling()
804 if (!vc4_hdmi->scdc_enabled) in vc4_hdmi_disable_scrambling()
807 vc4_hdmi->scdc_enabled = false; in vc4_hdmi_disable_scrambling()
809 if (delayed_work_pending(&vc4_hdmi->scrambling_work)) in vc4_hdmi_disable_scrambling()
810 cancel_delayed_work_sync(&vc4_hdmi->scrambling_work); in vc4_hdmi_disable_scrambling()
815 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_disable_scrambling()
818 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_disable_scrambling()
831 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_scrambling_wq()
839 queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, in vc4_hdmi_scrambling_wq()
847 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_encoder_post_crtc_disable()
851 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_disable()
853 vc4_hdmi->packet_ram_enabled = false; in vc4_hdmi_encoder_post_crtc_disable()
858 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_disable()
864 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_disable()
868 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_disable()
871 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_disable()
878 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_disable()
885 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_encoder_post_crtc_powerdown()
890 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_powerdown()
895 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_powerdown()
898 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_powerdown()
900 if (vc4_hdmi->variant->phy_disable) in vc4_hdmi_encoder_post_crtc_powerdown()
901 vc4_hdmi->variant->phy_disable(vc4_hdmi); in vc4_hdmi_encoder_post_crtc_powerdown()
903 clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_encoder_post_crtc_powerdown()
904 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_post_crtc_powerdown()
906 ret = pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_encoder_post_crtc_powerdown()
913 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_powerdown()
920 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_csc_setup()
928 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_csc_setup()
933 if (state->hdmi.is_limited_range) { in vc4_hdmi_csc_setup()
936 * Apply a colorspace conversion to squash 0-255 down in vc4_hdmi_csc_setup()
937 * to 16-235. The matrix here is: in vc4_hdmi_csc_setup()
960 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_csc_setup()
973 * Full range - unity
989 * colorspace conversion to squash 0-255 down to 16-235.
1013 * [ -0.168736 -0.331264 0.500000 128 ]
1014 * [ 0.500000 -0.418688 -0.081312 128 ]
1024 * [ -0.147644 -0.289856 0.437500 128 ]
1025 * [ 0.437500 -0.366352 -0.071148 128 ]
1044 * [ -0.114572 -0.385428 0.500000 128 ]
1045 * [ 0.500000 -0.454153 -0.045847 128 ]
1056 * [ -0.100268 -0.337232 0.437500 128 ]
1057 * [ 0.437500 -0.397386 -0.040114 128 ]
1076 * [ -0.139630 -0.360370 0.500000 128 ]
1077 * [ 0.500000 -0.459786 -0.040214 128 ]
1087 * [ -0.122176 -0.315324 0.437500 128 ]
1088 * [ 0.437500 -0.402312 -0.035188 128 ]
1099 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc5_hdmi_set_csc_coeffs()
1112 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc5_hdmi_set_csc_coeffs_swap()
1155 struct drm_device *drm = vc4_hdmi->connector.dev; in vc5_hdmi_csc_setup()
1156 unsigned int lim_range = state->hdmi.is_limited_range ? 1 : 0; in vc5_hdmi_csc_setup()
1169 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_csc_setup()
1171 switch (state->hdmi.output_format) { in vc5_hdmi_csc_setup()
1173 csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range); in vc5_hdmi_csc_setup()
1179 csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range); in vc5_hdmi_csc_setup()
1210 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_csc_setup()
1219 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_set_timings()
1220 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc4_hdmi_set_timings()
1221 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc4_hdmi_set_timings()
1222 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; in vc4_hdmi_set_timings()
1223 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; in vc4_hdmi_set_timings()
1224 u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, in vc4_hdmi_set_timings()
1226 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, in vc4_hdmi_set_timings()
1228 VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL)); in vc4_hdmi_set_timings()
1230 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + in vc4_hdmi_set_timings()
1234 VC4_SET_FIELD(mode->crtc_vtotal - in vc4_hdmi_set_timings()
1235 mode->crtc_vsync_end, in vc4_hdmi_set_timings()
1244 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_set_timings()
1249 VC4_SET_FIELD(mode->hdisplay * pixel_rep, in vc4_hdmi_set_timings()
1253 VC4_SET_FIELD((mode->htotal - in vc4_hdmi_set_timings()
1254 mode->hsync_end) * pixel_rep, in vc4_hdmi_set_timings()
1256 VC4_SET_FIELD((mode->hsync_end - in vc4_hdmi_set_timings()
1257 mode->hsync_start) * pixel_rep, in vc4_hdmi_set_timings()
1259 VC4_SET_FIELD((mode->hsync_start - in vc4_hdmi_set_timings()
1260 mode->hdisplay) * pixel_rep, in vc4_hdmi_set_timings()
1271 reg |= VC4_SET_FIELD(pixel_rep - 1, VC4_HDMI_MISC_CONTROL_PIXEL_REP); in vc4_hdmi_set_timings()
1274 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_set_timings()
1283 struct drm_device *drm = vc4_hdmi->connector.dev; in vc5_hdmi_set_timings()
1284 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc5_hdmi_set_timings()
1285 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc5_hdmi_set_timings()
1286 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; in vc5_hdmi_set_timings()
1287 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; in vc5_hdmi_set_timings()
1288 u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, in vc5_hdmi_set_timings()
1290 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, in vc5_hdmi_set_timings()
1292 VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); in vc5_hdmi_set_timings()
1293 u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep), in vc5_hdmi_set_timings()
1295 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + in vc5_hdmi_set_timings()
1299 VC4_SET_FIELD(mode->crtc_vtotal - in vc5_hdmi_set_timings()
1300 mode->crtc_vsync_end, in vc5_hdmi_set_timings()
1310 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_set_timings()
1315 VC4_SET_FIELD(mode->hdisplay * pixel_rep, in vc5_hdmi_set_timings()
1317 VC4_SET_FIELD((mode->hsync_start - in vc5_hdmi_set_timings()
1318 mode->hdisplay) * pixel_rep, in vc5_hdmi_set_timings()
1322 VC4_SET_FIELD((mode->htotal - in vc5_hdmi_set_timings()
1323 mode->hsync_end) * pixel_rep, in vc5_hdmi_set_timings()
1325 VC4_SET_FIELD((mode->hsync_end - in vc5_hdmi_set_timings()
1326 mode->hsync_start) * pixel_rep, in vc5_hdmi_set_timings()
1335 switch (state->hdmi.output_bpc) { in vc5_hdmi_set_timings()
1349 * YCC422 is always 36-bit and not considered deep colour so in vc5_hdmi_set_timings()
1352 if (state->hdmi.output_format == HDMI_COLORSPACE_YUV422) { in vc5_hdmi_set_timings()
1376 reg |= VC4_SET_FIELD(pixel_rep - 1, VC5_HDMI_MISC_CONTROL_PIXEL_REP); in vc5_hdmi_set_timings()
1381 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_set_timings()
1388 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_recenter_fifo()
1397 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_recenter_fifo()
1407 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_recenter_fifo()
1411 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_recenter_fifo()
1418 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_recenter_fifo()
1432 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_encoder_pre_crtc_configure()
1433 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_encoder_pre_crtc_configure()
1436 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; in vc4_hdmi_encoder_pre_crtc_configure()
1437 unsigned long long tmds_char_rate = conn_state->hdmi.tmds_char_rate; in vc4_hdmi_encoder_pre_crtc_configure()
1443 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_pre_crtc_configure()
1448 ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); in vc4_hdmi_encoder_pre_crtc_configure()
1464 * both clocks. Which, for RPi0-3 implies a maximum pixel clock of in vc4_hdmi_encoder_pre_crtc_configure()
1473 ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate); in vc4_hdmi_encoder_pre_crtc_configure()
1479 ret = clk_set_rate(vc4_hdmi->pixel_clock, tmds_char_rate); in vc4_hdmi_encoder_pre_crtc_configure()
1485 ret = clk_prepare_enable(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
1501 ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock, bvb_rate); in vc4_hdmi_encoder_pre_crtc_configure()
1507 ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_encoder_pre_crtc_configure()
1513 if (vc4_hdmi->variant->phy_init) in vc4_hdmi_encoder_pre_crtc_configure()
1514 vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state); in vc4_hdmi_encoder_pre_crtc_configure()
1516 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_pre_crtc_configure()
1523 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_pre_crtc_configure()
1525 if (vc4_hdmi->variant->set_timings) in vc4_hdmi_encoder_pre_crtc_configure()
1526 vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); in vc4_hdmi_encoder_pre_crtc_configure()
1530 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_pre_crtc_configure()
1535 clk_disable_unprepare(vc4_hdmi->pixel_clock); in vc4_hdmi_encoder_pre_crtc_configure()
1537 pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_encoder_pre_crtc_configure()
1541 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_pre_crtc_configure()
1549 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_encoder_pre_crtc_enable()
1550 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_encoder_pre_crtc_enable()
1551 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; in vc4_hdmi_encoder_pre_crtc_enable()
1557 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_pre_crtc_enable()
1562 if (vc4_hdmi->variant->csc_setup) in vc4_hdmi_encoder_pre_crtc_enable()
1563 vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode); in vc4_hdmi_encoder_pre_crtc_enable()
1565 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_pre_crtc_enable()
1567 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_pre_crtc_enable()
1572 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_pre_crtc_enable()
1579 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_encoder_post_crtc_enable()
1580 struct drm_device *drm = connector->dev; in vc4_hdmi_encoder_post_crtc_enable()
1581 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; in vc4_hdmi_encoder_post_crtc_enable()
1582 struct drm_display_info *display = &vc4_hdmi->connector.display_info; in vc4_hdmi_encoder_post_crtc_enable()
1583 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; in vc4_hdmi_encoder_post_crtc_enable()
1584 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; in vc4_hdmi_encoder_post_crtc_enable()
1589 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_enable()
1594 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_enable()
1608 if (display->is_hdmi) { in vc4_hdmi_encoder_post_crtc_enable()
1613 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_enable()
1627 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_enable()
1635 if (display->is_hdmi) { in vc4_hdmi_encoder_post_crtc_enable()
1636 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_enable()
1644 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_encoder_post_crtc_enable()
1645 vc4_hdmi->packet_ram_enabled = true; in vc4_hdmi_encoder_post_crtc_enable()
1656 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_post_crtc_enable()
1665 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_atomic_mode_set()
1666 drm_mode_copy(&vc4_hdmi->saved_adjusted_mode, in vc4_hdmi_encoder_atomic_mode_set()
1667 &crtc_state->adjusted_mode); in vc4_hdmi_encoder_atomic_mode_set()
1668 vc4_hdmi->output_bpc = conn_state->hdmi.output_bpc; in vc4_hdmi_encoder_atomic_mode_set()
1669 vc4_hdmi->output_format = conn_state->hdmi.output_format; in vc4_hdmi_encoder_atomic_mode_set()
1670 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_encoder_atomic_mode_set()
1679 struct vc4_dev *vc4 = to_vc4_dev(connector->dev); in vc4_hdmi_connector_clock_valid()
1681 if (clock > vc4_hdmi->variant->max_pixel_clock) in vc4_hdmi_connector_clock_valid()
1684 if (!vc4->hvs->vc5_hdmi_enable_hdmi_20 && clock > HDMI_14_MAX_TMDS_CLK) in vc4_hdmi_connector_clock_valid()
1688 if (!vc4->hvs->vc5_hdmi_enable_4096by2160 && in vc4_hdmi_connector_clock_valid()
1689 mode->hdisplay > 3840 && mode->vdisplay >= 2160 && in vc4_hdmi_connector_clock_valid()
1709 struct drm_display_mode *mode = &crtc_state->adjusted_mode; in vc4_hdmi_encoder_atomic_check()
1710 unsigned long long tmds_char_rate = mode->clock * 1000; in vc4_hdmi_encoder_atomic_check()
1713 if (vc4_hdmi->variant->unsupported_odd_h_timings) { in vc4_hdmi_encoder_atomic_check()
1714 if (mode->flags & DRM_MODE_FLAG_DBLCLK) { in vc4_hdmi_encoder_atomic_check()
1721 if ((mode->hsync_start - mode->hdisplay) & 1) in vc4_hdmi_encoder_atomic_check()
1722 mode->hsync_start--; in vc4_hdmi_encoder_atomic_check()
1723 if ((mode->hsync_end - mode->hsync_start) & 1) in vc4_hdmi_encoder_atomic_check()
1724 mode->hsync_end--; in vc4_hdmi_encoder_atomic_check()
1728 if ((mode->hdisplay % 2) || (mode->hsync_start % 2) || in vc4_hdmi_encoder_atomic_check()
1729 (mode->hsync_end % 2) || (mode->htotal % 2)) in vc4_hdmi_encoder_atomic_check()
1730 return -EINVAL; in vc4_hdmi_encoder_atomic_check()
1740 if (vc4_hdmi->disable_wifi_frequencies && in vc4_hdmi_encoder_atomic_check()
1743 mode->clock = 238560; in vc4_hdmi_encoder_atomic_check()
1744 tmds_char_rate = mode->clock * 1000; in vc4_hdmi_encoder_atomic_check()
1757 if (vc4_hdmi->variant->unsupported_odd_h_timings && in vc4_hdmi_encoder_mode_valid()
1758 !(mode->flags & DRM_MODE_FLAG_DBLCLK) && in vc4_hdmi_encoder_mode_valid()
1759 ((mode->hdisplay % 2) || (mode->hsync_start % 2) || in vc4_hdmi_encoder_mode_valid()
1760 (mode->hsync_end % 2) || (mode->htotal % 2))) in vc4_hdmi_encoder_mode_valid()
1764 return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate); in vc4_hdmi_encoder_mode_valid()
1775 struct drm_device *drm = encoder->dev; in vc4_hdmi_late_register()
1777 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; in vc4_hdmi_late_register()
1779 drm_debugfs_add_file(drm, variant->debugfs_name, in vc4_hdmi_late_register()
1815 struct drm_device *drm = vc4_hdmi->connector.dev; in vc5_hdmi_hp_detect()
1823 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_hp_detect()
1825 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc5_hdmi_hp_detect()
1836 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_audio_set_mai_clock()
1845 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock); in vc4_hdmi_audio_set_mai_clock()
1853 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_set_mai_clock()
1856 VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M)); in vc4_hdmi_audio_set_mai_clock()
1857 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_set_mai_clock()
1864 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; in vc4_hdmi_set_n_cts()
1868 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_set_n_cts()
1869 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc4_hdmi_set_n_cts()
1872 tmp = (u64)(mode->clock * 1000) * n; in vc4_hdmi_set_n_cts()
1898 struct drm_display_info *display = &vc4_hdmi->connector.display_info; in vc4_hdmi_audio_can_stream()
1900 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_audio_can_stream()
1906 if (!display->is_hdmi) in vc4_hdmi_audio_can_stream()
1915 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_audio_startup()
1920 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_audio_startup()
1923 ret = -ENODEV; in vc4_hdmi_audio_startup()
1928 ret = -ENOTSUPP; in vc4_hdmi_audio_startup()
1932 vc4_hdmi->audio.streaming = true; in vc4_hdmi_audio_startup()
1934 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_startup()
1941 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_startup()
1943 if (vc4_hdmi->variant->phy_rng_enable) in vc4_hdmi_audio_startup()
1944 vc4_hdmi->variant->phy_rng_enable(vc4_hdmi); in vc4_hdmi_audio_startup()
1949 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_audio_startup()
1956 struct device *dev = &vc4_hdmi->pdev->dev; in vc4_hdmi_audio_reset()
1960 lockdep_assert_held(&vc4_hdmi->mutex); in vc4_hdmi_audio_reset()
1962 vc4_hdmi->audio.streaming = false; in vc4_hdmi_audio_reset()
1967 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_reset()
1973 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_reset()
1979 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_audio_shutdown()
1983 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_audio_shutdown()
1988 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_shutdown()
1995 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_shutdown()
1997 if (vc4_hdmi->variant->phy_rng_disable) in vc4_hdmi_audio_shutdown()
1998 vc4_hdmi->variant->phy_rng_disable(vc4_hdmi); in vc4_hdmi_audio_shutdown()
2000 vc4_hdmi->audio.streaming = false; in vc4_hdmi_audio_shutdown()
2006 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_audio_shutdown()
2053 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_audio_prepare()
2054 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_audio_prepare()
2056 unsigned int sample_rate = params->sample_rate; in vc4_hdmi_audio_prepare()
2057 unsigned int channels = params->channels; in vc4_hdmi_audio_prepare()
2067 sample_rate, params->sample_width, channels); in vc4_hdmi_audio_prepare()
2069 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_audio_prepare()
2072 ret = -ENODEV; in vc4_hdmi_audio_prepare()
2077 ret = -EINVAL; in vc4_hdmi_audio_prepare()
2083 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_prepare()
2091 if (params->iec.status[0] & IEC958_AES0_NONAUDIO && in vc4_hdmi_audio_prepare()
2092 params->channels == 8) in vc4_hdmi_audio_prepare()
2102 /* The B frame identifier should match the value used by alsa-lib (8) */ in vc4_hdmi_audio_prepare()
2108 channel_mask = GENMASK(channels - 1, 0); in vc4_hdmi_audio_prepare()
2113 if (vc4->gen >= VC4_GEN_5) in vc4_hdmi_audio_prepare()
2131 channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask); in vc4_hdmi_audio_prepare()
2137 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_audio_prepare()
2140 ¶ms->cea); in vc4_hdmi_audio_prepare()
2147 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_audio_prepare()
2153 .name = "vc4-hdmi-cpu-dai-component",
2161 snd_soc_dai_init_dma_data(dai, &vc4_hdmi->audio.dma_data, NULL); in vc4_hdmi_audio_cpu_dai_probe()
2171 .name = "vc4-hdmi-cpu-dai",
2186 .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-rx",
2194 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_audio_get_eld()
2196 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_audio_get_eld()
2197 memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); in vc4_hdmi_audio_get_eld()
2198 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_audio_get_eld()
2220 platform_device_unregister(vc4_hdmi->audio.codec_pdev); in vc4_hdmi_audio_codec_release()
2221 vc4_hdmi->audio.codec_pdev = NULL; in vc4_hdmi_audio_codec_release()
2227 &vc4_hdmi->variant->registers[HDMI_MAI_DATA]; in vc4_hdmi_audio_init()
2228 struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; in vc4_hdmi_audio_init()
2229 struct snd_soc_card *card = &vc4_hdmi->audio.card; in vc4_hdmi_audio_init()
2230 struct device *dev = &vc4_hdmi->pdev->dev; in vc4_hdmi_audio_init()
2256 if (!of_find_property(dev->of_node, "dmas", &len) || !len) { in vc4_hdmi_audio_init()
2262 if (mai_data->reg != VC4_HD) { in vc4_hdmi_audio_init()
2264 return -EINVAL; in vc4_hdmi_audio_init()
2274 index = of_property_match_string(dev->of_node, "reg-names", "hd"); in vc4_hdmi_audio_init()
2279 addr = of_get_address(dev->of_node, index, NULL, NULL); in vc4_hdmi_audio_init()
2281 return -EINVAL; in vc4_hdmi_audio_init()
2283 vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset; in vc4_hdmi_audio_init()
2284 vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in vc4_hdmi_audio_init()
2285 vc4_hdmi->audio.dma_data.maxburst = 2; in vc4_hdmi_audio_init()
2288 * NOTE: Strictly speaking, we should probably use a DRM-managed in vc4_hdmi_audio_init()
2293 * when registering, even when using non-device-managed in vc4_hdmi_audio_init()
2296 * If we call snd_soc_unregister_component() in a DRM-managed in vc4_hdmi_audio_init()
2297 * action, the device-managed actions have already been executed in vc4_hdmi_audio_init()
2300 * Using device-managed hooks here probably leaves us open to a in vc4_hdmi_audio_init()
2307 * Then, the vc4_hdmi structure is DRM-managed and thus only in vc4_hdmi_audio_init()
2332 vc4_hdmi->audio.codec_pdev = codec_pdev; in vc4_hdmi_audio_init()
2338 dai_link->cpus = &vc4_hdmi->audio.cpu; in vc4_hdmi_audio_init()
2339 dai_link->codecs = &vc4_hdmi->audio.codec; in vc4_hdmi_audio_init()
2340 dai_link->platforms = &vc4_hdmi->audio.platform; in vc4_hdmi_audio_init()
2342 dai_link->num_cpus = 1; in vc4_hdmi_audio_init()
2343 dai_link->num_codecs = 1; in vc4_hdmi_audio_init()
2344 dai_link->num_platforms = 1; in vc4_hdmi_audio_init()
2346 dai_link->name = "MAI"; in vc4_hdmi_audio_init()
2347 dai_link->stream_name = "MAI PCM"; in vc4_hdmi_audio_init()
2348 dai_link->codecs->dai_name = "i2s-hifi"; in vc4_hdmi_audio_init()
2349 dai_link->cpus->dai_name = dev_name(dev); in vc4_hdmi_audio_init()
2350 dai_link->codecs->name = dev_name(&codec_pdev->dev); in vc4_hdmi_audio_init()
2351 dai_link->platforms->name = dev_name(dev); in vc4_hdmi_audio_init()
2353 card->dai_link = dai_link; in vc4_hdmi_audio_init()
2354 card->num_links = 1; in vc4_hdmi_audio_init()
2355 card->name = vc4_hdmi->variant->card_name; in vc4_hdmi_audio_init()
2356 card->driver_name = "vc4-hdmi"; in vc4_hdmi_audio_init()
2357 card->dev = dev; in vc4_hdmi_audio_init()
2358 card->owner = THIS_MODULE; in vc4_hdmi_audio_init()
2362 * stores a pointer to the snd card object in dev->driver_data. This in vc4_hdmi_audio_init()
2363 * means we cannot use it for something else. The hdmi back-pointer is in vc4_hdmi_audio_init()
2364 * now stored in card->drvdata and should be retrieved with in vc4_hdmi_audio_init()
2379 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_hpd_irq_thread()
2380 struct drm_device *dev = connector->dev; in vc4_hdmi_hpd_irq_thread()
2382 if (dev && dev->registered) in vc4_hdmi_hpd_irq_thread()
2390 struct drm_connector *connector = &vc4_hdmi->connector; in vc4_hdmi_hotplug_init()
2391 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_hotplug_init()
2394 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_hotplug_init()
2395 unsigned int hpd_con = platform_get_irq_byname(pdev, "hpd-connected"); in vc4_hdmi_hotplug_init()
2396 unsigned int hpd_rm = platform_get_irq_byname(pdev, "hpd-removed"); in vc4_hdmi_hotplug_init()
2398 ret = devm_request_threaded_irq(&pdev->dev, hpd_con, in vc4_hdmi_hotplug_init()
2405 ret = devm_request_threaded_irq(&pdev->dev, hpd_rm, in vc4_hdmi_hotplug_init()
2412 connector->polled = DRM_CONNECTOR_POLL_HPD; in vc4_hdmi_hotplug_init()
2423 if (vc4_hdmi->cec_rx_msg.len) in vc4_cec_irq_handler_rx_thread()
2424 cec_received_msg(vc4_hdmi->cec_adap, in vc4_cec_irq_handler_rx_thread()
2425 &vc4_hdmi->cec_rx_msg); in vc4_cec_irq_handler_rx_thread()
2434 if (vc4_hdmi->cec_tx_ok) { in vc4_cec_irq_handler_tx_thread()
2435 cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK, in vc4_cec_irq_handler_tx_thread()
2442 cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_NACK, in vc4_cec_irq_handler_tx_thread()
2453 if (vc4_hdmi->cec_irq_was_rx) in vc4_cec_irq_handler_thread()
2463 struct drm_device *dev = vc4_hdmi->connector.dev; in vc4_cec_read_msg()
2464 struct cec_msg *msg = &vc4_hdmi->cec_rx_msg; in vc4_cec_read_msg()
2467 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc4_cec_read_msg()
2469 msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >> in vc4_cec_read_msg()
2472 if (msg->len > 16) { in vc4_cec_read_msg()
2473 drm_err(dev, "Attempting to read too much data (%d)\n", msg->len); in vc4_cec_read_msg()
2477 for (i = 0; i < msg->len; i += 4) { in vc4_cec_read_msg()
2480 msg->msg[i] = val & 0xff; in vc4_cec_read_msg()
2481 msg->msg[i + 1] = (val >> 8) & 0xff; in vc4_cec_read_msg()
2482 msg->msg[i + 2] = (val >> 16) & 0xff; in vc4_cec_read_msg()
2483 msg->msg[i + 3] = (val >> 24) & 0xff; in vc4_cec_read_msg()
2502 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_tx_bare_locked()
2505 vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD; in vc4_cec_irq_handler_tx_bare_locked()
2517 spin_lock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_tx_bare()
2519 spin_unlock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_tx_bare()
2528 lockdep_assert_held(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_rx_bare_locked()
2541 vc4_hdmi->cec_rx_msg.len = 0; in vc4_cec_irq_handler_rx_bare_locked()
2558 spin_lock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_rx_bare()
2560 spin_unlock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler_rx_bare()
2586 spin_lock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler()
2588 vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT; in vc4_cec_irq_handler()
2589 if (vc4_hdmi->cec_irq_was_rx) in vc4_cec_irq_handler()
2595 spin_unlock(&vc4_hdmi->hw_lock); in vc4_cec_irq_handler()
2603 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_cec_enable()
2619 ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); in vc4_hdmi_cec_enable()
2625 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_cec_enable()
2627 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_enable()
2656 if (!vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_enable()
2659 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_enable()
2661 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_cec_enable()
2670 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_cec_disable()
2682 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_cec_disable()
2684 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_disable()
2686 if (!vc4_hdmi->variant->external_irq_controller) in vc4_hdmi_cec_disable()
2692 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_disable()
2694 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_cec_disable()
2696 pm_runtime_put(&vc4_hdmi->pdev->dev); in vc4_hdmi_cec_disable()
2714 struct drm_device *drm = vc4_hdmi->connector.dev; in vc4_hdmi_cec_adap_log_addr()
2726 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_cec_adap_log_addr()
2727 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_adap_log_addr()
2731 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_adap_log_addr()
2732 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_cec_adap_log_addr()
2743 struct drm_device *dev = vc4_hdmi->connector.dev; in vc4_hdmi_cec_adap_transmit()
2750 return -ENODEV; in vc4_hdmi_cec_adap_transmit()
2752 if (msg->len > 16) { in vc4_hdmi_cec_adap_transmit()
2753 drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len); in vc4_hdmi_cec_adap_transmit()
2755 return -ENOMEM; in vc4_hdmi_cec_adap_transmit()
2758 mutex_lock(&vc4_hdmi->mutex); in vc4_hdmi_cec_adap_transmit()
2760 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_adap_transmit()
2762 for (i = 0; i < msg->len; i += 4) in vc4_hdmi_cec_adap_transmit()
2764 (msg->msg[i]) | in vc4_hdmi_cec_adap_transmit()
2765 (msg->msg[i + 1] << 8) | in vc4_hdmi_cec_adap_transmit()
2766 (msg->msg[i + 2] << 16) | in vc4_hdmi_cec_adap_transmit()
2767 (msg->msg[i + 3] << 24)); in vc4_hdmi_cec_adap_transmit()
2773 val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT; in vc4_hdmi_cec_adap_transmit()
2778 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_cec_adap_transmit()
2779 mutex_unlock(&vc4_hdmi->mutex); in vc4_hdmi_cec_adap_transmit()
2795 cec_unregister_adapter(vc4_hdmi->cec_adap); in vc4_hdmi_cec_release()
2796 vc4_hdmi->cec_adap = NULL; in vc4_hdmi_cec_release()
2802 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_cec_init()
2803 struct device *dev = &pdev->dev; in vc4_hdmi_cec_init()
2806 if (!of_property_present(dev->of_node, "interrupts")) { in vc4_hdmi_cec_init()
2811 vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops, in vc4_hdmi_cec_init()
2813 vc4_hdmi->variant->card_name, in vc4_hdmi_cec_init()
2816 ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap); in vc4_hdmi_cec_init()
2820 cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector); in vc4_hdmi_cec_init()
2821 cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info); in vc4_hdmi_cec_init()
2823 if (vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_cec_init()
2824 ret = devm_request_threaded_irq(dev, platform_get_irq_byname(pdev, "cec-rx"), in vc4_hdmi_cec_init()
2827 "vc4 hdmi cec rx", vc4_hdmi); in vc4_hdmi_cec_init()
2831 ret = devm_request_threaded_irq(dev, platform_get_irq_byname(pdev, "cec-tx"), in vc4_hdmi_cec_init()
2846 ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev); in vc4_hdmi_cec_init()
2851 * NOTE: Strictly speaking, we should probably use a DRM-managed in vc4_hdmi_cec_init()
2859 * By the time the device-managed hook is executed, we will give in vc4_hdmi_cec_init()
2869 * moment, we could end up with a use-after-free. Fortunately, in vc4_hdmi_cec_init()
2880 cec_delete_adapter(vc4_hdmi->cec_adap); in vc4_hdmi_cec_init()
2903 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; in vc4_hdmi_build_regset()
2909 regs = kcalloc(variant->num_registers, sizeof(*regs), in vc4_hdmi_build_regset()
2912 return -ENOMEM; in vc4_hdmi_build_regset()
2914 for (i = 0; i < variant->num_registers; i++) { in vc4_hdmi_build_regset()
2915 const struct vc4_hdmi_register *field = &variant->registers[i]; in vc4_hdmi_build_regset()
2917 if (field->reg != reg) in vc4_hdmi_build_regset()
2920 regs[count].name = field->name; in vc4_hdmi_build_regset()
2921 regs[count].offset = field->offset; in vc4_hdmi_build_regset()
2927 return -ENOMEM; in vc4_hdmi_build_regset()
2929 regset->base = __vc4_hdmi_get_field_base(vc4_hdmi, reg); in vc4_hdmi_build_regset()
2930 regset->regs = new_regs; in vc4_hdmi_build_regset()
2931 regset->nregs = count; in vc4_hdmi_build_regset()
2943 struct platform_device *pdev = vc4_hdmi->pdev; in vc4_hdmi_init_resources()
2944 struct device *dev = &pdev->dev; in vc4_hdmi_init_resources()
2947 vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0); in vc4_hdmi_init_resources()
2948 if (IS_ERR(vc4_hdmi->hdmicore_regs)) in vc4_hdmi_init_resources()
2949 return PTR_ERR(vc4_hdmi->hdmicore_regs); in vc4_hdmi_init_resources()
2951 vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1); in vc4_hdmi_init_resources()
2952 if (IS_ERR(vc4_hdmi->hd_regs)) in vc4_hdmi_init_resources()
2953 return PTR_ERR(vc4_hdmi->hd_regs); in vc4_hdmi_init_resources()
2955 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD); in vc4_hdmi_init_resources()
2959 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI); in vc4_hdmi_init_resources()
2963 vc4_hdmi->pixel_clock = devm_clk_get(dev, "pixel"); in vc4_hdmi_init_resources()
2964 if (IS_ERR(vc4_hdmi->pixel_clock)) { in vc4_hdmi_init_resources()
2965 ret = PTR_ERR(vc4_hdmi->pixel_clock); in vc4_hdmi_init_resources()
2966 if (ret != -EPROBE_DEFER) in vc4_hdmi_init_resources()
2971 vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi"); in vc4_hdmi_init_resources()
2972 if (IS_ERR(vc4_hdmi->hsm_clock)) { in vc4_hdmi_init_resources()
2974 return PTR_ERR(vc4_hdmi->hsm_clock); in vc4_hdmi_init_resources()
2976 vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock; in vc4_hdmi_init_resources()
2977 vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock; in vc4_hdmi_init_resources()
2985 struct platform_device *pdev = vc4_hdmi->pdev; in vc5_hdmi_init_resources()
2986 struct device *dev = &pdev->dev; in vc5_hdmi_init_resources()
2992 return -ENODEV; in vc5_hdmi_init_resources()
2994 vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start, in vc5_hdmi_init_resources()
2996 if (!vc4_hdmi->hdmicore_regs) in vc5_hdmi_init_resources()
2997 return -ENOMEM; in vc5_hdmi_init_resources()
3001 return -ENODEV; in vc5_hdmi_init_resources()
3003 vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3004 if (!vc4_hdmi->hd_regs) in vc5_hdmi_init_resources()
3005 return -ENOMEM; in vc5_hdmi_init_resources()
3009 return -ENODEV; in vc5_hdmi_init_resources()
3011 vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3012 if (!vc4_hdmi->cec_regs) in vc5_hdmi_init_resources()
3013 return -ENOMEM; in vc5_hdmi_init_resources()
3017 return -ENODEV; in vc5_hdmi_init_resources()
3019 vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3020 if (!vc4_hdmi->csc_regs) in vc5_hdmi_init_resources()
3021 return -ENOMEM; in vc5_hdmi_init_resources()
3025 return -ENODEV; in vc5_hdmi_init_resources()
3027 vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3028 if (!vc4_hdmi->dvp_regs) in vc5_hdmi_init_resources()
3029 return -ENOMEM; in vc5_hdmi_init_resources()
3033 return -ENODEV; in vc5_hdmi_init_resources()
3035 vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3036 if (!vc4_hdmi->phy_regs) in vc5_hdmi_init_resources()
3037 return -ENOMEM; in vc5_hdmi_init_resources()
3041 return -ENODEV; in vc5_hdmi_init_resources()
3043 vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3044 if (!vc4_hdmi->ram_regs) in vc5_hdmi_init_resources()
3045 return -ENOMEM; in vc5_hdmi_init_resources()
3049 return -ENODEV; in vc5_hdmi_init_resources()
3051 vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res)); in vc5_hdmi_init_resources()
3052 if (!vc4_hdmi->rm_regs) in vc5_hdmi_init_resources()
3053 return -ENOMEM; in vc5_hdmi_init_resources()
3055 vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi"); in vc5_hdmi_init_resources()
3056 if (IS_ERR(vc4_hdmi->hsm_clock)) { in vc5_hdmi_init_resources()
3058 return PTR_ERR(vc4_hdmi->hsm_clock); in vc5_hdmi_init_resources()
3061 vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb"); in vc5_hdmi_init_resources()
3062 if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) { in vc5_hdmi_init_resources()
3064 return PTR_ERR(vc4_hdmi->pixel_bvb_clock); in vc5_hdmi_init_resources()
3067 vc4_hdmi->audio_clock = devm_clk_get(dev, "audio"); in vc5_hdmi_init_resources()
3068 if (IS_ERR(vc4_hdmi->audio_clock)) { in vc5_hdmi_init_resources()
3070 return PTR_ERR(vc4_hdmi->audio_clock); in vc5_hdmi_init_resources()
3073 vc4_hdmi->cec_clock = devm_clk_get(dev, "cec"); in vc5_hdmi_init_resources()
3074 if (IS_ERR(vc4_hdmi->cec_clock)) { in vc5_hdmi_init_resources()
3076 return PTR_ERR(vc4_hdmi->cec_clock); in vc5_hdmi_init_resources()
3079 vc4_hdmi->reset = devm_reset_control_get(dev, NULL); in vc5_hdmi_init_resources()
3080 if (IS_ERR(vc4_hdmi->reset)) { in vc5_hdmi_init_resources()
3082 return PTR_ERR(vc4_hdmi->reset); in vc5_hdmi_init_resources()
3085 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI); in vc5_hdmi_init_resources()
3089 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD); in vc5_hdmi_init_resources()
3093 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->cec_regset, VC5_CEC); in vc5_hdmi_init_resources()
3097 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->csc_regset, VC5_CSC); in vc5_hdmi_init_resources()
3101 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->dvp_regset, VC5_DVP); in vc5_hdmi_init_resources()
3105 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->phy_regset, VC5_PHY); in vc5_hdmi_init_resources()
3109 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->ram_regset, VC5_RAM); in vc5_hdmi_init_resources()
3113 ret = vc4_hdmi_build_regset(drm, vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM); in vc5_hdmi_init_resources()
3124 clk_disable_unprepare(vc4_hdmi->hsm_clock); in vc4_hdmi_runtime_suspend()
3137 ret = clk_prepare_enable(vc4_hdmi->hsm_clock); in vc4_hdmi_runtime_resume()
3150 rate = clk_get_rate(vc4_hdmi->hsm_clock); in vc4_hdmi_runtime_resume()
3152 ret = -EINVAL; in vc4_hdmi_runtime_resume()
3156 if (vc4_hdmi->variant->reset) in vc4_hdmi_runtime_resume()
3157 vc4_hdmi->variant->reset(vc4_hdmi); in vc4_hdmi_runtime_resume()
3160 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_runtime_resume()
3165 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_runtime_resume()
3169 if (!vc4_hdmi->variant->external_irq_controller) { in vc4_hdmi_runtime_resume()
3170 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_runtime_resume()
3172 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); in vc4_hdmi_runtime_resume()
3179 clk_disable_unprepare(vc4_hdmi->hsm_clock); in vc4_hdmi_runtime_resume()
3187 put_device(&vc4_hdmi->ddc->dev); in vc4_hdmi_put_ddc_device()
3202 return -ENOMEM; in vc4_hdmi_bind()
3204 ret = drmm_mutex_init(drm, &vc4_hdmi->mutex); in vc4_hdmi_bind()
3208 spin_lock_init(&vc4_hdmi->hw_lock); in vc4_hdmi_bind()
3209 INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); in vc4_hdmi_bind()
3212 encoder = &vc4_hdmi->encoder.base; in vc4_hdmi_bind()
3213 vc4_hdmi->encoder.type = variant->encoder_type; in vc4_hdmi_bind()
3214 vc4_hdmi->encoder.pre_crtc_configure = vc4_hdmi_encoder_pre_crtc_configure; in vc4_hdmi_bind()
3215 vc4_hdmi->encoder.pre_crtc_enable = vc4_hdmi_encoder_pre_crtc_enable; in vc4_hdmi_bind()
3216 vc4_hdmi->encoder.post_crtc_enable = vc4_hdmi_encoder_post_crtc_enable; in vc4_hdmi_bind()
3217 vc4_hdmi->encoder.post_crtc_disable = vc4_hdmi_encoder_post_crtc_disable; in vc4_hdmi_bind()
3218 vc4_hdmi->encoder.post_crtc_powerdown = vc4_hdmi_encoder_post_crtc_powerdown; in vc4_hdmi_bind()
3219 vc4_hdmi->pdev = pdev; in vc4_hdmi_bind()
3220 vc4_hdmi->variant = variant; in vc4_hdmi_bind()
3228 if (variant->max_pixel_clock > HDMI_14_MAX_TMDS_CLK) in vc4_hdmi_bind()
3229 vc4_hdmi->scdc_enabled = true; in vc4_hdmi_bind()
3231 ret = variant->init_resources(drm, vc4_hdmi); in vc4_hdmi_bind()
3235 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); in vc4_hdmi_bind()
3237 drm_err(drm, "Failed to find ddc node in device tree\n"); in vc4_hdmi_bind()
3238 return -ENODEV; in vc4_hdmi_bind()
3241 vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); in vc4_hdmi_bind()
3243 if (!vc4_hdmi->ddc) { in vc4_hdmi_bind()
3244 drm_err(drm, "Failed to get ddc i2c adapter by node\n"); in vc4_hdmi_bind()
3245 return -EPROBE_DEFER; in vc4_hdmi_bind()
3255 vc4_hdmi->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); in vc4_hdmi_bind()
3256 if (IS_ERR(vc4_hdmi->hpd_gpio)) { in vc4_hdmi_bind()
3257 return PTR_ERR(vc4_hdmi->hpd_gpio); in vc4_hdmi_bind()
3260 vc4_hdmi->disable_wifi_frequencies = in vc4_hdmi_bind()
3261 of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence"); in vc4_hdmi_bind()
3275 if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") || in vc4_hdmi_bind()
3276 of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) && in vc4_hdmi_bind()
3278 clk_prepare_enable(vc4_hdmi->pixel_clock); in vc4_hdmi_bind()
3279 clk_prepare_enable(vc4_hdmi->hsm_clock); in vc4_hdmi_bind()
3280 clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); in vc4_hdmi_bind()
3324 return component_add(&pdev->dev, &vc4_hdmi_ops); in vc4_hdmi_dev_probe()
3329 component_del(&pdev->dev, &vc4_hdmi_ops); in vc4_hdmi_dev_remove()
3335 .card_name = "vc4-hdmi",
3355 .card_name = "vc4-hdmi-0",
3384 .card_name = "vc4-hdmi-1",
3411 { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
3412 { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
3413 { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },