aboutsummaryrefslogtreecommitdiff
path: root/board/synopsys/emsdp/emsdp.c
blob: adec7d32199410e07ab19546fa12d6f8390df5ee (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
 */

#include <command.h>
#include <cpu_func.h>
#include <dwmmc.h>
#include <init.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <linux/bitops.h>

#include <asm/arcregs.h>

DECLARE_GLOBAL_DATA_PTR;

#define ARC_PERIPHERAL_BASE		0xF0000000

#define CGU_ARC_FMEAS_ARC		(void *)(ARC_PERIPHERAL_BASE + 0x84)
#define CGU_ARC_FMEAS_ARC_START		BIT(31)
#define CGU_ARC_FMEAS_ARC_DONE		BIT(30)
#define CGU_ARC_FMEAS_ARC_CNT_MASK	GENMASK(14, 0)
#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET	0
#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET	15

#define SDIO_BASE			(void *)(ARC_PERIPHERAL_BASE + 0x10000)

int mach_cpu_init(void)
{
	int rcnt, fcnt;
	u32 data;

	/* Start frequency measurement */
	writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);

	/* Poll DONE bit */
	do {
		data = readl(CGU_ARC_FMEAS_ARC);
	} while (!(data & CGU_ARC_FMEAS_ARC_DONE));

	/* Amount of reference 100 MHz clocks */
	rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
	       CGU_ARC_FMEAS_ARC_CNT_MASK);

	/* Amount of CPU clocks */
	fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
	       CGU_ARC_FMEAS_ARC_CNT_MASK);

	gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;

	return 0;
}

int board_early_init_r(void)
{
#define EMSDP_PSRAM_BASE		0xf2001000
#define PSRAM_FLASH_CONFIG_REG_0	(void *)(EMSDP_PSRAM_BASE + 0x10)
#define PSRAM_FLASH_CONFIG_REG_1	(void *)(EMSDP_PSRAM_BASE + 0x14)
#define CRE_ENABLE			BIT(31)
#define CRE_DRIVE_CMD			BIT(6)

#define PSRAM_RCR_DPD			BIT(1)
#define PSRAM_RCR_PAGE_MODE		BIT(7)

/*
 * PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
 * thus "<< 1".
 */
#define PSRAM_RCR_SETUP		((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)

	// Switch PSRAM controller to command mode
	writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
	// Program Refresh Configuration Register (RCR) for BANK0
	writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
	// Switch PSRAM controller back to memory mode
	writel(0, PSRAM_FLASH_CONFIG_REG_0);


	// Switch PSRAM controller to command mode
	writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
	// Program Refresh Configuration Register (RCR) for BANK1
	writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
	// Switch PSRAM controller back to memory mode
	writel(0, PSRAM_FLASH_CONFIG_REG_1);

	printf("PSRAM initialized.\n");

	return 0;
}

#define CREG_BASE		0xF0001000
#define CREG_BOOT		(void *)(CREG_BASE + 0x0FF0)
#define CREG_IP_SW_RESET	(void *)(CREG_BASE + 0x0FF0)
#define CREG_IP_VERSION		(void *)(CREG_BASE + 0x0FF8)

/* Bits in CREG_BOOT register */
#define CREG_BOOT_WP_BIT	BIT(8)

void reset_cpu(void)
{
	writel(1, CREG_IP_SW_RESET);
	while (1)
		; /* loop forever till reset */
}

static int do_emsdp_rom(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	u32 creg_boot = readl(CREG_BOOT);

	if (!strcmp(argv[1], "unlock"))
		creg_boot &= ~CREG_BOOT_WP_BIT;
	else if (!strcmp(argv[1], "lock"))
		creg_boot |= CREG_BOOT_WP_BIT;
	else
		return CMD_RET_USAGE;

	writel(creg_boot, CREG_BOOT);

	return CMD_RET_SUCCESS;
}

struct cmd_tbl cmd_emsdp[] = {
	U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""),
};

static int do_emsdp(struct cmd_tbl *cmdtp, int flag, int argc,
		    char *const argv[])
{
	struct cmd_tbl *c;

	c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp));

	/* Strip off leading 'emsdp' command */
	argc--;
	argv++;

	if (c == NULL || argc > c->maxargs)
		return CMD_RET_USAGE;

	return c->cmd(cmdtp, flag, argc, argv);
}

U_BOOT_CMD(
	emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp,
	"Synopsys EMSDP specific commands",
	"rom unlock - Unlock non-volatile memory for writing\n"
	"emsdp rom lock - Lock non-volatile memory to prevent writing\n"
);

int checkboard(void)
{
	int version = readl(CREG_IP_VERSION);

	printf("Board: ARC EM Software Development Platform v%d.%d\n",
	       (version >> 16) & 0xff, version & 0xff);
	return 0;
};