├── .DS_Store ├── .build_revision ├── .clang-format ├── .gitignore ├── .vscode ├── .cortex-debug.peripherals.state.json ├── .cortex-debug.registers.state.json ├── c_cpp_properties.json ├── settings.json └── tasks.json ├── Makefile ├── README.md ├── arch ├── .DS_Store ├── arch.mk └── arm32 │ ├── .DS_Store │ ├── include │ ├── arm32.h │ ├── atomic.h │ ├── barrier.h │ ├── endian.h │ ├── limits.h │ └── linkage.h │ ├── mach-t113s3 │ ├── arch_timer.c │ ├── dram.c │ ├── dram.h │ ├── exception.c │ ├── link.ld │ ├── memcpy.S │ ├── reg-ccu.h │ ├── reg-dram.h │ ├── sdmmc.c │ ├── sdmmc.h │ ├── start.S │ ├── sunxi_clk.c │ ├── sunxi_clk.h │ ├── sunxi_dma.c │ ├── sunxi_dma.h │ ├── sunxi_gpio.c │ ├── sunxi_gpio.h │ ├── sunxi_sdhci.c │ ├── sunxi_sdhci.h │ ├── sunxi_spi.c │ ├── sunxi_spi.h │ ├── sunxi_usart.c │ └── sunxi_usart.h │ ├── mach-t113s4 │ ├── arch_timer.c │ ├── dram.c │ ├── dram.h │ ├── exception.c │ ├── link.ld │ ├── memcpy.S │ ├── reg-ccu.h │ ├── reg-dram.h │ ├── sdmmc.c │ ├── sdmmc.h │ ├── start.S │ ├── sunxi_clk.c │ ├── sunxi_clk.h │ ├── sunxi_dma.c │ ├── sunxi_dma.h │ ├── sunxi_gpio.c │ ├── sunxi_gpio.h │ ├── sunxi_sdhci.c │ ├── sunxi_sdhci.h │ ├── sunxi_spi.c │ ├── sunxi_spi.h │ ├── sunxi_usart.c │ └── sunxi_usart.h │ └── mach-v851s │ ├── arch_timer.c │ ├── dram.c │ ├── dram.h │ ├── exception.c │ ├── link.ld │ ├── memcpy.S │ ├── reg-ccu.h │ ├── reg-dram.h │ ├── sdmmc.c │ ├── sdmmc.h │ ├── start.S │ ├── sunxi_clk.c │ ├── sunxi_clk.h │ ├── sunxi_dma.c │ ├── sunxi_dma.h │ ├── sunxi_gpio.c │ ├── sunxi_gpio.h │ ├── sunxi_sdhci.c │ ├── sunxi_sdhci.h │ ├── sunxi_spi.c │ ├── sunxi_spi.h │ ├── sunxi_usart.c │ └── sunxi_usart.h ├── board-v851s.c ├── board.c ├── board.h ├── include ├── io.h ├── string.h └── types.h ├── lib ├── debug.c ├── debug.h ├── fatfs │ ├── diskio.c │ ├── diskio.h │ ├── fatfs.mk │ ├── ff.c │ ├── ff.h │ ├── ffconf.h │ ├── ffsystem.c │ ├── ffunicode.c │ └── media.h ├── fdt.c ├── fdt.h ├── string.c ├── xformat.c └── xformat.h ├── linux-6.0-bootlog.txt ├── linux-6.11-v851s.txt ├── linux └── linux-6.13-rc1-wip.patch ├── main.c ├── main.h └── tools ├── Makefile ├── hooks └── pre-commit └── mksunxi.c /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szemzoa/awboot/395f732a64c9036148ee01e90f4170100264f05b/.DS_Store -------------------------------------------------------------------------------- /.build_revision: -------------------------------------------------------------------------------- 1 | 6160 2 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: Consecutive 7 | AlignConsecutiveDeclarations: Consecutive 8 | AlignConsecutiveMacros: Consecutive 9 | AlignEscapedNewlinesLeft: true 10 | AlignArrayOfStructures: Right 11 | AlignOperands: true 12 | AlignTrailingComments: false 13 | AllowAllParametersOfDeclarationOnNextLine: true 14 | AllowShortBlocksOnASingleLine: false 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortIfStatementsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: Empty 18 | AllowShortLoopsOnASingleLine: false 19 | AlwaysBreakAfterDefinitionReturnType: None 20 | AlwaysBreakAfterReturnType: None 21 | AlwaysBreakBeforeMultilineStrings: false 22 | AlwaysBreakTemplateDeclarations: true 23 | BinPackArguments: true 24 | BinPackParameters: true 25 | BraceWrapping: 26 | AfterClass: true 27 | AfterControlStatement: false 28 | AfterEnum: false 29 | AfterFunction: true 30 | AfterNamespace: true 31 | AfterObjCDeclaration: false 32 | AfterStruct: false 33 | AfterUnion: false 34 | BeforeCatch: true 35 | BeforeElse: false 36 | IndentBraces: false 37 | BreakBeforeBinaryOperators: None 38 | BreakBeforeBraces: Custom 39 | BreakBeforeTernaryOperators: true 40 | BreakConstructorInitializersBeforeComma: false 41 | BreakAfterJavaFieldAnnotations: false 42 | BreakStringLiterals: true 43 | ColumnLimit: 120 44 | CommentPragmas: '^ IWYU pragma:' 45 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 46 | ConstructorInitializerIndentWidth: 4 47 | ContinuationIndentWidth: 4 48 | Cpp11BracedListStyle: true 49 | DerivePointerAlignment: false 50 | DisableFormat: false 51 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 52 | IncludeCategories: 53 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 54 | Priority: 2 55 | - Regex: '^(<|"(gtest|isl|json)/)' 56 | Priority: 3 57 | - Regex: '.*' 58 | Priority: 1 59 | IncludeIsMainRegex: '$' 60 | IndentCaseLabels: true 61 | IndentWidth: 4 62 | IndentWrappedFunctionNames: true 63 | JavaScriptQuotes: Leave 64 | KeepEmptyLinesAtTheStartOfBlocks: false 65 | MacroBlockBegin: '' 66 | MacroBlockEnd: '' 67 | MaxEmptyLinesToKeep: 1 68 | NamespaceIndentation: None 69 | PenaltyBreakBeforeFirstCallParameter: 19 70 | PenaltyBreakComment: 300 71 | PenaltyBreakFirstLessLess: 120 72 | PenaltyBreakString: 1000 73 | PenaltyExcessCharacter: 1000000 74 | PenaltyReturnTypeOnItsOwnLine: 60 75 | PointerAlignment: Right 76 | ReflowComments: true 77 | SortIncludes: false 78 | SpaceAfterCStyleCast: false 79 | SpaceAfterTemplateKeyword: false 80 | SpaceBeforeAssignmentOperators: true 81 | SpaceBeforeParens: ControlStatements 82 | SpaceInEmptyParentheses: false 83 | SpacesBeforeTrailingComments: 1 84 | SpacesInAngles: false 85 | SpacesInContainerLiterals: false 86 | SpacesInCStyleCastParentheses: false 87 | SpacesInParentheses: false 88 | SpacesInSquareBrackets: false 89 | Standard: Cpp11 90 | TabWidth: 4 91 | UseTab: Always 92 | ... 93 | 94 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.d 3 | *.o 4 | *.bin 5 | *.elf 6 | *.map 7 | *.lfs 8 | 9 | build-*/* 10 | 11 | tools/mksunxi 12 | 13 | *boot.img 14 | -------------------------------------------------------------------------------- /.vscode/.cortex-debug.peripherals.state.json: -------------------------------------------------------------------------------- 1 | [{"node":"IPC0.ISCR","expanded":true,"format":0},{"node":"PIOB","expanded":true,"format":0,"pinned":false},{"node":"PIOB.ABCDSR[1]","expanded":true,"format":0},{"node":"PIOC.ABCDSR[1]","expanded":true,"format":0},{"node":"SPI0.CR","expanded":true,"format":0}] -------------------------------------------------------------------------------- /.vscode/.cortex-debug.registers.state.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "cStandard": "gnu99", 9 | "mergeConfigurations": true 10 | } 11 | ], 12 | "version": 4 13 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "makefile.extensionOutputFolder": "./.vscode", 3 | "C_Cpp.default.includePath": [ 4 | "${workspaceFolder}/**" 5 | ], 6 | "cmake.configureOnOpen": true, 7 | "files.exclude": { 8 | "**/*.o": true, 9 | }, 10 | "cortex-debug.variableUseNaturalFormat": true, 11 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build All", 8 | "type": "shell", 9 | "command": "make -j11", 10 | "group": { 11 | "kind": "build", 12 | "isDefault": true 13 | }, 14 | "presentation": { 15 | "reveal": "always", 16 | "panel": "new" 17 | }, 18 | "problemMatcher": { 19 | "owner": "eslint", 20 | "fileLocation": ["relative", "${workspaceRoot}"], 21 | "pattern": { 22 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 23 | "file": 1, 24 | "line": 2, 25 | "column": 3, 26 | "severity": 4, 27 | "message": 5 28 | } 29 | } 30 | }, 31 | { 32 | "label": "Clean All", 33 | "type": "shell", 34 | "command": "make clean", 35 | }, 36 | ] 37 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Target 2 | TARGET := awboot 3 | CROSS_COMPILE ?= arm-none-eabi 4 | 5 | # Log level defaults to info 6 | LOG_LEVEL ?= 30 7 | 8 | SRCS := main.c board.c lib/debug.c lib/xformat.c lib/fdt.c lib/string.c 9 | 10 | INCLUDE_DIRS :=-I . -I include -I lib 11 | LIBS := -lgcc -nostdlib 12 | DEFINES := -DLOG_LEVEL=$(LOG_LEVEL) -DBUILD_REVISION=$(shell cat .build_revision) 13 | 14 | include arch/arch.mk 15 | include lib/fatfs/fatfs.mk 16 | 17 | CFLAGS += -mcpu=cortex-a7 -mthumb-interwork -mthumb -mno-unaligned-access -mfpu=neon-vfpv4 -mfloat-abi=hard 18 | CFLAGS += -ffast-math -ffunction-sections -fdata-sections -Os -std=gnu99 -Wall -Werror -Wno-unused-function -g -MMD $(INCLUDES) $(DEFINES) 19 | 20 | ASFLAGS += $(CFLAGS) 21 | 22 | LDFLAGS += $(CFLAGS) $(LIBS) -Wl,--gc-sections 23 | 24 | STRIP=$(CROSS_COMPILE)-strip 25 | CC=$(CROSS_COMPILE)-gcc 26 | SIZE=$(CROSS_COMPILE)-size 27 | OBJCOPY=$(CROSS_COMPILE)-objcopy 28 | 29 | HOSTCC=gcc 30 | HOSTSTRIP=strip 31 | 32 | MAKE=make 33 | 34 | DTB ?= sun8i-t113-mangopi-dual.dtb 35 | KERNEL ?= zImage 36 | 37 | all: git begin build mkboot 38 | 39 | begin: 40 | @echo "---------------------------------------------------------------" 41 | @echo -n "Compiler version: " 42 | @$(CC) -v 2>&1 | tail -1 43 | 44 | build_revision: 45 | @expr `cat .build_revision` + 1 > .build_revision 46 | 47 | .PHONY: tools git begin build mkboot clean format 48 | .SILENT: 49 | 50 | git: 51 | cp -f tools/hooks/* .git/hooks/ 52 | 53 | build:: build_revision 54 | 55 | # $(1): varient name 56 | # $(2): values to remove from board.h 57 | define VARIENT = 58 | 59 | # Objects 60 | $(1)_OBJ_DIR = build-$(1) 61 | $(1)_BUILD_OBJS = $$(SRCS:%.c=$$($(1)_OBJ_DIR)/%.o) 62 | $(1)_BUILD_OBJSA = $$(ASRCS:%.S=$$($(1)_OBJ_DIR)/%.o) 63 | $(1)_OBJS = $$($(1)_BUILD_OBJSA) $$($(1)_BUILD_OBJS) 64 | 65 | build:: $$($(1)_OBJ_DIR)/$$(TARGET)-boot.elf $$($(1)_OBJ_DIR)/$$(TARGET)-boot.bin $$($(1)_OBJ_DIR)/$$(TARGET)-fel.elf $$($(1)_OBJ_DIR)/$$(TARGET)-fel.bin 66 | 67 | .PRECIOUS : $$($(1)_OBJS) 68 | $$($(1)_OBJ_DIR)/$$(TARGET)-fel.elf: $$($(1)_OBJS) 69 | echo " LD $$@" 70 | $$(CC) -E -P -x c -D__RAM_BASE=0x00030000 ./arch/arm32/mach-t113s3/link.ld > $$($(1)_OBJ_DIR)/link-fel.ld 71 | $$(CC) $$^ -o $$@ -T $$($(1)_OBJ_DIR)/link-fel.ld $$(LDFLAGS) -Wl,-Map,$$($(1)_OBJ_DIR)/$$(TARGET)-fel.map 72 | 73 | $$($(1)_OBJ_DIR)/$$(TARGET)-boot.elf: $$($(1)_OBJS) 74 | echo " LD $$@" 75 | $$(CC) -E -P -x c -D__RAM_BASE=0x00020000 ./arch/arm32/mach-t113s3/link.ld > $$($(1)_OBJ_DIR)/link-boot.ld 76 | $$(CC) $$^ -o $$@ -T $$($(1)_OBJ_DIR)/link-boot.ld $$(LDFLAGS) -Wl,-Map,$$($(1)_OBJ_DIR)/$$(TARGET)-boot.map 77 | 78 | $$($(1)_OBJ_DIR)/$$(TARGET)-fel.bin: $$($(1)_OBJ_DIR)/$$(TARGET)-fel.elf 79 | @echo OBJCOPY $$@ 80 | $$(OBJCOPY) -O binary $$< $$@ 81 | 82 | $$($(1)_OBJ_DIR)/$$(TARGET)-boot.bin: $$($(1)_OBJ_DIR)/$$(TARGET)-boot.elf 83 | @echo OBJCOPY $$@ 84 | $$(OBJCOPY) -O binary $$< $$@ 85 | 86 | $$($(1)_OBJ_DIR)/%.o : %.c 87 | echo " CC $$@" 88 | mkdir -p $$(@D) 89 | $$(CC) $$(CFLAGS) -include $$($(1)_OBJ_DIR)/board.h $$(INCLUDE_DIRS) -c $$< -o $$@ 90 | 91 | $$($(1)_OBJ_DIR)/%.o : %.S 92 | echo " CC $$@" 93 | mkdir -p $$(@D) 94 | $$(CC) $$(ASFLAGS) $$(INCLUDE_DIRS) -c $$< -o $$@ 95 | 96 | $$($(1)_OBJS): $$($(1)_OBJ_DIR)/board.h 97 | 98 | $$($(1)_OBJ_DIR)/board.h: board.h 99 | echo " GEN $$@" 100 | mkdir -p $$(@D) 101 | grep -v "$(2)" >$$@ <$$< 102 | 103 | clean:: 104 | rm -rf $$($(1)_OBJ_DIR) 105 | 106 | -include $$(patsubst %.o,%.d,$$($(1)_OBJS)) 107 | 108 | endef 109 | 110 | # build spi-only image without sd/mmc 111 | $(eval $(call VARIENT,spi,CONFIG_BOOT_SDCARD\|CONFIG_BOOT_MMC)) 112 | 113 | # build sd/mmc only image without spi 114 | $(eval $(call VARIENT,sdmmc,CONFIG_BOOT_SPINAND)) 115 | 116 | # build image with everything 117 | $(eval $(call VARIENT,all,XXXXXXXXX)) 118 | 119 | clean:: 120 | rm -f $(TARGET)-*.bin 121 | rm -f $(TARGET)-*.map 122 | rm -f *.img 123 | rm -f *.d 124 | $(MAKE) -C tools clean 125 | 126 | format: 127 | find . -iname "*.h" -o -iname "*.c" | xargs clang-format --verbose -i 128 | 129 | tools: 130 | $(MAKE) -C tools all 131 | 132 | mkboot: build tools 133 | echo "SPI:" 134 | $(SIZE) build-spi/$(TARGET)-boot.elf 135 | cp -f build-spi/$(TARGET)-boot.bin $(TARGET)-boot-spi.bin 136 | cp -f build-spi/$(TARGET)-boot.bin $(TARGET)-boot-spi-4k.bin 137 | tools/mksunxi $(TARGET)-boot-spi.bin 8192 138 | tools/mksunxi $(TARGET)-boot-spi-4k.bin 8192 4096 139 | 140 | echo "SDMMC:" 141 | $(SIZE) build-sdmmc/$(TARGET)-boot.elf 142 | cp -f build-sdmmc/$(TARGET)-boot.bin $(TARGET)-boot-sd.bin 143 | tools/mksunxi $(TARGET)-boot-sd.bin 512 144 | 145 | echo "ALL:" 146 | $(SIZE) build-all/$(TARGET)-boot.elf 147 | cp -f build-all/$(TARGET)-boot.bin $(TARGET)-boot-all.bin 148 | cp -f build-all/$(TARGET)-boot.bin $(TARGET)-fel.bin 149 | tools/mksunxi $(TARGET)-fel.bin 8192 150 | tools/mksunxi $(TARGET)-boot-all.bin 8192 151 | 152 | spi-boot.img: mkboot 153 | rm -f spi-boot.img 154 | dd if=$(TARGET)-boot-spi.bin of=spi-boot.img bs=2k 155 | dd if=$(TARGET)-boot-spi.bin of=spi-boot.img bs=2k seek=32 # Second copy on page 32 156 | dd if=$(TARGET)-boot-spi.bin of=spi-boot.img bs=2k seek=64 # Third copy on page 64 157 | # dd if=linux/boot/$(DTB) of=spi-boot.img bs=2k seek=128 # DTB on page 128 158 | # dd if=linux/boot/$(KERNEL) of=spi-boot.img bs=2k seek=256 # Kernel on page 256 159 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWBoot 2 | 3 | Small linux bootloader for Allwinner T113-S3 4 | 5 | ## Building 6 | 7 | Run `make LOG_LEVEL=40`. 8 | This will generate the bootloader with a valid EGON header, usable with the xfel tool or BOOTROM 9 | You can change the log level with the LOG_LEVEL argument. Default is 30 (info). 10 | 11 | ## Using 12 | 13 | You will need [xfel](https://github.com/xboot/xfel) for uploading the file to memory or SPI flash. 14 | This it not needed for writing to an SD card. 15 | 16 | ### FEL memory boot: 17 | ``` 18 | xfel write 0x30000 awboot-fel.bin 19 | xfel exec 0x30000 20 | ``` 21 | 22 | ### FEL SPI NOR boot: 23 | ``` 24 | make spi-boot.img 25 | xfel spinor 26 | xfel spinor write 0 spi-boot.img 27 | xfel reset 28 | ``` 29 | 30 | ### FEL SPI NAND boot: 31 | ``` 32 | make spi-boot.img 33 | xfel spi_nand 34 | xfel spi_nand write 0 spi-boot.img 35 | xfel reset 36 | ``` 37 | 38 | ### SD Card boot: 39 | - create an MBR or GPT partition table and a FAT32 partition with an offset of 4MB or more using fdisk. 40 | ``` 41 | sudo fdisk /dev/(your sd device) 42 | ``` 43 | write awboot-boot.bin to sdcard with an offset of: 44 | - MBR: 8KB (sector 16) 45 | - GPT: 128KB (sector 256) 46 | ``` 47 | sudo dd if=awboot-boot-sd.bin of=/dev/(your sd device) bs=1024 seek=8 48 | ``` 49 | - compile (if needed) and copy your `.dtb` file to the FAT partition. 50 | - copy zImage to the FAT partition. 51 | 52 | ### Linux kernel: 53 | WIP kernel from here: https://github.com/smaeul/linux/tree/d1/all 54 | -------------------------------------------------------------------------------- /arch/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szemzoa/awboot/395f732a64c9036148ee01e90f4170100264f05b/arch/.DS_Store -------------------------------------------------------------------------------- /arch/arch.mk: -------------------------------------------------------------------------------- 1 | ARCH := arch 2 | SOC:=$(ARCH)/arm32/mach-t113s3 3 | 4 | INCLUDE_DIRS += -I $(ARCH)/arm32/include -I $(SOC)/include -I $(SOC) -I $(SOC)/mmc 5 | 6 | CFLAGS += -DCOUNTER_FREQUENCY=24000000 7 | 8 | SRCS += $(SOC)/dram.c 9 | SRCS += $(SOC)/sunxi_usart.c 10 | SRCS += $(SOC)/arch_timer.c 11 | SRCS += $(SOC)/sunxi_spi.c 12 | SRCS += $(SOC)/sunxi_dma.c 13 | SRCS += $(SOC)/sunxi_gpio.c 14 | SRCS += $(SOC)/sdmmc.c 15 | SRCS += $(SOC)/sunxi_sdhci.c 16 | SRCS += $(SOC)/sunxi_clk.c 17 | SRCS += $(SOC)/exception.c 18 | 19 | ASRCS += $(SOC)/start.S 20 | ASRCS += $(SOC)/memcpy.S 21 | -------------------------------------------------------------------------------- /arch/arm32/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szemzoa/awboot/395f732a64c9036148ee01e90f4170100264f05b/arch/arm32/.DS_Store -------------------------------------------------------------------------------- /arch/arm32/include/arm32.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_H__ 2 | #define __ARM32_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | static inline uint32_t arm32_read_p15_c1(void) 11 | { 12 | uint32_t value; 13 | 14 | __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0" : "=r"(value) : : "memory"); 15 | 16 | return value; 17 | } 18 | 19 | static inline void arm32_write_p15_c1(uint32_t value) 20 | { 21 | __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0" : : "r"(value) : "memory"); 22 | arm32_read_p15_c1(); 23 | } 24 | 25 | static inline void arm32_interrupt_enable(void) 26 | { 27 | uint32_t tmp; 28 | 29 | __asm__ __volatile__("mrs %0, cpsr\n" 30 | "bic %0, %0, #(1<<7)\n" 31 | "msr cpsr_cxsf, %0" 32 | : "=r"(tmp) 33 | : 34 | : "memory"); 35 | } 36 | 37 | static inline void arm32_interrupt_disable(void) 38 | { 39 | uint32_t tmp; 40 | 41 | __asm__ __volatile__("mrs %0, cpsr\n" 42 | "orr %0, %0, #(1<<7)\n" 43 | "msr cpsr_cxsf, %0" 44 | : "=r"(tmp) 45 | : 46 | : "memory"); 47 | } 48 | 49 | static inline void arm32_mmu_enable(void) 50 | { 51 | uint32_t value = arm32_read_p15_c1(); 52 | arm32_write_p15_c1(value | (1 << 0)); 53 | } 54 | 55 | static inline void arm32_mmu_disable(void) 56 | { 57 | uint32_t value = arm32_read_p15_c1(); 58 | arm32_write_p15_c1(value & ~(1 << 0)); 59 | } 60 | 61 | static inline void arm32_dcache_enable(void) 62 | { 63 | uint32_t value = arm32_read_p15_c1(); 64 | arm32_write_p15_c1(value | (1 << 2)); 65 | } 66 | 67 | static inline void arm32_dcache_disable(void) 68 | { 69 | uint32_t value = arm32_read_p15_c1(); 70 | arm32_write_p15_c1(value & ~(1 << 2)); 71 | } 72 | 73 | static inline void arm32_icache_enable(void) 74 | { 75 | uint32_t value = arm32_read_p15_c1(); 76 | arm32_write_p15_c1(value | (1 << 12)); 77 | } 78 | 79 | static inline void arm32_icache_disable(void) 80 | { 81 | uint32_t value = arm32_read_p15_c1(); 82 | arm32_write_p15_c1(value & ~(1 << 12)); 83 | } 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /* __ARM32_H__ */ 90 | -------------------------------------------------------------------------------- /arch/arm32/include/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_ATOMIC_H__ 2 | #define __ARM32_ATOMIC_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #if (__ARM32_ARCH__ >= 6) 13 | static inline void atomic_add(atomic_t *a, int v) 14 | { 15 | unsigned int tmp; 16 | int result; 17 | 18 | __asm__ __volatile__("1: ldrex %0, [%3]\n" 19 | " add %0, %0, %4\n" 20 | " strex %1, %0, [%3]\n" 21 | " teq %1, #0\n" 22 | " bne 1b" 23 | : "=&r"(result), "=&r"(tmp), "+Qo"(a->counter) 24 | : "r"(&a->counter), "Ir"(v) 25 | : "cc"); 26 | } 27 | 28 | static inline int atomic_add_return(atomic_t *a, int v) 29 | { 30 | unsigned int tmp; 31 | int result; 32 | 33 | __asm__ __volatile__("1: ldrex %0, [%3]\n" 34 | " add %0, %0, %4\n" 35 | " strex %1, %0, [%3]\n" 36 | " teq %1, #0\n" 37 | " bne 1b" 38 | : "=&r"(result), "=&r"(tmp), "+Qo"(a->counter) 39 | : "r"(&a->counter), "Ir"(v) 40 | : "cc"); 41 | 42 | return result; 43 | } 44 | 45 | static inline void atomic_sub(atomic_t *a, int v) 46 | { 47 | unsigned int tmp; 48 | int result; 49 | 50 | __asm__ __volatile__("1: ldrex %0, [%3]\n" 51 | " sub %0, %0, %4\n" 52 | " strex %1, %0, [%3]\n" 53 | " teq %1, #0\n" 54 | " bne 1b" 55 | : "=&r"(result), "=&r"(tmp), "+Qo"(a->counter) 56 | : "r"(&a->counter), "Ir"(v) 57 | : "cc"); 58 | } 59 | 60 | static inline int atomic_sub_return(atomic_t *a, int v) 61 | { 62 | unsigned int tmp; 63 | int result; 64 | 65 | __asm__ __volatile__("1: ldrex %0, [%3]\n" 66 | " sub %0, %0, %4\n" 67 | " strex %1, %0, [%3]\n" 68 | " teq %1, #0\n" 69 | " bne 1b" 70 | : "=&r"(result), "=&r"(tmp), "+Qo"(a->counter) 71 | : "r"(&a->counter), "Ir"(v) 72 | : "cc"); 73 | 74 | return result; 75 | } 76 | 77 | static inline int atomic_cmp_exchange(atomic_t *a, int o, int n) 78 | { 79 | int pre, res; 80 | 81 | do { 82 | __asm__ __volatile__(" ldrex %1, [%3]\n" 83 | " mov %0, #0\n" 84 | " teq %1, %4\n" 85 | " strexeq %0, %5, [%3]\n" 86 | : "=&r"(res), "=&r"(pre), "+Qo"(a->counter) 87 | : "r"(&a->counter), "Ir"(o), "r"(n) 88 | : "cc"); 89 | } while (res); 90 | 91 | return pre; 92 | } 93 | #else 94 | static inline void atomic_add(atomic_t *a, int v) 95 | { 96 | mb(); 97 | a->counter += v; 98 | mb(); 99 | } 100 | 101 | static inline int atomic_add_return(atomic_t *a, int v) 102 | { 103 | mb(); 104 | a->counter += v; 105 | mb(); 106 | return a->counter; 107 | } 108 | 109 | static inline void atomic_sub(atomic_t *a, int v) 110 | { 111 | mb(); 112 | a->counter -= v; 113 | mb(); 114 | } 115 | 116 | static inline int atomic_sub_return(atomic_t *a, int v) 117 | { 118 | mb(); 119 | a->counter -= v; 120 | mb(); 121 | return a->counter; 122 | } 123 | 124 | static inline int atomic_cmp_exchange(atomic_t *a, int o, int n) 125 | { 126 | volatile int v; 127 | 128 | mb(); 129 | v = a->counter; 130 | if (v == o) 131 | a->counter = n; 132 | mb(); 133 | return v; 134 | } 135 | #endif 136 | 137 | #define atomic_set(a, v) \ 138 | do { \ 139 | ((a)->counter) = (v); \ 140 | smp_wmb(); \ 141 | } while (0) 142 | #define atomic_get(a) \ 143 | ({ \ 144 | int __v; \ 145 | __v = (a)->counter; \ 146 | smp_rmb(); \ 147 | __v; \ 148 | }) 149 | #define atomic_inc(a) (atomic_add(a, 1)) 150 | #define atomic_dec(a) (atomic_sub(a, 1)) 151 | #define atomic_inc_return(a) (atomic_add_return(a, 1)) 152 | #define atomic_dec_return(a) (atomic_sub_return(a, 1)) 153 | #define atomic_inc_and_test(a) (atomic_add_return(a, 1) == 0) 154 | #define atomic_dec_and_test(a) (atomic_sub_return(a, 1) == 0) 155 | #define atomic_add_negative(a, v) (atomic_add_return(a, v) < 0) 156 | #define atomic_sub_and_test(a, v) (atomic_sub_return(a, v) == 0) 157 | #define atomic_cmpxchg(a, o, n) (atomic_cmp_exchange(a, o, n)) 158 | 159 | #ifdef __cplusplus 160 | } 161 | #endif 162 | 163 | #endif /* __ARM32_ATOMIC_H__ */ 164 | -------------------------------------------------------------------------------- /arch/arm32/include/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_BARRIER_H__ 2 | #define __ARM32_BARRIER_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if __ARM32_ARCH__ == 5 9 | #define isb() __asm__ __volatile__("" : : : "memory") 10 | #define dsb() __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory") 11 | #define dmb() __asm__ __volatile__("" : : : "memory") 12 | #elif __ARM32_ARCH__ == 6 13 | #define isb() __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 4" : : "r"(0) : "memory") 14 | #define dsb() __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory") 15 | #define dmb() __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") 16 | #else 17 | #define isb() __asm__ __volatile__("isb sy" : : : "memory") 18 | #define dsb() __asm__ __volatile__("dsb sy" : : : "memory") 19 | #define dmb() __asm__ __volatile__("dmb sy" : : : "memory") 20 | #endif 21 | 22 | /* Read and write memory barrier */ 23 | #define mb() dsb() 24 | /* Read memory barrier */ 25 | #define rmb() dsb() 26 | /* Write memory barrier */ 27 | #define wmb() dsb() 28 | 29 | /* SMP read and write memory barrier */ 30 | #define smp_mb() dmb() 31 | /* SMP read memory barrier */ 32 | #define smp_rmb() dmb() 33 | /* SMP write memory barrier */ 34 | #define smp_wmb() dmb() 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* __ARM32_BARRIER_H__ */ 41 | -------------------------------------------------------------------------------- /arch/arm32/include/endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_ENDIAN_H__ 2 | #define __ARM32_ENDIAN_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #ifndef LITTLE_ENDIAN 9 | #define LITTLE_ENDIAN (0x1234) 10 | #endif 11 | #ifndef BIG_ENDIAN 12 | #define BIG_ENDIAN (0x4321) 13 | #endif 14 | 15 | #if (!defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)) 16 | #define __LITTLE_ENDIAN 17 | #endif 18 | 19 | #if defined(__LITTLE_ENDIAN) 20 | #define BYTE_ORDER LITTLE_ENDIAN 21 | #elif defined(__BIG_ENDIAN) 22 | #define BYTE_ORDER BIG_ENDIAN 23 | #else 24 | #error "Unknown byte order!" 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* __ARM32_ENDIAN_H__ */ 32 | -------------------------------------------------------------------------------- /arch/arm32/include/limits.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_LIMITS_H__ 2 | #define __ARM32_LIMITS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /* Number of bits in a 'char' */ 9 | #define CHAR_BIT (8) 10 | 11 | /* Minimum and maximum values a 'signed char' can hold */ 12 | #define SCHAR_MIN (-128) 13 | #define SCHAR_MAX 127 14 | 15 | /* Minimum and maximum values a 'char' can hold */ 16 | #define CHAR_MIN (-128) 17 | #define CHAR_MAX 127 18 | 19 | /* Maximum value an 'unsigned char' can hold (Minimum is 0) */ 20 | #define UCHAR_MAX 255 21 | 22 | /* Minimum and maximum values a 'signed short int' can hold */ 23 | #define SHRT_MIN (-1 - 0x7fff) 24 | #define SHRT_MAX 0x7fff 25 | 26 | /* Maximum value an 'unsigned short int' can hold (Minimum is 0) */ 27 | #define USHRT_MAX 0xffff 28 | 29 | /* Minimum and maximum values a 'signed int' can hold */ 30 | #define INT_MIN (-1 - 0x7fffffff) 31 | #define INT_MAX 0x7fffffff 32 | 33 | /* Maximum value an 'unsigned int' can hold (Minimum is 0) */ 34 | #define UINT_MAX 0xffffffffU 35 | 36 | /* Minimum and maximum values a 'signed long int' can hold */ 37 | #define LONG_MIN (-LONG_MAX - 1) 38 | #define LONG_MAX 0x7fffffffL 39 | 40 | /* Maximum value an 'unsigned long int' can hold (Minimum is 0) */ 41 | #define ULONG_MAX (2UL * LONG_MAX + 1) 42 | 43 | /* Minimum and maximum values a 'signed long long int' can hold */ 44 | #define LLONG_MIN (-LLONG_MAX - 1) 45 | #define LLONG_MAX 0x7fffffffffffffffLL 46 | 47 | /* Maximum value an 'unsigned long long int' can hold (Minimum is 0) */ 48 | #define ULLONG_MAX (2ULL * LLONG_MAX + 1) 49 | 50 | /* Minimum and maximum values a 'max int' can hold */ 51 | #define INTMAX_MIN LLONG_MIN 52 | #define INTMAX_MAX LLONG_MAX 53 | 54 | /* Maximum value an 'max uint' can hold (Minimum is 0) */ 55 | #define UINTMAX_MAX ULLONG_MAX 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* __ARM32_LIMITS_H__ */ 62 | -------------------------------------------------------------------------------- /arch/arm32/include/linkage.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARM32_LINKAGE_H__ 2 | #define __ARM32_LINKAGE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #define ALIGN .align 0 9 | #define ALIGN_STR ".align 0" 10 | 11 | #define ENTRY(name) \ 12 | .globl name; \ 13 | ALIGN; \ 14 | name: 15 | 16 | #define WEAK(name) \ 17 | .weak name; \ 18 | name: 19 | 20 | #define END(name) .size name, .- name 21 | 22 | #define ENDPROC(name) \ 23 | .type name, % function; \ 24 | END(name) 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif /* __ARM32_LINKAGE_H__ */ 31 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/arch_timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2018-2020 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * wangwei 6 | * 7 | */ 8 | 9 | #include "main.h" 10 | #include "io.h" 11 | 12 | /* 13 | * 64bit arch timer.CNTPCT 14 | * Freq = 24000000Hz 15 | */ 16 | uint64_t get_arch_counter(void) 17 | { 18 | uint32_t low = 0, high = 0; 19 | asm volatile("mrrc p15, 0, %0, %1, c14" : "=r"(low), "=r"(high) : : "memory"); 20 | return ((uint64_t)high << 32) | (uint64_t)low; 21 | } 22 | 23 | /* 24 | * get current time.(millisecond) 25 | */ 26 | uint32_t time_ms(void) 27 | { 28 | return get_arch_counter() / 24000; 29 | } 30 | 31 | /* 32 | * get current time.(microsecond) 33 | */ 34 | uint64_t time_us(void) 35 | { 36 | return get_arch_counter() / (uint64_t)24; 37 | } 38 | 39 | void udelay(uint64_t us) 40 | { 41 | uint64_t now; 42 | 43 | now = time_us(); 44 | while (time_us() - now < us) { 45 | }; 46 | } 47 | 48 | void mdelay(uint32_t ms) 49 | { 50 | udelay(ms * 1000); 51 | uint32_t now; 52 | 53 | now = time_ms(); 54 | while (time_ms() - now < ms) { 55 | }; 56 | } 57 | 58 | /************************************************************ 59 | * sdelay() - simple spin loop. Will be constant time as 60 | * its generally used in bypass conditions only. This 61 | * is necessary until timers are accessible. 62 | * 63 | * not inline to increase chances its in cache when called 64 | *************************************************************/ 65 | void sdelay(uint32_t loops) 66 | { 67 | __asm__ volatile("1:\n" 68 | "subs %0, %1, #1\n" 69 | "bne 1b" 70 | : "=r"(loops) 71 | : "0"(loops)); 72 | } 73 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2007-2013 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * Jerry Wang 6 | * 7 | * See file CREDITS for list of people who contributed to this 8 | * project. 9 | * 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License as 12 | * published by the Free Software Foundation; either version 2 of 13 | * the License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 | * MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef __dram_head_h__ 27 | #define __dram_head_h__ 28 | 29 | #define SDRAM_BASE (0x40000000) 30 | 31 | enum sunxi_dram_type { 32 | SUNXI_DRAM_TYPE_DDR2 = 2, 33 | SUNXI_DRAM_TYPE_DDR3 = 3, 34 | SUNXI_DRAM_TYPE_LPDDR2 = 6, 35 | SUNXI_DRAM_TYPE_LPDDR3 = 7, 36 | }; 37 | 38 | typedef struct __DRAM_PARA { 39 | // normal configuration 40 | unsigned int dram_clk; 41 | unsigned int dram_type; // dram_type DDR2: 2 DDR3: 3 LPDDR2: 6 LPDDR3: 7 DDR3L: 31 42 | // unsigned int lpddr2_type; //LPDDR2 type S4:0 S2:1 NVM:2 43 | unsigned int dram_zq; // do not need 44 | unsigned int dram_odt_en; 45 | 46 | // control configuration 47 | unsigned int dram_para1; 48 | unsigned int dram_para2; 49 | 50 | // timing configuration 51 | unsigned int dram_mr0; 52 | unsigned int dram_mr1; 53 | unsigned int dram_mr2; 54 | unsigned int dram_mr3; 55 | unsigned int dram_tpr0; // DRAMTMG0 56 | unsigned int dram_tpr1; // DRAMTMG1 57 | unsigned int dram_tpr2; // DRAMTMG2 58 | unsigned int dram_tpr3; // DRAMTMG3 59 | unsigned int dram_tpr4; // DRAMTMG4 60 | unsigned int dram_tpr5; // DRAMTMG5 61 | unsigned int dram_tpr6; // DRAMTMG8 62 | // reserved for future use 63 | unsigned int dram_tpr7; 64 | unsigned int dram_tpr8; 65 | unsigned int dram_tpr9; 66 | unsigned int dram_tpr10; 67 | unsigned int dram_tpr11; 68 | unsigned int dram_tpr12; 69 | unsigned int dram_tpr13; 70 | 71 | } dram_para_t; 72 | 73 | int init_DRAM(int type, dram_para_t *para); 74 | unsigned long sunxi_dram_init(void); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/exception.c: -------------------------------------------------------------------------------- 1 | /* 2 | * exception.c 3 | * 4 | * Copyright(c) 2007-2022 Jianjun Jiang <8192542@qq.com> 5 | * Official site: http://xboot.org 6 | * Mobile phone: +86-18665388956 7 | * QQ: 8192542 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include 30 | #include "debug.h" 31 | #include "main.h" 32 | 33 | struct arm_regs_t { 34 | uint32_t esp; 35 | uint32_t cpsr; 36 | uint32_t r[13]; 37 | uint32_t sp; 38 | uint32_t lr; 39 | uint32_t pc; 40 | }; 41 | 42 | static void show_regs(struct arm_regs_t *regs) 43 | { 44 | int i; 45 | 46 | error("pc : [<%08lx>] lr : [<%08lx>] cpsr: %08lx\r\n", regs->pc, regs->lr, regs->cpsr); 47 | error("sp : %08lx esp : %08lx\r\n", regs->sp, regs->esp); 48 | for (i = 12; i >= 0; i--) 49 | error("r%-2d: %08lx\r\n", i, regs->r[i]); 50 | error("\r\n"); 51 | } 52 | 53 | void arm32_do_undefined_instruction(struct arm_regs_t *regs) 54 | { 55 | show_regs(regs); 56 | // regs->pc += 4; 57 | fatal("undefined_instruction\r\n"); 58 | } 59 | 60 | void arm32_do_software_interrupt(struct arm_regs_t *regs) 61 | { 62 | show_regs(regs); 63 | // regs->pc += 4; 64 | fatal("software_interrupt\r\n"); 65 | } 66 | 67 | void arm32_do_prefetch_abort(struct arm_regs_t *regs) 68 | { 69 | show_regs(regs); 70 | // regs->pc += 4; 71 | fatal("prefetch_abort\r\n"); 72 | } 73 | 74 | void arm32_do_data_abort(struct arm_regs_t *regs) 75 | { 76 | show_regs(regs); 77 | // regs->pc += 4; 78 | fatal("data_abort\r\n"); 79 | } 80 | 81 | void arm32_do_irq(struct arm_regs_t *regs) 82 | { 83 | show_regs(regs); 84 | // regs->pc += 4; 85 | fatal("undefined IRQ\r\n"); 86 | } 87 | 88 | void arm32_do_fiq(struct arm_regs_t *regs) 89 | { 90 | show_regs(regs); 91 | // regs->pc += 4; 92 | fatal("undefined FIQ\r\n"); 93 | } 94 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/link.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * 4 | * \brief Linker script for T113-S3 internal SRAM 5 | * 6 | * based on: Linker script for running in internal FLASH on the SAMD21G17D 7 | * Copyright (c) 2018 Microchip Technology Inc. 8 | * 9 | * \asf_license_start 10 | * 11 | * \page License 12 | * 13 | * SPDX-License-Identifier: Apache-2.0 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 16 | * not use this file except in compliance with the License. 17 | * You may obtain a copy of the Licence at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 23 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | * 27 | * \asf_license_stop 28 | * 29 | */ 30 | 31 | /* This file gets parsed by the preprocessor */ 32 | 33 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 34 | OUTPUT_ARCH(arm) 35 | SEARCH_DIR(.) 36 | 37 | /* Memory Spaces Definitions */ 38 | MEMORY 39 | { 40 | ram (rwx) : ORIGIN = __RAM_BASE, LENGTH = 96K /* A1 + DSP0 IRAM + DSP0 DRAM0. 128K on boot mode, 96K on FEL mode */ 41 | } 42 | 43 | /* The stack size used by the application. NOTE: you need to adjust according to your application. */ 44 | STACK_SIZE = 0x1000; /* 4KB */ 45 | 46 | ENTRY(reset) 47 | 48 | /* Section Definitions */ 49 | SECTIONS 50 | { 51 | 52 | .text : 53 | { 54 | . = ALIGN(4); 55 | PROVIDE(__spl_start = .); 56 | *(.text .text.*) 57 | . = ALIGN(4); 58 | } > ram 59 | 60 | . = ALIGN(4); 61 | 62 | .ARM.exidx : { 63 | __exidx_start = .; 64 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 65 | __exidx_end = .; 66 | } > ram 67 | 68 | PROVIDE(__spl_end = .); 69 | PROVIDE(__spl_size = __spl_end - __spl_start); 70 | 71 | /* .bss section which is used for uninitialized data */ 72 | .bss (NOLOAD) : 73 | { 74 | . = ALIGN(4); 75 | _sbss = . ; 76 | *(.bss .bss.*) 77 | *(COMMON) 78 | . = ALIGN(4); 79 | _ebss = . ; 80 | } > ram 81 | 82 | .stack (NOLOAD): 83 | { 84 | . = ALIGN(8); 85 | /* SRV stack section */ 86 | __stack_srv_start = .; 87 | . += STACK_SIZE; 88 | __stack_srv_end = .; 89 | } > ram 90 | 91 | . = ALIGN(4); 92 | _end = . ; 93 | } 94 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/memcpy.S: -------------------------------------------------------------------------------- 1 | /* 2 | * NEON code contributed by Siarhei Siamashka . 3 | * Origin: http://sourceware.org/ml/libc-ports/2009-07/msg00003.html 4 | * 5 | * The GNU C Library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public License. 7 | * 8 | * tweaked for Android by Jim Huang 9 | */ 10 | 11 | .text 12 | .fpu neon 13 | 14 | .global memcpy 15 | .type memcpy, %function 16 | .align 4 17 | 18 | /* 19 | * ENABLE_UNALIGNED_MEM_ACCESSES macro can be defined to permit the use 20 | * of unaligned load/store memory accesses supported since ARMv6. This 21 | * will further improve performance, but can purely theoretically cause 22 | * problems if somebody decides to set SCTLR.A bit in the OS kernel 23 | * (to trap each unaligned memory access) or somehow mess with strongly 24 | * ordered/device memory. 25 | */ 26 | #define ENABLE_UNALIGNED_MEM_ACCESSES 1 27 | 28 | #define NEON_MAX_PREFETCH_DISTANCE 320 29 | 30 | memcpy: 31 | .fnstart 32 | mov ip, r0 33 | cmp r2, #16 34 | blt 4f @ Have less than 16 bytes to copy 35 | 36 | @ First ensure 16 byte alignment for the destination buffer 37 | tst r0, #0xF 38 | beq 2f 39 | tst r0, #1 40 | ldrneb r3, [r1], #1 41 | strneb r3, [ip], #1 42 | subne r2, r2, #1 43 | tst ip, #2 44 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 45 | ldrneh r3, [r1], #2 46 | strneh r3, [ip], #2 47 | #else 48 | ldrneb r3, [r1], #1 49 | strneb r3, [ip], #1 50 | ldrneb r3, [r1], #1 51 | strneb r3, [ip], #1 52 | #endif 53 | subne r2, r2, #2 54 | 55 | tst ip, #4 56 | beq 1f 57 | vld4.8 {d0[0], d1[0], d2[0], d3[0]}, [r1]! 58 | vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [ip, :32]! 59 | sub r2, r2, #4 60 | 1: 61 | tst ip, #8 62 | beq 2f 63 | vld1.8 {d0}, [r1]! 64 | vst1.8 {d0}, [ip, :64]! 65 | sub r2, r2, #8 66 | 2: 67 | subs r2, r2, #32 68 | blt 3f 69 | mov r3, #32 70 | 71 | @ Main copy loop, 32 bytes are processed per iteration. 72 | @ ARM instructions are used for doing fine-grained prefetch, 73 | @ increasing prefetch distance progressively up to 74 | @ NEON_MAX_PREFETCH_DISTANCE at runtime 75 | 1: 76 | vld1.8 {d0-d3}, [r1]! 77 | cmp r3, #(NEON_MAX_PREFETCH_DISTANCE - 32) 78 | pld [r1, r3] 79 | addle r3, r3, #32 80 | vst1.8 {d0-d3}, [ip, :128]! 81 | sub r2, r2, #32 82 | cmp r2, r3 83 | bge 1b 84 | cmp r2, #0 85 | blt 3f 86 | 1: @ Copy the remaining part of the buffer (already prefetched) 87 | vld1.8 {d0-d3}, [r1]! 88 | subs r2, r2, #32 89 | vst1.8 {d0-d3}, [ip, :128]! 90 | bge 1b 91 | 3: @ Copy up to 31 remaining bytes 92 | tst r2, #16 93 | beq 4f 94 | vld1.8 {d0, d1}, [r1]! 95 | vst1.8 {d0, d1}, [ip, :128]! 96 | 4: 97 | @ Use ARM instructions exclusively for the final trailing part 98 | @ not fully fitting into full 16 byte aligned block in order 99 | @ to avoid "ARM store after NEON store" hazard. Also NEON 100 | @ pipeline will be (mostly) flushed by the time when the 101 | @ control returns to the caller, making the use of NEON mostly 102 | @ transparent (and avoiding hazards in the caller code) 103 | 104 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 105 | movs r3, r2, lsl #29 106 | ldrcs r3, [r1], #4 107 | strcs r3, [ip], #4 108 | ldrcs r3, [r1], #4 109 | strcs r3, [ip], #4 110 | ldrmi r3, [r1], #4 111 | strmi r3, [ip], #4 112 | movs r2, r2, lsl #31 113 | ldrcsh r3, [r1], #2 114 | strcsh r3, [ip], #2 115 | ldrmib r3, [r1], #1 116 | strmib r3, [ip], #1 117 | #else 118 | movs r3, r2, lsl #29 119 | bcc 1f 120 | .rept 8 121 | ldrcsb r3, [r1], #1 122 | strcsb r3, [ip], #1 123 | .endr 124 | 1: 125 | bpl 1f 126 | .rept 4 127 | ldrmib r3, [r1], #1 128 | strmib r3, [ip], #1 129 | .endr 130 | 1: 131 | movs r2, r2, lsl #31 132 | ldrcsb r3, [r1], #1 133 | strcsb r3, [ip], #1 134 | ldrcsb r3, [r1], #1 135 | strcsb r3, [ip], #1 136 | ldrmib r3, [r1], #1 137 | strmib r3, [ip], #1 138 | #endif 139 | bx lr 140 | .fnend 141 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/reg-dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Allwinner D1/D1s/R528/T113-sx DRAM controller register 3 | * 4 | * (C) Copyright 2023 YuzukiTsuru 5 | * 6 | * SPDX-License-Identifier: GPL-2.0+ 7 | */ 8 | 9 | #ifndef __T113_REG_DRAM_H__ 10 | #define __T113_REG_DRAM_H__ 11 | 12 | #define MCTL_COM_BASE (0x3102000) 13 | #define MCTL_COM_WORK_MODE0 (0x00) 14 | #define MCTL_COM_WORK_MODE1 (0x04) 15 | #define MCTL_COM_DBGCR (0x08) 16 | #define MCTL_COM_TMR (0x0c) 17 | #define MCTL_COM_CCCR (0x14) 18 | #define MCTL_COM_MAER0 (0x20) 19 | #define MCTL_COM_MAER1 (0x24) 20 | #define MCTL_COM_MAER2 (0x28) 21 | #define MCTL_COM_REMAP0 (0x500) 22 | #define MCTL_COM_REMAP1 (0x504) 23 | #define MCTL_COM_REMAP2 (0x508) 24 | #define MCTL_COM_REMAP3 (0x50c) 25 | 26 | #define MCTL_PHY_BASE (0x3103000) 27 | #define MCTL_PHY_PIR (0x00) 28 | #define MCTL_PHY_PWRCTL (0x04) 29 | #define MCTL_PHY_MRCTRL0 (0x08) 30 | #define MCTL_PHY_CLKEN (0x0c) 31 | #define MCTL_PHY_PGSR0 (0x10) 32 | #define MCTL_PHY_PGSR1 (0x14) 33 | #define MCTL_PHY_STATR (0x18) 34 | #define MCTL_PHY_LP3MR11 (0x2c) 35 | #define MCTL_PHY_DRAM_MR0 (0x30) 36 | #define MCTL_PHY_DRAM_MR1 (0x34) 37 | #define MCTL_PHY_DRAM_MR2 (0x38) 38 | #define MCTL_PHY_DRAM_MR3 (0x3c) 39 | #define MCTL_PHY_PTR0 (0x44) 40 | #define MCTL_PHY_PTR2 (0x4c) 41 | #define MCTL_PHY_PTR3 (0x50) 42 | #define MCTL_PHY_PTR4 (0x54) 43 | #define MCTL_PHY_DRAMTMG0 (0x58) 44 | #define MCTL_PHY_DRAMTMG1 (0x5c) 45 | #define MCTL_PHY_DRAMTMG2 (0x60) 46 | #define MCTL_PHY_DRAMTMG3 (0x64) 47 | #define MCTL_PHY_DRAMTMG4 (0x68) 48 | #define MCTL_PHY_DRAMTMG5 (0x6c) 49 | #define MCTL_PHY_DRAMTMG6 (0x70) 50 | #define MCTL_PHY_DRAMTMG7 (0x74) 51 | #define MCTL_PHY_DRAMTMG8 (0x78) 52 | #define MCTL_PHY_ODTCFG (0x7c) 53 | #define MCTL_PHY_PITMG0 (0x80) 54 | #define MCTL_PHY_PITMG1 (0x84) 55 | #define MCTL_PHY_LPTPR (0x88) 56 | #define MCTL_PHY_RFSHCTL0 (0x8c) 57 | #define MCTL_PHY_RFSHTMG (0x90) 58 | #define MCTL_PHY_RFSHCTL1 (0x94) 59 | #define MCTL_PHY_PWRTMG (0x98) 60 | #define MCTL_PHY_ASRC (0x9c) 61 | #define MCTL_PHY_ASRTC (0xa0) 62 | #define MCTL_PHY_VTFCR (0xb8) 63 | #define MCTL_PHY_DQSGMR (0xbc) 64 | #define MCTL_PHY_DTCR (0xc0) 65 | #define MCTL_PHY_DTAR0 (0xc4) 66 | #define MCTL_PHY_PGCR0 (0x100) 67 | #define MCTL_PHY_PGCR1 (0x104) 68 | #define MCTL_PHY_PGCR2 (0x108) 69 | #define MCTL_PHY_PGCR3 (0x10c) 70 | #define MCTL_PHY_IOVCR0 (0x110) 71 | #define MCTL_PHY_IOVCR1 (0x114) 72 | #define MCTL_PHY_DXCCR (0x11c) 73 | #define MCTL_PHY_ODTMAP (0x120) 74 | #define MCTL_PHY_ZQCTL0 (0x124) 75 | #define MCTL_PHY_ZQCTL1 (0x128) 76 | #define MCTL_PHY_ZQCR (0x140) 77 | #define MCTL_PHY_ZQSR (0x144) 78 | #define MCTL_PHY_ZQDR0 (0x148) 79 | #define MCTL_PHY_ZQDR1 (0x14c) 80 | #define MCTL_PHY_ZQDR2 (0x150) 81 | #define MCTL_PHY_SCHED (0x1c0) 82 | #define MCTL_PHY_PERFHPR0 (0x1c4) 83 | #define MCTL_PHY_PERFHPR1 (0x1c8) 84 | #define MCTL_PHY_PERFLPR0 (0x1cc) 85 | #define MCTL_PHY_PERFLPR1 (0x1d0) 86 | #define MCTL_PHY_PERFWR0 (0x1d4) 87 | #define MCTL_PHY_PERFWR1 (0x1d8) 88 | #define MCTL_PHY_ACMDLR (0x200) 89 | #define MCTL_PHY_ACLDLR (0x204) 90 | #define MCTL_PHY_ACIOCR0 (0x208) 91 | #define MCTL_PHY_ACIOCR1(x) (0x210 + 0x4 * x) 92 | #define MCTL_PHY_DXnMDLR(x) (0x300 + 0x80 * x) 93 | #define MCTL_PHY_DXnLDLR0(x) (0x304 + 0x80 * x) 94 | #define MCTL_PHY_DXnLDLR1(x) (0x308 + 0x80 * x) 95 | #define MCTL_PHY_DXnLDLR2(x) (0x30c + 0x80 * x) 96 | #define MCTL_PHY_DXIOCR (0x310) 97 | #define MCTL_PHY_DATX0IOCR(x) (0x310 + 0x4 * x) 98 | #define MCTL_PHY_DATX1IOCR(x) (0x390 + 0x4 * x) 99 | #define MCTL_PHY_DATX2IOCR(x) (0x410 + 0x4 * x) 100 | #define MCTL_PHY_DATX3IOCR(x) (0x490 + 0x4 * x) 101 | #define MCTL_PHY_DXnSDLR6(x) (0x33c + 0x80 * x) 102 | #define MCTL_PHY_DXnGTR(x) (0x340 + 0x80 * x) 103 | #define MCTL_PHY_DXnGCR0(x) (0x344 + 0x80 * x) 104 | #define MCTL_PHY_DXnGSR0(x) (0x348 + 0x80 * x) 105 | 106 | #define SYS_CONTROL_REG_BASE (0x3000000) 107 | #define LDO_CTAL_REG (0x150) 108 | #define ZQ_CAL_CTRL_REG (0x160) 109 | #define ZQ_RES_CTRL_REG (0x168) 110 | #define ZQ_RES_STATUS_REG (0x16c) 111 | 112 | #define SYS_SID_BASE (0x3006000) 113 | #define SYS_EFUSE_REG (0x228) 114 | #define SYS_LDOB_SID (0x21c) 115 | 116 | #define SUNXI_R_CPUCFG_BASE (0x7000400) 117 | #define SUNXI_R_CPUCFG_SUP_STAN_FLAG (0x1d4) 118 | 119 | #define R_PRCM_BASE (0x7010000) 120 | #define VDD_SYS_PWROFF_GATING_REG (0x250) 121 | #define ANALOG_PWROFF_GATING_REG (0x254) 122 | 123 | #endif /* __T113_REG_DRAM_H__ */ -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sdmmc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDCARD_H__ 2 | #define __SDCARD_H__ 3 | 4 | #include "sunxi_sdhci.h" 5 | 6 | enum { 7 | /* Class 1 */ 8 | MMC_GO_IDLE_STATE = 0, 9 | MMC_SEND_OP_COND = 1, 10 | MMC_ALL_SEND_CID = 2, 11 | MMC_SET_RELATIVE_ADDR = 3, 12 | MMC_SET_DSR = 4, 13 | MMC_SWITCH = 6, 14 | MMC_SELECT_CARD = 7, 15 | MMC_SEND_EXT_CSD = 8, 16 | MMC_SEND_CSD = 9, 17 | MMC_SEND_CID = 10, 18 | MMC_READ_DAT_UNTIL_STOP = 11, 19 | MMC_STOP_TRANSMISSION = 12, 20 | MMC_SEND_STATUS = 13, 21 | MMC_GO_INACTIVE_STATE = 15, 22 | MMC_SPI_READ_OCR = 58, 23 | MMC_SPI_CRC_ON_OFF = 59, 24 | 25 | /* Class 2 */ 26 | MMC_SET_BLOCKLEN = 16, 27 | MMC_READ_SINGLE_BLOCK = 17, 28 | MMC_READ_MULTIPLE_BLOCK = 18, 29 | 30 | /* Class 3 */ 31 | MMC_WRITE_DAT_UNTIL_STOP = 20, 32 | 33 | /* Class 4 */ 34 | MMC_SET_BLOCK_COUNT = 23, 35 | MMC_WRITE_SINGLE_BLOCK = 24, 36 | MMC_WRITE_MULTIPLE_BLOCK = 25, 37 | MMC_PROGRAM_CID = 26, 38 | MMC_PROGRAM_CSD = 27, 39 | 40 | /* Class 5 */ 41 | MMC_ERASE_GROUP_START = 35, 42 | MMC_ERASE_GROUP_END = 36, 43 | MMC_ERASE = 38, 44 | 45 | /* Class 6 */ 46 | MMC_SET_WRITE_PROT = 28, 47 | MMC_CLR_WRITE_PROT = 29, 48 | MMC_SEND_WRITE_PROT = 30, 49 | 50 | /* Class 7 */ 51 | MMC_LOCK_UNLOCK = 42, 52 | 53 | /* Class 8 */ 54 | MMC_APP_CMD = 55, 55 | MMC_GEN_CMD = 56, 56 | 57 | /* Class 9 */ 58 | MMC_FAST_IO = 39, 59 | MMC_GO_IRQ_STATE = 40, 60 | }; 61 | 62 | enum { 63 | SD_CMD_SEND_RELATIVE_ADDR = 3, 64 | SD_CMD_SWITCH_FUNC = 6, 65 | SD_CMD_SEND_IF_COND = 8, 66 | SD_CMD_APP_SET_BUS_WIDTH = 6, 67 | SD_CMD_ERASE_WR_BLK_START = 32, 68 | SD_CMD_ERASE_WR_BLK_END = 33, 69 | SD_CMD_APP_SEND_OP_COND = 41, 70 | SD_CMD_APP_SEND_SCR = 51, 71 | }; 72 | 73 | enum { 74 | MMC_RSP_PRESENT = (1 << 0), 75 | MMC_RSP_136 = (1 << 1), 76 | MMC_RSP_CRC = (1 << 2), 77 | MMC_RSP_BUSY = (1 << 3), 78 | MMC_RSP_OPCODE = (1 << 4), 79 | }; 80 | 81 | enum { 82 | MMC_RSP_NONE = (0 << 24), 83 | MMC_RSP_R1 = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 84 | MMC_RSP_R1B = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY), 85 | MMC_RSP_R2 = (2 << 24) | (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC), 86 | MMC_RSP_R3 = (3 << 24) | (MMC_RSP_PRESENT), 87 | MMC_RSP_R4 = (4 << 24) | (MMC_RSP_PRESENT), 88 | MMC_RSP_R5 = (5 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 89 | MMC_RSP_R6 = (6 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 90 | MMC_RSP_R7 = (7 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 91 | }; 92 | 93 | enum { 94 | MMC_STATUS_IDLE = 0, 95 | MMC_STATUS_READY = 1, 96 | MMC_STATUS_IDENT = 2, 97 | MMC_STATUS_STBY = 3, 98 | MMC_STATUS_TRAN = 4, 99 | MMC_STATUS_DATA = 5, 100 | MMC_STATUS_RCV = 6, 101 | MMC_STATUS_PRG = 7, 102 | MMC_STATUS_DIS = 8, 103 | MMC_STATUS_BTST = 9, 104 | MMC_STATUS_SLP = 10, 105 | }; 106 | 107 | enum { 108 | OCR_BUSY = 0x80000000, 109 | OCR_HCS = 0x40000000, 110 | OCR_VOLTAGE_MASK = 0x00ffff80, 111 | OCR_ACCESS_MODE = 0x60000000, 112 | }; 113 | 114 | enum { 115 | MMC_DATA_READ = (1 << 0), 116 | MMC_DATA_WRITE = (1 << 1), 117 | }; 118 | 119 | enum { 120 | MMC_VDD_27_36 = (1 << 0), 121 | MMC_VDD_165_195 = (1 << 1), 122 | }; 123 | 124 | enum { 125 | MMC_BUS_WIDTH_1 = 1, 126 | MMC_BUS_WIDTH_4 = 2, 127 | }; 128 | 129 | enum { 130 | SD_VERSION_SD = 0x20000, 131 | SD_VERSION_3 = (SD_VERSION_SD | 0x300), 132 | SD_VERSION_2 = (SD_VERSION_SD | 0x200), 133 | SD_VERSION_1_0 = (SD_VERSION_SD | 0x100), 134 | SD_VERSION_1_10 = (SD_VERSION_SD | 0x10a), 135 | MMC_VERSION_MMC = 0x10000, 136 | MMC_VERSION_UNKNOWN = (MMC_VERSION_MMC), 137 | MMC_VERSION_1_2 = (MMC_VERSION_MMC | 0x102), 138 | MMC_VERSION_1_4 = (MMC_VERSION_MMC | 0x104), 139 | MMC_VERSION_2_2 = (MMC_VERSION_MMC | 0x202), 140 | MMC_VERSION_3 = (MMC_VERSION_MMC | 0x300), 141 | MMC_VERSION_4 = (MMC_VERSION_MMC | 0x400), 142 | MMC_VERSION_4_1 = (MMC_VERSION_MMC | 0x401), 143 | MMC_VERSION_4_2 = (MMC_VERSION_MMC | 0x402), 144 | MMC_VERSION_4_3 = (MMC_VERSION_MMC | 0x403), 145 | MMC_VERSION_4_41 = (MMC_VERSION_MMC | 0x429), 146 | MMC_VERSION_4_5 = (MMC_VERSION_MMC | 0x405), 147 | MMC_VERSION_5_0 = (MMC_VERSION_MMC | 0x500), 148 | MMC_VERSION_5_1 = (MMC_VERSION_MMC | 0x501), 149 | }; 150 | 151 | typedef struct { 152 | uint32_t version; 153 | uint32_t ocr; 154 | uint32_t rca; 155 | uint32_t cid[4]; 156 | uint32_t csd[4]; 157 | uint8_t extcsd[512]; 158 | 159 | uint32_t high_capacity; 160 | uint32_t tran_speed; 161 | uint32_t dsr_imp; 162 | uint32_t read_bl_len; 163 | uint32_t write_bl_len; 164 | uint64_t capacity; 165 | } sdmmc_t; 166 | 167 | typedef struct { 168 | sdmmc_t card; 169 | sdhci_t *hci; 170 | uint8_t buf[512]; 171 | bool online; 172 | } sdmmc_pdata_t; 173 | 174 | extern sdmmc_pdata_t card0; 175 | 176 | int sdmmc_init(sdmmc_pdata_t *data, sdhci_t *hci); 177 | uint64_t sdmmc_blk_read(sdmmc_pdata_t *data, uint8_t *buf, uint64_t blkno, uint64_t blkcnt); 178 | 179 | #endif /* __SDCARD_H__ */ 180 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/start.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CONFIG_NBOOT_STACK 0x38000 4 | 5 | #define ARMV7_USR_MODE 0x10 6 | #define ARMV7_FIQ_MODE 0x11 7 | #define ARMV7_IRQ_MODE 0x12 8 | #define ARMV7_SVC_MODE 0x13 9 | #define ARMV7_MON_MODE 0x16 10 | #define ARMV7_ABT_MODE 0x17 11 | #define ARMV7_UND_MODE 0x1b 12 | #define ARMV7_SYSTEM_MODE 0x1f 13 | #define ARMV7_MODE_MASK 0x1f 14 | #define ARMV7_FIQ_MASK 0x40 15 | #define ARMV7_IRQ_MASK 0x80 16 | 17 | .arm 18 | .globl reset 19 | .text 20 | 21 | reset: 22 | /* Boot head information for BROM */ 23 | .long 0xea000016 24 | .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' 25 | .long 0x12345678 /* checksum */ 26 | .long __spl_size /* spl size */ 27 | .long 0x30 /* boot header size */ 28 | .long 0x30303033 /* boot header version */ 29 | .long 0x00020000 /* return value */ 30 | .long 0x00028000 /* run address */ 31 | .long 0x0 /* eGON version */ 32 | .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ 33 | .byte 0x34, 0x2e, 0x30, 0x00 34 | 35 | /* 36 | * The actual reset code 37 | */ 38 | mrs r0, cpsr 39 | bic r0, r0, #ARMV7_MODE_MASK 40 | orr r0, r0, #ARMV7_SVC_MODE 41 | orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) 42 | bic r0, r0, #(1<<9) @set little-endian 43 | msr cpsr_c, r0 44 | 45 | /* Set vector base address register */ 46 | 47 | ldr r0, =_vector 48 | mcr p15, 0, r0, c12, c0, 0 49 | mrc p15, 0, r0, c1, c0, 0 50 | bic r0, #(1 << 13) 51 | mcr p15, 0, r0, c1, c0, 0 52 | 53 | mrc p15, 0, r0, c1, c0, 0 54 | bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 55 | bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 56 | orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 57 | bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 58 | mcr p15, 0, r0, c1, c0, 0 59 | 60 | /* Enable neon/vfp unit */ 61 | mrc p15, 0, r0, c1, c0, 2 62 | orr r0, r0, #(0xf << 20) 63 | mcr p15, 0, r0, c1, c0, 2 64 | isb 65 | mov r0, #0x40000000 66 | vmsr fpexc, r0 67 | 68 | /* Set stack pointer */ 69 | ldr sp, =__stack_srv_end 70 | 71 | bl clear_bss 72 | 73 | /* 74 | * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 75 | * except if in HYP mode already 76 | */ 77 | mrs r0, cpsr 78 | and r1, r0, #0x1f @ mask mode bits 79 | teq r1, #0x1a @ test for HYP mode 80 | bicne r0, r0, #0x1f @ clear all mode bits 81 | orrne r0, r0, #0x13 @ set SVC mode 82 | orr r0, r0, #0xc0 @ disable FIQ and IRQ 83 | msr cpsr,r0 84 | 85 | @set cntfrq to 24M 86 | ldr r0, =24000000 87 | mcr p15, 0, r0, c14, c0, 0 88 | 89 | bl main 90 | 91 | clear_bss: 92 | ldr r0, =_sbss 93 | ldr r1, =_ebss 94 | mov r2, #0 95 | 96 | clbss_1: 97 | stmia r0!, {r2} 98 | cmp r0, r1 99 | blt clbss_1 100 | 101 | mov pc, lr 102 | 103 | _vector: 104 | b reset 105 | ldr pc, _undefined_instruction 106 | ldr pc, _software_interrupt 107 | ldr pc, _prefetch_abort 108 | ldr pc, _data_abort 109 | ldr pc, _not_used 110 | ldr pc, _irq 111 | ldr pc, _fiq 112 | 113 | _undefined_instruction: 114 | .word undefined_instruction 115 | _software_interrupt: 116 | .word software_interrupt 117 | _prefetch_abort: 118 | .word prefetch_abort 119 | _data_abort: 120 | .word data_abort 121 | _not_used: 122 | .word not_used 123 | _irq: 124 | .word irq 125 | _fiq: 126 | .word fiq 127 | 128 | .macro save_regs 129 | str lr, [sp, #-4] 130 | mrs lr, spsr_all 131 | str lr, [sp, #-8] 132 | str r1, [sp, #-12] 133 | str r0, [sp, #-16] 134 | mov r0, sp 135 | cps #0x13 136 | ldr r1, [r0, #-4] 137 | str r1, [sp, #-4]! 138 | ldr r1, [r0, #-8] 139 | str r1, [sp, #-(4 * 16)] 140 | ldr r1, [r0, #-12] 141 | ldr r0, [r0, #-16] 142 | stmdb sp, {r0 - r14}^ 143 | sub sp, sp, #(4 * 16) 144 | ldr r4, [sp] 145 | and r0, r4, #0x1f 146 | cmp r0, #0x10 147 | beq 10f 148 | cmp r0, #0x13 149 | beq 11f 150 | b . 151 | 11: add r1, sp, #(4 * 17) 152 | str r1, [sp, #(4 * 14)] 153 | str lr, [sp, #(4 * 15)] 154 | 10: add r1, sp, #(4 * 17) 155 | str r1, [sp, #-4]! 156 | mov r0, sp 157 | .endm 158 | 159 | .macro restore_regs 160 | mov r12, sp 161 | ldr sp, [r12], #4 162 | ldr r1, [r12], #4 163 | msr spsr_cxsf, r1 164 | and r0, r1, #0x1f 165 | cmp r0, #0x10 166 | beq 20f 167 | cmp r0, #0x13 168 | beq 21f 169 | b . 170 | 20: ldr lr, [r12, #(4 * 15)] 171 | ldmia r12, {r0 - r14}^ 172 | movs pc, lr 173 | 21: ldm r12, {r0 - r15}^ 174 | mov r0, r0 175 | .endm 176 | 177 | /* 178 | * Exception handlers 179 | */ 180 | .align 5 181 | undefined_instruction: 182 | sub lr, lr, #4 183 | save_regs 184 | bl arm32_do_undefined_instruction 185 | restore_regs 186 | 187 | .align 5 188 | software_interrupt: 189 | sub lr, lr, #4 190 | save_regs 191 | bl arm32_do_software_interrupt 192 | restore_regs 193 | 194 | .align 5 195 | prefetch_abort: 196 | sub lr, lr, #4 197 | save_regs 198 | bl arm32_do_prefetch_abort 199 | restore_regs 200 | 201 | .align 5 202 | data_abort: 203 | sub lr, lr, #8 204 | save_regs 205 | bl arm32_do_data_abort 206 | restore_regs 207 | 208 | .align 5 209 | not_used: 210 | b . 211 | 212 | .align 5 213 | irq: 214 | sub lr, lr, #4 215 | save_regs 216 | bl arm32_do_irq 217 | restore_regs 218 | 219 | .align 5 220 | fiq: 221 | sub lr, lr, #4 222 | save_regs 223 | bl arm32_do_fiq 224 | restore_regs 225 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_clk.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_CLK_H__ 2 | #define __SUNXI_CLK_H__ 3 | 4 | #include "main.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_clk_init(void); 8 | uint32_t sunxi_clk_get_peri1x_rate(void); 9 | 10 | void sunxi_clk_dump(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_dma.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0+ */ 2 | /* 3 | * (C) Copyright 2015 Roy Spliet 4 | */ 5 | 6 | #include "types.h" 7 | 8 | #ifndef _SUNXI_DMA_H 9 | #define _SUNXI_DMA_H 10 | 11 | #define SUNXI_DMA_BASE 0x03002000 12 | #define SUNXI_DMA_CHANNEL_BASE (SUNXI_DMA_BASE + 0x100) 13 | #define DMA_AUTO_GATE_REG (SUNXI_DMA_BASE + 0x28) 14 | 15 | #define SUNXI_DMA_CHANNEL_SIZE (0x40) 16 | #define SUNXI_DMA_LINK_NULL (0xfffff800) 17 | 18 | #define DMAC_DMATYPE_NORMAL 0 19 | #define DMAC_CFG_TYPE_DRAM (1) 20 | #define DMAC_CFG_TYPE_SRAM (0) 21 | 22 | #define DMAC_CFG_TYPE_SPI0 (22) 23 | #define DMAC_CFG_TYPE_SHMC0 (20) 24 | #define DMAC_CFG_SRC_TYPE_NAND (5) 25 | 26 | /* DMA base config */ 27 | #define DMAC_CFG_CONTINUOUS_ENABLE (0x01) 28 | #define DMAC_CFG_CONTINUOUS_DISABLE (0x00) 29 | 30 | /* ----------DMA dest config-------------------- */ 31 | /* DMA dest width config */ 32 | #define DMAC_CFG_DEST_DATA_WIDTH_8BIT (0x00) 33 | #define DMAC_CFG_DEST_DATA_WIDTH_16BIT (0x01) 34 | #define DMAC_CFG_DEST_DATA_WIDTH_32BIT (0x02) 35 | #define DMAC_CFG_DEST_DATA_WIDTH_64BIT (0x03) 36 | 37 | /* DMA dest bust config */ 38 | #define DMAC_CFG_DEST_1_BURST (0x00) 39 | #define DMAC_CFG_DEST_4_BURST (0x01) 40 | #define DMAC_CFG_DEST_8_BURST (0x02) 41 | #define DMAC_CFG_DEST_16_BURST (0x03) 42 | 43 | #define DMAC_CFG_DEST_ADDR_TYPE_LINEAR_MODE (0x00) 44 | #define DMAC_CFG_DEST_ADDR_TYPE_IO_MODE (0x01) 45 | 46 | /* ----------DMA src config -------------------*/ 47 | #define DMAC_CFG_SRC_DATA_WIDTH_8BIT (0x00) 48 | #define DMAC_CFG_SRC_DATA_WIDTH_16BIT (0x01) 49 | #define DMAC_CFG_SRC_DATA_WIDTH_32BIT (0x02) 50 | #define DMAC_CFG_SRC_DATA_WIDTH_64BIT (0x03) 51 | 52 | #define DMAC_CFG_SRC_1_BURST (0x00) 53 | #define DMAC_CFG_SRC_4_BURST (0x01) 54 | #define DMAC_CFG_SRC_8_BURST (0x02) 55 | #define DMAC_CFG_SRC_16_BURST (0x03) 56 | 57 | #define DMAC_CFG_SRC_ADDR_TYPE_LINEAR_MODE (0x00) 58 | #define DMAC_CFG_SRC_ADDR_TYPE_IO_MODE (0x01) 59 | 60 | /*dma int config*/ 61 | #define DMA_PKG_HALF_INT (1 << 0) 62 | #define DMA_PKG_END_INT (1 << 1) 63 | #define DMA_QUEUE_END_INT (1 << 2) 64 | 65 | typedef struct { 66 | u32 volatile config; 67 | u32 volatile source_addr; 68 | u32 volatile dest_addr; 69 | u32 volatile byte_count; 70 | u32 volatile commit_para; 71 | u32 volatile link; 72 | u32 volatile reserved[2]; 73 | } dma_desc_t; 74 | 75 | typedef struct { 76 | u32 volatile src_drq_type : 6; 77 | u32 volatile src_burst_length : 2; 78 | u32 volatile src_addr_mode : 1; 79 | u32 volatile src_data_width : 2; 80 | u32 volatile reserved0 : 5; 81 | u32 volatile dst_drq_type : 6; 82 | u32 volatile dst_burst_length : 2; 83 | u32 volatile dst_addr_mode : 1; 84 | u32 volatile dst_data_width : 2; 85 | u32 volatile reserved1 : 5; 86 | } dma_channel_config_t; 87 | 88 | typedef struct { 89 | dma_channel_config_t channel_cfg; 90 | u32 loop_mode; 91 | u32 data_block_size; 92 | u32 wait_cyc; 93 | } dma_set_t; 94 | 95 | typedef struct { 96 | void *m_data; 97 | // void (*m_func)(void *data); 98 | void (*m_func)(void); 99 | } dma_irq_handler_t; 100 | 101 | typedef struct { 102 | u32 volatile enable; 103 | u32 volatile pause; 104 | u32 volatile desc_addr; 105 | u32 volatile config; 106 | u32 volatile cur_src_addr; 107 | u32 volatile cur_dst_addr; 108 | u32 volatile left_bytes; 109 | u32 volatile parameters; 110 | u32 volatile mode; 111 | u32 volatile fdesc_addr; 112 | u32 volatile pkg_num; 113 | u32 volatile res[5]; 114 | } dma_channel_reg_t; 115 | 116 | typedef struct { 117 | u32 volatile irq_en0; /* 0x0 dma irq enable register 0 */ 118 | u32 volatile irq_en1; /* 0x4 dma irq enable register 1 */ 119 | u32 volatile reserved0[2]; 120 | u32 volatile irq_pending0; /* 0x10 dma irq pending register 0 */ 121 | u32 volatile irq_pending1; /* 0x14 dma irq pending register 1 */ 122 | u32 volatile reserved1[2]; 123 | u32 volatile security; /* 0x20 dma security register */ 124 | u32 volatile reserved3[1]; 125 | u32 volatile auto_gate; /* 0x28 dma auto gating register */ 126 | u32 volatile reserved4[1]; 127 | u32 volatile status; /* 0x30 dma status register */ 128 | u32 volatile reserved5[3]; 129 | u32 volatile version; /* 0x40 dma Version register */ 130 | u32 volatile reserved6[47]; 131 | dma_channel_reg_t channel[16]; /* 0x100 dma channel register */ 132 | } dma_reg_t; 133 | 134 | typedef struct { 135 | u32 used; 136 | u32 channel_count; 137 | dma_channel_reg_t *channel; 138 | u32 reserved; 139 | dma_desc_t *desc; 140 | dma_irq_handler_t dma_func; 141 | } dma_source_t; 142 | 143 | #define DMA_RST_OFS 16 144 | #define DMA_GATING_OFS 0 145 | 146 | void dma_init(void); 147 | void dma_exit(void); 148 | 149 | u32 dma_request(u32 dmatype); 150 | u32 dma_request_from_last(u32 dmatype); 151 | int dma_release(u32 hdma); 152 | int dma_setting(u32 hdma, dma_set_t *cfg); 153 | int dma_start(u32 hdma, u32 saddr, u32 daddr, u32 bytes); 154 | int dma_stop(u32 hdma); 155 | int dma_querystatus(u32 hdma); 156 | 157 | int dma_test(); 158 | 159 | #endif /* _SUNXI_DMA_H */ 160 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_gpio.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "debug.h" 3 | #include "sunxi_gpio.h" 4 | 5 | enum { 6 | GPIO_CFG0 = 0x00, 7 | GPIO_CFG1 = 0x04, 8 | GPIO_CFG2 = 0x08, 9 | GPIO_CFG3 = 0x0c, 10 | GPIO_DAT = 0x10, 11 | GPIO_DRV0 = 0x14, 12 | GPIO_DRV1 = 0x18, 13 | GPIO_DRV2 = 0x1c, 14 | GPIO_DRV3 = 0x20, 15 | GPIO_PUL0 = 0x24, 16 | GPIO_PUL1 = 0x28, 17 | }; 18 | 19 | static inline uint32_t _port_num(gpio_t pin) 20 | { 21 | return pin >> PIO_NUM_IO_BITS; 22 | } 23 | 24 | static uint32_t _port_base_get(gpio_t pin) 25 | { 26 | uint32_t port = pin >> PIO_NUM_IO_BITS; 27 | 28 | switch (port) { 29 | case PORTB: 30 | return 0x02000030; 31 | break; 32 | case PORTC: 33 | return 0x02000060; 34 | break; 35 | case PORTD: 36 | return 0x02000090; 37 | break; 38 | case PORTE: 39 | return 0x020000c0; 40 | break; 41 | case PORTF: 42 | return 0x020000f0; 43 | break; 44 | case PORTG: 45 | return 0x02000120; 46 | break; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | static inline uint32_t _pin_num(gpio_t pin) 53 | { 54 | return (pin & ((1 << PIO_NUM_IO_BITS) - 1)); 55 | } 56 | 57 | void sunxi_gpio_init(gpio_t pin, int cfg) 58 | { 59 | uint32_t port_addr = _port_base_get(pin); 60 | uint32_t pin_num = _pin_num(pin); 61 | uint32_t addr; 62 | uint32_t val; 63 | 64 | addr = port_addr + GPIO_CFG0 + ((pin_num >> 3) << 2); 65 | val = read32(addr); 66 | val &= ~(0xf << ((pin_num & 0x7) << 2)); 67 | val |= ((cfg & 0xf) << ((pin_num & 0x7) << 2)); 68 | write32(addr, val); 69 | } 70 | 71 | void sunxi_gpio_set_value(gpio_t pin, int value) 72 | { 73 | uint32_t port_addr = _port_base_get(pin); 74 | uint32_t pin_num = _pin_num(pin); 75 | uint32_t val; 76 | 77 | val = read32(port_addr + GPIO_DAT); 78 | val &= ~(1 << pin_num); 79 | val |= (!!value) << pin_num; 80 | write32(port_addr + GPIO_DAT, val); 81 | } 82 | 83 | int sunxi_gpio_read(gpio_t pin) 84 | { 85 | uint32_t port_addr = _port_base_get(pin); 86 | uint32_t pin_num = _pin_num(pin); 87 | uint32_t val; 88 | 89 | val = read32(port_addr + GPIO_DAT); 90 | return !!(val & (1 << pin_num)); 91 | } 92 | 93 | void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull) 94 | { 95 | uint32_t port_addr = _port_base_get(pin); 96 | uint32_t pin_num = _pin_num(pin); 97 | uint32_t addr; 98 | uint32_t val, v; 99 | 100 | switch (pull) { 101 | case GPIO_PULL_UP: 102 | v = 0x1; 103 | break; 104 | 105 | case GPIO_PULL_DOWN: 106 | v = 0x2; 107 | break; 108 | 109 | case GPIO_PULL_NONE: 110 | v = 0x0; 111 | break; 112 | 113 | default: 114 | v = 0x0; 115 | break; 116 | } 117 | 118 | addr = port_addr + GPIO_PUL0 + ((pin_num >> 4) << 2); 119 | val = read32(addr); 120 | val &= ~(v << ((pin_num & 0xf) << 1)); 121 | val |= (v << ((pin_num & 0xf) << 1)); 122 | write32(addr, val); 123 | } 124 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_GPIO_H__ 2 | #define __SUNXI_GPIO_H__ 3 | 4 | #include 5 | 6 | enum { 7 | GPIO_INPUT = 0, 8 | GPIO_OUTPUT = 1, 9 | GPIO_PERIPH_MUX2 = 2, 10 | GPIO_PERIPH_MUX3 = 3, 11 | GPIO_PERIPH_MUX4 = 4, 12 | GPIO_PERIPH_MUX5 = 5, 13 | GPIO_PERIPH_MUX6 = 6, 14 | GPIO_PERIPH_MUX7 = 7, 15 | GPIO_PERIPH_MUX8 = 8, 16 | GPIO_PERIPH_MUX14 = 14, 17 | GPIO_DISABLED = 0xf, 18 | }; 19 | 20 | #define PORTB 0 21 | #define PORTC 1 22 | #define PORTD 2 23 | #define PORTE 3 24 | #define PORTF 4 25 | #define PORTG 5 26 | #define SUNXI_GPIO_PORTS (PORTG + 1) 27 | 28 | enum gpio_pull_t { 29 | GPIO_PULL_UP = 0, 30 | GPIO_PULL_DOWN = 1, 31 | GPIO_PULL_NONE = 2, 32 | }; 33 | 34 | typedef uint32_t gpio_t; 35 | #define PIO_NUM_IO_BITS 5 36 | 37 | #define GPIO_PIN(x, y) (((uint32_t)(x << PIO_NUM_IO_BITS)) | y) 38 | 39 | typedef struct { 40 | gpio_t pin; 41 | uint8_t mux; 42 | } gpio_mux_t; 43 | 44 | extern void sunxi_gpio_init(gpio_t pin, int cfg); 45 | extern void sunxi_gpio_set_value(gpio_t pin, int value); 46 | extern int sunxi_gpio_read(gpio_t pin); 47 | extern void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull); 48 | 49 | #endif -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_sdhci.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDHCI_H__ 2 | #define __SDHCI_H__ 3 | 4 | #include "sunxi_gpio.h" 5 | 6 | typedef enum { 7 | MMC_CLK_400K = 0, 8 | MMC_CLK_25M, 9 | MMC_CLK_50M, 10 | MMC_CLK_50M_DDR, 11 | MMC_CLK_100M, 12 | MMC_CLK_150M, 13 | MMC_CLK_200M 14 | } smhc_clk_t; 15 | 16 | typedef struct { 17 | volatile u32 gctrl; /* (0x00) SMC Global Control Register */ 18 | volatile u32 clkcr; /* (0x04) SMC Clock Control Register */ 19 | volatile u32 timeout; /* (0x08) SMC Time Out Register */ 20 | volatile u32 width; /* (0x0C) SMC Bus Width Register */ 21 | volatile u32 blksz; /* (0x10) SMC Block Size Register */ 22 | volatile u32 bytecnt; /* (0x14) SMC Byte Count Register */ 23 | volatile u32 cmd; /* (0x18) SMC Command Register */ 24 | volatile u32 arg; /* (0x1C) SMC Argument Register */ 25 | volatile u32 resp0; /* (0x20) SMC Response Register 0 */ 26 | volatile u32 resp1; /* (0x24) SMC Response Register 1 */ 27 | volatile u32 resp2; /* (0x28) SMC Response Register 2 */ 28 | volatile u32 resp3; /* (0x2C) SMC Response Register 3 */ 29 | volatile u32 imask; /* (0x30) SMC Interrupt Mask Register */ 30 | volatile u32 mint; /* (0x34) SMC Masked Interrupt Status Register */ 31 | volatile u32 rint; /* (0x38) SMC Raw Interrupt Status Register */ 32 | volatile u32 status; /* (0x3C) SMC Status Register */ 33 | volatile u32 ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Register */ 34 | volatile u32 funcsel; /* (0x44) SMC Function Select Register */ 35 | volatile u32 cbcr; /* (0x48) SMC CIU Byte Count Register */ 36 | volatile u32 bbcr; /* (0x4C) SMC BIU Byte Count Register */ 37 | volatile u32 dbgc; /* (0x50) SMC Debug Enable Register */ 38 | volatile u32 csdc; /* (0x54) CRC status detect control register*/ 39 | volatile u32 a12a; /* (0x58)Auto command 12 argument*/ 40 | volatile u32 ntsr; /* (0x5c)SMC2 Newtiming Set Register */ 41 | volatile u32 res1[6]; /* (0x60~0x74) */ 42 | volatile u32 hwrst; /* (0x78) SMC eMMC Hardware Reset Register */ 43 | volatile u32 res2; /* (0x7c) */ 44 | volatile u32 dmac; /* (0x80) SMC IDMAC Control Register */ 45 | volatile u32 dlba; /* (0x84) SMC IDMAC Descriptor List Base Address Register */ 46 | volatile u32 idst; /* (0x88) SMC IDMAC Status Register */ 47 | volatile u32 idie; /* (0x8C) SMC IDMAC Interrupt Enable Register */ 48 | volatile u32 chda; /* (0x90) */ 49 | volatile u32 cbda; /* (0x94) */ 50 | volatile u32 res3[26]; /* (0x98~0xff) */ 51 | volatile u32 thldc; /* (0x100) Card Threshold Control Register */ 52 | volatile u32 sfc; /* (0x104) Sample Fifo Control Register */ 53 | volatile u32 res4[1]; /* (0x10b) */ 54 | volatile u32 dsbd; /* (0x10c) eMMC4.5 DDR Start Bit Detection Control */ 55 | volatile u32 res5[12]; /* (0x110~0x13c) */ 56 | volatile u32 drv_dl; /* (0x140) Drive Delay Control register*/ 57 | volatile u32 samp_dl; /* (0x144) Sample Delay Control register*/ 58 | volatile u32 ds_dl; /* (0x148) Data Strobe Delay Control Register */ 59 | volatile u32 ntdc; /* (0x14C) HS400 New Timing Delay Control Register */ 60 | volatile u32 res6[4]; /* (0x150~0x15f) */ 61 | volatile u32 skew_dat0_dl; /*(0x160) deskew data0 delay control register*/ 62 | volatile u32 skew_dat1_dl; /*(0x164) deskew data1 delay control register*/ 63 | volatile u32 skew_dat2_dl; /*(0x168) deskew data2 delay control register*/ 64 | volatile u32 skew_dat3_dl; /*(0x16c) deskew data3 delay control register*/ 65 | volatile u32 skew_dat4_dl; /*(0x170) deskew data4 delay control register*/ 66 | volatile u32 skew_dat5_dl; /*(0x174) deskew data5 delay control register*/ 67 | volatile u32 skew_dat6_dl; /*(0x178) deskew data6 delay control register*/ 68 | volatile u32 skew_dat7_dl; /*(0x17c) deskew data7 delay control register*/ 69 | volatile u32 skew_ds_dl; /*(0x180) deskew ds delay control register*/ 70 | volatile u32 skew_ctrl; /*(0x184) deskew control control register*/ 71 | volatile u32 res8[30]; /* (0x188~0x1ff) */ 72 | volatile u32 fifo; /* (0x200) SMC FIFO Access Address */ 73 | volatile u32 res7[63]; /* (0x201~0x2FF)*/ 74 | volatile u32 vers; /* (0x300) SMHC Version Register */ 75 | } sdhci_reg_t; 76 | 77 | typedef struct { 78 | u32 idx; 79 | u32 arg; 80 | u32 resptype; 81 | u32 response[4]; 82 | } sdhci_cmd_t; 83 | 84 | typedef struct { 85 | u8 *buf; 86 | u32 flag; 87 | u32 blksz; 88 | u32 blkcnt; 89 | } sdhci_data_t; 90 | 91 | #define SMHC_DES_NUM_SHIFT 12 /* smhc2!! */ 92 | #define SMHC_DES_BUFFER_MAX_LEN (1 << SMHC_DES_NUM_SHIFT) 93 | typedef struct { 94 | u32 : 1, dic : 1, /* disable interrupt on completion */ 95 | last_desc : 1, /* 1-this data buffer is the last buffer */ 96 | first_desc : 1, /* 1-data buffer is the first buffer, 0-data buffer contained in the next descriptor is 1st 97 | buffer */ 98 | des_chain : 1, /* 1-the 2nd address in the descriptor is the next descriptor address */ 99 | // end_of_ring : 1, /* 1-last descriptor flag when using dual data buffer in descriptor */ 100 | : 25, err_flag : 1, /* transfer error flag */ 101 | own : 1; /* des owner:1-idma owns it, 0-host owns it */ 102 | 103 | u32 data_buf_sz : SMHC_DES_NUM_SHIFT, data_buf_dummy : (32 - SMHC_DES_NUM_SHIFT); 104 | 105 | u32 buf_addr; 106 | u32 next_desc_addr; 107 | 108 | } sdhci_idma_desc_t __attribute__((aligned(8))); 109 | 110 | typedef struct { 111 | char *name; 112 | sdhci_reg_t *reg; 113 | u32 reset; 114 | 115 | u32 voltage; 116 | u32 width; 117 | smhc_clk_t clock; 118 | u32 pclk; 119 | u8 odly[6]; 120 | u8 sdly[6]; 121 | 122 | sdhci_idma_desc_t dma_desc[32]; 123 | u32 dma_trglvl; 124 | 125 | bool removable; 126 | bool isspi; 127 | 128 | gpio_mux_t gpio_d0; 129 | gpio_mux_t gpio_d1; 130 | gpio_mux_t gpio_d2; 131 | gpio_mux_t gpio_d3; 132 | gpio_mux_t gpio_cmd; 133 | gpio_mux_t gpio_clk; 134 | 135 | } sdhci_t; 136 | 137 | extern sdhci_t sdhci0; 138 | 139 | bool sdhci_reset(sdhci_t *hci); 140 | bool sdhci_set_voltage(sdhci_t *hci, u32 voltage); 141 | bool sdhci_set_width(sdhci_t *hci, u32 width); 142 | bool sdhci_set_clock(sdhci_t *hci, smhc_clk_t hz); 143 | bool sdhci_transfer(sdhci_t *hci, sdhci_cmd_t *cmd, sdhci_data_t *dat); 144 | int sunxi_sdhci_init(sdhci_t *sdhci); 145 | 146 | #endif /* __SDHCI_H__ */ 147 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_SPI_H__ 2 | #define __SUNXI_SPI_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef enum { 8 | SPI_IO_SINGLE = 0x00, 9 | SPI_IO_DUAL_RX, 10 | SPI_IO_QUAD_RX, 11 | SPI_IO_QUAD_IO, 12 | } spi_io_mode_t; 13 | 14 | typedef struct { 15 | uint8_t mfr; 16 | uint16_t dev; 17 | uint8_t dlen; 18 | } __attribute__((packed)) spi_nand_id_t; 19 | 20 | typedef struct { 21 | char *name; 22 | spi_nand_id_t id; 23 | uint32_t page_size; 24 | uint32_t spare_size; 25 | uint32_t pages_per_block; 26 | uint32_t blocks_per_die; 27 | uint32_t planes_per_die; 28 | uint32_t ndies; 29 | spi_io_mode_t mode; 30 | } spi_nand_info_t; 31 | 32 | typedef struct { 33 | uint32_t base; 34 | uint8_t id; 35 | uint32_t clk_rate; 36 | gpio_mux_t gpio_cs; 37 | gpio_mux_t gpio_sck; 38 | gpio_mux_t gpio_miso; 39 | gpio_mux_t gpio_mosi; 40 | gpio_mux_t gpio_wp; 41 | gpio_mux_t gpio_hold; 42 | 43 | spi_nand_info_t info; 44 | } sunxi_spi_t; 45 | 46 | int sunxi_spi_init(sunxi_spi_t *spi); 47 | void sunxi_spi_disable(sunxi_spi_t *spi); 48 | int spi_nand_detect(sunxi_spi_t *spi); 49 | uint32_t spi_nand_read(sunxi_spi_t *spi, uint8_t *buf, uint32_t addr, uint32_t rxlen); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_usart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "io.h" 3 | #include "main.h" 4 | #include "sunxi_usart.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_usart_init(sunxi_usart_t *usart) 8 | { 9 | uint32_t addr; 10 | uint32_t val; 11 | 12 | /* Config usart TXD and RXD pins */ 13 | sunxi_gpio_init(usart->gpio_tx.pin, usart->gpio_tx.mux); 14 | sunxi_gpio_init(usart->gpio_rx.pin, usart->gpio_rx.mux); 15 | 16 | /* Open the clock gate for usart */ 17 | addr = T113_CCU_BASE + CCU_USART_BGR_REG; 18 | val = read32(addr); 19 | val |= 1 << usart->id; 20 | write32(addr, val); 21 | 22 | /* Deassert USART reset */ 23 | addr = T113_CCU_BASE + CCU_USART_BGR_REG; 24 | val = read32(addr); 25 | val |= 1 << (16 + usart->id); 26 | write32(addr, val); 27 | 28 | /* Config USART to 115200-8-1-0 */ 29 | addr = usart->base; 30 | write32(addr + 0x04, 0x0); 31 | write32(addr + 0x08, 0xf7); 32 | write32(addr + 0x10, 0x0); 33 | val = read32(addr + 0x0c); 34 | val |= (1 << 7); 35 | write32(addr + 0x0c, val); 36 | write32(addr + 0x00, 0xd & 0xff); 37 | write32(addr + 0x04, (0xd >> 8) & 0xff); 38 | val = read32(addr + 0x0c); 39 | val &= ~(1 << 7); 40 | write32(addr + 0x0c, val); 41 | val = read32(addr + 0x0c); 42 | val &= ~0x1f; 43 | val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); 44 | write32(addr + 0x0c, val); 45 | } 46 | 47 | void sunxi_usart_putc(void *arg, char c) 48 | { 49 | sunxi_usart_t *usart = (sunxi_usart_t *)arg; 50 | 51 | while ((read32(usart->base + 0x7c) & (0x1 << 1)) == 0) 52 | ; 53 | write32(usart->base + 0x00, c); 54 | while ((read32(usart->base + 0x7c) & (0x1 << 0)) == 1) 55 | ; 56 | } 57 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s3/sunxi_usart.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_USART_H__ 2 | #define __SUNXI_USART_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef struct { 8 | uint32_t base; 9 | uint8_t id; 10 | gpio_mux_t gpio_tx; 11 | gpio_mux_t gpio_rx; 12 | } sunxi_usart_t; 13 | 14 | extern void sunxi_usart_init(sunxi_usart_t *usart); 15 | extern void sunxi_usart_putc(void *arg, char c); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/arch_timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2018-2020 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * wangwei 6 | * 7 | */ 8 | 9 | #include "main.h" 10 | #include "io.h" 11 | 12 | /* 13 | * 64bit arch timer.CNTPCT 14 | * Freq = 24000000Hz 15 | */ 16 | uint64_t get_arch_counter(void) 17 | { 18 | uint32_t low = 0, high = 0; 19 | asm volatile("mrrc p15, 0, %0, %1, c14" : "=r"(low), "=r"(high) : : "memory"); 20 | return ((uint64_t)high << 32) | (uint64_t)low; 21 | } 22 | 23 | /* 24 | * get current time.(millisecond) 25 | */ 26 | uint32_t time_ms(void) 27 | { 28 | return get_arch_counter() / 24000; 29 | } 30 | 31 | /* 32 | * get current time.(microsecond) 33 | */ 34 | uint64_t time_us(void) 35 | { 36 | return get_arch_counter() / (uint64_t)24; 37 | } 38 | 39 | void udelay(uint64_t us) 40 | { 41 | uint64_t now; 42 | 43 | now = time_us(); 44 | while (time_us() - now < us) { 45 | }; 46 | } 47 | 48 | void mdelay(uint32_t ms) 49 | { 50 | udelay(ms * 1000); 51 | uint32_t now; 52 | 53 | now = time_ms(); 54 | while (time_ms() - now < ms) { 55 | }; 56 | } 57 | 58 | /************************************************************ 59 | * sdelay() - simple spin loop. Will be constant time as 60 | * its generally used in bypass conditions only. This 61 | * is necessary until timers are accessible. 62 | * 63 | * not inline to increase chances its in cache when called 64 | *************************************************************/ 65 | void sdelay(uint32_t loops) 66 | { 67 | __asm__ volatile("1:\n" 68 | "subs %0, %1, #1\n" 69 | "bne 1b" 70 | : "=r"(loops) 71 | : "0"(loops)); 72 | } 73 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2007-2013 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * Jerry Wang 6 | * 7 | * See file CREDITS for list of people who contributed to this 8 | * project. 9 | * 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License as 12 | * published by the Free Software Foundation; either version 2 of 13 | * the License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 | * MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef __dram_head_h__ 27 | #define __dram_head_h__ 28 | 29 | #define SDRAM_BASE (0x40000000) 30 | 31 | enum sunxi_dram_type { 32 | SUNXI_DRAM_TYPE_DDR2 = 2, 33 | SUNXI_DRAM_TYPE_DDR3 = 3, 34 | SUNXI_DRAM_TYPE_LPDDR2 = 6, 35 | SUNXI_DRAM_TYPE_LPDDR3 = 7, 36 | }; 37 | 38 | typedef struct __DRAM_PARA { 39 | // normal configuration 40 | unsigned int dram_clk; 41 | unsigned int dram_type; // dram_type DDR2: 2 DDR3: 3 LPDDR2: 6 LPDDR3: 7 DDR3L: 31 42 | // unsigned int lpddr2_type; //LPDDR2 type S4:0 S2:1 NVM:2 43 | unsigned int dram_zq; // do not need 44 | unsigned int dram_odt_en; 45 | 46 | // control configuration 47 | unsigned int dram_para1; 48 | unsigned int dram_para2; 49 | 50 | // timing configuration 51 | unsigned int dram_mr0; 52 | unsigned int dram_mr1; 53 | unsigned int dram_mr2; 54 | unsigned int dram_mr3; 55 | unsigned int dram_tpr0; // DRAMTMG0 56 | unsigned int dram_tpr1; // DRAMTMG1 57 | unsigned int dram_tpr2; // DRAMTMG2 58 | unsigned int dram_tpr3; // DRAMTMG3 59 | unsigned int dram_tpr4; // DRAMTMG4 60 | unsigned int dram_tpr5; // DRAMTMG5 61 | unsigned int dram_tpr6; // DRAMTMG8 62 | // reserved for future use 63 | unsigned int dram_tpr7; 64 | unsigned int dram_tpr8; 65 | unsigned int dram_tpr9; 66 | unsigned int dram_tpr10; 67 | unsigned int dram_tpr11; 68 | unsigned int dram_tpr12; 69 | unsigned int dram_tpr13; 70 | 71 | } dram_para_t; 72 | 73 | int init_DRAM(int type, dram_para_t *para); 74 | unsigned long sunxi_dram_init(void); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/exception.c: -------------------------------------------------------------------------------- 1 | /* 2 | * exception.c 3 | * 4 | * Copyright(c) 2007-2022 Jianjun Jiang <8192542@qq.com> 5 | * Official site: http://xboot.org 6 | * Mobile phone: +86-18665388956 7 | * QQ: 8192542 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include 30 | #include "debug.h" 31 | #include "main.h" 32 | 33 | struct arm_regs_t { 34 | uint32_t esp; 35 | uint32_t cpsr; 36 | uint32_t r[13]; 37 | uint32_t sp; 38 | uint32_t lr; 39 | uint32_t pc; 40 | }; 41 | 42 | static void show_regs(struct arm_regs_t *regs) 43 | { 44 | int i; 45 | 46 | error("pc : [<%08lx>] lr : [<%08lx>] cpsr: %08lx\r\n", regs->pc, regs->lr, regs->cpsr); 47 | error("sp : %08lx esp : %08lx\r\n", regs->sp, regs->esp); 48 | for (i = 12; i >= 0; i--) 49 | error("r%-2d: %08lx\r\n", i, regs->r[i]); 50 | error("\r\n"); 51 | } 52 | 53 | void arm32_do_undefined_instruction(struct arm_regs_t *regs) 54 | { 55 | show_regs(regs); 56 | // regs->pc += 4; 57 | fatal("undefined_instruction\r\n"); 58 | } 59 | 60 | void arm32_do_software_interrupt(struct arm_regs_t *regs) 61 | { 62 | show_regs(regs); 63 | // regs->pc += 4; 64 | fatal("software_interrupt\r\n"); 65 | } 66 | 67 | void arm32_do_prefetch_abort(struct arm_regs_t *regs) 68 | { 69 | show_regs(regs); 70 | // regs->pc += 4; 71 | fatal("prefetch_abort\r\n"); 72 | } 73 | 74 | void arm32_do_data_abort(struct arm_regs_t *regs) 75 | { 76 | show_regs(regs); 77 | // regs->pc += 4; 78 | fatal("data_abort\r\n"); 79 | } 80 | 81 | void arm32_do_irq(struct arm_regs_t *regs) 82 | { 83 | show_regs(regs); 84 | // regs->pc += 4; 85 | fatal("undefined IRQ\r\n"); 86 | } 87 | 88 | void arm32_do_fiq(struct arm_regs_t *regs) 89 | { 90 | show_regs(regs); 91 | // regs->pc += 4; 92 | fatal("undefined FIQ\r\n"); 93 | } 94 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/link.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * 4 | * \brief Linker script for T113-S4 internal SRAM 5 | * 6 | * based on: Linker script for running in internal FLASH on the SAMD21G17D 7 | * Copyright (c) 2018 Microchip Technology Inc. 8 | * 9 | * \asf_license_start 10 | * 11 | * \page License 12 | * 13 | * SPDX-License-Identifier: Apache-2.0 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 16 | * not use this file except in compliance with the License. 17 | * You may obtain a copy of the Licence at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 23 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | * 27 | * \asf_license_stop 28 | * 29 | */ 30 | 31 | /* This file gets parsed by the preprocessor */ 32 | 33 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 34 | OUTPUT_ARCH(arm) 35 | SEARCH_DIR(.) 36 | 37 | /* Memory Spaces Definitions */ 38 | MEMORY 39 | { 40 | ram (rwx) : ORIGIN = __RAM_BASE, LENGTH = 96K /* A1 + DSP0 IRAM + DSP0 DRAM0. 128K on boot mode, 96K on FEL mode */ 41 | } 42 | 43 | /* The stack size used by the application. NOTE: you need to adjust according to your application. */ 44 | STACK_SIZE = 0x1000; /* 4KB */ 45 | 46 | /* Section Definitions */ 47 | SECTIONS 48 | { 49 | 50 | .text : 51 | { 52 | . = ALIGN(4); 53 | PROVIDE(__spl_start = .); 54 | *(.text .text.*) 55 | . = ALIGN(4); 56 | } > ram 57 | 58 | . = ALIGN(4); 59 | 60 | .ARM.exidx : { 61 | __exidx_start = .; 62 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 63 | __exidx_end = .; 64 | } > ram 65 | 66 | PROVIDE(__spl_end = .); 67 | PROVIDE(__spl_size = __spl_end - __spl_start); 68 | 69 | /* .bss section which is used for uninitialized data */ 70 | .bss (NOLOAD) : 71 | { 72 | . = ALIGN(4); 73 | _sbss = . ; 74 | *(.bss .bss.*) 75 | *(COMMON) 76 | . = ALIGN(4); 77 | _ebss = . ; 78 | } > ram 79 | 80 | .stack (NOLOAD): 81 | { 82 | . = ALIGN(8); 83 | /* SRV stack section */ 84 | __stack_srv_start = .; 85 | . += STACK_SIZE; 86 | __stack_srv_end = .; 87 | } > ram 88 | 89 | . = ALIGN(4); 90 | _end = . ; 91 | } 92 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/memcpy.S: -------------------------------------------------------------------------------- 1 | /* 2 | * NEON code contributed by Siarhei Siamashka . 3 | * Origin: http://sourceware.org/ml/libc-ports/2009-07/msg00003.html 4 | * 5 | * The GNU C Library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public License. 7 | * 8 | * tweaked for Android by Jim Huang 9 | */ 10 | 11 | .text 12 | .fpu neon 13 | 14 | .global memcpy 15 | .type memcpy, %function 16 | .align 4 17 | 18 | /* 19 | * ENABLE_UNALIGNED_MEM_ACCESSES macro can be defined to permit the use 20 | * of unaligned load/store memory accesses supported since ARMv6. This 21 | * will further improve performance, but can purely theoretically cause 22 | * problems if somebody decides to set SCTLR.A bit in the OS kernel 23 | * (to trap each unaligned memory access) or somehow mess with strongly 24 | * ordered/device memory. 25 | */ 26 | #define ENABLE_UNALIGNED_MEM_ACCESSES 1 27 | 28 | #define NEON_MAX_PREFETCH_DISTANCE 320 29 | 30 | memcpy: 31 | .fnstart 32 | mov ip, r0 33 | cmp r2, #16 34 | blt 4f @ Have less than 16 bytes to copy 35 | 36 | @ First ensure 16 byte alignment for the destination buffer 37 | tst r0, #0xF 38 | beq 2f 39 | tst r0, #1 40 | ldrneb r3, [r1], #1 41 | strneb r3, [ip], #1 42 | subne r2, r2, #1 43 | tst ip, #2 44 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 45 | ldrneh r3, [r1], #2 46 | strneh r3, [ip], #2 47 | #else 48 | ldrneb r3, [r1], #1 49 | strneb r3, [ip], #1 50 | ldrneb r3, [r1], #1 51 | strneb r3, [ip], #1 52 | #endif 53 | subne r2, r2, #2 54 | 55 | tst ip, #4 56 | beq 1f 57 | vld4.8 {d0[0], d1[0], d2[0], d3[0]}, [r1]! 58 | vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [ip, :32]! 59 | sub r2, r2, #4 60 | 1: 61 | tst ip, #8 62 | beq 2f 63 | vld1.8 {d0}, [r1]! 64 | vst1.8 {d0}, [ip, :64]! 65 | sub r2, r2, #8 66 | 2: 67 | subs r2, r2, #32 68 | blt 3f 69 | mov r3, #32 70 | 71 | @ Main copy loop, 32 bytes are processed per iteration. 72 | @ ARM instructions are used for doing fine-grained prefetch, 73 | @ increasing prefetch distance progressively up to 74 | @ NEON_MAX_PREFETCH_DISTANCE at runtime 75 | 1: 76 | vld1.8 {d0-d3}, [r1]! 77 | cmp r3, #(NEON_MAX_PREFETCH_DISTANCE - 32) 78 | pld [r1, r3] 79 | addle r3, r3, #32 80 | vst1.8 {d0-d3}, [ip, :128]! 81 | sub r2, r2, #32 82 | cmp r2, r3 83 | bge 1b 84 | cmp r2, #0 85 | blt 3f 86 | 1: @ Copy the remaining part of the buffer (already prefetched) 87 | vld1.8 {d0-d3}, [r1]! 88 | subs r2, r2, #32 89 | vst1.8 {d0-d3}, [ip, :128]! 90 | bge 1b 91 | 3: @ Copy up to 31 remaining bytes 92 | tst r2, #16 93 | beq 4f 94 | vld1.8 {d0, d1}, [r1]! 95 | vst1.8 {d0, d1}, [ip, :128]! 96 | 4: 97 | @ Use ARM instructions exclusively for the final trailing part 98 | @ not fully fitting into full 16 byte aligned block in order 99 | @ to avoid "ARM store after NEON store" hazard. Also NEON 100 | @ pipeline will be (mostly) flushed by the time when the 101 | @ control returns to the caller, making the use of NEON mostly 102 | @ transparent (and avoiding hazards in the caller code) 103 | 104 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 105 | movs r3, r2, lsl #29 106 | ldrcs r3, [r1], #4 107 | strcs r3, [ip], #4 108 | ldrcs r3, [r1], #4 109 | strcs r3, [ip], #4 110 | ldrmi r3, [r1], #4 111 | strmi r3, [ip], #4 112 | movs r2, r2, lsl #31 113 | ldrcsh r3, [r1], #2 114 | strcsh r3, [ip], #2 115 | ldrmib r3, [r1], #1 116 | strmib r3, [ip], #1 117 | #else 118 | movs r3, r2, lsl #29 119 | bcc 1f 120 | .rept 8 121 | ldrcsb r3, [r1], #1 122 | strcsb r3, [ip], #1 123 | .endr 124 | 1: 125 | bpl 1f 126 | .rept 4 127 | ldrmib r3, [r1], #1 128 | strmib r3, [ip], #1 129 | .endr 130 | 1: 131 | movs r2, r2, lsl #31 132 | ldrcsb r3, [r1], #1 133 | strcsb r3, [ip], #1 134 | ldrcsb r3, [r1], #1 135 | strcsb r3, [ip], #1 136 | ldrmib r3, [r1], #1 137 | strmib r3, [ip], #1 138 | #endif 139 | bx lr 140 | .fnend 141 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/reg-dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Allwinner D1/D1s/R528/T113-sx DRAM controller register 3 | * 4 | * (C) Copyright 2023 YuzukiTsuru 5 | * 6 | * SPDX-License-Identifier: GPL-2.0+ 7 | */ 8 | 9 | #ifndef __T113_REG_DRAM_H__ 10 | #define __T113_REG_DRAM_H__ 11 | 12 | #define MCTL_COM_BASE (0x3102000) 13 | #define MCTL_COM_WORK_MODE0 (0x00) 14 | #define MCTL_COM_WORK_MODE1 (0x04) 15 | #define MCTL_COM_DBGCR (0x08) 16 | #define MCTL_COM_TMR (0x0c) 17 | #define MCTL_COM_CCCR (0x14) 18 | #define MCTL_COM_MAER0 (0x20) 19 | #define MCTL_COM_MAER1 (0x24) 20 | #define MCTL_COM_MAER2 (0x28) 21 | #define MCTL_COM_REMAP0 (0x500) 22 | #define MCTL_COM_REMAP1 (0x504) 23 | #define MCTL_COM_REMAP2 (0x508) 24 | #define MCTL_COM_REMAP3 (0x50c) 25 | 26 | #define MCTL_PHY_BASE (0x3103000) 27 | #define MCTL_PHY_PIR (0x00) 28 | #define MCTL_PHY_PWRCTL (0x04) 29 | #define MCTL_PHY_MRCTRL0 (0x08) 30 | #define MCTL_PHY_CLKEN (0x0c) 31 | #define MCTL_PHY_PGSR0 (0x10) 32 | #define MCTL_PHY_PGSR1 (0x14) 33 | #define MCTL_PHY_STATR (0x18) 34 | #define MCTL_PHY_LP3MR11 (0x2c) 35 | #define MCTL_PHY_DRAM_MR0 (0x30) 36 | #define MCTL_PHY_DRAM_MR1 (0x34) 37 | #define MCTL_PHY_DRAM_MR2 (0x38) 38 | #define MCTL_PHY_DRAM_MR3 (0x3c) 39 | #define MCTL_PHY_PTR0 (0x44) 40 | #define MCTL_PHY_PTR2 (0x4c) 41 | #define MCTL_PHY_PTR3 (0x50) 42 | #define MCTL_PHY_PTR4 (0x54) 43 | #define MCTL_PHY_DRAMTMG0 (0x58) 44 | #define MCTL_PHY_DRAMTMG1 (0x5c) 45 | #define MCTL_PHY_DRAMTMG2 (0x60) 46 | #define MCTL_PHY_DRAMTMG3 (0x64) 47 | #define MCTL_PHY_DRAMTMG4 (0x68) 48 | #define MCTL_PHY_DRAMTMG5 (0x6c) 49 | #define MCTL_PHY_DRAMTMG6 (0x70) 50 | #define MCTL_PHY_DRAMTMG7 (0x74) 51 | #define MCTL_PHY_DRAMTMG8 (0x78) 52 | #define MCTL_PHY_ODTCFG (0x7c) 53 | #define MCTL_PHY_PITMG0 (0x80) 54 | #define MCTL_PHY_PITMG1 (0x84) 55 | #define MCTL_PHY_LPTPR (0x88) 56 | #define MCTL_PHY_RFSHCTL0 (0x8c) 57 | #define MCTL_PHY_RFSHTMG (0x90) 58 | #define MCTL_PHY_RFSHCTL1 (0x94) 59 | #define MCTL_PHY_PWRTMG (0x98) 60 | #define MCTL_PHY_ASRC (0x9c) 61 | #define MCTL_PHY_ASRTC (0xa0) 62 | #define MCTL_PHY_VTFCR (0xb8) 63 | #define MCTL_PHY_DQSGMR (0xbc) 64 | #define MCTL_PHY_DTCR (0xc0) 65 | #define MCTL_PHY_DTAR0 (0xc4) 66 | #define MCTL_PHY_PGCR0 (0x100) 67 | #define MCTL_PHY_PGCR1 (0x104) 68 | #define MCTL_PHY_PGCR2 (0x108) 69 | #define MCTL_PHY_PGCR3 (0x10c) 70 | #define MCTL_PHY_IOVCR0 (0x110) 71 | #define MCTL_PHY_IOVCR1 (0x114) 72 | #define MCTL_PHY_DXCCR (0x11c) 73 | #define MCTL_PHY_ODTMAP (0x120) 74 | #define MCTL_PHY_ZQCTL0 (0x124) 75 | #define MCTL_PHY_ZQCTL1 (0x128) 76 | #define MCTL_PHY_ZQCR (0x140) 77 | #define MCTL_PHY_ZQSR (0x144) 78 | #define MCTL_PHY_ZQDR0 (0x148) 79 | #define MCTL_PHY_ZQDR1 (0x14c) 80 | #define MCTL_PHY_ZQDR2 (0x150) 81 | #define MCTL_PHY_SCHED (0x1c0) 82 | #define MCTL_PHY_PERFHPR0 (0x1c4) 83 | #define MCTL_PHY_PERFHPR1 (0x1c8) 84 | #define MCTL_PHY_PERFLPR0 (0x1cc) 85 | #define MCTL_PHY_PERFLPR1 (0x1d0) 86 | #define MCTL_PHY_PERFWR0 (0x1d4) 87 | #define MCTL_PHY_PERFWR1 (0x1d8) 88 | #define MCTL_PHY_ACMDLR (0x200) 89 | #define MCTL_PHY_ACLDLR (0x204) 90 | #define MCTL_PHY_ACIOCR0 (0x208) 91 | #define MCTL_PHY_ACIOCR1(x) (0x210 + 0x4 * x) 92 | #define MCTL_PHY_DXnMDLR(x) (0x300 + 0x80 * x) 93 | #define MCTL_PHY_DXnLDLR0(x) (0x304 + 0x80 * x) 94 | #define MCTL_PHY_DXnLDLR1(x) (0x308 + 0x80 * x) 95 | #define MCTL_PHY_DXnLDLR2(x) (0x30c + 0x80 * x) 96 | #define MCTL_PHY_DXIOCR (0x310) 97 | #define MCTL_PHY_DATX0IOCR(x) (0x310 + 0x4 * x) 98 | #define MCTL_PHY_DATX1IOCR(x) (0x390 + 0x4 * x) 99 | #define MCTL_PHY_DATX2IOCR(x) (0x410 + 0x4 * x) 100 | #define MCTL_PHY_DATX3IOCR(x) (0x490 + 0x4 * x) 101 | #define MCTL_PHY_DXnSDLR6(x) (0x33c + 0x80 * x) 102 | #define MCTL_PHY_DXnGTR(x) (0x340 + 0x80 * x) 103 | #define MCTL_PHY_DXnGCR0(x) (0x344 + 0x80 * x) 104 | #define MCTL_PHY_DXnGSR0(x) (0x348 + 0x80 * x) 105 | 106 | #define SYS_CONTROL_REG_BASE (0x3000000) 107 | #define LDO_CTAL_REG (0x150) 108 | #define ZQ_CAL_CTRL_REG (0x160) 109 | #define ZQ_RES_CTRL_REG (0x168) 110 | #define ZQ_RES_STATUS_REG (0x16c) 111 | 112 | #define SYS_SID_BASE (0x3006000) 113 | #define SYS_EFUSE_REG (0x228) 114 | #define SYS_LDOB_SID (0x21c) 115 | 116 | #define SUNXI_R_CPUCFG_BASE (0x7000400) 117 | #define SUNXI_R_CPUCFG_SUP_STAN_FLAG (0x1d4) 118 | 119 | #define R_PRCM_BASE (0x7010000) 120 | #define VDD_SYS_PWROFF_GATING_REG (0x250) 121 | #define ANALOG_PWROFF_GATING_REG (0x254) 122 | 123 | #endif /* __T113_REG_DRAM_H__ */ -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sdmmc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDCARD_H__ 2 | #define __SDCARD_H__ 3 | 4 | #include "sunxi_sdhci.h" 5 | 6 | enum { 7 | /* Class 1 */ 8 | MMC_GO_IDLE_STATE = 0, 9 | MMC_SEND_OP_COND = 1, 10 | MMC_ALL_SEND_CID = 2, 11 | MMC_SET_RELATIVE_ADDR = 3, 12 | MMC_SET_DSR = 4, 13 | MMC_SWITCH = 6, 14 | MMC_SELECT_CARD = 7, 15 | MMC_SEND_EXT_CSD = 8, 16 | MMC_SEND_CSD = 9, 17 | MMC_SEND_CID = 10, 18 | MMC_READ_DAT_UNTIL_STOP = 11, 19 | MMC_STOP_TRANSMISSION = 12, 20 | MMC_SEND_STATUS = 13, 21 | MMC_GO_INACTIVE_STATE = 15, 22 | MMC_SPI_READ_OCR = 58, 23 | MMC_SPI_CRC_ON_OFF = 59, 24 | 25 | /* Class 2 */ 26 | MMC_SET_BLOCKLEN = 16, 27 | MMC_READ_SINGLE_BLOCK = 17, 28 | MMC_READ_MULTIPLE_BLOCK = 18, 29 | 30 | /* Class 3 */ 31 | MMC_WRITE_DAT_UNTIL_STOP = 20, 32 | 33 | /* Class 4 */ 34 | MMC_SET_BLOCK_COUNT = 23, 35 | MMC_WRITE_SINGLE_BLOCK = 24, 36 | MMC_WRITE_MULTIPLE_BLOCK = 25, 37 | MMC_PROGRAM_CID = 26, 38 | MMC_PROGRAM_CSD = 27, 39 | 40 | /* Class 5 */ 41 | MMC_ERASE_GROUP_START = 35, 42 | MMC_ERASE_GROUP_END = 36, 43 | MMC_ERASE = 38, 44 | 45 | /* Class 6 */ 46 | MMC_SET_WRITE_PROT = 28, 47 | MMC_CLR_WRITE_PROT = 29, 48 | MMC_SEND_WRITE_PROT = 30, 49 | 50 | /* Class 7 */ 51 | MMC_LOCK_UNLOCK = 42, 52 | 53 | /* Class 8 */ 54 | MMC_APP_CMD = 55, 55 | MMC_GEN_CMD = 56, 56 | 57 | /* Class 9 */ 58 | MMC_FAST_IO = 39, 59 | MMC_GO_IRQ_STATE = 40, 60 | }; 61 | 62 | enum { 63 | SD_CMD_SEND_RELATIVE_ADDR = 3, 64 | SD_CMD_SWITCH_FUNC = 6, 65 | SD_CMD_SEND_IF_COND = 8, 66 | SD_CMD_APP_SET_BUS_WIDTH = 6, 67 | SD_CMD_ERASE_WR_BLK_START = 32, 68 | SD_CMD_ERASE_WR_BLK_END = 33, 69 | SD_CMD_APP_SEND_OP_COND = 41, 70 | SD_CMD_APP_SEND_SCR = 51, 71 | }; 72 | 73 | enum { 74 | MMC_RSP_PRESENT = (1 << 0), 75 | MMC_RSP_136 = (1 << 1), 76 | MMC_RSP_CRC = (1 << 2), 77 | MMC_RSP_BUSY = (1 << 3), 78 | MMC_RSP_OPCODE = (1 << 4), 79 | }; 80 | 81 | enum { 82 | MMC_RSP_NONE = (0 << 24), 83 | MMC_RSP_R1 = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 84 | MMC_RSP_R1B = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY), 85 | MMC_RSP_R2 = (2 << 24) | (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC), 86 | MMC_RSP_R3 = (3 << 24) | (MMC_RSP_PRESENT), 87 | MMC_RSP_R4 = (4 << 24) | (MMC_RSP_PRESENT), 88 | MMC_RSP_R5 = (5 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 89 | MMC_RSP_R6 = (6 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 90 | MMC_RSP_R7 = (7 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 91 | }; 92 | 93 | enum { 94 | MMC_STATUS_IDLE = 0, 95 | MMC_STATUS_READY = 1, 96 | MMC_STATUS_IDENT = 2, 97 | MMC_STATUS_STBY = 3, 98 | MMC_STATUS_TRAN = 4, 99 | MMC_STATUS_DATA = 5, 100 | MMC_STATUS_RCV = 6, 101 | MMC_STATUS_PRG = 7, 102 | MMC_STATUS_DIS = 8, 103 | MMC_STATUS_BTST = 9, 104 | MMC_STATUS_SLP = 10, 105 | }; 106 | 107 | enum { 108 | OCR_BUSY = 0x80000000, 109 | OCR_HCS = 0x40000000, 110 | OCR_VOLTAGE_MASK = 0x00ffff80, 111 | OCR_ACCESS_MODE = 0x60000000, 112 | }; 113 | 114 | enum { 115 | MMC_DATA_READ = (1 << 0), 116 | MMC_DATA_WRITE = (1 << 1), 117 | }; 118 | 119 | enum { 120 | MMC_VDD_27_36 = (1 << 0), 121 | MMC_VDD_165_195 = (1 << 1), 122 | }; 123 | 124 | enum { 125 | MMC_BUS_WIDTH_1 = 1, 126 | MMC_BUS_WIDTH_4 = 2, 127 | }; 128 | 129 | enum { 130 | SD_VERSION_SD = 0x20000, 131 | SD_VERSION_3 = (SD_VERSION_SD | 0x300), 132 | SD_VERSION_2 = (SD_VERSION_SD | 0x200), 133 | SD_VERSION_1_0 = (SD_VERSION_SD | 0x100), 134 | SD_VERSION_1_10 = (SD_VERSION_SD | 0x10a), 135 | MMC_VERSION_MMC = 0x10000, 136 | MMC_VERSION_UNKNOWN = (MMC_VERSION_MMC), 137 | MMC_VERSION_1_2 = (MMC_VERSION_MMC | 0x102), 138 | MMC_VERSION_1_4 = (MMC_VERSION_MMC | 0x104), 139 | MMC_VERSION_2_2 = (MMC_VERSION_MMC | 0x202), 140 | MMC_VERSION_3 = (MMC_VERSION_MMC | 0x300), 141 | MMC_VERSION_4 = (MMC_VERSION_MMC | 0x400), 142 | MMC_VERSION_4_1 = (MMC_VERSION_MMC | 0x401), 143 | MMC_VERSION_4_2 = (MMC_VERSION_MMC | 0x402), 144 | MMC_VERSION_4_3 = (MMC_VERSION_MMC | 0x403), 145 | MMC_VERSION_4_41 = (MMC_VERSION_MMC | 0x429), 146 | MMC_VERSION_4_5 = (MMC_VERSION_MMC | 0x405), 147 | MMC_VERSION_5_0 = (MMC_VERSION_MMC | 0x500), 148 | MMC_VERSION_5_1 = (MMC_VERSION_MMC | 0x501), 149 | }; 150 | 151 | typedef struct { 152 | uint32_t version; 153 | uint32_t ocr; 154 | uint32_t rca; 155 | uint32_t cid[4]; 156 | uint32_t csd[4]; 157 | uint8_t extcsd[512]; 158 | 159 | uint32_t high_capacity; 160 | uint32_t tran_speed; 161 | uint32_t dsr_imp; 162 | uint32_t read_bl_len; 163 | uint32_t write_bl_len; 164 | uint64_t capacity; 165 | } sdmmc_t; 166 | 167 | typedef struct { 168 | sdmmc_t card; 169 | sdhci_t *hci; 170 | uint8_t buf[512]; 171 | bool online; 172 | } sdmmc_pdata_t; 173 | 174 | extern sdmmc_pdata_t card0; 175 | 176 | int sdmmc_init(sdmmc_pdata_t *data, sdhci_t *hci); 177 | uint64_t sdmmc_blk_read(sdmmc_pdata_t *data, uint8_t *buf, uint64_t blkno, uint64_t blkcnt); 178 | 179 | #endif /* __SDCARD_H__ */ 180 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/start.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CONFIG_NBOOT_STACK 0x38000 4 | 5 | #define ARMV7_USR_MODE 0x10 6 | #define ARMV7_FIQ_MODE 0x11 7 | #define ARMV7_IRQ_MODE 0x12 8 | #define ARMV7_SVC_MODE 0x13 9 | #define ARMV7_MON_MODE 0x16 10 | #define ARMV7_ABT_MODE 0x17 11 | #define ARMV7_UND_MODE 0x1b 12 | #define ARMV7_SYSTEM_MODE 0x1f 13 | #define ARMV7_MODE_MASK 0x1f 14 | #define ARMV7_FIQ_MASK 0x40 15 | #define ARMV7_IRQ_MASK 0x80 16 | 17 | .arm 18 | .globl reset 19 | .text 20 | 21 | reset: 22 | /* Boot head information for BROM */ 23 | .long 0xea000016 24 | .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' 25 | .long 0x12345678 /* checksum */ 26 | .long __spl_size /* spl size */ 27 | .long 0x30 /* boot header size */ 28 | .long 0x30303033 /* boot header version */ 29 | .long 0x00020000 /* return value */ 30 | .long 0x00028000 /* run address */ 31 | .long 0x0 /* eGON version */ 32 | .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ 33 | .byte 0x34, 0x2e, 0x30, 0x00 34 | 35 | /* 36 | * The actual reset code 37 | */ 38 | mrs r0, cpsr 39 | bic r0, r0, #ARMV7_MODE_MASK 40 | orr r0, r0, #ARMV7_SVC_MODE 41 | orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) 42 | bic r0, r0, #(1<<9) @set little-endian 43 | msr cpsr_c, r0 44 | 45 | /* Set vector base address register */ 46 | 47 | ldr r0, =_vector 48 | mcr p15, 0, r0, c12, c0, 0 49 | mrc p15, 0, r0, c1, c0, 0 50 | bic r0, #(1 << 13) 51 | mcr p15, 0, r0, c1, c0, 0 52 | 53 | mrc p15, 0, r0, c1, c0, 0 54 | bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 55 | bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 56 | orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 57 | bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 58 | mcr p15, 0, r0, c1, c0, 0 59 | 60 | /* Enable neon/vfp unit */ 61 | mrc p15, 0, r0, c1, c0, 2 62 | orr r0, r0, #(0xf << 20) 63 | mcr p15, 0, r0, c1, c0, 2 64 | isb 65 | mov r0, #0x40000000 66 | vmsr fpexc, r0 67 | 68 | /* Set stack pointer */ 69 | ldr sp, =__stack_srv_end 70 | 71 | bl clear_bss 72 | 73 | /* 74 | * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 75 | * except if in HYP mode already 76 | */ 77 | mrs r0, cpsr 78 | and r1, r0, #0x1f @ mask mode bits 79 | teq r1, #0x1a @ test for HYP mode 80 | bicne r0, r0, #0x1f @ clear all mode bits 81 | orrne r0, r0, #0x13 @ set SVC mode 82 | orr r0, r0, #0xc0 @ disable FIQ and IRQ 83 | msr cpsr,r0 84 | 85 | @set cntfrq to 24M 86 | ldr r0, =24000000 87 | mcr p15, 0, r0, c14, c0, 0 88 | 89 | bl main 90 | 91 | clear_bss: 92 | ldr r0, =_sbss 93 | ldr r1, =_ebss 94 | mov r2, #0 95 | 96 | clbss_1: 97 | stmia r0!, {r2} 98 | cmp r0, r1 99 | blt clbss_1 100 | 101 | mov pc, lr 102 | 103 | _vector: 104 | b reset 105 | ldr pc, _undefined_instruction 106 | ldr pc, _software_interrupt 107 | ldr pc, _prefetch_abort 108 | ldr pc, _data_abort 109 | ldr pc, _not_used 110 | ldr pc, _irq 111 | ldr pc, _fiq 112 | 113 | _undefined_instruction: 114 | .word undefined_instruction 115 | _software_interrupt: 116 | .word software_interrupt 117 | _prefetch_abort: 118 | .word prefetch_abort 119 | _data_abort: 120 | .word data_abort 121 | _not_used: 122 | .word not_used 123 | _irq: 124 | .word irq 125 | _fiq: 126 | .word fiq 127 | 128 | .macro save_regs 129 | str lr, [sp, #-4] 130 | mrs lr, spsr_all 131 | str lr, [sp, #-8] 132 | str r1, [sp, #-12] 133 | str r0, [sp, #-16] 134 | mov r0, sp 135 | cps #0x13 136 | ldr r1, [r0, #-4] 137 | str r1, [sp, #-4]! 138 | ldr r1, [r0, #-8] 139 | str r1, [sp, #-(4 * 16)] 140 | ldr r1, [r0, #-12] 141 | ldr r0, [r0, #-16] 142 | stmdb sp, {r0 - r14}^ 143 | sub sp, sp, #(4 * 16) 144 | ldr r4, [sp] 145 | and r0, r4, #0x1f 146 | cmp r0, #0x10 147 | beq 10f 148 | cmp r0, #0x13 149 | beq 11f 150 | b . 151 | 11: add r1, sp, #(4 * 17) 152 | str r1, [sp, #(4 * 14)] 153 | str lr, [sp, #(4 * 15)] 154 | 10: add r1, sp, #(4 * 17) 155 | str r1, [sp, #-4]! 156 | mov r0, sp 157 | .endm 158 | 159 | .macro restore_regs 160 | mov r12, sp 161 | ldr sp, [r12], #4 162 | ldr r1, [r12], #4 163 | msr spsr_cxsf, r1 164 | and r0, r1, #0x1f 165 | cmp r0, #0x10 166 | beq 20f 167 | cmp r0, #0x13 168 | beq 21f 169 | b . 170 | 20: ldr lr, [r12, #(4 * 15)] 171 | ldmia r12, {r0 - r14}^ 172 | movs pc, lr 173 | 21: ldm r12, {r0 - r15}^ 174 | mov r0, r0 175 | .endm 176 | 177 | /* 178 | * Exception handlers 179 | */ 180 | .align 5 181 | undefined_instruction: 182 | sub lr, lr, #4 183 | save_regs 184 | bl arm32_do_undefined_instruction 185 | restore_regs 186 | 187 | .align 5 188 | software_interrupt: 189 | sub lr, lr, #4 190 | save_regs 191 | bl arm32_do_software_interrupt 192 | restore_regs 193 | 194 | .align 5 195 | prefetch_abort: 196 | sub lr, lr, #4 197 | save_regs 198 | bl arm32_do_prefetch_abort 199 | restore_regs 200 | 201 | .align 5 202 | data_abort: 203 | sub lr, lr, #8 204 | save_regs 205 | bl arm32_do_data_abort 206 | restore_regs 207 | 208 | .align 5 209 | not_used: 210 | b . 211 | 212 | .align 5 213 | irq: 214 | sub lr, lr, #4 215 | save_regs 216 | bl arm32_do_irq 217 | restore_regs 218 | 219 | .align 5 220 | fiq: 221 | sub lr, lr, #4 222 | save_regs 223 | bl arm32_do_fiq 224 | restore_regs 225 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_clk.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "board.h" 3 | #include "sunxi_clk.h" 4 | #include "reg-ccu.h" 5 | #include "debug.h" 6 | 7 | volatile ccu_reg_t *const ccu = (ccu_reg_t *)T113_CCU_BASE; 8 | 9 | void set_pll_cpux_axi(void) 10 | { 11 | uint32_t val; 12 | 13 | /* AXI: Select cpu clock src to PLL_PERI(1x) */ 14 | write32(T113_CCU_BASE + CCU_CPU_AXI_CFG_REG, (4 << 24) | (1 << 0)); 15 | sdelay(10); 16 | 17 | /* Disable pll gating */ 18 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 19 | val &= ~(1 << 27); 20 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 21 | 22 | /* Enable pll ldo */ 23 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 24 | val |= (1 << 30); 25 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 26 | sdelay(5); 27 | 28 | /* Set clk to 1008mhz (default) or CONFIG_CPU_FREQ */ 29 | /* PLL_CPUX = 24 MHz*N/P */ 30 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 31 | val &= ~((0x3 << 16) | (0xff << 8) | (0x3 << 0)); 32 | #ifdef CONFIG_CPU_FREQ 33 | val |= (((CONFIG_CPU_FREQ / 24000000) - 1) << 8); 34 | #else 35 | val |= (41 << 8); 36 | #endif 37 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 38 | 39 | /* Lock enable */ 40 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 41 | val |= (1 << 29); 42 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 43 | 44 | /* Enable pll */ 45 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 46 | val |= (1 << 31); 47 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 48 | 49 | /* Wait pll stable */ 50 | while (!(read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG) & (0x1 << 28))) 51 | ; 52 | sdelay(20); 53 | 54 | /* Enable pll gating */ 55 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 56 | val |= (1 << 27); 57 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 58 | 59 | /* Lock disable */ 60 | val = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 61 | val &= ~(1 << 29); 62 | write32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 63 | sdelay(1); 64 | 65 | /* AXI: set and change cpu clk src to PLL_CPUX, PLL_CPUX:AXI0 = 1200MHz:600MHz */ 66 | val = read32(T113_CCU_BASE + CCU_CPU_AXI_CFG_REG); 67 | val &= ~(0x07 << 24 | 0x3 << 16 | 0x3 << 8 | 0xf << 0); // Clear 68 | val |= (0x03 << 24 | 0x0 << 16 | 0x1 << 8 | 0x1 << 0); // CLK_SEL=PLL_CPU/P, DIVP=0, DIV2=1, DIV1=1 69 | write32(T113_CCU_BASE + CCU_CPU_AXI_CFG_REG, val); 70 | sdelay(1); 71 | } 72 | 73 | static void set_pll_periph0(void) 74 | { 75 | uint32_t val; 76 | 77 | /* Periph0 has been enabled */ 78 | if (read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG) & (1 << 31)) 79 | return; 80 | 81 | /* Set default val */ 82 | write32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG, 0x63 << 8); 83 | 84 | /* Lock enable */ 85 | val = read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 86 | val |= (1 << 29); 87 | write32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG, val); 88 | 89 | /* Enabe pll 600m(1x) 1200m(2x) */ 90 | val = read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 91 | val |= (1 << 31); 92 | write32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG, val); 93 | 94 | /* Wait pll stable */ 95 | while (!(read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG) & (0x1 << 28))) 96 | ; 97 | sdelay(20); 98 | 99 | /* Lock disable */ 100 | val = read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 101 | val &= ~(1 << 29); 102 | write32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG, val); 103 | } 104 | 105 | static void set_ahb(void) 106 | { 107 | write32(T113_CCU_BASE + CCU_PSI_CLK_REG, (2 << 0) | (0 << 8) | (0x03 << 24)); 108 | sdelay(1); 109 | } 110 | 111 | static void set_apb(void) 112 | { 113 | write32(T113_CCU_BASE + CCU_APB0_CLK_REG, (2 << 0) | (1 << 8) | (0x03 << 24)); 114 | sdelay(1); 115 | } 116 | 117 | static void set_dma(void) 118 | { 119 | /* Dma reset */ 120 | write32(T113_CCU_BASE + CCU_DMA_BGR_REG, read32(T113_CCU_BASE + CCU_DMA_BGR_REG) | (1 << 16)); 121 | sdelay(20); 122 | /* Enable gating clock for dma */ 123 | write32(T113_CCU_BASE + CCU_DMA_BGR_REG, read32(T113_CCU_BASE + CCU_DMA_BGR_REG) | (1 << 0)); 124 | } 125 | 126 | static void set_mbus(void) 127 | { 128 | uint32_t val; 129 | 130 | /* Reset mbus domain */ 131 | val = read32(T113_CCU_BASE + CCU_MBUS_CLK_REG); 132 | val |= (0x1 << 30); 133 | write32(T113_CCU_BASE + CCU_MBUS_CLK_REG, val); 134 | sdelay(1); 135 | 136 | /* Enable mbus master clock gating */ 137 | write32(T113_CCU_BASE + CCU_MBUS_MAT_CLK_GATING_REG, 0x00000d87); 138 | } 139 | 140 | static void set_module(virtual_addr_t addr) 141 | { 142 | uint32_t val; 143 | 144 | if (!(read32(addr) & (1 << 31))) { 145 | val = read32(addr); 146 | write32(addr, val | (1 << 31) | (1 << 30)); 147 | 148 | /* Lock enable */ 149 | val = read32(addr); 150 | val |= (1 << 29); 151 | write32(addr, val); 152 | 153 | /* Wait pll stable */ 154 | while (!(read32(addr) & (0x1 << 28))) 155 | ; 156 | sdelay(20); 157 | 158 | /* Lock disable */ 159 | val = read32(addr); 160 | val &= ~(1 << 29); 161 | write32(addr, val); 162 | } 163 | } 164 | 165 | void sunxi_clk_init(void) 166 | { 167 | set_pll_cpux_axi(); 168 | set_pll_periph0(); 169 | set_ahb(); 170 | set_apb(); 171 | set_dma(); 172 | set_mbus(); 173 | set_module(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 174 | set_module(T113_CCU_BASE + CCU_PLL_VIDEO0_CTRL_REG); 175 | set_module(T113_CCU_BASE + CCU_PLL_VIDEO1_CTRL_REG); 176 | set_module(T113_CCU_BASE + CCU_PLL_VE_CTRL); 177 | set_module(T113_CCU_BASE + CCU_PLL_AUDIO0_CTRL_REG); 178 | set_module(T113_CCU_BASE + CCU_PLL_AUDIO1_CTRL_REG); 179 | } 180 | 181 | uint32_t sunxi_clk_get_peri1x_rate() 182 | { 183 | uint32_t reg32; 184 | uint8_t plln, pllm, p0; 185 | 186 | /* PLL PERIx */ 187 | reg32 = read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 188 | if (reg32 & (1 << 31)) { 189 | plln = ((reg32 >> 8) & 0xff) + 1; 190 | pllm = (reg32 & 0x01) + 1; 191 | p0 = ((reg32 >> 16) & 0x03) + 1; 192 | 193 | return ((((24 * plln) / (pllm * p0)) >> 1) * 1000 * 1000); 194 | } 195 | 196 | return 0; 197 | } 198 | 199 | #ifdef CONFIG_ENABLE_CPU_FREQ_DUMP 200 | void sunxi_clk_dump() 201 | { 202 | uint32_t reg32; 203 | uint32_t cpu_clk_src, plln, pllm; 204 | uint8_t p0, p1; 205 | const char *clock_str; 206 | 207 | /* PLL CPU */ 208 | reg32 = read32(T113_CCU_BASE + CCU_CPU_AXI_CFG_REG); 209 | cpu_clk_src = (reg32 >> 24) & 0x7; 210 | 211 | switch (cpu_clk_src) { 212 | case 0x0: 213 | clock_str = "OSC24M"; 214 | break; 215 | 216 | case 0x1: 217 | clock_str = "CLK32"; 218 | break; 219 | 220 | case 0x2: 221 | clock_str = "CLK16M_RC"; 222 | break; 223 | 224 | case 0x3: 225 | clock_str = "PLL_CPU"; 226 | break; 227 | 228 | case 0x4: 229 | clock_str = "PLL_PERI(1X)"; 230 | break; 231 | 232 | case 0x5: 233 | clock_str = "PLL_PERI(2X)"; 234 | break; 235 | 236 | case 0x6: 237 | clock_str = "PLL_PERI(800M)"; 238 | break; 239 | 240 | default: 241 | clock_str = "ERROR"; 242 | } 243 | 244 | reg32 = read32(T113_CCU_BASE + CCU_PLL_CPU_CTRL_REG); 245 | p0 = (reg32 >> 16) & 0x03; 246 | if (p0 == 0) { 247 | p1 = 1; 248 | } else if (p0 == 1) { 249 | p1 = 2; 250 | } else if (p0 == 2) { 251 | p1 = 4; 252 | } else { 253 | p1 = 1; 254 | } 255 | 256 | debug("CLK: CPU PLL=%s FREQ=%uMHz\r\n", clock_str, ((((reg32 >> 8) & 0xff) + 1) * 24 / p1)); 257 | 258 | /* PLL PERIx */ 259 | reg32 = read32(T113_CCU_BASE + CCU_PLL_PERI0_CTRL_REG); 260 | if (reg32 & (1 << 31)) { 261 | plln = ((reg32 >> 8) & 0xff) + 1; 262 | pllm = (reg32 & 0x01) + 1; 263 | p0 = ((reg32 >> 16) & 0x03) + 1; 264 | p1 = ((reg32 >> 20) & 0x03) + 1; 265 | 266 | debug("CLK: PLL_peri (2X)=%uMHz, (1X)=%uMHz, (800M)=%uMHz\r\n", (24 * plln) / (pllm * p0), 267 | (24 * plln) / (pllm * p0) >> 1, (24 * plln) / (pllm * p1)); 268 | } else { 269 | debug("CLK: PLL_peri disabled\r\n"); 270 | } 271 | 272 | /* PLL DDR */ 273 | reg32 = read32(T113_CCU_BASE + CCU_PLL_DDR_CTRL_REG); 274 | if (reg32 & (1 << 31)) { 275 | plln = ((reg32 >> 8) & 0xff) + 1; 276 | 277 | pllm = (reg32 & 0x01) + 1; 278 | p1 = ((reg32 >> 1) & 0x1) + 1; 279 | p0 = (reg32 & 0x01) + 1; 280 | 281 | debug("CLK: PLL_ddr=%uMHz\r\n", (24 * plln) / (p0 * p1)); 282 | 283 | } else { 284 | debug("CLK: PLL_ddr disabled\r\n"); 285 | } 286 | } 287 | #endif 288 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_clk.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_CLK_H__ 2 | #define __SUNXI_CLK_H__ 3 | 4 | #include "main.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_clk_init(void); 8 | uint32_t sunxi_clk_get_peri1x_rate(void); 9 | 10 | void sunxi_clk_dump(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_dma.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0+ */ 2 | /* 3 | * (C) Copyright 2015 Roy Spliet 4 | */ 5 | 6 | #include "types.h" 7 | 8 | #ifndef _SUNXI_DMA_H 9 | #define _SUNXI_DMA_H 10 | 11 | #define SUNXI_DMA_BASE 0x03002000 12 | #define SUNXI_DMA_CHANNEL_BASE (SUNXI_DMA_BASE + 0x100) 13 | #define DMA_AUTO_GATE_REG (SUNXI_DMA_BASE + 0x28) 14 | 15 | #define SUNXI_DMA_CHANNEL_SIZE (0x40) 16 | #define SUNXI_DMA_LINK_NULL (0xfffff800) 17 | 18 | #define DMAC_DMATYPE_NORMAL 0 19 | #define DMAC_CFG_TYPE_DRAM (1) 20 | #define DMAC_CFG_TYPE_SRAM (0) 21 | 22 | #define DMAC_CFG_TYPE_SPI0 (22) 23 | #define DMAC_CFG_TYPE_SHMC0 (20) 24 | #define DMAC_CFG_SRC_TYPE_NAND (5) 25 | 26 | /* DMA base config */ 27 | #define DMAC_CFG_CONTINUOUS_ENABLE (0x01) 28 | #define DMAC_CFG_CONTINUOUS_DISABLE (0x00) 29 | 30 | /* ----------DMA dest config-------------------- */ 31 | /* DMA dest width config */ 32 | #define DMAC_CFG_DEST_DATA_WIDTH_8BIT (0x00) 33 | #define DMAC_CFG_DEST_DATA_WIDTH_16BIT (0x01) 34 | #define DMAC_CFG_DEST_DATA_WIDTH_32BIT (0x02) 35 | #define DMAC_CFG_DEST_DATA_WIDTH_64BIT (0x03) 36 | 37 | /* DMA dest bust config */ 38 | #define DMAC_CFG_DEST_1_BURST (0x00) 39 | #define DMAC_CFG_DEST_4_BURST (0x01) 40 | #define DMAC_CFG_DEST_8_BURST (0x02) 41 | #define DMAC_CFG_DEST_16_BURST (0x03) 42 | 43 | #define DMAC_CFG_DEST_ADDR_TYPE_LINEAR_MODE (0x00) 44 | #define DMAC_CFG_DEST_ADDR_TYPE_IO_MODE (0x01) 45 | 46 | /* ----------DMA src config -------------------*/ 47 | #define DMAC_CFG_SRC_DATA_WIDTH_8BIT (0x00) 48 | #define DMAC_CFG_SRC_DATA_WIDTH_16BIT (0x01) 49 | #define DMAC_CFG_SRC_DATA_WIDTH_32BIT (0x02) 50 | #define DMAC_CFG_SRC_DATA_WIDTH_64BIT (0x03) 51 | 52 | #define DMAC_CFG_SRC_1_BURST (0x00) 53 | #define DMAC_CFG_SRC_4_BURST (0x01) 54 | #define DMAC_CFG_SRC_8_BURST (0x02) 55 | #define DMAC_CFG_SRC_16_BURST (0x03) 56 | 57 | #define DMAC_CFG_SRC_ADDR_TYPE_LINEAR_MODE (0x00) 58 | #define DMAC_CFG_SRC_ADDR_TYPE_IO_MODE (0x01) 59 | 60 | /*dma int config*/ 61 | #define DMA_PKG_HALF_INT (1 << 0) 62 | #define DMA_PKG_END_INT (1 << 1) 63 | #define DMA_QUEUE_END_INT (1 << 2) 64 | 65 | typedef struct { 66 | u32 volatile config; 67 | u32 volatile source_addr; 68 | u32 volatile dest_addr; 69 | u32 volatile byte_count; 70 | u32 volatile commit_para; 71 | u32 volatile link; 72 | u32 volatile reserved[2]; 73 | } dma_desc_t; 74 | 75 | typedef struct { 76 | u32 volatile src_drq_type : 6; 77 | u32 volatile src_burst_length : 2; 78 | u32 volatile src_addr_mode : 1; 79 | u32 volatile src_data_width : 2; 80 | u32 volatile reserved0 : 5; 81 | u32 volatile dst_drq_type : 6; 82 | u32 volatile dst_burst_length : 2; 83 | u32 volatile dst_addr_mode : 1; 84 | u32 volatile dst_data_width : 2; 85 | u32 volatile reserved1 : 5; 86 | } dma_channel_config_t; 87 | 88 | typedef struct { 89 | dma_channel_config_t channel_cfg; 90 | u32 loop_mode; 91 | u32 data_block_size; 92 | u32 wait_cyc; 93 | } dma_set_t; 94 | 95 | typedef struct { 96 | void *m_data; 97 | // void (*m_func)(void *data); 98 | void (*m_func)(void); 99 | } dma_irq_handler_t; 100 | 101 | typedef struct { 102 | u32 volatile enable; 103 | u32 volatile pause; 104 | u32 volatile desc_addr; 105 | u32 volatile config; 106 | u32 volatile cur_src_addr; 107 | u32 volatile cur_dst_addr; 108 | u32 volatile left_bytes; 109 | u32 volatile parameters; 110 | u32 volatile mode; 111 | u32 volatile fdesc_addr; 112 | u32 volatile pkg_num; 113 | u32 volatile res[5]; 114 | } dma_channel_reg_t; 115 | 116 | typedef struct { 117 | u32 volatile irq_en0; /* 0x0 dma irq enable register 0 */ 118 | u32 volatile irq_en1; /* 0x4 dma irq enable register 1 */ 119 | u32 volatile reserved0[2]; 120 | u32 volatile irq_pending0; /* 0x10 dma irq pending register 0 */ 121 | u32 volatile irq_pending1; /* 0x14 dma irq pending register 1 */ 122 | u32 volatile reserved1[2]; 123 | u32 volatile security; /* 0x20 dma security register */ 124 | u32 volatile reserved3[1]; 125 | u32 volatile auto_gate; /* 0x28 dma auto gating register */ 126 | u32 volatile reserved4[1]; 127 | u32 volatile status; /* 0x30 dma status register */ 128 | u32 volatile reserved5[3]; 129 | u32 volatile version; /* 0x40 dma Version register */ 130 | u32 volatile reserved6[47]; 131 | dma_channel_reg_t channel[16]; /* 0x100 dma channel register */ 132 | } dma_reg_t; 133 | 134 | typedef struct { 135 | u32 used; 136 | u32 channel_count; 137 | dma_channel_reg_t *channel; 138 | u32 reserved; 139 | dma_desc_t *desc; 140 | dma_irq_handler_t dma_func; 141 | } dma_source_t; 142 | 143 | #define DMA_RST_OFS 16 144 | #define DMA_GATING_OFS 0 145 | 146 | void dma_init(void); 147 | void dma_exit(void); 148 | 149 | u32 dma_request(u32 dmatype); 150 | u32 dma_request_from_last(u32 dmatype); 151 | int dma_release(u32 hdma); 152 | int dma_setting(u32 hdma, dma_set_t *cfg); 153 | int dma_start(u32 hdma, u32 saddr, u32 daddr, u32 bytes); 154 | int dma_stop(u32 hdma); 155 | int dma_querystatus(u32 hdma); 156 | 157 | int dma_test(); 158 | 159 | #endif /* _SUNXI_DMA_H */ 160 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_gpio.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "debug.h" 3 | #include "sunxi_gpio.h" 4 | 5 | enum { 6 | GPIO_CFG0 = 0x00, 7 | GPIO_CFG1 = 0x04, 8 | GPIO_CFG2 = 0x08, 9 | GPIO_CFG3 = 0x0c, 10 | GPIO_DAT = 0x10, 11 | GPIO_DRV0 = 0x14, 12 | GPIO_DRV1 = 0x18, 13 | GPIO_DRV2 = 0x1c, 14 | GPIO_DRV3 = 0x20, 15 | GPIO_PUL0 = 0x24, 16 | GPIO_PUL1 = 0x28, 17 | }; 18 | 19 | static inline uint32_t _port_num(gpio_t pin) 20 | { 21 | return pin >> PIO_NUM_IO_BITS; 22 | } 23 | 24 | static uint32_t _port_base_get(gpio_t pin) 25 | { 26 | uint32_t port = pin >> PIO_NUM_IO_BITS; 27 | 28 | switch (port) { 29 | case PORTB: 30 | return 0x02000030; 31 | break; 32 | case PORTC: 33 | return 0x02000060; 34 | break; 35 | case PORTD: 36 | return 0x02000090; 37 | break; 38 | case PORTE: 39 | return 0x020000c0; 40 | break; 41 | case PORTF: 42 | return 0x020000f0; 43 | break; 44 | case PORTG: 45 | return 0x02000120; 46 | break; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | static inline uint32_t _pin_num(gpio_t pin) 53 | { 54 | return (pin & ((1 << PIO_NUM_IO_BITS) - 1)); 55 | } 56 | 57 | void sunxi_gpio_init(gpio_t pin, int cfg) 58 | { 59 | uint32_t port_addr = _port_base_get(pin); 60 | uint32_t pin_num = _pin_num(pin); 61 | uint32_t addr; 62 | uint32_t val; 63 | 64 | addr = port_addr + GPIO_CFG0 + ((pin_num >> 3) << 2); 65 | val = read32(addr); 66 | val &= ~(0xf << ((pin_num & 0x7) << 2)); 67 | val |= ((cfg & 0xf) << ((pin_num & 0x7) << 2)); 68 | write32(addr, val); 69 | } 70 | 71 | void sunxi_gpio_set_value(gpio_t pin, int value) 72 | { 73 | uint32_t port_addr = _port_base_get(pin); 74 | uint32_t pin_num = _pin_num(pin); 75 | uint32_t val; 76 | 77 | val = read32(port_addr + GPIO_DAT); 78 | val &= ~(1 << pin_num); 79 | val |= (!!value) << pin_num; 80 | write32(port_addr + GPIO_DAT, val); 81 | } 82 | 83 | int sunxi_gpio_read(gpio_t pin) 84 | { 85 | uint32_t port_addr = _port_base_get(pin); 86 | uint32_t pin_num = _pin_num(pin); 87 | uint32_t val; 88 | 89 | val = read32(port_addr + GPIO_DAT); 90 | return !!(val & (1 << pin_num)); 91 | } 92 | 93 | void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull) 94 | { 95 | uint32_t port_addr = _port_base_get(pin); 96 | uint32_t pin_num = _pin_num(pin); 97 | uint32_t addr; 98 | uint32_t val, v; 99 | 100 | switch (pull) { 101 | case GPIO_PULL_UP: 102 | v = 0x1; 103 | break; 104 | 105 | case GPIO_PULL_DOWN: 106 | v = 0x2; 107 | break; 108 | 109 | case GPIO_PULL_NONE: 110 | v = 0x0; 111 | break; 112 | 113 | default: 114 | v = 0x0; 115 | break; 116 | } 117 | 118 | addr = port_addr + GPIO_PUL0 + ((pin_num >> 4) << 2); 119 | val = read32(addr); 120 | val &= ~(v << ((pin_num & 0xf) << 1)); 121 | val |= (v << ((pin_num & 0xf) << 1)); 122 | write32(addr, val); 123 | } 124 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_GPIO_H__ 2 | #define __SUNXI_GPIO_H__ 3 | 4 | #include 5 | 6 | enum { 7 | GPIO_INPUT = 0, 8 | GPIO_OUTPUT = 1, 9 | GPIO_PERIPH_MUX2 = 2, 10 | GPIO_PERIPH_MUX3 = 3, 11 | GPIO_PERIPH_MUX4 = 4, 12 | GPIO_PERIPH_MUX5 = 5, 13 | GPIO_PERIPH_MUX6 = 6, 14 | GPIO_PERIPH_MUX7 = 7, 15 | GPIO_PERIPH_MUX8 = 8, 16 | GPIO_PERIPH_MUX14 = 14, 17 | GPIO_DISABLED = 0xf, 18 | }; 19 | 20 | #define PORTB 0 21 | #define PORTC 1 22 | #define PORTD 2 23 | #define PORTE 3 24 | #define PORTF 4 25 | #define PORTG 5 26 | #define SUNXI_GPIO_PORTS (PORTG + 1) 27 | 28 | enum gpio_pull_t { 29 | GPIO_PULL_UP = 0, 30 | GPIO_PULL_DOWN = 1, 31 | GPIO_PULL_NONE = 2, 32 | }; 33 | 34 | typedef uint32_t gpio_t; 35 | #define PIO_NUM_IO_BITS 5 36 | 37 | #define GPIO_PIN(x, y) (((uint32_t)(x << PIO_NUM_IO_BITS)) | y) 38 | 39 | typedef struct { 40 | gpio_t pin; 41 | uint8_t mux; 42 | } gpio_mux_t; 43 | 44 | extern void sunxi_gpio_init(gpio_t pin, int cfg); 45 | extern void sunxi_gpio_set_value(gpio_t pin, int value); 46 | extern int sunxi_gpio_read(gpio_t pin); 47 | extern void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull); 48 | 49 | #endif -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_sdhci.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDHCI_H__ 2 | #define __SDHCI_H__ 3 | 4 | #include "sunxi_gpio.h" 5 | 6 | typedef enum { 7 | MMC_CLK_400K = 0, 8 | MMC_CLK_25M, 9 | MMC_CLK_50M, 10 | MMC_CLK_50M_DDR, 11 | MMC_CLK_100M, 12 | MMC_CLK_150M, 13 | MMC_CLK_200M 14 | } smhc_clk_t; 15 | 16 | typedef struct { 17 | volatile u32 gctrl; /* (0x00) SMC Global Control Register */ 18 | volatile u32 clkcr; /* (0x04) SMC Clock Control Register */ 19 | volatile u32 timeout; /* (0x08) SMC Time Out Register */ 20 | volatile u32 width; /* (0x0C) SMC Bus Width Register */ 21 | volatile u32 blksz; /* (0x10) SMC Block Size Register */ 22 | volatile u32 bytecnt; /* (0x14) SMC Byte Count Register */ 23 | volatile u32 cmd; /* (0x18) SMC Command Register */ 24 | volatile u32 arg; /* (0x1C) SMC Argument Register */ 25 | volatile u32 resp0; /* (0x20) SMC Response Register 0 */ 26 | volatile u32 resp1; /* (0x24) SMC Response Register 1 */ 27 | volatile u32 resp2; /* (0x28) SMC Response Register 2 */ 28 | volatile u32 resp3; /* (0x2C) SMC Response Register 3 */ 29 | volatile u32 imask; /* (0x30) SMC Interrupt Mask Register */ 30 | volatile u32 mint; /* (0x34) SMC Masked Interrupt Status Register */ 31 | volatile u32 rint; /* (0x38) SMC Raw Interrupt Status Register */ 32 | volatile u32 status; /* (0x3C) SMC Status Register */ 33 | volatile u32 ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Register */ 34 | volatile u32 funcsel; /* (0x44) SMC Function Select Register */ 35 | volatile u32 cbcr; /* (0x48) SMC CIU Byte Count Register */ 36 | volatile u32 bbcr; /* (0x4C) SMC BIU Byte Count Register */ 37 | volatile u32 dbgc; /* (0x50) SMC Debug Enable Register */ 38 | volatile u32 csdc; /* (0x54) CRC status detect control register*/ 39 | volatile u32 a12a; /* (0x58)Auto command 12 argument*/ 40 | volatile u32 ntsr; /* (0x5c)SMC2 Newtiming Set Register */ 41 | volatile u32 res1[6]; /* (0x60~0x74) */ 42 | volatile u32 hwrst; /* (0x78) SMC eMMC Hardware Reset Register */ 43 | volatile u32 res2; /* (0x7c) */ 44 | volatile u32 dmac; /* (0x80) SMC IDMAC Control Register */ 45 | volatile u32 dlba; /* (0x84) SMC IDMAC Descriptor List Base Address Register */ 46 | volatile u32 idst; /* (0x88) SMC IDMAC Status Register */ 47 | volatile u32 idie; /* (0x8C) SMC IDMAC Interrupt Enable Register */ 48 | volatile u32 chda; /* (0x90) */ 49 | volatile u32 cbda; /* (0x94) */ 50 | volatile u32 res3[26]; /* (0x98~0xff) */ 51 | volatile u32 thldc; /* (0x100) Card Threshold Control Register */ 52 | volatile u32 sfc; /* (0x104) Sample Fifo Control Register */ 53 | volatile u32 res4[1]; /* (0x10b) */ 54 | volatile u32 dsbd; /* (0x10c) eMMC4.5 DDR Start Bit Detection Control */ 55 | volatile u32 res5[12]; /* (0x110~0x13c) */ 56 | volatile u32 drv_dl; /* (0x140) Drive Delay Control register*/ 57 | volatile u32 samp_dl; /* (0x144) Sample Delay Control register*/ 58 | volatile u32 ds_dl; /* (0x148) Data Strobe Delay Control Register */ 59 | volatile u32 ntdc; /* (0x14C) HS400 New Timing Delay Control Register */ 60 | volatile u32 res6[4]; /* (0x150~0x15f) */ 61 | volatile u32 skew_dat0_dl; /*(0x160) deskew data0 delay control register*/ 62 | volatile u32 skew_dat1_dl; /*(0x164) deskew data1 delay control register*/ 63 | volatile u32 skew_dat2_dl; /*(0x168) deskew data2 delay control register*/ 64 | volatile u32 skew_dat3_dl; /*(0x16c) deskew data3 delay control register*/ 65 | volatile u32 skew_dat4_dl; /*(0x170) deskew data4 delay control register*/ 66 | volatile u32 skew_dat5_dl; /*(0x174) deskew data5 delay control register*/ 67 | volatile u32 skew_dat6_dl; /*(0x178) deskew data6 delay control register*/ 68 | volatile u32 skew_dat7_dl; /*(0x17c) deskew data7 delay control register*/ 69 | volatile u32 skew_ds_dl; /*(0x180) deskew ds delay control register*/ 70 | volatile u32 skew_ctrl; /*(0x184) deskew control control register*/ 71 | volatile u32 res8[30]; /* (0x188~0x1ff) */ 72 | volatile u32 fifo; /* (0x200) SMC FIFO Access Address */ 73 | volatile u32 res7[63]; /* (0x201~0x2FF)*/ 74 | volatile u32 vers; /* (0x300) SMHC Version Register */ 75 | } sdhci_reg_t; 76 | 77 | typedef struct { 78 | u32 idx; 79 | u32 arg; 80 | u32 resptype; 81 | u32 response[4]; 82 | } sdhci_cmd_t; 83 | 84 | typedef struct { 85 | u8 *buf; 86 | u32 flag; 87 | u32 blksz; 88 | u32 blkcnt; 89 | } sdhci_data_t; 90 | 91 | #define SMHC_DES_NUM_SHIFT 12 /* smhc2!! */ 92 | #define SMHC_DES_BUFFER_MAX_LEN (1 << SMHC_DES_NUM_SHIFT) 93 | typedef struct { 94 | u32 : 1, dic : 1, /* disable interrupt on completion */ 95 | last_desc : 1, /* 1-this data buffer is the last buffer */ 96 | first_desc : 1, /* 1-data buffer is the first buffer, 0-data buffer contained in the next descriptor is 1st 97 | buffer */ 98 | des_chain : 1, /* 1-the 2nd address in the descriptor is the next descriptor address */ 99 | // end_of_ring : 1, /* 1-last descriptor flag when using dual data buffer in descriptor */ 100 | : 25, err_flag : 1, /* transfer error flag */ 101 | own : 1; /* des owner:1-idma owns it, 0-host owns it */ 102 | 103 | u32 data_buf_sz : SMHC_DES_NUM_SHIFT, data_buf_dummy : (32 - SMHC_DES_NUM_SHIFT); 104 | 105 | u32 buf_addr; 106 | u32 next_desc_addr; 107 | 108 | } sdhci_idma_desc_t __attribute__((aligned(8))); 109 | 110 | typedef struct { 111 | char *name; 112 | sdhci_reg_t *reg; 113 | u32 reset; 114 | 115 | u32 voltage; 116 | u32 width; 117 | smhc_clk_t clock; 118 | u32 pclk; 119 | u8 odly[6]; 120 | u8 sdly[6]; 121 | 122 | sdhci_idma_desc_t dma_desc[32]; 123 | u32 dma_trglvl; 124 | 125 | bool removable; 126 | bool isspi; 127 | 128 | gpio_mux_t gpio_d0; 129 | gpio_mux_t gpio_d1; 130 | gpio_mux_t gpio_d2; 131 | gpio_mux_t gpio_d3; 132 | gpio_mux_t gpio_cmd; 133 | gpio_mux_t gpio_clk; 134 | 135 | } sdhci_t; 136 | 137 | extern sdhci_t sdhci0; 138 | 139 | bool sdhci_reset(sdhci_t *hci); 140 | bool sdhci_set_voltage(sdhci_t *hci, u32 voltage); 141 | bool sdhci_set_width(sdhci_t *hci, u32 width); 142 | bool sdhci_set_clock(sdhci_t *hci, smhc_clk_t hz); 143 | bool sdhci_transfer(sdhci_t *hci, sdhci_cmd_t *cmd, sdhci_data_t *dat); 144 | int sunxi_sdhci_init(sdhci_t *sdhci); 145 | 146 | #endif /* __SDHCI_H__ */ 147 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_SPI_H__ 2 | #define __SUNXI_SPI_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef enum { 8 | SPI_IO_SINGLE = 0x00, 9 | SPI_IO_DUAL_RX, 10 | SPI_IO_QUAD_RX, 11 | SPI_IO_QUAD_IO, 12 | } spi_io_mode_t; 13 | 14 | typedef struct { 15 | uint8_t mfr; 16 | uint16_t dev; 17 | uint8_t dlen; 18 | } __attribute__((packed)) spi_nand_id_t; 19 | 20 | typedef struct { 21 | char *name; 22 | spi_nand_id_t id; 23 | uint32_t page_size; 24 | uint32_t spare_size; 25 | uint32_t pages_per_block; 26 | uint32_t blocks_per_die; 27 | uint32_t planes_per_die; 28 | uint32_t ndies; 29 | spi_io_mode_t mode; 30 | } spi_nand_info_t; 31 | 32 | typedef struct { 33 | uint32_t base; 34 | uint8_t id; 35 | uint32_t clk_rate; 36 | gpio_mux_t gpio_cs; 37 | gpio_mux_t gpio_sck; 38 | gpio_mux_t gpio_miso; 39 | gpio_mux_t gpio_mosi; 40 | gpio_mux_t gpio_wp; 41 | gpio_mux_t gpio_hold; 42 | 43 | spi_nand_info_t info; 44 | } sunxi_spi_t; 45 | 46 | int sunxi_spi_init(sunxi_spi_t *spi); 47 | void sunxi_spi_disable(sunxi_spi_t *spi); 48 | int spi_nand_detect(sunxi_spi_t *spi); 49 | uint32_t spi_nand_read(sunxi_spi_t *spi, uint8_t *buf, uint32_t addr, uint32_t rxlen); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_usart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "io.h" 3 | #include "main.h" 4 | #include "sunxi_usart.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_usart_init(sunxi_usart_t *usart) 8 | { 9 | uint32_t addr; 10 | uint32_t val; 11 | 12 | /* Config usart TXD and RXD pins */ 13 | sunxi_gpio_init(usart->gpio_tx.pin, usart->gpio_tx.mux); 14 | sunxi_gpio_init(usart->gpio_rx.pin, usart->gpio_rx.mux); 15 | 16 | /* Open the clock gate for usart */ 17 | addr = T113_CCU_BASE + CCU_USART_BGR_REG; 18 | val = read32(addr); 19 | val |= 1 << usart->id; 20 | write32(addr, val); 21 | 22 | /* Deassert USART reset */ 23 | addr = T113_CCU_BASE + CCU_USART_BGR_REG; 24 | val = read32(addr); 25 | val |= 1 << (16 + usart->id); 26 | write32(addr, val); 27 | 28 | /* Config USART to 115200-8-1-0 */ 29 | addr = usart->base; 30 | write32(addr + 0x04, 0x0); 31 | write32(addr + 0x08, 0xf7); 32 | write32(addr + 0x10, 0x0); 33 | val = read32(addr + 0x0c); 34 | val |= (1 << 7); 35 | write32(addr + 0x0c, val); 36 | write32(addr + 0x00, 0xd & 0xff); 37 | write32(addr + 0x04, (0xd >> 8) & 0xff); 38 | val = read32(addr + 0x0c); 39 | val &= ~(1 << 7); 40 | write32(addr + 0x0c, val); 41 | val = read32(addr + 0x0c); 42 | val &= ~0x1f; 43 | val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); 44 | write32(addr + 0x0c, val); 45 | } 46 | 47 | void sunxi_usart_putc(void *arg, char c) 48 | { 49 | sunxi_usart_t *usart = (sunxi_usart_t *)arg; 50 | 51 | while ((read32(usart->base + 0x7c) & (0x1 << 1)) == 0) 52 | ; 53 | write32(usart->base + 0x00, c); 54 | while ((read32(usart->base + 0x7c) & (0x1 << 0)) == 1) 55 | ; 56 | } 57 | -------------------------------------------------------------------------------- /arch/arm32/mach-t113s4/sunxi_usart.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_USART_H__ 2 | #define __SUNXI_USART_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef struct { 8 | uint32_t base; 9 | uint8_t id; 10 | gpio_mux_t gpio_tx; 11 | gpio_mux_t gpio_rx; 12 | } sunxi_usart_t; 13 | 14 | extern void sunxi_usart_init(sunxi_usart_t *usart); 15 | extern void sunxi_usart_putc(void *arg, char c); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/arch_timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2018-2020 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * wangwei 6 | * 7 | */ 8 | 9 | #include "main.h" 10 | #include "io.h" 11 | 12 | /* 13 | * 64bit arch timer.CNTPCT 14 | * Freq = 24000000Hz 15 | */ 16 | uint64_t get_arch_counter(void) 17 | { 18 | uint32_t low = 0, high = 0; 19 | asm volatile("mrrc p15, 0, %0, %1, c14" : "=r"(low), "=r"(high) : : "memory"); 20 | return ((uint64_t)high << 32) | (uint64_t)low; 21 | } 22 | 23 | /* 24 | * get current time.(millisecond) 25 | */ 26 | uint32_t time_ms(void) 27 | { 28 | return get_arch_counter() / 24000; 29 | } 30 | 31 | /* 32 | * get current time.(microsecond) 33 | */ 34 | uint64_t time_us(void) 35 | { 36 | return get_arch_counter() / (uint64_t)24; 37 | } 38 | 39 | void udelay(uint64_t us) 40 | { 41 | uint64_t now; 42 | 43 | now = time_us(); 44 | while (time_us() - now < us) { 45 | }; 46 | } 47 | 48 | void mdelay(uint32_t ms) 49 | { 50 | udelay(ms * 1000); 51 | uint32_t now; 52 | 53 | now = time_ms(); 54 | while (time_ms() - now < ms) { 55 | }; 56 | } 57 | 58 | /************************************************************ 59 | * sdelay() - simple spin loop. Will be constant time as 60 | * its generally used in bypass conditions only. This 61 | * is necessary until timers are accessible. 62 | * 63 | * not inline to increase chances its in cache when called 64 | *************************************************************/ 65 | void sdelay(uint32_t loops) 66 | { 67 | __asm__ volatile("1:\n" 68 | "subs %0, %1, #1\n" 69 | "bne 1b" 70 | : "=r"(loops) 71 | : "0"(loops)); 72 | } 73 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2007-2013 3 | * SPDX-License-Identifier: GPL-2.0+ 4 | * Allwinner Technology Co., Ltd. 5 | * Jerry Wang 6 | * 7 | * See file CREDITS for list of people who contributed to this 8 | * project. 9 | * 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License as 12 | * published by the Free Software Foundation; either version 2 of 13 | * the License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 | * MA 02111-1307 USA 24 | */ 25 | 26 | #ifndef __dram_head_h__ 27 | #define __dram_head_h__ 28 | 29 | #define SDRAM_BASE (0x40000000) 30 | 31 | enum sunxi_dram_type { 32 | SUNXI_DRAM_TYPE_DDR2 = 2, 33 | SUNXI_DRAM_TYPE_DDR3 = 3, 34 | SUNXI_DRAM_TYPE_LPDDR2 = 6, 35 | SUNXI_DRAM_TYPE_LPDDR3 = 7, 36 | }; 37 | 38 | typedef struct __DRAM_PARA { 39 | // normal configuration 40 | unsigned int dram_clk; 41 | unsigned int dram_type; // dram_type DDR2: 2 DDR3: 3 LPDDR2: 6 LPDDR3: 7 DDR3L: 31 42 | // unsigned int lpddr2_type; //LPDDR2 type S4:0 S2:1 NVM:2 43 | unsigned int dram_zq; // do not need 44 | unsigned int dram_odt_en; 45 | 46 | // control configuration 47 | unsigned int dram_para1; 48 | unsigned int dram_para2; 49 | 50 | // timing configuration 51 | unsigned int dram_mr0; 52 | unsigned int dram_mr1; 53 | unsigned int dram_mr2; 54 | unsigned int dram_mr3; 55 | unsigned int dram_tpr0; // DRAMTMG0 56 | unsigned int dram_tpr1; // DRAMTMG1 57 | unsigned int dram_tpr2; // DRAMTMG2 58 | unsigned int dram_tpr3; // DRAMTMG3 59 | unsigned int dram_tpr4; // DRAMTMG4 60 | unsigned int dram_tpr5; // DRAMTMG5 61 | unsigned int dram_tpr6; // DRAMTMG8 62 | // reserved for future use 63 | unsigned int dram_tpr7; 64 | unsigned int dram_tpr8; 65 | unsigned int dram_tpr9; 66 | unsigned int dram_tpr10; 67 | unsigned int dram_tpr11; 68 | unsigned int dram_tpr12; 69 | unsigned int dram_tpr13; 70 | 71 | } dram_para_t; 72 | 73 | int init_DRAM(int type, dram_para_t *para); 74 | unsigned long sunxi_dram_init(void); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/exception.c: -------------------------------------------------------------------------------- 1 | /* 2 | * exception.c 3 | * 4 | * Copyright(c) 2007-2022 Jianjun Jiang <8192542@qq.com> 5 | * Official site: http://xboot.org 6 | * Mobile phone: +86-18665388956 7 | * QQ: 8192542 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include 30 | #include "debug.h" 31 | #include "main.h" 32 | 33 | struct arm_regs_t { 34 | uint32_t esp; 35 | uint32_t cpsr; 36 | uint32_t r[13]; 37 | uint32_t sp; 38 | uint32_t lr; 39 | uint32_t pc; 40 | }; 41 | 42 | static void show_regs(struct arm_regs_t *regs) 43 | { 44 | int i; 45 | 46 | error("pc : [<%08lx>] lr : [<%08lx>] cpsr: %08lx\r\n", regs->pc, regs->lr, regs->cpsr); 47 | error("sp : %08lx esp : %08lx\r\n", regs->sp, regs->esp); 48 | for (i = 12; i >= 0; i--) 49 | error("r%-2d: %08lx\r\n", i, regs->r[i]); 50 | error("\r\n"); 51 | } 52 | 53 | void arm32_do_undefined_instruction(struct arm_regs_t *regs) 54 | { 55 | show_regs(regs); 56 | // regs->pc += 4; 57 | fatal("undefined_instruction\r\n"); 58 | } 59 | 60 | void arm32_do_software_interrupt(struct arm_regs_t *regs) 61 | { 62 | show_regs(regs); 63 | // regs->pc += 4; 64 | fatal("software_interrupt\r\n"); 65 | } 66 | 67 | void arm32_do_prefetch_abort(struct arm_regs_t *regs) 68 | { 69 | show_regs(regs); 70 | // regs->pc += 4; 71 | fatal("prefetch_abort\r\n"); 72 | } 73 | 74 | void arm32_do_data_abort(struct arm_regs_t *regs) 75 | { 76 | show_regs(regs); 77 | // regs->pc += 4; 78 | fatal("data_abort\r\n"); 79 | } 80 | 81 | void arm32_do_irq(struct arm_regs_t *regs) 82 | { 83 | show_regs(regs); 84 | // regs->pc += 4; 85 | fatal("undefined IRQ\r\n"); 86 | } 87 | 88 | void arm32_do_fiq(struct arm_regs_t *regs) 89 | { 90 | show_regs(regs); 91 | // regs->pc += 4; 92 | fatal("undefined FIQ\r\n"); 93 | } 94 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/link.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * 4 | * \brief Linker script for T113-S3 internal SRAM 5 | * 6 | * based on: Linker script for running in internal FLASH on the SAMD21G17D 7 | * Copyright (c) 2018 Microchip Technology Inc. 8 | * 9 | * \asf_license_start 10 | * 11 | * \page License 12 | * 13 | * SPDX-License-Identifier: Apache-2.0 14 | * 15 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 16 | * not use this file except in compliance with the License. 17 | * You may obtain a copy of the Licence at 18 | * 19 | * http://www.apache.org/licenses/LICENSE-2.0 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 23 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | * 27 | * \asf_license_stop 28 | * 29 | */ 30 | 31 | /* This file gets parsed by the preprocessor */ 32 | 33 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 34 | OUTPUT_ARCH(arm) 35 | SEARCH_DIR(.) 36 | 37 | /* Memory Spaces Definitions */ 38 | MEMORY 39 | { 40 | ram (rwx) : ORIGIN = __RAM_BASE, LENGTH = 128K /* SRAMC. 132K on boot mode, 100K on FEL mode */ 41 | } 42 | 43 | /* The stack size used by the application. NOTE: you need to adjust according to your application. */ 44 | STACK_SIZE = 0x1000; /* 4KB */ 45 | 46 | /* Section Definitions */ 47 | SECTIONS 48 | { 49 | 50 | .text : 51 | { 52 | . = ALIGN(4); 53 | PROVIDE(__spl_start = .); 54 | *(.text .text.*) 55 | . = ALIGN(4); 56 | } > ram 57 | 58 | . = ALIGN(4); 59 | 60 | .ARM.exidx : { 61 | __exidx_start = .; 62 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 63 | __exidx_end = .; 64 | } > ram 65 | 66 | PROVIDE(__spl_end = .); 67 | PROVIDE(__spl_size = __spl_end - __spl_start); 68 | 69 | /* .bss section which is used for uninitialized data */ 70 | .bss (NOLOAD) : 71 | { 72 | . = ALIGN(4); 73 | _sbss = . ; 74 | *(.bss .bss.*) 75 | *(COMMON) 76 | . = ALIGN(4); 77 | _ebss = . ; 78 | } > ram 79 | 80 | .stack (NOLOAD): 81 | { 82 | . = ALIGN(8); 83 | /* SRV stack section */ 84 | __stack_srv_start = .; 85 | . += STACK_SIZE; 86 | __stack_srv_end = .; 87 | } > ram 88 | 89 | . = ALIGN(4); 90 | _end = . ; 91 | } 92 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/memcpy.S: -------------------------------------------------------------------------------- 1 | /* 2 | * NEON code contributed by Siarhei Siamashka . 3 | * Origin: http://sourceware.org/ml/libc-ports/2009-07/msg00003.html 4 | * 5 | * The GNU C Library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public License. 7 | * 8 | * tweaked for Android by Jim Huang 9 | */ 10 | 11 | .text 12 | .fpu neon 13 | 14 | .global memcpy 15 | .type memcpy, %function 16 | .align 4 17 | 18 | /* 19 | * ENABLE_UNALIGNED_MEM_ACCESSES macro can be defined to permit the use 20 | * of unaligned load/store memory accesses supported since ARMv6. This 21 | * will further improve performance, but can purely theoretically cause 22 | * problems if somebody decides to set SCTLR.A bit in the OS kernel 23 | * (to trap each unaligned memory access) or somehow mess with strongly 24 | * ordered/device memory. 25 | */ 26 | #define ENABLE_UNALIGNED_MEM_ACCESSES 1 27 | 28 | #define NEON_MAX_PREFETCH_DISTANCE 320 29 | 30 | memcpy: 31 | .fnstart 32 | mov ip, r0 33 | cmp r2, #16 34 | blt 4f @ Have less than 16 bytes to copy 35 | 36 | @ First ensure 16 byte alignment for the destination buffer 37 | tst r0, #0xF 38 | beq 2f 39 | tst r0, #1 40 | ldrneb r3, [r1], #1 41 | strneb r3, [ip], #1 42 | subne r2, r2, #1 43 | tst ip, #2 44 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 45 | ldrneh r3, [r1], #2 46 | strneh r3, [ip], #2 47 | #else 48 | ldrneb r3, [r1], #1 49 | strneb r3, [ip], #1 50 | ldrneb r3, [r1], #1 51 | strneb r3, [ip], #1 52 | #endif 53 | subne r2, r2, #2 54 | 55 | tst ip, #4 56 | beq 1f 57 | vld4.8 {d0[0], d1[0], d2[0], d3[0]}, [r1]! 58 | vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [ip, :32]! 59 | sub r2, r2, #4 60 | 1: 61 | tst ip, #8 62 | beq 2f 63 | vld1.8 {d0}, [r1]! 64 | vst1.8 {d0}, [ip, :64]! 65 | sub r2, r2, #8 66 | 2: 67 | subs r2, r2, #32 68 | blt 3f 69 | mov r3, #32 70 | 71 | @ Main copy loop, 32 bytes are processed per iteration. 72 | @ ARM instructions are used for doing fine-grained prefetch, 73 | @ increasing prefetch distance progressively up to 74 | @ NEON_MAX_PREFETCH_DISTANCE at runtime 75 | 1: 76 | vld1.8 {d0-d3}, [r1]! 77 | cmp r3, #(NEON_MAX_PREFETCH_DISTANCE - 32) 78 | pld [r1, r3] 79 | addle r3, r3, #32 80 | vst1.8 {d0-d3}, [ip, :128]! 81 | sub r2, r2, #32 82 | cmp r2, r3 83 | bge 1b 84 | cmp r2, #0 85 | blt 3f 86 | 1: @ Copy the remaining part of the buffer (already prefetched) 87 | vld1.8 {d0-d3}, [r1]! 88 | subs r2, r2, #32 89 | vst1.8 {d0-d3}, [ip, :128]! 90 | bge 1b 91 | 3: @ Copy up to 31 remaining bytes 92 | tst r2, #16 93 | beq 4f 94 | vld1.8 {d0, d1}, [r1]! 95 | vst1.8 {d0, d1}, [ip, :128]! 96 | 4: 97 | @ Use ARM instructions exclusively for the final trailing part 98 | @ not fully fitting into full 16 byte aligned block in order 99 | @ to avoid "ARM store after NEON store" hazard. Also NEON 100 | @ pipeline will be (mostly) flushed by the time when the 101 | @ control returns to the caller, making the use of NEON mostly 102 | @ transparent (and avoiding hazards in the caller code) 103 | 104 | #ifdef ENABLE_UNALIGNED_MEM_ACCESSES 105 | movs r3, r2, lsl #29 106 | ldrcs r3, [r1], #4 107 | strcs r3, [ip], #4 108 | ldrcs r3, [r1], #4 109 | strcs r3, [ip], #4 110 | ldrmi r3, [r1], #4 111 | strmi r3, [ip], #4 112 | movs r2, r2, lsl #31 113 | ldrcsh r3, [r1], #2 114 | strcsh r3, [ip], #2 115 | ldrmib r3, [r1], #1 116 | strmib r3, [ip], #1 117 | #else 118 | movs r3, r2, lsl #29 119 | bcc 1f 120 | .rept 8 121 | ldrcsb r3, [r1], #1 122 | strcsb r3, [ip], #1 123 | .endr 124 | 1: 125 | bpl 1f 126 | .rept 4 127 | ldrmib r3, [r1], #1 128 | strmib r3, [ip], #1 129 | .endr 130 | 1: 131 | movs r2, r2, lsl #31 132 | ldrcsb r3, [r1], #1 133 | strcsb r3, [ip], #1 134 | ldrcsb r3, [r1], #1 135 | strcsb r3, [ip], #1 136 | ldrmib r3, [r1], #1 137 | strmib r3, [ip], #1 138 | #endif 139 | bx lr 140 | .fnend 141 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/reg-dram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Allwinner D1/D1s/R528/T113-sx DRAM controller register 3 | * 4 | * (C) Copyright 2023 YuzukiTsuru 5 | * 6 | * SPDX-License-Identifier: GPL-2.0+ 7 | */ 8 | 9 | #ifndef __T113_REG_DRAM_H__ 10 | #define __T113_REG_DRAM_H__ 11 | 12 | #define MCTL_COM_BASE (0x3102000) 13 | #define MCTL_COM_WORK_MODE0 (0x00) 14 | #define MCTL_COM_WORK_MODE1 (0x04) 15 | #define MCTL_COM_DBGCR (0x08) 16 | #define MCTL_COM_TMR (0x0c) 17 | #define MCTL_COM_CCCR (0x14) 18 | #define MCTL_COM_MAER0 (0x20) 19 | #define MCTL_COM_MAER1 (0x24) 20 | #define MCTL_COM_MAER2 (0x28) 21 | #define MCTL_COM_REMAP0 (0x500) 22 | #define MCTL_COM_REMAP1 (0x504) 23 | #define MCTL_COM_REMAP2 (0x508) 24 | #define MCTL_COM_REMAP3 (0x50c) 25 | 26 | #define MCTL_PHY_BASE (0x3103000) 27 | #define MCTL_PHY_PIR (0x00) 28 | #define MCTL_PHY_PWRCTL (0x04) 29 | #define MCTL_PHY_MRCTRL0 (0x08) 30 | #define MCTL_PHY_CLKEN (0x0c) 31 | #define MCTL_PHY_PGSR0 (0x10) 32 | #define MCTL_PHY_PGSR1 (0x14) 33 | #define MCTL_PHY_STATR (0x18) 34 | #define MCTL_PHY_LP3MR11 (0x2c) 35 | #define MCTL_PHY_DRAM_MR0 (0x30) 36 | #define MCTL_PHY_DRAM_MR1 (0x34) 37 | #define MCTL_PHY_DRAM_MR2 (0x38) 38 | #define MCTL_PHY_DRAM_MR3 (0x3c) 39 | #define MCTL_PHY_PTR0 (0x44) 40 | #define MCTL_PHY_PTR2 (0x4c) 41 | #define MCTL_PHY_PTR3 (0x50) 42 | #define MCTL_PHY_PTR4 (0x54) 43 | #define MCTL_PHY_DRAMTMG0 (0x58) 44 | #define MCTL_PHY_DRAMTMG1 (0x5c) 45 | #define MCTL_PHY_DRAMTMG2 (0x60) 46 | #define MCTL_PHY_DRAMTMG3 (0x64) 47 | #define MCTL_PHY_DRAMTMG4 (0x68) 48 | #define MCTL_PHY_DRAMTMG5 (0x6c) 49 | #define MCTL_PHY_DRAMTMG6 (0x70) 50 | #define MCTL_PHY_DRAMTMG7 (0x74) 51 | #define MCTL_PHY_DRAMTMG8 (0x78) 52 | #define MCTL_PHY_ODTCFG (0x7c) 53 | #define MCTL_PHY_PITMG0 (0x80) 54 | #define MCTL_PHY_PITMG1 (0x84) 55 | #define MCTL_PHY_LPTPR (0x88) 56 | #define MCTL_PHY_RFSHCTL0 (0x8c) 57 | #define MCTL_PHY_RFSHTMG (0x90) 58 | #define MCTL_PHY_RFSHCTL1 (0x94) 59 | #define MCTL_PHY_PWRTMG (0x98) 60 | #define MCTL_PHY_ASRC (0x9c) 61 | #define MCTL_PHY_ASRTC (0xa0) 62 | #define MCTL_PHY_VTFCR (0xb8) 63 | #define MCTL_PHY_DQSGMR (0xbc) 64 | #define MCTL_PHY_DTCR (0xc0) 65 | #define MCTL_PHY_DTAR0 (0xc4) 66 | #define MCTL_PHY_PGCR0 (0x100) 67 | #define MCTL_PHY_PGCR1 (0x104) 68 | #define MCTL_PHY_PGCR2 (0x108) 69 | #define MCTL_PHY_PGCR3 (0x10c) 70 | #define MCTL_PHY_IOVCR0 (0x110) 71 | #define MCTL_PHY_IOVCR1 (0x114) 72 | #define MCTL_PHY_DXCCR (0x11c) 73 | #define MCTL_PHY_ODTMAP (0x120) 74 | #define MCTL_PHY_ZQCTL0 (0x124) 75 | #define MCTL_PHY_ZQCTL1 (0x128) 76 | #define MCTL_PHY_ZQCR (0x140) 77 | #define MCTL_PHY_ZQSR (0x144) 78 | #define MCTL_PHY_ZQDR0 (0x148) 79 | #define MCTL_PHY_ZQDR1 (0x14c) 80 | #define MCTL_PHY_ZQDR2 (0x150) 81 | #define MCTL_PHY_SCHED (0x1c0) 82 | #define MCTL_PHY_PERFHPR0 (0x1c4) 83 | #define MCTL_PHY_PERFHPR1 (0x1c8) 84 | #define MCTL_PHY_PERFLPR0 (0x1cc) 85 | #define MCTL_PHY_PERFLPR1 (0x1d0) 86 | #define MCTL_PHY_PERFWR0 (0x1d4) 87 | #define MCTL_PHY_PERFWR1 (0x1d8) 88 | #define MCTL_PHY_ACMDLR (0x200) 89 | #define MCTL_PHY_ACLDLR (0x204) 90 | #define MCTL_PHY_ACIOCR0 (0x208) 91 | #define MCTL_PHY_ACIOCR1(x) (0x210 + 0x4 * x) 92 | #define MCTL_PHY_DXnMDLR(x) (0x300 + 0x80 * x) 93 | #define MCTL_PHY_DXnLDLR0(x) (0x304 + 0x80 * x) 94 | #define MCTL_PHY_DXnLDLR1(x) (0x308 + 0x80 * x) 95 | #define MCTL_PHY_DXnLDLR2(x) (0x30c + 0x80 * x) 96 | #define MCTL_PHY_DXIOCR (0x310) 97 | #define MCTL_PHY_DATX0IOCR(x) (0x310 + 0x4 * x) 98 | #define MCTL_PHY_DATX1IOCR(x) (0x390 + 0x4 * x) 99 | #define MCTL_PHY_DATX2IOCR(x) (0x410 + 0x4 * x) 100 | #define MCTL_PHY_DATX3IOCR(x) (0x490 + 0x4 * x) 101 | #define MCTL_PHY_DXnSDLR6(x) (0x33c + 0x80 * x) 102 | #define MCTL_PHY_DXnGTR(x) (0x340 + 0x80 * x) 103 | #define MCTL_PHY_DXnGCR0(x) (0x344 + 0x80 * x) 104 | #define MCTL_PHY_DXnGSR0(x) (0x348 + 0x80 * x) 105 | 106 | #define SYS_CONTROL_REG_BASE (0x3000000) 107 | #define LDO_CTAL_REG (0x150) 108 | #define ZQ_CAL_CTRL_REG (0x160) 109 | #define ZQ_RES_CTRL_REG (0x168) 110 | #define ZQ_RES_STATUS_REG (0x16c) 111 | 112 | #define SYS_SID_BASE (0x3006000) 113 | #define SYS_EFUSE_REG (0x228) 114 | #define SYS_LDOB_SID (0x21c) 115 | 116 | #define SUNXI_R_CPUCFG_BASE (0x7000400) 117 | #define SUNXI_R_CPUCFG_SUP_STAN_FLAG (0x1d4) 118 | 119 | #define R_PRCM_BASE (0x7010000) 120 | #define VDD_SYS_PWROFF_GATING_REG (0x250) 121 | #define ANALOG_PWROFF_GATING_REG (0x254) 122 | 123 | #endif /* __T113_REG_DRAM_H__ */ -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sdmmc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDCARD_H__ 2 | #define __SDCARD_H__ 3 | 4 | #include "sunxi_sdhci.h" 5 | 6 | enum { 7 | /* Class 1 */ 8 | MMC_GO_IDLE_STATE = 0, 9 | MMC_SEND_OP_COND = 1, 10 | MMC_ALL_SEND_CID = 2, 11 | MMC_SET_RELATIVE_ADDR = 3, 12 | MMC_SET_DSR = 4, 13 | MMC_SWITCH = 6, 14 | MMC_SELECT_CARD = 7, 15 | MMC_SEND_EXT_CSD = 8, 16 | MMC_SEND_CSD = 9, 17 | MMC_SEND_CID = 10, 18 | MMC_READ_DAT_UNTIL_STOP = 11, 19 | MMC_STOP_TRANSMISSION = 12, 20 | MMC_SEND_STATUS = 13, 21 | MMC_GO_INACTIVE_STATE = 15, 22 | MMC_SPI_READ_OCR = 58, 23 | MMC_SPI_CRC_ON_OFF = 59, 24 | 25 | /* Class 2 */ 26 | MMC_SET_BLOCKLEN = 16, 27 | MMC_READ_SINGLE_BLOCK = 17, 28 | MMC_READ_MULTIPLE_BLOCK = 18, 29 | 30 | /* Class 3 */ 31 | MMC_WRITE_DAT_UNTIL_STOP = 20, 32 | 33 | /* Class 4 */ 34 | MMC_SET_BLOCK_COUNT = 23, 35 | MMC_WRITE_SINGLE_BLOCK = 24, 36 | MMC_WRITE_MULTIPLE_BLOCK = 25, 37 | MMC_PROGRAM_CID = 26, 38 | MMC_PROGRAM_CSD = 27, 39 | 40 | /* Class 5 */ 41 | MMC_ERASE_GROUP_START = 35, 42 | MMC_ERASE_GROUP_END = 36, 43 | MMC_ERASE = 38, 44 | 45 | /* Class 6 */ 46 | MMC_SET_WRITE_PROT = 28, 47 | MMC_CLR_WRITE_PROT = 29, 48 | MMC_SEND_WRITE_PROT = 30, 49 | 50 | /* Class 7 */ 51 | MMC_LOCK_UNLOCK = 42, 52 | 53 | /* Class 8 */ 54 | MMC_APP_CMD = 55, 55 | MMC_GEN_CMD = 56, 56 | 57 | /* Class 9 */ 58 | MMC_FAST_IO = 39, 59 | MMC_GO_IRQ_STATE = 40, 60 | }; 61 | 62 | enum { 63 | SD_CMD_SEND_RELATIVE_ADDR = 3, 64 | SD_CMD_SWITCH_FUNC = 6, 65 | SD_CMD_SEND_IF_COND = 8, 66 | SD_CMD_APP_SET_BUS_WIDTH = 6, 67 | SD_CMD_ERASE_WR_BLK_START = 32, 68 | SD_CMD_ERASE_WR_BLK_END = 33, 69 | SD_CMD_APP_SEND_OP_COND = 41, 70 | SD_CMD_APP_SEND_SCR = 51, 71 | }; 72 | 73 | enum { 74 | MMC_RSP_PRESENT = (1 << 0), 75 | MMC_RSP_136 = (1 << 1), 76 | MMC_RSP_CRC = (1 << 2), 77 | MMC_RSP_BUSY = (1 << 3), 78 | MMC_RSP_OPCODE = (1 << 4), 79 | }; 80 | 81 | enum { 82 | MMC_RSP_NONE = (0 << 24), 83 | MMC_RSP_R1 = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 84 | MMC_RSP_R1B = (1 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY), 85 | MMC_RSP_R2 = (2 << 24) | (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC), 86 | MMC_RSP_R3 = (3 << 24) | (MMC_RSP_PRESENT), 87 | MMC_RSP_R4 = (4 << 24) | (MMC_RSP_PRESENT), 88 | MMC_RSP_R5 = (5 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 89 | MMC_RSP_R6 = (6 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 90 | MMC_RSP_R7 = (7 << 24) | (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE), 91 | }; 92 | 93 | enum { 94 | MMC_STATUS_IDLE = 0, 95 | MMC_STATUS_READY = 1, 96 | MMC_STATUS_IDENT = 2, 97 | MMC_STATUS_STBY = 3, 98 | MMC_STATUS_TRAN = 4, 99 | MMC_STATUS_DATA = 5, 100 | MMC_STATUS_RCV = 6, 101 | MMC_STATUS_PRG = 7, 102 | MMC_STATUS_DIS = 8, 103 | MMC_STATUS_BTST = 9, 104 | MMC_STATUS_SLP = 10, 105 | }; 106 | 107 | enum { 108 | OCR_BUSY = 0x80000000, 109 | OCR_HCS = 0x40000000, 110 | OCR_VOLTAGE_MASK = 0x00ffff80, 111 | OCR_ACCESS_MODE = 0x60000000, 112 | }; 113 | 114 | enum { 115 | MMC_DATA_READ = (1 << 0), 116 | MMC_DATA_WRITE = (1 << 1), 117 | }; 118 | 119 | enum { 120 | MMC_VDD_27_36 = (1 << 0), 121 | MMC_VDD_165_195 = (1 << 1), 122 | }; 123 | 124 | enum { 125 | MMC_BUS_WIDTH_1 = 1, 126 | MMC_BUS_WIDTH_4 = 2, 127 | }; 128 | 129 | enum { 130 | SD_VERSION_SD = 0x20000, 131 | SD_VERSION_3 = (SD_VERSION_SD | 0x300), 132 | SD_VERSION_2 = (SD_VERSION_SD | 0x200), 133 | SD_VERSION_1_0 = (SD_VERSION_SD | 0x100), 134 | SD_VERSION_1_10 = (SD_VERSION_SD | 0x10a), 135 | MMC_VERSION_MMC = 0x10000, 136 | MMC_VERSION_UNKNOWN = (MMC_VERSION_MMC), 137 | MMC_VERSION_1_2 = (MMC_VERSION_MMC | 0x102), 138 | MMC_VERSION_1_4 = (MMC_VERSION_MMC | 0x104), 139 | MMC_VERSION_2_2 = (MMC_VERSION_MMC | 0x202), 140 | MMC_VERSION_3 = (MMC_VERSION_MMC | 0x300), 141 | MMC_VERSION_4 = (MMC_VERSION_MMC | 0x400), 142 | MMC_VERSION_4_1 = (MMC_VERSION_MMC | 0x401), 143 | MMC_VERSION_4_2 = (MMC_VERSION_MMC | 0x402), 144 | MMC_VERSION_4_3 = (MMC_VERSION_MMC | 0x403), 145 | MMC_VERSION_4_41 = (MMC_VERSION_MMC | 0x429), 146 | MMC_VERSION_4_5 = (MMC_VERSION_MMC | 0x405), 147 | MMC_VERSION_5_0 = (MMC_VERSION_MMC | 0x500), 148 | MMC_VERSION_5_1 = (MMC_VERSION_MMC | 0x501), 149 | }; 150 | 151 | typedef struct { 152 | uint32_t version; 153 | uint32_t ocr; 154 | uint32_t rca; 155 | uint32_t cid[4]; 156 | uint32_t csd[4]; 157 | uint8_t extcsd[512]; 158 | 159 | uint32_t high_capacity; 160 | uint32_t tran_speed; 161 | uint32_t dsr_imp; 162 | uint32_t read_bl_len; 163 | uint32_t write_bl_len; 164 | uint64_t capacity; 165 | } sdmmc_t; 166 | 167 | typedef struct { 168 | sdmmc_t card; 169 | sdhci_t *hci; 170 | uint8_t buf[512]; 171 | bool online; 172 | } sdmmc_pdata_t; 173 | 174 | extern sdmmc_pdata_t card0; 175 | 176 | int sdmmc_init(sdmmc_pdata_t *data, sdhci_t *hci); 177 | uint64_t sdmmc_blk_read(sdmmc_pdata_t *data, uint8_t *buf, uint64_t blkno, uint64_t blkcnt); 178 | 179 | #endif /* __SDCARD_H__ */ 180 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/start.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | #define ARMV7_USR_MODE 0x10 5 | #define ARMV7_FIQ_MODE 0x11 6 | #define ARMV7_IRQ_MODE 0x12 7 | #define ARMV7_SVC_MODE 0x13 8 | #define ARMV7_MON_MODE 0x16 9 | #define ARMV7_ABT_MODE 0x17 10 | #define ARMV7_UND_MODE 0x1b 11 | #define ARMV7_SYSTEM_MODE 0x1f 12 | #define ARMV7_MODE_MASK 0x1f 13 | #define ARMV7_FIQ_MASK 0x40 14 | #define ARMV7_IRQ_MASK 0x80 15 | 16 | .arm 17 | .globl reset 18 | .text 19 | 20 | reset: 21 | /* Boot head information for BROM */ 22 | .long 0xea000016 23 | .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' 24 | .long 0x12345678 /* checksum */ 25 | .long __spl_size /* spl size */ 26 | .long 0x30 /* boot header size */ 27 | .long 0x30303033 /* boot header version */ 28 | .long 0x00020000 /* return value */ 29 | .long 0x00028000 /* run address */ 30 | .long 0x0 /* eGON version */ 31 | .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ 32 | .byte 0x34, 0x2e, 0x30, 0x00 33 | 34 | /* 35 | * The actual reset code 36 | */ 37 | mrs r0, cpsr 38 | bic r0, r0, #ARMV7_MODE_MASK 39 | orr r0, r0, #ARMV7_SVC_MODE 40 | orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) 41 | bic r0, r0, #(1<<9) @set little-endian 42 | msr cpsr_c, r0 43 | 44 | /* Set vector base address register */ 45 | 46 | ldr r0, =_vector 47 | mcr p15, 0, r0, c12, c0, 0 48 | mrc p15, 0, r0, c1, c0, 0 49 | bic r0, #(1 << 13) 50 | mcr p15, 0, r0, c1, c0, 0 51 | 52 | mrc p15, 0, r0, c1, c0, 0 53 | bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 54 | bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 55 | orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 56 | bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 57 | mcr p15, 0, r0, c1, c0, 0 58 | 59 | /* Enable neon/vfp unit */ 60 | mrc p15, 0, r0, c1, c0, 2 61 | orr r0, r0, #(0xf << 20) 62 | mcr p15, 0, r0, c1, c0, 2 63 | isb 64 | mov r0, #0x40000000 65 | vmsr fpexc, r0 66 | 67 | /* Set stack pointer */ 68 | ldr sp, =__stack_srv_end 69 | 70 | bl clear_bss 71 | 72 | /* 73 | * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 74 | * except if in HYP mode already 75 | */ 76 | mrs r0, cpsr 77 | and r1, r0, #0x1f @ mask mode bits 78 | teq r1, #0x1a @ test for HYP mode 79 | bicne r0, r0, #0x1f @ clear all mode bits 80 | orrne r0, r0, #0x13 @ set SVC mode 81 | orr r0, r0, #0xc0 @ disable FIQ and IRQ 82 | msr cpsr,r0 83 | 84 | @set cntfrq to 24M 85 | ldr r0, =24000000 86 | mcr p15, 0, r0, c14, c0, 0 87 | 88 | bl main 89 | 90 | clear_bss: 91 | ldr r0, =_sbss 92 | ldr r1, =_ebss 93 | mov r2, #0 94 | 95 | clbss_1: 96 | stmia r0!, {r2} 97 | cmp r0, r1 98 | blt clbss_1 99 | 100 | mov pc, lr 101 | 102 | _vector: 103 | b reset 104 | ldr pc, _undefined_instruction 105 | ldr pc, _software_interrupt 106 | ldr pc, _prefetch_abort 107 | ldr pc, _data_abort 108 | ldr pc, _not_used 109 | ldr pc, _irq 110 | ldr pc, _fiq 111 | 112 | _undefined_instruction: 113 | .word undefined_instruction 114 | _software_interrupt: 115 | .word software_interrupt 116 | _prefetch_abort: 117 | .word prefetch_abort 118 | _data_abort: 119 | .word data_abort 120 | _not_used: 121 | .word not_used 122 | _irq: 123 | .word irq 124 | _fiq: 125 | .word fiq 126 | 127 | .macro save_regs 128 | str lr, [sp, #-4] 129 | mrs lr, spsr_all 130 | str lr, [sp, #-8] 131 | str r1, [sp, #-12] 132 | str r0, [sp, #-16] 133 | mov r0, sp 134 | cps #0x13 135 | ldr r1, [r0, #-4] 136 | str r1, [sp, #-4]! 137 | ldr r1, [r0, #-8] 138 | str r1, [sp, #-(4 * 16)] 139 | ldr r1, [r0, #-12] 140 | ldr r0, [r0, #-16] 141 | stmdb sp, {r0 - r14}^ 142 | sub sp, sp, #(4 * 16) 143 | ldr r4, [sp] 144 | and r0, r4, #0x1f 145 | cmp r0, #0x10 146 | beq 10f 147 | cmp r0, #0x13 148 | beq 11f 149 | b . 150 | 11: add r1, sp, #(4 * 17) 151 | str r1, [sp, #(4 * 14)] 152 | str lr, [sp, #(4 * 15)] 153 | 10: add r1, sp, #(4 * 17) 154 | str r1, [sp, #-4]! 155 | mov r0, sp 156 | .endm 157 | 158 | .macro restore_regs 159 | mov r12, sp 160 | ldr sp, [r12], #4 161 | ldr r1, [r12], #4 162 | msr spsr_cxsf, r1 163 | and r0, r1, #0x1f 164 | cmp r0, #0x10 165 | beq 20f 166 | cmp r0, #0x13 167 | beq 21f 168 | b . 169 | 20: ldr lr, [r12, #(4 * 15)] 170 | ldmia r12, {r0 - r14}^ 171 | movs pc, lr 172 | 21: ldm r12, {r0 - r15}^ 173 | mov r0, r0 174 | .endm 175 | 176 | /* 177 | * Exception handlers 178 | */ 179 | .align 5 180 | undefined_instruction: 181 | sub lr, lr, #4 182 | save_regs 183 | bl arm32_do_undefined_instruction 184 | restore_regs 185 | 186 | .align 5 187 | software_interrupt: 188 | sub lr, lr, #4 189 | save_regs 190 | bl arm32_do_software_interrupt 191 | restore_regs 192 | 193 | .align 5 194 | prefetch_abort: 195 | sub lr, lr, #4 196 | save_regs 197 | bl arm32_do_prefetch_abort 198 | restore_regs 199 | 200 | .align 5 201 | data_abort: 202 | sub lr, lr, #8 203 | save_regs 204 | bl arm32_do_data_abort 205 | restore_regs 206 | 207 | .align 5 208 | not_used: 209 | b . 210 | 211 | .align 5 212 | irq: 213 | sub lr, lr, #4 214 | save_regs 215 | bl arm32_do_irq 216 | restore_regs 217 | 218 | .align 5 219 | fiq: 220 | sub lr, lr, #4 221 | save_regs 222 | bl arm32_do_fiq 223 | restore_regs 224 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_clk.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "board.h" 3 | #include "sunxi_clk.h" 4 | #include "reg-ccu.h" 5 | #include "debug.h" 6 | 7 | 8 | void sunxi_clk_init(void) 9 | { 10 | uint32_t val; 11 | 12 | /* cpu_clk = CPU_PLL/P, AXI_DIV = 2 */ 13 | write32(CCU_BASE + CCU_CPU_CLK_REG, (0x3 << 8) | 0x01); 14 | sdelay(1); 15 | 16 | /* cpu_clk divider = 1 */ 17 | val = read32(CCU_BASE + CCU_CPU_CLK_REG); 18 | val &= ~((1 << 16) | (1 << 17)); 19 | // val |= (1 << 16); 20 | write32(CCU_BASE + CCU_CPU_CLK_REG, val); 21 | sdelay(5); 22 | 23 | /* CPU_PLL: enable LOCK, enable LDO, N = 38 * 24 = 912MHz */ 24 | val = read32(CCU_BASE + CCU_PLL_CPU_CTRL_REG); 25 | val &= ~((1 << 27) | (0x3FF << 8) | 0x3); /* CPU_PLL: Output disable, PLL_N = 0, M = 0 */ 26 | val |= (1 << 30 | (1 << 29) | (37 << 8)); 27 | write32(CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 28 | sdelay(5); 29 | 30 | /* wait for PLL lock */ 31 | while (!(read32(CCU_BASE + CCU_PLL_CPU_CTRL_REG) & (0x1 << 28))) 32 | ; 33 | 34 | sdelay(20); 35 | 36 | /* PLL lock disable, output enable */ 37 | val = read32(CCU_BASE + CCU_PLL_CPU_CTRL_REG); 38 | val &= ~(1 << 29); 39 | val |= (1 << 27); 40 | write32(CCU_BASE + CCU_PLL_CPU_CTRL_REG, val); 41 | 42 | /* cpu clock = CPU_PLL / P, APB DIV = 4, AXI_DIV = 2 */ 43 | val = read32(CCU_BASE + CCU_CPU_CLK_REG); 44 | val &= ~((0x7 << 24) | (0x3 << 8) | 0x3); 45 | val |= ((0x3 << 24) | (0x3 << 8) | 0x1); 46 | write32(CCU_BASE + CCU_CPU_CLK_REG, val); 47 | sdelay(1); 48 | 49 | /* Periph0 has been enabled */ 50 | if (read32(CCU_BASE + CCU_PLL_PERI_CTRL_REG) & (1 << 31)) 51 | debug("periph0 has been enabled\r\n"); 52 | 53 | /* AHB_Clock = CLK_SRC/M/N, PERIPH_600M / N(1) / M(3) = 200MHz */ 54 | write32(CCU_BASE + CCU_AHB_CLK_REG, (0x3 << 24) | 0x2); 55 | sdelay(1); 56 | 57 | /* APB0_Clock = CLK_SRC/M/N, PERIPH_600M / N(2) / M(3) = 100MHz */ 58 | write32(CCU_BASE + CCU_APB0_CLK_REG, (0x3 << 24) | (1 << 8) | 0x2); 59 | sdelay(1); 60 | 61 | /* DMA reset */ 62 | val = read32(CCU_BASE + CCU_DMA_BGR_REG); 63 | val |= (1 << 16); 64 | write32(CCU_BASE + CCU_DMA_BGR_REG, val); 65 | sdelay(20); 66 | 67 | /* enable DMA gate */ 68 | val = read32(CCU_BASE + CCU_DMA_BGR_REG); 69 | val |= 0x01; 70 | write32(CCU_BASE + CCU_DMA_BGR_REG, val); 71 | sdelay(1); 72 | 73 | /* MBUS reset */ 74 | val = read32(CCU_BASE + CCU_MBUS_CLK_REG); 75 | val |= (1 << 30); 76 | write32(CCU_BASE + CCU_MBUS_CLK_REG, val); 77 | sdelay(1); 78 | 79 | debug("sunxi clock init end\r\n"); 80 | debug("cpu clk reg (#0x%x): 0x%08x\r\n", CCU_CPU_CLK_REG, read32(CCU_BASE + CCU_CPU_CLK_REG)); 81 | 82 | return; 83 | } 84 | 85 | uint32_t sunxi_clk_get_peri1x_rate() 86 | { 87 | uint32_t reg32; 88 | uint8_t plln, pllm, p0; 89 | 90 | /* PLL PERI */ 91 | reg32 = read32(CCU_BASE + CCU_PLL_PERI_CTRL_REG); 92 | if (reg32 & (1 << 31)) { 93 | plln = ((reg32 >> 8) & 0xff) + 1; 94 | pllm = (reg32 & 0x01) + 1; 95 | p0 = ((reg32 >> 16) & 0x03) + 1; 96 | 97 | return ((((24 * plln) / (pllm * p0))) * 1000 * 1000); 98 | } 99 | 100 | return 0; 101 | } 102 | 103 | #ifdef CONFIG_ENABLE_CPU_FREQ_DUMP 104 | void sunxi_clk_dump() 105 | { 106 | uint32_t reg32; 107 | uint32_t cpu_clk_src, plln, pllm; 108 | uint8_t p0, p1; 109 | const char *clock_str; 110 | 111 | /* PLL CPU */ 112 | reg32 = read32(CCU_BASE + CCU_CPU_CLK_REG); 113 | cpu_clk_src = (reg32 >> 24) & 0x7; 114 | debug("CLK: CPU CLK_reg=0x%08x\r\n", reg32); 115 | 116 | switch (cpu_clk_src) { 117 | case 0x0: 118 | clock_str = "OSC24M"; 119 | break; 120 | 121 | case 0x1: 122 | clock_str = "CLK32"; 123 | break; 124 | 125 | case 0x2: 126 | clock_str = "CLK16M_RC"; 127 | break; 128 | 129 | case 0x3: 130 | clock_str = "PLL_CPU"; 131 | break; 132 | 133 | case 0x4: 134 | clock_str = "PLL_PERI_600M"; 135 | break; 136 | 137 | case 0x5: 138 | clock_str = "PLL_PERI_800M"; 139 | break; 140 | 141 | default: 142 | clock_str = "ERROR"; 143 | } 144 | 145 | p0 = (reg32 >> 16) & 0x03; 146 | if (p0 == 0) { 147 | p1 = 1; 148 | } else if (p0 == 1) { 149 | p1 = 2; 150 | } else if (p0 == 2) { 151 | p1 = 4; 152 | } else { 153 | p1 = 1; 154 | } 155 | 156 | debug("CLK: CPU PLL=%s FREQ=%uMHz\r\n", clock_str, ((((read32(CCU_BASE + CCU_PLL_CPU_CTRL_REG) >> 8) & 0xff) + 1) * 24 / p1)); 157 | 158 | /* PLL PERI */ 159 | reg32 = read32(CCU_BASE + CCU_PLL_PERI_CTRL_REG); 160 | if (reg32 & (1 << 31)) { 161 | plln = ((reg32 >> 8) & 0xff) + 1; 162 | pllm = (reg32 & 0x01) + 1; 163 | p0 = ((reg32 >> 16) & 0x03) + 1; 164 | p1 = ((reg32 >> 20) & 0x03) + 1; 165 | 166 | debug("CLK: PLL_peri (2X)=%uMHz, (1X)=%uMHz, (800M)=%uMHz\r\n", (24 * plln) / (pllm * p0), 167 | (24 * plln) / (pllm * p0) >> 1, (24 * plln) / (pllm * p1)); 168 | } else { 169 | debug("CLK: PLL_peri disabled\r\n"); 170 | } 171 | 172 | /* PLL DDR */ 173 | reg32 = read32(CCU_BASE + CCU_PLL_DDR_CTRL_REG); 174 | if (reg32 & (1 << 31)) { 175 | plln = ((reg32 >> 8) & 0xff) + 1; 176 | 177 | pllm = (reg32 & 0x01) + 1; 178 | p1 = ((reg32 >> 1) & 0x1) + 1; 179 | p0 = (reg32 & 0x01) + 1; 180 | 181 | debug("CLK: PLL_ddr=%uMHz\r\n", (24 * plln) / (p0 * p1)); 182 | 183 | } else { 184 | debug("CLK: PLL_ddr disabled\r\n"); 185 | } 186 | } 187 | #endif 188 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_clk.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_CLK_H__ 2 | #define __SUNXI_CLK_H__ 3 | 4 | #include "main.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_clk_init(void); 8 | uint32_t sunxi_clk_get_peri1x_rate(void); 9 | 10 | void sunxi_clk_dump(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_dma.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0+ */ 2 | /* 3 | * (C) Copyright 2015 Roy Spliet 4 | */ 5 | 6 | #include "types.h" 7 | 8 | #ifndef _SUNXI_DMA_H 9 | #define _SUNXI_DMA_H 10 | 11 | #define SUNXI_DMA_BASE 0x03002000 12 | #define SUNXI_DMA_CHANNEL_BASE (SUNXI_DMA_BASE + 0x100) 13 | #define DMA_AUTO_GATE_REG (SUNXI_DMA_BASE + 0x28) 14 | 15 | #define SUNXI_DMA_CHANNEL_SIZE (0x40) 16 | #define SUNXI_DMA_LINK_NULL (0xfffff800) 17 | 18 | #define DMAC_DMATYPE_NORMAL 0 19 | #define DMAC_CFG_TYPE_DRAM (1) 20 | #define DMAC_CFG_TYPE_SRAM (0) 21 | 22 | #define DMAC_CFG_TYPE_SPI0 (22) 23 | #define DMAC_CFG_TYPE_SHMC0 (20) 24 | #define DMAC_CFG_SRC_TYPE_NAND (5) 25 | 26 | /* DMA base config */ 27 | #define DMAC_CFG_CONTINUOUS_ENABLE (0x01) 28 | #define DMAC_CFG_CONTINUOUS_DISABLE (0x00) 29 | 30 | /* ----------DMA dest config-------------------- */ 31 | /* DMA dest width config */ 32 | #define DMAC_CFG_DEST_DATA_WIDTH_8BIT (0x00) 33 | #define DMAC_CFG_DEST_DATA_WIDTH_16BIT (0x01) 34 | #define DMAC_CFG_DEST_DATA_WIDTH_32BIT (0x02) 35 | #define DMAC_CFG_DEST_DATA_WIDTH_64BIT (0x03) 36 | 37 | /* DMA dest bust config */ 38 | #define DMAC_CFG_DEST_1_BURST (0x00) 39 | #define DMAC_CFG_DEST_4_BURST (0x01) 40 | #define DMAC_CFG_DEST_8_BURST (0x02) 41 | #define DMAC_CFG_DEST_16_BURST (0x03) 42 | 43 | #define DMAC_CFG_DEST_ADDR_TYPE_LINEAR_MODE (0x00) 44 | #define DMAC_CFG_DEST_ADDR_TYPE_IO_MODE (0x01) 45 | 46 | /* ----------DMA src config -------------------*/ 47 | #define DMAC_CFG_SRC_DATA_WIDTH_8BIT (0x00) 48 | #define DMAC_CFG_SRC_DATA_WIDTH_16BIT (0x01) 49 | #define DMAC_CFG_SRC_DATA_WIDTH_32BIT (0x02) 50 | #define DMAC_CFG_SRC_DATA_WIDTH_64BIT (0x03) 51 | 52 | #define DMAC_CFG_SRC_1_BURST (0x00) 53 | #define DMAC_CFG_SRC_4_BURST (0x01) 54 | #define DMAC_CFG_SRC_8_BURST (0x02) 55 | #define DMAC_CFG_SRC_16_BURST (0x03) 56 | 57 | #define DMAC_CFG_SRC_ADDR_TYPE_LINEAR_MODE (0x00) 58 | #define DMAC_CFG_SRC_ADDR_TYPE_IO_MODE (0x01) 59 | 60 | /*dma int config*/ 61 | #define DMA_PKG_HALF_INT (1 << 0) 62 | #define DMA_PKG_END_INT (1 << 1) 63 | #define DMA_QUEUE_END_INT (1 << 2) 64 | 65 | typedef struct { 66 | u32 volatile config; 67 | u32 volatile source_addr; 68 | u32 volatile dest_addr; 69 | u32 volatile byte_count; 70 | u32 volatile commit_para; 71 | u32 volatile link; 72 | u32 volatile reserved[2]; 73 | } dma_desc_t; 74 | 75 | typedef struct { 76 | u32 volatile src_drq_type : 6; 77 | u32 volatile src_burst_length : 2; 78 | u32 volatile src_addr_mode : 1; 79 | u32 volatile src_data_width : 2; 80 | u32 volatile reserved0 : 5; 81 | u32 volatile dst_drq_type : 6; 82 | u32 volatile dst_burst_length : 2; 83 | u32 volatile dst_addr_mode : 1; 84 | u32 volatile dst_data_width : 2; 85 | u32 volatile reserved1 : 5; 86 | } dma_channel_config_t; 87 | 88 | typedef struct { 89 | dma_channel_config_t channel_cfg; 90 | u32 loop_mode; 91 | u32 data_block_size; 92 | u32 wait_cyc; 93 | } dma_set_t; 94 | 95 | typedef struct { 96 | void *m_data; 97 | // void (*m_func)(void *data); 98 | void (*m_func)(void); 99 | } dma_irq_handler_t; 100 | 101 | typedef struct { 102 | u32 volatile enable; 103 | u32 volatile pause; 104 | u32 volatile desc_addr; 105 | u32 volatile config; 106 | u32 volatile cur_src_addr; 107 | u32 volatile cur_dst_addr; 108 | u32 volatile left_bytes; 109 | u32 volatile parameters; 110 | u32 volatile mode; 111 | u32 volatile fdesc_addr; 112 | u32 volatile pkg_num; 113 | u32 volatile res[5]; 114 | } dma_channel_reg_t; 115 | 116 | typedef struct { 117 | u32 volatile irq_en0; /* 0x0 dma irq enable register 0 */ 118 | u32 volatile irq_en1; /* 0x4 dma irq enable register 1 */ 119 | u32 volatile reserved0[2]; 120 | u32 volatile irq_pending0; /* 0x10 dma irq pending register 0 */ 121 | u32 volatile irq_pending1; /* 0x14 dma irq pending register 1 */ 122 | u32 volatile reserved1[2]; 123 | u32 volatile security; /* 0x20 dma security register */ 124 | u32 volatile reserved3[1]; 125 | u32 volatile auto_gate; /* 0x28 dma auto gating register */ 126 | u32 volatile reserved4[1]; 127 | u32 volatile status; /* 0x30 dma status register */ 128 | u32 volatile reserved5[3]; 129 | u32 volatile version; /* 0x40 dma Version register */ 130 | u32 volatile reserved6[47]; 131 | dma_channel_reg_t channel[16]; /* 0x100 dma channel register */ 132 | } dma_reg_t; 133 | 134 | typedef struct { 135 | u32 used; 136 | u32 channel_count; 137 | dma_channel_reg_t *channel; 138 | u32 reserved; 139 | dma_desc_t *desc; 140 | dma_irq_handler_t dma_func; 141 | } dma_source_t; 142 | 143 | #define DMA_RST_OFS 16 144 | #define DMA_GATING_OFS 0 145 | 146 | void dma_init(void); 147 | void dma_exit(void); 148 | 149 | u32 dma_request(u32 dmatype); 150 | u32 dma_request_from_last(u32 dmatype); 151 | int dma_release(u32 hdma); 152 | int dma_setting(u32 hdma, dma_set_t *cfg); 153 | int dma_start(u32 hdma, u32 saddr, u32 daddr, u32 bytes); 154 | int dma_stop(u32 hdma); 155 | int dma_querystatus(u32 hdma); 156 | 157 | int dma_test(); 158 | 159 | #endif /* _SUNXI_DMA_H */ 160 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_gpio.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "debug.h" 3 | #include "sunxi_gpio.h" 4 | 5 | enum { 6 | GPIO_CFG0 = 0x00, 7 | GPIO_CFG1 = 0x04, 8 | GPIO_CFG2 = 0x08, 9 | GPIO_CFG3 = 0x0c, 10 | GPIO_DAT = 0x10, 11 | GPIO_DRV0 = 0x14, 12 | GPIO_DRV1 = 0x18, 13 | GPIO_DRV2 = 0x1c, 14 | GPIO_DRV3 = 0x20, 15 | GPIO_PUL0 = 0x24, 16 | GPIO_PUL1 = 0x28, 17 | }; 18 | 19 | static inline uint32_t _port_num(gpio_t pin) 20 | { 21 | return pin >> PIO_NUM_IO_BITS; 22 | } 23 | 24 | static uint32_t _port_base_get(gpio_t pin) 25 | { 26 | uint32_t port = pin >> PIO_NUM_IO_BITS; 27 | 28 | switch (port) { 29 | case PORTA: 30 | return 0x02000000; 31 | break; 32 | case PORTC: 33 | return 0x02000060; 34 | break; 35 | case PORTD: 36 | return 0x02000090; 37 | break; 38 | case PORTE: 39 | return 0x020000c0; 40 | break; 41 | case PORTF: 42 | return 0x020000f0; 43 | break; 44 | case PORTH: 45 | return 0x02000150; 46 | break; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | static inline uint32_t _pin_num(gpio_t pin) 53 | { 54 | return (pin & ((1 << PIO_NUM_IO_BITS) - 1)); 55 | } 56 | 57 | void sunxi_gpio_init(gpio_t pin, int cfg) 58 | { 59 | uint32_t port_addr = _port_base_get(pin); 60 | uint32_t pin_num = _pin_num(pin); 61 | uint32_t addr; 62 | uint32_t val; 63 | 64 | addr = port_addr + GPIO_CFG0 + ((pin_num >> 3) << 2); 65 | val = read32(addr); 66 | val &= ~(0xf << ((pin_num & 0x7) << 2)); 67 | val |= ((cfg & 0xf) << ((pin_num & 0x7) << 2)); 68 | write32(addr, val); 69 | } 70 | 71 | void sunxi_gpio_set_value(gpio_t pin, int value) 72 | { 73 | uint32_t port_addr = _port_base_get(pin); 74 | uint32_t pin_num = _pin_num(pin); 75 | uint32_t val; 76 | 77 | val = read32(port_addr + GPIO_DAT); 78 | val &= ~(1 << pin_num); 79 | val |= (!!value) << pin_num; 80 | write32(port_addr + GPIO_DAT, val); 81 | } 82 | 83 | int sunxi_gpio_read(gpio_t pin) 84 | { 85 | uint32_t port_addr = _port_base_get(pin); 86 | uint32_t pin_num = _pin_num(pin); 87 | uint32_t val; 88 | 89 | val = read32(port_addr + GPIO_DAT); 90 | return !!(val & (1 << pin_num)); 91 | } 92 | 93 | void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull) 94 | { 95 | uint32_t port_addr = _port_base_get(pin); 96 | uint32_t pin_num = _pin_num(pin); 97 | uint32_t addr; 98 | uint32_t val, v; 99 | 100 | switch (pull) { 101 | case GPIO_PULL_UP: 102 | v = 0x1; 103 | break; 104 | 105 | case GPIO_PULL_DOWN: 106 | v = 0x2; 107 | break; 108 | 109 | case GPIO_PULL_NONE: 110 | v = 0x0; 111 | break; 112 | 113 | default: 114 | v = 0x0; 115 | break; 116 | } 117 | 118 | addr = port_addr + GPIO_PUL0 + ((pin_num >> 4) << 2); 119 | val = read32(addr); 120 | val &= ~(v << ((pin_num & 0xf) << 1)); 121 | val |= (v << ((pin_num & 0xf) << 1)); 122 | write32(addr, val); 123 | } 124 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_GPIO_H__ 2 | #define __SUNXI_GPIO_H__ 3 | 4 | #include 5 | 6 | enum { 7 | GPIO_INPUT = 0, 8 | GPIO_OUTPUT = 1, 9 | GPIO_PERIPH_MUX2 = 2, 10 | GPIO_PERIPH_MUX3 = 3, 11 | GPIO_PERIPH_MUX4 = 4, 12 | GPIO_PERIPH_MUX5 = 5, 13 | GPIO_PERIPH_MUX6 = 6, 14 | GPIO_PERIPH_MUX7 = 7, 15 | GPIO_PERIPH_MUX8 = 8, 16 | GPIO_PERIPH_MUX14 = 14, 17 | GPIO_DISABLED = 0xf, 18 | }; 19 | 20 | #define PORTA 0 21 | #define PORTC 1 22 | #define PORTD 2 23 | #define PORTE 3 24 | #define PORTF 4 25 | #define PORTH 5 26 | #define SUNXI_GPIO_PORTS 6 27 | 28 | enum gpio_pull_t { 29 | GPIO_PULL_UP = 0, 30 | GPIO_PULL_DOWN = 1, 31 | GPIO_PULL_NONE = 2, 32 | }; 33 | 34 | typedef uint32_t gpio_t; 35 | #define PIO_NUM_IO_BITS 5 36 | 37 | #define GPIO_PIN(x, y) (((uint32_t)(x << PIO_NUM_IO_BITS)) | y) 38 | 39 | typedef struct { 40 | gpio_t pin; 41 | uint8_t mux; 42 | } gpio_mux_t; 43 | 44 | extern void sunxi_gpio_init(gpio_t pin, int cfg); 45 | extern void sunxi_gpio_set_value(gpio_t pin, int value); 46 | extern int sunxi_gpio_read(gpio_t pin); 47 | extern void sunxi_gpio_set_pull(gpio_t pin, enum gpio_pull_t pull); 48 | 49 | #endif -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_sdhci.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDHCI_H__ 2 | #define __SDHCI_H__ 3 | 4 | #include "sunxi_gpio.h" 5 | 6 | typedef enum { 7 | MMC_CLK_400K = 0, 8 | MMC_CLK_25M, 9 | MMC_CLK_50M, 10 | MMC_CLK_50M_DDR, 11 | MMC_CLK_100M, 12 | MMC_CLK_150M, 13 | MMC_CLK_200M 14 | } smhc_clk_t; 15 | 16 | typedef struct { 17 | volatile u32 gctrl; /* (0x00) SMC Global Control Register */ 18 | volatile u32 clkcr; /* (0x04) SMC Clock Control Register */ 19 | volatile u32 timeout; /* (0x08) SMC Time Out Register */ 20 | volatile u32 width; /* (0x0C) SMC Bus Width Register */ 21 | volatile u32 blksz; /* (0x10) SMC Block Size Register */ 22 | volatile u32 bytecnt; /* (0x14) SMC Byte Count Register */ 23 | volatile u32 cmd; /* (0x18) SMC Command Register */ 24 | volatile u32 arg; /* (0x1C) SMC Argument Register */ 25 | volatile u32 resp0; /* (0x20) SMC Response Register 0 */ 26 | volatile u32 resp1; /* (0x24) SMC Response Register 1 */ 27 | volatile u32 resp2; /* (0x28) SMC Response Register 2 */ 28 | volatile u32 resp3; /* (0x2C) SMC Response Register 3 */ 29 | volatile u32 imask; /* (0x30) SMC Interrupt Mask Register */ 30 | volatile u32 mint; /* (0x34) SMC Masked Interrupt Status Register */ 31 | volatile u32 rint; /* (0x38) SMC Raw Interrupt Status Register */ 32 | volatile u32 status; /* (0x3C) SMC Status Register */ 33 | volatile u32 ftrglevel; /* (0x40) SMC FIFO Threshold Watermark Register */ 34 | volatile u32 funcsel; /* (0x44) SMC Function Select Register */ 35 | volatile u32 cbcr; /* (0x48) SMC CIU Byte Count Register */ 36 | volatile u32 bbcr; /* (0x4C) SMC BIU Byte Count Register */ 37 | volatile u32 dbgc; /* (0x50) SMC Debug Enable Register */ 38 | volatile u32 csdc; /* (0x54) CRC status detect control register*/ 39 | volatile u32 a12a; /* (0x58)Auto command 12 argument*/ 40 | volatile u32 ntsr; /* (0x5c)SMC2 Newtiming Set Register */ 41 | volatile u32 res1[6]; /* (0x60~0x74) */ 42 | volatile u32 hwrst; /* (0x78) SMC eMMC Hardware Reset Register */ 43 | volatile u32 res2; /* (0x7c) */ 44 | volatile u32 dmac; /* (0x80) SMC IDMAC Control Register */ 45 | volatile u32 dlba; /* (0x84) SMC IDMAC Descriptor List Base Address Register */ 46 | volatile u32 idst; /* (0x88) SMC IDMAC Status Register */ 47 | volatile u32 idie; /* (0x8C) SMC IDMAC Interrupt Enable Register */ 48 | volatile u32 chda; /* (0x90) */ 49 | volatile u32 cbda; /* (0x94) */ 50 | volatile u32 res3[26]; /* (0x98~0xff) */ 51 | volatile u32 thldc; /* (0x100) Card Threshold Control Register */ 52 | volatile u32 sfc; /* (0x104) Sample Fifo Control Register */ 53 | volatile u32 res4[1]; /* (0x10b) */ 54 | volatile u32 dsbd; /* (0x10c) eMMC4.5 DDR Start Bit Detection Control */ 55 | volatile u32 res5[12]; /* (0x110~0x13c) */ 56 | volatile u32 drv_dl; /* (0x140) Drive Delay Control register*/ 57 | volatile u32 samp_dl; /* (0x144) Sample Delay Control register*/ 58 | volatile u32 ds_dl; /* (0x148) Data Strobe Delay Control Register */ 59 | volatile u32 ntdc; /* (0x14C) HS400 New Timing Delay Control Register */ 60 | volatile u32 res6[4]; /* (0x150~0x15f) */ 61 | volatile u32 skew_dat0_dl; /*(0x160) deskew data0 delay control register*/ 62 | volatile u32 skew_dat1_dl; /*(0x164) deskew data1 delay control register*/ 63 | volatile u32 skew_dat2_dl; /*(0x168) deskew data2 delay control register*/ 64 | volatile u32 skew_dat3_dl; /*(0x16c) deskew data3 delay control register*/ 65 | volatile u32 skew_dat4_dl; /*(0x170) deskew data4 delay control register*/ 66 | volatile u32 skew_dat5_dl; /*(0x174) deskew data5 delay control register*/ 67 | volatile u32 skew_dat6_dl; /*(0x178) deskew data6 delay control register*/ 68 | volatile u32 skew_dat7_dl; /*(0x17c) deskew data7 delay control register*/ 69 | volatile u32 skew_ds_dl; /*(0x180) deskew ds delay control register*/ 70 | volatile u32 skew_ctrl; /*(0x184) deskew control control register*/ 71 | volatile u32 res8[30]; /* (0x188~0x1ff) */ 72 | volatile u32 fifo; /* (0x200) SMC FIFO Access Address */ 73 | volatile u32 res7[63]; /* (0x201~0x2FF)*/ 74 | volatile u32 vers; /* (0x300) SMHC Version Register */ 75 | } sdhci_reg_t; 76 | 77 | typedef struct { 78 | u32 idx; 79 | u32 arg; 80 | u32 resptype; 81 | u32 response[4]; 82 | } sdhci_cmd_t; 83 | 84 | typedef struct { 85 | u8 *buf; 86 | u32 flag; 87 | u32 blksz; 88 | u32 blkcnt; 89 | } sdhci_data_t; 90 | 91 | #define SMHC_DES_NUM_SHIFT 12 /* smhc2!! */ 92 | #define SMHC_DES_BUFFER_MAX_LEN (1 << SMHC_DES_NUM_SHIFT) 93 | typedef struct { 94 | u32 : 1, dic : 1, /* disable interrupt on completion */ 95 | last_desc : 1, /* 1-this data buffer is the last buffer */ 96 | first_desc : 1, /* 1-data buffer is the first buffer, 0-data buffer contained in the next descriptor is 1st 97 | buffer */ 98 | des_chain : 1, /* 1-the 2nd address in the descriptor is the next descriptor address */ 99 | // end_of_ring : 1, /* 1-last descriptor flag when using dual data buffer in descriptor */ 100 | : 25, err_flag : 1, /* transfer error flag */ 101 | own : 1; /* des owner:1-idma owns it, 0-host owns it */ 102 | 103 | u32 data_buf_sz : SMHC_DES_NUM_SHIFT, data_buf_dummy : (32 - SMHC_DES_NUM_SHIFT); 104 | 105 | u32 buf_addr; 106 | u32 next_desc_addr; 107 | 108 | } sdhci_idma_desc_t __attribute__((aligned(8))); 109 | 110 | typedef struct { 111 | char *name; 112 | sdhci_reg_t *reg; 113 | u32 reset; 114 | 115 | u32 voltage; 116 | u32 width; 117 | smhc_clk_t clock; 118 | u32 pclk; 119 | u8 odly[6]; 120 | u8 sdly[6]; 121 | 122 | sdhci_idma_desc_t dma_desc[32]; 123 | u32 dma_trglvl; 124 | 125 | bool removable; 126 | bool isspi; 127 | 128 | gpio_mux_t gpio_d0; 129 | gpio_mux_t gpio_d1; 130 | gpio_mux_t gpio_d2; 131 | gpio_mux_t gpio_d3; 132 | gpio_mux_t gpio_cmd; 133 | gpio_mux_t gpio_clk; 134 | 135 | } sdhci_t; 136 | 137 | extern sdhci_t sdhci0; 138 | 139 | bool sdhci_reset(sdhci_t *hci); 140 | bool sdhci_set_voltage(sdhci_t *hci, u32 voltage); 141 | bool sdhci_set_width(sdhci_t *hci, u32 width); 142 | bool sdhci_set_clock(sdhci_t *hci, smhc_clk_t hz); 143 | bool sdhci_transfer(sdhci_t *hci, sdhci_cmd_t *cmd, sdhci_data_t *dat); 144 | int sunxi_sdhci_init(sdhci_t *sdhci); 145 | 146 | #endif /* __SDHCI_H__ */ 147 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_SPI_H__ 2 | #define __SUNXI_SPI_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef enum { 8 | SPI_IO_SINGLE = 0x00, 9 | SPI_IO_DUAL_RX, 10 | SPI_IO_QUAD_RX, 11 | SPI_IO_QUAD_IO, 12 | } spi_io_mode_t; 13 | 14 | typedef struct { 15 | uint8_t mfr; 16 | uint16_t dev; 17 | uint8_t dlen; 18 | } __attribute__((packed)) spi_nand_id_t; 19 | 20 | typedef struct { 21 | char *name; 22 | spi_nand_id_t id; 23 | uint32_t page_size; 24 | uint32_t spare_size; 25 | uint32_t pages_per_block; 26 | uint32_t blocks_per_die; 27 | uint32_t planes_per_die; 28 | uint32_t ndies; 29 | spi_io_mode_t mode; 30 | } spi_nand_info_t; 31 | 32 | typedef struct { 33 | uint32_t base; 34 | uint8_t id; 35 | uint32_t clk_rate; 36 | gpio_mux_t gpio_cs; 37 | gpio_mux_t gpio_sck; 38 | gpio_mux_t gpio_miso; 39 | gpio_mux_t gpio_mosi; 40 | gpio_mux_t gpio_wp; 41 | gpio_mux_t gpio_hold; 42 | 43 | spi_nand_info_t info; 44 | } sunxi_spi_t; 45 | 46 | int sunxi_spi_init(sunxi_spi_t *spi); 47 | void sunxi_spi_disable(sunxi_spi_t *spi); 48 | int spi_nand_detect(sunxi_spi_t *spi); 49 | uint32_t spi_nand_read(sunxi_spi_t *spi, uint8_t *buf, uint32_t addr, uint32_t rxlen); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_usart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "io.h" 3 | #include "main.h" 4 | #include "sunxi_usart.h" 5 | #include "reg-ccu.h" 6 | 7 | void sunxi_usart_init(sunxi_usart_t *usart) 8 | { 9 | uint32_t addr; 10 | uint32_t val; 11 | 12 | /* Config usart TXD and RXD pins */ 13 | sunxi_gpio_init(usart->gpio_tx.pin, usart->gpio_tx.mux); 14 | sunxi_gpio_init(usart->gpio_rx.pin, usart->gpio_rx.mux); 15 | 16 | /* Open the clock gate for usart */ 17 | addr = CCU_BASE + CCU_UART_BGR_REG; 18 | val = read32(addr); 19 | val |= 1 << usart->id; 20 | write32(addr, val); 21 | 22 | /* Deassert USART reset */ 23 | addr = CCU_BASE + CCU_UART_BGR_REG; 24 | val = read32(addr); 25 | val |= 1 << (16 + usart->id); 26 | write32(addr, val); 27 | 28 | /* Config USART to 115200-8-1-0 */ 29 | addr = usart->base; 30 | write32(addr + 0x04, 0x0); 31 | write32(addr + 0x08, 0xf7); 32 | write32(addr + 0x10, 0x0); 33 | val = read32(addr + 0x0c); 34 | val |= (1 << 7); 35 | write32(addr + 0x0c, val); 36 | write32(addr + 0x00, 0xd & 0xff); 37 | write32(addr + 0x04, (0xd >> 8) & 0xff); 38 | val = read32(addr + 0x0c); 39 | val &= ~(1 << 7); 40 | write32(addr + 0x0c, val); 41 | val = read32(addr + 0x0c); 42 | val &= ~0x1f; 43 | val |= (0x3 << 0) | (0 << 2) | (0x0 << 3); 44 | write32(addr + 0x0c, val); 45 | } 46 | 47 | void sunxi_usart_putc(void *arg, char c) 48 | { 49 | sunxi_usart_t *usart = (sunxi_usart_t *)arg; 50 | 51 | while ((read32(usart->base + 0x7c) & (0x1 << 1)) == 0) 52 | ; 53 | write32(usart->base + 0x00, c); 54 | } 55 | -------------------------------------------------------------------------------- /arch/arm32/mach-v851s/sunxi_usart.h: -------------------------------------------------------------------------------- 1 | #ifndef __SUNXI_USART_H__ 2 | #define __SUNXI_USART_H__ 3 | 4 | #include "main.h" 5 | #include "sunxi_gpio.h" 6 | 7 | typedef struct { 8 | uint32_t base; 9 | uint8_t id; 10 | gpio_mux_t gpio_tx; 11 | gpio_mux_t gpio_rx; 12 | } sunxi_usart_t; 13 | 14 | extern void sunxi_usart_init(sunxi_usart_t *usart); 15 | extern void sunxi_usart_putc(void *arg, char c); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /board-v851s.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "board.h" 3 | #include "sunxi_gpio.h" 4 | #include "sunxi_sdhci.h" 5 | #include "sunxi_usart.h" 6 | #include "sunxi_spi.h" 7 | #include "sdmmc.h" 8 | 9 | 10 | sunxi_usart_t usart_dbg = { 11 | .base = 0x02500800, 12 | .id = 2, 13 | .gpio_tx = {GPIO_PIN(PORTE, 12), GPIO_PERIPH_MUX6}, 14 | .gpio_rx = {GPIO_PIN(PORTE, 13), GPIO_PERIPH_MUX6}, 15 | }; 16 | 17 | sunxi_spi_t sunxi_spi0 = { 18 | .base = 0x04025000, 19 | .id = 0, 20 | .clk_rate = 75 * 1000 * 1000, 21 | .gpio_cs = {GPIO_PIN(PORTC, 1), GPIO_PERIPH_MUX4}, 22 | .gpio_sck = {GPIO_PIN(PORTC, 0), GPIO_PERIPH_MUX4}, 23 | .gpio_mosi = {GPIO_PIN(PORTC, 2), GPIO_PERIPH_MUX4}, 24 | .gpio_miso = {GPIO_PIN(PORTC, 3), GPIO_PERIPH_MUX4}, 25 | .gpio_wp = {GPIO_PIN(PORTC, 4), GPIO_PERIPH_MUX4}, 26 | .gpio_hold = {GPIO_PIN(PORTC, 5), GPIO_PERIPH_MUX4}, 27 | }; 28 | 29 | sdhci_t sdhci0 = { 30 | .name = "sdhci0", 31 | .reg = (sdhci_reg_t *)0x04020000, 32 | .voltage = MMC_VDD_27_36, 33 | .width = MMC_BUS_WIDTH_4, 34 | .clock = MMC_CLK_50M, 35 | .removable = 0, 36 | .isspi = FALSE, 37 | .gpio_clk = {GPIO_PIN(PORTF, 2), GPIO_PERIPH_MUX2}, 38 | .gpio_cmd = {GPIO_PIN(PORTF, 3), GPIO_PERIPH_MUX2}, 39 | .gpio_d0 = {GPIO_PIN(PORTF, 1), GPIO_PERIPH_MUX2}, 40 | .gpio_d1 = {GPIO_PIN(PORTF, 0), GPIO_PERIPH_MUX2}, 41 | .gpio_d2 = {GPIO_PIN(PORTF, 5), GPIO_PERIPH_MUX2}, 42 | .gpio_d3 = {GPIO_PIN(PORTF, 4), GPIO_PERIPH_MUX2}, 43 | }; 44 | 45 | gpio_t led_blue = GPIO_PIN(PORTF, 6); 46 | 47 | void board_init_led(gpio_t led) 48 | { 49 | sunxi_gpio_init(led, GPIO_OUTPUT); 50 | sunxi_gpio_set_value(led, 0); 51 | } 52 | 53 | int board_sdhci_init() 54 | { 55 | sunxi_sdhci_init(&sdhci0); 56 | return sdmmc_init(&card0, &sdhci0); 57 | } 58 | 59 | void board_init() 60 | { 61 | board_init_led(led_blue); 62 | sunxi_usart_init(&usart_dbg); 63 | } 64 | -------------------------------------------------------------------------------- /board.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "board.h" 3 | #include "sunxi_gpio.h" 4 | #include "sunxi_sdhci.h" 5 | #include "sunxi_usart.h" 6 | #include "sunxi_spi.h" 7 | #include "sdmmc.h" 8 | 9 | sunxi_usart_t usart5_dbg = { 10 | .base = 0x02501400, 11 | .id = 5, 12 | .gpio_tx = {GPIO_PIN(PORTB, 4), GPIO_PERIPH_MUX7}, 13 | .gpio_rx = {GPIO_PIN(PORTB, 5), GPIO_PERIPH_MUX7}, 14 | }; 15 | 16 | sunxi_usart_t usart0_dbg = { 17 | .base = 0x02500000, 18 | .id = 0, 19 | .gpio_tx = {GPIO_PIN(PORTE, 2), GPIO_PERIPH_MUX6}, 20 | .gpio_rx = {GPIO_PIN(PORTE, 3), GPIO_PERIPH_MUX6}, 21 | }; 22 | 23 | sunxi_usart_t usart3_dbg = { 24 | .base = 0x02500c00, 25 | .id = 3, 26 | .gpio_tx = {GPIO_PIN(PORTB, 6), GPIO_PERIPH_MUX7}, 27 | .gpio_rx = {GPIO_PIN(PORTB, 7), GPIO_PERIPH_MUX7}, 28 | }; 29 | 30 | sunxi_spi_t sunxi_spi0 = { 31 | .base = 0x04025000, 32 | .id = 0, 33 | .clk_rate = 100 * 1000 * 1000, 34 | .gpio_cs = {GPIO_PIN(PORTC, 3), GPIO_PERIPH_MUX2}, 35 | .gpio_sck = {GPIO_PIN(PORTC, 2), GPIO_PERIPH_MUX2}, 36 | .gpio_mosi = {GPIO_PIN(PORTC, 4), GPIO_PERIPH_MUX2}, 37 | .gpio_miso = {GPIO_PIN(PORTC, 5), GPIO_PERIPH_MUX2}, 38 | .gpio_wp = {GPIO_PIN(PORTC, 6), GPIO_PERIPH_MUX2}, 39 | .gpio_hold = {GPIO_PIN(PORTC, 7), GPIO_PERIPH_MUX2}, 40 | }; 41 | 42 | sdhci_t sdhci0 = { 43 | .name = "sdhci0", 44 | .reg = (sdhci_reg_t *)0x04020000, 45 | .voltage = MMC_VDD_27_36, 46 | .width = MMC_BUS_WIDTH_4, 47 | .clock = MMC_CLK_50M, 48 | .removable = 0, 49 | .isspi = FALSE, 50 | .gpio_clk = {GPIO_PIN(PORTF, 2), GPIO_PERIPH_MUX2}, 51 | .gpio_cmd = {GPIO_PIN(PORTF, 3), GPIO_PERIPH_MUX2}, 52 | .gpio_d0 = {GPIO_PIN(PORTF, 1), GPIO_PERIPH_MUX2}, 53 | .gpio_d1 = {GPIO_PIN(PORTF, 0), GPIO_PERIPH_MUX2}, 54 | .gpio_d2 = {GPIO_PIN(PORTF, 5), GPIO_PERIPH_MUX2}, 55 | .gpio_d3 = {GPIO_PIN(PORTF, 4), GPIO_PERIPH_MUX2}, 56 | }; 57 | 58 | static gpio_t led_blue = GPIO_PIN(PORTD, 22); 59 | 60 | void board_init_led(gpio_t led) 61 | { 62 | sunxi_gpio_init(led, GPIO_OUTPUT); 63 | sunxi_gpio_set_value(led, 0); 64 | } 65 | 66 | int board_sdhci_init() 67 | { 68 | sunxi_sdhci_init(&sdhci0); 69 | return sdmmc_init(&card0, &sdhci0); 70 | } 71 | 72 | void board_init() 73 | { 74 | board_init_led(led_blue); 75 | sunxi_usart_init(&USART_DBG); 76 | } 77 | -------------------------------------------------------------------------------- /board.h: -------------------------------------------------------------------------------- 1 | #ifndef __BOARD_H__ 2 | #define __BOARD_H__ 3 | 4 | #include "dram.h" 5 | #include "sunxi_spi.h" 6 | #include "sunxi_usart.h" 7 | #include "sunxi_sdhci.h" 8 | 9 | #define USART_DBG usart5_dbg 10 | 11 | #define CONFIG_BOOT_SPINAND 12 | #define CONFIG_BOOT_SDCARD 13 | #define CONFIG_BOOT_MMC 14 | 15 | #define CONFIG_FATFS_CACHE_SIZE (CONFIG_DTB_LOAD_ADDR - SDRAM_BASE) // in bytes 16 | #define CONFIG_SDMMC_SPEED_TEST_SIZE 1024 // (unit: 512B sectors) 17 | 18 | #define CONFIG_CPU_FREQ 1200000000 19 | 20 | // #define CONFIG_ENABLE_CPU_FREQ_DUMP 21 | 22 | #define CONFIG_KERNEL_FILENAME "zImage" 23 | #define CONFIG_DTB_FILENAME "sun8i-t113-mangopi-dual.dtb" 24 | 25 | #define CONFIG_KERNEL_LOAD_ADDR (SDRAM_BASE + (72 * 1024 * 1024)) 26 | #define CONFIG_DTB_LOAD_ADDR (SDRAM_BASE + (64 * 1024 * 1024)) 27 | 28 | // 128KB erase sectors, so place them starting from 2nd sector 29 | #define CONFIG_SPINAND_DTB_ADDR (128 * 2048) 30 | #define CONFIG_SPINAND_KERNEL_ADDR (256 * 2048) 31 | 32 | extern dram_para_t ddr_param; 33 | extern sunxi_usart_t USART_DBG; 34 | extern sunxi_spi_t sunxi_spi0; 35 | 36 | extern void board_init(void); 37 | extern int board_sdhci_init(void); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_H__ 2 | #define __IO_H__ 3 | 4 | #include 5 | 6 | #define BIT(x) (1 << x) 7 | 8 | typedef unsigned int virtual_addr_t; 9 | 10 | static inline __attribute__((__always_inline__)) uint8_t read8(virtual_addr_t addr) 11 | { 12 | return (*((volatile uint8_t *)(addr))); 13 | } 14 | 15 | static inline __attribute__((__always_inline__)) uint16_t read16(virtual_addr_t addr) 16 | { 17 | return (*((volatile uint16_t *)(addr))); 18 | } 19 | 20 | static inline __attribute__((__always_inline__)) uint32_t read32(virtual_addr_t addr) 21 | { 22 | return (*((volatile uint32_t *)(addr))); 23 | } 24 | 25 | static inline __attribute__((__always_inline__)) uint64_t read64(virtual_addr_t addr) 26 | { 27 | return (*((volatile uint64_t *)(addr))); 28 | } 29 | 30 | static inline __attribute__((__always_inline__)) void write8(virtual_addr_t addr, uint8_t value) 31 | { 32 | *((volatile uint8_t *)(addr)) = value; 33 | } 34 | 35 | static inline __attribute__((__always_inline__)) void write16(virtual_addr_t addr, uint16_t value) 36 | { 37 | *((volatile uint16_t *)(addr)) = value; 38 | } 39 | 40 | static inline __attribute__((__always_inline__)) void write32(virtual_addr_t addr, uint32_t value) 41 | { 42 | *((volatile uint32_t *)(addr)) = value; 43 | } 44 | 45 | static inline __attribute__((__always_inline__)) void write64(virtual_addr_t addr, uint64_t value) 46 | { 47 | *((volatile uint64_t *)(addr)) = value; 48 | } 49 | 50 | #endif -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 Microchip Technology Inc. and its subsidiaries 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #ifndef __STRING_H__ 8 | #define __STRING_H__ 9 | 10 | #include "types.h" 11 | 12 | extern void *memcpy(void *dst, const void *src, int cnt); 13 | extern void *memset(void *dst, int val, int cnt); 14 | extern int memcmp(const void *dst, const void *src, unsigned int cnt); 15 | extern unsigned int strlen(const char *str); 16 | extern char *strcpy(char *dst, const char *src); 17 | extern char *strcat(char *dst, const char *src); 18 | extern int strcmp(const char *p1, const char *p2); 19 | extern int strncmp(const char *p1, const char *p2, unsigned int cnt); 20 | extern char *strchr(const char *s, int c); 21 | extern char *strstr(const char *s, const char *what); 22 | extern void *memchr(void *ptr, int value, unsigned int num); 23 | extern void *memmove(void *dest, const void *src, unsigned int count); 24 | 25 | #endif /* #ifndef __STRING_H__ */ 26 | -------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | // * SPDX-License-Identifier: GPL-2.0+ 2 | #ifndef __ASM_ARM_TYPES_H 3 | #define __ASM_ARM_TYPES_H 4 | 5 | #include 6 | 7 | typedef unsigned short umode_t; 8 | 9 | /* 10 | * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the 11 | * header files exported to user space 12 | */ 13 | 14 | typedef __signed__ char __s8; 15 | typedef unsigned char __u8; 16 | 17 | typedef __signed__ short __s16; 18 | typedef unsigned short __u16; 19 | 20 | typedef __signed__ int __s32; 21 | typedef unsigned int __u32; 22 | 23 | #if defined(__GNUC__) 24 | __extension__ typedef __signed__ long long __s64; 25 | __extension__ typedef unsigned long long __u64; 26 | #endif 27 | 28 | /* 29 | * These aren't exported outside the kernel to avoid name space clashes 30 | */ 31 | //#ifdef __KERNEL__ 32 | 33 | typedef signed char s8; 34 | typedef unsigned char u8; 35 | 36 | typedef signed short s16; 37 | typedef unsigned short u16; 38 | 39 | /* dont mix stdint and basic types, uint32_t and u32 are intermixed throughout code */ 40 | typedef int32_t s32; 41 | typedef uint32_t u32; 42 | 43 | typedef signed long long s64; 44 | typedef unsigned long long u64; 45 | 46 | typedef float f32; 47 | typedef double f64; 48 | 49 | #ifdef CONFIG_ARM64 50 | #define BITS_PER_LONG 64 51 | #else /* CONFIG_ARM64 */ 52 | #define BITS_PER_LONG 32 53 | #endif /* CONFIG_ARM64 */ 54 | 55 | #ifdef CONFIG_PHYS_64BIT 56 | typedef unsigned long long phys_addr_t; 57 | typedef unsigned long long phys_size_t; 58 | #else 59 | /* DMA addresses are 32-bits wide */ 60 | typedef unsigned long phys_addr_t; 61 | typedef unsigned long phys_size_t; 62 | #endif 63 | 64 | /* 65 | * A dma_addr_t can hold any valid DMA address, i.e., any address returned 66 | * by the DMA API. 67 | * 68 | * If the DMA API only uses 32-bit addresses, dma_addr_t need only be 32 69 | * bits wide. Bus addresses, e.g., PCI BARs, may be wider than 32 bits, 70 | * but drivers do memory-mapped I/O to ioremapped kernel virtual addresses, 71 | * so they don't care about the size of the actual bus addresses. 72 | */ 73 | #ifdef CONFIG_DMA_ADDR_T_64BIT 74 | typedef unsigned long long dma_addr_t; 75 | #else 76 | typedef u32 dma_addr_t; 77 | #endif 78 | 79 | //#endif /* __KERNEL__ */ 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /lib/debug.c: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | #include "sunxi_usart.h" 3 | #include "main.h" 4 | #include "board.h" 5 | 6 | void message(const char *fmt, ...) 7 | { 8 | va_list args; 9 | va_start(args, fmt); 10 | xvformat(sunxi_usart_putc, &USART_DBG, fmt, args); 11 | va_end(args); 12 | } 13 | -------------------------------------------------------------------------------- /lib/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include "xformat.h" 5 | 6 | #define LOG_ERROR 10 7 | #define LOG_WARN 20 8 | #define LOG_INFO 30 9 | #define LOG_DEBUG 40 10 | #define LOG_TRACE 50 11 | 12 | #if LOG_LEVEL >= LOG_TRACE 13 | #define trace(fmt, ...) message("[T] " fmt, ##__VA_ARGS__) 14 | #define UNUSED_TRACE 15 | #else 16 | #define trace(...) 17 | #define UNUSED_TRACE __attribute__((__unused__)) 18 | #endif 19 | 20 | #if LOG_LEVEL >= LOG_DEBUG 21 | #define debug(fmt, ...) message("[D] " fmt, ##__VA_ARGS__) 22 | #define UNUSED_DEBUG 23 | #else 24 | #define debug(...) 25 | #define UNUSED_DEBUG __attribute__((__unused__)) 26 | #endif 27 | 28 | #if LOG_LEVEL >= LOG_INFO 29 | #define info(fmt, ...) message("[I] " fmt, ##__VA_ARGS__) 30 | #define UNUSED_INFO 31 | #else 32 | #define info(...) 33 | #define UNUSED_INFO __attribute__((__unused__)) 34 | #endif 35 | 36 | #if LOG_LEVEL >= LOG_WARNING 37 | #define warning(fmt, ...) message("[W] " fmt, ##__VA_ARGS__) 38 | #define UNUSED_WARNING 39 | #else 40 | #define warning(...) 41 | #define UNUSED_WARNING __attribute__((__unused__)) 42 | #endif 43 | 44 | #if LOG_LEVEL >= LOG_ERROR 45 | #define error(fmt, ...) message("[E] " fmt, ##__VA_ARGS__) 46 | #define UNUSED_ERROR 47 | #else 48 | #define error(...) 49 | #define UNUSED_ERROR __attribute__((__unused__)) 50 | #endif 51 | 52 | #define fatal(fmt, ...) \ 53 | { \ 54 | message("[F] " fmt "restarting...\r\n", ##__VA_ARGS__); \ 55 | mdelay(100); \ 56 | reset(); \ 57 | } 58 | 59 | void __attribute__((format(printf, 1, 2))) message(const char *fmt, ...); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /lib/fatfs/diskio.c: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------*/ 2 | /* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */ 3 | /*-----------------------------------------------------------------------*/ 4 | /* If a working storage control module is available, it should be */ 5 | /* attached to the FatFs via a glue function rather than modifying it. */ 6 | /* This is an example of glue functions to attach various exsisting */ 7 | /* storage control modules to the FatFs module with a defined API. */ 8 | /*-----------------------------------------------------------------------*/ 9 | #include "ff.h" /* Obtains integer types */ 10 | #include "diskio.h" 11 | #include "main.h" 12 | #include "sdmmc.h" 13 | #include "debug.h" 14 | #include "dram.h" 15 | #include "sunxi_dma.h" 16 | #include "board.h" 17 | 18 | static DSTATUS Stat = STA_NOINIT; /* Disk status */ 19 | 20 | #ifdef CONFIG_FATFS_CACHE_SIZE 21 | /* we can consume up to CONFIG_FATFS_CACHE_SIZE of SDRAM starting at SDRAM_BASE */ 22 | #define FATFS_CACHE_CHUNK_SIZE (32*1024) 23 | #define FATFS_CACHE_SECTORS (CONFIG_FATFS_CACHE_SIZE / FF_MIN_SS) 24 | #define FATFS_CACHE_SECTORS_PER_BIT (FATFS_CACHE_CHUNK_SIZE / FF_MIN_SS) 25 | #define FATFS_CACHE_CHUNKS (FATFS_CACHE_SECTORS / FATFS_CACHE_SECTORS_PER_BIT) 26 | 27 | static u8 *const cache_data = (u8 *)SDRAM_BASE; /* in SDRAM */ 28 | static u8 cache_bitmap[FATFS_CACHE_CHUNKS/8]; /* in SRAM */ 29 | static BYTE cache_pdrv = -1; 30 | 31 | #define CACHE_SECTOR_TO_OFFSET(ss) (((ss)/FATFS_CACHE_SECTORS_PER_BIT) / 8) 32 | #define CACHE_SECTOR_TO_BIT(ss) (((ss)/FATFS_CACHE_SECTORS_PER_BIT) % 8) 33 | 34 | #define CACHE_IS_VALID(ss) ({ __typeof(ss) _ss = (ss); cache_bitmap[CACHE_SECTOR_TO_OFFSET(_ss)] & (1 << CACHE_SECTOR_TO_BIT(_ss)); }) 35 | #define CACHE_SET_VALID(ss) do { __typeof(ss) _ss = (ss); cache_bitmap[CACHE_SECTOR_TO_OFFSET(_ss)] |= (1 << CACHE_SECTOR_TO_BIT(_ss)); } while(0) 36 | #endif 37 | 38 | /*-----------------------------------------------------------------------*/ 39 | /* Get Drive Status */ 40 | /*-----------------------------------------------------------------------*/ 41 | 42 | DSTATUS disk_status(BYTE pdrv /* Physical drive nmuber to identify the drive */ 43 | ) 44 | { 45 | if (pdrv) 46 | return STA_NOINIT; 47 | 48 | return Stat; 49 | } 50 | 51 | /*-----------------------------------------------------------------------*/ 52 | /* Inidialize a Drive */ 53 | /*-----------------------------------------------------------------------*/ 54 | 55 | DSTATUS disk_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */ 56 | ) 57 | { 58 | if (pdrv) 59 | return STA_NOINIT; 60 | 61 | Stat &= ~STA_NOINIT; 62 | 63 | return Stat; 64 | } 65 | 66 | /*-----------------------------------------------------------------------*/ 67 | /* Read Sector(s) */ 68 | /*-----------------------------------------------------------------------*/ 69 | 70 | DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */ 71 | BYTE *buff, /* Data buffer to store read data */ 72 | LBA_t sector, /* Start sector in LBA */ 73 | UINT count /* Number of sectors to read */ 74 | ) 75 | { 76 | if (pdrv || !count) 77 | return RES_PARERR; 78 | if (Stat & STA_NOINIT) 79 | return RES_NOTRDY; 80 | 81 | trace("FATFS: read %u sectors at %llu\r\n", count, sector); 82 | 83 | #ifdef CONFIG_FATFS_CACHE_SIZE 84 | if (pdrv != cache_pdrv) { 85 | info("FATFS: cache: %u bytes in %u chunks\r\n", CONFIG_FATFS_CACHE_SIZE, FATFS_CACHE_CHUNKS); 86 | if (cache_pdrv != -1) 87 | memset(cache_bitmap, 0, sizeof(cache_bitmap)); 88 | cache_pdrv = pdrv; 89 | } 90 | 91 | while (count) { 92 | if (sector >= FATFS_CACHE_SECTORS) { 93 | trace("FATFS: beyond cache %llu count %u\r\n", sector, count); 94 | /* beyond end of cache, read remaining */ 95 | if (sdmmc_blk_read(&card0, buff, sector, count) != count) { 96 | warning("FATFS: read failed %llu count %u\r\n", sector, count); 97 | return RES_ERROR; 98 | } 99 | return RES_OK; 100 | } 101 | 102 | if (!CACHE_IS_VALID(sector)) { 103 | LBA_t chunk = sector & ~(FATFS_CACHE_SECTORS_PER_BIT-1); 104 | trace("FATFS: cache miss %llu, loading %llu count %u\r\n", sector, chunk, FATFS_CACHE_SECTORS_PER_BIT); 105 | if (sdmmc_blk_read(&card0, &cache_data[chunk*FF_MIN_SS], chunk, FATFS_CACHE_SECTORS_PER_BIT) != FATFS_CACHE_SECTORS_PER_BIT) { 106 | warning("FATFS: read failed %llu count %u\r\n", sector, FATFS_CACHE_SECTORS_PER_BIT); 107 | return RES_ERROR; 108 | } 109 | CACHE_SET_VALID(sector); 110 | } 111 | else { 112 | trace("FATFS: cache hit %llu\r\n", sector); 113 | } 114 | memcpy(buff, &cache_data[sector*FF_MIN_SS], FF_MIN_SS); 115 | 116 | sector++; 117 | buff += FF_MIN_SS; 118 | count--; 119 | } 120 | return RES_OK; 121 | #else 122 | return (sdmmc_blk_read(&card0, buff, sector, count) == count ? RES_OK : RES_ERROR); 123 | #endif 124 | } 125 | 126 | /*-----------------------------------------------------------------------*/ 127 | /* Write Sector(s) */ 128 | /*-----------------------------------------------------------------------*/ 129 | 130 | #if FF_FS_READONLY == 0 131 | 132 | DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */ 133 | const BYTE *buff, /* Data to be written */ 134 | LBA_t sector, /* Start sector in LBA */ 135 | UINT count /* Number of sectors to write */ 136 | ) 137 | { 138 | return RES_ERROR; 139 | } 140 | 141 | #endif 142 | 143 | /*-----------------------------------------------------------------------*/ 144 | /* Miscellaneous Functions */ 145 | /*-----------------------------------------------------------------------*/ 146 | 147 | DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */ 148 | BYTE cmd, /* Control code */ 149 | void *buff /* Buffer to send/receive control data */ 150 | ) 151 | { 152 | return RES_PARERR; 153 | } 154 | -------------------------------------------------------------------------------- /lib/fatfs/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2019 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | /*---------------------------------------*/ 25 | /* Prototypes for disk control functions */ 26 | 27 | DSTATUS disk_initialize(BYTE pdrv); 28 | DSTATUS disk_status(BYTE pdrv); 29 | DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count); 30 | DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count); 31 | DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff); 32 | 33 | /* Disk Status Bits (DSTATUS) */ 34 | 35 | #define STA_NOINIT 0x01 /* Drive not initialized */ 36 | #define STA_NODISK 0x02 /* No medium in the drive */ 37 | #define STA_PROTECT 0x04 /* Write protected */ 38 | 39 | /* Command code for disk_ioctrl fucntion */ 40 | 41 | /* Generic command (Used by FatFs) */ 42 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 43 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 44 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 45 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 46 | #define CTRL_TRIM \ 47 | 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 48 | 49 | /* Generic command (Not used by FatFs) */ 50 | #define CTRL_POWER 5 /* Get/Set power status */ 51 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 52 | #define CTRL_EJECT 7 /* Eject media */ 53 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 54 | 55 | /* MMC/SDC specific ioctl command */ 56 | #define MMC_GET_TYPE 10 /* Get card type */ 57 | #define MMC_GET_CSD 11 /* Get CSD */ 58 | #define MMC_GET_CID 12 /* Get CID */ 59 | #define MMC_GET_OCR 13 /* Get OCR */ 60 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 61 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 62 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 63 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 64 | 65 | /* ATA/CF specific ioctl command */ 66 | #define ATA_GET_REV 20 /* Get F/W revision */ 67 | #define ATA_GET_MODEL 21 /* Get model name */ 68 | #define ATA_GET_SN 22 /* Get serial number */ 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /lib/fatfs/fatfs.mk: -------------------------------------------------------------------------------- 1 | FS_FAT := lib/fatfs 2 | 3 | INCLUDE_DIRS += -I $(FS_FAT) 4 | 5 | SRCS += $(FS_FAT)/ff.c 6 | SRCS += $(FS_FAT)/diskio.c 7 | SRCS += $(FS_FAT)/ffsystem.c 8 | SRCS += $(FS_FAT)/ffunicode.c 9 | -------------------------------------------------------------------------------- /lib/fatfs/ffsystem.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* A Sample Code of User Provided OS Dependent Functions for FatFs */ 3 | /*------------------------------------------------------------------------*/ 4 | 5 | #include "ff.h" 6 | 7 | #if FF_USE_LFN == 3 /* Use dynamic memory allocation */ 8 | 9 | /*------------------------------------------------------------------------*/ 10 | /* Allocate/Free a Memory Block */ 11 | /*------------------------------------------------------------------------*/ 12 | 13 | #include /* with POSIX API */ 14 | 15 | void *ff_memalloc(/* Returns pointer to the allocated memory block (null if not enough core) */ 16 | UINT msize /* Number of bytes to allocate */ 17 | ) 18 | { 19 | return malloc((size_t)msize); /* Allocate a new memory block */ 20 | } 21 | 22 | void ff_memfree(void *mblock /* Pointer to the memory block to free (no effect if null) */ 23 | ) 24 | { 25 | free(mblock); /* Free the memory block */ 26 | } 27 | 28 | #endif 29 | 30 | #if FF_FS_REENTRANT /* Mutal exclusion */ 31 | /*------------------------------------------------------------------------*/ 32 | /* Definitions of Mutex */ 33 | /*------------------------------------------------------------------------*/ 34 | 35 | #define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */ 36 | 37 | #if OS_TYPE == 0 /* Win32 */ 38 | #include 39 | static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */ 40 | 41 | #elif OS_TYPE == 1 /* uITRON */ 42 | #include "itron.h" 43 | #include "kernel.h" 44 | static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */ 45 | 46 | #elif OS_TYPE == 2 /* uc/OS-II */ 47 | #include "includes.h" 48 | static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */ 49 | 50 | #elif OS_TYPE == 3 /* FreeRTOS */ 51 | #include "FreeRTOS.h" 52 | #include "semphr.h" 53 | static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */ 54 | 55 | #elif OS_TYPE == 4 /* CMSIS-RTOS */ 56 | #include "cmsis_os.h" 57 | static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */ 58 | 59 | #endif 60 | 61 | /*------------------------------------------------------------------------*/ 62 | /* Create a Mutex */ 63 | /*------------------------------------------------------------------------*/ 64 | /* This function is called in f_mount function to create a new mutex 65 | / or semaphore for the volume. When a 0 is returned, the f_mount function 66 | / fails with FR_INT_ERR. 67 | */ 68 | 69 | int ff_mutex_create(/* Returns 1:Function succeeded or 0:Could not create the mutex */ 70 | int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ 71 | ) 72 | { 73 | #if OS_TYPE == 0 /* Win32 */ 74 | Mutex[vol] = CreateMutex(NULL, FALSE, NULL); 75 | return (int)(Mutex[vol] != INVALID_HANDLE_VALUE); 76 | 77 | #elif OS_TYPE == 1 /* uITRON */ 78 | T_CMTX cmtx = {TA_TPRI, 1}; 79 | 80 | Mutex[vol] = acre_mtx(&cmtx); 81 | return (int)(Mutex[vol] > 0); 82 | 83 | #elif OS_TYPE == 2 /* uC/OS-II */ 84 | OS_ERR err; 85 | 86 | Mutex[vol] = OSMutexCreate(0, &err); 87 | return (int)(err == OS_NO_ERR); 88 | 89 | #elif OS_TYPE == 3 /* FreeRTOS */ 90 | Mutex[vol] = xSemaphoreCreateMutex(); 91 | return (int)(Mutex[vol] != NULL); 92 | 93 | #elif OS_TYPE == 4 /* CMSIS-RTOS */ 94 | osMutexDef(cmsis_os_mutex); 95 | 96 | Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex)); 97 | return (int)(Mutex[vol] != NULL); 98 | 99 | #endif 100 | } 101 | 102 | /*------------------------------------------------------------------------*/ 103 | /* Delete a Mutex */ 104 | /*------------------------------------------------------------------------*/ 105 | /* This function is called in f_mount function to delete a mutex or 106 | / semaphore of the volume created with ff_mutex_create function. 107 | */ 108 | 109 | void ff_mutex_delete(/* Returns 1:Function succeeded or 0:Could not delete due to an error */ 110 | int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ 111 | ) 112 | { 113 | #if OS_TYPE == 0 /* Win32 */ 114 | CloseHandle(Mutex[vol]); 115 | 116 | #elif OS_TYPE == 1 /* uITRON */ 117 | del_mtx(Mutex[vol]); 118 | 119 | #elif OS_TYPE == 2 /* uC/OS-II */ 120 | OS_ERR err; 121 | 122 | OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err); 123 | 124 | #elif OS_TYPE == 3 /* FreeRTOS */ 125 | vSemaphoreDelete(Mutex[vol]); 126 | 127 | #elif OS_TYPE == 4 /* CMSIS-RTOS */ 128 | osMutexDelete(Mutex[vol]); 129 | 130 | #endif 131 | } 132 | 133 | /*------------------------------------------------------------------------*/ 134 | /* Request a Grant to Access the Volume */ 135 | /*------------------------------------------------------------------------*/ 136 | /* This function is called on enter file functions to lock the volume. 137 | / When a 0 is returned, the file function fails with FR_TIMEOUT. 138 | */ 139 | 140 | int ff_mutex_take(/* Returns 1:Succeeded or 0:Timeout */ 141 | int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ 142 | ) 143 | { 144 | #if OS_TYPE == 0 /* Win32 */ 145 | return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0); 146 | 147 | #elif OS_TYPE == 1 /* uITRON */ 148 | return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK); 149 | 150 | #elif OS_TYPE == 2 /* uC/OS-II */ 151 | OS_ERR err; 152 | 153 | OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err)); 154 | return (int)(err == OS_NO_ERR); 155 | 156 | #elif OS_TYPE == 3 /* FreeRTOS */ 157 | return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE); 158 | 159 | #elif OS_TYPE == 4 /* CMSIS-RTOS */ 160 | return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK); 161 | 162 | #endif 163 | } 164 | 165 | /*------------------------------------------------------------------------*/ 166 | /* Release a Grant to Access the Volume */ 167 | /*------------------------------------------------------------------------*/ 168 | /* This function is called on leave file functions to unlock the volume. 169 | */ 170 | 171 | void ff_mutex_give(int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ 172 | ) 173 | { 174 | #if OS_TYPE == 0 /* Win32 */ 175 | ReleaseMutex(Mutex[vol]); 176 | 177 | #elif OS_TYPE == 1 /* uITRON */ 178 | unl_mtx(Mutex[vol]); 179 | 180 | #elif OS_TYPE == 2 /* uC/OS-II */ 181 | OSMutexPost(Mutex[vol]); 182 | 183 | #elif OS_TYPE == 3 /* FreeRTOS */ 184 | xSemaphoreGive(Mutex[vol]); 185 | 186 | #elif OS_TYPE == 4 /* CMSIS-RTOS */ 187 | osMutexRelease(Mutex[vol]); 188 | 189 | #endif 190 | } 191 | 192 | #endif /* FF_FS_REENTRANT */ 193 | -------------------------------------------------------------------------------- /lib/fatfs/media.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * ATMEL Microcontroller Software Support 3 | * ---------------------------------------------------------------------------- 4 | * Copyright (c) 2006, Atmel Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * - Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the disclaimer below. 13 | * 14 | * Atmel's name may not be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 | * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | #ifndef __MEDIA_H__ 29 | #define __MEDIA_H__ 30 | 31 | extern int sdmmc_initialize(void); 32 | extern unsigned int sdmmc_block_read(unsigned int start, unsigned int blkcnt, void *dest); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lib/fdt.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------- 2 | * ATMEL Microcontroller Software Support 3 | * ---------------------------------------------------------------------------- 4 | * Copyright (c) 2012, Atmel Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * - Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the disclaimer below. 13 | * 14 | * Atmel's name may not be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 | * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | #ifndef __FDT_H__ 29 | #define __FDT_H__ 30 | 31 | /* see linux document: ./Documentation/devicetree/booting-without-of.txt */ 32 | #define OF_DT_MAGIC 0xd00dfeed 33 | 34 | typedef struct { 35 | unsigned int magic_number; 36 | unsigned int total_size; 37 | unsigned int offset_dt_struct; 38 | unsigned int offset_dt_strings; 39 | unsigned int offset_reserve_map; 40 | unsigned int format_version; 41 | unsigned int last_compatible_version; 42 | 43 | /* version 2 field */ 44 | unsigned int mach_id; 45 | /* version 3 field */ 46 | unsigned int dt_strings_len; 47 | /* version 17 field */ 48 | unsigned int dt_struct_len; 49 | } boot_param_header_t; 50 | 51 | unsigned int of_get_magic_number(void *blob); 52 | unsigned int of_get_dt_total_size(void *blob); 53 | int check_dt_blob_valid(void *blob); 54 | int fixup_chosen_node(void *blob, char *bootargs); 55 | int fixup_memory_node(void *blob, unsigned int *mem_bank, unsigned int *mem_size); 56 | #endif /* #ifndef __FDT_H__ */ 57 | -------------------------------------------------------------------------------- /lib/string.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2006 Microchip Technology Inc. and its subsidiaries 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | #include "string.h" 6 | #include "main.h" 7 | 8 | void *memset(void *dst, int val, int cnt) 9 | { 10 | char *d = (char *)dst; 11 | 12 | while (cnt--) 13 | *d++ = (char)val; 14 | 15 | return dst; 16 | } 17 | 18 | int memcmp(const void *dst, const void *src, unsigned int cnt) 19 | { 20 | const char *d = (const char *)dst; 21 | const char *s = (const char *)src; 22 | int r = 0; 23 | 24 | while (cnt-- && (r = *d++ - *s++) == 0) 25 | ; 26 | 27 | return r; 28 | } 29 | 30 | unsigned int strlen(const char *str) 31 | { 32 | int i = 0; 33 | 34 | while (str[i++] != '\0') 35 | ; 36 | 37 | return i - 1; 38 | } 39 | 40 | char *strcpy(char *dst, const char *src) 41 | { 42 | char *bak = dst; 43 | 44 | while ((*dst++ = *src++) != '\0') 45 | ; 46 | 47 | return bak; 48 | } 49 | 50 | char *strcat(char *dst, const char *src) 51 | { 52 | char *p = dst; 53 | 54 | while (*dst != '\0') 55 | dst++; 56 | 57 | while ((*dst++ = *src++) != '\0') 58 | ; 59 | 60 | return p; 61 | } 62 | 63 | int strcmp(const char *p1, const char *p2) 64 | { 65 | unsigned char c1, c2; 66 | 67 | while (1) { 68 | c1 = *p1++; 69 | c2 = *p2++; 70 | if (c1 != c2) 71 | return c1 < c2 ? -1 : 1; 72 | if (!c1) 73 | break; 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | int strncmp(const char *p1, const char *p2, unsigned int cnt) 80 | { 81 | unsigned char c1, c2; 82 | 83 | while (cnt--) { 84 | c1 = *p1++; 85 | c2 = *p2++; 86 | 87 | if (c1 != c2) 88 | return c1 < c2 ? -1 : 1; 89 | 90 | if (!c1) 91 | break; 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | char *strchr(const char *s, int c) 98 | { 99 | for (; *s != (char)c; ++s) 100 | if (*s == '\0') 101 | return NULL; 102 | 103 | return (char *)s; 104 | } 105 | 106 | /* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */ 107 | 108 | char *strstr(const char *s1, const char *s2) 109 | { 110 | register const char *s = s1; 111 | register const char *p = s2; 112 | 113 | do { 114 | if (!*p) { 115 | return (char *)s1; 116 | ; 117 | } 118 | if (*p == *s) { 119 | ++p; 120 | ++s; 121 | } else { 122 | p = s2; 123 | if (!*s) { 124 | return NULL; 125 | } 126 | s = ++s1; 127 | } 128 | } while (1); 129 | } 130 | 131 | void *memchr(void *src, int val, unsigned int cnt) 132 | { 133 | char *p = NULL; 134 | char *s = (char *)src; 135 | 136 | while (cnt) { 137 | if (*s == val) { 138 | p = s; 139 | break; 140 | } 141 | s++; 142 | cnt--; 143 | } 144 | 145 | return p; 146 | } 147 | 148 | void *memmove(void *dst, const void *src, unsigned int cnt) 149 | { 150 | char *p, *s; 151 | 152 | if (dst <= src) { 153 | p = (char *)dst; 154 | s = (char *)src; 155 | while (cnt--) 156 | *p++ = *s++; 157 | } else { 158 | p = (char *)dst + cnt; 159 | s = (char *)src + cnt; 160 | while (cnt--) 161 | *--p = *--s; 162 | } 163 | 164 | return dst; 165 | } 166 | -------------------------------------------------------------------------------- /lib/xformat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file xformatc.h 3 | * 4 | * @brief Printf C declaration. 5 | * 6 | * @author Mario Viara 7 | * 8 | * @version 1.01 9 | * 10 | * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) 11 | * This is a free software and is opened for education, research and commercial 12 | * developments under license policy of following terms: 13 | * - This is a free software and there is NO WARRANTY. 14 | * - No restriction on use. You can use, modify and redistribute it for personal, 15 | * non-profit or commercial product UNDER YOUR RESPONSIBILITY. 16 | * - Redistributions of source code must retain the above copyright notice. 17 | * 18 | */ 19 | #ifndef __XFORMAT_H__ 20 | #define __XFORMAT_H__ 21 | 22 | #include 23 | #include 24 | 25 | /** 26 | * Define internal parameters as volatile for 8 bit cpu define 27 | * XCFG_FORMAT_STATIC=static to reduce stack usage. 28 | */ 29 | #define XCFG_FORMAT_STATIC 30 | 31 | /** 32 | * Define XCFG_FORMAT_FLOAT=0 to remove floating point support 33 | */ 34 | #define XCFG_FORMAT_FLOAT 1 35 | 36 | /** 37 | * Define to 0 to support long long type (prefix ll) 38 | */ 39 | #ifndef XCFG_FORMAT_LONGLONG 40 | #define XCFG_FORMAT_LONGLONG 0 41 | #endif 42 | 43 | unsigned xvformat(void (*outchar)(void *arg, char), void *arg, const char *fmt, va_list args); 44 | unsigned xformat(void (*outchar)(void *arg, char), void *arg, const char *fmt, ...); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "string.h" 8 | #include "io.h" 9 | #include "types.h" 10 | #include "debug.h" 11 | 12 | #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) 13 | 14 | #define ALIGN(size, align) (((size) + (align)-1) & (~((align)-1))) 15 | #define OF_ALIGN(size) ALIGN(size, 4) 16 | 17 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 18 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 19 | 20 | #ifndef NULL 21 | #define NULL 0 22 | #endif 23 | 24 | #define FALSE 0 25 | #define TRUE 1 26 | 27 | static inline unsigned int swap_uint32(unsigned int data) 28 | { 29 | volatile unsigned int a, b, c, d; 30 | 31 | a = ((data)&0xff000000) >> 24; 32 | b = ((data)&0x00ff0000) >> 8; 33 | c = ((data)&0x0000ff00) << 8; 34 | d = ((data)&0x000000ff) << 24; 35 | 36 | return a | b | c | d; 37 | } 38 | 39 | #define FILENAME_MAX_LEN 64 40 | typedef struct { 41 | unsigned int offset; 42 | unsigned int length; 43 | unsigned char *dest; 44 | 45 | unsigned int of_offset; 46 | unsigned char *of_dest; 47 | 48 | char filename[FILENAME_MAX_LEN]; 49 | char of_filename[FILENAME_MAX_LEN]; 50 | } image_info_t; 51 | 52 | void udelay(uint64_t us); 53 | void mdelay(uint32_t ms); 54 | void sdelay(uint32_t loops); 55 | uint32_t time_ms(void); 56 | uint64_t time_us(void); 57 | uint64_t get_arch_counter(void); 58 | void init_sp_irq(uint32_t addr); 59 | void reset(); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | 2 | BUILD_DIR=build 3 | 4 | MKSUNXI = mksunxi 5 | 6 | CSRC = mksunxi.c 7 | CXXSRC = 8 | 9 | COBJS = $(addprefix $(BUILD_DIR)/,$(CSRC:.c=.o)) 10 | CXXOBJS = $(addprefix $(BUILD_DIR)/,$(CXXSRC:.cpp=.opp)) 11 | 12 | INCLUDES = -I includes -I ../lib 13 | CFLAGS = -O2 -std=gnu99 $(INCLUDES) 14 | CXXFLAGS = -O2 -std=gnu++11 $(INCLUDES) 15 | 16 | CC ?= gcc 17 | CXX ?= g++ 18 | 19 | all: tools 20 | tools: $(MKSUNXI) 21 | 22 | .PHONY: all tools clean 23 | .SILENT: 24 | 25 | clean: 26 | rm -rf build 27 | rm -f $(MKSUNXI) 28 | 29 | $(BUILD_DIR)/%.o : %.c 30 | echo " CC $@" 31 | mkdir -p $(@D) 32 | $(CC) $(CFLAGS) -c $< -o $@ 33 | 34 | $(BUILD_DIR)/%.opp : %.cpp 35 | echo " CXX $@" 36 | mkdir -p $(@D) 37 | $(CXX) $(CXXFLAGS) -c $< -o $@ 38 | 39 | $(MKSUNXI): $(COBJS) 40 | echo " LD $@" 41 | $(CC) $(CFLAGS) $(COBJS) -o $(MKSUNXI) 42 | -------------------------------------------------------------------------------- /tools/hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | for i in `git diff --name-only | grep -E ".+\.(h|hpp|c|cpp)$"` 6 | do 7 | clang-format --verbose -i $i 8 | done 9 | -------------------------------------------------------------------------------- /tools/mksunxi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) 7 | #define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1) 8 | 9 | #if 0 10 | static inline uint32_t __swab32(uint32_t x) 11 | { 12 | return ( (x<<24) | (x>>24) | \ 13 | ((x & (uint32_t)0x0000ff00UL)<<8) | \ 14 | ((x & (uint32_t)0x00ff0000UL)>>8) ); 15 | } 16 | #define cpu_to_le32(x) (__swab32((uint32_t)(x))) 17 | #define le32_to_cpu(x) (__swab32((uint32_t)(x))) 18 | #else 19 | #define cpu_to_le32(x) (x) 20 | #define le32_to_cpu(x) (x) 21 | #endif 22 | 23 | #define BROM_PAGE_SIZE 2048 24 | 25 | struct boot_head_t { 26 | uint32_t instruction; 27 | uint8_t magic[8]; 28 | uint32_t checksum; 29 | uint32_t length; 30 | uint8_t spl_signature[4]; 31 | uint32_t fel_script_address; 32 | uint32_t fel_uenv_length; 33 | uint32_t dt_name_offset; 34 | uint32_t reserved1; 35 | uint32_t boot_media; 36 | uint32_t string_pool[13]; 37 | }; 38 | 39 | /* 40 | * BUG: the bootrom assumes all SPI flashes are 2KB page size. 41 | * If we want to boot from a device with larger page size, we need to adjust 42 | * the image in flash so that only the 1st 2KB of each page is used. 43 | */ 44 | static char* expand_pagesize(char *buffer, int *buflen, int pagesize) 45 | { 46 | char *buffer2; 47 | int offset, multiple; 48 | 49 | multiple = pagesize / BROM_PAGE_SIZE; 50 | 51 | if (multiple == 1) return buffer; 52 | 53 | buffer2 = malloc(*buflen * multiple); 54 | memset(buffer2, 0, *buflen * multiple); 55 | 56 | for (offset = 0; offset < *buflen; offset += BROM_PAGE_SIZE) { 57 | memcpy(buffer2 + (offset * multiple), buffer + offset, BROM_PAGE_SIZE); 58 | } 59 | 60 | free(buffer); 61 | *buflen *= multiple; 62 | return buffer2; 63 | } 64 | 65 | 66 | int main(int argc, char *argv[]) 67 | { 68 | struct boot_head_t *h; 69 | FILE *fp; 70 | char *buffer; 71 | int buflen, filelen; 72 | uint32_t *p; 73 | uint32_t sum; 74 | int i, l, loop, padding, pagesize; 75 | 76 | if (argc < 3 || argc > 4) { 77 | printf("Usage: mksunxi [pagesize]\n"); 78 | return -1; 79 | } 80 | 81 | padding = atoi(argv[2]); 82 | printf("padding: %d\n", padding); 83 | 84 | if (argc >= 4) { 85 | pagesize = atoi(argv[3]); 86 | if ((pagesize < 1) || (pagesize & (BROM_PAGE_SIZE-1))) { 87 | printf("pagesize must be multiple of 2048\n"); 88 | exit(1); 89 | } 90 | printf("pagesize: %d\n", pagesize); 91 | } 92 | else { 93 | pagesize = BROM_PAGE_SIZE; 94 | } 95 | 96 | if (padding != 512 && padding != 8192) { 97 | printf("padding must be 512 (block devices) or 8192 (flash)\n"); 98 | exit(1); 99 | } 100 | 101 | fp = fopen(argv[1], "r+b"); 102 | if (fp == NULL) { 103 | printf("Open bootloader error\n"); 104 | return -1; 105 | } 106 | fseek(fp, 0L, SEEK_END); 107 | filelen = ftell(fp); 108 | fseek(fp, 0L, SEEK_SET); 109 | 110 | if (filelen <= sizeof(struct boot_head_t)) { 111 | fclose(fp); 112 | printf("The size of bootloader too small\n"); 113 | return -1; 114 | } 115 | 116 | buflen = ALIGN(filelen, padding); 117 | buffer = malloc(buflen); 118 | memset(buffer, 0, buflen); 119 | if (fread(buffer, 1, filelen, fp) != filelen) { 120 | printf("Can't read bootloader\n"); 121 | free(buffer); 122 | fclose(fp); 123 | return -1; 124 | } 125 | 126 | h = (struct boot_head_t *)buffer; 127 | p = (uint32_t *)h; 128 | l = le32_to_cpu(h->length); 129 | printf("len: %u\n", l); 130 | l = ALIGN(l, padding); 131 | h->length = cpu_to_le32(l); 132 | h->checksum = cpu_to_le32(0x5F0A6C39); 133 | loop = l >> 2; 134 | for (i = 0, sum = 0; i < loop; i++) 135 | sum += le32_to_cpu(p[i]); 136 | h->checksum = cpu_to_le32(sum); 137 | 138 | buffer = expand_pagesize(buffer, &buflen, pagesize); 139 | 140 | fseek(fp, 0L, SEEK_SET); 141 | if (fwrite(buffer, 1, buflen, fp) != buflen) { 142 | printf("Write bootloader error\n"); 143 | free(buffer); 144 | fclose(fp); 145 | return -1; 146 | } 147 | 148 | free(buffer); 149 | fclose(fp); 150 | printf("The bootloader head has been fixed, spl size is %d bytes, flash size %d bytes.\r\n", l, buflen); 151 | return 0; 152 | } 153 | --------------------------------------------------------------------------------