1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include <elfloader.h>
8#include <sys_fputc.h>
9
10#define MPCORE_PRIV               0xF8F00000
11
12/* SCU */
13#define SCU_BASE                  (MPCORE_PRIV + 0x0)
14#define SCU_CTRL_OFFSET           0x000
15#define SCU_FILTADDR_START_OFFSET 0x040
16#define SCU_FILTADDR_END_OFFSET   0x044
17
18#define SCU_CTRL_EN               BIT(0)
19#define SCU_CTRL_ADDRFILT_EN      BIT(1)
20
21/* SLCR */
22#define SLCR_BASE                 0xF8000000
23#define SLCR_LOCK_OFFSET          0x004
24#define SLCR_UNLOCK_OFFSET        0x008
25#define SLCR_OCM_CFG_OFFSET       0x910
26
27#define SLCR_LOCK_KEY             0x767B
28#define SLCR_UNLOCK_KEY           0xDF0D
29
30#define SLCR_OCM_CFG_RAMHI(x)     BIT(x)
31#define SLCR_OCM_CFG_RAMHI_ALL    ( SLCR_OCM_CFG_RAMHI(0) \
32                                  | SLCR_OCM_CFG_RAMHI(1) \
33                                  | SLCR_OCM_CFG_RAMHI(2) \
34                                  | SLCR_OCM_CFG_RAMHI(3) )
35
36#define REG(a) *(volatile uint32_t*)(a)
37
38#define SCU(o)  REG(SCU_BASE + SCU_##o##_OFFSET)
39#define SLCR(o) REG(SLCR_BASE + SLCR_##o##_OFFSET)
40
41/* Remaps the OCM and ensures DDR is accessible at 0x00000000 */
42void remap_ram(void)
43{
44    /*** 29.4.1 Changing Address Mapping ***/
45    /* 1: Complete outstanding transactions */
46    asm volatile("dsb");
47    asm volatile("isb");
48
49    /* 2-4: prime the icache with this function
50     *      skipped because icache is disabled and our remapping does not
51     *      affect .text section */
52
53    /* 5-7: unlock SLCR, Modify OCM_CFG, lock SLCR */
54    SLCR(UNLOCK) = SLCR_UNLOCK_KEY;
55    SLCR(OCM_CFG) |= SLCR_OCM_CFG_RAMHI_ALL;
56    SLCR(LOCK) = SLCR_LOCK_KEY;
57
58    /* 8-9: Modify address filtering */
59    SCU(FILTADDR_START) = 0x00000000;
60    SCU(FILTADDR_END) = 0xFFE00000;
61
62    /* 10: Enable filtering */
63    SCU(CTRL) |= (SCU_CTRL_EN | SCU_CTRL_ADDRFILT_EN);
64
65    /* Ensure completion */
66    asm volatile("dmb");
67}
68
69void platform_init(void)
70{
71    remap_ram();
72}
73