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
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
zephyr_sources()
|
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"
|
bool "SiFive Freedom SOC implementation"
|
||||||
select ATOMIC_OPERATIONS_C
|
select ATOMIC_OPERATIONS_C
|
||||||
|
|
||||||
|
config SOC_RISCV_SIFIVE_FU540
|
||||||
|
bool "SiFive Freedom U540 SOC implementation"
|
||||||
|
select ATOMIC_OPERATIONS_C
|
||||||
|
select 64BIT
|
||||||
|
|
||||||
endchoice
|
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 <soc_common.h>
|
||||||
#include <devicetree.h>
|
#include <devicetree.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM)
|
||||||
|
|
||||||
/* PINMUX IO Hardware Functions */
|
/* PINMUX IO Hardware Functions */
|
||||||
#define SIFIVE_PINMUX_IOF0 0x00
|
#define SIFIVE_PINMUX_IOF0 0x00
|
||||||
#define SIFIVE_PINMUX_IOF1 0x01
|
#define SIFIVE_PINMUX_IOF1 0x01
|
||||||
|
@ -24,10 +26,6 @@
|
||||||
/* Clock controller. */
|
/* Clock controller. */
|
||||||
#define PRCI_BASE_ADDR 0x10008000
|
#define PRCI_BASE_ADDR 0x10008000
|
||||||
|
|
||||||
/* Timer configuration */
|
|
||||||
#define RISCV_MTIME_BASE 0x0200BFF8
|
|
||||||
#define RISCV_MTIMECMP_BASE 0x02004000
|
|
||||||
|
|
||||||
/* Always ON Domain */
|
/* Always ON Domain */
|
||||||
#define SIFIVE_PMUIE 0x10000140
|
#define SIFIVE_PMUIE 0x10000140
|
||||||
#define SIFIVE_PMUCAUSE 0x10000144
|
#define SIFIVE_PMUCAUSE 0x10000144
|
||||||
|
@ -37,6 +35,17 @@
|
||||||
|
|
||||||
#define SIFIVE_BACKUP_REG_BASE 0x10000080
|
#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 */
|
/* lib-c hooks required RAM defined variables */
|
||||||
#define RISCV_RAM_BASE CONFIG_SRAM_BASE_ADDRESS
|
#define RISCV_RAM_BASE CONFIG_SRAM_BASE_ADDRESS
|
||||||
#define RISCV_RAM_SIZE KB(CONFIG_SRAM_SIZE)
|
#define RISCV_RAM_SIZE KB(CONFIG_SRAM_SIZE)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue