Skip to content

Commit

Permalink
drm/sun4i: dw-hdmi: Make HDMI PHY into a platform device
Browse files Browse the repository at this point in the history
On sunxi boards that use HDMI output, HDMI device probe keeps being
avoided indefinitely with these repeated messages in dmesg:

  platform 1ee0000.hdmi: probe deferral - supplier 1ef0000.hdmi-phy
    not ready

There's a fwnode_link being created with fw_devlink=on between hdmi
and hdmi-phy nodes, because both nodes have 'compatible' property set.

Fw_devlink code assumes that nodes that have compatible property
set will also have a device associated with them by some driver
eventually. This is not the case with the current sun8i-hdmi
driver.

This commit makes sun8i-hdmi-phy into a proper platform device
and fixes the display pipeline probe on sunxi boards that use HDMI.

More context: https://lkml.org/lkml/2021/5/16/203

Signed-off-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ondrej Jirman <megous@megous.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210607085836.2827429-1-megous@megous.com
  • Loading branch information
Saravana Kannan authored and mripard committed Jun 7, 2021
1 parent 0b78f8b commit 9bf3797
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 11 deletions.
31 changes: 27 additions & 4 deletions drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
goto err_disable_clk_tmds;
}

ret = sun8i_hdmi_phy_probe(hdmi, phy_node);
ret = sun8i_hdmi_phy_get(hdmi, phy_node);
of_node_put(phy_node);
if (ret) {
dev_err(dev, "Couldn't get the HDMI PHY\n");
Expand Down Expand Up @@ -242,7 +242,6 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,

cleanup_encoder:
drm_encoder_cleanup(encoder);
sun8i_hdmi_phy_remove(hdmi);
err_disable_clk_tmds:
clk_disable_unprepare(hdmi->clk_tmds);
err_assert_ctrl_reset:
Expand All @@ -263,7 +262,6 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master,
struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev);

dw_hdmi_unbind(hdmi->hdmi);
sun8i_hdmi_phy_remove(hdmi);
clk_disable_unprepare(hdmi->clk_tmds);
reset_control_assert(hdmi->rst_ctrl);
gpiod_set_value(hdmi->ddc_en, 0);
Expand Down Expand Up @@ -320,7 +318,32 @@ static struct platform_driver sun8i_dw_hdmi_pltfm_driver = {
.of_match_table = sun8i_dw_hdmi_dt_ids,
},
};
module_platform_driver(sun8i_dw_hdmi_pltfm_driver);

static int __init sun8i_dw_hdmi_init(void)
{
int ret;

ret = platform_driver_register(&sun8i_dw_hdmi_pltfm_driver);
if (ret)
return ret;

ret = platform_driver_register(&sun8i_hdmi_phy_driver);
if (ret) {
platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver);
return ret;
}

return ret;
}

static void __exit sun8i_dw_hdmi_exit(void)
{
platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver);
platform_driver_unregister(&sun8i_hdmi_phy_driver);
}

module_init(sun8i_dw_hdmi_init);
module_exit(sun8i_dw_hdmi_exit);

MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
MODULE_DESCRIPTION("Allwinner DW HDMI bridge");
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,15 @@ struct sun8i_dw_hdmi {
struct gpio_desc *ddc_en;
};

extern struct platform_driver sun8i_hdmi_phy_driver;

static inline struct sun8i_dw_hdmi *
encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder)
{
return container_of(encoder, struct sun8i_dw_hdmi, encoder);
}

int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node);

void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
Expand Down
41 changes: 36 additions & 5 deletions drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <linux/delay.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>

#include "sun8i_dw_hdmi.h"

Expand Down Expand Up @@ -597,10 +598,30 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
{ /* sentinel */ }
};

int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
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;

if (!pdev)
return -EPROBE_DEFER;

phy = platform_get_drvdata(pdev);
if (!phy)
return -EPROBE_DEFER;

hdmi->phy = phy;

put_device(&pdev->dev);

return 0;
}

static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device *dev = hdmi->dev;
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct sun8i_hdmi_phy *phy;
struct resource res;
void __iomem *regs;
Expand Down Expand Up @@ -704,7 +725,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
clk_prepare_enable(phy->clk_phy);
}

hdmi->phy = phy;
platform_set_drvdata(pdev, phy);

return 0;

Expand All @@ -728,9 +749,9 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
return ret;
}

void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
static int sun8i_hdmi_phy_remove(struct platform_device *pdev)
{
struct sun8i_hdmi_phy *phy = hdmi->phy;
struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev);

clk_disable_unprepare(phy->clk_mod);
clk_disable_unprepare(phy->clk_bus);
Expand All @@ -744,4 +765,14 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
clk_put(phy->clk_pll1);
clk_put(phy->clk_mod);
clk_put(phy->clk_bus);
return 0;
}

struct platform_driver sun8i_hdmi_phy_driver = {
.probe = sun8i_hdmi_phy_probe,
.remove = sun8i_hdmi_phy_remove,
.driver = {
.name = "sun8i-hdmi-phy",
.of_match_table = sun8i_hdmi_phy_of_table,
},
};

0 comments on commit 9bf3797

Please sign in to comment.