Skip to content

Commit 82f75ed

Browse files
katsustercfriedt
authored andcommitted
soc: riscv: add initial support for SiFive Freedom U540
This patch adds support for SiFive Freedom U540 SoC. First version is minimum only using UART, SPI and DDR memory area. Signed-off-by: Katsuhiro Suzuki <[email protected]>
1 parent 763428d commit 82f75ed

File tree

6 files changed

+268
-5
lines changed

6 files changed

+268
-5
lines changed

dts/riscv/riscv64-fu540.dtsi

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
* Copyright (c) 2021 Katsuhiro Suzuki
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <dt-bindings/gpio/gpio.h>
8+
9+
/ {
10+
#address-cells = <1>;
11+
#size-cells = <1>;
12+
compatible = "sifive,FU540-C000", "fu540-dev", "sifive-dev";
13+
model = "sifive,FU540";
14+
15+
cpus {
16+
#address-cells = <1>;
17+
#size-cells = <0>;
18+
19+
cpu: cpu@0 {
20+
compatible = "sifive,e51", "riscv";
21+
device_type = "cpu";
22+
reg = <0>;
23+
riscv,isa = "rv64imac";
24+
status = "okay";
25+
26+
hlic: interrupt-controller {
27+
#interrupt-cells = <1>;
28+
compatible = "riscv,cpu-intc";
29+
interrupt-controller;
30+
};
31+
};
32+
};
33+
34+
soc {
35+
#address-cells = <1>;
36+
#size-cells = <1>;
37+
compatible = "simple-bus";
38+
ranges;
39+
40+
modeselect: rom@1000 {
41+
compatible = "sifive,modeselect0";
42+
reg = <0x1000 0x1000>;
43+
reg-names = "mem";
44+
};
45+
46+
maskrom: rom@10000 {
47+
compatible = "sifive,maskrom0";
48+
reg = <0x10000 0x8000>;
49+
reg-names = "mem";
50+
};
51+
52+
dtim: dtim@1000000 {
53+
compatible = "sifive,dtim0";
54+
reg = <0x1000000 0x2000>;
55+
reg-names = "mem";
56+
};
57+
58+
itim0: itim0@1800000 {
59+
compatible = "sifive,itim0";
60+
reg = <0x1800000 0x2000>;
61+
reg-names = "mem";
62+
};
63+
64+
itim1: itim1@1808000 {
65+
compatible = "sifive,itim0";
66+
reg = <0x1808000 0x7000>;
67+
reg-names = "mem";
68+
};
69+
70+
itim2: itim2@1810000 {
71+
compatible = "sifive,itim0";
72+
reg = <0x1810000 0x7000>;
73+
reg-names = "mem";
74+
};
75+
76+
itim3: itim3@1818000 {
77+
compatible = "sifive,itim0";
78+
reg = <0x1818000 0x7000>;
79+
reg-names = "mem";
80+
};
81+
82+
itim4: itim4@1820000 {
83+
compatible = "sifive,itim0";
84+
reg = <0x1820000 0x7000>;
85+
reg-names = "mem";
86+
};
87+
88+
clint: clint@2000000 {
89+
#interrupt-cells = <1>;
90+
compatible = "riscv,clint0";
91+
interrupt-controller;
92+
interrupts-extended = <&hlic 3 &hlic 7>;
93+
reg = <0x2000000 0x10000>;
94+
reg-names = "control";
95+
};
96+
97+
l2lim: l2lim@8000000 {
98+
compatible = "sifive,l2lim0";
99+
reg = <0x8000000 0x2000000>;
100+
reg-names = "mem";
101+
};
102+
103+
plic: interrupt-controller@c000000 {
104+
#interrupt-cells = <2>;
105+
compatible = "sifive,plic-1.0.0";
106+
interrupt-controller;
107+
interrupts-extended = <&hlic 11>;
108+
reg = <0x0c000000 0x00002000
109+
0x0c002000 0x001fe000
110+
0x0c200000 0x03e00000>;
111+
reg-names = "prio", "irq_en", "reg";
112+
riscv,max-priority = <7>;
113+
riscv,ndev = <52>;
114+
};
115+
116+
uart0: serial@10010000 {
117+
compatible = "sifive,uart0";
118+
interrupt-parent = <&plic>;
119+
interrupts = <4 1>;
120+
reg = <0x10010000 0x1000>;
121+
reg-names = "control";
122+
label = "uart_0";
123+
status = "disabled";
124+
};
125+
126+
uart1: serial@10011000 {
127+
compatible = "sifive,uart0";
128+
interrupt-parent = <&plic>;
129+
interrupts = <5 1>;
130+
reg = <0x10011000 0x1000>;
131+
reg-names = "control";
132+
label = "uart_1";
133+
status = "disabled";
134+
};
135+
136+
spi0: spi@10040000 {
137+
compatible = "sifive,spi0";
138+
interrupt-parent = <&plic>;
139+
interrupts = <51 1>;
140+
reg = <0x10040000 0x1000 0x20000000 0x10000000>;
141+
reg-names = "control", "mem";
142+
label = "spi_0";
143+
status = "disabled";
144+
#address-cells = <1>;
145+
#size-cells = <0>;
146+
};
147+
148+
spi1: spi@10041000 {
149+
compatible = "sifive,spi0";
150+
interrupt-parent = <&plic>;
151+
interrupts = <52 1>;
152+
reg = <0x10041000 0x1000>;
153+
reg-names = "control";
154+
label = "spi_1";
155+
status = "disabled";
156+
#address-cells = <1>;
157+
#size-cells = <0>;
158+
};
159+
160+
spi2: spi@10050000 {
161+
compatible = "sifive,spi0";
162+
interrupt-parent = <&plic>;
163+
interrupts = <6 1>;
164+
reg = <0x10050000 0x1000>;
165+
reg-names = "control";
166+
label = "spi_2";
167+
status = "disabled";
168+
#address-cells = <1>;
169+
#size-cells = <0>;
170+
};
171+
};
172+
};
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
zephyr_sources()
4-
zephyr_sources(fe310_clock.c)
4+
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FREEDOM fe310_clock.c)
5+
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU540 fu540_clock.c)

