summaryrefslogtreecommitdiff
path: root/board/cortina/presidio-asic/presidio.c
blob: 5c735222637319f97810ac28df9324f9d84bbc64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2020 - Cortina Access Inc.
 *
 */
#include <common.h>
#include <init.h>
#include <malloc.h>
#include <errno.h>
#include <netdev.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <configs/presidio_asic.h>
#include <linux/psci.h>
#include <asm/psci.h>
#include <cpu_func.h>
#include <asm/armv8/mmu.h>

DECLARE_GLOBAL_DATA_PTR;

#define CA_PERIPH_BASE                  0xE0000000UL
#define CA_PERIPH_SIZE                  0x20000000UL
#define CA_GLOBAL_BASE                  0xf4320000
#define CA_GLOBAL_JTAG_ID               0xf4320000
#define CA_GLOBAL_BLOCK_RESET           0xf4320004
#define CA_GLOBAL_BLOCK_RESET_RESET_DMA BIT(16)
#define CA_DMA_SEC_SSP_BAUDRATE_CTRL    0xf7001b94
#define CA_DMA_SEC_SSP_ID               0xf7001b80

int print_cpuinfo(void)
{
	printf("CPU:   Cortina Presidio G3\n");
	return 0;
}

static struct mm_region presidio_mem_map[] = {
	{
	.virt = DDR_BASE,
	.phys = DDR_BASE,
	.size = PHYS_SDRAM_1_SIZE,
	.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
		 PTE_BLOCK_OUTER_SHARE
	},
	{
	.virt = CA_PERIPH_BASE,
	.phys = CA_PERIPH_BASE,
	.size = CA_PERIPH_SIZE,
	.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
		 PTE_BLOCK_NON_SHARE
	},
	{
	/* List terminator */
	0,
	}
};

struct mm_region *mem_map = presidio_mem_map;

static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
				       u64 arg2)
{
	asm volatile("mov x0, %0\n"
		    "mov x1, %1\n"
		    "mov x2, %2\n"
		    "mov x3, %3\n"
		    "smc	#0\n"
		    : "+r" (function_id)
		    : "r" (arg0), "r" (arg1), "r" (arg2)
		    );

	return function_id;
}

int board_early_init_r(void)
{
	dcache_disable();
	return 0;
}

int board_init(void)
{
	unsigned int reg_data, jtag_id;

	/* Enable timer */
	writel(1, CONFIG_SYS_TIMER_BASE);

	/* Enable snoop in CCI400 slave port#4 */
	writel(3, 0xF5595000);

	jtag_id = readl(CA_GLOBAL_JTAG_ID);

	/* If this is HGU variant then do not use
	 * the Saturn daughter card ref. clk
	 */
	if (jtag_id == 0x1010D8F3) {
		reg_data = readl(0xF3100064);
		/* change multifunc. REF CLK pin to
		 * a simple GPIO pin
		 */
		reg_data |= (1 << 1);
		writel(reg_data, 0xf3100064);
	}

	return 0;
}

int dram_init(void)
{
	unsigned int ddr_size;

	ddr_size = readl(0x111100c);
	gd->ram_size = ddr_size * 0x100000;
	return 0;
}

void reset_cpu(ulong addr)
{
	invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}

#ifdef CONFIG_LAST_STAGE_INIT
int last_stage_init(void)
{
	u32 val;

	val = readl(CA_GLOBAL_BLOCK_RESET);
	val &= ~CA_GLOBAL_BLOCK_RESET_RESET_DMA;
	writel(val, CA_GLOBAL_BLOCK_RESET);

	/* reduce output pclk ~3.7Hz to save power consumption */
	writel(0x000000FF, CA_DMA_SEC_SSP_BAUDRATE_CTRL);

	return 0;
}
#endif