[PATCH 3/3] riscv: sifive: fu540: add SPL configuration

Pragnesh Patel pragnesh.patel at sifive.com
Mon Jan 13 15:32:12 CET 2020


>-----Original Message-----
>From: Pragnesh Patel
>Sent: 06 January 2020 15:39
>To: Jagan Teki <jagan at amarulasolutions.com>
>Cc: U-Boot-Denx <u-boot at lists.denx.de>; Atish Patra
><atish.patra at wdc.com>; Alexander Graf <agraf at csgraf.de>; Boris Brezillon
><bbrezillon at kernel.org>; Rick Chen <rick at andestech.com>; Anup Patel
><Anup.Patel at wdc.com>; palmerdabbelt at google.com
>Subject: RE: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>
>>-----Original Message-----
>>From: Jagan Teki <jagan at amarulasolutions.com>
>>Sent: 02 January 2020 10:29
>>To: Pragnesh Patel <pragnesh.patel at sifive.com>
>>Cc: U-Boot-Denx <u-boot at lists.denx.de>; Palmer Dabbelt ( Sifive)
>><palmer at sifive.com>; Atish Patra <atish.patra at wdc.com>; Alexander Graf
>><agraf at csgraf.de>; Boris Brezillon <bbrezillon at kernel.org>; Rick Chen
>><rick at andestech.com>; Anup Patel <Anup.Patel at wdc.com>
>>Subject: Re: [PATCH 3/3] riscv: sifive: fu540: add SPL configuration
>>
>>+ Rick, Anup
>>
>>Thanks for the patch, scratching my head to get SPL running on this board.
>>
>>On Tue, Dec 31, 2019 at 7:30 PM Pragnesh Patel
>><pragnesh.patel at sifive.com> wrote:
>>>
>>> This patch provides sifive_fu540_spl_defconfig which can support
>>> U-boot SPL to boot from L2 LIM (0x0800_0000) and then boot FIT
>>> image including OpenSBI FW_DYNAMIC firmware and U-Boot proper
>>> images from MMC boot devices.
>>>
>>> With sifive_fu540_spl_defconfig:
>>>
>>> U-Boot SPL will be loaded by ZSBL from SD card (replace fsbl.bin with
>>> u-boot-spl.bin) and runs in L2 LIM in machine mode and then load FIT
>>> image u-boot.itb from SD card (replace fw_payload.bin with u-boot.itb)
>>> into RAM.
>>>
>>> SPL related code is leverage from FSBL
>>> (https://github.com/sifive/freedom-u540-c000-bootloader.git)
>>>
>>> Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com>
>>> ---
>>>  arch/riscv/cpu/u-boot-spl.lds                 |    1 +
>>>  arch/riscv/dts/fu540-c000-u-boot.dtsi         |   65 +
>>>  .../dts/hifive-unleashed-a00-u-boot.dtsi      |   24 +
>>>  arch/riscv/include/asm/csr.h                  |    2 +
>>>  board/sifive/fu540/Kconfig                    |    8 +
>>>  board/sifive/fu540/MAINTAINERS                |    1 +
>>>  board/sifive/fu540/Makefile                   |    6 +
>>>  board/sifive/fu540/ememoryotp.c               |  143 ++
>>>  board/sifive/fu540/fu540.c                    |   31 +-
>>>  board/sifive/fu540/include/ccache.h           |   47 +
>>>  board/sifive/fu540/include/clkutils.h         |   75 +
>>>  board/sifive/fu540/include/ddrregs.h          |  622 +++++++++
>>>  board/sifive/fu540/include/ememoryotp.h       |   24 +
>>>  board/sifive/fu540/include/fu540-memory-map.h |  427 ++++++
>>>  board/sifive/fu540/include/i2c.h              |   49 +
>>>  board/sifive/fu540/include/regconfig-ctl.h    |  274 ++++
>>>  board/sifive/fu540/include/regconfig-phy.h    | 1224 +++++++++++++++++
>>>  board/sifive/fu540/include/spi.h              |  233 ++++
>>>  board/sifive/fu540/include/uart.h             |   54 +
>>>  board/sifive/fu540/include/ux00ddr.h          |  268 ++++
>>>  board/sifive/fu540/include/ux00prci.h         |  206 +++
>>>  board/sifive/fu540/spl.c                      |  321 +++++
>>>  board/sifive/fu540/uart.c                     |   64 +
>>>  configs/sifive_fu540_spl_defconfig            |   23 +
>>>  include/configs/sifive-fu540.h                |   17 +
>>>  lib/Makefile                                  |    1 +
>>
>>This patch need to divide into multiple patches since it has multiple
>>functionalities all in one which indeed difficult for review and not
>>good to go for merging.
>
>Will spilt this into multiple patches in v2. Thanks for the suggestion.
>
>>
>>>  26 files changed, 4209 insertions(+), 1 deletion(-)
>>>  create mode 100644 arch/riscv/dts/fu540-c000-u-boot.dtsi
>>>  create mode 100644 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>>  create mode 100644 board/sifive/fu540/ememoryotp.c
>>>  create mode 100644 board/sifive/fu540/include/ccache.h
>>>  create mode 100644 board/sifive/fu540/include/clkutils.h
>>>  create mode 100644 board/sifive/fu540/include/ddrregs.h
>>>  create mode 100644 board/sifive/fu540/include/ememoryotp.h
>>>  create mode 100644 board/sifive/fu540/include/fu540-memory-map.h
>>>  create mode 100644 board/sifive/fu540/include/i2c.h
>>>  create mode 100644 board/sifive/fu540/include/regconfig-ctl.h
>>>  create mode 100644 board/sifive/fu540/include/regconfig-phy.h
>>>  create mode 100644 board/sifive/fu540/include/spi.h
>>>  create mode 100644 board/sifive/fu540/include/uart.h
>>>  create mode 100644 board/sifive/fu540/include/ux00ddr.h
>>>  create mode 100644 board/sifive/fu540/include/ux00prci.h
>>>  create mode 100644 board/sifive/fu540/spl.c
>>>  create mode 100644 board/sifive/fu540/uart.c
>>>  create mode 100644 configs/sifive_fu540_spl_defconfig
>>>
>>> diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds
>>> index 955dd3106d..d0495ce248 100644
>>> --- a/arch/riscv/cpu/u-boot-spl.lds
>>> +++ b/arch/riscv/cpu/u-boot-spl.lds
>>> @@ -72,6 +72,7 @@ SECTIONS
>>>         . = ALIGN(4);
>>>
>>>         _end = .;
>>> +       _image_binary_end = .;
>>>
>>>         .bss : {
>>>                 __bss_start = .;
>>> diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-
>>c000-u-boot.dtsi
>>> new file mode 100644
>>> index 0000000000..b86cdfb38d
>>> --- /dev/null
>>> +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
>>> @@ -0,0 +1,65 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * (C) Copyright 2019 SiFive, Inc
>>> + */
>>> +
>>> +/ {
>>> +       cpus {
>>> +               u-boot,dm-spl;
>>> +               cpu0: cpu at 0 {
>>> +                       u-boot,dm-spl;
>>> +                       status = "okay";
>>> +                       cpu0_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu1: cpu at 1 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu1_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu2: cpu at 2 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu2_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu3: cpu at 3 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu3_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +               cpu4: cpu at 4 {
>>> +                       u-boot,dm-spl;
>>> +                       cpu4_intc: interrupt-controller {
>>> +                               u-boot,dm-spl;
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       soc {
>>> +               u-boot,dm-spl;
>>> +               clint at 2000000 {
>>> +                       compatible = "riscv,clint0";
>>> +                       interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 >;
>>> +                       reg = <0x0 0x2000000 0x0 0xc0000>;
>>> +                       u-boot,dm-spl;
>>> +               };
>>> +
>>> +       };
>>> +
>>> +};
>>> +
>>> +&prci {
>>> +       u-boot,dm-spl;
>>> +};
>>> +
>>> +&uart0 {
>>> +       u-boot,dm-spl;
>>> +};
>>> +
>>> +&qspi2 {
>>> +       u-boot,dm-spl;
>>> +};
>>> diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>> new file mode 100644
>>> index 0000000000..9b59f4ee14
>>> --- /dev/null
>>> +++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
>>> @@ -0,0 +1,24 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2019 SiFive, Inc
>>> + */
>>> +
>>> +#include "fu540-c000-u-boot.dtsi"
>>> +
>>> +/ {
>>> +       hfclk {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +
>>> +       rtcclk {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +};
>>> +
>>> +&qspi2 {
>>> +
>>> +       mmc at 0 {
>>> +               u-boot,dm-spl;
>>> +       };
>>> +
>>> +};
>>> diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
>>> index d1520743a2..125c05dd8a 100644
>>> --- a/arch/riscv/include/asm/csr.h
>>> +++ b/arch/riscv/include/asm/csr.h
>>> @@ -103,6 +103,8 @@
>>>  #define CSR_TIMEH              0xc81
>>>  #define CSR_INSTRETH           0xc82
>>>  #define CSR_MHARTID            0xf14
>>> +#define CSR_MCYCLE             0xb00
>>> +#define CSR_MCYCLEH            0xb80
>>>
>>>  #ifndef __ASSEMBLY__
>>>
>>> diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
>>> index 816a135b21..ac7c6bff37 100644
>>> --- a/board/sifive/fu540/Kconfig
>>> +++ b/board/sifive/fu540/Kconfig
>>> @@ -16,12 +16,20 @@ config SYS_SOC
>>>         default "fu540"
>>>
>>>  config SYS_TEXT_BASE
>>> +       default 0x80200000 if SPL
>>>         default 0x80000000 if !RISCV_SMODE
>>>         default 0x80200000 if RISCV_SMODE
>>>
>>> +config SPL_TEXT_BASE
>>> +       default 0x08000000
>>> +
>>> +config SPL_OPENSBI_LOAD_ADDR
>>> +       default 0x80000000
>>> +
>>>  config BOARD_SPECIFIC_OPTIONS # dummy
>>>         def_bool y
>>>         select GENERIC_RISCV
>>> +       select SUPPORT_SPL
>>>         imply CMD_DHCP
>>>         imply CMD_EXT2
>>>         imply CMD_EXT4
>>> diff --git a/board/sifive/fu540/MAINTAINERS
>>b/board/sifive/fu540/MAINTAINERS
>>> index 702d803ad8..42c3f3deb0 100644
>>> --- a/board/sifive/fu540/MAINTAINERS
>>> +++ b/board/sifive/fu540/MAINTAINERS
>>> @@ -7,3 +7,4 @@ S:      Maintained
>>>  F:     board/sifive/fu540/
>>>  F:     include/configs/sifive-fu540.h
>>>  F:     configs/sifive_fu540_defconfig
>>> +F:     configs/sifive_fu540_spl_defconfig
>>> diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile
>>> index 6e1862c475..e532beb9d5 100644
>>> --- a/board/sifive/fu540/Makefile
>>> +++ b/board/sifive/fu540/Makefile
>>> @@ -3,3 +3,9 @@
>>>  # Copyright (c) 2019 Western Digital Corporation or its affiliates.
>>>
>>>  obj-y  += fu540.o
>>> +
>>> +ifdef CONFIG_SPL_BUILD
>>> +obj-y += spl.o
>>> +obj-y += ememoryotp.o
>>> +obj-y += uart.o
>>> +endif
>>> diff --git a/board/sifive/fu540/ememoryotp.c
>>b/board/sifive/fu540/ememoryotp.c
>>> new file mode 100644
>>> index 0000000000..994724af37
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/ememoryotp.c
>>> @@ -0,0 +1,143 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel at sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes at sifive.com>
>>> + */
>>> +
>>> +#include <stdint.h>
>>> +#include "include/fu540-memory-map.h"
>>> +#include "include/clkutils.h"
>>> +#include "include/ememoryotp.h"
>>> +
>>> +#define max(x, y) ((x) > (y) ? (x) : (y))
>>> +
>>> +extern inline void clkutils_delay_ns(int delay_ns);
>>> +
>>> +void ememory_otp_power_up_sequence(void)
>>> +{
>>> +       // Probably don't need to do this, since
>>> +       // all the other stuff has been happening.
>>> +       // But it is on the wave form.
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TVDS * 1000);
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TSAS * 1000);
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAS * 1000);
>>> +}
>>> +
>>> +void ememory_otp_power_down_sequence(void)
>>> +{
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TTAH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TASH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDSTB) = 0;
>>> +       // No delay indicated after this
>>> +}
>>> +
>>> +void ememory_otp_begin_read(void)
>>> +{
>>> +       // Initialize
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>>> +
>>> +       // Enable chip select
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TCS * 1000);
>>> +}
>>> +
>>> +void ememory_otp_exit_read(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       // Disable chip select
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>>> +       // Wait before changing PTM
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>>> +}
>>> +
>>> +unsigned int ememory_otp_read(int address)
>>> +{
>>> +       unsigned int read_value;
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>>> +       // Toggle clock
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TAS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 1;
>>> +       // Insert delay until data is ready.
>>> +       // There are lots of delays
>>> +       // on the chart, but I think this is the most relevant.
>>> +       int delay = max(EMEMORYOTP_MAX_TCD, EMEMORYOTP_MIN_TKH);
>>> +
>>> +       clkutils_delay_ns(delay * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       read_value = EMEMORYOTP_REG(EMEMORYOTP_PDOUT);
>>> +       // Could check here for things like TCYC < TAH + TCD
>>> +       return read_value;
>>> +}
>>> +
>>> +void ememory_otp_pgm_entry(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCLK) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 2;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TCSP * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 1;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPS * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTRIM) = 1;
>>> +}
>>> +
>>> +void ememory_otp_pgm_exit(void)
>>> +{
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PPROG) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_TYP_TPPR * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PCE) = 0;
>>> +       clkutils_delay_ns(EMEMORYOTP_MIN_TMH * 1000);
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PTM) = 0;
>>> +}
>>> +
>>> +void ememory_otp_pgm_access(int address, unsigned int write_data)
>>> +{
>>> +       int i;
>>> +
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PA) = address;
>>> +       for (int pas = 0; pas < 2; pas++) {
>>> +               EMEMORYOTP_REG(EMEMORYOTP_PAS) = pas;
>>> +               for (i = 0; i < 32; i++) {
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PAIO) = i;
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PDIN) = ((write_data >>
>i)
>>&
>>> +                                                          1);
>>> +
>>> +                       int delay = max(EMEMORYOTP_MIN_TASP,
>>> +                                       EMEMORYOTP_MIN_TDSP);
>>> +
>>> +                       clkutils_delay_ns(delay * 1000);
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 1;
>>> +                       clkutils_delay_ns(EMEMORYOTP_TYP_TPW * 1000);
>>> +                       EMEMORYOTP_REG(EMEMORYOTP_PWE) = 0;
>>> +                       delay = max(EMEMORYOTP_MIN_TAHP,
>>EMEMORYOTP_MIN_TDHP);
>>> +                       delay = max(delay, EMEMORYOTP_TYP_TPWI);
>>> +                       clkutils_delay_ns(delay * 1000);
>>> +               }
>>> +       }
>>> +       EMEMORYOTP_REG(EMEMORYOTP_PAS) = 0;
>>> +}
>>
>>Please add dm driver for this.
>
>I will add dm driver in v2.
>
>>
>>> diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
>>> index 47a2090251..e91418a88a 100644
>>> --- a/board/sifive/fu540/fu540.c
>>> +++ b/board/sifive/fu540/fu540.c
>>> @@ -10,6 +10,9 @@
>>>  #include <dm.h>
>>>  #include <linux/delay.h>
>>>  #include <linux/io.h>
>>> +#include <spl.h>
>>> +#include "include/ccache.h"
>>> +#include "include/fu540-memory-map.h"
>>>
>>>  #ifdef CONFIG_MISC_INIT_R
>>>
>>> @@ -143,7 +146,33 @@ int misc_init_r(void)
>>>
>>>  int board_init(void)
>>>  {
>>> -       /* For now nothing to do here. */
>>> +       /* enable all cache ways */
>>> +       ccache_enable_ways(CCACHE_CTRL_ADDR, 15);
>>> +       return 0;
>>> +}
>>> +
>>> +#ifdef CONFIG_SPL
>>> +void board_boot_order(u32 *spl_boot_list)
>>> +{
>>> +       u8 i;
>>> +       u32 boot_devices[] = {
>>> +#ifdef CONFIG_SPL_RAM_SUPPORT
>>> +               BOOT_DEVICE_RAM,
>>> +#endif
>>
>>You may skip if you haven't tested Boot from RAM yet?
>
>I have tested the BOOT from RAM.
>
>>
>>> +#ifdef CONFIG_SPL_MMC_SUPPORT
>>> +               BOOT_DEVICE_MMC1,
>>> +#endif
>>> +       };
>>>
>>> +       for (i = 0; i < ARRAY_SIZE(boot_devices); i++)
>>> +               spl_boot_list[i] = boot_devices[i];
>>> +}
>>> +#endif
>>> +
>>> +#ifdef CONFIG_SPL_LOAD_FIT
>>> +int board_fit_config_name_match(const char *name)
>>> +{
>>> +       /* boot using first FIT config */
>>>         return 0;
>>>  }
>>> +#endif
>>> diff --git a/board/sifive/fu540/include/ccache.h
>>b/board/sifive/fu540/include/ccache.h
>>> new file mode 100644
>>> index 0000000000..c7978ebdee
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ccache.h
>>> @@ -0,0 +1,47 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel at sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes at sifive.com>
>>> + */
>>> +
>>> +#ifndef FU540_CCACHE_H
>>> +#define FU540_CCACHE_H
>>> +
>>> +#include <asm/arch/cache.h>
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <stdatomic.h>
>>> +#include <linux/types.h>
>>> +
>>> +// Block memory access until operation completed
>>> +static inline void ccache_barrier_0(void)
>>> +{
>>> +       asm volatile("fence rw, io" : : : "memory");
>>> +}
>>> +
>>> +static inline void ccache_barrier_1(void)
>>> +{
>>> +       asm volatile("fence io, rw" : : : "memory");
>>> +}
>>> +
>>> +// Enable ways; allow cache to use these ways
>>> +static inline u8 ccache_enable_ways(u64 base_addr, u8 value)
>>> +{
>>> +       u32 old;
>>> +
>>> +       volatile _Atomic(u32) * enable = (_Atomic(u32) *)(base_addr +
>>> +                                         CCACHE_ENABLE);
>>> +       ccache_barrier_0();
>>> +       old = atomic_exchange_explicit(enable, value,
>>memory_order_relaxed);
>>> +       ccache_barrier_1();
>>> +       return old;
>>> +}
>>> +
>>> +#endif
>>> +
>>> +#endif /* FU540_CCACHE_H */
>>> diff --git a/board/sifive/fu540/include/clkutils.h
>>b/board/sifive/fu540/include/clkutils.h
>>> new file mode 100644
>>> index 0000000000..dbb260a1c3
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/clkutils.h
>>> @@ -0,0 +1,75 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel at sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes at sifive.com>
>>> + */
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <asm/encoding.h>
>>> +#include "fu540-memory-map.h"
>>> +
>>> +// Inlining header functions in C
>>> +// https://stackoverflow.com/a/23699777/7433423
>>> +inline u64 clkutils_read_mtime(void)
>>> +{
>>> +#if __riscv_xlen == 32
>>> +       u32 mtime_hi_0;
>>> +       u32 mtime_lo;
>>> +       u32 mtime_hi_1;
>>> +
>>> +       do {
>>> +               mtime_hi_0 = CLINT_REG(CLINT_MTIME + 4);
>>> +               mtime_lo   = CLINT_REG(CLINT_MTIME + 0);
>>> +               mtime_hi_1 = CLINT_REG(CLINT_MTIME + 4);
>>> +       } while (mtime_hi_0 != mtime_hi_1);
>>> +
>>> +       return (((u64)mtime_hi_1 << 32) | ((u64)mtime_lo));
>>> +#else
>>> +       return CLINT_REG64(CLINT_MTIME);
>>> +#endif
>>> +}
>>> +
>>> +static inline u64 clkutils_read_mcycle(void)
>>> +{
>>> +#if __riscv_xlen == 32
>>> +       u32 mcycle_hi_0;
>>> +       u32 mcycle_lo;
>>> +       u32 mcycle_hi_1;
>>> +
>>> +       do {
>>> +               mcycle_hi_0 = read_csr(mcycleh);
>>> +               mcycle_lo   = read_csr(mcycle);
>>> +               mcycle_hi_1 = read_csr(mcycleh);
>>> +       } while (mcycle_hi_0 != mcycle_hi_1);
>>> +
>>> +       return (((u64)mcycle_hi_1 << 32) | ((u64)mcycle_lo));
>>> +#else
>>> +       return csr_read(CSR_MCYCLE);
>>> +#endif
>>> +}
>>> +
>>> +// Note that since this runs off RTC, which is
>>> +// currently ~1-10MHz, this function is
>>> +// not acccurate for small delays.
>>> +// In the future, we may want to determine whether to
>>> +// use RTC vs mcycle, or create a different function
>>> +// based off mcycle.
>>> +// We add 1 to the then value because otherwise, if you wanted
>>> +// to delay up to RTC_PERIOD_NS-1 (for example), you wouldn't delay
>>> +// at all. So this function delays AT LEAST delay_ns.
>>
>>Improper syntax for multiple comments.
>
>I will update this in v2.
>
>>
>>> +inline void clkutils_delay_ns(int delay_ns)
>>> +{
>>> +       u64 now = clkutils_read_mtime();
>>> +       u64 then = now + delay_ns / RTC_PERIOD_NS + 1;
>>> +
>>> +       do {
>>> +               now = clkutils_read_mtime();
>>> +       } while (now < then);
>>> +}
>>> +
>>> +#endif /* !__ASSEMBLER__ */
>>> diff --git a/board/sifive/fu540/include/ddrregs.h
>>b/board/sifive/fu540/include/ddrregs.h
>>> new file mode 100644
>>> index 0000000000..e436496d87
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ddrregs.h
>>> @@ -0,0 +1,622 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel at sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes at sifive.com>
>>> + */
>>> +
>>> +#include <stdint.h>
>>> +
>>> +u32 DENALI_PHY_DATA[1215] = {
>>> +       DENALI_PHY_00_DATA, DENALI_PHY_01_DATA,
>>DENALI_PHY_02_DATA,
>>> +       DENALI_PHY_03_DATA, DENALI_PHY_04_DATA,
>>DENALI_PHY_05_DATA,
>>> +       DENALI_PHY_06_DATA, DENALI_PHY_07_DATA,
>>DENALI_PHY_08_DATA,
>>
>>Can this handle to write separate driver for ram like drivers/ram ?

We can add DM driver for RAM later. Right now, I want to get U-boot SPL running for FU540.

>
>I didn't get you.
>
>>> diff --git a/board/sifive/fu540/include/ememoryotp.h
>>b/board/sifive/fu540/include/ememoryotp.h
>>> new file mode 100644
>>> index 0000000000..274283c4db
>>> --- /dev/null
>>> +++ b/board/sifive/fu540/include/ememoryotp.h
>>> @@ -0,0 +1,24 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2019 SiFive, Inc
>>> + *
>>> + * Authors:
>>> + *   Pragnesh Patel <pragnesh.patel at sifive.com>
>>> + *   Troy Benjegerdes <troy.benjegerdes at sifive.com>
>>> + */
>>> +
>
>[...]
>
>>> +
>>> +#ifndef __ASSEMBLER__
>>> +
>>> +#include <stdint.h>
>>> +#include <stddef.h>
>>> +#include <stdbool.h>
>>> +#include "uart.h"
>>> +#include "fu540-memory-map.h"
>>> +
>>> +#define DRAM_CLASS_OFFSET                      8
>>> +#define DRAM_CLASS_DDR4                        0xA
>>> +#define OPTIMAL_RMODW_EN_OFFSET                0
>>> +#define DISABLE_RD_INTERLEAVE_OFFSET           16
>>> +#define OUT_OF_RANGE_OFFSET                    1
>>> +#define MULTIPLE_OUT_OF_RANGE_OFFSET           2
>>> +#
>>
>>Sorry, too much stuff in single patch. it is worth require multiple patches.
>
>Sure, will split this into multiple patches.
>
>>
>>Jagan.


More information about the U-Boot mailing list