soc/riscv/riscv-privilege/sifive-freedom/Kconfig.soc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ config SOC_RISCV_SIFIVE_FREEDOM
1111
bool "SiFive Freedom SOC implementation"
1212
select ATOMIC_OPERATIONS_C
1313

14+
config SOC_RISCV_SIFIVE_FU540
15+
bool "SiFive Freedom U540 SOC implementation"
16+
select ATOMIC_OPERATIONS_C
17+
select 64BIT
18+
1419
endchoice
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2021 Katsuhiro Suzuki
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <init.h>
8+
#include "fu540_prci.h"
9+
10+
/*
11+
* Switch the clock source to 1GHz PLL from 33.333MHz oscilator on the HiFive
12+
* Unleashed board.
13+
*/
14+
static int fu540_clock_init(const struct device *dev)
15+
{
16+
ARG_UNUSED(dev);
17+
18+
PRCI_REG(PRCI_COREPLLCFG0) =
19+
PLL_R(0) | /* input divider: Fin / (0 + 1) = 33.33MHz */
20+
PLL_F(59) | /* VCO: 2 x (59 + 1) = 120 = 3999.6MHz */
21+
PLL_Q(2) | /* output divider: VCO / 2^2 = 999.9MHz */
22+
PLL_RANGE(PLL_RANGE_33MHZ) |
23+
PLL_BYPASS(PLL_BYPASS_DISABLE) |
24+
PLL_FSE(PLL_FSE_INTERNAL);
25+
while ((PRCI_REG(PRCI_COREPLLCFG0) & PLL_LOCK(1)) == 0)
26+
;
27+
28+
/* Switch clock to COREPLL */
29+
PRCI_REG(PRCI_CORECLKSEL) = CORECLKSEL_CORECLKSEL(CORECLKSEL_CORE_PLL);
30+
31+
return 0;
32+
}
33+
34+
SYS_INIT(fu540_clock_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2021 Katsuhiro Suzuki
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _SIFIVE_FU540_PRCI_H
8+
#define _SIFIVE_FU540_PRCI_H
9+
10+
#define Z_REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
11+
#define PRCI_REG(offset) Z_REG32(PRCI_BASE_ADDR, offset)
12+
13+
/* Register offsets */
14+
15+
#define PRCI_HFXOSCCFG (0x0000)
16+
#define PRCI_COREPLLCFG0 (0x0004)
17+
#define PRCI_DDRPLLCFG0 (0x000c)
18+
#define PRCI_DDRPLLCFG1 (0x0010)
19+
#define PRCI_GEMGXLPLLCFG0 (0x001c)
20+
#define PRCI_GEMGXLPLLCFG1 (0x0020)
21+
#define PRCI_CORECLKSEL (0x0024)
22+
#define PRCI_DEVICESRESETREG (0x0028)
23+
24+
#define PLL_R(x) (((x) & 0x3f) << 0)
25+
#define PLL_F(x) (((x) & 0x1ff) << 6)
26+
#define PLL_Q(x) (((x) & 0x7) << 15)
27+
#define PLL_RANGE(x) (((x) & 0x7) << 18)
28+
#define PLL_BYPASS(x) (((x) & 0x1) << 24)
29+
#define PLL_FSE(x) (((x) & 0x1) << 25)
30+
#define PLL_LOCK(x) (((x) & 0x1) << 31)
31+
32+
#define PLL_RANGE_33MHZ 4
33+
#define PLL_BYPASS_DISABLE 0
34+
#define PLL_BYPASS_ENABLE 1
35+
#define PLL_FSE_INTERNAL 1
36+
37+
#define CORECLKSEL_CORECLKSEL(x) (((x) & 0x1) << 0)
38+
39+
#define CORECLKSEL_CORE_PLL 0
40+
#define CORECLKSEL_HFCLK 1
41+
42+
#endif /* _SIFIVE_FU540_PRCI_H */

soc/riscv/riscv-privilege/sifive-freedom/soc.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <soc_common.h>
1515
#include <devicetree.h>
1616

17+
#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM)
18+
1719
/* PINMUX IO Hardware Functions */
1820
#define SIFIVE_PINMUX_IOF0 0x00
1921
#define SIFIVE_PINMUX_IOF1 0x01
@@ -24,10 +26,6 @@
2426
/* Clock controller. */
2527
#define PRCI_BASE_ADDR 0x10008000
2628

27-
/* Timer configuration */
28-
#define RISCV_MTIME_BASE 0x0200BFF8
29-
#define RISCV_MTIMECMP_BASE 0x02004000
30-
3129
/* Always ON Domain */
3230
#define SIFIVE_PMUIE 0x10000140
3331
#define SIFIVE_PMUCAUSE 0x10000144
@@ -37,6 +35,17 @@
3735

3836
#define SIFIVE_BACKUP_REG_BASE 0x10000080
3937

38+
#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540)
39+
40+
/* Clock controller. */
41+
#define PRCI_BASE_ADDR 0x10000000
42+
43+
#endif
44+
45+
/* Timer configuration */
46+
#define RISCV_MTIME_BASE 0x0200BFF8
47+
#define RISCV_MTIMECMP_BASE 0x02004000
48+
4049
/* lib-c hooks required RAM defined variables */
4150
#define RISCV_RAM_BASE CONFIG_SRAM_BASE_ADDRESS
4251
#define RISCV_RAM_SIZE KB(CONFIG_SRAM_SIZE)

0 commit comments

Comments
 (0)