Commit aa54f334 authored by Alex Bee's avatar Alex Bee Committed by Heiko Stuebner

drm/rockchip: inno_hdmi: Add RK3128 support

This variant requires the phy reference clock to be enabled before the DDC
block can work and the (initial) DDC bus frequency is calculated based on
the rate of this clock. Besides the only difference is phy configuration
required to make the driver working for this variant as well.
Signed-off-by: default avatarAlex Bee <knaerzche@gmail.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20231222174220.55249-25-knaerzche@gmail.com
parent 5f2e93e6
......@@ -50,6 +50,7 @@ struct inno_hdmi {
struct device *dev;
struct clk *pclk;
struct clk *refclk;
void __iomem *regs;
struct drm_connector connector;
......@@ -131,6 +132,12 @@ static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs[] = {
{ ~0UL, 0x00, 0x00 }
};
static struct inno_hdmi_phy_config rk3128_hdmi_phy_configs[] = {
{ 74250000, 0x3f, 0xaa },
{ 165000000, 0x5f, 0xaa },
{ ~0UL, 0x00, 0x00 }
};
static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
unsigned long pixelclk)
{
......@@ -909,6 +916,20 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
return ret;
}
hdmi->refclk = devm_clk_get_optional(hdmi->dev, "ref");
if (IS_ERR(hdmi->refclk)) {
DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI reference clock\n");
ret = PTR_ERR(hdmi->refclk);
goto err_disable_pclk;
}
ret = clk_prepare_enable(hdmi->refclk);
if (ret) {
DRM_DEV_ERROR(hdmi->dev,
"Cannot enable HDMI reference clock: %d\n", ret);
goto err_disable_pclk;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
......@@ -925,12 +946,16 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
}
/*
* When IP controller haven't configured to an accurate video
* timing, then the TMDS clock source would be switched to
* PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
* and reconfigure the DDC clock.
* When the controller isn't configured to an accurate
* video timing and there is no reference clock available,
* then the TMDS clock source would be switched to PCLK_HDMI,
* so we need to init the TMDS rate to PCLK rate, and
* reconfigure the DDC clock.
*/
inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
if (hdmi->refclk)
inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->refclk));
else
inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
ret = inno_hdmi_register(drm, hdmi);
if (ret)
......@@ -954,6 +979,8 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
err_put_adapter:
i2c_put_adapter(hdmi->ddc);
err_disable_clk:
clk_disable_unprepare(hdmi->refclk);
err_disable_pclk:
clk_disable_unprepare(hdmi->pclk);
return ret;
}
......@@ -967,6 +994,7 @@ static void inno_hdmi_unbind(struct device *dev, struct device *master,
hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
i2c_put_adapter(hdmi->ddc);
clk_disable_unprepare(hdmi->refclk);
clk_disable_unprepare(hdmi->pclk);
}
......@@ -990,10 +1018,18 @@ static const struct inno_hdmi_variant rk3036_inno_hdmi_variant = {
.default_phy_config = &rk3036_hdmi_phy_configs[1],
};
static const struct inno_hdmi_variant rk3128_inno_hdmi_variant = {
.phy_configs = rk3128_hdmi_phy_configs,
.default_phy_config = &rk3128_hdmi_phy_configs[1],
};
static const struct of_device_id inno_hdmi_dt_ids[] = {
{ .compatible = "rockchip,rk3036-inno-hdmi",
.data = &rk3036_inno_hdmi_variant,
},
{ .compatible = "rockchip,rk3128-inno-hdmi",
.data = &rk3128_inno_hdmi_variant,
},
{},
};
MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment