Commit 79e1c5e7 authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Rich Felker

arch/sh: pcie-sh7786: adjust the memory mapping

The code setting up the PCI -> SuperHighway mapping doesn't take into
account the fact that the address stored in PCIELARx must be aligned
with the size stored in PCIELAMRx.

For example, when your physical memory starts at 0x0800_0000 (128 MB),
a size of 64 MB or 128 MB is fine. However, if you have 256 MB of
memory, it doesn't work because the base address is not aligned on the
size.

In such situation, we have to round down the base address to make sure
it is aligned on the size of the area. For for a 0x0800_0000 base
address with 256 MB of memory, we will round down to 0x0, and extend
the size of the mapping to 512 MB.

This allows the mapping to work on platforms that have 256 MB of
RAM. The current setup would only work with 128 MB of RAM or less.
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: default avatarRich Felker <dalias@libc.org>
parent 5da1bb96
...@@ -302,7 +302,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) ...@@ -302,7 +302,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
{ {
struct pci_channel *chan = port->hose; struct pci_channel *chan = port->hose;
unsigned int data; unsigned int data;
phys_addr_t memphys; phys_addr_t memstart, memend;
size_t memsize; size_t memsize;
int ret, i, win; int ret, i, win;
...@@ -358,15 +358,24 @@ static int __init pcie_init(struct sh7786_pcie_port *port) ...@@ -358,15 +358,24 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
data |= (0xff << 16); data |= (0xff << 16);
pci_write_reg(chan, data, SH4A_PCIEMACCTLR); pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
memphys = __pa(memory_start); memstart = __pa(memory_start);
memsize = roundup_pow_of_two(memory_end - memory_start); memend = __pa(memory_end);
memsize = roundup_pow_of_two(memend - memstart);
/*
* The start address must be aligned on its size. So we round
* it down, and then recalculate the size so that it covers
* the entire memory.
*/
memstart = ALIGN_DOWN(memstart, memsize);
memsize = roundup_pow_of_two(memend - memstart);
/* /*
* If there's more than 512MB of memory, we need to roll over to * If there's more than 512MB of memory, we need to roll over to
* LAR1/LAMR1. * LAR1/LAMR1.
*/ */
if (memsize > SZ_512M) { if (memsize > SZ_512M) {
pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1); pci_write_reg(chan, memstart + SZ_512M, SH4A_PCIELAR1);
pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1, pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
SH4A_PCIELAMR1); SH4A_PCIELAMR1);
memsize = SZ_512M; memsize = SZ_512M;
...@@ -382,7 +391,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) ...@@ -382,7 +391,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
* LAR0/LAMR0 covers up to the first 512MB, which is enough to * LAR0/LAMR0 covers up to the first 512MB, which is enough to
* cover all of lowmem on most platforms. * cover all of lowmem on most platforms.
*/ */
pci_write_reg(chan, memphys, SH4A_PCIELAR0); pci_write_reg(chan, memstart, SH4A_PCIELAR0);
pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0); pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);
/* Finish initialization */ /* Finish initialization */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment