Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / board / cortina / presidio-asic / presidio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2020 - Cortina Access Inc.
4  *
5  */
6 #include <common.h>
7 #include <init.h>
8 #include <malloc.h>
9 #include <errno.h>
10 #include <netdev.h>
11 #include <asm/io.h>
12 #include <linux/bitops.h>
13 #include <linux/compiler.h>
14 #include <configs/presidio_asic.h>
15 #include <linux/psci.h>
16 #include <asm/psci.h>
17 #include <cpu_func.h>
18 #include <asm/armv8/mmu.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #define CA_PERIPH_BASE                  0xE0000000UL
23 #define CA_PERIPH_SIZE                  0x20000000UL
24 #define CA_GLOBAL_BASE                  0xf4320000
25 #define CA_GLOBAL_JTAG_ID               0xf4320000
26 #define CA_GLOBAL_BLOCK_RESET           0xf4320004
27 #define CA_GLOBAL_BLOCK_RESET_RESET_DMA BIT(16)
28 #define CA_DMA_SEC_SSP_BAUDRATE_CTRL    0xf7001b94
29 #define CA_DMA_SEC_SSP_ID               0xf7001b80
30
31 int print_cpuinfo(void)
32 {
33         printf("CPU:   Cortina Presidio G3\n");
34         return 0;
35 }
36
37 static struct mm_region presidio_mem_map[] = {
38         {
39         .virt = DDR_BASE,
40         .phys = DDR_BASE,
41         .size = PHYS_SDRAM_1_SIZE,
42         .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
43                  PTE_BLOCK_OUTER_SHARE
44         },
45         {
46         .virt = CA_PERIPH_BASE,
47         .phys = CA_PERIPH_BASE,
48         .size = CA_PERIPH_SIZE,
49         .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
50                  PTE_BLOCK_NON_SHARE
51         },
52         {
53         /* List terminator */
54         0,
55         }
56 };
57
58 struct mm_region *mem_map = presidio_mem_map;
59
60 static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
61                                        u64 arg2)
62 {
63         asm volatile("mov x0, %0\n"
64                     "mov x1, %1\n"
65                     "mov x2, %2\n"
66                     "mov x3, %3\n"
67                     "smc        #0\n"
68                     : "+r" (function_id)
69                     : "r" (arg0), "r" (arg1), "r" (arg2)
70                     );
71
72         return function_id;
73 }
74
75 int board_early_init_r(void)
76 {
77         dcache_disable();
78         return 0;
79 }
80
81 int board_init(void)
82 {
83         unsigned int reg_data, jtag_id;
84
85         /* Enable timer */
86         writel(1, CONFIG_SYS_TIMER_BASE);
87
88         /* Enable snoop in CCI400 slave port#4 */
89         writel(3, 0xF5595000);
90
91         jtag_id = readl(CA_GLOBAL_JTAG_ID);
92
93         /* If this is HGU variant then do not use
94          * the Saturn daughter card ref. clk
95          */
96         if (jtag_id == 0x1010D8F3) {
97                 reg_data = readl(0xF3100064);
98                 /* change multifunc. REF CLK pin to
99                  * a simple GPIO pin
100                  */
101                 reg_data |= (1 << 1);
102                 writel(reg_data, 0xf3100064);
103         }
104
105         return 0;
106 }
107
108 int dram_init(void)
109 {
110         unsigned int ddr_size;
111
112         ddr_size = readl(0x111100c);
113         gd->ram_size = ddr_size * 0x100000;
114         return 0;
115 }
116
117 void reset_cpu(ulong addr)
118 {
119         invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
120 }
121
122 #ifdef CONFIG_LAST_STAGE_INIT
123 int last_stage_init(void)
124 {
125         u32 val;
126
127         val = readl(CA_GLOBAL_BLOCK_RESET);
128         val &= ~CA_GLOBAL_BLOCK_RESET_RESET_DMA;
129         writel(val, CA_GLOBAL_BLOCK_RESET);
130
131         /* reduce output pclk ~3.7Hz to save power consumption */
132         writel(0x000000FF, CA_DMA_SEC_SSP_BAUDRATE_CTRL);
133
134         return 0;
135 }
136 #endif