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 <katsuhiro@katsuster.net>
This commit is contained in:
parent
763428d5a4
commit
82f75ed337
6 changed files with 268 additions and 5 deletions
172
dts/riscv/riscv64-fu540.dtsi
Normal file
172
dts/riscv/riscv64-fu540.dtsi
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Katsuhiro Suzuki
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "sifive,FU540-C000", "fu540-dev", "sifive-dev";
|
||||
model = "sifive,FU540";
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu: cpu@0 {
|
||||
compatible = "sifive,e51", "riscv";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imac";
|
||||
status = "okay";
|
||||
|
||||
hlic: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
modeselect: rom@1000 {
|
||||
compatible = "sifive,modeselect0";
|
||||
reg = <0x1000 0x1000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
maskrom: rom@10000 {
|
||||
compatible = "sifive,maskrom0";
|
||||
reg = <0x10000 0x8000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
dtim: dtim@1000000 {
|
||||
compatible = "sifive,dtim0";
|
||||
reg = <0x1000000 0x2000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
itim0: itim0@1800000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x1800000 0x2000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
itim1: itim1@1808000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x1808000 0x7000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
itim2: itim2@1810000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x1810000 0x7000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
itim3: itim3@1818000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x1818000 0x7000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
itim4: itim4@1820000 {
|
||||
compatible = "sifive,itim0";
|
||||
reg = <0x1820000 0x7000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
clint: clint@2000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,clint0";
|
||||
interrupt-controller;
|
||||
interrupts-extended = <&hlic 3 &hlic 7>;
|
||||
reg = <0x2000000 0x10000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
|
||||
l2lim: l2lim@8000000 {
|
||||
compatible = "sifive,l2lim0";
|
||||
reg = <0x8000000 0x2000000>;
|
||||
reg-names = "mem";
|
||||
};
|
||||
|
||||
plic: interrupt-controller@c000000 {
|
||||
#interrupt-cells = <2>;
|
||||
compatible = "sifive,plic-1.0.0";
|
||||
interrupt-controller;
|
||||
interrupts-extended = <&hlic 11>;
|
||||
reg = <0x0c000000 0x00002000
|
||||
0x0c002000 0x001fe000
|
||||
0x0c200000 0x03e00000>;
|
||||
reg-names = "prio", "irq_en", "reg";
|
||||
riscv,max-priority = <7>;
|
||||
riscv,ndev = <52>;
|
||||
};
|
||||
|
||||
uart0: serial@10010000 {
|
||||
compatible = "sifive,uart0";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <4 1>;
|
||||
reg = <0x10010000 0x1000>;
|
||||
reg-names = "control";
|
||||
label = "uart_0";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart1: serial@10011000 {
|
||||
compatible = "sifive,uart0";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <5 1>;
|
||||
reg = <0x10011000 0x1000>;
|
||||
reg-names = "control";
|
||||
label = "uart_1";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi0: spi@10040000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <51 1>;
|
||||
reg = <0x10040000 0x1000 0x20000000 0x10000000>;
|
||||
reg-names = "control", "mem";
|
||||
label = "spi_0";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
spi1: spi@10041000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <52 1>;
|
||||
reg = <0x10041000 0x1000>;
|
||||
reg-names = "control";
|
||||
label = "spi_1";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
spi2: spi@10050000 {
|
||||
compatible = "sifive,spi0";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <6 1>;
|
||||
reg = <0x10050000 0x1000>;
|
||||
reg-names = "control";
|
||||
label = "spi_2";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources()
|
||||
zephyr_sources(fe310_clock.c)
|
||||
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FREEDOM fe310_clock.c)
|
||||
zephyr_sources_ifdef(CONFIG_SOC_RISCV_SIFIVE_FU540 fu540_clock.c)
|
||||
|
|
|
@ -11,4 +11,9 @@ config SOC_RISCV_SIFIVE_FREEDOM
|
|||
bool "SiFive Freedom SOC implementation"
|
||||
select ATOMIC_OPERATIONS_C
|
||||
|
||||
config SOC_RISCV_SIFIVE_FU540
|
||||
bool "SiFive Freedom U540 SOC implementation"
|
||||
select ATOMIC_OPERATIONS_C
|
||||
select 64BIT
|
||||
|
||||
endchoice
|
||||
|
|
34
soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c
Normal file
34
soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Katsuhiro Suzuki
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <init.h>
|
||||
#include "fu540_prci.h"
|
||||
|
||||
/*
|
||||
* Switch the clock source to 1GHz PLL from 33.333MHz oscilator on the HiFive
|
||||
* Unleashed board.
|
||||
*/
|
||||
static int fu540_clock_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
PRCI_REG(PRCI_COREPLLCFG0) =
|
||||
PLL_R(0) | /* input divider: Fin / (0 + 1) = 33.33MHz */
|
||||
PLL_F(59) | /* VCO: 2 x (59 + 1) = 120 = 3999.6MHz */
|
||||
PLL_Q(2) | /* output divider: VCO / 2^2 = 999.9MHz */
|
||||
PLL_RANGE(PLL_RANGE_33MHZ) |
|
||||
PLL_BYPASS(PLL_BYPASS_DISABLE) |
|
||||
PLL_FSE(PLL_FSE_INTERNAL);
|
||||
while ((PRCI_REG(PRCI_COREPLLCFG0) & PLL_LOCK(1)) == 0)
|
||||
;
|
||||
|
||||
/* Switch clock to COREPLL */
|
||||
PRCI_REG(PRCI_CORECLKSEL) = CORECLKSEL_CORECLKSEL(CORECLKSEL_CORE_PLL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(fu540_clock_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
42
soc/riscv/riscv-privilege/sifive-freedom/fu540_prci.h
Normal file
42
soc/riscv/riscv-privilege/sifive-freedom/fu540_prci.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Katsuhiro Suzuki
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _SIFIVE_FU540_PRCI_H
|
||||
#define _SIFIVE_FU540_PRCI_H
|
||||
|
||||
#define Z_REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
|
||||
#define PRCI_REG(offset) Z_REG32(PRCI_BASE_ADDR, offset)
|
||||
|
||||
/* Register offsets */
|
||||
|
||||
#define PRCI_HFXOSCCFG (0x0000)
|
||||
#define PRCI_COREPLLCFG0 (0x0004)
|
||||
#define PRCI_DDRPLLCFG0 (0x000c)
|
||||
#define PRCI_DDRPLLCFG1 (0x0010)
|
||||
#define PRCI_GEMGXLPLLCFG0 (0x001c)
|
||||
#define PRCI_GEMGXLPLLCFG1 (0x0020)
|
||||
#define PRCI_CORECLKSEL (0x0024)
|
||||
#define PRCI_DEVICESRESETREG (0x0028)
|
||||
|
||||
#define PLL_R(x) (((x) & 0x3f) << 0)
|
||||
#define PLL_F(x) (((x) & 0x1ff) << 6)
|
||||
#define PLL_Q(x) (((x) & 0x7) << 15)
|
||||
#define PLL_RANGE(x) (((x) & 0x7) << 18)
|
||||
#define PLL_BYPASS(x) (((x) & 0x1) << 24)
|
||||
#define PLL_FSE(x) (((x) & 0x1) << 25)
|
||||
#define PLL_LOCK(x) (((x) & 0x1) << 31)
|
||||
|
||||
#define PLL_RANGE_33MHZ 4
|
||||
#define PLL_BYPASS_DISABLE 0
|
||||
#define PLL_BYPASS_ENABLE 1
|
||||
#define PLL_FSE_INTERNAL 1
|
||||
|
||||
#define CORECLKSEL_CORECLKSEL(x) (((x) & 0x1) << 0)
|
||||
|
||||
#define CORECLKSEL_CORE_PLL 0
|
||||
#define CORECLKSEL_HFCLK 1
|
||||
|
||||
#endif /* _SIFIVE_FU540_PRCI_H */
|
|
@ -14,6 +14,8 @@
|
|||
#include <soc_common.h>
|
||||
#include <devicetree.h>
|
||||
|
||||
#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM)
|
||||
|
||||
/* PINMUX IO Hardware Functions */
|
||||
#define SIFIVE_PINMUX_IOF0 0x00
|
||||
#define SIFIVE_PINMUX_IOF1 0x01
|
||||
|
@ -24,10 +26,6 @@
|
|||
/* Clock controller. */
|
||||
#define PRCI_BASE_ADDR 0x10008000
|
||||
|
||||
/* Timer configuration */
|
||||
#define RISCV_MTIME_BASE 0x0200BFF8
|
||||
#define RISCV_MTIMECMP_BASE 0x02004000
|
||||
|
||||
/* Always ON Domain */
|
||||
#define SIFIVE_PMUIE 0x10000140
|
||||
#define SIFIVE_PMUCAUSE 0x10000144
|
||||
|
@ -37,6 +35,17 @@
|
|||
|
||||
#define SIFIVE_BACKUP_REG_BASE 0x10000080
|
||||
|
||||
#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540)
|
||||
|
||||
/* Clock controller. */
|
||||
#define PRCI_BASE_ADDR 0x10000000
|
||||
|
||||
#endif
|
||||
|
||||
/* Timer configuration */
|
||||
#define RISCV_MTIME_BASE 0x0200BFF8
|
||||
#define RISCV_MTIMECMP_BASE 0x02004000
|
||||
|
||||
/* lib-c hooks required RAM defined variables */
|
||||
#define RISCV_RAM_BASE CONFIG_SRAM_BASE_ADDRESS
|
||||
#define RISCV_RAM_SIZE KB(CONFIG_SRAM_SIZE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue