aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch165
1 files changed, 165 insertions, 0 deletions
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
index 0000000000..533eb89e7a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch
@@ -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);
+