Patchwork [2/4] arm: plat-orion: fix address decoding when > 4GB is used

login
register
mail settings
Submitter Thomas Petazzoni
Date March 6, 2013, 10:23 a.m.
Message ID <1362565416-15718-3-git-send-email-thomas.petazzoni@free-electrons.com>
Download mbox | patch
Permalink /patch/225472/
State New
Headers show

Comments

Thomas Petazzoni - March 6, 2013, 10:23 a.m.
During the system initialization, the orion_setup_cpu_mbus_target()
function reads the SDRAM address decoding registers to find out how
many chip-selects of SDRAM have been enabled, and builds a small array
with one entry per chip-select. This array is then used by device
drivers (XOR, Ethernet, etc.) to configure their own address decoding
windows to the SDRAM.

However, devices can only access the first 32 bits of the physical
memory. Even though LPAE is not supported for now, some Marvell boards
are now showing up with 8 GB of RAM, configured using two SDRAM
address decoding windows: the first covering the first 4 GB, the
second covering the last 4 GB. The array built by
orion_setup_cpu_mbus_target() has therefore two entries, and device
drivers try to set up two address decoding windows to the
SDRAM. However, in the device registers for the address decoding, the
base address is only 32 bits, so those two windows overlap each other,
and the devices do not work at all.

This patch makes sure that the array built by
orion_setup_cpu_mbus_target() only contains the SDRAM decoding windows
that correspond to the first 4 GB of the memory. To do that, it
ignores the SDRAM decoding windows for which the 4 low-order bits are
not zero (the 4 low-order bits of the base register are used to store
bits 32:35 of the base address, so they actually indicate whether the
base address is above 4 GB).

This patch allows the newly introduced armada-xp-gp board to properly
operate when it is mounted with more than 4 GB of RAM. Without that,
all devices doing DMA (for example XOR and Ethernet) do not work at
all.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
This is a slightly updated version compared to the one sent on
February 27th on LAKML. The earlier version was looking at the three
low-order bits, but in fact there are four low-order bits to encode
the high bits of the base address. So the mask was changed from 0x7 to
0xF.

Since I've changed the patch, I haven't kept the Tested-by from Lior
Amsalem, Grégory Clement and Ezequiel Garcia.
---
 arch/arm/plat-orion/addr-map.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
Jason - March 7, 2013, 12:30 a.m.
On Wed, Mar 06, 2013 at 11:23:34AM +0100, Thomas Petazzoni wrote:
...
> This is a slightly updated version compared to the one sent on
> February 27th on LAKML. The earlier version was looking at the three
> low-order bits, but in fact there are four low-order bits to encode
> the high bits of the base address. So the mask was changed from 0x7 to
> 0xF.
> 
> Since I've changed the patch, I haven't kept the Tested-by from Lior
> Amsalem, Grégory Clement and Ezequiel Garcia.

Then please don't send this as part of a pull-request.  Threading it
under a pull-request implies that it is ready to be applied, causing
most reviewers/testers to ignore the email.  Please have Lior, Grégory,
and Ezequiel retest and report back.

thx,

Jason.
Ezequiel Garcia - March 7, 2013, 10:25 a.m.
On Wed, Mar 06, 2013 at 11:23:34AM +0100, Thomas Petazzoni wrote:
> During the system initialization, the orion_setup_cpu_mbus_target()
> function reads the SDRAM address decoding registers to find out how
> many chip-selects of SDRAM have been enabled, and builds a small array
> with one entry per chip-select. This array is then used by device
> drivers (XOR, Ethernet, etc.) to configure their own address decoding
> windows to the SDRAM.
> 
> However, devices can only access the first 32 bits of the physical
> memory. Even though LPAE is not supported for now, some Marvell boards
> are now showing up with 8 GB of RAM, configured using two SDRAM
> address decoding windows: the first covering the first 4 GB, the
> second covering the last 4 GB. The array built by
> orion_setup_cpu_mbus_target() has therefore two entries, and device
> drivers try to set up two address decoding windows to the
> SDRAM. However, in the device registers for the address decoding, the
> base address is only 32 bits, so those two windows overlap each other,
> and the devices do not work at all.
> 
> This patch makes sure that the array built by
> orion_setup_cpu_mbus_target() only contains the SDRAM decoding windows
> that correspond to the first 4 GB of the memory. To do that, it
> ignores the SDRAM decoding windows for which the 4 low-order bits are
> not zero (the 4 low-order bits of the base register are used to store
> bits 32:35 of the base address, so they actually indicate whether the
> base address is above 4 GB).
> 
> This patch allows the newly introduced armada-xp-gp board to properly
> operate when it is mounted with more than 4 GB of RAM. Without that,
> all devices doing DMA (for example XOR and Ethernet) do not work at
> all.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Thomas Petazzoni - March 7, 2013, 10:30 a.m.
Dear Jason Cooper,

On Wed, 6 Mar 2013 19:30:22 -0500, Jason Cooper wrote:

> > Since I've changed the patch, I haven't kept the Tested-by from Lior
> > Amsalem, Grégory Clement and Ezequiel Garcia.
> 
> Then please don't send this as part of a pull-request.  Threading it
> under a pull-request implies that it is ready to be applied, causing
> most reviewers/testers to ignore the email.  Please have Lior,
> Grégory, and Ezequiel retest and report back.

I believe it is ready to be applied. The change I've done from the
version tested by others is minor, and I'm quite convinced that the
change is OK. If the change had been more significant, I would for sure
not have sent this as a pull request.

Best regards,

Thomas

Patch

diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
index febe386..807ac8e 100644
--- a/arch/arm/plat-orion/addr-map.c
+++ b/arch/arm/plat-orion/addr-map.c
@@ -157,9 +157,12 @@  void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
 		u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
 
 		/*
-		 * Chip select enabled?
+		 * We only take care of entries for which the chip
+		 * select is enabled, and that don't have high base
+		 * address bits set (devices can only access the first
+		 * 32 bits of the memory).
 		 */
-		if (size & 1) {
+		if ((size & 1) && !(base & 0xF)) {
 			struct mbus_dram_window *w;
 
 			w = &orion_mbus_dram_info.cs[cs++];