blob: 3c132f127179cd0bb765951f25b9d2b108cc597b [file] [log] [blame]
Alex Nemirovsky1ecad072020-01-30 12:34:59 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2020 - Cortina Access Inc.
4 *
5 */
6#include <common.h>
Simon Glass97589732020-05-10 11:40:02 -06007#include <init.h>
Alex Nemirovsky1ecad072020-01-30 12:34:59 -08008#include <malloc.h>
9#include <errno.h>
10#include <netdev.h>
11#include <asm/io.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060012#include <linux/bitops.h>
Alex Nemirovsky1ecad072020-01-30 12:34:59 -080013#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
20DECLARE_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
31int print_cpuinfo(void)
32{
33 printf("CPU: Cortina Presidio G3\n");
34 return 0;
35}
36
37static 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
58struct mm_region *mem_map = presidio_mem_map;
59
60static 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
75int board_early_init_r(void)
76{
77 dcache_disable();
78 return 0;
79}
80
81int 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
108int 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
117void 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
123int 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