diff --git a/Documentation/platforms/risc-v/allwinner-d1/boards/lichee-rv-86-panel/index.rst b/Documentation/platforms/risc-v/allwinner-d1/boards/lichee-rv-86-panel/index.rst new file mode 100644 index 00000000000..62c5f5def43 --- /dev/null +++ b/Documentation/platforms/risc-v/allwinner-d1/boards/lichee-rv-86-panel/index.rst @@ -0,0 +1,98 @@ +================== +Lichee RV 86 Panel +================== + +The Sipeed Lichee RV 86 Panel is based on the Allwinner D1 SoC. The board +contains a single T-Head C906 RV64 core and 512 MiB of external DDR3 memory. +This NuttX port runs in supervisor mode under OpenSBI and uses a FLAT address +space. + +The initial port supports: + +* UART0 as the serial console; +* the D1 PLIC; +* the native D1 Timer1 as the scheduler tick source; and +* an NSH configuration. + +Serial Console +============== + +UART0 is available on PB8 (TX) and PB9 (RX). Connect a 3.3 V USB-to-serial +adapter with crossed TX and RX signals and a common ground. Configure the +terminal for 115200 baud, 8 data bits, no parity, one stop bit and no flow +control. + +Toolchain +========= + +Install a ``riscv-none-elf`` bare-metal toolchain and add its ``bin`` +directory to ``PATH``. The configuration builds for RV64IMAFDC with the +LP64D ABI. + +Building +======== + +Configure and build NuttX from the NuttX source directory: + +.. code:: console + + $ tools/configure.sh lichee-rv-86-panel:nsh + $ make + +The configuration links NuttX at ``0x40200000`` and produces ``nuttx`` and +``nuttx.bin``. It uses the RAM region from ``0x40200000`` to ``0x48000000``. + +The tested U-Boot flow uses a legacy image wrapper. Install ``mkimage`` and +create the image as follows: + +.. code:: console + + $ mkimage -A riscv -O linux -T kernel -C none -a 0x40200000 \ + -e 0x40200000 -n "Apache NuttX Allwinner D1" \ + -d nuttx.bin nuttx-d1.img + +Booting NuttX +============= + +The board must already have a working D1 BootROM, U-Boot SPL, OpenSBI and +U-Boot boot chain. NuttX is the supervisor-mode payload; it does not replace +SPL, OpenSBI or U-Boot. + +Copy ``nuttx-d1.img`` to ``/boot`` on the existing root filesystem. At the +U-Boot prompt, verify the MMC device and partition, then load the image to a +temporary address and boot it: + +.. code:: console + + => ext4load mmc 0:1 0x48000000 /boot/nuttx-d1.img + => bootm 0x48000000 - ${fdtcontroladdr} + +U-Boot relocates the payload to its ``0x40200000`` load address. The initial +NuttX port receives the device-tree pointer from the firmware but does not +consume the device tree. + +Watchdog +======== + +Some U-Boot configurations leave the D1 RISC-V watchdog running with an +approximately 16-second timeout. Early NuttX startup writes the D1 watchdog +disable key to the watchdog mode register before normal initialization, so a +manual U-Boot watchdog-disable command is not required. + +Scheduler Tick +============== + +The scheduler uses native D1 Timer1 as an external interrupt through the +PLIC. Timer1 uses OSC24M with a divide-by-one prescaler in periodic mode. +With ``CONFIG_USEC_PER_TICK=1000``, the interval register is programmed with +23999. The inclusive down-counter therefore consumes exactly 24000 input +clocks per interrupt and provides a 1000 Hz scheduler tick. + +Configurations +============== + +nsh +--- + +The ``nsh`` configuration provides an interactive NuttShell on UART0. It is +a FLAT supervisor-mode build intended for initial command-line bring-up. diff --git a/Documentation/platforms/risc-v/allwinner-d1/index.rst b/Documentation/platforms/risc-v/allwinner-d1/index.rst new file mode 100644 index 00000000000..4e2bb4c7686 --- /dev/null +++ b/Documentation/platforms/risc-v/allwinner-d1/index.rst @@ -0,0 +1,20 @@ +============ +Allwinner D1 +============ + +The Allwinner D1 is a 64-bit RISC-V SoC based on a single T-Head C906 core. +It implements the RV64IMAFDC ISA and provides an Sv39 MMU, a platform-level +interrupt controller (PLIC), general-purpose timers, UARTs and other +peripherals. Boards typically pair the SoC with external DDR3 memory. + +NuttX runs in supervisor mode under OpenSBI. The initial port uses a FLAT +build and does not consume a device tree. + +Supported Boards +================ + +.. toctree:: + :glob: + :maxdepth: 1 + + boards/*/* diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 6ce72af7af7..f134be00edb 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -435,6 +435,18 @@ config ARCH_CHIP_SG2000 ---help--- SOPHGO SG2000 SoC. +config ARCH_CHIP_ALLWINNER_D1 + bool "Allwinner D1" + select ARCH_RV64 + select ARCH_RV_ISA_M + select ARCH_RV_ISA_A + select ARCH_RV_ISA_C + select ARCH_HAVE_FPU + select ARCH_HAVE_DPFPU + select ARCH_HAVE_S_MODE + ---help--- + Allwinner D1 / sun20i-d1 SoC with a T-Head C906 RV64 core. + config ARCH_CHIP_EIC7700X bool "ESWIN EIC7700X" select ARCH_BOARD_COMMON @@ -665,6 +677,7 @@ config ARCH_CHIP default "bl808" if ARCH_CHIP_BL808 default "k230" if ARCH_CHIP_K230 default "sg2000" if ARCH_CHIP_SG2000 + default "allwinner-d1" if ARCH_CHIP_ALLWINNER_D1 default "eic7700x" if ARCH_CHIP_EIC7700X default "rp23xx-rv" if ARCH_CHIP_RP23XX_RV @@ -931,6 +944,9 @@ endif if ARCH_CHIP_SG2000 source "arch/risc-v/src/sg2000/Kconfig" endif +if ARCH_CHIP_ALLWINNER_D1 +source "arch/risc-v/src/allwinner-d1/Kconfig" +endif if ARCH_CHIP_EIC7700X source "arch/risc-v/src/eic7700x/Kconfig" endif diff --git a/arch/risc-v/include/allwinner-d1/chip.h b/arch/risc-v/include/allwinner-d1/chip.h new file mode 100644 index 00000000000..ea14187f211 --- /dev/null +++ b/arch/risc-v/include/allwinner-d1/chip.h @@ -0,0 +1,9 @@ +/**************************************************************************** + * arch/risc-v/include/allwinner-d1/chip.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_ALLWINNER_D1_CHIP_H +#define __ARCH_RISCV_INCLUDE_ALLWINNER_D1_CHIP_H + +#endif /* __ARCH_RISCV_INCLUDE_ALLWINNER_D1_CHIP_H */ diff --git a/arch/risc-v/include/allwinner-d1/irq.h b/arch/risc-v/include/allwinner-d1/irq.h new file mode 100644 index 00000000000..8a4914d15c5 --- /dev/null +++ b/arch/risc-v/include/allwinner-d1/irq.h @@ -0,0 +1,21 @@ +/**************************************************************************** + * arch/risc-v/include/allwinner-d1/irq.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_ALLWINNER_D1_IRQ_H +#define __ARCH_RISCV_INCLUDE_ALLWINNER_D1_IRQ_H + +/* The D1 PLIC exposes interrupt source IDs 1 through 175. */ + +#define ALLWINNER_D1_PLIC_TIMER0 75 +#define ALLWINNER_D1_PLIC_TIMER1 76 + +#define ALLWINNER_D1_IRQ_TIMER0 \ + (RISCV_IRQ_SEXT + ALLWINNER_D1_PLIC_TIMER0) +#define ALLWINNER_D1_IRQ_TIMER1 \ + (RISCV_IRQ_SEXT + ALLWINNER_D1_PLIC_TIMER1) + +#define NR_IRQS (RISCV_IRQ_SEXT + 176) + +#endif /* __ARCH_RISCV_INCLUDE_ALLWINNER_D1_IRQ_H */ diff --git a/arch/risc-v/src/allwinner-d1/Kconfig b/arch/risc-v/src/allwinner-d1/Kconfig new file mode 100644 index 00000000000..db15ef02ab5 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/Kconfig @@ -0,0 +1 @@ +# Allwinner D1 chip-specific configuration diff --git a/arch/risc-v/src/allwinner-d1/Make.defs b/arch/risc-v/src/allwinner-d1/Make.defs new file mode 100644 index 00000000000..c69187c9232 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/Make.defs @@ -0,0 +1,11 @@ +############################################################################ +# arch/risc-v/src/allwinner-d1/Make.defs +# SPDX-License-Identifier: Apache-2.0 +############################################################################ + +include common/Make.defs + +HEAD_ASRC = allwinner_d1_head.S + +CHIP_CSRCS = allwinner_d1_start.c allwinner_d1_irq_dispatch.c +CHIP_CSRCS += allwinner_d1_irq.c allwinner_d1_timerisr.c diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_head.S b/arch/risc-v/src/allwinner-d1/allwinner_d1_head.S new file mode 100644 index 00000000000..62983e3db04 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_head.S @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_head.S + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "riscv_internal.h" +#include "riscv_macros.S" + + .section .text + .global __start + .type __start, function + +__start: + /* Linux-compatible RISC-V image header. The image is linked 2 MiB above + * the D1 DRAM base, as required by the RISC-V boot protocol. + */ + + c.li s4, -13 + j real_start + .long 0 + .quad 0x200000 + .quad _ebss - __start + .quad 0 + .long 2 + .long 0 + .quad 0 + .ascii "RISCV\x00\x00\x00" + .ascii "RSC\x05" + .long 0 + +real_start: +#ifdef CONFIG_SMP + li t1, CONFIG_SMP_NCPUS +#else + li t1, 1 +#endif + blt a0, t1, 1f + csrw CSR_SIE, zero +0: + wfi + j 0b + +1: + riscv_set_inital_sp ALLWINNER_D1_IDLESTACK_BASE, SMP_STACK_SIZE, a0 + csrw CSR_SIE, zero + la t0, __trap_vec + csrw CSR_STVEC, t0 + jal x1, allwinner_d1_start + + .global _init + .global _fini +_init: +_fini: + ret diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_irq.c b/arch/risc-v/src/allwinner-d1/allwinner_d1_irq.c new file mode 100644 index 00000000000..29428c8f0a3 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_irq.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_irq.c + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "chip.h" +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + uintptr_t claim; + int id; + int word; + + up_irq_save(); + riscv_exception_attach(); + + for (word = 0; word < (ALLWINNER_D1_PLIC_NDEV + 31) / 32; word++) + { + putreg32(0, ALLWINNER_D1_PLIC_ENABLE + 4 * word); + } + + claim = getreg32(ALLWINNER_D1_PLIC_CLAIM); + if (claim != 0) + { + putreg32(claim, ALLWINNER_D1_PLIC_CLAIM); + } + + for (id = 1; id <= ALLWINNER_D1_PLIC_NDEV; id++) + { + putreg32(1, ALLWINNER_D1_PLIC_PRIORITY + 4 * id); + } + + putreg32(0, ALLWINNER_D1_PLIC_THRESHOLD); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + riscv_color_intstack(); + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + int extirq; + + if (irq == RISCV_IRQ_SOFT) + { + CLEAR_CSR(CSR_IE, IE_SIE); + } + else if (irq == RISCV_IRQ_TIMER) + { + CLEAR_CSR(CSR_IE, IE_TIE); + } + else if (irq > RISCV_IRQ_EXT) + { + extirq = irq - RISCV_IRQ_EXT; + if (extirq > 0 && extirq <= ALLWINNER_D1_PLIC_NDEV) + { + modifyreg32(ALLWINNER_D1_PLIC_ENABLE + 4 * (extirq / 32), + 1u << (extirq % 32), 0); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + int extirq; + + if (irq == RISCV_IRQ_SOFT) + { + SET_CSR(CSR_IE, IE_SIE); + } + else if (irq == RISCV_IRQ_TIMER) + { + SET_CSR(CSR_IE, IE_TIE); + } + else if (irq > RISCV_IRQ_EXT) + { + extirq = irq - RISCV_IRQ_EXT; + if (extirq > 0 && extirq <= ALLWINNER_D1_PLIC_NDEV) + { + modifyreg32(ALLWINNER_D1_PLIC_ENABLE + 4 * (extirq / 32), + 0, 1u << (extirq % 32)); + } + } +} + +/**************************************************************************** + * Name: up_irq_enable + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + irqstate_t oldstat; + + SET_CSR(CSR_IE, IE_EIE); + oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE); + return oldstat; +} diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_irq_dispatch.c b/arch/risc-v/src/allwinner-d1/allwinner_d1_irq_dispatch.c new file mode 100644 index 00000000000..74dce1bd55d --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_irq_dispatch.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_irq_dispatch.c + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "chip.h" +#include "riscv_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RV_IRQ_MASK 59 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_dispatch_irq + ****************************************************************************/ + +void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs) +{ + int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf); + uint32_t source = 0; + + if (irq == RISCV_IRQ_EXT) + { + source = getreg32(ALLWINNER_D1_PLIC_CLAIM); + if (source != 0) + { + irq += source; + } + } + + if (irq != RISCV_IRQ_EXT) + { + regs = riscv_doirq(irq, regs); + } + + if (source != 0) + { + putreg32(source, ALLWINNER_D1_PLIC_CLAIM); + } + + return regs; +} diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_memorymap.h b/arch/risc-v/src/allwinner-d1/allwinner_d1_memorymap.h new file mode 100644 index 00000000000..2308b24d162 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_memorymap.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_memorymap.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_ALLWINNER_D1_MEMORYMAP_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_ALLWINNER_D1_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "riscv_common_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# define ALLWINNER_D1_IDLESTACK_BASE ((uintptr_t)_ebss) +#else +# define ALLWINNER_D1_IDLESTACK_BASE _ebss +#endif + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_ALLWINNER_D1_MEMORYMAP_H */ diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_start.c b/arch/risc-v/src/allwinner-d1/allwinner_d1_start.c new file mode 100644 index 00000000000..6f3e4ba55af --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_start.c @@ -0,0 +1,160 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_start.c + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "riscv_internal.h" +#include "hardware/allwinner_d1_wdt.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) up_putc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Extern Function Declarations + ****************************************************************************/ + +extern void __trap_vec(void); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: allwinner_d1_disable_inherited_watchdog + ****************************************************************************/ + +static void allwinner_d1_disable_inherited_watchdog(void) +{ + /* U-Boot may leave the D1 RISC-V watchdog running with a 16-second + * timeout. The key with all mode bits clear stops that inherited timer. + */ + + putreg32(ALLWINNER_D1_RISCV_WDT_DISABLE_KEY, + ALLWINNER_D1_RISCV_WDT_MODE); + UP_DSB(); +} + +/**************************************************************************** + * Name: allwinner_d1_clear_bss + ****************************************************************************/ + +static void allwinner_d1_clear_bss(void) +{ + uint32_t *dest; + + for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) + { + *dest++ = 0; + } +} + +/**************************************************************************** + * Name: allwinner_d1_lowsetup + ****************************************************************************/ + +static void allwinner_d1_lowsetup(void) +{ + uint32_t regval; + + /* Enable the UART0 APB gate and deassert its bus reset. */ + + modifyreg32(ALLWINNER_D1_UART_BGR, 0, (1u << 0) | (1u << 16)); + + /* Select UART0 function 6 on PB8 (TX) and PB9 (RX). */ + + regval = getreg32(ALLWINNER_D1_PB_CFG1); + regval &= ~0xffu; + regval |= 0x66u; + putreg32(regval, ALLWINNER_D1_PB_CFG1); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: allwinner_d1_start + ****************************************************************************/ + +void allwinner_d1_start(int hartid, uintptr_t dtb) +{ + (void)dtb; /* The initial FLAT port does not consume a device tree. */ + + allwinner_d1_disable_inherited_watchdog(); + + if (hartid != 0) + { + for (; ; ) + { + asm volatile ("wfi"); + } + } + + allwinner_d1_clear_bss(); + +#ifdef CONFIG_RISCV_PERCPU_SCRATCH + riscv_percpu_add_hart(hartid); +#endif + + WRITE_CSR(CSR_SATP, 0); + asm volatile ("sfence.vma" ::: "memory"); + WRITE_CSR(CSR_STVEC, (uintptr_t)__trap_vec); + + riscv_fpuconfig(); + allwinner_d1_lowsetup(); + +#ifdef USE_EARLYSERIALINIT + riscv_earlyserialinit(); +#endif + + showprogress('A'); + nx_start(); + + for (; ; ) + { + asm volatile ("wfi"); + } +} + +/**************************************************************************** + * Name: riscv_earlyserialinit + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ +#ifdef CONFIG_16550_UART + u16550_earlyserialinit(); +#endif +} + +/**************************************************************************** + * Name: riscv_serialinit + ****************************************************************************/ + +void riscv_serialinit(void) +{ +#ifdef CONFIG_16550_UART + u16550_serialinit(); +#endif +} diff --git a/arch/risc-v/src/allwinner-d1/allwinner_d1_timerisr.c b/arch/risc-v/src/allwinner-d1/allwinner_d1_timerisr.c new file mode 100644 index 00000000000..1df6619d294 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/allwinner_d1_timerisr.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/allwinner_d1_timerisr.c + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include "chip.h" +#include "riscv_internal.h" +#include "hardware/allwinner_d1_timer.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALLWINNER_D1_TICK_TIMER 1 +#define ALLWINNER_D1_TIMER_FREQUENCY 24000000ul +#define ALLWINNER_D1_TIMER_COUNTS_PER_TICK \ + (ALLWINNER_D1_TIMER_FREQUENCY / TICK_PER_SEC) +#define ALLWINNER_D1_TIMER_INTERVAL_VALUE \ + (ALLWINNER_D1_TIMER_COUNTS_PER_TICK - 1) + +#if (ALLWINNER_D1_TIMER_FREQUENCY % TICK_PER_SEC) != 0 +# error "The D1 timer requires an integer number of counts per tick" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: allwinner_d1_timerisr + ****************************************************************************/ + +static int allwinner_d1_timerisr(int irq, void *context, void *arg) +{ + /* The timer interrupt status is write-one-to-clear. Clear the peripheral + * before processing the scheduler tick; the PLIC dispatcher completes the + * external interrupt after this handler returns. + */ + + putreg32(ALLWINNER_D1_TIMER_IRQ(ALLWINNER_D1_TICK_TIMER), + ALLWINNER_D1_TIMER_IRQ_STATUS); + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regval; + int ret; + + /* Channel 1 is the scheduler timer used by the proven D1 RT-Smart BSP. + * Select the 24 MHz oscillator, divide by one, and use periodic mode. + */ + + regval = getreg32(ALLWINNER_D1_TIMER_CTRL(ALLWINNER_D1_TICK_TIMER)); + regval &= ~(ALLWINNER_D1_TIMER_CTRL_ENABLE | + ALLWINNER_D1_TIMER_CTRL_RELOAD | + ALLWINNER_D1_TIMER_CTRL_CLK_SRC_MASK | + ALLWINNER_D1_TIMER_CTRL_PRES_MASK | + ALLWINNER_D1_TIMER_CTRL_ONESHOT); + regval |= ALLWINNER_D1_TIMER_CTRL_CLK_OSC24M | + ALLWINNER_D1_TIMER_CTRL_PRES_DIV1; + putreg32(regval, + ALLWINNER_D1_TIMER_CTRL(ALLWINNER_D1_TICK_TIMER)); + + /* The down-counter includes zero, so N input clocks require N - 1 in the + * interval register. + */ + + putreg32(ALLWINNER_D1_TIMER_INTERVAL_VALUE, + ALLWINNER_D1_TIMER_INTERVAL(ALLWINNER_D1_TICK_TIMER)); + + /* Clear a stale channel interrupt before attaching and enabling it. */ + + putreg32(ALLWINNER_D1_TIMER_IRQ(ALLWINNER_D1_TICK_TIMER), + ALLWINNER_D1_TIMER_IRQ_STATUS); + + ret = irq_attach(ALLWINNER_D1_IRQ_TIMER1, + allwinner_d1_timerisr, NULL); + DEBUGASSERT(ret >= 0); + if (ret < 0) + { + return; + } + + /* This port no longer uses the OpenSBI supervisor timer interrupt. */ + + up_disable_irq(RISCV_IRQ_STIMER); + up_enable_irq(ALLWINNER_D1_IRQ_TIMER1); + + modifyreg32(ALLWINNER_D1_TIMER_IRQ_EN, 0, + ALLWINNER_D1_TIMER_IRQ(ALLWINNER_D1_TICK_TIMER)); + + /* Reload the interval and start the channel in periodic mode. */ + + putreg32(regval | ALLWINNER_D1_TIMER_CTRL_RELOAD | + ALLWINNER_D1_TIMER_CTRL_ENABLE, + ALLWINNER_D1_TIMER_CTRL(ALLWINNER_D1_TICK_TIMER)); +} diff --git a/arch/risc-v/src/allwinner-d1/chip.h b/arch/risc-v/src/allwinner-d1/chip.h new file mode 100644 index 00000000000..f8d3350c705 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/chip.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/chip.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_CHIP_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "allwinner_d1_memorymap.h" +#include "hardware/allwinner_d1_memorymap.h" +#include "hardware/allwinner_d1_plic.h" +#include "riscv_internal.h" +#include "riscv_percpu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef __ASSEMBLY__ +#if CONFIG_ARCH_INTERRUPTSTACK > 15 && !defined(CONFIG_SMP) && \ + defined(CONFIG_ARCH_USE_S_MODE) +.macro setintstack tmp0, tmp1 + csrr \tmp0, CSR_SCRATCH + REGLOAD sp, RISCV_PERCPU_IRQSTACK(\tmp0) +.endm +#endif +#endif + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_CHIP_H */ diff --git a/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_memorymap.h b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_memorymap.h new file mode 100644 index 00000000000..924eb1f1a49 --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_memorymap.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_memorymap.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_MEMORYMAP_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_MEMORYMAP_H + +#define ALLWINNER_D1_PIO_BASE 0x02000000ul +#define ALLWINNER_D1_CCU_BASE 0x02001000ul +#define ALLWINNER_D1_TIMER_BASE 0x02050000ul +#define ALLWINNER_D1_UART0_BASE 0x02500000ul +#define ALLWINNER_D1_RISCV_WDT_BASE 0x06011000ul +#define ALLWINNER_D1_PLIC_BASE 0x10000000ul +#define ALLWINNER_D1_DRAM_BASE 0x40000000ul + +#define ALLWINNER_D1_PB_CFG1 (ALLWINNER_D1_PIO_BASE + 0x34) +#define ALLWINNER_D1_UART_BGR (ALLWINNER_D1_CCU_BASE + 0x90c) + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_MEMORYMAP_H */ diff --git a/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_plic.h b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_plic.h new file mode 100644 index 00000000000..a95e23c07fb --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_plic.h @@ -0,0 +1,25 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_plic.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_PLIC_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_PLIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "allwinner_d1_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALLWINNER_D1_PLIC_NDEV 175 +#define ALLWINNER_D1_PLIC_PRIORITY (ALLWINNER_D1_PLIC_BASE + 0x000000) +#define ALLWINNER_D1_PLIC_ENABLE (ALLWINNER_D1_PLIC_BASE + 0x002080) +#define ALLWINNER_D1_PLIC_THRESHOLD (ALLWINNER_D1_PLIC_BASE + 0x201000) +#define ALLWINNER_D1_PLIC_CLAIM (ALLWINNER_D1_PLIC_BASE + 0x201004) + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_PLIC_H */ diff --git a/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_timer.h b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_timer.h new file mode 100644 index 00000000000..44306047eed --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_timer.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_timer.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_TIMER_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_TIMER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "allwinner_d1_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALLWINNER_D1_TIMER_IRQ_EN (ALLWINNER_D1_TIMER_BASE + 0x00) +#define ALLWINNER_D1_TIMER_IRQ_STATUS (ALLWINNER_D1_TIMER_BASE + 0x04) + +#define ALLWINNER_D1_TIMER_CTRL(n) \ + (ALLWINNER_D1_TIMER_BASE + 0x10 * (n) + 0x10) +#define ALLWINNER_D1_TIMER_INTERVAL(n) \ + (ALLWINNER_D1_TIMER_BASE + 0x10 * (n) + 0x14) +#define ALLWINNER_D1_TIMER_CURRENT(n) \ + (ALLWINNER_D1_TIMER_BASE + 0x10 * (n) + 0x18) + +#define ALLWINNER_D1_TIMER_IRQ(n) (1u << (n)) +#define ALLWINNER_D1_TIMER_CTRL_ENABLE (1u << 0) +#define ALLWINNER_D1_TIMER_CTRL_RELOAD (1u << 1) +#define ALLWINNER_D1_TIMER_CTRL_CLK_SRC_MASK (3u << 2) +#define ALLWINNER_D1_TIMER_CTRL_CLK_OSC24M (1u << 2) +#define ALLWINNER_D1_TIMER_CTRL_PRES_MASK (7u << 4) +#define ALLWINNER_D1_TIMER_CTRL_PRES_DIV1 (0u << 4) +#define ALLWINNER_D1_TIMER_CTRL_ONESHOT (1u << 7) + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_TIMER_H */ diff --git a/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_wdt.h b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_wdt.h new file mode 100644 index 00000000000..f0adeda14ac --- /dev/null +++ b/arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_wdt.h @@ -0,0 +1,23 @@ +/**************************************************************************** + * arch/risc-v/src/allwinner-d1/hardware/allwinner_d1_wdt.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_WDT_H +#define __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_WDT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "allwinner_d1_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALLWINNER_D1_RISCV_WDT_MODE \ + (ALLWINNER_D1_RISCV_WDT_BASE + 0x18) +#define ALLWINNER_D1_RISCV_WDT_DISABLE_KEY 0x16aa0000u + +#endif /* __ARCH_RISCV_SRC_ALLWINNER_D1_HARDWARE_ALLWINNER_D1_WDT_H */ diff --git a/boards/Kconfig b/boards/Kconfig index add123751e1..498c61ca17a 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -2416,6 +2416,13 @@ config ARCH_BOARD_SG2000_MILKV_DUOS This options selects support for NuttX on Milk-V Duo S based on SOPHGO SG2000 SoC. +config ARCH_BOARD_LICHEE_RV_86_PANEL + bool "Sipeed Lichee RV 86 Panel" + depends on ARCH_CHIP_ALLWINNER_D1 + ---help--- + This selects the Sipeed Lichee RV 86 Panel / Lichee RV D1 + platform based on the Allwinner D1 SoC. + config ARCH_BOARD_EIC7700X_STARPRO64 bool "PINE64 StarPro64" depends on ARCH_CHIP_EIC7700X @@ -4066,6 +4073,7 @@ config ARCH_BOARD default "canmv230" if ARCH_BOARD_K230_CANMV default "ox64" if ARCH_BOARD_BL808_OX64 default "milkv_duos" if ARCH_BOARD_SG2000_MILKV_DUOS + default "lichee-rv-86-panel" if ARCH_BOARD_LICHEE_RV_86_PANEL default "starpro64" if ARCH_BOARD_EIC7700X_STARPRO64 default "eic7700-evb" if ARCH_BOARD_EIC7700X_EVB default "sabre-6quad" if ARCH_BOARD_SABRE_6QUAD @@ -5167,6 +5175,9 @@ endif if ARCH_BOARD_SG2000_MILKV_DUOS source "boards/risc-v/sg2000/milkv_duos/Kconfig" endif +if ARCH_BOARD_LICHEE_RV_86_PANEL +source "boards/risc-v/allwinner-d1/lichee-rv-86-panel/Kconfig" +endif if ARCH_BOARD_EIC7700X_STARPRO64 source "boards/risc-v/eic7700x/starpro64/Kconfig" endif diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/Kconfig b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/Kconfig new file mode 100644 index 00000000000..22c4e24110c --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/Kconfig @@ -0,0 +1 @@ +# Sipeed Lichee RV 86 Panel board-specific configuration diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/configs/nsh/defconfig b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/configs/nsh/defconfig new file mode 100644 index 00000000000..73dd4d28573 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/configs/nsh/defconfig @@ -0,0 +1,56 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_OS_API is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +CONFIG_16550_ADDRWIDTH=0 +CONFIG_16550_REGINCR=4 +CONFIG_16550_UART0=y +CONFIG_16550_UART0_BASE=0x02500000 +CONFIG_16550_UART0_CLOCK=24000000 +CONFIG_16550_UART0_IRQ=43 +CONFIG_16550_UART0_SERIAL_CONSOLE=y +CONFIG_16550_UART=y +CONFIG_16550_WAIT_LCR=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="lichee-rv-86-panel" +CONFIG_ARCH_BOARD_LICHEE_RV_86_PANEL=y +CONFIG_ARCH_CHIP="allwinner-d1" +CONFIG_ARCH_CHIP_ALLWINNER_D1=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_USE_S_MODE=y +CONFIG_BOARD_LOOPSPERMSEC=1000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=4096 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_ENVPATH=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=132120576 +CONFIG_RAM_START=0x40200000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_UART_ARCH_MMIO=y +CONFIG_STACK_COLORATION=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=4096 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/include/board.h b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/include/board.h new file mode 100644 index 00000000000..810d57269d3 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/include/board.h @@ -0,0 +1,18 @@ +/**************************************************************************** + * boards/risc-v/allwinner-d1/lichee-rv-86-panel/include/board.h + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_ALLWINNER_D1_LICHEE_RV_86_PANEL_INCLUDE_BOARD_H +#define __BOARDS_RISCV_ALLWINNER_D1_LICHEE_RV_86_PANEL_INCLUDE_BOARD_H + +#define LED_STARTED 0 +#define LED_HEAPALLOCATE 1 +#define LED_IRQSENABLED 2 +#define LED_STACKCREATED 3 +#define LED_INIRQ 4 +#define LED_SIGNAL 5 +#define LED_ASSERTION 6 +#define LED_PANIC 7 + +#endif /* __BOARDS_RISCV_ALLWINNER_D1_LICHEE_RV_86_PANEL_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/Make.defs b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/Make.defs new file mode 100644 index 00000000000..e03f6f37694 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/Make.defs @@ -0,0 +1,18 @@ +############################################################################ +# boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/Make.defs +# SPDX-License-Identifier: Apache-2.0 +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs + +LDSCRIPT = ld.script +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/ld.script b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/ld.script new file mode 100644 index 00000000000..10781d11b67 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/ld.script @@ -0,0 +1,95 @@ +/**************************************************************************** + * boards/risc-v/allwinner-d1/lichee-rv-86-panel/scripts/ld.script + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +#include + +OUTPUT_ARCH("riscv") +ENTRY(__start) + +SECTIONS +{ + . = CONFIG_RAM_START; + + .text : + { + _stext = .; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.gnu.linkonce.t.*) + *(.init) + *(.fini) + _etext = .; + } + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) + SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + _einit = ABSOLUTE(.); + } + + .rodata : + { + _srodata = .; + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + _erodata = .; + } + + .tdata : + { + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + } + + .tbss : + { + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + } + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = .; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(8); + _edata = .; + } + + .bss : + { + _sbss = .; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + . = ALIGN(32); + _ebss = .; + } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/Makefile b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/Makefile new file mode 100644 index 00000000000..b94cd8f8248 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/Makefile @@ -0,0 +1,10 @@ +############################################################################ +# boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/Makefile +# SPDX-License-Identifier: Apache-2.0 +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = allwinner_d1_boardinit.c + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/allwinner_d1_boardinit.c b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/allwinner_d1_boardinit.c new file mode 100644 index 00000000000..e281e2ce083 --- /dev/null +++ b/boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/allwinner_d1_boardinit.c @@ -0,0 +1,29 @@ +/**************************************************************************** + * boards/risc-v/allwinner-d1/lichee-rv-86-panel/src/allwinner_d1_boardinit.c + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_FS_PROCFS +# include +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_late_initialize + ****************************************************************************/ + +void board_late_initialize(void) +{ +#ifdef CONFIG_FS_PROCFS + mount(NULL, "/proc", "procfs", 0, NULL); +#endif +}