Skip to contentSkip to conversation

amba: tegra-ahb: fix base address and register offsets for future chip support

PATCH In review Paul Walmsley 2 participants 6 messages Mar 20, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw
Quoted 1 line

From a hardware SoC integration point of view, the offsets of the

Tegra AHB registers that are currently defined in tegra-ahb.c macros are all off by four bytes. Similarly, the starting address of this IP block in our existing DT files is also off by four bytes. This series fixes the driver such that the macro offsets are correct, and that the driver is backwards-compatible with previous chip DT data, but that future chip DT data can use the correct base. See also

    http://www.spinics.net/lists/arm-kernel/msg394171.html

This series has been boot-tested on Tegra20 Trimslice, Tegra30 Beaver, Tegra114 Dalmore, Tegra124 Jetson TK1, Tegra132 Norrin64 FFD (with a few additional out-of-tree patches, since T132 support is not yet upstream), and QEMU Versatile Express 64. Basic build and boot test logs for T30, T114, T124, and QEMU Versatile Express 64 are here:

http://nvt.pwsan.com/pub/pwalmsley-tester/testlogs/test_20150317011136_159e7763d517804c61a673736660a5a35f2ea5f8/20150317011136/

This series is based on next-20150319 and is intended for v4.1.

This third version of the series incorporates feedback from Russell King <[email protected]> and Stephen Warren <[email protected]>.

- Paul

#1 lore raw

PATCH v3 1/3 amba: tegra-ahb: fix register offsets in the macros

Quoted 1 line

From a hardware SoC integration point of view, the offsets of the

Tegra AHB registers that are currently defined in tegra-ahb.c macros are all off by four bytes. Similarly, the starting address of this IP block in our existing DT files is also off by four bytes. Since we attempt to make old DT files forward-compatible with newer kernels, we cannot fix the IP block base address in old DT data. However, we can fix the offsets in the driver so that they are correct with respect to the hardware, which is what this patch does. And a subsequent patch will allow the offset to be removed for DT 'compatible' strings used in future DT files for newer Tegra chips that the kernel does not yet support.

Cc Paul Walmsley <[email protected]>
Cc Alexandre Courbot <[email protected]>
Cc Hiroshi DOYU <[email protected]>
Cc Russell King <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Thierry Reding <[email protected]>
Cc linux-kernel at vger.kernel.org
---
 drivers/amba/tegra-ahb.c |   63 +++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 31 deletions(-)
drivers/amba/tegra-ahb.c +32 -31
index c6dc3548e5d1..30759a55efe4 100644
@@ -25,49 +25,50 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/of.h>
 
 #include <soc/tegra/ahb.h>
 
 #define DRV_NAME "tegra-ahb"
 
-#define AHB_ARBITRATION_DISABLE		0x00
-#define AHB_ARBITRATION_PRIORITY_CTRL	0x04
+#define AHB_ARBITRATION_DISABLE		0x04
+#define AHB_ARBITRATION_PRIORITY_CTRL	0x08
 #define   AHB_PRIORITY_WEIGHT(x)	(((x) & 0x7) << 29)
 #define   PRIORITY_SELECT_USB BIT(6)
 #define   PRIORITY_SELECT_USB2 BIT(18)
 #define   PRIORITY_SELECT_USB3 BIT(17)
 
-#define AHB_GIZMO_AHB_MEM		0x0c
+#define AHB_GIZMO_AHB_MEM		0x10
 #define   ENB_FAST_REARBITRATE BIT(2)
 #define   DONT_SPLIT_AHB_WR     BIT(7)
 
