mirror of
https://github.com/libretro/Lakka-LibreELEC.git
synced 2024-12-12 19:15:44 +00:00
Merge pull request #5751 from jernejsk/h3-cec-fix
[LE11] Allwinner: H3: linux: Fix SW CEC
This commit is contained in:
commit
bb67729b56
@ -1,21 +1,23 @@
|
||||
From 0981ac8f42983c820790b14668d59f39b0375d90 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 25 May 2019 12:03:39 +0200
|
||||
From 411f022496f0f9715ca3dc9296f5823cbc0c867c Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
Date: Mon, 11 Oct 2021 20:13:41 +0200
|
||||
Subject: [PATCH] HACK: SW CEC implementation for H3
|
||||
|
||||
Many H3 boards lack 32768 Hz external oscillator, so internal RC is used
|
||||
instead. However, it's too unstable for CEC. Use SW implementation
|
||||
instead. That makes it usable, albeit sensitive to cpufreq changes.
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +-
|
||||
drivers/gpu/drm/sun4i/Kconfig | 2 +
|
||||
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 12 ++++
|
||||
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 74 ++++++++++++++++++++++-
|
||||
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 76 ++++++++++++++++++++++-
|
||||
include/drm/bridge/dw_hdmi.h | 2 +
|
||||
5 files changed, 89 insertions(+), 3 deletions(-)
|
||||
5 files changed, 91 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
|
||||
index 5755f0432e77..b93eb2fb52ce 100644
|
||||
--- a/drivers/gpu/drm/sun4i/Kconfig
|
||||
+++ b/drivers/gpu/drm/sun4i/Kconfig
|
||||
@@ -56,6 +56,8 @@ config DRM_SUN8I_DW_HDMI
|
||||
@ -27,6 +29,8 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
help
|
||||
Choose this option if you have an Allwinner SoC with the
|
||||
DesignWare HDMI controller with custom HDMI PHY. If M is
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
index bffe1b9cd3dc..438f7398e26d 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
|
||||
@@ -13,6 +13,8 @@
|
||||
@ -69,9 +73,11 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
struct clk *clk_bus;
|
||||
struct clk *clk_mod;
|
||||
struct clk *clk_phy;
|
||||
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
index 78b152973957..0d87b56b700a 100644
|
||||
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
|
||||
@@ -498,8 +498,9 @@ static void sun8i_hdmi_phy_init_h3(struc
|
||||
@@ -498,8 +498,9 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
|
||||
regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
|
||||
SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK, 0);
|
||||
|
||||
@ -83,7 +89,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
|
||||
/* read calibration data */
|
||||
regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val);
|
||||
@@ -525,8 +526,47 @@ void sun8i_hdmi_phy_set_ops(struct sun8i
|
||||
@@ -576,8 +577,47 @@ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
|
||||
plat_data->cur_ctr = variant->cur_ctr;
|
||||
plat_data->phy_config = variant->phy_cfg;
|
||||
}
|
||||
@ -131,7 +137,7 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
static const struct regmap_config sun8i_hdmi_phy_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
@@ -543,6 +583,7 @@ static const struct sun8i_hdmi_phy_varia
|
||||
@@ -594,6 +634,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
|
||||
};
|
||||
|
||||
static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
|
||||
@ -139,10 +145,19 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
.has_phy_clk = true,
|
||||
.is_custom_phy = true,
|
||||
.phy_init = &sun8i_hdmi_phy_init_h3,
|
||||
@@ -725,10 +766,36 @@ static int sun8i_hdmi_phy_probe(struct p
|
||||
goto err_put_clk_pll1;
|
||||
}
|
||||
@@ -653,6 +694,7 @@ int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
|
||||
{
|
||||
struct platform_device *pdev = of_find_device_by_node(node);
|
||||
struct sun8i_hdmi_phy *phy;
|
||||
+ int ret;
|
||||
|
||||
if (!pdev)
|
||||
return -EPROBE_DEFER;
|
||||
@@ -664,8 +706,35 @@ int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
|
||||
hdmi->phy = phy;
|
||||
|
||||
put_device(&pdev->dev);
|
||||
+
|
||||
+ if (phy->variant->bit_bang_cec) {
|
||||
+ phy->cec_adapter =
|
||||
+ cec_pin_allocate_adapter(&sun8i_hdmi_phy_cec_pin_ops,
|
||||
@ -150,33 +165,31 @@ Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ CEC_CAP_DEFAULTS);
|
||||
+ ret = PTR_ERR_OR_ZERO(phy->cec_adapter);
|
||||
+ if (ret < 0)
|
||||
+ goto err_disable_clk_phy;
|
||||
+ return 0;
|
||||
+
|
||||
+ phy->cec_notifier = cec_notifier_cec_adap_register(dev, NULL, phy->cec_adapter);
|
||||
+ phy->cec_notifier = cec_notifier_cec_adap_register(hdmi->dev, NULL, phy->cec_adapter);
|
||||
+ if (!phy->cec_notifier) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_delete_cec_adapter;
|
||||
+ }
|
||||
+
|
||||
+ ret = cec_register_adapter(phy->cec_adapter, dev);
|
||||
+ ret = cec_register_adapter(phy->cec_adapter, hdmi->dev);
|
||||
+ if (ret < 0)
|
||||
+ goto err_put_cec_notifier;
|
||||
+ }
|
||||
+
|
||||
platform_set_drvdata(pdev, phy);
|
||||
|
||||
return 0;
|
||||
|
||||
+
|
||||
+err_put_cec_notifier:
|
||||
+ cec_notifier_cec_adap_unregister(phy->cec_notifier, phy->cec_adapter);
|
||||
+err_delete_cec_adapter:
|
||||
+ cec_delete_adapter(phy->cec_adapter);
|
||||
+err_disable_clk_phy:
|
||||
+ clk_disable_unprepare(phy->clk_phy);
|
||||
err_put_clk_pll1:
|
||||
clk_put(phy->clk_pll1);
|
||||
err_put_clk_pll0:
|
||||
@@ -753,6 +820,9 @@ static int sun8i_hdmi_phy_remove(struct
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
|
||||
@@ -768,6 +837,9 @@ static int sun8i_hdmi_phy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user