mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 07:46:48 +00:00
88 lines
2.9 KiB
Diff
88 lines
2.9 KiB
Diff
|
From 4633a7bc5ffc15fe24c05e52f17a72c346baab6b Mon Sep 17 00:00:00 2001
|
||
|
From: Maxime Ripard <maxime@cerno.tech>
|
||
|
Date: Tue, 17 Dec 2019 09:58:34 +0100
|
||
|
Subject: [PATCH] i2c: brcmstb: Support BCM2711 HDMI BSC controllers
|
||
|
|
||
|
The HDMI blocks in the BCM2771 have an i2c controller to retrieve the
|
||
|
EDID. This block is split into two parts, the BSC and the AUTO_I2C,
|
||
|
lying in two separate register areas.
|
||
|
|
||
|
The AUTO_I2C block has a mailbox-like interface and will take away the
|
||
|
BSC control from the CPU if enabled. However, the BSC is the actually
|
||
|
the same controller than the one supported by the brcmstb driver, and
|
||
|
the AUTO_I2C doesn't really bring any immediate benefit.
|
||
|
|
||
|
Let's use the BSC then, but let's also tie the AUTO_I2C registers with a
|
||
|
separate compatible so that we can enable AUTO_I2C if needed in the
|
||
|
future.
|
||
|
|
||
|
The AUTO_I2C is enabled by default at boot though, so we first need to
|
||
|
release the BSC from the AUTO_I2C control.
|
||
|
|
||
|
Cc: Kamal Dasu <kdasu.kdev@gmail.com>
|
||
|
Cc: Wolfram Sang <wsa@the-dreams.de>
|
||
|
Cc: bcm-kernel-feedback-list@broadcom.com
|
||
|
Cc: linux-i2c@vger.kernel.org
|
||
|
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
|
||
|
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||
|
---
|
||
|
drivers/i2c/busses/i2c-brcmstb.c | 33 ++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 33 insertions(+)
|
||
|
|
||
|
--- a/drivers/i2c/busses/i2c-brcmstb.c
|
||
|
+++ b/drivers/i2c/busses/i2c-brcmstb.c
|
||
|
@@ -580,6 +580,31 @@ static void brcmstb_i2c_set_bsc_reg_defa
|
||
|
brcmstb_i2c_set_bus_speed(dev);
|
||
|
}
|
||
|
|
||
|
+#define AUTOI2C_CTRL0 0x26c
|
||
|
+#define AUTOI2C_CTRL0_RELEASE_BSC BIT(1)
|
||
|
+
|
||
|
+static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev)
|
||
|
+{
|
||
|
+ struct platform_device *pdev = to_platform_device(dev->device);
|
||
|
+ struct resource *iomem;
|
||
|
+ void __iomem *autoi2c;
|
||
|
+
|
||
|
+ /* Map hardware registers */
|
||
|
+ iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c");
|
||
|
+ autoi2c = devm_ioremap_resource(&pdev->dev, iomem);
|
||
|
+ if (IS_ERR(autoi2c))
|
||
|
+ return PTR_ERR(autoi2c);
|
||
|
+
|
||
|
+ writel(AUTOI2C_CTRL0_RELEASE_BSC, autoi2c + AUTOI2C_CTRL0);
|
||
|
+ devm_iounmap(&pdev->dev, autoi2c);
|
||
|
+
|
||
|
+ /* We need to reset the controller after the release */
|
||
|
+ dev->bsc_regmap->iic_enable = 0;
|
||
|
+ bsc_writel(dev, dev->bsc_regmap->iic_enable, iic_enable);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static int brcmstb_i2c_probe(struct platform_device *pdev)
|
||
|
{
|
||
|
int rc = 0;
|
||
|
@@ -609,6 +634,13 @@ static int brcmstb_i2c_probe(struct plat
|
||
|
goto probe_errorout;
|
||
|
}
|
||
|
|
||
|
+ if (of_device_is_compatible(dev->device->of_node,
|
||
|
+ "brcm,bcm2711-hdmi-i2c")) {
|
||
|
+ rc = bcm2711_release_bsc(dev);
|
||
|
+ if (rc)
|
||
|
+ goto probe_errorout;
|
||
|
+ }
|
||
|
+
|
||
|
rc = of_property_read_string(dev->device->of_node, "interrupt-names",
|
||
|
&int_name);
|
||
|
if (rc < 0)
|
||
|
@@ -705,6 +737,7 @@ static SIMPLE_DEV_PM_OPS(brcmstb_i2c_pm,
|
||
|
static const struct of_device_id brcmstb_i2c_of_match[] = {
|
||
|
{.compatible = "brcm,brcmstb-i2c"},
|
||
|
{.compatible = "brcm,brcmper-i2c"},
|
||
|
+ {.compatible = "brcm,bcm2711-hdmi-i2c"},
|
||
|
{},
|
||
|
};
|
||
|
MODULE_DEVICE_TABLE(of, brcmstb_i2c_of_match);
|