Skip to content

Commit ca853af

Browse files
katsustercfriedt
authored andcommitted
soc: riscv: add initial support for SiFive Freedom U740
This patch adds support for SiFive Freedom U740 SoC. First version is minimum only using UART, SPI and L2-LIM area. Signed-off-by: Katsuhiro Suzuki <[email protected]>
1 parent ae355cc commit ca853af

File tree

6 files changed

+276
-1
lines changed

6 files changed

+276
-1
lines changed

dts/riscv/riscv64-fu740.dtsi

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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,FU740-C000", "fu740-dev", "sifive-dev";
13+
model = "sifive,FU740";
14+
15+
cpus {
16+
#address-cells = <1>;
17+
#size-cells = <0>;
18+
19+
cpu: cpu@0 {
20+
compatible = "sifive,s7", "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+
clint: clint@2000000 {
59+
#interrupt-cells = <1>;
60+
compatible = "riscv,clint0";
61+
interrupt-controller;
62+
interrupts-extended = <&hlic 3 &hlic 7>;
63+
reg = <0x2000000 0x10000>;
64+
reg-names = "control";
65+
};
66+
67+
l2lim: l2lim@8000000 {
68+
compatible = "sifive,l2lim0";
69+
reg = <0x8000000 0x200000>;
70+
reg-names = "mem";
71+
};
72+
73+
74+
plic: interrupt-controller@c000000 {
75+
#interrupt-cells = <2>;
76+
compatible = "sifive,plic-1.0.0";
77+
interrupt-controller;
78+
interrupts-extended = <&hlic 11>;
79+
reg = <0x0c000000 0x00002000
80+
0x0c002000 0x001fe000
81+
0x0c200000 0x03e00000>;
82+
reg-names = "prio", "irq_en", "reg";
83+
riscv,max-priority = <7>;
84+
riscv,ndev = <52>;
85+
};
86+
87+
uart0: serial@10010000 {
88+
compatible = "sifive,uart0";
89+
interrupt-parent = <&plic>;
90+
interrupts = <4 1>;
91+
reg = <0x10010000 0x1000>;
92+
reg-names = "control";
93+
label = "uart_0";
94+
status = "disabled";
95+
};
96+
97+
uart1: serial@10011000 {
98+
compatible = "sifive,uart0";
99+
interrupt-parent = <&plic>;
100+
interrupts = <5 1>;
101+
reg = <0x10011000 0x1000>;
102+
reg-names = "control";
103+
label = "uart_1";
104+
status = "disabled";
105+
};
106+
107+
spi0: spi@10040000 {
108+
compatible = "sifive,spi0";
109+
interrupt-parent = <&plic>;
110+
interrupts = <51 1>;
111+
reg = <0x10040000 0x1000 0x20000000 0x10000000>;
112+
reg-names = "control", "mem";
113+
label = "spi_0";
114+
status = "disabled";
115+
#address-cells = <1>;
116+
#size-cells = <0>;
117+
};
118+
119+
spi1: spi@10041000 {
120+
compatible = "sifive,spi0";
121+
interrupt-parent = <&plic>;
122+
interrupts = <52 1>;
123+
reg = <0x10041000 0x1000>;
124+
reg-names = "control";
125+
label = "spi_1";
126+
status = "disabled";
127+
#address-cells = <1>;
128+
#size-cells = <0>;
129+
};
130+
131+
spi2: spi@10050000 {
132+
compatible = "sifive,spi0";
133+
interrupt-parent = <&plic>;
134+
interrupts = <6 1>;
135+
reg = <0x10050000 0x1000>;
136+
reg-names = "control";
137+
label = "spi_2";
138+
status = "disabled";
139+
#address-cells = <1>;
140+
#size-cells = <0>;
141+
};
142+
};
143+
};

soc/riscv/riscv-privilege/sifive-freedom/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
zephyr_sources()
44
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FREEDOM fe310_clock.c)
55
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU540 fu540_clock.c)
6+
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU740 fu740_clock.c)

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

+5
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@ config SOC_RISCV_SIFIVE_FU540
1616
select ATOMIC_OPERATIONS_C
1717
select 64BIT
1818

