[PATCH v7 09/19] drm/bridge: inno-hdmi: Use a regmap for register access
Michal Wilczynski
m.wilczynski at samsung.com
Fri Nov 6 05:58:43 PST 2026
On some SoCs the HDMI controller does not own its register window. The
StarFive JH7110 documents one 64 KB block, u0_hdmitx, that holds both
the controller and the PHY, so the parent device maps it and owns the
regmap while the two children share it.
Access the registers through a regmap. Use the one supplied by the
parent device when there is one, and otherwise create an MMIO regmap
over our own resource. The MMIO regmap uses 32-bit accesses with a
4-byte stride, matching the readl_relaxed() and writel_relaxed() calls
it replaces, so the Rockchip platforms see the same register accesses.
Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
---
drivers/gpu/drm/bridge/Kconfig | 1 +
drivers/gpu/drm/bridge/inno-hdmi.c | 39 ++++++++++++++++++++++++++++++++------
2 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index c7da6b02d7b6b281f328fb3016ea2f167f8da093..34bcee88170317a4796178452ab5d2e673daf1fd 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -105,6 +105,7 @@ config DRM_INNO_HDMI
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
+ select REGMAP_MMIO
config DRM_ITE_IT6263
tristate "ITE IT6263 LVDS/HDMI bridge"
diff --git a/drivers/gpu/drm/bridge/inno-hdmi.c b/drivers/gpu/drm/bridge/inno-hdmi.c
index aa64ffdbd30721603aebbcd5d5747851be789911..05007ed1d7af0b0f72721a0fd4def08fa621b525 100644
--- a/drivers/gpu/drm/bridge/inno-hdmi.c
+++ b/drivers/gpu/drm/bridge/inno-hdmi.c
@@ -396,7 +396,7 @@ struct inno_hdmi {
struct drm_bridge bridge;
struct clk *pclk;
struct clk *refclk;
- void __iomem *regs;
+ struct regmap *regmap;
struct regmap *grf;
struct inno_hdmi_i2c *i2c;
@@ -468,14 +468,25 @@ static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
return -EINVAL;
}
+static const struct regmap_config inno_hdmi_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
{
- return readl_relaxed(hdmi->regs + (offset) * 0x04);
+ u32 val;
+
+ if (regmap_read(hdmi->regmap, offset * 4, &val))
+ return 0;
+
+ return val;
}
static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val)
{
- writel_relaxed(val, hdmi->regs + (offset) * 0x04);
+ regmap_write(hdmi->regmap, offset * 4, val);
}
static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
@@ -1082,6 +1093,7 @@ struct inno_hdmi *inno_hdmi_probe(struct platform_device *pdev,
{
struct device *dev = &pdev->dev;
struct inno_hdmi *hdmi;
+ void __iomem *regs;
int irq;
int ret;
@@ -1097,9 +1109,24 @@ struct inno_hdmi *inno_hdmi_probe(struct platform_device *pdev,
hdmi->dev = dev;
hdmi->plat_data = plat_data;
- hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(hdmi->regs))
- return ERR_CAST(hdmi->regs);
+ /*
+ * On platforms where the controller shares a register space with
+ * other blocks, the parent owns the regmap. Otherwise map our own
+ * resource.
+ */
+ if (dev->parent)
+ hdmi->regmap = dev_get_regmap(dev->parent, NULL);
+
+ if (!hdmi->regmap) {
+ regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(regs))
+ return ERR_CAST(regs);
+
+ hdmi->regmap = devm_regmap_init_mmio(dev, regs,
+ &inno_hdmi_regmap_config);
+ if (IS_ERR(hdmi->regmap))
+ return ERR_CAST(hdmi->regmap);
+ }
hdmi->pclk = devm_clk_get_enabled(hdmi->dev, "pclk");
if (IS_ERR(hdmi->pclk)) {
--
2.34.1
More information about the linux-riscv
mailing list