bcm27xx: update patches from RPi foundation
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0515-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch
1 From 4633a7bc5ffc15fe24c05e52f17a72c346baab6b Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Tue, 17 Dec 2019 09:58:34 +0100
4 Subject: [PATCH] i2c: brcmstb: Support BCM2711 HDMI BSC controllers
5
6 The HDMI blocks in the BCM2771 have an i2c controller to retrieve the
7 EDID. This block is split into two parts, the BSC and the AUTO_I2C,
8 lying in two separate register areas.
9
10 The AUTO_I2C block has a mailbox-like interface and will take away the
11 BSC control from the CPU if enabled. However, the BSC is the actually
12 the same controller than the one supported by the brcmstb driver, and
13 the AUTO_I2C doesn't really bring any immediate benefit.
14
15 Let's use the BSC then, but let's also tie the AUTO_I2C registers with a
16 separate compatible so that we can enable AUTO_I2C if needed in the
17 future.
18
19 The AUTO_I2C is enabled by default at boot though, so we first need to
20 release the BSC from the AUTO_I2C control.
21
22 Cc: Kamal Dasu <kdasu.kdev@gmail.com>
23 Cc: Wolfram Sang <wsa@the-dreams.de>
24 Cc: bcm-kernel-feedback-list@broadcom.com
25 Cc: linux-i2c@vger.kernel.org
26 Acked-by: Florian Fainelli <f.fainelli@gmail.com>
27 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
28 ---
29 drivers/i2c/busses/i2c-brcmstb.c | 33 ++++++++++++++++++++++++++++++++
30 1 file changed, 33 insertions(+)
31
32 --- a/drivers/i2c/busses/i2c-brcmstb.c
33 +++ b/drivers/i2c/busses/i2c-brcmstb.c
34 @@ -580,6 +580,31 @@ static void brcmstb_i2c_set_bsc_reg_defa
35 brcmstb_i2c_set_bus_speed(dev);
36 }
37
38 +#define AUTOI2C_CTRL0 0x26c
39 +#define AUTOI2C_CTRL0_RELEASE_BSC BIT(1)
40 +
41 +static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev)
42 +{
43 + struct platform_device *pdev = to_platform_device(dev->device);
44 + struct resource *iomem;
45 + void __iomem *autoi2c;
46 +
47 + /* Map hardware registers */
48 + iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c");
49 + autoi2c = devm_ioremap_resource(&pdev->dev, iomem);
50 + if (IS_ERR(autoi2c))
51 + return PTR_ERR(autoi2c);
52 +
53 + writel(AUTOI2C_CTRL0_RELEASE_BSC, autoi2c + AUTOI2C_CTRL0);
54 + devm_iounmap(&pdev->dev, autoi2c);
55 +
56 + /* We need to reset the controller after the release */
57 + dev->bsc_regmap->iic_enable = 0;
58 + bsc_writel(dev, dev->bsc_regmap->iic_enable, iic_enable);
59 +
60 + return 0;
61 +}
62 +
63 static int brcmstb_i2c_probe(struct platform_device *pdev)
64 {
65 int rc = 0;
66 @@ -609,6 +634,13 @@ static int brcmstb_i2c_probe(struct plat
67 goto probe_errorout;
68 }
69
70 + if (of_device_is_compatible(dev->device->of_node,
71 + "brcm,bcm2711-hdmi-i2c")) {
72 + rc = bcm2711_release_bsc(dev);
73 + if (rc)
74 + goto probe_errorout;
75 + }
76 +
77 rc = of_property_read_string(dev->device->of_node, "interrupt-names",
78 &int_name);
79 if (rc < 0)
80 @@ -705,6 +737,7 @@ static SIMPLE_DEV_PM_OPS(brcmstb_i2c_pm,
81 static const struct of_device_id brcmstb_i2c_of_match[] = {
82 {.compatible = "brcm,brcmstb-i2c"},
83 {.compatible = "brcm,brcmper-i2c"},
84 + {.compatible = "brcm,bcm2711-hdmi-i2c"},
85 {},
86 };
87 MODULE_DEVICE_TABLE(of, brcmstb_i2c_of_match);