aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/amba/tegra-ahb.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 30759a55efe4..b0b688c481e8 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -82,6 +82,16 @@
82 82
83#define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17) 83#define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)
84 84
85/*
86 * INCORRECT_BASE_ADDR_LOW_BYTE: Legacy kernel DT files for Tegra SoCs
87 * prior to Tegra124 generally use a physical base address ending in
88 * 0x4 for the AHB IP block. According to the TRM, the low byte
89 * should be 0x0. During device probing, this macro is used to detect
90 * whether the passed-in physical address is incorrect, and if so, to
91 * correct it.
92 */
93#define INCORRECT_BASE_ADDR_LOW_BYTE 0x4
94
85static struct platform_driver tegra_ahb_driver; 95static struct platform_driver tegra_ahb_driver;
86 96
87static const u32 tegra_ahb_gizmo[] = { 97static const u32 tegra_ahb_gizmo[] = {
@@ -124,12 +134,12 @@ struct tegra_ahb {
124 134
125static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset) 135static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
126{ 136{
127 return readl(ahb->regs - 4 + offset); 137 return readl(ahb->regs + offset);
128} 138}
129 139
130static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset) 140static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
131{ 141{
132 writel(value, ahb->regs - 4 + offset); 142 writel(value, ahb->regs + offset);
133} 143}
134 144
135#ifdef CONFIG_TEGRA_IOMMU_SMMU 145#ifdef CONFIG_TEGRA_IOMMU_SMMU
@@ -258,6 +268,15 @@ static int tegra_ahb_probe(struct platform_device *pdev)
258 return -ENOMEM; 268 return -ENOMEM;
259 269
260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 270 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
271
272 /* Correct the IP block base address if necessary */
273 if (res &&
274 (res->start & INCORRECT_BASE_ADDR_LOW_BYTE) ==
275 INCORRECT_BASE_ADDR_LOW_BYTE) {
276 dev_warn(&pdev->dev, "incorrect AHB base address in DT data - enabling workaround\n");
277 res->start -= INCORRECT_BASE_ADDR_LOW_BYTE;
278 }
279
261 ahb->regs = devm_ioremap_resource(&pdev->dev, res); 280 ahb->regs = devm_ioremap_resource(&pdev->dev, res);
262 if (IS_ERR(ahb->regs)) 281 if (IS_ERR(ahb->regs))
263 return PTR_ERR(ahb->regs); 282 return PTR_ERR(ahb->regs);