19+
config SOC_RISCV_SIFIVE_FU740
20+
bool "SiFive Freedom U740 SOC implementation"
21+
select ATOMIC_OPERATIONS_C
22+
select 64BIT
23+
1924
endchoice
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2021 Katsuhiro Suzuki
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <init.h>
8+
#include "fu740_prci.h"
9+
10+
/*
11+
* Switch the clock source
12+
* - core: to 1GHz PLL (CORE_PLL) from 26MHz oscilator (HFCLK)
13+
* - peri: to 250MHz PLL (HFPCLKPLL) from HFCLK
14+
* on the HiFive Unmatched board.
15+
*
16+
* Note: Valid PLL VCO range is 2400MHz to 4800MHz
17+
*/
18+
static int fu740_clock_init(const struct device *dev)
19+
{
20+
ARG_UNUSED(dev);
21+
22+
PRCI_REG(PRCI_COREPLLCFG) =
23+
PLL_R(0) | /* input divider: Fin / (0 + 1) = 26MHz */
24+
PLL_F(76) | /* VCO: 2 x (76 + 1) = 154 = 4004MHz */
25+
PLL_Q(2) | /* output divider: VCO / 2^2 = 1001MHz */
26+
PLL_RANGE(PLL_RANGE_18MHZ) | /* 18MHz <= post divr(= 26MHz) < 30MHz */
27+
PLL_BYPASS(PLL_BYPASS_DISABLE) |
28+
PLL_FSE(PLL_FSE_INTERNAL);
29+
while ((PRCI_REG(PRCI_COREPLLCFG) & PLL_LOCK(1)) == 0)
30+
;
31+
32+
/* Switch CORE_CLK to CORE_PLL from HFCLK */
33+
PRCI_REG(PRCI_COREPLLSEL) = COREPLLSEL_SEL(COREPLLSEL_COREPLL);
34+
PRCI_REG(PRCI_CORECLKSEL) = CLKSEL_SEL(CLKSEL_PLL);
35+
36+
PRCI_REG(PRCI_HFPCLKPLLCFG) =
37+
PLL_R(0) | /* input divider: Fin / (0 + 1) = 26MHz */
38+
PLL_F(76) | /* VCO: 2 x (76 + 1) = 154 = 4004MHz */
39+
PLL_Q(4) | /* output divider: VCO / 2^4 = 250.25MHz */
40+
PLL_RANGE(PLL_RANGE_18MHZ) | /* 18MHz <= post divr(= 26MHz) < 30MHz */
41+
PLL_BYPASS(PLL_BYPASS_DISABLE) |
42+
PLL_FSE(PLL_FSE_INTERNAL);
43+
while ((PRCI_REG(PRCI_HFPCLKPLLCFG) & PLL_LOCK(1)) == 0)
44+
;
45+
46+
/* Switch PCLK to HFPCLKPLL/2 from HFCLK/2 */
47+
PRCI_REG(PRCI_HFPCLKPLLOUTDIV) = OUTDIV_PLLCKE(OUTDIV_PLLCKE_ENA);
48+
PRCI_REG(PRCI_HFPCLKPLLSEL) = CLKSEL_SEL(CLKSEL_PLL);
49+
50+
return 0;
51+
}
52+
53+
SYS_INIT(fu740_clock_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2021 Katsuhiro Suzuki
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _SIFIVE_FU740_PRCI_H
8+
#define _SIFIVE_FU740_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_COREPLLCFG (0x0004)
17+
#define PRCI_COREPLLOUTDIV (0x0008)
18+
#define PRCI_DDRPLLCFG (0x000c)
19+
#define PRCI_DDRPLLOUTDIV (0x0010)
20+
#define PRCI_GEMGXLPLLCFG (0x001c)
21+
#define PRCI_GEMGXLPLLOUTDIV (0x0020)
22+
#define PRCI_CORECLKSEL (0x0024)
23+
#define PRCI_DEVICESRESETN (0x0028)
24+
#define PRCI_CLKMUXSTATUS (0x002c)
25+
#define PRCI_COREPLLSEL (0x0040)
26+
#define PRCI_HFPCLKPLLCFG (0x0050)
27+
#define PRCI_HFPCLKPLLOUTDIV (0x0054)
28+
#define PRCI_HFPCLKPLLSEL (0x0058)
29+
30+
#define PLL_R(x) (((x) & 0x3f) << 0)
31+
#define PLL_F(x) (((x) & 0x1ff) << 6)
32+
#define PLL_Q(x) (((x) & 0x7) << 15)
33+
#define PLL_RANGE(x) (((x) & 0x7) << 18)
34+
#define PLL_BYPASS(x) (((x) & 0x1) << 24)
35+
#define PLL_FSE(x) (((x) & 0x1) << 25)
36+
#define PLL_LOCK(x) (((x) & 0x1) << 31)
37+
38+
#define PLL_RANGE_RESET 0
39+
#define PLL_RANGE_0MHZ 1
40+
#define PLL_RANGE_11MHZ 2
41+
#define PLL_RANGE_18MHZ 3
42+
#define PLL_RANGE_30MHZ 4
43+
#define PLL_RANGE_50MHZ 5
44+
#define PLL_RANGE_80MHZ 6
45+
#define PLL_RANGE_130MHZ 7
46+
#define PLL_BYPASS_DISABLE 0
47+
#define PLL_BYPASS_ENABLE 1
48+
#define PLL_FSE_INTERNAL 1
49+
50+
#define OUTDIV_PLLCKE(x) (((x) & 0x1) << 31)
51+
52+
#define OUTDIV_PLLCKE_DIS 0
53+
#define OUTDIV_PLLCKE_ENA 1
54+
55+
#define CLKSEL_SEL(x) (((x) & 0x1) << 0)
56+
57+
#define CLKSEL_PLL 0
58+
#define CLKSEL_HFCLK 1
59+
60+
#define CLKMUXSTATUS_CORECLKPLLSEL_OFF 0
61+
#define CLKMUXSTATUS_TLCLKSEL_OFF 1
62+
#define CLKMUXSTATUS_RTCXSEL_OFF 2
63+
#define CLKMUXSTATUS_DDRCTRLCLKSEL_OFF 3
64+
#define CLKMUXSTATUS_DDRPHYCLKSEL_OFF 4
65+
#define CLKMUXSTATUS_GEMGXLCLKSEL_OFF 6
66+
#define CLKMUXSTATUS_MAINMEMCLKSEL_OFF 7
67+
68+
#define COREPLLSEL_SEL(x) (((x) & 0x1) << 0)
69+
70+
#define COREPLLSEL_COREPLL 0
71+
#define COREPLLSEL_DVFSCOREPLL 1
72+
73+
#endif /* _SIFIVE_FU740_PRCI_H */

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
#define SIFIVE_BACKUP_REG_BASE 0x10000080
3737

38-
#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540)
38+
#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540) || defined(CONFIG_SOC_RISCV_SIFIVE_FU740)
3939

4040
/* Clock controller. */
4141
#define PRCI_BASE_ADDR 0x10000000

0 commit comments

Comments
 (0)