-#define AHB_GIZMO_APB_DMA		0x10
-#define AHB_GIZMO_IDE			0x18
-#define AHB_GIZMO_USB			0x1c
-#define AHB_GIZMO_AHB_XBAR_BRIDGE	0x20
-#define AHB_GIZMO_CPU_AHB_BRIDGE	0x24
-#define AHB_GIZMO_COP_AHB_BRIDGE	0x28
-#define AHB_GIZMO_XBAR_APB_CTLR		0x2c
-#define AHB_GIZMO_VCP_AHB_BRIDGE	0x30
-#define AHB_GIZMO_NAND			0x3c
-#define AHB_GIZMO_SDMMC4		0x44
-#define AHB_GIZMO_XIO			0x48
-#define AHB_GIZMO_BSEV			0x60
-#define AHB_GIZMO_BSEA			0x70
-#define AHB_GIZMO_NOR			0x74
-#define AHB_GIZMO_USB2			0x78
-#define AHB_GIZMO_USB3			0x7c
+#define AHB_GIZMO_APB_DMA		0x14
+#define AHB_GIZMO_IDE			0x1c
+#define AHB_GIZMO_USB			0x20
+#define AHB_GIZMO_AHB_XBAR_BRIDGE	0x24
+#define AHB_GIZMO_CPU_AHB_BRIDGE	0x28
+#define AHB_GIZMO_COP_AHB_BRIDGE	0x2c
+#define AHB_GIZMO_XBAR_APB_CTLR		0x30
+#define AHB_GIZMO_VCP_AHB_BRIDGE	0x34
+#define AHB_GIZMO_NAND			0x40
+#define AHB_GIZMO_SDMMC4		0x48
+#define AHB_GIZMO_XIO			0x4c
+#define AHB_GIZMO_BSEV			0x64
+#define AHB_GIZMO_BSEA			0x74
+#define AHB_GIZMO_NOR			0x78
+#define AHB_GIZMO_USB2			0x7c
+#define AHB_GIZMO_USB3			0x80
 #define   IMMEDIATE	BIT(18)
 
-#define AHB_GIZMO_SDMMC1		0x80
-#define AHB_GIZMO_SDMMC2		0x84
-#define AHB_GIZMO_SDMMC3		0x88
-#define AHB_MEM_PREFETCH_CFG_X		0xd8
-#define AHB_ARBITRATION_XBAR_CTRL	0xdc
-#define AHB_MEM_PREFETCH_CFG3		0xe0
-#define AHB_MEM_PREFETCH_CFG4		0xe4
-#define AHB_MEM_PREFETCH_CFG1		0xec
-#define AHB_MEM_PREFETCH_CFG2		0xf0
+#define AHB_GIZMO_SDMMC1		0x84
+#define AHB_GIZMO_SDMMC2		0x88
+#define AHB_GIZMO_SDMMC3		0x8c
+#define AHB_MEM_PREFETCH_CFG_X		0xdc
+#define AHB_ARBITRATION_XBAR_CTRL	0xe0
+#define AHB_MEM_PREFETCH_CFG3		0xe4
+#define AHB_MEM_PREFETCH_CFG4		0xe8
+#define AHB_MEM_PREFETCH_CFG1		0xf0
+#define AHB_MEM_PREFETCH_CFG2		0xf4
 #define   PREFETCH_ENB	BIT(31)
 #define   MST_ID(x)	(((x) & 0x1f) << 26)
 #define   AHBDMA_MST_ID	MST_ID(5)
@@ -77,7 +78,7 @@
 #define   ADDR_BNDRY(x)	(((x) & 0xf) << 21)
 #define   INACTIVITY_TIMEOUT(x)	(((x) & 0xffff) << 0)
 
-#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID	0xf8
+#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID	0xfc
 
 #define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)
 
