121b29fc6SStefan Roese /*
221b29fc6SStefan Roese * Copyright (C) 2016 Stefan Roese <sr@denx.de>
321b29fc6SStefan Roese *
421b29fc6SStefan Roese * SPDX-License-Identifier: GPL-2.0+
521b29fc6SStefan Roese */
621b29fc6SStefan Roese
721b29fc6SStefan Roese #include <common.h>
821b29fc6SStefan Roese #include <dm.h>
921b29fc6SStefan Roese #include <fdtdec.h>
10*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
1121b29fc6SStefan Roese #include <asm/io.h>
1221b29fc6SStefan Roese #include <asm/system.h>
1321b29fc6SStefan Roese #include <asm/arch/cpu.h>
1421b29fc6SStefan Roese #include <asm/arch/soc.h>
1521b29fc6SStefan Roese #include <asm/armv8/mmu.h>
1621b29fc6SStefan Roese
1721b29fc6SStefan Roese DECLARE_GLOBAL_DATA_PTR;
1821b29fc6SStefan Roese
1921b29fc6SStefan Roese /* Armada 7k/8k */
2021b29fc6SStefan Roese #define MVEBU_RFU_BASE (MVEBU_REGISTER(0x6f0000))
2121b29fc6SStefan Roese #define RFU_GLOBAL_SW_RST (MVEBU_RFU_BASE + 0x84)
2221b29fc6SStefan Roese #define RFU_SW_RESET_OFFSET 0
2321b29fc6SStefan Roese
240d92f214SKonstantin Porotchkin /*
250d92f214SKonstantin Porotchkin * The following table includes all memory regions for Armada 7k and
260d92f214SKonstantin Porotchkin * 8k SoCs. The Armada 7k is missing the CP110 slave regions here. Lets
270d92f214SKonstantin Porotchkin * define these regions at the beginning of the struct so that they
280d92f214SKonstantin Porotchkin * can be easier removed later dynamically if an Armada 7k device is detected.
290d92f214SKonstantin Porotchkin * For a detailed memory map, please see doc/mvebu/armada-8k-memory.txt
300d92f214SKonstantin Porotchkin */
310d92f214SKonstantin Porotchkin #define ARMADA_7K8K_COMMON_REGIONS_START 2
3221b29fc6SStefan Roese static struct mm_region mvebu_mem_map[] = {
330d92f214SKonstantin Porotchkin /* Armada 80x0 memory regions include the CP1 (slave) units */
340d92f214SKonstantin Porotchkin {
350d92f214SKonstantin Porotchkin /* SRAM, MMIO regions - CP110 slave region */
360d92f214SKonstantin Porotchkin .phys = 0xf4000000UL,
370d92f214SKonstantin Porotchkin .virt = 0xf4000000UL,
380d92f214SKonstantin Porotchkin .size = 0x02000000UL, /* 32MiB internal registers */
390d92f214SKonstantin Porotchkin .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
400d92f214SKonstantin Porotchkin PTE_BLOCK_NON_SHARE
410d92f214SKonstantin Porotchkin },
420d92f214SKonstantin Porotchkin {
430d92f214SKonstantin Porotchkin /* PCI CP1 regions */
440d92f214SKonstantin Porotchkin .phys = 0xfa000000UL,
450d92f214SKonstantin Porotchkin .virt = 0xfa000000UL,
460d92f214SKonstantin Porotchkin .size = 0x04000000UL, /* 64MiB CP110 slave PCI space */
470d92f214SKonstantin Porotchkin .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
480d92f214SKonstantin Porotchkin PTE_BLOCK_NON_SHARE
490d92f214SKonstantin Porotchkin },
500d92f214SKonstantin Porotchkin /* Armada 80x0 and 70x0 common memory regions start here */
5121b29fc6SStefan Roese {
5221b29fc6SStefan Roese /* RAM */
5321b29fc6SStefan Roese .phys = 0x0UL,
5421b29fc6SStefan Roese .virt = 0x0UL,
5521b29fc6SStefan Roese .size = 0x80000000UL,
5621b29fc6SStefan Roese .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
5721b29fc6SStefan Roese PTE_BLOCK_INNER_SHARE
5821b29fc6SStefan Roese },
5921b29fc6SStefan Roese {
6021b29fc6SStefan Roese /* SRAM, MMIO regions - AP806 region */
6121b29fc6SStefan Roese .phys = 0xf0000000UL,
6221b29fc6SStefan Roese .virt = 0xf0000000UL,
6321b29fc6SStefan Roese .size = 0x01000000UL, /* 16MiB internal registers */
6421b29fc6SStefan Roese .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
6521b29fc6SStefan Roese PTE_BLOCK_NON_SHARE
6621b29fc6SStefan Roese },
6721b29fc6SStefan Roese {
683fef31a3SStefan Roese /* SRAM, MMIO regions - CP110 master region */
6921b29fc6SStefan Roese .phys = 0xf2000000UL,
7021b29fc6SStefan Roese .virt = 0xf2000000UL,
7121b29fc6SStefan Roese .size = 0x02000000UL, /* 32MiB internal registers */
7221b29fc6SStefan Roese .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
7321b29fc6SStefan Roese PTE_BLOCK_NON_SHARE
7421b29fc6SStefan Roese },
7521b29fc6SStefan Roese {
760d92f214SKonstantin Porotchkin /* PCI CP0 regions */
770d92f214SKonstantin Porotchkin .phys = 0xf6000000UL,
780d92f214SKonstantin Porotchkin .virt = 0xf6000000UL,
790d92f214SKonstantin Porotchkin .size = 0x04000000UL, /* 64MiB CP110 master PCI space */
803fef31a3SStefan Roese .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
813fef31a3SStefan Roese PTE_BLOCK_NON_SHARE
823fef31a3SStefan Roese },
833fef31a3SStefan Roese {
8421b29fc6SStefan Roese 0,
8521b29fc6SStefan Roese }
8621b29fc6SStefan Roese };
8721b29fc6SStefan Roese
8821b29fc6SStefan Roese struct mm_region *mem_map = mvebu_mem_map;
8921b29fc6SStefan Roese
enable_caches(void)900d92f214SKonstantin Porotchkin void enable_caches(void)
910d92f214SKonstantin Porotchkin {
920d92f214SKonstantin Porotchkin /*
930d92f214SKonstantin Porotchkin * Armada 7k is not equipped with the CP110 slave CP. In case this
940d92f214SKonstantin Porotchkin * code runs on an Armada 7k device, lets remove the CP110 slave
950d92f214SKonstantin Porotchkin * entries from the memory mapping by moving the start to the
960d92f214SKonstantin Porotchkin * common regions.
970d92f214SKonstantin Porotchkin */
980d92f214SKonstantin Porotchkin if (of_machine_is_compatible("marvell,armada7040"))
990d92f214SKonstantin Porotchkin mem_map = &mvebu_mem_map[ARMADA_7K8K_COMMON_REGIONS_START];
1000d92f214SKonstantin Porotchkin
1010d92f214SKonstantin Porotchkin icache_enable();
1020d92f214SKonstantin Porotchkin dcache_enable();
1030d92f214SKonstantin Porotchkin }
1040d92f214SKonstantin Porotchkin
reset_cpu(ulong ignored)10521b29fc6SStefan Roese void reset_cpu(ulong ignored)
10621b29fc6SStefan Roese {
10721b29fc6SStefan Roese u32 reg;
10821b29fc6SStefan Roese
10921b29fc6SStefan Roese reg = readl(RFU_GLOBAL_SW_RST);
11021b29fc6SStefan Roese reg &= ~(1 << RFU_SW_RESET_OFFSET);
11121b29fc6SStefan Roese writel(reg, RFU_GLOBAL_SW_RST);
11221b29fc6SStefan Roese }
113a2cb5593SKonstantin Porotchkin
114a2cb5593SKonstantin Porotchkin /*
115a2cb5593SKonstantin Porotchkin * TODO - implement this functionality using platform
116a2cb5593SKonstantin Porotchkin * clock driver once it gets available
117a2cb5593SKonstantin Porotchkin * Return NAND clock in Hz
118a2cb5593SKonstantin Porotchkin */
mvebu_get_nand_clock(void)119a2cb5593SKonstantin Porotchkin u32 mvebu_get_nand_clock(void)
120a2cb5593SKonstantin Porotchkin {
121a2cb5593SKonstantin Porotchkin unsigned long NAND_FLASH_CLK_CTRL = 0xF2440700UL;
122a2cb5593SKonstantin Porotchkin unsigned long NF_CLOCK_SEL_MASK = 0x1;
123a2cb5593SKonstantin Porotchkin u32 reg;
124a2cb5593SKonstantin Porotchkin
125a2cb5593SKonstantin Porotchkin reg = readl(NAND_FLASH_CLK_CTRL);
126a2cb5593SKonstantin Porotchkin if (reg & NF_CLOCK_SEL_MASK)
127a2cb5593SKonstantin Porotchkin return 400 * 1000000;
128a2cb5593SKonstantin Porotchkin else
129a2cb5593SKonstantin Porotchkin return 250 * 1000000;
130a2cb5593SKonstantin Porotchkin }
131