diff --git a/board/CMakeLists.txt b/board/CMakeLists.txt index 4efcbf63..54bbcd7d 100644 --- a/board/CMakeLists.txt +++ b/board/CMakeLists.txt @@ -20,4 +20,8 @@ endif() if(CONFIG_BOARD_LONGANPI-4B) add_subdirectory(longanpi-4b) +endif() + +if(CONFIG_BOARD_BINGPI-M1) + add_subdirectory(bingpi-m1) endif() \ No newline at end of file diff --git a/board/bingpi-m1/CMakeLists.txt b/board/bingpi-m1/CMakeLists.txt new file mode 100644 index 00000000..27e2805d --- /dev/null +++ b/board/bingpi-m1/CMakeLists.txt @@ -0,0 +1,7 @@ +set(APP_COMMON_SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/start.S + ${CMAKE_CURRENT_SOURCE_DIR}/board.c + ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c +) + +add_subdirectory(hello_world) diff --git a/board/bingpi-m1/README.md b/board/bingpi-m1/README.md new file mode 100644 index 00000000..fc121158 --- /dev/null +++ b/board/bingpi-m1/README.md @@ -0,0 +1,29 @@ +# SyterKit Common + +## start.S + +This code snippet is an ARM assembly language program that includes initialization settings and exception handlers. Here's a breakdown of its functionalities: + +1. Initialization Settings: It sets registers and writes specific values to configure the processor's working mode, interrupt enable, etc. + +2. Set Vector Table: It writes the address of the vector table to the Vector Base Address Register, which is used for handling exceptions and interrupts. + +3. Enable NEON/VFP Unit: It configures the processor to enable the NEON (Advanced SIMD) and VFP (Floating-Point) units. + +4. Clear BSS Section: It zeroes out variables in the BSS section. + +5. Disable Interrupts: It disables FIQ and IRQ interrupts and switches the processor to SVC32 mode. + +6. Set Timer Frequency: It sets the timer frequency to 24M. + +7. Call the main Function: It jumps to the main function to execute the main logic. + +## eabi_compat.c + +This code snippet appears to be providing implementations for the functions `abort`, `raise`, and `__aeabi_unwind_cpp_pr0`. Here's a breakdown of their functionalities: + +1. `void abort(void)`: This function creates an infinite loop, causing the program to hang indefinitely. It is typically used to indicate a critical error or unrecoverable condition in a program. + +2. `int raise(int signum)`: This function is a placeholder and always returns 0. In standard C, this function is used to raise a signal and initiate the corresponding signal handler. However, in this implementation, it does nothing and simply returns 0. + +3. `void __aeabi_unwind_cpp_pr0(void)`: This is a dummy function that serves as a placeholder to avoid linker complaints. Its purpose is to satisfy the linker when using C++ exceptions and unwinding, but it does not contain any actual functionality. diff --git a/board/bingpi-m1/board.c b/board/bingpi-m1/board.c new file mode 100644 index 00000000..c4b1ed95 --- /dev/null +++ b/board/bingpi-m1/board.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +sunxi_serial_t uart_dbg = { + .base = SUNXI_UART0_BASE, + .id = 0, + .gpio_tx = {GPIO_PIN(GPIO_PORTH, 9), GPIO_PERIPH_MUX5}, + .gpio_rx = {GPIO_PIN(GPIO_PORTH, 10), GPIO_PERIPH_MUX5}, +}; + +void clean_syterkit_data(void) { + /* Disable MMU, data cache, instruction cache, interrupts */ + arm32_mmu_disable(); + printk(LOG_LEVEL_INFO, "disable mmu ok...\n"); + arm32_dcache_disable(); + printk(LOG_LEVEL_INFO, "disable dcache ok...\n"); + arm32_icache_disable(); + printk(LOG_LEVEL_INFO, "disable icache ok...\n"); + arm32_interrupt_disable(); + printk(LOG_LEVEL_INFO, "free interrupt ok...\n"); +} + +void sunxi_serial_init_v3s(sunxi_serial_t *uart) { + uint32_t addr; + uint32_t val; + + /* Open the clock gate for uart */ + addr = CCU_BASE + CCU_BUS_CLK_GATE3; + val = read32(addr); + val |= 1 << uart->id; + write32(addr, val); + + /* Deassert USART reset */ + addr = CCU_BASE + CCU_BUS_SOFT_RST4; + val = read32(addr); + val |= 1 << (16 + uart->id); + write32(addr, val); + + /* Config USART to 115200-8-1-0 */ + addr = uart->base; + write32(addr + 0x04, 0x0); + write32(addr + 0x08, 0xf7); + write32(addr + 0x10, 0x0); + val = read32(addr + 0x0c); + val |= (1 << 7); + write32(addr + 0x0c, val); + write32(addr + 0x00, 0xd & 0xff); + write32(addr + 0x04, (0xd >> 8) & 0xff); + val = read32(addr + 0x0c); + val &= ~(1 << 7); + write32(addr + 0x0c, val); + val = read32(addr + 0x0c); + val &= ~0x1f; + val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); + write32(addr + 0x0c, val); + + /* Config uart TXD and RXD pins */ + sunxi_gpio_init(uart->gpio_tx.pin, uart->gpio_tx.mux); + sunxi_gpio_init(uart->gpio_rx.pin, uart->gpio_rx.mux); +} \ No newline at end of file diff --git a/board/bingpi-m1/eabi_compat.c b/board/bingpi-m1/eabi_compat.c new file mode 100644 index 00000000..93303d89 --- /dev/null +++ b/board/bingpi-m1/eabi_compat.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +void abort(void) { + while (1) + ; +} + +int raise(int signum) { + return 0; +} + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) { +} \ No newline at end of file diff --git a/board/bingpi-m1/hello_world/CMakeLists.txt b/board/bingpi-m1/hello_world/CMakeLists.txt new file mode 100644 index 00000000..b5ce1ea5 --- /dev/null +++ b/board/bingpi-m1/hello_world/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(helloworld + main.c +) \ No newline at end of file diff --git a/board/bingpi-m1/hello_world/main.c b/board/bingpi-m1/hello_world/main.c new file mode 100644 index 00000000..b4c499d7 --- /dev/null +++ b/board/bingpi-m1/hello_world/main.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init_v3s(&uart_dbg); + + sunxi_clk_init(); + + printk(LOG_LEVEL_INFO, "Hello World!\n"); + + return 0; +} \ No newline at end of file diff --git a/board/bingpi-m1/start.S b/board/bingpi-m1/start.S new file mode 100644 index 00000000..cfe9c72e --- /dev/null +++ b/board/bingpi-m1/start.S @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#define ARMV7_USR_MODE 0x10 +#define ARMV7_FIQ_MODE 0x11 +#define ARMV7_IRQ_MODE 0x12 +#define ARMV7_SVC_MODE 0x13 +#define ARMV7_MON_MODE 0x16 +#define ARMV7_ABT_MODE 0x17 +#define ARMV7_UND_MODE 0x1b +#define ARMV7_SYSTEM_MODE 0x1f +#define ARMV7_MODE_MASK 0x1f +#define ARMV7_FIQ_MASK 0x40 +#define ARMV7_IRQ_MASK 0x80 + +.arm +.globl reset +.text + +reset: + /* Boot head information for BROM */ + .long 0xea000016 + .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' + .long 0x12345678 /* checksum */ + .long __spl_size /* spl size */ + .long 0x30 /* boot header size */ + .long 0x30303033 /* boot header version */ + .long 0x00020000 /* return value */ + .long 0x00028000 /* run address */ + .long 0x0 /* eGON version */ + .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ + .byte 0x34, 0x2e, 0x30, 0x00 + + /* + * The actual reset code + */ + mrs r0, cpsr + bic r0, r0, #ARMV7_MODE_MASK + orr r0, r0, #ARMV7_SVC_MODE + orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) + bic r0, r0, #(1<<9) @set little-endian + msr cpsr_c, r0 + + /* Set vector base address register */ + + ldr r0, =_vector + mcr p15, 0, r0, c12, c0, 0 + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 13) + mcr p15, 0, r0, c1, c0, 0 + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache + mcr p15, 0, r0, c1, c0, 0 + + /* Enable neon/vfp unit */ + mrc p15, 0, r0, c1, c0, 2 + orr r0, r0, #(0xf << 20) + mcr p15, 0, r0, c1, c0, 2 + isb + mov r0, #0x40000000 + vmsr fpexc, r0 + + /* Set stack pointer */ + ldr sp, =__stack_srv_end + + bl clear_bss + + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + + @set cntfrq to 24M + ldr r0, =24000000 + mcr p15, 0, r0, c14, c0, 0 + + bl set_timer_count + + bl main + +clear_bss: + ldr r0, =_sbss + ldr r1, =_ebss + mov r2, #0 + +clbss_1: + stmia r0!, {r2} + cmp r0, r1 + blt clbss_1 + + mov pc, lr + +_vector: + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction + +_software_interrupt: + .word software_interrupt + +_prefetch_abort: + .word prefetch_abort + +_data_abort: + .word data_abort + +_not_used: + .word not_used + +_irq: + .word irq + +_fiq: + .word fiq + +.macro save_regs + str lr, [sp, #-4] + mrs lr, spsr_all + str lr, [sp, #-8] + str r1, [sp, #-12] + str r0, [sp, #-16] + mov r0, sp + cps #0x13 + ldr r1, [r0, #-4] + str r1, [sp, #-4]! + ldr r1, [r0, #-8] + str r1, [sp, #-(4 * 16)] + ldr r1, [r0, #-12] + ldr r0, [r0, #-16] + stmdb sp, {r0 - r14}^ + sub sp, sp, #(4 * 16) + ldr r4, [sp] + and r0, r4, #0x1f + cmp r0, #0x10 + beq 10f + cmp r0, #0x13 + beq 11f + b . +11: add r1, sp, #(4 * 17) + str r1, [sp, #(4 * 14)] + str lr, [sp, #(4 * 15)] +10: add r1, sp, #(4 * 17) + str r1, [sp, #-4]! + mov r0, sp +.endm + +.macro restore_regs + mov r12, sp + ldr sp, [r12], #4 + ldr r1, [r12], #4 + msr spsr_cxsf, r1 + and r0, r1, #0x1f + cmp r0, #0x10 + beq 20f + cmp r0, #0x13 + beq 21f + b . +20: ldr lr, [r12, #(4 * 15)] + ldmia r12, {r0 - r14}^ + movs pc, lr +21: ldm r12, {r0 - r15}^ + mov r0, r0 +.endm + + /* + * Exception handlers + */ + .align 5 +undefined_instruction: + sub lr, lr, #4 + save_regs + bl arm32_do_undefined_instruction + restore_regs + + .align 5 +software_interrupt: + sub lr, lr, #4 + save_regs + bl arm32_do_software_interrupt + restore_regs + + .align 5 +prefetch_abort: + sub lr, lr, #4 + save_regs + bl arm32_do_prefetch_abort + restore_regs + + .align 5 +data_abort: + sub lr, lr, #8 + save_regs + bl arm32_do_data_abort + restore_regs + + .align 5 +not_used: + b . + + .align 5 +irq: + sub lr, lr, #4 + save_regs + bl arm32_do_irq + restore_regs + + .align 5 +fiq: + sub lr, lr, #4 + save_regs + bl arm32_do_fiq + restore_regs diff --git a/cmake/board/bingpi-m1.cmake b/cmake/board/bingpi-m1.cmake new file mode 100644 index 00000000..0ae337bb --- /dev/null +++ b/cmake/board/bingpi-m1.cmake @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(CONFIG_ARCH_ARM32 True) +set(CONFIG_CHIP_SUN8IW8 True) +set(CONFIG_BOARD_BINGPI-M1 True) +set(CONFIG_CHIP_GPIO_V1 True) +set(CONFIG_CHIP_CLK_V1 True) + +add_definitions(-DCONFIG_CHIP_SUN8IW8 -DCONFIG_CHIP_CLK_V1) + +# Options + +# By setting ENABLE_HARDFP to ON, it indicates that the project is configured +# to utilize hard floating-point operations when applicable. This can be beneficial +# in scenarios where performance gains from hardware acceleration are desired. +option(ENABLE_HARDFP "Enable hardware floating-point operations" ON) + +# Set the cross-compile toolchain +set(CROSS_COMPILE "arm-none-eabi-") +set(CROSS_COMPILE ${CROSS_COMPILE} CACHE STRING "CROSS_COMPILE Toolchain") + +# Set the C and C++ compilers +set(CMAKE_C_COMPILER "${CROSS_COMPILE}gcc") +set(CMAKE_CXX_COMPILER "${CROSS_COMPILE}g++") + +# Configure compiler flags based on ENABLE_HARDFP option +if(ENABLE_HARDFP) + set(CMAKE_COMMON_FLAGS "-nostdlib -g -ggdb -O3 -mcpu=cortex-a7 -mthumb-interwork -mthumb -mno-unaligned-access -mfpu=neon-vfpv4 -mfloat-abi=hard") +else() + set(CMAKE_COMMON_FLAGS "-nostdlib -g -ggdb -O3 -mcpu=cortex-a7 -mthumb-interwork -mthumb -mno-unaligned-access -mfpu=neon-vfpv4 -mfloat-abi=softfp") +endif() + +# Disable specific warning flags for C and C++ compilers +set(CMAKE_C_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers") +set(CMAKE_CXX_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast") + +set(ARCH_BIN_START_ADDRESS "0x00020000") +set(ARCH_BIN_SRAM_LENGTH "128K") + +set(ARCH_FEL_START_ADDRESS "0x00028000") +set(ARCH_FEL_SRAM_LENGTH "100K") \ No newline at end of file diff --git a/include/drivers/reg/reg-ncat.h b/include/drivers/reg/reg-ncat.h index baf833ff..235fcfdb 100644 --- a/include/drivers/reg/reg-ncat.h +++ b/include/drivers/reg/reg-ncat.h @@ -15,6 +15,8 @@ extern "C" { #include #elif defined(CONFIG_CHIP_SUN55IW3) #include +#elif defined(CONFIG_CHIP_SUN8IW8) + #include #else #error "Unsupported chip" #endif diff --git a/include/drivers/sun8iw8/reg/reg-ccu.h b/include/drivers/sun8iw8/reg/reg-ccu.h new file mode 100644 index 00000000..c2a74cde --- /dev/null +++ b/include/drivers/sun8iw8/reg/reg-ccu.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __SUN8IW8_REG_CCU_H__ +#define __SUN8IW8_REG_CCU_H__ + +#include + +#define CCU_BASE (0x01c20000) + +#define CCU_PLL_CPU_CTRL (0x000) +#define CCU_PLL_AUDIO_CTRL (0x008) +#define CCU_PLL_VIDEO_CTRL (0x010) +#define CCU_PLL_VE_CTRL (0x018) +#define CCU_PLL_DDR0_CTRL (0x020) +#define CCU_PLL_PERIPH0_CTRL (0x028) +#define CCU_PLL_ISP_CTRL (0x02c) +#define CCU_PLL_PERIPH1_CTRL (0x044) +#define CCU_PLL_DDR1_CTRL (0x04c) + +#define CCU_CPU_AXI_CFG (0x050) +#define CCU_AHB_APB0_CFG (0x054) +#define CCU_APB1_CFG (0x058) +#define CCU_AHB2_CFG (0x05c) + +#define CCU_BUS_CLK_GATE0 (0x060) +#define CCU_BUS_CLK_GATE1 (0x064) +#define CCU_BUS_CLK_GATE2 (0x068) +#define CCU_BUS_CLK_GATE3 (0x06c) +#define CCU_BUS_CLK_GATE4 (0x070) + +#define CCU_SDMMC0_CLK (0x088) +#define CCU_SDMMC1_CLK (0x08c) +#define CCU_SDMMC2_CLK (0x090) +#define CCU_CE_CLK (0x09c) +#define CCU_SPI0_CLK (0x0a0) +#define CCU_USBPHY_CFG (0x0cc) +#define CCU_DRAM_CFG (0x0f4) +#define CCU_PLL_DDR1_CFG (0x0f8) +#define CCU_MBUS_RST (0x0fc) +#define CCU_DRAM_CLK_GATE (0x100) +#define CCU_TCON_CLK (0x118) +#define CCU_CSI_MISC_CLK (0x130) +#define CCU_CSI_CLK (0x134) +#define CCU_VE_CLK (0x13c) +#define CCU_AC_DIG_CLK (0x140) +#define CCU_AVS_CLK (0x144) +#define CCU_MBUS_CLK (0x15c) +#define CCU_MIPI_CSI_CLK (0x16c) + +#define CCU_PLL_STABLE_TIME0 (0x200) +#define CCU_PLL_STABLE_TIME1 (0x204) +#define CCU_PLL_CPU_BIAS (0x220) +#define CCU_PLL_AUDIO_BIAS (0x224) +#define CCU_PLL_VIDEO_BIAS (0x228) +#define CCU_PLL_VE_BIAS (0x22c) +#define CCU_PLL_DDR0_BIAS (0x230) +#define CCU_PLL_PERIPH0_BIAS (0x234) +#define CCU_PLL_ISP_BIAS (0x238) +#define CCU_PLL_PERIPH1_BIAS (0x244) +#define CCU_PLL_DDR1_BIAS (0x24C) +#define CCU_PLL_CPU_TUN (0x250) +#define CCU_PLL_DDR0_TUN (0x260) +#define CCU_PLL_CPU_PAT (0x280) +#define CCU_PLL_AUDIO_PAT (0x284) +#define CCU_PLL_VIDEO_PAT (0x288) +#define CCU_PLL_VE_PAT (0x28c) +#define CCU_PLL_DDR0_PAT (0x290) +#define CCU_PLL_ISP_PAT (0x298) +#define CCU_PLL_PERIPH1_PAT (0x2a4) +#define CCU_PLL_DDR1_PAT0 (0x2ac) +#define CCU_PLL_DDR1_PAT1 (0x2b0) + +#define CCU_BUS_SOFT_RST0 (0x2c0) +#define CCU_BUS_SOFT_RST1 (0x2c4) +#define CCU_BUS_SOFT_RST2 (0x2c8) +#define CCU_BUS_SOFT_RST3 (0x2d0) +#define CCU_BUS_SOFT_RST4 (0x2d8) + +#define CCU_PS_CTRL (0x300) +#define CCU_PS_CNT (0x304) + +#endif// __SUN8IW8_REG_CCU_H__ diff --git a/include/drivers/sun8iw8/reg/reg-dram.h b/include/drivers/sun8iw8/reg/reg-dram.h new file mode 100644 index 00000000..3e844b15 --- /dev/null +++ b/include/drivers/sun8iw8/reg/reg-dram.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __SUN8IW8_REG_DRAM_H__ +#define __SUN8IW8_REG_DRAM_H__ + +#define DRAM_COM_BASE (0x01c62000) +#define DRAM_CTL_BASE (0x01c63000) + +#define MCTL_CR_BL8 (0x4 << 20) +#define MCTL_CR_1T (0x1 << 19) +#define MCTL_CR_2T (0x0 << 19) +#define MCTL_CR_LPDDR3 (0x7 << 16) +#define MCTL_CR_LPDDR2 (0x6 << 16) +#define MCTL_CR_DDR3 (0x3 << 16) +#define MCTL_CR_DDR2 (0x2 << 16) +#define MCTL_CR_SEQUENTIAL (0x1 << 15) +#define MCTL_CR_INTERLEAVED (0x0 << 15) +#define MCTL_CR_32BIT (0x1 << 12) +#define MCTL_CR_16BIT (0x0 << 12) +#define MCTL_CR_BUS_WIDTH(x) ((x) == 32 ? MCTL_CR_32BIT : MCTL_CR_16BIT) +#define MCTL_CR_PAGE_SIZE(x) ((gfls(x) - 4) << 8) +#define MCTL_CR_ROW_BITS(x) (((x) -1) << 4) +#define MCTL_CR_EIGHT_BANKS (0x1 << 2) +#define MCTL_CR_FOUR_BANKS (0x0 << 2) +#define MCTL_CR_DUAL_RANK (0x1 << 0) +#define MCTL_CR_SINGLE_RANK (0x0 << 0) + +#define DRAMTMG0_TWTP(x) ((x) << 24) +#define DRAMTMG0_TFAW(x) ((x) << 16) +#define DRAMTMG0_TRAS_MAX(x) ((x) << 8) +#define DRAMTMG0_TRAS(x) ((x) << 0) + +#define DRAMTMG1_TXP(x) ((x) << 16) +#define DRAMTMG1_TRTP(x) ((x) << 8) +#define DRAMTMG1_TRC(x) ((x) << 0) + +#define DRAMTMG2_TCWL(x) ((x) << 24) +#define DRAMTMG2_TCL(x) ((x) << 16) +#define DRAMTMG2_TRD2WR(x) ((x) << 8) +#define DRAMTMG2_TWR2RD(x) ((x) << 0) + +#define DRAMTMG3_TMRW(x) ((x) << 16) +#define DRAMTMG3_TMRD(x) ((x) << 12) +#define DRAMTMG3_TMOD(x) ((x) << 0) + +#define DRAMTMG4_TRCD(x) ((x) << 24) +#define DRAMTMG4_TCCD(x) ((x) << 16) +#define DRAMTMG4_TRRD(x) ((x) << 8) +#define DRAMTMG4_TRP(x) ((x) << 0) + +#define DRAMTMG5_TCKSRX(x) ((x) << 24) +#define DRAMTMG5_TCKSRE(x) ((x) << 16) +#define DRAMTMG5_TCKESR(x) ((x) << 8) +#define DRAMTMG5_TCKE(x) ((x) << 0) + +#define PTR3_TDINIT1(x) ((x) << 20) +#define PTR3_TDINIT0(x) ((x) << 0) + +#define PTR4_TDINIT3(x) ((x) << 20) +#define PTR4_TDINIT2(x) ((x) << 0) + +#define RFSHTMG_TREFI(x) ((x) << 16) +#define RFSHTMG_TRFC(x) ((x) << 0) + +#define PIR_CLRSR (0x1 << 27) /* Clear status registers */ +#define PIR_QSGATE (0x1 << 10) /* Read DQS gate training */ +#define PIR_DRAMINIT (0x1 << 8) /* DRAM initialization */ +#define PIR_DRAMRST (0x1 << 7) /* DRAM reset */ +#define PIR_PHYRST (0x1 << 6) /* PHY reset */ +#define PIR_DCAL (0x1 << 5) /* DDL calibration */ +#define PIR_PLLINIT (0x1 << 4) /* PLL initialization */ +#define PIR_ZCAL (0x1 << 1) /* ZQ calibration */ +#define PIR_INIT (0x1 << 0) /* PHY initialization trigger */ +#define PGSR_INIT_DONE (0x1 << 0) /* PHY init done */ +#define ZQCR_PWRDOWN (0x1 << 31) /* ZQ power down */ + +#define DATX_IOCR_DQ(x) (x) +#define DATX_IOCR_DM (8) +#define DATX_IOCR_DQS (9) +#define DATX_IOCR_DQSN (10) + +#define DATX_IOCR_WRITE_DELAY(x) ((x) << 8) +#define DATX_IOCR_READ_DELAY(x) ((x) << 0) + +#endif /* __SUN8IW8_REG_DRAM_H__ */ \ No newline at end of file diff --git a/include/drivers/sun8iw8/reg/reg-ncat.h b/include/drivers/sun8iw8/reg/reg-ncat.h new file mode 100644 index 00000000..f247ed3a --- /dev/null +++ b/include/drivers/sun8iw8/reg/reg-ncat.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __SUN8IW8_REG_NCAT_H__ +#define __SUN8IW8_REG_NCAT_H__ + +#define SUNXI_CE_BASE (0x01c15000) +#define SUNXI_SS_BASE SUNXI_CE_BASE +//sys ctrl +#define SUNXI_SYSCRL_BASE (0x01c00000) +#define SUNXI_CCM_BASE (0x01c20000) +#define SUNXI_DMA_BASE (0x01c02000) +#define SUNXI_MSGBOX_BASE (0X01C17000) +#define SUNXI_SPINLOCK_BASE (0X01C18000) +#define SUNXI_HSTMR_BASE (0x01c60000) + +#define SUNXI_SMC_BASE (0x01c1e000) +#define SUNXI_TIMER_BASE (0x01c20c00) + +#define SUNXI_PIO_BASE (0x01c20800) +#define SUNXI_GIC_BASE (0x01c81000) + +// storage +#define SUNXI_DRAMCTL0_BASE (0x01c63000) +#define SUNXI_NFC_BASE (0x01c03000) +#define SUNXI_SMHC0_BASE (0x01c0f000) +#define SUNXI_SMHC1_BASE (0x01c10000) +#define SUNXI_SMHC2_BASE (0x01c11000) + +// noraml +#define SUNXI_UART0_BASE (0x01c28000) +#define SUNXI_UART1_BASE (0x01c28400) +#define SUNXI_UART2_BASE (0x01c28800) +#define SUNXI_UART3_BASE (0x01c28c00) +#define SUNXI_UART4_BASE (0x01c29000) + +#define SUNXI_RTWI_BASE (0x01c2ac00) +#define SUNXI_TWI0_BASE (0x01c2ac00) +#define SUNXI_TWI1_BASE (0x01c2b000) +#define SUNXI_TWI2_BASE (0x01c2b400) +#define SUNXI_TWI3_BASE (0x01c2b800) + +#define SUNXI_SPI0_BASE (0x01c68000) + +#define SUNXI_RPRCM_BASE (0x01f01400) +#define SUNXI_RTWI_BRG_REG (SUNXI_RPRCM_BASE + 0x019c) +#define SUNXI_RPIO_BASE (0X01F02C00) +#define SUNXI_RTC_BASE (0x01c20400) +#define SUNXI_RTC_DATA_BASE (SUNXI_RTC_BASE + 0x100) +#define GPIO_POW_MODE_REG (0x0340) + +/* +* Because the platform uses a very old clock framework, +* the following register configuration is only suitable +* for the new driver, and is not practical. +*/ +#define CCU_UART_BGR_REG (0x0) +#define CCU_SPI0_CLK_REG (0x0) +#define CCU_SPI_BGR_REG (0x0) + +#endif// __SUN8IW8_REG_NCAT_H__ \ No newline at end of file diff --git a/include/drivers/sun8iw8/reg/reg-smhc.h b/include/drivers/sun8iw8/reg/reg-smhc.h new file mode 100644 index 00000000..3e190279 --- /dev/null +++ b/include/drivers/sun8iw8/reg/reg-smhc.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __REG_SMHC_H__ +#define __REG_SMHC_H__ + +/* + * Global control register bits + */ +#define SMHC_GCTRL_SOFT_RESET (1 << 0) +#define SMHC_GCTRL_FIFO_RESET (1 << 1) +#define SMHC_GCTRL_DMA_RESET (1 << 2) +#define SMHC_GCTRL_INTERRUPT_ENABLE (1 << 4) +#define SMHC_GCTRL_DMA_ENABLE (1 << 5) +#define SMHC_GCTRL_DEBOUNCE_ENABLE (1 << 8) +#define SMHC_GCTRL_POSEDGE_LATCH_DATA (1 << 9) +#define SMHC_GCTRL_DDR_MODE (1 << 10) +#define SMHC_GCTRL_MEMORY_ACCESS_DONE (1 << 29) +#define SMHC_GCTRL_ACCESS_DONE_DIRECT (1 << 30) +#define SMHC_GCTRL_ACCESS_BY_AHB (1 << 31) +#define SMHC_GCTRL_ACCESS_BY_DMA (0 << 31) +#define SMHC_GCTRL_HARDWARE_RESET \ + (SMHC_GCTRL_SOFT_RESET | SMHC_GCTRL_FIFO_RESET | SMHC_GCTRL_DMA_RESET) + +/* + * Clock control bits + */ +#define SMHC_CLKCR_MASK_D0 (1 << 31) +#define SMHC_CLKCR_CARD_CLOCK_ON (1 << 16) +#define SMHC_CLKCR_LOW_POWER_ON (1 << 17) +#define SMHC_CLKCR_CLOCK_DIV(n) ((n - 1) & 0xff) + +/* + * Bus width + */ +#define SMHC_WIDTH_1BIT (0) +#define SMHC_WIDTH_4BIT (1) + +/* + * Smc command bits + */ +#define SMHC_CMD_RESP_EXPIRE (1 << 6) +#define SMHC_CMD_LONG_RESPONSE (1 << 7) +#define SMHC_CMD_CHECK_RESPONSE_CRC (1 << 8) +#define SMHC_CMD_DATA_EXPIRE (1 << 9) +#define SMHC_CMD_WRITE (1 << 10) +#define SMHC_CMD_SEQUENCE_MODE (1 << 11) +#define SMHC_CMD_SEND_AUTO_STOP (1 << 12) +#define SMHC_CMD_WAIT_PRE_OVER (1 << 13) +#define SMHC_CMD_STOP_ABORT_CMD (1 << 14) +#define SMHC_CMD_SEND_INIT_SEQUENCE (1 << 15) +#define SMHC_CMD_UPCLK_ONLY (1 << 21) +#define SMHC_CMD_READ_CEATA_DEV (1 << 22) +#define SMHC_CMD_CCS_EXPIRE (1 << 23) +#define SMHC_CMD_ENABLE_BIT_BOOT (1 << 24) +#define SMHC_CMD_ALT_BOOT_OPTIONS (1 << 25) +#define SMHC_CMD_BOOT_ACK_EXPIRE (1 << 26) +#define SMHC_CMD_BOOT_ABORT (1 << 27) +#define SMHC_CMD_VOLTAGE_SWITCH (1 << 28) +#define SMHC_CMD_USE_HOLD_REGISTER (1 << 29) +#define SMHC_CMD_START (1 << 31) + +/* + * Interrupt bits + */ +#define SMHC_RINT_RESP_ERROR (0x1 << 1) +#define SMHC_RINT_COMMAND_DONE (0x1 << 2) +#define SMHC_RINT_DATA_OVER (0x1 << 3) +#define SMHC_RINT_TX_DATA_REQUEST (0x1 << 4) +#define SMHC_RINT_RX_DATA_REQUEST (0x1 << 5) +#define SMHC_RINT_RESP_CRC_ERROR (0x1 << 6) +#define SMHC_RINT_DATA_CRC_ERROR (0x1 << 7) +#define SMHC_RINT_RESP_TIMEOUT (0x1 << 8) +#define SMHC_RINT_DATA_TIMEOUT (0x1 << 9) +#define SMHC_RINT_VOLTAGE_CHANGE_DONE (0x1 << 10) +#define SMHC_RINT_FIFO_RUN_ERROR (0x1 << 11) +#define SMHC_RINT_HARD_WARE_LOCKED (0x1 << 12) +#define SMHC_RINT_START_BIT_ERROR (0x1 << 13) +#define SMHC_RINT_AUTO_COMMAND_DONE (0x1 << 14) +#define SMHC_RINT_END_BIT_ERROR (0x1 << 15) +#define SMHC_RINT_SDIO_INTERRUPT (0x1 << 16) +#define SMHC_RINT_CARD_INSERT (0x1 << 30) +#define SMHC_RINT_CARD_REMOVE (0x1 << 31) +#define SMHC_RINT_INTERRUPT_ERROR_BIT \ + (SMHC_RINT_RESP_ERROR | SMHC_RINT_RESP_CRC_ERROR | \ + SMHC_RINT_DATA_CRC_ERROR | SMHC_RINT_RESP_TIMEOUT | \ + SMHC_RINT_DATA_TIMEOUT | SMHC_RINT_VOLTAGE_CHANGE_DONE | \ + SMHC_RINT_FIFO_RUN_ERROR | SMHC_RINT_HARD_WARE_LOCKED | \ + SMHC_RINT_START_BIT_ERROR | SMHC_RINT_END_BIT_ERROR) /* 0xbfc2 */ +#define SMHC_RINT_INTERRUPT_DONE_BIT \ + (SMHC_RINT_AUTO_COMMAND_DONE | SMHC_RINT_DATA_OVER | \ + SMHC_RINT_COMMAND_DONE | SMHC_RINT_VOLTAGE_CHANGE_DONE) + +/* + * Status + */ +#define SMHC_STATUS_RXWL_FLAG (1 << 0) +#define SMHC_STATUS_TXWL_FLAG (1 << 1) +#define SMHC_STATUS_FIFO_EMPTY (1 << 2) +#define SMHC_STATUS_FIFO_FULL (1 << 3) +#define SMHC_STATUS_CARD_PRESENT (1 << 8) +#define SMHC_STATUS_CARD_DATA_BUSY (1 << 9) +#define SMHC_STATUS_DATA_FSM_BUSY (1 << 10) +#define SMHC_STATUS_DMA_REQUEST (1 << 31) +#define SMHC_STATUS_FIFO_SIZE (16) +#define SMHC_STATUS_FIFO_LEVEL(x) (((x) >> 17) & 0x3fff) + +/* IDMA controller bus mod bit field */ +#define SMHC_IDMAC_SOFT_RESET BIT(0) +#define SMHC_IDMAC_FIX_BURST BIT(1) +#define SMHC_IDMAC_IDMA_ON BIT(7) +#define SMHC_IDMAC_REFETCH_DES BIT(31) + +/* IDMA status bit field */ +#define SMHC_IDMAC_TRANSMIT_INTERRUPT BIT(0) +#define SMHC_IDMAC_RECEIVE_INTERRUPT BIT(1) +#define SMHC_IDMAC_FATAL_BUS_ERROR BIT(2) +#define SMHC_IDMAC_DESTINATION_INVALID BIT(4) +#define SMHC_IDMAC_CARD_ERROR_SUM BIT(5) +#define SMHC_IDMAC_NORMAL_INTERRUPT_SUM BIT(8) +#define SMHC_IDMAC_ABNORMAL_INTERRUPT_SUM BIT(9) +#define SMHC_IDMAC_HOST_ABORT_INTERRUPT BIT(10) +#define SMHC_IDMAC_IDLE (0 << 13) +#define SMHC_IDMAC_SUSPEND (1 << 13) +#define SMHC_IDMAC_DESC_READ (2 << 13) +#define SMHC_IDMAC_DESC_CHECK (3 << 13) +#define SMHC_IDMAC_READ_REQUEST_WAIT (4 << 13) +#define SMHC_IDMAC_WRITE_REQUEST_WAIT (5 << 13) +#define SMHC_IDMAC_READ (6 << 13) +#define SMHC_IDMAC_WRITE (7 << 13) +#define SMHC_IDMAC_DESC_CLOSE (8 << 13) + +/* + * If the idma-des-size-bits of property is ie 13, bufsize bits are: + * Bits 0-12: buf1 size + * Bits 13-25: buf2 size + * Bits 26-31: not used + * Since we only ever set buf1 size, we can simply store it directly. + */ +#define SMHC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */ +#define SMHC_IDMAC_DES0_LD BIT(2) /* last descriptor */ +#define SMHC_IDMAC_DES0_FD BIT(3) /* first descriptor */ +#define SMHC_IDMAC_DES0_CH BIT(4) /* chain mode */ +#define SMHC_IDMAC_DES0_ER BIT(5) /* end of ring */ +#define SMHC_IDMAC_DES0_CES BIT(30) /* card error summary */ +#define SMHC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */ + +/* +timing mode +0: output and input are both based on [0,1,...,7] pll delay. +1: output and input are both based on phase. +2: output is based on phase, input is based on delay chain except hs400. + input of hs400 is based on delay chain. +3: output is based on phase, input is based on delay chain. +4: output is based on phase, input is based on delay chain. + it also support to use delay chain on data strobe signal. +*/ +#define SUNXI_MMC_TIMING_MODE_0 0U +#define SUNXI_MMC_TIMING_MODE_1 1U +#define SUNXI_MMC_TIMING_MODE_2 2U +#define SUNXI_MMC_TIMING_MODE_3 3U +#define SUNXI_MMC_TIMING_MODE_4 4U +#define SUNXI_MMC_TIMING_MODE_5 5U + +#define MMC_CLK_SAMPLE_POINIT_MODE_0 8U +#define MMC_CLK_SAMPLE_POINIT_MODE_1 3U +#define MMC_CLK_SAMPLE_POINIT_MODE_2 2U +#define MMC_CLK_SAMPLE_POINIT_MODE_2_HS400 64U +#define MMC_CLK_SAMPLE_POINIT_MODE_3 64U +#define MMC_CLK_SAMPLE_POINIT_MODE_4 64U +#define MMC_CLK_SAMPLE_POINIT_MODE_5 64U + +#define TM5_OUT_PH90 (0) +#define TM5_OUT_PH180 (1) +#define TM5_IN_PH90 (0) +#define TM5_IN_PH180 (1) +#define TM5_IN_PH270 (2) +#define TM5_IN_PH0 (3) + +/* delay control */ +#define SDXC_NTDC_START_CAL (1 << 15) +#define SDXC_NTDC_CAL_DONE (1 << 14) +#define SDXC_NTDC_CAL_DLY (0x3F << 8) +#define SDXC_NTDC_ENABLE_DLY (1 << 7) +#define SDXC_NTDC_CFG_DLY (0x3F << 0) +#define SDXC_NTDC_CFG_NEW_DLY (0xF << 0) + +#define DTO_MAX 200 +#define SUNXI_MMC_NTSR_MODE_SEL_NEW (0x1 << 31) + +typedef struct { + volatile uint32_t gctrl; /* (0x00) SMC Global Control Register */ + volatile uint32_t clkcr; /* (0x04) SMC Clock Control Register */ + volatile uint32_t timeout; /* (0x08) SMC Time Out Register */ + volatile uint32_t width; /* (0x0C) SMC Bus Width Register */ + volatile uint32_t blksz; /* (0x10) SMC Block Size Register */ + volatile uint32_t bytecnt; /* (0x14) SMC Byte Count Register */ + volatile uint32_t cmd; /* (0x18) SMC Command Register */ + volatile uint32_t arg; /* (0x1C) SMC Argument Register */ + volatile uint32_t resp0; /* (0x20) SMC Response Register 0 */ + volatile uint32_t resp1; /* (0x24) SMC Response Register 1 */ + volatile uint32_t resp2; /* (0x28) SMC Response Register 2 */ + volatile uint32_t resp3; /* (0x2C) SMC Response Register 3 */ + volatile uint32_t imask; /* (0x30) SMC Interrupt Mask Register */ + volatile uint32_t mint; /* (0x34) SMC Masked Interrupt Status Register */ + volatile uint32_t rint; /* (0x38) SMC Raw Interrupt Status Register */ + volatile uint32_t status; /* (0x3C) SMC Status Register */ + volatile uint32_t + ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Register */ + volatile uint32_t funcsel; /* (0x44) SMC Function Select Register */ + volatile uint32_t cbcr; /* (0x48) SMC CIU Byte Count Register */ + volatile uint32_t bbcr; /* (0x4C) SMC BIU Byte Count Register */ + volatile uint32_t dbgc; /* (0x50) SMC Debug Enable Register */ + volatile uint32_t csdc; /* (0x54) CRC status detect control register*/ + volatile uint32_t a12a; /* (0x58)Auto command 12 argument*/ + volatile uint32_t ntsr; /* (0x5c)SMC2 Newtiming Set Register */ + volatile uint32_t res1[6]; /* (0x60~0x74) */ + volatile uint32_t hwrst; /* (0x78) SMC eMMC Hardware Reset Register */ + volatile uint32_t res2; /* (0x7c) */ + volatile uint32_t dmac; /* (0x80) SMC IDMAC Control Register */ + volatile uint32_t + dlba; /* (0x84) SMC IDMAC Descriptor List Base Address Register */ + volatile uint32_t idst; /* (0x88) SMC IDMAC Status Register */ + volatile uint32_t idie; /* (0x8C) SMC IDMAC Interrupt Enable Register */ + volatile uint32_t chda; /* (0x90) */ + volatile uint32_t cbda; /* (0x94) */ + volatile uint32_t res3[26]; /* (0x98~0xff) */ + volatile uint32_t thldc; /* (0x100) Card Threshold Control Register */ + volatile uint32_t sfc; /* (0x104) Sample Fifo Control Register */ + volatile uint32_t res4[1]; /* (0x10b) */ + volatile uint32_t + dsbd; /* (0x10c) eMMC4.5 DDR Start Bit Detection Control */ + volatile uint32_t res5[12]; /* (0x110~0x13c) */ + volatile uint32_t drv_dl; /* (0x140) Drive Delay Control register*/ + volatile uint32_t samp_dl; /* (0x144) Sample Delay Control register*/ + volatile uint32_t ds_dl; /* (0x148) Data Strobe Delay Control Register */ + volatile uint32_t + ntdc; /* (0x14C) HS400 New Timing Delay Control Register */ + volatile uint32_t res6[4]; /* (0x150~0x15f) */ + volatile uint32_t + skew_dat0_dl; /*(0x160) deskew data0 delay control register*/ + volatile uint32_t + skew_dat1_dl; /*(0x164) deskew data1 delay control register*/ + volatile uint32_t + skew_dat2_dl; /*(0x168) deskew data2 delay control register*/ + volatile uint32_t + skew_dat3_dl; /*(0x16c) deskew data3 delay control register*/ + volatile uint32_t + skew_dat4_dl; /*(0x170) deskew data4 delay control register*/ + volatile uint32_t + skew_dat5_dl; /*(0x174) deskew data5 delay control register*/ + volatile uint32_t + skew_dat6_dl; /*(0x178) deskew data6 delay control register*/ + volatile uint32_t + skew_dat7_dl; /*(0x17c) deskew data7 delay control register*/ + volatile uint32_t skew_ds_dl; /*(0x180) deskew ds delay control register*/ + volatile uint32_t skew_ctrl; /*(0x184) deskew control control register*/ + volatile uint32_t res8[30]; /* (0x188~0x1ff) */ + volatile uint32_t fifo; /* (0x200) SMC FIFO Access Address */ + volatile uint32_t res7[63]; /* (0x201~0x2FF)*/ + volatile uint32_t vers; /* (0x300) SMHC Version Register */ +} sdhci_reg_t; + +#endif // __REG_SMHC_H__ \ No newline at end of file diff --git a/include/drivers/sun8iw8/sys-clk.h b/include/drivers/sun8iw8/sys-clk.h new file mode 100644 index 00000000..02fd7975 --- /dev/null +++ b/include/drivers/sun8iw8/sys-clk.h @@ -0,0 +1,35 @@ +#ifndef __SUN8IW8_CLK_H__ +#define __SUN8IW8_CLK_H__ + +#include "reg/reg-ccu.h" + +/** + * @brief Initialize the global clocks. + * + * This function initializes the global clocks, including PLLs and clock dividers. + */ +void sunxi_clk_init(void); + +/** + * @brief Reset the global clocks. + * + * This function resets all global clocks to their default values. + */ +void sunxi_clk_reset(void); + +/** + * @brief Dump all clock-related register values. + * + * This function prints out all clock-related register values for debugging and observation. + */ +void sunxi_clk_dump(void); + +/** + * @brief Get the clock rate of the PERI1X bus. + * + * @return The clock rate of the PERI1X bus in Hz. + */ +uint32_t sunxi_clk_get_peri1x_rate(); + + +#endif// __SUN8IW8_CLK_H__ \ No newline at end of file diff --git a/include/drivers/sun8iw8/sys-dram.h b/include/drivers/sun8iw8/sys-dram.h new file mode 100644 index 00000000..434352d0 --- /dev/null +++ b/include/drivers/sun8iw8/sys-dram.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __SUN8IW8_SYS_DRAM_H__ +#define __SUN8IW8_SYS_DRAM_H__ + +#include +#include +#include +#include +#include +#include + +#include "reg/reg-dram.h" + +#define SDRAM_BASE (0x40000000) + +enum sunxi_dram_type { + SUNXI_DRAM_TYPE_DDR2 = 2, +}; + +typedef struct __DRAM_PARA { + // normal configuration + uint32_t dram_clk; + uint32_t dram_type;// dram_type DDR2: 2 DDR3: 3 LPDDR2: 6 LPDDR3: 7 DDR3L: 31 + uint32_t dram_zq; // do not need + uint32_t dram_odt_en; + + // control configuration + uint32_t dram_para1; + uint32_t dram_para2; + + // timing configuration + uint32_t dram_mr0; + uint32_t dram_mr1; + uint32_t dram_mr2; + uint32_t dram_mr3; + uint32_t dram_tpr0;// DRAMTMG0 + uint32_t dram_tpr1;// DRAMTMG1 + uint32_t dram_tpr2;// DRAMTMG2 + uint32_t dram_tpr3;// DRAMTMG3 + uint32_t dram_tpr4;// DRAMTMG4 + uint32_t dram_tpr5;// DRAMTMG5 + uint32_t dram_tpr6;// DRAMTMG8 + // reserved for future use + uint32_t dram_tpr7; + uint32_t dram_tpr8; + uint32_t dram_tpr9; + uint32_t dram_tpr10; + uint32_t dram_tpr11; + uint32_t dram_tpr12; + uint32_t dram_tpr13; +} dram_para_t; + +int init_DRAM(int type, dram_para_t *para); + +uint64_t sunxi_dram_init(dram_para_t *para); + +#endif // __SUN8IW8_SYS_DRAM_H__ diff --git a/include/drivers/sun8iw8/sys-sdhci.h b/include/drivers/sun8iw8/sys-sdhci.h new file mode 100644 index 00000000..dcfb3339 --- /dev/null +++ b/include/drivers/sun8iw8/sys-sdhci.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __SDHCI_H__ +#define __SDHCI_H__ + +#include +#include +#include +#include +#include +#include + +#include "reg/reg-smhc.h" +#include "sys-gpio.h" + +#include "log.h" + +typedef enum { + MMC_CLK_400K = 0, + MMC_CLK_25M, + MMC_CLK_50M, + MMC_CLK_50M_DDR, + MMC_CLK_100M, + MMC_CLK_150M, + MMC_CLK_200M +} smhc_clk_t; + +typedef struct { + uint32_t idx; + uint32_t arg; + uint32_t resptype; + uint32_t response[4]; +} sdhci_cmd_t; + +typedef struct { + uint8_t *buf; + uint32_t flag; + uint32_t blksz; + uint32_t blkcnt; +} sdhci_data_t; + +#define SMHC_DES_NUM_SHIFT 12 /* smhc2!! */ +#define SMHC_DES_BUFFER_MAX_LEN (1 << SMHC_DES_NUM_SHIFT) +typedef struct { + uint32_t : 1, dic : 1, /* disable interrupt on completion */ + last_desc : 1, /* 1-this data buffer is the last buffer */ + first_desc : 1, /* 1-data buffer is the first buffer, 0-data buffer contained in the next descriptor is 1st + buffer */ + des_chain : 1, /* 1-the 2nd address in the descriptor is the next descriptor address */ + // end_of_ring : 1, /* 1-last descriptor flag when using dual data buffer in descriptor */ + : 25, err_flag : 1, /* transfer error flag */ + own : 1; /* des owner:1-idma owns it, 0-host owns it */ + + uint32_t data_buf_sz : SMHC_DES_NUM_SHIFT, + data_buf_dummy : (32 - SMHC_DES_NUM_SHIFT); + + uint32_t buf_addr; + uint32_t next_desc_addr; + +} sdhci_idma_desc_t __attribute__((aligned(8))); + +typedef struct { + char *name; + sdhci_reg_t *reg; + uint32_t reset; + + uint32_t voltage; + uint32_t width; + smhc_clk_t clock; + uint32_t pclk; + uint8_t odly[6]; + uint8_t sdly[6]; + + sdhci_idma_desc_t dma_desc[32]; + uint32_t dma_trglvl; + + bool removable; + bool isspi; + + gpio_mux_t gpio_d0; + gpio_mux_t gpio_d1; + gpio_mux_t gpio_d2; + gpio_mux_t gpio_d3; + gpio_mux_t gpio_cmd; + gpio_mux_t gpio_clk; + +} sdhci_t; + +extern sdhci_t sdhci0; + +bool sdhci_reset(sdhci_t *hci); +bool sdhci_set_voltage(sdhci_t *hci, uint32_t voltage); +bool sdhci_set_width(sdhci_t *hci, uint32_t width); +bool sdhci_set_clock(sdhci_t *hci, smhc_clk_t hz); +bool sdhci_transfer(sdhci_t *hci, sdhci_cmd_t *cmd, sdhci_data_t *dat); +int sunxi_sdhci_init(sdhci_t *sdhci); + +#endif /* __SDHCI_H__ */ diff --git a/include/drivers/sun8iw8/sys-sid.h b/include/drivers/sun8iw8/sys-sid.h new file mode 100644 index 00000000..ebbf6200 --- /dev/null +++ b/include/drivers/sun8iw8/sys-sid.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __SUN50IW9_SYS_SID_H__ +#define __SUN50IW9_SYS_SID_H__ + +#include +#include +#include +#include +#include +#include + +#include "log.h" + +#include + +uint32_t syter_efuse_read(uint32_t offset); + +void syter_efuse_write(uint32_t offset, uint32_t value); + +void syter_efuse_dump(void); + +#endif// __SUN50IW9_SYS_SID_H__ \ No newline at end of file diff --git a/include/drivers/sys-clk.h b/include/drivers/sys-clk.h index f4a3dbd1..0815367a 100644 --- a/include/drivers/sys-clk.h +++ b/include/drivers/sys-clk.h @@ -13,6 +13,8 @@ extern "C" { #include #elif defined(CONFIG_CHIP_SUN55IW3) #include +#elif defined(CONFIG_CHIP_SUN8IW8) + #include #else #error "Unsupported chip" #endif diff --git a/include/drivers/sys-dram.h b/include/drivers/sys-dram.h index 9d06050b..abfcf3b3 100644 --- a/include/drivers/sys-dram.h +++ b/include/drivers/sys-dram.h @@ -15,6 +15,8 @@ extern "C" { #include #elif defined(CONFIG_CHIP_SUN55IW3) #include +#elif defined(CONFIG_CHIP_SUN8IW8) + #include #else #error "Unsupported chip" #endif diff --git a/include/drivers/sys-sdhci.h b/include/drivers/sys-sdhci.h index d87b8ea6..49bbc16f 100644 --- a/include/drivers/sys-sdhci.h +++ b/include/drivers/sys-sdhci.h @@ -15,6 +15,8 @@ extern "C" { #include #elif defined(CONFIG_CHIP_SUN55IW3) #include +#elif defined(CONFIG_CHIP_SUN8IW8) + #include #else # error "Unsupported chip" #endif diff --git a/include/drivers/sys-sid.h b/include/drivers/sys-sid.h index aaf54c55..fdf6b08f 100644 --- a/include/drivers/sys-sid.h +++ b/include/drivers/sys-sid.h @@ -15,6 +15,8 @@ extern "C" { #include #elif defined(CONFIG_CHIP_SUN55IW3) #include +#elif defined(CONFIG_CHIP_SUN8IW8) + #include #else #error "Unsupported chip" #endif diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt index d222ac92..4c7fc60d 100644 --- a/src/drivers/CMakeLists.txt +++ b/src/drivers/CMakeLists.txt @@ -6,24 +6,37 @@ elseif(CONFIG_CHIP_SUN50IW9) add_subdirectory(sun50iw9) elseif(CONFIG_CHIP_SUN55IW3) add_subdirectory(sun55iw3) +elseif(CONFIG_CHIP_SUN8IW8) + add_subdirectory(sun8iw8) endif() set(DRIVER_PMU "") +set(COMMON_DRIVER + sys-uart.c + sys-gpio.c +) + if (CONFIG_CHIP_WITHPMU) set(DRIVER_PMU pmu/axp1530.c ) endif() +if (!CONFIG_CHIP_CLK_V1) + set(COMMON_DRIVER + ${COMMON_DRIVER} + sys-rtc.c + sys-spi-nand.c + sys-spi.c + sys-sdcard.c + sys-dma.c + sys-i2c.c + ) +endif() + + add_library(drivers-obj OBJECT - sys-uart.c - sys-gpio.c - sys-rtc.c - sys-spi-nand.c - sys-spi.c - sys-sdcard.c - sys-dma.c - sys-i2c.c + ${COMMON_DRIVER} ${DRIVER_PMU} ) \ No newline at end of file diff --git a/src/drivers/sun8iw8/CMakeLists.txt b/src/drivers/sun8iw8/CMakeLists.txt new file mode 100644 index 00000000..e24926ef --- /dev/null +++ b/src/drivers/sun8iw8/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_library(chip_drivers-obj OBJECT + sys-clk.c + sys-dram.c +) \ No newline at end of file diff --git a/src/drivers/sun8iw8/sys-clk.c b/src/drivers/sun8iw8/sys-clk.c new file mode 100644 index 00000000..3a82939f --- /dev/null +++ b/src/drivers/sun8iw8/sys-clk.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +static void clock_set_pll_cpu(uint32_t clk) { + int p = 0; + int k = 1; + int m = 1; + uint32_t val; + + if (clk > 1152000000) { + k = 2; + } else if (clk > 768000000) { + k = 3; + m = 2; + } + + /* Switch to 24MHz clock while changing cpu pll */ + val = (2 << 0) | (1 << 8) | (1 << 16); + write32(CCU_BASE + CCU_CPU_AXI_CFG, val); + + /* cpu pll rate = ((24000000 * n * k) >> p) / m */ + val = (0x1 << 31); + val |= ((p & 0x3) << 16); + val |= ((((clk / (24000000 * k / m)) - 1) & 0x1f) << 8); + val |= (((k - 1) & 0x3) << 4); + val |= (((m - 1) & 0x3) << 0); + write32(CCU_BASE + CCU_PLL_CPU_CTRL, val); + sdelay(200); + + /* Switch clock source */ + val = (2 << 0) | (1 << 8) | (2 << 16); + write32(CCU_BASE + CCU_CPU_AXI_CFG, val); +} + +void sunxi_clk_init(void) { + clock_set_pll_cpu(1008000000); + + /* pll video - 396MHZ */ + write32(CCU_BASE + CCU_PLL_VIDEO_CTRL, 0x91004107); + + /* pll periph0 - 600MHZ */ + write32(CCU_BASE + CCU_PLL_PERIPH0_CTRL, 0x90041811); + while (!(read32(CCU_BASE + CCU_PLL_PERIPH0_CTRL) & (1 << 28))) + ; + + /* ahb1 = pll periph0 / 3, apb1 = ahb1 / 2 */ + write32(CCU_BASE + CCU_AHB_APB0_CFG, 0x00003180); + + /* mbus = pll periph0 / 4 */ + write32(CCU_BASE + CCU_MBUS_CLK, 0x81000003); +} + +void sunxi_clk_reset(void) { + return; +} + +void sunxi_clk_dump(void) { + return; +} + +uint32_t sunxi_clk_get_peri1x_rate() { + return 0; +} \ No newline at end of file diff --git a/src/drivers/sun8iw8/sys-dram.c b/src/drivers/sun8iw8/sys-dram.c new file mode 100644 index 00000000..b8032561 --- /dev/null +++ b/src/drivers/sun8iw8/sys-dram.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +uint64_t sunxi_dram_init(dram_para_t *para) { + return 0; +} \ No newline at end of file diff --git a/src/drivers/sun8iw8/sys-sid.c b/src/drivers/sun8iw8/sys-sid.c new file mode 100644 index 00000000..db3cecf8 --- /dev/null +++ b/src/drivers/sun8iw8/sys-sid.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "sys-sid.h" + +uint32_t syter_efuse_read(uint32_t offset) { + return 0; +} + +void syter_efuse_write(uint32_t offset, uint32_t value) { +} + +void syter_efuse_dump(void) { +} \ No newline at end of file