diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch b/target/linux/bcm27xx/patches-5.4/950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch new file mode 100644 index 0000000000..76ce7403da --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch @@ -0,0 +1,87 @@ +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); |