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