From c74526919d7ccb9c571699a87fe146d102a10899 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Thu, 31 Mar 2022 10:51:54 -0700 Subject: [PATCH] soc: riscv: sifive-freedom: Get coreclk and peripheral clock from DTS. Rather than specify input clock for each peripheral individually, instead specify the relevant clocks in DTS. This will enable easier support for non-default coreclk on fe310 in a follow-up CL. Signed-off-by: Shawn Nematbakhsh --- boards/riscv/hifive1/hifive1.dts | 11 ---------- boards/riscv/hifive1_revb/hifive1_revb.dts | 9 -------- .../hifive_unleashed/hifive_unleashed.dts | 4 ---- .../hifive_unmatched/hifive_unmatched.dts | 4 ---- .../riscv/qemu_riscv32/qemu_riscv32_xip.dts | 5 ----- drivers/i2c/i2c_sifive.c | 3 ++- drivers/pwm/pwm_sifive.c | 3 ++- drivers/serial/uart_sifive.c | 5 +++-- drivers/spi/spi_sifive.c | 3 ++- dts/bindings/i2c/sifive,i2c0.yaml | 5 ----- dts/bindings/pwm/sifive,pwm0.yaml | 5 ----- dts/riscv/riscv32-fe310.dtsi | 15 +++++++++++++ dts/riscv/riscv64-fu540.dtsi | 16 ++++++++++++++ dts/riscv/riscv64-fu740.dtsi | 15 +++++++++++++ .../sifive-freedom/fe310_clock.c | 5 +++++ .../sifive-freedom/fu540_clock.c | 5 +++++ .../sifive-freedom/fu740_clock.c | 5 +++++ .../riscv-privilege/sifive-freedom/soc.h | 22 ++++++++++++++++++- 18 files changed, 91 insertions(+), 49 deletions(-) diff --git a/boards/riscv/hifive1/hifive1.dts b/boards/riscv/hifive1/hifive1.dts index a8bec8a6a12..9720b769917 100644 --- a/boards/riscv/hifive1/hifive1.dts +++ b/boards/riscv/hifive1/hifive1.dts @@ -46,18 +46,12 @@ &uart0 { status = "okay"; current-speed = <115200>; - clock-frequency = <16000000>; pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; pinctrl-names = "default"; }; -&uart1 { - clock-frequency = <16000000>; -}; - &spi0 { status = "okay"; - clock-frequency = <16000000>; reg = <0x10014000 0x1000 0x20400000 0xc00000>; flash0: flash@0 { @@ -72,7 +66,6 @@ &spi1 { status = "okay"; - clock-frequency = <16000000>; pinctrl-0 = <&spi1_cs0_default &spi1_cs2_default &spi1_cs3_default &spi1_mosi_default &spi1_miso_default &spi1_sck_default>; pinctrl-names = "default"; @@ -80,24 +73,20 @@ &spi2 { status = "okay"; - clock-frequency = <16000000>; }; &pwm0 { status = "okay"; - clock-frequency = <16000000>; }; &pwm1 { status = "okay"; - clock-frequency = <16000000>; pinctrl-0 = <&pwm1_1_default &pwm1_2_default &pwm1_3_default>; pinctrl-names = "default"; }; &pwm2 { status = "okay"; - clock-frequency = <16000000>; pinctrl-0 = <&pwm2_1_default &pwm2_2_default &pwm2_3_default>; pinctrl-names = "default"; }; diff --git a/boards/riscv/hifive1_revb/hifive1_revb.dts b/boards/riscv/hifive1_revb/hifive1_revb.dts index fc76f5936bd..b7830fed2c6 100644 --- a/boards/riscv/hifive1_revb/hifive1_revb.dts +++ b/boards/riscv/hifive1_revb/hifive1_revb.dts @@ -78,7 +78,6 @@ &uart0 { status = "okay"; current-speed = <115200>; - clock-frequency = <16000000>; pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; pinctrl-names = "default"; }; @@ -86,12 +85,10 @@ &uart1 { status = "okay"; current-speed = <115200>; - clock-frequency = <16000000>; }; &spi0 { status = "okay"; - clock-frequency = <16000000>; reg = <0x10014000 0x1000 0x20010000 0x3c0900>; flash0: flash@0 { @@ -106,33 +103,27 @@ &spi1 { status = "okay"; - clock-frequency = <16000000>; }; &spi2 { status = "okay"; - clock-frequency = <16000000>; }; &pwm0 { status = "okay"; - clock-frequency = <16000000>; }; &pwm1 { status = "okay"; - clock-frequency = <16000000>; }; &pwm2 { status = "okay"; - clock-frequency = <16000000>; }; arduino_i2c: &i2c0 { status = "okay"; label = "I2C_0"; - input-frequency = <16000000>; clock-frequency = <100000>; pinctrl-0 = <&i2c0_0_default &i2c0_1_default>; pinctrl-names = "default"; diff --git a/boards/riscv/hifive_unleashed/hifive_unleashed.dts b/boards/riscv/hifive_unleashed/hifive_unleashed.dts index 742c9ad3de3..c046d564ce6 100644 --- a/boards/riscv/hifive_unleashed/hifive_unleashed.dts +++ b/boards/riscv/hifive_unleashed/hifive_unleashed.dts @@ -44,12 +44,10 @@ &uart0 { status = "okay"; current-speed = <115200>; - clock-frequency = <500000000>; }; &spi0 { status = "okay"; - clock-frequency = <500000000>; reg = <0x10040000 0x1000 0x20000000 0x2000000>; flash0: flash@0 { @@ -64,12 +62,10 @@ &spi1 { status = "okay"; - clock-frequency = <500000000>; }; &spi2 { status = "okay"; - clock-frequency = <500000000>; }; &gpio0 { diff --git a/boards/riscv/hifive_unmatched/hifive_unmatched.dts b/boards/riscv/hifive_unmatched/hifive_unmatched.dts index 5226704400b..5ab330a1e42 100644 --- a/boards/riscv/hifive_unmatched/hifive_unmatched.dts +++ b/boards/riscv/hifive_unmatched/hifive_unmatched.dts @@ -25,12 +25,10 @@ &uart0 { status = "okay"; current-speed = <115200>; - clock-frequency = <125125000>; }; &spi0 { status = "okay"; - clock-frequency = <125125000>; reg = <0x10040000 0x1000 0x20000000 0x2000000>; flash0: flash@0 { @@ -45,10 +43,8 @@ &spi1 { status = "okay"; - clock-frequency = <125125000>; }; &spi2 { status = "okay"; - clock-frequency = <125125000>; }; diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_xip.dts b/boards/riscv/qemu_riscv32/qemu_riscv32_xip.dts index deb04e19ae3..50dd06c8129 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_xip.dts +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_xip.dts @@ -29,15 +29,10 @@ &uart0 { status = "okay"; current-speed = <115200>; - clock-frequency = <16000000>; pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; pinctrl-names = "default"; }; -&uart1 { - clock-frequency = <16000000>; -}; - &spi0 { status = "okay"; diff --git a/drivers/i2c/i2c_sifive.c b/drivers/i2c/i2c_sifive.c index fa8e225a73d..6bce780650e 100644 --- a/drivers/i2c/i2c_sifive.c +++ b/drivers/i2c/i2c_sifive.c @@ -12,6 +12,7 @@ LOG_MODULE_REGISTER(i2c_sifive); #include #include +#include #include #include "i2c-priv.h" @@ -326,7 +327,7 @@ static struct i2c_driver_api i2c_sifive_api = { #define I2C_SIFIVE_INIT(n) \ static struct i2c_sifive_cfg i2c_sifive_cfg_##n = { \ .base = DT_INST_REG_ADDR(n), \ - .f_sys = DT_INST_PROP(n, input_frequency), \ + .f_sys = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, \ .f_bus = DT_INST_PROP(n, clock_frequency), \ }; \ I2C_DEVICE_DT_INST_DEFINE(n, \ diff --git a/drivers/pwm/pwm_sifive.c b/drivers/pwm/pwm_sifive.c index 73a02ae2fcc..8a49a89c868 100644 --- a/drivers/pwm/pwm_sifive.c +++ b/drivers/pwm/pwm_sifive.c @@ -14,6 +14,7 @@ LOG_MODULE_REGISTER(pwm_sifive, CONFIG_PWM_LOG_LEVEL); #include #include #include +#include /* Macros */ @@ -237,7 +238,7 @@ static const struct pwm_driver_api pwm_sifive_api = { static struct pwm_sifive_data pwm_sifive_data_##n; \ static const struct pwm_sifive_cfg pwm_sifive_cfg_##n = { \ .base = DT_INST_REG_ADDR(n), \ - .f_sys = DT_INST_PROP(n, clock_frequency), \ + .f_sys = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, \ .cmpwidth = DT_INST_PROP(n, sifive_compare_width), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; \ diff --git a/drivers/serial/uart_sifive.c b/drivers/serial/uart_sifive.c index cf18cbef0b2..925f192bf87 100644 --- a/drivers/serial/uart_sifive.c +++ b/drivers/serial/uart_sifive.c @@ -14,6 +14,7 @@ #include #include #include +#include #define RXDATA_EMPTY (1 << 31) /* Receive FIFO Empty */ #define RXDATA_MASK 0xFF /* Receive Data Mask */ @@ -383,7 +384,7 @@ PINCTRL_DT_INST_DEFINE(0); static const struct uart_sifive_device_config uart_sifive_dev_cfg_0 = { .port = DT_INST_REG_ADDR(0), - .sys_clk_freq = DT_INST_PROP(0, clock_frequency), + .sys_clk_freq = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, .baud_rate = DT_INST_PROP(0, current_speed), .rxcnt_irq = CONFIG_UART_SIFIVE_PORT_0_RXCNT_IRQ, .txcnt_irq = CONFIG_UART_SIFIVE_PORT_0_TXCNT_IRQ, @@ -426,7 +427,7 @@ PINCTRL_DT_INST_DEFINE(1); static const struct uart_sifive_device_config uart_sifive_dev_cfg_1 = { .port = DT_INST_REG_ADDR(1), - .sys_clk_freq = DT_INST_PROP(1, clock_frequency), + .sys_clk_freq = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, .baud_rate = DT_INST_PROP(1, current_speed), .rxcnt_irq = CONFIG_UART_SIFIVE_PORT_1_RXCNT_IRQ, .txcnt_irq = CONFIG_UART_SIFIVE_PORT_1_TXCNT_IRQ, diff --git a/drivers/spi/spi_sifive.c b/drivers/spi/spi_sifive.c index fc42a4648d0..5e960878b53 100644 --- a/drivers/spi/spi_sifive.c +++ b/drivers/spi/spi_sifive.c @@ -12,6 +12,7 @@ LOG_MODULE_REGISTER(spi_sifive); #include "spi_sifive.h" +#include #include /* Helper Functions */ @@ -270,7 +271,7 @@ static struct spi_driver_api spi_sifive_api = { }; \ static struct spi_sifive_cfg spi_sifive_cfg_##n = { \ .base = DT_INST_REG_ADDR_BY_NAME(n, control), \ - .f_sys = DT_INST_PROP(n, clock_frequency), \ + .f_sys = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; \ DEVICE_DT_INST_DEFINE(n, \ diff --git a/dts/bindings/i2c/sifive,i2c0.yaml b/dts/bindings/i2c/sifive,i2c0.yaml index 5f74df571e4..ab0b1102149 100644 --- a/dts/bindings/i2c/sifive,i2c0.yaml +++ b/dts/bindings/i2c/sifive,i2c0.yaml @@ -8,10 +8,5 @@ compatible: "sifive,i2c0" include: i2c-controller.yaml properties: - input-frequency: - type: int - required: false - description: Frequency of the peripheral input clock. - reg: required: true diff --git a/dts/bindings/pwm/sifive,pwm0.yaml b/dts/bindings/pwm/sifive,pwm0.yaml index f2652cafa6b..126d7e95d6d 100644 --- a/dts/bindings/pwm/sifive,pwm0.yaml +++ b/dts/bindings/pwm/sifive,pwm0.yaml @@ -8,11 +8,6 @@ compatible: "sifive,pwm0" include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] properties: - clock-frequency: - type: int - required: false - description: Clock frequency information for PWM operation - reg: required: true diff --git a/dts/riscv/riscv32-fe310.dtsi b/dts/riscv/riscv32-fe310.dtsi index 536e5c2187b..13468b671df 100644 --- a/dts/riscv/riscv32-fe310.dtsi +++ b/dts/riscv/riscv32-fe310.dtsi @@ -1,12 +1,27 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include +#include / { #address-cells = <1>; #size-cells = <1>; compatible = "sifive,FE310G-0002-Z0-dev", "fe310-dev", "sifive-dev"; model = "SiFive,FE310G-0002-Z0"; + clocks { + coreclk: core-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + + tlclk: tl-clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&coreclk>; + clock-div = <1>; + }; + }; cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/riscv/riscv64-fu540.dtsi b/dts/riscv/riscv64-fu540.dtsi index 1fafe57e912..fe6337b411d 100644 --- a/dts/riscv/riscv64-fu540.dtsi +++ b/dts/riscv/riscv64-fu540.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { #address-cells = <1>; @@ -12,6 +13,21 @@ compatible = "sifive,FU540-C000", "fu540-dev", "sifive-dev"; model = "sifive,FU540"; + clocks { + coreclk: core-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + + tlclk: tl-clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&coreclk>; + clock-div = <2>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/riscv/riscv64-fu740.dtsi b/dts/riscv/riscv64-fu740.dtsi index 9880ad42f4b..4a45bc071cd 100644 --- a/dts/riscv/riscv64-fu740.dtsi +++ b/dts/riscv/riscv64-fu740.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { #address-cells = <1>; @@ -12,6 +13,20 @@ compatible = "sifive,FU740-C000", "fu740-dev", "sifive-dev"; model = "sifive,FU740"; + clocks { + coreclk: core-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + + pclk: p-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/soc/riscv/riscv-privilege/sifive-freedom/fe310_clock.c b/soc/riscv/riscv-privilege/sifive-freedom/fe310_clock.c index ded7e2eabfb..837643f5c3c 100644 --- a/soc/riscv/riscv-privilege/sifive-freedom/fe310_clock.c +++ b/soc/riscv/riscv-privilege/sifive-freedom/fe310_clock.c @@ -8,6 +8,11 @@ #include #include "fe310_prci.h" +BUILD_ASSERT(MHZ(16) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), + "Unsupported CORECLK frequency"); +BUILD_ASSERT(DT_PROP(DT_NODELABEL(tlclk), clock_div) == 1, + "Unsupported TLCLK divider"); + /* Selects the 16MHz oscillator on the HiFive1 board, which provides a clock * that's accurate enough to actually drive serial ports off of. */ diff --git a/soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c b/soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c index d0ac9e30e82..c3826ab043a 100644 --- a/soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c +++ b/soc/riscv/riscv-privilege/sifive-freedom/fu540_clock.c @@ -7,6 +7,11 @@ #include #include "fu540_prci.h" +BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), + "Unsupported CORECLK frequency"); +BUILD_ASSERT(DT_PROP(DT_NODELABEL(tlclk), clock_div) == 2, + "Unsupported TLCLK divider"); + /* * Switch the clock source to 1GHz PLL from 33.333MHz oscillator on the HiFive * Unleashed board. diff --git a/soc/riscv/riscv-privilege/sifive-freedom/fu740_clock.c b/soc/riscv/riscv-privilege/sifive-freedom/fu740_clock.c index cff655430c9..5fa99460407 100644 --- a/soc/riscv/riscv-privilege/sifive-freedom/fu740_clock.c +++ b/soc/riscv/riscv-privilege/sifive-freedom/fu740_clock.c @@ -7,6 +7,11 @@ #include #include "fu740_prci.h" +BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), + "Unsupported CORECLK frequency"); +BUILD_ASSERT(KHZ(125125) == DT_PROP(DT_NODELABEL(pclk), clock_frequency), + "Unsupported PCLK frequency"); + /* * Switch the clock source * - core: to 1GHz PLL (CORE_PLL) from 26MHz oscillator (HFCLK) diff --git a/soc/riscv/riscv-privilege/sifive-freedom/soc.h b/soc/riscv/riscv-privilege/sifive-freedom/soc.h index 52078ef5c35..12376182134 100644 --- a/soc/riscv/riscv-privilege/sifive-freedom/soc.h +++ b/soc/riscv/riscv-privilege/sifive-freedom/soc.h @@ -23,7 +23,7 @@ #define SIFIVE_PINMUX_PINS 32 /* Clock controller. */ -#define PRCI_BASE_ADDR 0x10008000 +#define PRCI_BASE_ADDR 0x10008000 /* Always ON Domain */ #define SIFIVE_PMUIE 0x10000140 @@ -44,6 +44,26 @@ #endif +#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM) || defined(CONFIG_SOC_RISCV_SIFIVE_FU540) + +/* + * On FE310 and FU540, peripherals such as SPI, UART, I2C and PWM are clocked + * by TLCLK, which is derived from CORECLK. + */ +#define SIFIVE_TLCLK_BASE_FREQUENCY \ + DT_PROP_BY_PHANDLE_IDX(DT_NODELABEL(tlclk), clocks, 0, clock_frequency) +#define SIFIVE_TLCLK_DIVIDER DT_PROP(DT_NODELABEL(tlclk), clock_div) +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + (SIFIVE_TLCLK_BASE_FREQUENCY / SIFIVE_TLCLK_DIVIDER) + +#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU740) + +/* On FU740, peripherals are clocked by PCLK. */ +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + DT_PROP(DT_NODELABEL(pclk), clock_frequency) + +#endif + /* Timer configuration */ #define RISCV_MTIME_BASE 0x0200BFF8 #define RISCV_MTIMECMP_BASE 0x02004000