blob: adec7d32199410e07ab19546fa12d6f8390df5ee [file] [log] [blame]
Alexey Brodkin2c3f9262018-05-28 15:27:43 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
4 */
5
Simon Glass09140112020-05-10 11:40:03 -06006#include <command.h>
Simon Glass9a3b4ce2019-12-28 10:45:01 -07007#include <cpu_func.h>
Alexey Brodkin2c3f9262018-05-28 15:27:43 +03008#include <dwmmc.h>
Simon Glass691d7192020-05-10 11:40:02 -06009#include <init.h>
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030010#include <malloc.h>
Simon Glass401d1c42020-10-30 21:38:53 -060011#include <asm/global_data.h>
Simon Glasscd93d622020-05-10 11:40:13 -060012#include <linux/bitops.h>
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030013
Alexey Brodkin4e86c7e2018-11-27 09:46:59 +030014#include <asm/arcregs.h>
15
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030016DECLARE_GLOBAL_DATA_PTR;
17
Alexey Brodkin4e86c7e2018-11-27 09:46:59 +030018#define ARC_PERIPHERAL_BASE 0xF0000000
19
20#define CGU_ARC_FMEAS_ARC (void *)(ARC_PERIPHERAL_BASE + 0x84)
21#define CGU_ARC_FMEAS_ARC_START BIT(31)
22#define CGU_ARC_FMEAS_ARC_DONE BIT(30)
23#define CGU_ARC_FMEAS_ARC_CNT_MASK GENMASK(14, 0)
24#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET 0
25#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET 15
26
27#define SDIO_BASE (void *)(ARC_PERIPHERAL_BASE + 0x10000)
28
29int mach_cpu_init(void)
30{
31 int rcnt, fcnt;
32 u32 data;
33
34 /* Start frequency measurement */
35 writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
36
37 /* Poll DONE bit */
38 do {
39 data = readl(CGU_ARC_FMEAS_ARC);
40 } while (!(data & CGU_ARC_FMEAS_ARC_DONE));
41
42 /* Amount of reference 100 MHz clocks */
43 rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
44 CGU_ARC_FMEAS_ARC_CNT_MASK);
45
46 /* Amount of CPU clocks */
47 fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
48 CGU_ARC_FMEAS_ARC_CNT_MASK);
49
50 gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
51
52 return 0;
53}
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030054
Alexey Brodkin9ddaf1d2019-07-18 15:51:25 +030055int board_early_init_r(void)
56{
57#define EMSDP_PSRAM_BASE 0xf2001000
58#define PSRAM_FLASH_CONFIG_REG_0 (void *)(EMSDP_PSRAM_BASE + 0x10)
59#define PSRAM_FLASH_CONFIG_REG_1 (void *)(EMSDP_PSRAM_BASE + 0x14)
60#define CRE_ENABLE BIT(31)
61#define CRE_DRIVE_CMD BIT(6)
62
63#define PSRAM_RCR_DPD BIT(1)
64#define PSRAM_RCR_PAGE_MODE BIT(7)
65
66/*
67 * PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
68 * thus "<< 1".
69 */
70#define PSRAM_RCR_SETUP ((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)
71
72 // Switch PSRAM controller to command mode
73 writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
74 // Program Refresh Configuration Register (RCR) for BANK0
75 writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
76 // Switch PSRAM controller back to memory mode
77 writel(0, PSRAM_FLASH_CONFIG_REG_0);
78
79
80 // Switch PSRAM controller to command mode
81 writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
82 // Program Refresh Configuration Register (RCR) for BANK1
83 writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
84 // Switch PSRAM controller back to memory mode
85 writel(0, PSRAM_FLASH_CONFIG_REG_1);
86
87 printf("PSRAM initialized.\n");
88
89 return 0;
90}
91
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030092#define CREG_BASE 0xF0001000
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +030093#define CREG_BOOT (void *)(CREG_BASE + 0x0FF0)
94#define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0)
Alexey Brodkin6ef705b2018-11-27 09:47:01 +030095#define CREG_IP_VERSION (void *)(CREG_BASE + 0x0FF8)
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030096
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +030097/* Bits in CREG_BOOT register */
98#define CREG_BOOT_WP_BIT BIT(8)
Alexey Brodkin2c3f9262018-05-28 15:27:43 +030099
Harald Seiler35b65dd2020-12-15 16:47:52 +0100100void reset_cpu(void)
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300101{
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +0300102 writel(1, CREG_IP_SW_RESET);
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300103 while (1)
104 ; /* loop forever till reset */
105}
106
Simon Glass09140112020-05-10 11:40:03 -0600107static int do_emsdp_rom(struct cmd_tbl *cmdtp, int flag, int argc,
108 char *const argv[])
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300109{
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +0300110 u32 creg_boot = readl(CREG_BOOT);
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300111
112 if (!strcmp(argv[1], "unlock"))
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +0300113 creg_boot &= ~CREG_BOOT_WP_BIT;
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300114 else if (!strcmp(argv[1], "lock"))
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +0300115 creg_boot |= CREG_BOOT_WP_BIT;
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300116 else
117 return CMD_RET_USAGE;
118
Alexey Brodkinfb9a46a2018-11-27 09:47:00 +0300119 writel(creg_boot, CREG_BOOT);
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300120
121 return CMD_RET_SUCCESS;
122}
123
Simon Glass09140112020-05-10 11:40:03 -0600124struct cmd_tbl cmd_emsdp[] = {
Alexey Brodkinadc9b092018-10-18 09:54:58 +0300125 U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""),
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300126};
127
Simon Glass09140112020-05-10 11:40:03 -0600128static int do_emsdp(struct cmd_tbl *cmdtp, int flag, int argc,
129 char *const argv[])
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300130{
Simon Glass09140112020-05-10 11:40:03 -0600131 struct cmd_tbl *c;
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300132
Alexey Brodkinadc9b092018-10-18 09:54:58 +0300133 c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp));
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300134
Alexey Brodkinadc9b092018-10-18 09:54:58 +0300135 /* Strip off leading 'emsdp' command */
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300136 argc--;
137 argv++;
138
139 if (c == NULL || argc > c->maxargs)
140 return CMD_RET_USAGE;
141
142 return c->cmd(cmdtp, flag, argc, argv);
143}
144
145U_BOOT_CMD(
Alexey Brodkinadc9b092018-10-18 09:54:58 +0300146 emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp,
147 "Synopsys EMSDP specific commands",
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300148 "rom unlock - Unlock non-volatile memory for writing\n"
Alexey Brodkinadc9b092018-10-18 09:54:58 +0300149 "emsdp rom lock - Lock non-volatile memory to prevent writing\n"
Alexey Brodkin2c3f9262018-05-28 15:27:43 +0300150);
Alexey Brodkin6ef705b2018-11-27 09:47:01 +0300151
152int checkboard(void)
153{
154 int version = readl(CREG_IP_VERSION);
155
156 printf("Board: ARC EM Software Development Platform v%d.%d\n",
157 (version >> 16) & 0xff, version & 0xff);
158 return 0;
159};