Lines Matching +full:0 +full:- +full:576
1 // SPDX-License-Identifier: GPL-2.0-or-later
19 #include <media/cec-notifier.h>
29 #include <linux/media-bus-format.h>
57 return drm_bridge_attach(encoder, encoder_hdmi->next_bridge, in meson_encoder_hdmi_attach()
58 &encoder_hdmi->bridge, flags); in meson_encoder_hdmi_attach()
65 cec_notifier_conn_unregister(encoder_hdmi->cec_notifier); in meson_encoder_hdmi_detach()
66 encoder_hdmi->cec_notifier = NULL; in meson_encoder_hdmi_detach()
72 struct meson_drm *priv = encoder_hdmi->priv; in meson_encoder_hdmi_set_vclk()
79 vclk_freq = mode->clock * 1000ULL; in meson_encoder_hdmi_set_vclk()
82 if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in meson_encoder_hdmi_set_vclk()
94 /* 480i/576i needs global pixel doubling */ in meson_encoder_hdmi_set_vclk()
95 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in meson_encoder_hdmi_set_vclk()
103 encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in meson_encoder_hdmi_set_vclk()
108 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in meson_encoder_hdmi_set_vclk()
111 dev_dbg(priv->dev, in meson_encoder_hdmi_set_vclk()
114 priv->venc.hdmi_use_enci); in meson_encoder_hdmi_set_vclk()
117 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); in meson_encoder_hdmi_set_vclk()
125 struct meson_drm *priv = encoder_hdmi->priv; in meson_encoder_hdmi_mode_valid()
126 bool is_hdmi2_sink = display_info->hdmi.scdc.supported; in meson_encoder_hdmi_mode_valid()
127 unsigned long long clock = mode->clock * 1000ULL; in meson_encoder_hdmi_mode_valid()
135 dev_dbg(priv->dev, "Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); in meson_encoder_hdmi_mode_valid()
137 /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ in meson_encoder_hdmi_mode_valid()
138 if (display_info->max_tmds_clock && in meson_encoder_hdmi_mode_valid()
139 mode->clock > display_info->max_tmds_clock && in meson_encoder_hdmi_mode_valid()
144 /* Check against non-VIC supported modes */ in meson_encoder_hdmi_mode_valid()
166 /* 480i/576i needs global pixel doubling */ in meson_encoder_hdmi_mode_valid()
167 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in meson_encoder_hdmi_mode_valid()
182 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in meson_encoder_hdmi_mode_valid()
185 dev_dbg(priv->dev, in meson_encoder_hdmi_mode_valid()
197 struct meson_drm *priv = encoder_hdmi->priv; in meson_encoder_hdmi_atomic_enable()
205 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); in meson_encoder_hdmi_atomic_enable()
213 crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); in meson_encoder_hdmi_atomic_enable()
217 mode = &crtc_state->adjusted_mode; in meson_encoder_hdmi_atomic_enable()
221 dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic); in meson_encoder_hdmi_atomic_enable()
223 if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { in meson_encoder_hdmi_atomic_enable()
226 } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) in meson_encoder_hdmi_atomic_enable()
229 /* VENC + VENC-DVI Mode setup */ in meson_encoder_hdmi_atomic_enable()
235 if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in meson_encoder_hdmi_atomic_enable()
236 /* Setup YUV420 to HDMI-TX, no 10bit diphering */ in meson_encoder_hdmi_atomic_enable()
238 priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); in meson_encoder_hdmi_atomic_enable()
239 else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) in meson_encoder_hdmi_atomic_enable()
240 /* Setup YUV422 to HDMI-TX, no 10bit diphering */ in meson_encoder_hdmi_atomic_enable()
242 priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); in meson_encoder_hdmi_atomic_enable()
244 /* Setup YUV444 to HDMI-TX, no 10bit diphering */ in meson_encoder_hdmi_atomic_enable()
245 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); in meson_encoder_hdmi_atomic_enable()
247 dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); in meson_encoder_hdmi_atomic_enable()
249 if (priv->venc.hdmi_use_enci) in meson_encoder_hdmi_atomic_enable()
250 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); in meson_encoder_hdmi_atomic_enable()
252 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); in meson_encoder_hdmi_atomic_enable()
259 struct meson_drm *priv = encoder_hdmi->priv; in meson_encoder_hdmi_atomic_disable()
261 writel_bits_relaxed(0x3, 0, in meson_encoder_hdmi_atomic_disable()
262 priv->io_base + _REG(VPU_HDMI_SETTING)); in meson_encoder_hdmi_atomic_disable()
264 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); in meson_encoder_hdmi_atomic_disable()
265 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); in meson_encoder_hdmi_atomic_disable()
285 *num_input_fmts = 0; in meson_encoder_hdmi_get_inp_bus_fmts()
287 for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) { in meson_encoder_hdmi_get_inp_bus_fmts()
296 input_fmts[0] = output_fmt; in meson_encoder_hdmi_get_inp_bus_fmts()
312 drm_atomic_get_old_connector_state(conn_state->state, conn_state->connector); in meson_encoder_hdmi_atomic_check()
313 struct meson_drm *priv = encoder_hdmi->priv; in meson_encoder_hdmi_atomic_check()
315 encoder_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; in meson_encoder_hdmi_atomic_check()
317 dev_dbg(priv->dev, "output_bus_fmt %lx\n", encoder_hdmi->output_bus_fmt); in meson_encoder_hdmi_atomic_check()
320 crtc_state->mode_changed = true; in meson_encoder_hdmi_atomic_check()
322 return 0; in meson_encoder_hdmi_atomic_check()
330 if (!encoder_hdmi->cec_notifier) in meson_encoder_hdmi_hpd_notify()
337 drm_edid = drm_bridge_edid_read(encoder_hdmi->next_bridge, in meson_encoder_hdmi_hpd_notify()
338 encoder_hdmi->connector); in meson_encoder_hdmi_hpd_notify()
344 * cec_notifier_set_phys_addr(encoder_hdmi->cec_notifier, in meson_encoder_hdmi_hpd_notify()
345 * connector->display_info.source_physical_address) from a path in meson_encoder_hdmi_hpd_notify()
351 cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); in meson_encoder_hdmi_hpd_notify()
355 cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); in meson_encoder_hdmi_hpd_notify()
379 meson_encoder_hdmi = devm_drm_bridge_alloc(priv->dev, in meson_encoder_hdmi_probe()
387 remote = of_graph_get_remote_node(priv->dev->of_node, 1, 0); in meson_encoder_hdmi_probe()
389 dev_err(priv->dev, "HDMI transceiver device is disabled"); in meson_encoder_hdmi_probe()
390 return 0; in meson_encoder_hdmi_probe()
393 meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote); in meson_encoder_hdmi_probe()
394 if (!meson_encoder_hdmi->next_bridge) { in meson_encoder_hdmi_probe()
395 ret = dev_err_probe(priv->dev, -EPROBE_DEFER, in meson_encoder_hdmi_probe()
401 meson_encoder_hdmi->bridge.of_node = priv->dev->of_node; in meson_encoder_hdmi_probe()
402 meson_encoder_hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; in meson_encoder_hdmi_probe()
403 meson_encoder_hdmi->bridge.interlace_allowed = true; in meson_encoder_hdmi_probe()
405 drm_bridge_add(&meson_encoder_hdmi->bridge); in meson_encoder_hdmi_probe()
407 meson_encoder_hdmi->priv = priv; in meson_encoder_hdmi_probe()
410 ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder, in meson_encoder_hdmi_probe()
413 dev_err_probe(priv->dev, ret, "Failed to init HDMI encoder\n"); in meson_encoder_hdmi_probe()
417 meson_encoder_hdmi->encoder.possible_crtcs = BIT(0); in meson_encoder_hdmi_probe()
420 ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL, in meson_encoder_hdmi_probe()
423 dev_err_probe(priv->dev, ret, "Failed to attach bridge\n"); in meson_encoder_hdmi_probe()
428 meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm, in meson_encoder_hdmi_probe()
429 &meson_encoder_hdmi->encoder); in meson_encoder_hdmi_probe()
430 if (IS_ERR(meson_encoder_hdmi->connector)) { in meson_encoder_hdmi_probe()
431 ret = dev_err_probe(priv->dev, in meson_encoder_hdmi_probe()
432 PTR_ERR(meson_encoder_hdmi->connector), in meson_encoder_hdmi_probe()
436 drm_connector_attach_encoder(meson_encoder_hdmi->connector, in meson_encoder_hdmi_probe()
437 &meson_encoder_hdmi->encoder); in meson_encoder_hdmi_probe()
441 …* encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[display connector bridge]->[display connector] in meson_encoder_hdmi_probe()
448 drm_atomic_helper_connector_reset(meson_encoder_hdmi->connector); in meson_encoder_hdmi_probe()
453 drm_connector_attach_hdr_output_metadata_property(meson_encoder_hdmi->connector); in meson_encoder_hdmi_probe()
455 drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8); in meson_encoder_hdmi_probe()
458 meson_encoder_hdmi->connector->ycbcr_420_allowed = true; in meson_encoder_hdmi_probe()
466 cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector); in meson_encoder_hdmi_probe()
468 notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info); in meson_encoder_hdmi_probe()
470 put_device(&pdev->dev); in meson_encoder_hdmi_probe()
471 return -ENOMEM; in meson_encoder_hdmi_probe()
474 meson_encoder_hdmi->cec_notifier = notifier; in meson_encoder_hdmi_probe()
477 priv->encoders[MESON_ENC_HDMI] = meson_encoder_hdmi; in meson_encoder_hdmi_probe()
479 dev_dbg(priv->dev, "HDMI encoder initialized\n"); in meson_encoder_hdmi_probe()
481 return 0; in meson_encoder_hdmi_probe()
492 if (priv->encoders[MESON_ENC_HDMI]) { in meson_encoder_hdmi_remove()
493 meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI]; in meson_encoder_hdmi_remove()
494 drm_bridge_remove(&meson_encoder_hdmi->bridge); in meson_encoder_hdmi_remove()