@@ -123,12 +124,12 @@ struct tegra_ahb {
 
 static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
 {
-	return readl(ahb->regs + offset);
+	return readl(ahb->regs - 4 + offset);
 }
 
 static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
 {
-	writel(value, ahb->regs + offset);
+	writel(value, ahb->regs - 4 + offset);
 }
 
 #ifdef CONFIG_TEGRA_IOMMU_SMMU
#2 lore raw

PATCH v3 2/3 amba: tegra-ahb: detect and correct bogus base address

In reply to Paul Walmsley
Quoted 1 line

From a hardware SoC integration point of view, the starting address of

this IP block in the existing Tegra SoC DT files is off by 4 bytes from the actual base address. Since we attempt to make old DT files forward-compatible with newer kernels, we cannot fix the IP block base address in old DT data. This patch works around the problem by detecting the four byte base address offset in the driver code, and correcting it if it's detected. (In general, IP block base addresses almost always have a null low byte.)

Future SoC DT data for Tegra AHB should use the correct Tegra AHB base address, in cases where there is no DT data backward compatibility requirement.

This patch is a revision of the patch originally titled "amba: tegra-ahb: use correct base address for future chip support". This revision implements changes requested by Russell King:

http://marc.info/?l=linux-tegra&m=142658851825062&w=2
http://marc.info/?l=linux-tegra&m=142658873925178&w=2

Cc Paul Walmsley <[email protected]>
Cc Alexandre Courbot <[email protected]>
Cc Hiroshi DOYU <[email protected]>
Cc Russell King <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Thierry Reding <[email protected]>
Cc linux-kernel at vger.kernel.org
---
 drivers/amba/tegra-ahb.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/amba/tegra-ahb.c +21 -2
index 30759a55efe4..b0b688c481e8 100644
@@ -82,6 +82,16 @@
 
 #define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17)
 
+/*
+ * INCORRECT_BASE_ADDR_LOW_BYTE: Legacy kernel DT files for Tegra SoCs
+ * prior to Tegra124 generally use a physical base address ending in
+ * 0x4 for the AHB IP block.  According to the TRM, the low byte
+ * should be 0x0.  During device probing, this macro is used to detect
+ * whether the passed-in physical address is incorrect, and if so, to
+ * correct it.
+ */
+#define INCORRECT_BASE_ADDR_LOW_BYTE		0x4
+
 static struct platform_driver tegra_ahb_driver;
 
 static const u32 tegra_ahb_gizmo[] = {
@@ -124,12 +134,12 @@ struct tegra_ahb {
 
 static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
 {
-	return readl(ahb->regs - 4 + offset);
+	return readl(ahb->regs + offset);
 }
 
 static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset)
 {
-	writel(value, ahb->regs - 4 + offset);
+	writel(value, ahb->regs + offset);
 }
 
 #ifdef CONFIG_TEGRA_IOMMU_SMMU
@@ -258,6 +268,15 @@ static int tegra_ahb_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	/* Correct the IP block base address if necessary */
+	if (res &&
+	    (res->start & INCORRECT_BASE_ADDR_LOW_BYTE) ==
+	    INCORRECT_BASE_ADDR_LOW_BYTE) {
+		dev_warn(&pdev->dev, "incorrect AHB base address in DT data - enabling workaround\n");
+		res->start -= INCORRECT_BASE_ADDR_LOW_BYTE;
+	}
+
 	ahb->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(ahb->regs))
 		return PTR_ERR(ahb->regs);
#3 lore raw

PATCH v3 3/3 Documentation: DT bindings: Tegra AHB: require the legacy base address for existing chips

In reply to Paul Walmsley

Per Stephen Warren, note in the Tegra AHB DT binding documentation that we specifically deprecate any attempt to use the IP block's actual hardware base address, and advocate the use of the legacy "off-by-four" address in the 'regs' property, for Tegra chips with existing upstream Linux DT files that include a Tegra AHB node. This patch updates the documentation accordingly.

Changing the existing kernel DT data isn't under consideration because Linux kernel DT data policy is to preserve compatibility between newer DT data files and older kernels. However, this additional step of changing the documentation should discourage others from sending kernel patches to try to change the legacy kernel DT data. Furthermore, for out-of-tree software (such as bootloaders or other operating systems) that may rely on Linux kernel DT binding documentation as an ABI (but not the Linux kernel DT data itself), such a change may allow future convergence with the Linux kernel DT data without additional code changes.

Cc Paul Walmsley <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Alexandre Courbot <[email protected]>
Cc Eduardo Valentin <[email protected]>
Cc Ian Campbell <[email protected]>
Cc Kumar Gala <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Pawel Moll <[email protected]>
Cc Rob Herring <[email protected]>
Cc Thierry Reding <[email protected]>
Cc devicetree at vger.kernel.org
Cc linux-kernel at vger.kernel.org
---
 .../bindings/arm/tegra/nvidia,tegra20-ahb.txt      |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt +5 -2
index 067c9790062f..9a4295b54539 100644
@@ -5,9 +5,12 @@ Required properties:
   Tegra30, must contain "nvidia,tegra30-ahb".  Otherwise, must contain
   '"nvidia,<chip>-ahb", "nvidia,tegra30-ahb"' where <chip> is tegra124,
   tegra132, or tegra210.
-- reg : Should contain 1 register ranges(address and length)
+- reg : Should contain 1 register ranges(address and length).  For
+  Tegra20, Tegra30, and Tegra114 chips, the value must be <0x6000c004
+  0x10c>.  For Tegra124, Tegra132 and Tegra210 chips, the value should
+  be be <0x6000c000 0x150>.
 
-Example:
+Example (for a Tegra20 chip):
 	ahb: ahb at 6000c004 {
 		compatible = "nvidia,tegra20-ahb";
 		reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
#5 lore raw
In reply to Paul Walmsley

Hi folks

Quoted 8 lines · Paul Walmsley

This series has been boot-tested on Tegra20 Trimslice, Tegra30 Beaver, Tegra114 Dalmore, Tegra124 Jetson TK1, Tegra132 Norrin64 FFD (with a few additional out-of-tree patches, since T132 support is not yet upstream), and QEMU Versatile Express 64. Basic build and boot test logs for T30, T114, T124, and QEMU Versatile Express 64 are here:

http://nvt.pwsan.com/pub/pwalmsley-tester/testlogs/test_20150317011136_159e7763d517804c61a673736660a5a35f2ea5f8/20150317011136/

The above paragraph was accurate for the initial version of this series. But for this third version, the testing is a little different. Here's what the paragraph should have read:

---
This series has been boot-tested on Tegra20 Trimslice, Tegra30 Beaver, Tegra114 Dalmore, Tegra124 Jetson TK1, and QEMU Versatile Express 64. Basic build and boot test logs for T20, T30, T114, T124, and QEMU Versatile Express 64 are here:

http://nvt.pwsan.com/pub/pwalmsley-tester/testlogs/test_20150319225643_e8444885428c4257999e632eff35e8e8c8a8b504/20150319225643
---

The test summary is included below.

Sorry for the extra noise; I'm still working out some bugs in my NVIDIA patch-posting toolchain, which unfortunately is more complicated than it should be.

The rest of the original message is accurate.

- Paul

Test summary
------------

Build: zImage:
Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig

Build: Image:

    Pass: ( 1/ 1): defconfig

Boot to userspace: defconfig:

    Pass: ( 1/ 1): qemu-vexpress64

Boot to userspace: multi_v7_defconfig:

    Pass: ( 3/ 3): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra30-beaver

Boot to userspace: tegra_defconfig:

    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver
Acked-by on v3 3/3
#4 lore raw

Re: [PATCH v3 3/3] Documentation: DT bindings: Tegra AHB: require the legacy base address for existing chips

In reply to Paul Walmsley
Quoted 23 lines · Paul Walmsley

Per Stephen Warren, note in the Tegra AHB DT binding documentation that we specifically deprecate any attempt to use the IP block's actual hardware base address, and advocate the use of the legacy "off-by-four" address in the 'regs' property, for Tegra chips with existing upstream Linux DT files that include a Tegra AHB node. This patch updates the documentation accordingly.

Changing the existing kernel DT data isn't under consideration because Linux kernel DT data policy is to preserve compatibility between newer DT data files and older kernels. However, this additional step of changing the documentation should discourage others from sending kernel patches to try to change the legacy kernel DT data. Furthermore, for out-of-tree software (such as bootloaders or other operating systems) that may rely on Linux kernel DT binding documentation as an ABI (but not the Linux kernel DT data itself), such a change may allow future convergence with the Linux kernel DT data without additional code changes.

Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt +0 -0
index 067c9790062f..9a4295b54539 100644

Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt Required properties: · line 11

Quoted 8 lines
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt +4 -1
@@ -5,9 +5,12 @@ Required properties:
    Tegra30, must contain "nvidia,tegra30-ahb".  Otherwise, must contain
    '"nvidia,<chip>-ahb", "nvidia,tegra30-ahb"' where <chip> is tegra124,
    tegra132, or tegra210.
-- reg : Should contain 1 register ranges(address and length)
+- reg : Should contain 1 register ranges(address and length).  For
+  Tegra20, Tegra30, and Tegra114 chips, the value must be <0x6000c004
+  0x10c>.  For Tegra124, Tegra132 and Tegra210 chips, the value should
+  be be <0x6000c000 0x150>.

I would have expected the exception to exist on Tegra124 too since that's long been supported upstream. However, since we haven't actually added the AHB node into the DT files on Tegra124 yet, I suppose we can assume that nobody has anywhere so the slightly retro-active change on Tegra124 is OK.

The series,