Add the MFD parent driver for the monolithic JH7110 HDMI IP block. This driver binds to the starfive,jh7110-hdmi-mfd node. Its sole responsibility is to map the entire shared register block, create a regmap with the correct configuration, and then call devm_of_platform_populate() to create its hdmi_phy and hdmi_controller child devices.
The child drivers will retrieve the shared regmap from this parent driver. Signed-off-by: Michal Wilczynski <[email protected]> --- MAINTAINERS | 1 + drivers/soc/starfive/Kconfig | 17 +++++++++ drivers/soc/starfive/Makefile | 1 + drivers/soc/starfive/jh7110-hdmi-mfd.c | 67 ++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 74e562a6b57ac9f776c4be2d6f0977c62bc03d46..f1867018ee92fb754689934f6d238f9c9f185161 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -24051,6 +24051,7 @@ F: Documentation/devicetree/bindings/display/bridge/starfive,jh7110-inno-hdmi-co F: Documentation/devicetree/bindings/mfd/starfive,jh7110-hdmi-mfd.yaml F: Documentation/devicetree/bindings/phy/starfive,jh7110-inno-hdmi-phy.yaml F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-vout-subsystem.yaml +F: drivers/soc/starfive/jh7110-hdmi-mfd.c F: drivers/soc/starfive/jh7110-vout-subsystem.c STARFIVE JH7110 DPHY RX DRIVER diff --git a/drivers/soc/starfive/Kconfig b/drivers/soc/starfive/Kconfig index 47e82aaaa7e0af9d5c718166601c59c1ca683d3a..e0232988050bd250529e373243f5ae1851b26135 100644 --- a/drivers/soc/starfive/Kconfig +++ b/drivers/soc/starfive/Kconfig @@ -21,5 +21,22 @@ config SOC_STARFIVE_JH7110_VOUT_SUBSYSTEM This is essential for the display hardware to be detected and to function correctly. +config SOC_STARFIVE_JH7110_HDMI_MFD + tristate "StarFive JH7110 HDMI MFD Driver" + depends on OF + help + This option enables the MFD (Multi-Function Device) parent driver + for the monolithic StarFive JH7110 HDMI peripheral. + + The JH7110 HDMI IP block contains both the digital controller + (DRM bridge) and the analog PHY (clock/phy provider) logic within + a single shared register space. + + This MFD driver acts as a wrapper. Its only job is to map the + shared registers and create separate logical child devices + for the "PHY" and the "controller". This is required to + correctly manage resources and break a circular clock dependency + between the PHY and the VOUT clock generator at probe time. + endmenu endif diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile index 17081cd67635b02f495230b117c9acb691ef33ba..15a4e8ca358f2bfe3ed0d00fea948edac4ccbd75 100644 --- a/drivers/soc/starfive/Makefile +++ b/drivers/soc/starfive/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_SOC_STARFIVE_JH7110_VOUT_SUBSYSTEM) += jh7110-vout-subsystem.o +obj-$(CONFIG_SOC_STARFIVE_JH7110_HDMI_MFD) += jh7110-hdmi-mfd.o diff --git a/drivers/soc/starfive/jh7110-hdmi-mfd.c b/drivers/soc/starfive/jh7110-hdmi-mfd.c new file mode 100644 index 0000000000000000000000000000000000000000..73f1d58b280d3efb770c2dcf1ac934e7a6a51c64 --- /dev/null +++ b/drivers/soc/starfive/jh7110-hdmi-mfd.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MFD Driver for StarFive JH7110 HDMI + * + * Copyright (c) 2025 Samsung Electronics Co., Ltd. + * Author: Michal Wilczynski <[email protected]> + * + * This driver binds to the monolithic HDMI block and creates separate + * logical platform devices for the HDMI Controller (bridge) and the + * HDMI PHY (clock/phy provider), allowing them to share a single regmap + * and breaking the probing circular dependency. + */ + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +static const struct regmap_config starfive_hdmi_regmap_config = { + .reg_bits = 32, + .val_bits = 8, + .max_register = 0x4000, +}; + +static int starfive_hdmi_mfd_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *regs; + struct regmap *regmap; + int ret; + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + regmap = devm_regmap_init_mmio(dev, regs, + &starfive_hdmi_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to init shared regmap\n"); + + ret = devm_of_platform_populate(dev); + if (ret) + dev_err(dev, "Failed to populate child devices: %d\n", ret); + + return ret; +} + +static const struct of_device_id starfive_hdmi_mfd_of_match[] = { + { .compatible = "starfive,jh7110-hdmi-mfd", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, starfive_hdmi_mfd_of_match); + +static struct platform_driver starfive_hdmi_mfd_driver = { + .probe = starfive_hdmi_mfd_probe, + .driver = { + .name = "starfive-hdmi-mfd", + .of_match_table = starfive_hdmi_mfd_of_match, + }, +}; +module_platform_driver(starfive_hdmi_mfd_driver); + +MODULE_AUTHOR("Michal Wilczynski <[email protected]>"); +MODULE_DESCRIPTION("StarFive JH7110 HDMI MFD Driver"); +MODULE_LICENSE("GPL"); -- 2.34.1
