bcm27xx: update patches from RPi foundation
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch b/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
new file mode 100644 (file)
index 0000000..533eb89
--- /dev/null
@@ -0,0 +1,165 @@
+From 9efd6edc4c7d01c74a92f2011ba285329ba956e4 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Thu, 6 Feb 2020 16:22:13 +0100
+Subject: [PATCH] drm/vc4: hdmi: Move CEC init to its own function
+
+The CEC init code was put directly into the bind function, which was quite
+inconsistent with how the audio support was done, and would prevent us from
+further changes to skip that initialisation entirely.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 108 ++++++++++++++++++++-------------
+ 1 file changed, 67 insertions(+), 41 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1178,6 +1178,67 @@ static const struct cec_adap_ops vc4_hdm
+       .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
+       .adap_transmit = vc4_hdmi_cec_adap_transmit,
+ };
++
++static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
++{
++      struct cec_connector_info conn_info;
++      struct platform_device *pdev = vc4_hdmi->pdev;
++      u32 value;
++      int ret;
++
++      vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
++                                                vc4_hdmi, "vc4",
++                                                CEC_CAP_DEFAULTS |
++                                                CEC_CAP_CONNECTOR_INFO, 1);
++      ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
++      if (ret < 0)
++              return ret;
++
++      cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
++      cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
++
++      HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
++      value = HDMI_READ(HDMI_CEC_CNTRL_1);
++      value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
++      /*
++       * Set the logical address to Unregistered and set the clock
++       * divider: the hsm_clock rate and this divider setting will
++       * give a 40 kHz CEC clock.
++       */
++      value |= VC4_HDMI_CEC_ADDR_MASK |
++               (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
++      HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
++      ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0),
++                                      vc4_cec_irq_handler,
++                                      vc4_cec_irq_handler_thread, 0,
++                                      "vc4 hdmi cec", vc4_hdmi);
++      if (ret)
++              goto err_delete_cec_adap;
++
++      ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev);
++      if (ret < 0)
++              goto err_delete_cec_adap;
++
++      return 0;
++
++err_delete_cec_adap:
++      cec_delete_adapter(vc4_hdmi->cec_adap);
++
++      return ret;
++}
++
++static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi)
++{
++      cec_unregister_adapter(vc4_hdmi->cec_adap);
++}
++#else
++static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
++{
++      return 0;
++}
++
++static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {};
++
+ #endif
+ static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
+@@ -1255,9 +1316,6 @@ static int vc4_hdmi_init_resources(struc
+ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+ {
+-#ifdef CONFIG_DRM_VC4_HDMI_CEC
+-      struct cec_connector_info conn_info;
+-#endif
+       struct platform_device *pdev = to_platform_device(dev);
+       struct drm_device *drm = dev_get_drvdata(master);
+       const struct vc4_hdmi_variant *variant;
+@@ -1345,43 +1403,13 @@ static int vc4_hdmi_bind(struct device *
+       if (ret)
+               goto err_destroy_encoder;
+-#ifdef CONFIG_DRM_VC4_HDMI_CEC
+-      vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
+-                                            vc4_hdmi, "vc4",
+-                                            CEC_CAP_DEFAULTS |
+-                                            CEC_CAP_CONNECTOR_INFO, 1);
+-      ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
+-      if (ret < 0)
+-              goto err_destroy_conn;
+-
+-      cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
+-      cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
+-
+-      HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
+-      value = HDMI_READ(HDMI_CEC_CNTRL_1);
+-      value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
+-      /*
+-       * Set the logical address to Unregistered and set the clock
+-       * divider: the hsm_clock rate and this divider setting will
+-       * give a 40 kHz CEC clock.
+-       */
+-      value |= VC4_HDMI_CEC_ADDR_MASK |
+-               (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
+-      HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
+-      ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
+-                                      vc4_cec_irq_handler,
+-                                      vc4_cec_irq_handler_thread, 0,
+-                                      "vc4 hdmi cec", vc4_hdmi);
++      ret = vc4_hdmi_cec_init(vc4_hdmi);
+       if (ret)
+-              goto err_delete_cec_adap;
+-      ret = cec_register_adapter(vc4_hdmi->cec_adap, dev);
+-      if (ret < 0)
+-              goto err_delete_cec_adap;
+-#endif
++              goto err_destroy_conn;
+       ret = vc4_hdmi_audio_init(vc4_hdmi);
+       if (ret)
+-              goto err_destroy_encoder;
++              goto err_free_cec;
+       vc4_debugfs_add_file(drm,
+                            variant->id ? "hdmi1_regs" : "hdmi_regs",
+@@ -1390,12 +1418,10 @@ static int vc4_hdmi_bind(struct device *
+       return 0;
+-#ifdef CONFIG_DRM_VC4_HDMI_CEC
+-err_delete_cec_adap:
+-      cec_delete_adapter(vc4_hdmi->cec_adap);
++err_free_cec:
++      vc4_hdmi_cec_exit(vc4_hdmi);
+ err_destroy_conn:
+       vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
+-#endif
+ err_destroy_encoder:
+       vc4_hdmi_encoder_destroy(encoder);
+ err_unprepare_hsm:
+@@ -1420,7 +1446,7 @@ static void vc4_hdmi_unbind(struct devic
+       kfree(vc4_hdmi->hdmi_regset.regs);
+       kfree(vc4_hdmi->hd_regset.regs);
+-      cec_unregister_adapter(vc4_hdmi->cec_adap);
++      vc4_hdmi_cec_exit(vc4_hdmi);
+       vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
+       vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);