[PATCH v2 2/4] drm/sun4i: tcon: Refactor the LVDS and panel probing
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Aug 31 20:38:21 UTC 2020
Hi Maxime,
Thank you for the patch.
On Thu, Jul 30, 2020 at 11:35:02AM +0200, Maxime Ripard wrote:
> The current code to parse the DT, deal with the older device trees, and
> register either the RGB or LVDS output has so far grown organically into
> the bind function and has become quite hard to extend properly.
>
> Let's move it into a single function that grabs all the resources it needs
> and registers the proper panel output.
>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---
> drivers/gpu/drm/sun4i/sun4i_tcon.c | 139 +++++++++++++++---------------
> 1 file changed, 70 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 2a5a9903c4c6..d03ad75f9900 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -875,6 +875,75 @@ static int sun4i_tcon_init_regmap(struct device *dev,
> return 0;
> }
>
> +static int sun4i_tcon_register_panel(struct drm_device *drm,
> + struct sun4i_tcon *tcon)
> +{
> + struct device_node *companion;
> + struct device_node *remote;
> + struct device *dev = tcon->dev;
> + bool has_lvds_alt;
> + bool has_lvds_rst;
> + int ret;
> +
> + /*
> + * If we have an LVDS panel connected to the TCON, we should
> + * just probe the LVDS connector. Otherwise, let's just register
> + * an RGB panel.
> + */
> + remote = of_graph_get_remote_node(dev->of_node, 1, 0);
> + if (!tcon->quirks->supports_lvds ||
> + !of_device_is_compatible(remote, "panel-lvds"))
This isn't very nice :-S Not a candidate for a fix in this patch, but
something that should be addressed in the future. As Chen-Yu mentioned,
there are LVDS panels supported by the panel-simple driver.
> + return sun4i_rgb_init(drm, tcon);
> +
> + /*
> + * This can only be made optional since we've had DT
> + * nodes without the LVDS reset properties.
> + *
> + * If the property is missing, just disable LVDS, and
> + * print a warning.
> + */
> + tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
> + if (IS_ERR(tcon->lvds_rst)) {
> + dev_err(dev, "Couldn't get our reset line\n");
> + return PTR_ERR(tcon->lvds_rst);
> + } else if (tcon->lvds_rst) {
> + has_lvds_rst = true;
> + reset_control_reset(tcon->lvds_rst);
> + } else {
> + has_lvds_rst = false;
> + }
> +
> + /*
> + * This can only be made optional since we've had DT
> + * nodes without the LVDS reset properties.
Shouldn't this mention clock, not reset ?
> + *
> + * If the property is missing, just disable LVDS, and
> + * print a warning.
> + */
> + if (tcon->quirks->has_lvds_alt) {
> + tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
> + if (IS_ERR(tcon->lvds_pll)) {
> + if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
> + has_lvds_alt = false;
> + } else {
> + dev_err(dev, "Couldn't get the LVDS PLL\n");
> + return PTR_ERR(tcon->lvds_pll);
> + }
> + } else {
> + has_lvds_alt = true;
> + }
> + }
> +
> + if (!has_lvds_rst ||
> + (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
> + dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
> + dev_warn(dev, "LVDS output disabled\n");
Would it make sense to move this to the has_lvds_rst = false and
has_lvds_alt = false code sections about ? You could then print which
property is missing.
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> + return -ENODEV;
> + }
> +
> + return sun4i_lvds_init(drm, tcon);
> +}
> +
> /*
> * On SoCs with the old display pipeline design (Display Engine 1.0),
> * the TCON is always tied to just one backend. Hence we can traverse
> @@ -1122,10 +1191,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> struct drm_device *drm = data;
> struct sun4i_drv *drv = drm->dev_private;
> struct sunxi_engine *engine;
> - struct device_node *remote;
> struct sun4i_tcon *tcon;
> struct reset_control *edp_rstc;
> - bool has_lvds_rst, has_lvds_alt, can_lvds;
> int ret;
>
> engine = sun4i_tcon_find_engine(drv, dev->of_node);
> @@ -1170,58 +1237,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> return ret;
> }
>
> - if (tcon->quirks->supports_lvds) {
> - /*
> - * This can only be made optional since we've had DT
> - * nodes without the LVDS reset properties.
> - *
> - * If the property is missing, just disable LVDS, and
> - * print a warning.
> - */
> - tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
> - if (IS_ERR(tcon->lvds_rst)) {
> - dev_err(dev, "Couldn't get our reset line\n");
> - return PTR_ERR(tcon->lvds_rst);
> - } else if (tcon->lvds_rst) {
> - has_lvds_rst = true;
> - reset_control_reset(tcon->lvds_rst);
> - } else {
> - has_lvds_rst = false;
> - }
> -
> - /*
> - * This can only be made optional since we've had DT
> - * nodes without the LVDS reset properties.
> - *
> - * If the property is missing, just disable LVDS, and
> - * print a warning.
> - */
> - if (tcon->quirks->has_lvds_alt) {
> - tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
> - if (IS_ERR(tcon->lvds_pll)) {
> - if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
> - has_lvds_alt = false;
> - } else {
> - dev_err(dev, "Couldn't get the LVDS PLL\n");
> - return PTR_ERR(tcon->lvds_pll);
> - }
> - } else {
> - has_lvds_alt = true;
> - }
> - }
> -
> - if (!has_lvds_rst ||
> - (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
> - dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
> - dev_warn(dev, "LVDS output disabled\n");
> - can_lvds = false;
> - } else {
> - can_lvds = true;
> - }
> - } else {
> - can_lvds = false;
> - }
> -
> ret = sun4i_tcon_init_clocks(dev, tcon);
> if (ret) {
> dev_err(dev, "Couldn't init our TCON clocks\n");
> @@ -1256,21 +1271,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> }
>
> if (tcon->quirks->has_channel_0) {
> - /*
> - * If we have an LVDS panel connected to the TCON, we should
> - * just probe the LVDS connector. Otherwise, just probe RGB as
> - * we used to.
> - */
> - remote = of_graph_get_remote_node(dev->of_node, 1, 0);
> - if (of_device_is_compatible(remote, "panel-lvds"))
> - if (can_lvds)
> - ret = sun4i_lvds_init(drm, tcon);
> - else
> - ret = -EINVAL;
> - else
> - ret = sun4i_rgb_init(drm, tcon);
> - of_node_put(remote);
> -
> + ret = sun4i_tcon_register_panel(drm, tcon);
> if (ret < 0)
> goto err_free_dotclock;
> }
--
Regards,
Laurent Pinchart
More information about the dri-devel
mailing list