/* * arch/arm/plat-orion/pcie.c * * Marvell Orion SoC PCIe handling. * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied.
*/
void __init orion_pcie_set_local_bus_nr(void __iomem *base, int nr)
{
u32 stat;
stat = readl(base + PCIE_STAT_OFF);
stat &= ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_OFFS);
stat |= nr << PCIE_STAT_BUS_OFFS;
writel(stat, base + PCIE_STAT_OFF);
}
void __init orion_pcie_reset(void __iomem *base)
{
u32 reg; int i;
/* * MV-S104860-U0, Rev. C: * PCI Express Unit Soft Reset * When set, generates an internal reset in the PCI Express unit. * This bit should be cleared after the link is re-established.
*/
reg = readl(base + PCIE_DEBUG_CTRL);
reg |= PCIE_DEBUG_SOFT_RESET;
writel(reg, base + PCIE_DEBUG_CTRL);
for (i = 0; i < 20; i++) {
mdelay(10);
if (orion_pcie_link_up(base)) break;
}
reg &= ~(PCIE_DEBUG_SOFT_RESET);
writel(reg, base + PCIE_DEBUG_CTRL);
}
/* * Setup PCIE BARs and Address Decode Wins: * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks * WIN[0-3] -> DRAM bank[0-3]
*/ staticvoid __init orion_pcie_setup_wins(void __iomem *base)
{ conststruct mbus_dram_target_info *dram;
u32 size; int i;
dram = mv_mbus_dram_info();
/* * First, disable and clear BARs and windows.
*/ for (i = 1; i <= 2; i++) {
writel(0, base + PCIE_BAR_CTRL_OFF(i));
writel(0, base + PCIE_BAR_LO_OFF(i));
writel(0, base + PCIE_BAR_HI_OFF(i));
}
for (i = 0; i < 5; i++) {
writel(0, base + PCIE_WIN04_CTRL_OFF(i));
writel(0, base + PCIE_WIN04_BASE_OFF(i));
writel(0, base + PCIE_WIN04_REMAP_OFF(i));
}
writel(0, base + PCIE_WIN5_CTRL_OFF);
writel(0, base + PCIE_WIN5_BASE_OFF);
writel(0, base + PCIE_WIN5_REMAP_OFF);
/* * Setup windows for DDR banks. Count total DDR size on the fly.
*/
size = 0; for (i = 0; i < dram->num_cs; i++) { conststruct mbus_dram_window *cs = dram->cs + i;
writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
writel(0, base + PCIE_WIN04_REMAP_OFF(i));
writel(((cs->size - 1) & 0xffff0000) |
(cs->mbus_attr << 8) |
(dram->mbus_dram_target_id << 4) | 1,
base + PCIE_WIN04_CTRL_OFF(i));
size += cs->size;
}
/* * Round up 'size' to the nearest power of two.
*/ if ((size & (size - 1)) != 0)
size = 1 << fls(size);
/* * Setup BAR[1] to all DRAM banks.
*/
writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
writel(0, base + PCIE_BAR_HI_OFF(1));
writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.