Lines Matching +full:hdmi +full:- +full:tx

1 // SPDX-License-Identifier: GPL-2.0-or-later
25 #include <linux/media-bus-format.h>
34 #define DRIVER_NAME "meson-dw-hdmi"
35 #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver"
38 * DOC: HDMI Output
40 * HDMI Output is composed of :
42 * - A Synopsys DesignWare HDMI Controller IP
43 * - A TOP control block controlling the Clocks and PHY
44 * - A custom HDMI PHY in order convert video to TMDS signal
49 * | HDMI TOP |<= HPD
52 * | Synopsys HDMI | HDMI PHY |=> TMDS
57 * The HDMI TOP block only supports HPD sensing.
58 * The Synopsys HDMI Controller interrupt is routed
61 * HDMI Controller is done a pair of addr+read/write
63 * The HDMI PHY is configured by registers in the
67 * block and the VPU HDMI mux selects either the ENCI
73 * HDMI controller.
76 * HDMI TX IP version 2.01a with HDCP and I2C & S/PDIF
81 * - HPD Rise & Fall interrupt
82 * - HDMI Controller Interrupt
83 * - HDMI PHY Init for 480i to 1080p60
84 * - VENC & HDMI Clock setup for 480i to 1080p60
85 * - VENC Mode setup for 480i to 1080p60
89 * - PHY, Clock and Mode setup for 2k && 4k modes
90 * - SDDC Scrambling mode for HDMI 2.0a
91 * - HDCP Setup
92 * - CEC Management
150 struct dw_hdmi *hdmi; member
161 return of_device_is_compatible(dw_hdmi->dev->of_node, compat); in dw_hdmi_is_compatible()
175 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); in dw_hdmi_top_read()
176 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); in dw_hdmi_top_read()
179 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); in dw_hdmi_top_read()
180 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); in dw_hdmi_top_read()
190 return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); in dw_hdmi_g12a_top_read()
201 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); in dw_hdmi_top_write()
202 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); in dw_hdmi_top_write()
205 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); in dw_hdmi_top_write()
213 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); in dw_hdmi_g12a_top_write()
222 unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr); in dw_hdmi_top_write_bits()
227 dw_hdmi->data->top_write(dw_hdmi, addr, data); in dw_hdmi_top_write_bits()
239 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); in dw_hdmi_dwc_read()
240 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); in dw_hdmi_dwc_read()
243 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); in dw_hdmi_dwc_read()
244 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); in dw_hdmi_dwc_read()
254 return readb(dw_hdmi->hdmitx + addr); in dw_hdmi_g12a_dwc_read()
265 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); in dw_hdmi_dwc_write()
266 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); in dw_hdmi_dwc_write()
269 writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); in dw_hdmi_dwc_write()
277 writeb(data, dw_hdmi->hdmitx + addr); in dw_hdmi_g12a_dwc_write()
286 unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); in dw_hdmi_dwc_write_bits()
291 dw_hdmi->data->dwc_write(dw_hdmi, addr, data); in dw_hdmi_dwc_write_bits()
300 struct meson_drm *priv = dw_hdmi->priv; in meson_hdmi_phy_setup_mode()
301 unsigned int pixel_clock = mode->clock; in meson_hdmi_phy_setup_mode()
304 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in meson_hdmi_phy_setup_mode()
307 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || in meson_hdmi_phy_setup_mode()
308 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { in meson_hdmi_phy_setup_mode()
311 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); in meson_hdmi_phy_setup_mode()
312 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); in meson_hdmi_phy_setup_mode()
315 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); in meson_hdmi_phy_setup_mode()
316 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); in meson_hdmi_phy_setup_mode()
319 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); in meson_hdmi_phy_setup_mode()
320 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); in meson_hdmi_phy_setup_mode()
323 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); in meson_hdmi_phy_setup_mode()
324 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); in meson_hdmi_phy_setup_mode()
327 "amlogic,meson-gxbb-dw-hdmi")) { in meson_hdmi_phy_setup_mode()
330 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); in meson_hdmi_phy_setup_mode()
331 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); in meson_hdmi_phy_setup_mode()
334 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); in meson_hdmi_phy_setup_mode()
335 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); in meson_hdmi_phy_setup_mode()
338 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); in meson_hdmi_phy_setup_mode()
339 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); in meson_hdmi_phy_setup_mode()
342 "amlogic,meson-g12a-dw-hdmi")) { in meson_hdmi_phy_setup_mode()
345 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4); in meson_hdmi_phy_setup_mode()
346 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); in meson_hdmi_phy_setup_mode()
347 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b); in meson_hdmi_phy_setup_mode()
350 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262); in meson_hdmi_phy_setup_mode()
351 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); in meson_hdmi_phy_setup_mode()
352 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); in meson_hdmi_phy_setup_mode()
355 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242); in meson_hdmi_phy_setup_mode()
356 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); in meson_hdmi_phy_setup_mode()
357 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); in meson_hdmi_phy_setup_mode()
364 struct meson_drm *priv = dw_hdmi->priv; in meson_dw_hdmi_phy_reset()
367 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf); in meson_dw_hdmi_phy_reset()
372 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe); in meson_dw_hdmi_phy_reset()
380 struct meson_drm *priv = dw_hdmi->priv; in dw_hdmi_set_vclk()
387 vclk_freq = mode->clock; in dw_hdmi_set_vclk()
390 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in dw_hdmi_set_vclk()
403 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in dw_hdmi_set_vclk()
411 dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in dw_hdmi_set_vclk()
416 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in dw_hdmi_set_vclk()
419 DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", in dw_hdmi_set_vclk()
421 priv->venc.hdmi_use_enci); in dw_hdmi_set_vclk()
424 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); in dw_hdmi_set_vclk()
427 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, in dw_hdmi_phy_init() argument
432 struct meson_drm *priv = dw_hdmi->priv; in dw_hdmi_phy_init()
434 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
436 DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name, in dw_hdmi_phy_init()
437 mode->clock > 340000 ? 40 : 10); in dw_hdmi_phy_init()
440 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); in dw_hdmi_phy_init()
443 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); in dw_hdmi_phy_init()
446 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0); in dw_hdmi_phy_init()
457 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); in dw_hdmi_phy_init()
460 if (mode->clock > 340000 && in dw_hdmi_phy_init()
461 dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) { in dw_hdmi_phy_init()
462 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, in dw_hdmi_phy_init()
464 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, in dw_hdmi_phy_init()
467 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, in dw_hdmi_phy_init()
469 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, in dw_hdmi_phy_init()
474 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); in dw_hdmi_phy_init()
476 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); in dw_hdmi_phy_init()
482 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, in dw_hdmi_phy_init()
486 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || in dw_hdmi_phy_init()
487 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || in dw_hdmi_phy_init()
488 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) in dw_hdmi_phy_init()
489 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, in dw_hdmi_phy_init()
492 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, in dw_hdmi_phy_init()
496 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); in dw_hdmi_phy_init()
498 dw_hdmi_set_high_tmds_clock_ratio(hdmi, display); in dw_hdmi_phy_init()
508 if (priv->venc.hdmi_use_enci) in dw_hdmi_phy_init()
509 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); in dw_hdmi_phy_init()
511 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); in dw_hdmi_phy_init()
513 /* Temporary Disable HDMI video stream to HDMI-TX */ in dw_hdmi_phy_init()
515 priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
517 priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
519 /* Re-Enable VENC video stream */ in dw_hdmi_phy_init()
520 if (priv->venc.hdmi_use_enci) in dw_hdmi_phy_init()
521 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); in dw_hdmi_phy_init()
523 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); in dw_hdmi_phy_init()
525 /* Push back HDMI clock settings */ in dw_hdmi_phy_init()
527 priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
529 /* Enable and Select HDMI video source for HDMI-TX */ in dw_hdmi_phy_init()
530 if (priv->venc.hdmi_use_enci) in dw_hdmi_phy_init()
532 priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
535 priv->io_base + _REG(VPU_HDMI_SETTING)); in dw_hdmi_phy_init()
540 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, in dw_hdmi_phy_disable() argument
544 struct meson_drm *priv = dw_hdmi->priv; in dw_hdmi_phy_disable()
548 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); in dw_hdmi_phy_disable()
551 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, in dw_hdmi_read_hpd() argument
556 return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ? in dw_hdmi_read_hpd()
560 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi, in dw_hdmi_setup_hpd() argument
566 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER, in dw_hdmi_setup_hpd()
570 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, in dw_hdmi_setup_hpd()
591 stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT); in dw_hdmi_top_irq()
592 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat); in dw_hdmi_top_irq()
596 dw_hdmi->irq_stat = stat; in dw_hdmi_top_irq()
600 /* HDMI Controller Interrupt */ in dw_hdmi_top_irq()
613 u32 stat = dw_hdmi->irq_stat; in dw_hdmi_top_thread_irq()
622 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, in dw_hdmi_top_thread_irq()
625 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); in dw_hdmi_top_thread_irq()
632 dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, in dw_hdmi_mode_valid() argument
637 struct meson_drm *priv = dw_hdmi->priv; in dw_hdmi_mode_valid()
638 bool is_hdmi2_sink = display_info->hdmi.scdc.supported; in dw_hdmi_mode_valid()
648 /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ in dw_hdmi_mode_valid()
649 if (display_info->max_tmds_clock && in dw_hdmi_mode_valid()
650 mode->clock > display_info->max_tmds_clock && in dw_hdmi_mode_valid()
655 /* Check against non-VIC supported modes */ in dw_hdmi_mode_valid()
661 return meson_vclk_dmt_supported_freq(priv, mode->clock); in dw_hdmi_mode_valid()
666 vclk_freq = mode->clock; in dw_hdmi_mode_valid()
678 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in dw_hdmi_mode_valid()
693 if (mode->flags & DRM_MODE_FLAG_DBLCLK) in dw_hdmi_mode_valid()
696 dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", in dw_hdmi_mode_valid()
756 dw_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; in meson_venc_hdmi_encoder_atomic_check()
758 DRM_DEBUG_DRIVER("output_bus_fmt %lx\n", dw_hdmi->output_bus_fmt); in meson_venc_hdmi_encoder_atomic_check()
766 struct meson_drm *priv = dw_hdmi->priv; in meson_venc_hdmi_encoder_disable()
771 priv->io_base + _REG(VPU_HDMI_SETTING)); in meson_venc_hdmi_encoder_disable()
773 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); in meson_venc_hdmi_encoder_disable()
774 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); in meson_venc_hdmi_encoder_disable()
780 struct meson_drm *priv = dw_hdmi->priv; in meson_venc_hdmi_encoder_enable()
782 DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); in meson_venc_hdmi_encoder_enable()
784 if (priv->venc.hdmi_use_enci) in meson_venc_hdmi_encoder_enable()
785 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); in meson_venc_hdmi_encoder_enable()
787 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); in meson_venc_hdmi_encoder_enable()
795 struct meson_drm *priv = dw_hdmi->priv; in meson_venc_hdmi_encoder_mode_set()
800 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); in meson_venc_hdmi_encoder_mode_set()
802 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { in meson_venc_hdmi_encoder_mode_set()
807 /* VENC + VENC-DVI Mode setup */ in meson_venc_hdmi_encoder_mode_set()
813 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) in meson_venc_hdmi_encoder_mode_set()
814 /* Setup YUV420 to HDMI-TX, no 10bit diphering */ in meson_venc_hdmi_encoder_mode_set()
816 priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); in meson_venc_hdmi_encoder_mode_set()
818 /* Setup YUV444 to HDMI-TX, no 10bit diphering */ in meson_venc_hdmi_encoder_mode_set()
819 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); in meson_venc_hdmi_encoder_mode_set()
833 /* DW HDMI Regmap */
840 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg); in meson_dw_hdmi_reg_read()
851 dw_hdmi->data->dwc_write(dw_hdmi, reg, val); in meson_dw_hdmi_reg_write()
883 /* HDMI Connector is on the second port, first endpoint */ in meson_hdmi_connector_is_available()
884 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); in meson_hdmi_connector_is_available()
903 struct meson_drm *priv = meson_dw_hdmi->priv; in meson_dw_hdmi_init()
906 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); in meson_dw_hdmi_init()
909 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); in meson_dw_hdmi_init()
911 /* Reset HDMITX APB & TX & PHY */ in meson_dw_hdmi_init()
912 reset_control_reset(meson_dw_hdmi->hdmitx_apb); in meson_dw_hdmi_init()
913 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); in meson_dw_hdmi_init()
914 reset_control_reset(meson_dw_hdmi->hdmitx_phy); in meson_dw_hdmi_init()
919 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); in meson_dw_hdmi_init()
921 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); in meson_dw_hdmi_init()
925 meson_dw_hdmi->data->top_write(meson_dw_hdmi, in meson_dw_hdmi_init()
930 meson_dw_hdmi->data->top_write(meson_dw_hdmi, in meson_dw_hdmi_init()
933 /* Enable HDMI-TX Interrupt */ in meson_dw_hdmi_init()
934 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, in meson_dw_hdmi_init()
937 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, in meson_dw_hdmi_init()
977 struct meson_drm *priv = drm->dev_private; in meson_dw_hdmi_bind()
988 dev_info(drm->dev, "HDMI Output connector not available\n"); in meson_dw_hdmi_bind()
989 return -ENODEV; in meson_dw_hdmi_bind()
992 match = of_device_get_match_data(&pdev->dev); in meson_dw_hdmi_bind()
994 dev_err(&pdev->dev, "failed to get match data\n"); in meson_dw_hdmi_bind()
995 return -ENODEV; in meson_dw_hdmi_bind()
1001 return -ENOMEM; in meson_dw_hdmi_bind()
1003 meson_dw_hdmi->priv = priv; in meson_dw_hdmi_bind()
1004 meson_dw_hdmi->dev = dev; in meson_dw_hdmi_bind()
1005 meson_dw_hdmi->data = match; in meson_dw_hdmi_bind()
1006 dw_plat_data = &meson_dw_hdmi->dw_plat_data; in meson_dw_hdmi_bind()
1007 encoder = &meson_dw_hdmi->encoder; in meson_dw_hdmi_bind()
1009 meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); in meson_dw_hdmi_bind()
1010 if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { in meson_dw_hdmi_bind()
1011 if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) in meson_dw_hdmi_bind()
1012 return -EPROBE_DEFER; in meson_dw_hdmi_bind()
1013 meson_dw_hdmi->hdmi_supply = NULL; in meson_dw_hdmi_bind()
1015 ret = regulator_enable(meson_dw_hdmi->hdmi_supply); in meson_dw_hdmi_bind()
1019 meson_dw_hdmi->hdmi_supply); in meson_dw_hdmi_bind()
1024 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, in meson_dw_hdmi_bind()
1026 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { in meson_dw_hdmi_bind()
1028 return PTR_ERR(meson_dw_hdmi->hdmitx_apb); in meson_dw_hdmi_bind()
1031 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, in meson_dw_hdmi_bind()
1033 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { in meson_dw_hdmi_bind()
1035 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); in meson_dw_hdmi_bind()
1038 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, in meson_dw_hdmi_bind()
1040 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { in meson_dw_hdmi_bind()
1042 return PTR_ERR(meson_dw_hdmi->hdmitx_phy); in meson_dw_hdmi_bind()
1046 meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); in meson_dw_hdmi_bind()
1047 if (IS_ERR(meson_dw_hdmi->hdmitx)) in meson_dw_hdmi_bind()
1048 return PTR_ERR(meson_dw_hdmi->hdmitx); in meson_dw_hdmi_bind()
1062 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, in meson_dw_hdmi_bind()
1064 if (IS_ERR(dw_plat_data->regm)) in meson_dw_hdmi_bind()
1065 return PTR_ERR(dw_plat_data->regm); in meson_dw_hdmi_bind()
1075 dev_err(dev, "Failed to request hdmi top irq\n"); in meson_dw_hdmi_bind()
1084 dev_err(priv->dev, "Failed to init HDMI encoder\n"); in meson_dw_hdmi_bind()
1088 meson_dw_hdmi->bridge.funcs = &meson_venc_hdmi_encoder_bridge_funcs; in meson_dw_hdmi_bind()
1089 drm_bridge_attach(encoder, &meson_dw_hdmi->bridge, NULL, 0); in meson_dw_hdmi_bind()
1091 encoder->possible_crtcs = BIT(0); in meson_dw_hdmi_bind()
1099 dw_plat_data->priv_data = meson_dw_hdmi; in meson_dw_hdmi_bind()
1100 dw_plat_data->mode_valid = dw_hdmi_mode_valid; in meson_dw_hdmi_bind()
1101 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; in meson_dw_hdmi_bind()
1102 dw_plat_data->phy_name = "meson_dw_hdmi_phy"; in meson_dw_hdmi_bind()
1103 dw_plat_data->phy_data = meson_dw_hdmi; in meson_dw_hdmi_bind()
1104 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; in meson_dw_hdmi_bind()
1105 dw_plat_data->ycbcr_420_allowed = true; in meson_dw_hdmi_bind()
1106 dw_plat_data->disable_cec = true; in meson_dw_hdmi_bind()
1108 if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || in meson_dw_hdmi_bind()
1109 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || in meson_dw_hdmi_bind()
1110 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) in meson_dw_hdmi_bind()
1111 dw_plat_data->use_drm_infoframe = true; in meson_dw_hdmi_bind()
1115 meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, in meson_dw_hdmi_bind()
1116 &meson_dw_hdmi->dw_plat_data); in meson_dw_hdmi_bind()
1117 if (IS_ERR(meson_dw_hdmi->hdmi)) in meson_dw_hdmi_bind()
1118 return PTR_ERR(meson_dw_hdmi->hdmi); in meson_dw_hdmi_bind()
1120 next_bridge = of_drm_find_bridge(pdev->dev.of_node); in meson_dw_hdmi_bind()
1123 &meson_dw_hdmi->bridge, 0); in meson_dw_hdmi_bind()
1125 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); in meson_dw_hdmi_bind()
1135 dw_hdmi_unbind(meson_dw_hdmi->hdmi); in meson_dw_hdmi_unbind()
1151 meson_dw_hdmi->data->top_write(meson_dw_hdmi, in meson_dw_hdmi_pm_suspend()
1166 dw_hdmi_resume(meson_dw_hdmi->hdmi); in meson_dw_hdmi_pm_resume()
1173 return component_add(&pdev->dev, &meson_dw_hdmi_ops); in meson_dw_hdmi_probe()
1178 component_del(&pdev->dev, &meson_dw_hdmi_ops); in meson_dw_hdmi_remove()
1189 { .compatible = "amlogic,meson-gxbb-dw-hdmi",
1191 { .compatible = "amlogic,meson-gxl-dw-hdmi",
1193 { .compatible = "amlogic,meson-gxm-dw-hdmi",
1195 { .compatible = "amlogic,meson-g12a-dw-hdmi",