Compare commits
398 Commits
v6.3.0
...
hekate-pro
| Author | SHA1 | Date | |
|---|---|---|---|
| fa9197245c | |||
|
|
bf9c214cef | ||
|
|
bf3390c081 | ||
|
|
958163d207 | ||
|
|
295c368490 | ||
|
|
d2a2832107 | ||
|
|
91ee3e0b7d | ||
|
|
b5baa15451 | ||
|
|
e4f72d8ab1 | ||
|
|
f77faf890b | ||
|
|
462e5c12aa | ||
|
|
9d0ed664cb | ||
|
|
8e6667ed72 | ||
|
|
e69ef9ee0d | ||
|
|
de7cf0cf83 | ||
|
|
4626816d40 | ||
|
|
5cab679a07 | ||
|
|
38c74c961b | ||
|
|
ddbc8e0d76 | ||
|
|
1c7792e386 | ||
|
|
17425831d5 | ||
|
|
517aa92740 | ||
|
|
91cdf02c43 | ||
|
|
45318f691f | ||
|
|
a60510f7de | ||
|
|
6b8f857021 | ||
|
|
d086da50d7 | ||
|
|
fee45ff62d | ||
|
|
1d4b835060 | ||
|
|
1561af252f | ||
|
|
5b1f9d25e7 | ||
|
|
14d9d3e9bf | ||
|
|
70262c8695 | ||
|
|
d8487e529b | ||
|
|
f6cecdc783 | ||
|
|
387b5b07ed | ||
|
|
e7deafd6a1 | ||
|
|
3e6df2459d | ||
|
|
902246984b | ||
|
|
7ca071a67c | ||
|
|
07408305f5 | ||
|
|
64a5d48ab5 | ||
|
|
fb6fb75448 | ||
|
|
a02624cd39 | ||
|
|
a4765e2839 | ||
|
|
88ba35b73f | ||
|
|
860e1b12ac | ||
|
|
95639d9bf1 | ||
|
|
eb8f46fd74 | ||
|
|
f975364a8e | ||
|
|
096e544332 | ||
|
|
c5eefcb609 | ||
|
|
89b71d9e81 | ||
|
|
72623d5a80 | ||
|
|
12d970fa64 | ||
|
|
0a0e8697bc | ||
|
|
9bca3c0253 | ||
|
|
fcbae9d581 | ||
|
|
a8325f4ec4 | ||
|
|
2ce8a57b89 | ||
|
|
0e49d62bed | ||
|
|
1101db8f19 | ||
|
|
45446486f2 | ||
|
|
267f4bff93 | ||
|
|
10fceea4be | ||
|
|
f26e9f0504 | ||
|
|
5ecc2a8202 | ||
|
|
58064bda34 | ||
|
|
1319984285 | ||
|
|
f45cb1c536 | ||
|
|
8881faa91b | ||
|
|
0e64b9384f | ||
|
|
e3fba92e00 | ||
|
|
2a7e148011 | ||
|
|
476c070cf4 | ||
|
|
8f6dce1368 | ||
|
|
10c2d3d379 | ||
|
|
84234948cd | ||
|
|
67b002348e | ||
|
|
e2ff75291b | ||
|
|
45a08c058f | ||
|
|
e4c226f101 | ||
|
|
7a37ddc45e | ||
|
|
2939f69928 | ||
|
|
2c071eb878 | ||
|
|
de3a74d351 | ||
|
|
eb62a31a1a | ||
|
|
29c64c5458 | ||
|
|
bf5372628a | ||
|
|
f16602c0cf | ||
|
|
aba56fd173 | ||
|
|
27bc159831 | ||
|
|
d24debc642 | ||
|
|
618e3007b5 | ||
|
|
378d38b850 | ||
|
|
6a43aa8c33 | ||
|
|
801c31f613 | ||
|
|
b8dcd5a05b | ||
|
|
f155346238 | ||
|
|
f08557fb8f | ||
|
|
c69cdacf30 | ||
|
|
b3c95990ed | ||
|
|
b86701823c | ||
|
|
9fe3ac7589 | ||
|
|
315457651c | ||
|
|
aecd657358 | ||
|
|
ef84b9804c | ||
|
|
16b14b74c2 | ||
|
|
925b6e22bb | ||
|
|
5a35a61753 | ||
|
|
e649d1df8e | ||
|
|
154d8b114c | ||
|
|
a8d3018e83 | ||
|
|
ef2247a3f0 | ||
|
|
0f4636546c | ||
|
|
22dd1a42c7 | ||
|
|
4daa02fe85 | ||
|
|
8c8ca53ab7 | ||
|
|
e6a3c80f4d | ||
|
|
2a0617dbf6 | ||
|
|
690beb0de7 | ||
|
|
6bcc2e082f | ||
|
|
c605e924ed | ||
|
|
d252dd7e52 | ||
|
|
2d3b6e1a39 | ||
|
|
b414e6b35f | ||
|
|
1651316f72 | ||
|
|
c200ef3f4a | ||
|
|
5fe649d7dd | ||
|
|
d5a1bdf9bf | ||
|
|
8e2a776e73 | ||
|
|
57e6875b42 | ||
|
|
d0dcfd0008 | ||
|
|
0cd9a5c80e | ||
|
|
a258c726dc | ||
|
|
89795a4c96 | ||
|
|
5a40f26010 | ||
|
|
ab794bc61d | ||
|
|
6c7370bec3 | ||
|
|
ba71fb0dba | ||
|
|
d1066da9fa | ||
|
|
542fba6fbd | ||
|
|
1295152f20 | ||
|
|
9ebd03802f | ||
|
|
07229f1002 | ||
|
|
d391ef3b0f | ||
|
|
18a3dd6374 | ||
|
|
8a25c8294f | ||
|
|
9ef684037b | ||
|
|
19279fa57d | ||
|
|
0edd5295d6 | ||
|
|
992245f044 | ||
|
|
2004b38f41 | ||
|
|
64a4f9db16 | ||
|
|
8220466523 | ||
|
|
d379a17444 | ||
|
|
db4c6a0b69 | ||
|
|
8b86bf3808 | ||
|
|
46fa18be89 | ||
|
|
c17881f2c3 | ||
|
|
c907d143b7 | ||
|
|
a8db6470ea | ||
|
|
e50a7c8bfd | ||
|
|
ffc0aa2c3d | ||
|
|
bb20eabea2 | ||
|
|
330b463110 | ||
|
|
4af99c9f78 | ||
|
|
4c2f8f14dc | ||
|
|
fd8c2ef56d | ||
|
|
6b66b7f079 | ||
|
|
76922b7b87 | ||
|
|
2bc4000acc | ||
|
|
892dba3a71 | ||
|
|
851bf05841 | ||
|
|
03cb1aac29 | ||
|
|
61cb77a016 | ||
|
|
facd5c9ae9 | ||
|
|
5c04530bfc | ||
|
|
ef5033fb0e | ||
|
|
952a7e8aa2 | ||
|
|
4430833d28 | ||
|
|
3af536f954 | ||
|
|
5bc98c4b19 | ||
|
|
2b353c1336 | ||
|
|
32c374aff5 | ||
|
|
1af22f6c45 | ||
|
|
4b796ab63f | ||
|
|
8d525a3c50 | ||
|
|
ef0ab0b0f1 | ||
|
|
7b7906efc2 | ||
|
|
e29d139946 | ||
|
|
cfcbb62768 | ||
|
|
b862311c0c | ||
|
|
11b49e3bbc | ||
|
|
ac245a0b6f | ||
|
|
c0300b1cee | ||
|
|
1eaa801d6a | ||
|
|
25359b23b9 | ||
|
|
db08514ff0 | ||
|
|
877e2c7c2e | ||
|
|
fa2d7854d3 | ||
|
|
ac0d98ad29 | ||
|
|
9b216efddf | ||
|
|
911b170b4d | ||
|
|
c026b1db3d | ||
|
|
dc1ad1a5a7 | ||
|
|
36aa1b21ad | ||
|
|
10521a32d3 | ||
|
|
82a97aae53 | ||
|
|
a365af0492 | ||
|
|
28dce16877 | ||
|
|
f541f14699 | ||
|
|
518cfd401a | ||
|
|
44dd00c29a | ||
|
|
0fa5db1d74 | ||
|
|
76d5cf591f | ||
|
|
daf832971e | ||
|
|
3c260b1918 | ||
|
|
6b4b20e0ac | ||
|
|
0468877136 | ||
|
|
fba05d4e7a | ||
|
|
b70fcb77e2 | ||
|
|
5437f9ce2c | ||
|
|
87e3ddadf7 | ||
|
|
8b7777f25b | ||
|
|
b0ec8a1e64 | ||
|
|
67157b1867 | ||
|
|
23ac454b1d | ||
|
|
af72bb5b94 | ||
|
|
e19cf3038b | ||
|
|
b52f5edce6 | ||
|
|
393d135105 | ||
|
|
6cc3aee389 | ||
|
|
7b4b26bb38 | ||
|
|
030576ff3f | ||
|
|
44e4c0ab21 | ||
|
|
f45adfd92f | ||
|
|
2fda4115aa | ||
|
|
d289224653 | ||
|
|
0647fd06d8 | ||
|
|
d33ded5f6d | ||
|
|
d0cb4f54a5 | ||
|
|
b70932cfaa | ||
|
|
1cf9cdc390 | ||
|
|
a532353682 | ||
|
|
3c02710192 | ||
|
|
b91ee67521 | ||
|
|
961acef306 | ||
|
|
86a70c3431 | ||
|
|
8bb483f20a | ||
|
|
c83bd247dd | ||
|
|
e484986c8f | ||
|
|
ba9863cca7 | ||
|
|
760c93e92f | ||
|
|
48b2f20c88 | ||
|
|
d13088f177 | ||
|
|
f6a32b538f | ||
|
|
3874b025a9 | ||
|
|
dd3b7d3ceb | ||
|
|
a2d35fb90e | ||
|
|
cca4f4c1fa | ||
|
|
0d3df99f76 | ||
|
|
93e3aa7830 | ||
|
|
86bb96e01a | ||
|
|
9158036902 | ||
|
|
64a754509e | ||
|
|
c3e971eb5b | ||
|
|
91caf7822f | ||
|
|
b22b90e55e | ||
|
|
26d8faa502 | ||
|
|
e66ab207d9 | ||
|
|
baea3b0265 | ||
|
|
380c1dc9b2 | ||
|
|
1ee9a9cd64 | ||
|
|
528e1fb0a4 | ||
|
|
077986cb47 | ||
|
|
ec84a58dcc | ||
|
|
51c1e31134 | ||
|
|
95af92d912 | ||
|
|
a028568349 | ||
|
|
fbaa88cc31 | ||
|
|
1e870bcef4 | ||
|
|
2d91e9b549 | ||
|
|
e2968c69dc | ||
|
|
bc42579f01 | ||
|
|
335b8b9a94 | ||
|
|
e1e2366684 | ||
|
|
b0690a7280 | ||
|
|
7f0835a548 | ||
|
|
5704004bc8 | ||
|
|
c7e1f5c09f | ||
|
|
50170f7cf2 | ||
|
|
52dba9a5a5 | ||
|
|
db519a454b | ||
|
|
f8436d1247 | ||
|
|
6340881f59 | ||
|
|
8405a86937 | ||
|
|
a3f5e33625 | ||
|
|
cfc2febc1b | ||
|
|
d6fda80057 | ||
|
|
37c8874930 | ||
|
|
37a016122c | ||
|
|
9b95d026f3 | ||
|
|
865b9dc1a4 | ||
|
|
7ebceb78bd | ||
|
|
154ed594fc | ||
|
|
af39c76b3a | ||
|
|
657b895aaf | ||
|
|
52a1e0ba67 | ||
|
|
f3b104e234 | ||
|
|
a5a2235b9d | ||
|
|
4c58708253 | ||
|
|
cbac787cff | ||
|
|
082490deda | ||
|
|
72b0f42514 | ||
|
|
8978ba9e54 | ||
|
|
74833e19e7 | ||
|
|
d5d0f79c38 | ||
|
|
7927cfe818 | ||
|
|
a1f48e858e | ||
|
|
fa561b70a4 | ||
|
|
567f0f66e1 | ||
|
|
b798dd1ef6 | ||
|
|
c91cf80f8b | ||
|
|
dca5df653b | ||
|
|
db08fab876 | ||
|
|
9adca44fe4 | ||
|
|
c202b4afb1 | ||
|
|
814ef14f2d | ||
|
|
eaedec7b6e | ||
|
|
e8addedd2f | ||
|
|
3c6bb75267 | ||
|
|
169c551445 | ||
|
|
7dad628dfc | ||
|
|
8ba90ae55f | ||
|
|
fe61c1a374 | ||
|
|
3412714402 | ||
|
|
2b0591e2b0 | ||
|
|
03b30a23c4 | ||
|
|
4f0bba605f | ||
|
|
4cfbef5062 | ||
|
|
02281fccf1 | ||
|
|
84078e5469 | ||
|
|
805686105d | ||
|
|
eacb4f2844 | ||
|
|
c8da71229a | ||
|
|
1a157a33f6 | ||
|
|
f093c9368b | ||
|
|
9a755b895b | ||
|
|
4c4a63795e | ||
|
|
04dc8d2a86 | ||
|
|
ed4b638545 | ||
|
|
a8a67ee775 | ||
|
|
1e54d538fd | ||
|
|
20487cb8b9 | ||
|
|
8bc14f1043 | ||
|
|
c8acea7ad5 | ||
|
|
3ea4fd81f7 | ||
|
|
76508c74e8 | ||
|
|
79b6df64d6 | ||
|
|
0a7a004839 | ||
|
|
7521055bec | ||
|
|
39d99a77fe | ||
|
|
b0f0e9be47 | ||
|
|
55a4a814e0 | ||
|
|
4bfe1fe2cd | ||
|
|
6d09e65d85 | ||
|
|
59a173c994 | ||
|
|
e5ceb4a2de | ||
|
|
ea3dae672e | ||
|
|
2af1cc0b8c | ||
|
|
942e7defe3 | ||
|
|
39b74dd50d | ||
|
|
bbe8ddaf66 | ||
|
|
47e030c7fc | ||
|
|
4a127db80b | ||
|
|
241b0f2274 | ||
|
|
ba6073610c | ||
|
|
70cb99cd0c | ||
|
|
7941a3d4d6 | ||
|
|
1ddf9690b1 | ||
|
|
f4d8ee4efc | ||
|
|
4f72660603 | ||
|
|
2440318cb5 | ||
|
|
61e91f79c1 | ||
|
|
bad8566c58 | ||
|
|
28796b417b | ||
|
|
31c8ad0d88 | ||
|
|
0be3fd4f64 | ||
|
|
3e9def3608 | ||
|
|
678ce79a54 | ||
|
|
b11e8095ed | ||
|
|
849d533200 | ||
|
|
337f219ac6 | ||
|
|
4e9e21b3b1 | ||
|
|
fe5e4dc40a | ||
|
|
5798dcde0d | ||
|
|
9d2ec42a9f |
123
Makefile
123
Makefile
@@ -14,6 +14,7 @@ include ./Versions.inc
|
||||
|
||||
TARGET := hekate
|
||||
BUILDDIR := build
|
||||
BUILDTDIR := build/$(TARGET)
|
||||
OUTPUTDIR := output
|
||||
SOURCEDIR = bootloader
|
||||
BDKDIR := bdk
|
||||
@@ -21,42 +22,33 @@ BDKINC := -I./$(BDKDIR)
|
||||
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
|
||||
|
||||
# Track compiler flags
|
||||
TRACK_CFLAGS = $(BUILDTDIR)/.cflags
|
||||
TRACK_LDFLAGS = $(BUILDTDIR)/.ldflags
|
||||
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
start.o exception_handlers.o \
|
||||
main.o heap.o \
|
||||
gfx.o logos.o tui.o \
|
||||
l4t.o fe_info.o fe_tools.o \
|
||||
)
|
||||
OBJS = start exception_handlers main heap gfx logos tui fe_info fe_tools
|
||||
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o ccplex.o clock.o di.o i2c.o irq.o timer.o \
|
||||
mc.o sdram.o minerva.o \
|
||||
gpio.o pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o \
|
||||
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
hw_init.o \
|
||||
)
|
||||
OBJS += bpmp ccplex clock di i2c irq timer \
|
||||
mc sdram minerva smmu \
|
||||
gpio pinmux pmc se tsec uart \
|
||||
fuse kfuse \
|
||||
sdmmc sdmmc_driver emmc sd emummc emummc_file_based emusd \
|
||||
bq24193 max17050 max7762x max77620-rtc \
|
||||
hw_init boot_storage file_based_storage
|
||||
|
||||
# Utilities.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
btn.o dirlist.o ianos.o util.o \
|
||||
config.o ini.o \
|
||||
)
|
||||
OBJS += btn dirlist ianos ini util config
|
||||
|
||||
# Horizon.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o \
|
||||
)
|
||||
# OS loaders.
|
||||
OBJS += l4t hos hos_config pkg1 pkg2 pkg3 pkg2_ini_kippatch secmon_exo
|
||||
|
||||
# Libraries.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
lz.o lz4.o blz.o \
|
||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
OBJS += lz lz4 blz diskio ff ffunicode ffsystem elfload elfreloc_arm
|
||||
|
||||
OBJS := $(addsuffix .o, $(OBJS))
|
||||
OBJS := $(addprefix $(BUILDTDIR)/, $(OBJS))
|
||||
|
||||
GFX_INC := '"../$(SOURCEDIR)/gfx/gfx.h"'
|
||||
FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"'
|
||||
@@ -68,7 +60,7 @@ CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_VER_RL=$(NYXVERSION_REL)
|
||||
|
||||
# BDK defines.
|
||||
CUSTOMDEFINES += -DBDK_MALLOC_NO_DEFRAG -DBDK_MC_ENABLE_AHB_REDIRECT -DBDK_EMUMMC_ENABLE
|
||||
CUSTOMDEFINES += -DBDK_MALLOC_NO_DEFRAG -DBDK_EMUMMC_ENABLE
|
||||
CUSTOMDEFINES += -DBDK_WATCHDOG_FIQ_ENABLE -DBDK_RESTART_BL_ON_WDT
|
||||
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
@@ -76,15 +68,15 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
# UART Logging: Max baudrate 12.5M.
|
||||
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=1
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wsign-compare -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
WARNINGS := -Wall -Wsign-compare -Wtype-limits -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
#-fno-delete-null-pointer-checks
|
||||
#-Wstack-usage=byte-size -fstack-usage
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork $(WARNINGS)
|
||||
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
@@ -94,39 +86,47 @@ TOOLSLZ := $(wildcard tools/lz)
|
||||
TOOLSB2C := $(wildcard tools/bin2c)
|
||||
TOOLS := $(TOOLSLZ) $(TOOLSB2C)
|
||||
|
||||
ifndef IPLECHO
|
||||
T := $(shell $(MAKE) $(BUILDTDIR)/$(TARGET).elf --no-print-directory -nrRf $(firstword $(MAKEFILE_LIST)) IPLECHO="IPLOBJ" | grep -c "IPLOBJ")
|
||||
|
||||
N := x
|
||||
C = $(words $N)$(eval N := x $N)
|
||||
IPLECHO = echo -ne "\r`expr " [\`expr $C '*' 100 / $T\`" : '.*\(....\)$$'`%]\033[K"
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR) $(LDRDIR) $(TOOLS)
|
||||
.PHONY: all clean $(LDRDIR) $(TOOLS) $(NYXDIR) $(MODULEDIRS)
|
||||
|
||||
all: $(TARGET).bin $(LDRDIR)
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo -n "Uncompr size: "
|
||||
@echo "$(TARGET) size:"
|
||||
@echo -n "Uncompr: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET)_unc.bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Uncompr Max: 140288 Bytes + 3 KiB BSS"
|
||||
@if [ ${BIN_SIZE} -gt 140288 ]; then echo "\e[1;33mUncompr size exceeds limit!\e[0m"; fi
|
||||
@echo -n "Payload size: "
|
||||
@echo -n "Payload: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Payload Max: 126296 Bytes"
|
||||
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean: $(TOOLS)
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
@$(MAKE) --no-print-directory -C $(LDRDIR) $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(MODULEDIRS):
|
||||
$(MODULEDIRS): $(BUILDTDIR)/$(TARGET).elf
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(NYXDIR):
|
||||
$(NYXDIR): $(BUILDTDIR)/$(TARGET).elf $(MODULEDIRS)
|
||||
@echo --------------------------------------
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(LDRDIR): $(TARGET).bin
|
||||
$(LDRDIR): $(TARGET).bin $(TOOLS) $(NYXDIR) $(MODULEDIRS)
|
||||
@$(TOOLSLZ)/lz77 $(OUTPUTDIR)/$(TARGET).bin
|
||||
mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.00.lz payload_00
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.01.lz payload_01
|
||||
@$(TOOLSB2C)/bin2c payload_00 > $(LDRDIR)/payload_00.h
|
||||
@@ -138,24 +138,31 @@ $(LDRDIR): $(TARGET).bin
|
||||
$(TOOLS):
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
$(TARGET).bin: $(BUILDTDIR)/$(TARGET).elf
|
||||
@$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
@echo --------------------------------------
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@echo "hekate was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
|
||||
$(BUILDTDIR)/$(TARGET).elf: $(OBJS) $(TRACK_LDFLAGS)
|
||||
@echo -ne "\r[100%] Linking $(TARGET).elf\033[K"
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $(OBJS) -o $@
|
||||
@printf "\n$(TARGET) was built with the following flags:\nCFLAGS: $(CFLAGS)\nLDFLAGS: $(LDFLAGS)\n"
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) $(BDKINC) -c $< -o $@
|
||||
$(BUILDTDIR)/%.o: %.c $(TRACK_CFLAGS) | $(BUILDTDIR)
|
||||
@$(IPLECHO) Building $@
|
||||
@$(CC) $(CFLAGS) $(BDKINC) -MMD -MP -c $< -o $@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.S
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
$(BUILDTDIR)/%.o: %.S $(TRACK_CFLAGS) | $(BUILDTDIR)
|
||||
@$(IPLECHO) Building $@
|
||||
@$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
|
||||
|
||||
$(OBJS): $(BUILDDIR)/$(TARGET)
|
||||
|
||||
$(BUILDDIR)/$(TARGET):
|
||||
$(BUILDTDIR):
|
||||
@mkdir -p "$(BUILDDIR)"
|
||||
@mkdir -p "$(BUILDDIR)/$(TARGET)"
|
||||
@mkdir -p "$(BUILDTDIR)"
|
||||
@mkdir -p "$(OUTPUTDIR)"
|
||||
|
||||
# Non objects change detectors.
|
||||
$(TRACK_CFLAGS): $(BUILDTDIR)
|
||||
@echo '$(CFLAGS)' | cmp -s - $@ || echo '$(CFLAGS)' > $@
|
||||
$(TRACK_LDFLAGS): $(BUILDTDIR)
|
||||
@echo '$(LDFLAGS)' | cmp -s - $@ || echo '$(LDFLAGS)' > $@
|
||||
-include $(OBJS:.o=.d)
|
||||
|
||||
83
README.md
83
README.md
@@ -50,13 +50,14 @@ Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many m
|
||||
| \|__ background.bmp | Nyx - Custom background. User provided. |
|
||||
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
|
||||
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. !Important! |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. !Important! |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. !Important! |
|
||||
| \|__ res.pak | Nyx resources package. !Important! |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. !Important! |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. !Important! |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. |
|
||||
| \|__ res.pak | Nyx resources package. |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. |
|
||||
| \|__ /l4t/ | Folder with firmware relevant to L4T (Linux/Android). |
|
||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||
| bootloader/payloads/ | For the `Payloads` menu. All CFW bootloaders, tools, Linux payloads are supported. Autoboot only supported by including them into an ini. |
|
||||
| bootloader/libtools/ | Reserved |
|
||||
@@ -65,7 +66,7 @@ Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many m
|
||||
|
||||
## Bootloader configuration
|
||||
|
||||
The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration.
|
||||
The bootloader can be configured via `Nyx` -> `Options` or 'bootloader/hekate_ipl.ini'. The special section 'config' controls the actual global configuration. Any other ini section represents a boot entry and can only be edited manually via the ini.
|
||||
|
||||
|
||||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||
@@ -74,22 +75,27 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
||||
**You can find a template [Here](./res/hekate_ipl_template.ini)**
|
||||
|
||||
|
||||
### hekate Global Configuration keys/values (when entry is *[config]*):
|
||||
### hekate Configuration keys/values (section *[config]*)
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
Use `Options` in Nyx to edit the following configuration:
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | -------------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| autoboot_list=0 | 0: Read `autoboot` boot entry from hekate_ipl.ini, 1: Read from ini folder (ini files are ASCII ordered). |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. Max: 20s. |
|
||||
| noticker=0 | 0: Animated line is drawn during custom bootlogo, signifying time left to skip to menu. 1: Disable. |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
| ------------------ | --------- *The following can be edited via ini only* --------- |
|
||||
| noticker=0 | 0: Animated line is drawn during custom bootlogo, signifying time left to skip to menu. 1: Disable. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
|
||||
|
||||
### Boot entry key/value combinations:
|
||||
### Boot entry key/value combinations
|
||||
|
||||
A boot entry needs to be manually added/edited with the user's chosen key/value combos.
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
@@ -98,18 +104,20 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
||||
| kernel={FILE path} | Replaces the kernel binary |
|
||||
| kip1={FILE path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={FOLDER path}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={FILE path} | Takes an Atmosphere `package3` binary (formerly fusee-secondary.bin) and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere if enabled. |
|
||||
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
|
||||
| pkg3={FILE path} | Takes an Atmosphere `package3` binary and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere. |
|
||||
| fss0={FILE path} | Same as above. !Deprecated! |
|
||||
| pkg3ex=1 | Enables loading of experimental content from a PKG3/FSS0 storage |
|
||||
| pkg3kip1skip={KIP name} | Skips loading a kip from `pkg3`/`fss0`. Allows multiple and `,` as separator. The name must exactly match the name in `PKG3`. |
|
||||
| exofatal={FILE path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or in one line with `,` as separator. If actual patch is not found, a warning will show up |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Allows multiple and `,` as separator. If actual patch is not found, a warning will show up. |
|
||||
| emupath={FOLDER path} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
|
||||
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
|
||||
| stock=1 | OFW via hekate bootloader. Disables unneeded kernel patching and CFW kips when running stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission). Doesn't work with Mesosphere as kernel. |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
|
||||
| kernelprocid=1 | Enables stock kernel process id send/recv patching. Not needed when `pkg3`/`fss0` is used. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| payload={FILE path} | Payload launching. Tools, Android/Linux, CFW bootloaders, etc. Any key above when used with that, doesn't get into account. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
@@ -119,6 +127,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
||||
| ram_oc_vdd2=1100 | L4T RAM VDD2 Voltage. Set VDD2 (T210B01) or VDD2/VDDQ (T210) voltage. 1050-1175. |
|
||||
| ram_oc_vddq=600 | L4T RAM VDDQ Voltage. Set VDDQ (T210B01). 550-650. |
|
||||
| uart_port=0 | Enables logging on serial port for L4T uboot/kernel. |
|
||||
| sld_type=0x31444C53 | Controls the type of seamless display support. 0x0: Disable, 0x31444C53: L4T seamless display. |
|
||||
| Additional keys | Each distro supports more keys. Check README_CONFIG.txt for more info. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| bootwait=3 | Overrides global bootwait from `[config]`. |
|
||||
@@ -129,14 +138,16 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
**Note2**: When using PKG3/FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `pkg3`/`fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be under `fss0` line.
|
||||
**Warning**: Careful when you override *pkg3/fss core* kips with `kip1`.
|
||||
That's in case the kips are incompatible between them. If compatible, you can override `pkg3`/`fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be **after** `pkg3`/`fss0` line.
|
||||
|
||||
|
||||
### Boot entry key/value combinations for Exosphère:
|
||||
### Boot entry key/value combinations for Exosphère
|
||||
|
||||
The following can be paired together with a HOS boot entry:
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
@@ -145,6 +156,7 @@ This is in case the kips are incompatible between them. If compatible, you can o
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
|
||||
| memmode=1 | Enables boot config memory mode for retail units. By default, max ram is limited to 4GB. Enabling this will automatically choose size. |
|
||||
|
||||
|
||||
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
|
||||
@@ -153,9 +165,9 @@ This is in case the kips are incompatible between them. If compatible, you can o
|
||||
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
## Payload storage
|
||||
|
||||
hekate has a boot storage in the binary that helps it configure it outside of BPMP enviroment:
|
||||
hekate has a boot storage in the binary that helps it configure it outside of BPMP environment:
|
||||
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
@@ -164,33 +176,36 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1/2/3: eMMC BOOT0/BOOT1/GPP, 4/5/6: emuMMC BOOT0/BOOT1/GPP, |
|
||||
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |
|
||||
|
||||
|
||||
### Nyx Configuration keys/values (nyx.ini):
|
||||
## Nyx Configuration keys/values (nyx.ini)
|
||||
|
||||
Use `Nyx Settings` in Nyx to edit the following configuration:
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| themebg=2d2d2d | Sets Nyx background color in HEX. EXPERIMENTAL. |
|
||||
| themebg=2d2d2d | Sets Nyx background color in HEX. 0x0B0B0B to 0xC7C7C7. |
|
||||
| themecolor=167 | Sets Nyx color of text highlights. |
|
||||
| entries5col=0 | 1: Sets Launch entry columns from 4 to 5 per line. For a total of 10 entries. |
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| timeoffset=0 | Sets time offset in HEX. Must be in epoch format |
|
||||
| timedst=1 | Enables automatic daylight saving hour adjustment |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| ------------------ | ------- The following options can only be edited in nyx.ini ------- |
|
||||
| ------------------ | ----- *The following can be edited via nyx.ini only* ----- |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
| jcforceright=0 | 1: Forces right joycon to be used as main mouse control. |
|
||||
| bpmpclock=1 | 0: Auto, 1: Fastest, 2: Faster, 3: Fast. Use 2 or 3 if Nyx hangs or some functions like UMS/Backup Verification fail. |
|
||||
| bpmpclock=1 | 0: Auto, 1: 589 MHz, 2: 576 MHz, 3: 563 MHz, 4: 544 MHz, 5: 408 MHz. Use 2 to 5 if Nyx hangs or some functions like UMS/Backup Verification fail. |
|
||||
|
||||
|
||||
```
|
||||
hekate (c) 2018, naehrwert, st4rk.
|
||||
(c) 2018-2024, CTCaer.
|
||||
(c) 2018-2026, CTCaer.
|
||||
|
||||
Nyx GUI (c) 2019-2024, CTCaer.
|
||||
Nyx GUI (c) 2019-2026, CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 6
|
||||
BLVERSION_MINOR := 2
|
||||
BLVERSION_HOTFX := 2
|
||||
BLVERSION_MINOR := 5
|
||||
BLVERSION_HOTFX := 3
|
||||
BLVERSION_REL := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 6
|
||||
NYXVERSION_HOTFX := 4
|
||||
NYXVERSION_MINOR := 9
|
||||
NYXVERSION_HOTFX := 3
|
||||
NYXVERSION_REL := 0
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <input/als.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
@@ -58,7 +58,7 @@
|
||||
#include <soc/uart.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/mmc_def.h>
|
||||
#include <storage/nx_emmc_bis.h>
|
||||
#include <storage/ramdisk.h>
|
||||
#include <storage/sd.h>
|
||||
@@ -72,6 +72,8 @@
|
||||
#include <utils/ini.h>
|
||||
#include <utils/list.h>
|
||||
#include <utils/sprintf.h>
|
||||
#include <utils/tegra_bct.h>
|
||||
#include <utils/tegra_bit.h>
|
||||
#include <utils/types.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
|
||||
543
bdk/display/di.c
543
bdk/display/di.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -30,15 +30,16 @@
|
||||
#define WINDOW_D 3
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
// All Display/DSI/MIPI register defines and macros are index based (not offset).
|
||||
// DC_CMD/DC_COM/WINC Non-shadowed. DC_DISP/DC_WIN/DC_WINBUF Shadowed.
|
||||
|
||||
// Display controller scratch registers.
|
||||
#define DC_D_WINBUF_DD_SCRATCH_REGISTER_0 0xED
|
||||
#define DC_D_WINBUF_DD_SCRATCH_REGISTER_1 0xEE
|
||||
#define DC_T_WINBUF_TD_SCRATCH_REGISTER_0 0x16D
|
||||
#define DC_T_WINBUF_TD_SCRATCH_REGISTER_1 0x16E
|
||||
#define DC_COM_SCRATCH_REGISTER_A 0x325
|
||||
#define DC_COM_SCRATCH_REGISTER_B 0x326
|
||||
#define DC_COM_SCRATCH_REGISTER_A 0x325
|
||||
#define DC_COM_SCRATCH_REGISTER_B 0x326
|
||||
#define DC_A_WINBUF_AD_SCRATCH_REGISTER_0 0xBED
|
||||
#define DC_A_WINBUF_AD_SCRATCH_REGISTER_1 0xBEE
|
||||
#define DC_B_WINBUF_BD_SCRATCH_REGISTER_0 0xDED
|
||||
@@ -280,8 +281,8 @@
|
||||
#define DC_DISP_CURSOR_BACKGROUND 0x43D
|
||||
#define CURSOR_COLOR(r,g,b) (((r) & 0xFF) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16))
|
||||
|
||||
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
||||
#define DC_DISP_CURSOR_START_ADDR_NS 0x43F
|
||||
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
||||
#define DC_DISP_CURSOR_START_ADDR_NS 0x43F
|
||||
#define CURSOR_CLIPPING(w) ((w) << 28)
|
||||
#define CURSOR_CLIP_WIN_A 1
|
||||
#define CURSOR_CLIP_WIN_B 2
|
||||
@@ -290,11 +291,10 @@
|
||||
#define CURSOR_SIZE_64 (1 << 24)
|
||||
#define CURSOR_SIZE_128 (2 << 24)
|
||||
#define CURSOR_SIZE_256 (3 << 24)
|
||||
#define DC_DISP_CURSOR_POSITION 0x440
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||
#define DC_DISP_CURSOR_POSITION 0x440
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI_NS 0x4ED
|
||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||
#define CURSOR_BLEND_2BIT (0 << 24)
|
||||
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
|
||||
#define CURSOR_BLEND_SRC_FACTOR(n) ((n) << 8)
|
||||
@@ -304,11 +304,14 @@
|
||||
#define CURSOR_BLEND_NK1 2
|
||||
// End of cursor cfg regs.
|
||||
|
||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
||||
#define DC_DISP_SD_BL_PARAMETERS 0x4D7
|
||||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
||||
#define DC_DISP_SD_BL_PARAMETERS 0x4D7
|
||||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
|
||||
#define DC_DISP_DISPLAY_SPARE0 0x4F7 // Used by SW/HW.
|
||||
#define DC_DISP_DISPLAY_SPARE1 0x4F8
|
||||
|
||||
#define DC_WINC_COLOR_PALETTE 0x500
|
||||
#define COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off))
|
||||
#define COLOR_PALETTE_RGB(rgb) (byte_swap_32(rgb) >> 8)
|
||||
@@ -466,9 +469,10 @@
|
||||
|
||||
#define DC_WINBUF_MEMFETCH_CONTROL 0x82B
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
/* Scratch register to store DCS backlight level (custom). */
|
||||
#define DC_DCS_BACKLIGHT_LEVEL DC_COM_SCRATCH_REGISTER_B
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define DSI_INCR_SYNCPT_CNTRL 0x1
|
||||
#define DSI_INCR_SYNCPT_SOFT_RESET BIT(0)
|
||||
#define DSI_INCR_SYNCPT_NO_STALL BIT(8)
|
||||
@@ -520,6 +524,7 @@
|
||||
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
||||
#define DSI_STATUS_TX_FIFO_SIZE 0x20 // Actual depth is 64.
|
||||
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
@@ -717,7 +722,7 @@
|
||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0 // 43 bytes.
|
||||
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
||||
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
@@ -727,8 +732,9 @@
|
||||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
#define MIPI_DCS_PRIV_SM_DISPLAY_ID 0xDD
|
||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Lock/Unlock: A5/5A. LVL1 group is normal registers.
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||
|
||||
@@ -765,19 +771,21 @@
|
||||
|
||||
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3) // Transition fading.
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
#define DCS_CONTROL_DISPLAY_HBM_CTRL0 BIT(6)
|
||||
#define DCS_CONTROL_DISPLAY_HBM_CTRL1 BIT(7)
|
||||
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Based on Vivid but over-saturated.
|
||||
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03 // Real natural profile.
|
||||
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural.. Extra saturation.
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65 // Saturated.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on Washed Out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on Basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on Natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on Vivid.
|
||||
|
||||
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
||||
|
||||
@@ -800,7 +808,10 @@
|
||||
* [30] 97 [0F]: AUO A062TAN02 (59.06A33.002) [From photo of assumed same panel]
|
||||
* [30] 98 [0F]: AUO A062TAN0? [UNCONFIRMED MODEL]
|
||||
* [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID]
|
||||
*
|
||||
* [E0] 01 [0F]: Retro Remake SUPER7 IPS (Rev 01)
|
||||
* [E1] 01 [0F]: Retro Remake SUPER7 IPS HD (Rev 01)
|
||||
* [E0] 11 [0F]: Retro Remake SUPER7 OLED (Rev 01)
|
||||
* [E1] 11 [0F]: Retro Remake SUPER7 OLED HD (Rev 01)
|
||||
*
|
||||
* 5.5" panels for Hoag SKU:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) (6203B001P4000)
|
||||
@@ -810,10 +821,13 @@
|
||||
* [30] 94 [10]: AUO A055TAN02 (59.05A30.002)
|
||||
* [30] 95 [10]: AUO A055TAN03 (59.05A30.003)
|
||||
* [40] 94 [10]: Sharp LQ055T1SW10 (Rev P)
|
||||
*
|
||||
* [E0] 01 [10]: Retro Remake SUPER5 OLED (Rev 01)
|
||||
* [E1] 01 [10]: Retro Remake SUPER5 OLED HD (Rev 01)
|
||||
*
|
||||
* 7.0" OLED panels for Aula SKU:
|
||||
* [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5)
|
||||
* [E0] 01 [20]: Retro Remake SUPER7 OLED (Rev 01)
|
||||
* [E1] 01 [20]: Retro Remake SUPER7 OLED HD (Rev 01)
|
||||
*/
|
||||
|
||||
/* Display ID Decoding:
|
||||
@@ -838,21 +852,29 @@
|
||||
enum
|
||||
{
|
||||
PANEL_JDI_XXX062M = 0x10,
|
||||
PANEL_JDI_LAM062M109A = 0x0910,
|
||||
PANEL_JDI_LPM062M326A = 0x2610,
|
||||
PANEL_JDI_LAM062M109A = 0x0910, // SI.
|
||||
PANEL_JDI_LPM062M326A = 0x2610, // LTPS.
|
||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030,
|
||||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||
PANEL_SAM_AMS699VC01 = 0x2050,
|
||||
PANEL_RR_SUPER5_OLED_V1 = 0x10E0,
|
||||
PANEL_RR_SUPER5_OLED_HD_V1 = 0x10E1,
|
||||
PANEL_RR_SUPER7_IPS_V1 = 0x0FE0,
|
||||
PANEL_RR_SUPER7_IPS_HD_V1 = 0x0FE1,
|
||||
PANEL_RR_SUPER7_OLED_7V1 = 0x20E0,
|
||||
PANEL_RR_SUPER7_OLED_HD_7V1 = 0x20E1,
|
||||
|
||||
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
|
||||
// Found on 6/2" clones. Unknown markings. Clone of AUO A062TAN01.
|
||||
// Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F]. Sometimes reports [30] 94 [0F]. Both IDs have correct CRC16.
|
||||
PANEL_OEM_CLONE_6_2 = 0x0F83,
|
||||
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||
PANEL_OEM_CLONE_5_5 = 0x00B3,
|
||||
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
|
||||
PANEL_OEM_CLONE = 0x0000
|
||||
//0x0F40 [40] 94 [0F], 5.5" clone
|
||||
};
|
||||
|
||||
void display_init();
|
||||
@@ -865,6 +887,7 @@ void display_disable_interrupt(u32 intr);
|
||||
void display_wait_interrupt(u32 intr);
|
||||
|
||||
/*! Get/Set Display panel ID. */
|
||||
u32 display_get_verbose_panel_id();
|
||||
u16 display_get_decoded_panel_id();
|
||||
void display_set_decoded_panel_id(u32 id);
|
||||
|
||||
@@ -877,10 +900,9 @@ void display_dsi_vblank_write(u8 cmd, u32 len, void *data);
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Switches screen backlight ON/OFF. */
|
||||
/*! Screen backlight ON/OFF or set via duty and fading. */
|
||||
void display_backlight(bool enable);
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
u32 display_get_backlight_brightness();
|
||||
|
||||
u32 *display_init_window_a_pitch();
|
||||
u32 *display_init_window_a_pitch_vic();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -16,11 +16,10 @@
|
||||
*/
|
||||
|
||||
// Display A config.
|
||||
static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
static const reg_cfg_t _di_dc_init_config[] = {
|
||||
/* Display init */
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL | WIN_D_ACT_HCNTR_SEL},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||
@@ -32,10 +31,11 @@ static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||
|
||||
/* Setup Windows A/B/C */
|
||||
/* Disable A/B/C/D Windows */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WINC_CSC_YOF, 0xF0},
|
||||
{DC_WINC_CSC_KYRGB, 0x12A},
|
||||
@@ -45,8 +45,8 @@ static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
{DC_WINC_CSC_KVG, 0x32F},
|
||||
{DC_WINC_CSC_KUB, 0x204},
|
||||
{DC_WINC_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
|
||||
/* Init color, format and background */
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
|
||||
@@ -55,6 +55,8 @@ static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ},
|
||||
|
||||
/* Stop display */
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, 0},
|
||||
@@ -113,7 +115,7 @@ static const reg_cfg_t _di_dsi_init_config[] = {
|
||||
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
/* DSI PHY timings Init - 19.2 MHz */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
@@ -125,12 +127,13 @@ static const reg_cfg_t _di_dsi_init_config[] = {
|
||||
|
||||
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Power up.
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
};
|
||||
|
||||
// DSI LP config.
|
||||
static const reg_cfg_t _di_dsi_timing_lp_config[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
/* DSI PHY timings LP - 50 MHz */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
@@ -143,7 +146,6 @@ static const reg_cfg_t _di_dsi_init_config[] = {
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
@@ -197,11 +199,11 @@ static const reg_cfg_t _di_dsi_panel_init_config_jdi[] = {
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
// DSI packet config.
|
||||
// DSI HS packet config.
|
||||
static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
/* DSI PHY timings HP - 234 MHz */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
@@ -211,6 +213,7 @@ static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
/* DSI packet sequence */
|
||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||
@@ -293,7 +296,7 @@ static const reg_cfg_t _di_mipi_dsi_cal_unused_config[] = {
|
||||
};
|
||||
|
||||
// Display A enable config.
|
||||
static const reg_cfg_t _di_dc_video_enable_config[] = {
|
||||
static const reg_cfg_t _di_dc_video_mode_config[] = {
|
||||
/* Set panel timings */
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)},
|
||||
{DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)},
|
||||
@@ -306,7 +309,6 @@ static const reg_cfg_t _di_dc_video_enable_config[] = {
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||
|
||||
/* Start continuous display. */
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
|
||||
@@ -318,8 +320,6 @@ static const reg_cfg_t _di_dc_video_enable_config[] = {
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)}, // 4: div3.
|
||||
};
|
||||
|
||||
// Display A disable config.
|
||||
@@ -345,30 +345,6 @@ static const reg_cfg_t _di_dc_video_disable_config[] = {
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
};
|
||||
|
||||
// DSI deinit config.
|
||||
static const reg_cfg_t _di_dsi_timing_deinit_config[] = {
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
/* DSI PHY timings */
|
||||
{DSI_PHY_TIMING_0, 0x6070603},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
/* DSI timeout */
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
// DSI panel JDI deinit config.
|
||||
static const reg_cfg_t _di_dsi_panel_deinit_config_jdi[] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* VIC driver for Tegra X1
|
||||
* VIC (4.0) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
*
|
||||
@@ -45,9 +45,10 @@
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C
|
||||
#define CACHE_WIDTH(n) ((n) << 16)
|
||||
#define CACHE_WIDTH_16BX16 0 // Block Linear.
|
||||
#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear.
|
||||
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch.
|
||||
#define CACHE_WIDTH_32BX8 1 // Block Linear.
|
||||
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended.
|
||||
#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch.
|
||||
#define CACHE_WIDTH_256BX1 4 // Pitch.
|
||||
#define OUTPUT_FLIP_X BIT(20)
|
||||
#define OUTPUT_FLIP_Y BIT(21)
|
||||
#define OUTPUT_TRANSPOSE BIT(22)
|
||||
@@ -374,7 +375,7 @@ static void _vic_write_priv(u32 addr, u32 data)
|
||||
VIC(PVIC_FALCON_ADDR) = 0;
|
||||
}
|
||||
|
||||
static int _vic_wait_idle()
|
||||
int vic_wait_idle()
|
||||
{
|
||||
u32 timeout_count = 15000; // 150ms.
|
||||
|
||||
@@ -384,7 +385,7 @@ static int _vic_wait_idle()
|
||||
|
||||
timeout_count--;
|
||||
if (!timeout_count)
|
||||
return -1;
|
||||
return 1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
@@ -508,7 +509,7 @@ void vic_set_surface(const vic_surface_t *sfc)
|
||||
_vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
vic_wait_idle();
|
||||
|
||||
// Set slot mapping.
|
||||
_vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
|
||||
@@ -523,13 +524,13 @@ void vic_set_surface(const vic_surface_t *sfc)
|
||||
_vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
vic_wait_idle();
|
||||
}
|
||||
|
||||
int vic_compose()
|
||||
{
|
||||
// Wait for surface cache to get ready. Otherwise VIC will hang.
|
||||
int res = _vic_wait_idle();
|
||||
int res = vic_wait_idle();
|
||||
|
||||
// Start composition of a single frame.
|
||||
_vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
|
||||
@@ -551,7 +552,7 @@ int vic_init()
|
||||
// Start Fetch Control Engine.
|
||||
_vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
|
||||
|
||||
return _vic_wait_idle();
|
||||
return vic_wait_idle();
|
||||
}
|
||||
|
||||
void vic_end()
|
||||
|
||||
@@ -59,6 +59,7 @@ typedef struct _vic_surface_t
|
||||
} vic_surface_t;
|
||||
|
||||
void vic_set_surface(const vic_surface_t *sfc);
|
||||
int vic_wait_idle();
|
||||
int vic_compose();
|
||||
int vic_init();
|
||||
void vic_end();
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
* 11111 | SYS | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
|
||||
*/
|
||||
|
||||
#define EXCP_EN_ADDR 0x4003FFFC
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_LR_ADDR 0x4003FFF4
|
||||
#define EXCP_EN_ADDR 0x4003FF1C
|
||||
#define EXCP_TYPE_ADDR 0x4003FF18
|
||||
#define EXCP_LR_ADDR 0x4003FF14
|
||||
|
||||
#define EXCP_VEC_BASE 0x6000F000
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)
|
||||
{
|
||||
return ctx->pread(ctx, def, nb, offset) ? EL_OK : EL_EIO;
|
||||
return ctx->pread(ctx, def, nb, offset);
|
||||
}
|
||||
|
||||
#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))
|
||||
|
||||
@@ -53,7 +53,7 @@ typedef enum
|
||||
|
||||
typedef struct el_ctx
|
||||
{
|
||||
bool (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset);
|
||||
el_status (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset);
|
||||
|
||||
/* base_load_* -> address we are actually going to load at
|
||||
*/
|
||||
@@ -61,6 +61,9 @@ typedef struct el_ctx
|
||||
base_load_paddr,
|
||||
base_load_vaddr;
|
||||
|
||||
/* original memory of binary */
|
||||
Elf_Addr eaddr;
|
||||
|
||||
/* size in memory of binary */
|
||||
Elf_Addr memsz;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 M4xw
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -15,109 +15,148 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <storage/boot_storage.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ianos.h"
|
||||
#include "elfload/elfload.h"
|
||||
#include <module.h>
|
||||
#include <mem/heap.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <storage/sd.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define DRAM_LIB_ADDR 0xE0000000
|
||||
|
||||
extern heap_t _heap;
|
||||
|
||||
void *elfBuf = NULL;
|
||||
void *fileBuf = NULL;
|
||||
static bdk_params_t _bdk_params = {
|
||||
.gfx_con = (void *)&gfx_con,
|
||||
.gfx_ctx = (void *)&gfx_ctxt,
|
||||
.heap = &_heap,
|
||||
.memcpy = (memcpy_t)&memcpy,
|
||||
.memset = (memset_t)&memset,
|
||||
|
||||
static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
||||
{
|
||||
bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));
|
||||
bdkParameters->gfxCon = (void *)&gfx_con;
|
||||
bdkParameters->gfxCtx = (void *)&gfx_ctxt;
|
||||
bdkParameters->memcpy = (memcpy_t)&memcpy;
|
||||
bdkParameters->memset = (memset_t)&memset;
|
||||
bdkParameters->sharedHeap = &_heap;
|
||||
|
||||
// Extra functions.
|
||||
bdkParameters->extension_magic = IANOS_EXT0;
|
||||
bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage;
|
||||
|
||||
entrypoint(moduleConfig, bdkParameters);
|
||||
}
|
||||
.extension_magic = 0
|
||||
};
|
||||
|
||||
static void *_ianos_alloc_cb(el_ctx *ctx, Elf_Addr phys, Elf_Addr virt, Elf_Addr size)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)phys;
|
||||
(void)size;
|
||||
return (void *)virt;
|
||||
}
|
||||
|
||||
static bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset)
|
||||
static el_status _ianos_read_cb(el_ctx *ctx, void *dest, size_t nb, size_t offset)
|
||||
{
|
||||
(void)ctx;
|
||||
memcpy(dest, (void *)(ctx->eaddr + offset), nb);
|
||||
|
||||
memcpy(dest, fileBuf + offset, numberBytes);
|
||||
|
||||
return true;
|
||||
return EL_OK;
|
||||
}
|
||||
|
||||
//TODO: Support shared libraries.
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
||||
int ianos_loader(ianos_lib_t *lib, char *path)
|
||||
{
|
||||
el_ctx ctx;
|
||||
uintptr_t epaddr = 0;
|
||||
lib->buf = NULL;
|
||||
if (!lib->bdk)
|
||||
lib->bdk = &_bdk_params;
|
||||
|
||||
// Read library.
|
||||
fileBuf = sd_file_read(path, NULL);
|
||||
|
||||
if (!fileBuf)
|
||||
goto out;
|
||||
ctx.eaddr = (Elf_Addr)boot_storage_file_read(path, NULL);
|
||||
if (!ctx.eaddr)
|
||||
goto error;
|
||||
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
goto out;
|
||||
goto error;
|
||||
|
||||
if (lib->type & IA_SHARED_LIB)
|
||||
goto error; // No support for shared libs now.
|
||||
|
||||
// Set our relocated library's buffer.
|
||||
switch (type & 0xFFFF)
|
||||
switch (lib->type & ~IA_SHARED_LIB)
|
||||
{
|
||||
case EXEC_ELF:
|
||||
case AR64_ELF:
|
||||
elfBuf = (void *)DRAM_LIB_ADDR;
|
||||
case IA_DRAM_LIB:
|
||||
lib->buf = malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
break;
|
||||
|
||||
case IA_IRAM_LIB:
|
||||
break;
|
||||
|
||||
case IA_AUTO_LIB: // Default to DRAM for now.
|
||||
default:
|
||||
elfBuf = malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
lib->buf = malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!elfBuf)
|
||||
goto out;
|
||||
if (!lib->buf)
|
||||
goto error;
|
||||
|
||||
// Load and relocate library.
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = (Elf_Addr)lib->buf;
|
||||
if (el_load(&ctx, _ianos_alloc_cb))
|
||||
goto out_free;
|
||||
goto error;
|
||||
|
||||
if (el_relocate(&ctx))
|
||||
goto out_free;
|
||||
goto error;
|
||||
|
||||
free((void *)ctx.eaddr);
|
||||
|
||||
// Launch.
|
||||
epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;
|
||||
moduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr;
|
||||
Elf_Addr epaddr = ctx.ehdr.e_entry + (Elf_Addr)lib->buf;
|
||||
moduleEntrypoint ep = (moduleEntrypoint)epaddr;
|
||||
ep(lib->private, lib->bdk);
|
||||
|
||||
_ianos_call_ep(ep, moduleConfig);
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
free(fileBuf);
|
||||
elfBuf = NULL;
|
||||
fileBuf = NULL;
|
||||
error:
|
||||
free((void *)ctx.eaddr);
|
||||
free(lib->buf);
|
||||
|
||||
out:
|
||||
return epaddr;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uintptr_t ianos_static_module(char *path, void *private)
|
||||
{
|
||||
el_ctx ctx;
|
||||
Elf_Addr buf = 0;
|
||||
Elf_Addr epaddr = 0;
|
||||
|
||||
// Read library.
|
||||
ctx.eaddr = (Elf_Addr)sd_file_read(path, NULL);
|
||||
if (!ctx.eaddr)
|
||||
goto error;
|
||||
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
// Initialize elfload context.
|
||||
if (el_init(&ctx))
|
||||
goto error;
|
||||
|
||||
// Set our relocated library's buffer.
|
||||
buf = (Elf_Addr)malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
if (!buf)
|
||||
goto error;
|
||||
|
||||
// Load and relocate library.
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = buf;
|
||||
if (el_load(&ctx, _ianos_alloc_cb))
|
||||
goto error;
|
||||
|
||||
if (el_relocate(&ctx))
|
||||
goto error;
|
||||
|
||||
free((void *)ctx.eaddr);
|
||||
|
||||
// Launch.
|
||||
epaddr = ctx.ehdr.e_entry + buf;
|
||||
moduleEntrypoint ep = (moduleEntrypoint)epaddr;
|
||||
ep(private, &_bdk_params);
|
||||
|
||||
return (uintptr_t)epaddr;
|
||||
|
||||
error:
|
||||
free((void *)ctx.eaddr);
|
||||
free((void *)buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 M4xw
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,16 +19,26 @@
|
||||
#define IANOS_H
|
||||
|
||||
#include <utils/types.h>
|
||||
#include <module.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DRAM_LIB = 0, // DRAM library.
|
||||
EXEC_ELF = 1, // Executable elf that does not return.
|
||||
DR64_LIB = 2, // AARCH64 DRAM library.
|
||||
AR64_ELF = 3, // Executable elf that does not return.
|
||||
KEEP_IN_RAM = (1 << 31) // Shared library mask.
|
||||
} elfType_t;
|
||||
IA_DRAM_LIB = 0, // DRAM library.
|
||||
IA_IRAM_LIB = 1, // IRAM library. No support for now.
|
||||
IA_AUTO_LIB = 2, // AUTO library. Defaults to DRAM for now.
|
||||
IA_SHARED_LIB = BIT(7) // Shared library mask. No support for now.
|
||||
} ianos_type_t;
|
||||
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void* config);
|
||||
typedef struct _ianos_lib_t
|
||||
{
|
||||
uintptr_t epaddr;
|
||||
void *buf;
|
||||
void *private;
|
||||
ianos_type_t type;
|
||||
bdk_params_t *bdk;
|
||||
} ianos_lib_t;
|
||||
|
||||
#endif
|
||||
int ianos_loader(ianos_lib_t *lib, char *path);
|
||||
uintptr_t ianos_static_module(char *path, void *private); // Session-lived DRAM lib.
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,8 +70,6 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Ambient light sensor driver for Nintendo Switch's Rohm BH1730
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -86,6 +86,8 @@ typedef struct _jc_gamepad_rpt_t
|
||||
bool sio_mode;
|
||||
u8 batt_info_l; // Also Sio Connected status.
|
||||
u8 batt_info_r; // Also Sio IRQ.
|
||||
u8 batt_chrg_l;
|
||||
u8 batt_chrg_r;
|
||||
jc_bt_conn_t bt_conn_l;
|
||||
jc_bt_conn_t bt_conn_r;
|
||||
} jc_gamepad_rpt_t;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (FTM4CD60DA1BE/FTM4CD50TA1BE) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -29,10 +29,6 @@
|
||||
#include <utils/btn.h>
|
||||
#include "touch.h"
|
||||
|
||||
|
||||
#include <gfx_utils.h>
|
||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
|
||||
static touch_panel_info_t _panels[] =
|
||||
{
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0.
|
||||
@@ -43,39 +39,52 @@ static touch_panel_info_t _panels[] =
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
|
||||
};
|
||||
|
||||
static int touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
static touch_info_t _touch_info = { 0 };
|
||||
static touch_panel_info_t _touch_panel_info = { 0 };
|
||||
|
||||
static int _touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
|
||||
if (!res)
|
||||
return 1;
|
||||
return 0;
|
||||
return i2c_send_buf_small(I2C_3, FTS4_I2C_ADDR, cmd, buf, size);
|
||||
}
|
||||
|
||||
static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
|
||||
static int _touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd[0], &cmd[1], csize - 1);
|
||||
if (res)
|
||||
res = i2c_recv_buf(buf, size, I2C_3, STMFTS_I2C_ADDR);
|
||||
if (!res)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return i2c_xfer_packet(I2C_3, FTS4_I2C_ADDR, cmd, csize, buf, size);
|
||||
}
|
||||
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
int touch_get_event_count()
|
||||
{
|
||||
u8 cmd[3] = { FTS4_CMD_HW_REG_READ, 0, FTS4_HW_REG_EVENT_COUNT };
|
||||
u8 buf[2];
|
||||
|
||||
if (_touch_read_reg(cmd, sizeof(cmd), buf, sizeof(buf)))
|
||||
return 0;
|
||||
|
||||
return (buf[1] >> 1);
|
||||
}
|
||||
|
||||
static int _touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
{
|
||||
u32 timer = get_tmr_ms() + timeout;
|
||||
while (true)
|
||||
{
|
||||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == event && tmp[2] == status)
|
||||
if (!touch_get_event_count())
|
||||
goto retry;
|
||||
|
||||
u8 tmp[FTS4_EVENT_SIZE];
|
||||
int res = i2c_recv_buf_big(tmp, FTS4_EVENT_SIZE, I2C_3, FTS4_I2C_ADDR, FTS4_CMD_READ_ONE_EVENT);
|
||||
|
||||
// Check that event type and status match.
|
||||
if (!res && tmp[0] == event && tmp[1] == status)
|
||||
{
|
||||
if (buf)
|
||||
memcpy(buf, &tmp[3], 5);
|
||||
memcpy(buf, &tmp[2], 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retry:
|
||||
usleep(500);
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
return 1;
|
||||
}
|
||||
@@ -85,7 +94,7 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
#define Y_REAL_MAX 704
|
||||
#define EDGE_OFFSET 15
|
||||
|
||||
static void _touch_compensate_limits(touch_event *event, bool touching)
|
||||
static void _touch_compensate_limits(touch_event_t *event, bool touching)
|
||||
{
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
@@ -103,116 +112,102 @@ static void _touch_compensate_limits(touch_event *event, bool touching)
|
||||
}
|
||||
}
|
||||
|
||||
static void _touch_process_contact_event(touch_event *event, bool touching)
|
||||
static void _touch_process_contact_event(touch_event_t *event, bool touching)
|
||||
{
|
||||
event->x = (event->raw[2] << 4) | ((event->raw[4] & STMFTS_MASK_Y_LSB) >> 4);
|
||||
event->x = (event->raw[1] << 4) | ((event->raw[3] & FTS4_MASK_Y_LSB) >> 4);
|
||||
|
||||
// Normally, GUI elements have bigger horizontal estate.
|
||||
// Avoid parsing y axis when finger is removed to minimize touch noise.
|
||||
if (touching)
|
||||
{
|
||||
event->y = (event->raw[3] << 4) | (event->raw[4] & STMFTS_MASK_X_MSB);
|
||||
event->y = (event->raw[2] << 4) | (event->raw[3] & FTS4_MASK_X_MSB);
|
||||
|
||||
event->z = event->raw[5] | (event->raw[6] << 8);
|
||||
event->z = event->raw[4] | (event->raw[5] << 8);
|
||||
event->z = event->z << 6;
|
||||
|
||||
u16 tmp = 0x40;
|
||||
if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F)
|
||||
tmp = event->raw[7] & 0x3F;
|
||||
if ((event->raw[6] & 0x3F) != 1 && (event->raw[6] & 0x3F) != 0x3F)
|
||||
tmp = event->raw[6] & 0x3F;
|
||||
event->z /= tmp + 0x40;
|
||||
|
||||
event->fingers = ((event->raw[1] & STMFTS_MASK_TOUCH_ID) >> 4) + 1;
|
||||
event->finger = ((event->raw[0] & FTS4_MASK_TOUCH_ID) >> 4) + 1;
|
||||
}
|
||||
else
|
||||
event->fingers = 0;
|
||||
event->finger = 0;
|
||||
|
||||
_touch_compensate_limits(event, touching);
|
||||
}
|
||||
|
||||
static void _touch_parse_event(touch_event *event)
|
||||
static int _touch_parse_input_event(touch_event_t *event)
|
||||
{
|
||||
event->type = event->raw[1] & STMFTS_MASK_EVENT_ID;
|
||||
|
||||
switch (event->type)
|
||||
switch (event->raw[0] & FTS4_MASK_EVENT_ID)
|
||||
{
|
||||
case STMFTS_EV_MULTI_TOUCH_ENTER:
|
||||
case STMFTS_EV_MULTI_TOUCH_MOTION:
|
||||
case FTS4_EV_MULTI_TOUCH_ENTER:
|
||||
case FTS4_EV_MULTI_TOUCH_MOTION:
|
||||
_touch_process_contact_event(event, true);
|
||||
if (event->z < 255) // Reject palm rest.
|
||||
if (event->z < 500) // Reject palm rest.
|
||||
event->touch = true;
|
||||
else
|
||||
{
|
||||
event->touch = false;
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_LEAVE:
|
||||
return 0;
|
||||
|
||||
case FTS4_EV_MULTI_TOUCH_LEAVE:
|
||||
event->touch = false;
|
||||
_touch_process_contact_event(event, false);
|
||||
break;
|
||||
case STMFTS_EV_NO_EVENT:
|
||||
if (event->touch)
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_MOTION;
|
||||
break;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
if (event->touch && event->raw[0] == STMFTS_EV_MULTI_TOUCH_MOTION)
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_MOTION;
|
||||
else
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
return 1; // No event.
|
||||
}
|
||||
}
|
||||
|
||||
int touch_poll(touch_event_t *event)
|
||||
{
|
||||
u8 cmd = !_touch_info.clone ? FTS4_CMD_LATEST_EVENT : FTS4_CMD_READ_ONE_EVENT;
|
||||
|
||||
int res = i2c_recv_buf_big(event->raw, FTS4_EVENT_SIZE, I2C_3, FTS4_I2C_ADDR, cmd);
|
||||
if (!res)
|
||||
res = _touch_parse_input_event(event);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
touch_info_t *touch_get_chip_info()
|
||||
{
|
||||
u8 buf[7] = { 0 };
|
||||
|
||||
// Get chip info.
|
||||
u8 cmd[3] = { FTS4_CMD_HW_REG_READ, 0, FTS4_HW_REG_CHIP_ID_INFO };
|
||||
if (_touch_read_reg(cmd, sizeof(cmd), buf, sizeof(buf)))
|
||||
{
|
||||
memset(&_touch_info, 0, sizeof(touch_info_t));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// gfx_con_setpos(0, 300);
|
||||
// DPRINTF("x = %d \ny = %d \nz = %d \n", event->x, event->y, event->z);
|
||||
// DPRINTF("0 = %02X\n1 = %02X\n2 = %02X\n3 = %02X\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02X\n6 = %02X\n7 = %02X\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
}
|
||||
_touch_info.chip_id = buf[1] << 8 | buf[2];
|
||||
_touch_info.fw_ver = buf[3] << 8 | buf[4];
|
||||
_touch_info.config_id = buf[5];
|
||||
_touch_info.config_ver = buf[6];
|
||||
|
||||
void touch_poll(touch_event *event)
|
||||
{
|
||||
i2c_recv_buf_small(event->raw, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_LATEST_EVENT);
|
||||
// Validate that device is genuine or proper.
|
||||
cmd[2] = 2;
|
||||
_touch_read_reg(cmd, sizeof(cmd), buf, sizeof(buf));
|
||||
_touch_info.clone = _touch_info.chip_id != (buf[3] << 8 | buf[4]);
|
||||
|
||||
_touch_parse_event(event);
|
||||
}
|
||||
|
||||
touch_event touch_poll_wait()
|
||||
{
|
||||
touch_event event;
|
||||
do
|
||||
{
|
||||
touch_poll(&event);
|
||||
} while (event.type != STMFTS_EV_MULTI_TOUCH_LEAVE);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
touch_info touch_get_info()
|
||||
{
|
||||
touch_info info;
|
||||
u8 buf[8];
|
||||
memset(&buf, 0, 8);
|
||||
i2c_recv_buf_small(buf, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_INFO);
|
||||
|
||||
info.chip_id = buf[0] << 8 | buf[1];
|
||||
info.fw_ver = buf[2] << 8 | buf[3];
|
||||
info.config_id = buf[4];
|
||||
info.config_ver = buf[5];
|
||||
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02X, Cfg Ver: %d\n",
|
||||
// info.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver);
|
||||
|
||||
return info;
|
||||
exit:
|
||||
return &_touch_info;
|
||||
}
|
||||
|
||||
touch_panel_info_t *touch_get_panel_vendor()
|
||||
{
|
||||
u8 buf[5] = {0};
|
||||
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
||||
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
|
||||
_touch_panel_info.idx = -2;
|
||||
|
||||
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
||||
u8 cmd = FTS4_VENDOR_GPIO_STATE;
|
||||
if (_touch_command(FTS4_CMD_VENDOR, &cmd, 1))
|
||||
return NULL;
|
||||
|
||||
if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
|
||||
u8 buf[6] = { 0 };
|
||||
if (_touch_wait_event(FTS4_EV_VENDOR, FTS4_VENDOR_GPIO_STATE, 2000, buf))
|
||||
return NULL;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_panels); i++)
|
||||
@@ -223,37 +218,33 @@ touch_panel_info_t *touch_get_panel_vendor()
|
||||
}
|
||||
|
||||
// Touch panel not found, return current gpios.
|
||||
panel_info.gpio0 = buf[0];
|
||||
panel_info.gpio1 = buf[1];
|
||||
panel_info.gpio2 = buf[2];
|
||||
_touch_panel_info.gpio0 = buf[0];
|
||||
_touch_panel_info.gpio1 = buf[1];
|
||||
_touch_panel_info.gpio2 = buf[2];
|
||||
|
||||
return &panel_info;
|
||||
return &_touch_panel_info;
|
||||
}
|
||||
|
||||
int touch_get_fw_info(touch_fw_info_t *fw)
|
||||
{
|
||||
u8 buf[8] = {0};
|
||||
u8 buf[9] = { 0 };
|
||||
|
||||
memset(fw, 0, sizeof(touch_fw_info_t));
|
||||
|
||||
// Get fw address info.
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
||||
int res = touch_read_reg(cmd, 3, buf, 3);
|
||||
u8 cmd[3] = { FTS4_CMD_FB_REG_READ, 0, 0x60 };
|
||||
int res = _touch_read_reg(cmd, sizeof(cmd), buf, 3);
|
||||
if (!res)
|
||||
{
|
||||
// Get fw info.
|
||||
cmd[1] = buf[2]; cmd[2] = buf[1];
|
||||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
res = _touch_read_reg(cmd, sizeof(cmd), buf, sizeof(buf));
|
||||
if (!res)
|
||||
{
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->ftb_ver = (buf[6] << 8) | buf[5];
|
||||
fw->ftb_ver = (buf[6] << 8) | buf[5];
|
||||
fw->fw_rev = (buf[8] << 8) | buf[7];
|
||||
}
|
||||
|
||||
cmd[2]++;
|
||||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
if (!res)
|
||||
fw->fw_rev = (buf[7] << 8) | buf[6];
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -261,16 +252,17 @@ int touch_get_fw_info(touch_fw_info_t *fw)
|
||||
|
||||
int touch_sys_reset()
|
||||
{
|
||||
u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd.
|
||||
u8 cmd[3] = { 0, FTS4_HW_REG_SYS_RESET, 0x80 }; // System reset cmd.
|
||||
for (u8 retries = 0; retries < 3; retries++)
|
||||
{
|
||||
if (touch_command(STMFTS_WRITE_REG, cmd, 3))
|
||||
if (_touch_command(FTS4_CMD_HW_REG_WRITE, cmd, 3))
|
||||
{
|
||||
msleep(10);
|
||||
continue;
|
||||
}
|
||||
msleep(10);
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL))
|
||||
|
||||
if (_touch_wait_event(FTS4_EV_CONTROLLER_READY, 0, 20, NULL))
|
||||
continue;
|
||||
else
|
||||
return 0;
|
||||
@@ -281,36 +273,25 @@ int touch_sys_reset()
|
||||
|
||||
int touch_panel_ito_test(u8 *err)
|
||||
{
|
||||
int res = 0;
|
||||
// Check that touch IC is supported.
|
||||
touch_info_t *info = touch_get_chip_info();
|
||||
if (info->chip_id != FTS4_I2C_CHIP_ID || info->clone)
|
||||
return 1;
|
||||
|
||||
// Reset touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return res;
|
||||
return 1;
|
||||
|
||||
// Do ITO Production test.
|
||||
u8 cmd[2] = { 1, 0 };
|
||||
if (touch_command(STMFTS_ITO_CHECK, cmd, 2))
|
||||
return res;
|
||||
if (_touch_command(FTS4_CMD_ITO_CHECK, NULL, 0))
|
||||
return 1;
|
||||
|
||||
u32 timer = get_tmr_ms() + 2000;
|
||||
while (true)
|
||||
u8 buf[6] = { 0 };
|
||||
int res = _touch_wait_event(FTS4_EV_ERROR, FTS4_EV_ERROR_ITO_TEST, 2000, buf);
|
||||
if (!res && err)
|
||||
{
|
||||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == 0xF && tmp[2] == 0x5)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
err[0] = tmp[3];
|
||||
err[1] = tmp[4];
|
||||
}
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
break;
|
||||
err[0] = buf[0];
|
||||
err[1] = buf[1];
|
||||
}
|
||||
|
||||
// Reset touchscreen module.
|
||||
@@ -321,20 +302,19 @@ int touch_panel_ito_test(u8 *err)
|
||||
|
||||
int touch_get_fb_info(u8 *buf)
|
||||
{
|
||||
u8 tmp[5];
|
||||
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0 };
|
||||
u8 cmd[3] = { FTS4_CMD_FB_REG_READ, 0, 0 };
|
||||
int res = 0;
|
||||
|
||||
|
||||
for (u32 i = 0; i < 0x10000; i += 4)
|
||||
{
|
||||
if (!res)
|
||||
{
|
||||
cmd[1] = (i >> 8) & 0xFF;
|
||||
cmd[2] = i & 0xFF;
|
||||
memset(tmp, 0xCC, 5);
|
||||
res = touch_read_reg(cmd, 3, tmp, 5);
|
||||
|
||||
u8 tmp[5];
|
||||
memset(tmp, 0xCC, sizeof(tmp));
|
||||
res = _touch_read_reg(cmd, sizeof(cmd), tmp, sizeof(tmp));
|
||||
memcpy(&buf[i], tmp + 1, 4);
|
||||
}
|
||||
}
|
||||
@@ -342,70 +322,97 @@ int touch_get_fb_info(u8 *buf)
|
||||
return res;
|
||||
}
|
||||
|
||||
int touch_switch_sense_mode(u8 mode, bool gis_6_2)
|
||||
{
|
||||
// Set detection config.
|
||||
u8 cmd[3] = { 1, 0x64, 0 };
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case FTS4_STYLUS_MODE:
|
||||
cmd[2] = !gis_6_2 ? 0xC8 : 0xAD;
|
||||
break;
|
||||
case FTS4_FINGER_MODE:
|
||||
cmd[2] = !gis_6_2 ? 0x8C : 0x79;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_touch_command(FTS4_CMD_DETECTION_CONFIG, cmd, 3))
|
||||
return 1;
|
||||
|
||||
// Sense mode.
|
||||
cmd[0] = mode;
|
||||
|
||||
return _touch_command(FTS4_CMD_SWITCH_SENSE_MODE, cmd, 1);
|
||||
}
|
||||
|
||||
int touch_sense_enable()
|
||||
{
|
||||
// Switch sense mode and enable multi-touch sensing.
|
||||
u8 cmd = STMFTS_FINGER_MODE;
|
||||
if (touch_command(STMFTS_SWITCH_SENSE_MODE, &cmd, 1))
|
||||
return 0;
|
||||
u8 cmd = FTS4_FINGER_MODE;
|
||||
if (_touch_command(FTS4_CMD_SWITCH_SENSE_MODE, &cmd, 1))
|
||||
return 1;
|
||||
|
||||
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_MS_MT_SENSE_ON, NULL, 0))
|
||||
return 1;
|
||||
|
||||
if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_CLEAR_EVENT_STACK, NULL, 0))
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int touch_execute_autotune()
|
||||
{
|
||||
u8 buf[6] = { 0 };
|
||||
|
||||
// Reset touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
// Trim low power oscillator.
|
||||
if (touch_command(STMFTS_LP_TIMER_CALIB, NULL, 0))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_LP_TIMER_CALIB, NULL, 0))
|
||||
return 1;
|
||||
|
||||
msleep(200);
|
||||
|
||||
// Apply Mutual Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_MS_CX_TUNING, NULL, 0))
|
||||
return 1;
|
||||
if (_touch_wait_event(FTS4_EV_STATUS, FTS4_EV_STATUS_MS_CX_TUNING_DONE, 2000, buf) || buf[0] || buf[1])
|
||||
return 1;
|
||||
|
||||
// Apply Self Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_SS_CX_TUNING, NULL, 0))
|
||||
return 1;
|
||||
if (_touch_wait_event(FTS4_EV_STATUS, FTS4_EV_STATUS_SS_CX_TUNING_DONE, 2000, buf) || buf[0] || buf[1])
|
||||
return 1;
|
||||
|
||||
// Save Compensation data to EEPROM.
|
||||
if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, NULL))
|
||||
return 0;
|
||||
if (_touch_command(FTS4_CMD_SAVE_CX_TUNING, NULL, 0))
|
||||
return 1;
|
||||
if (_touch_wait_event(FTS4_EV_STATUS, FTS4_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, buf) || buf[0] || buf[1])
|
||||
return 1;
|
||||
|
||||
return touch_sense_enable();
|
||||
}
|
||||
|
||||
static int touch_init()
|
||||
{
|
||||
// Check that touch IC is supported.
|
||||
touch_info_t *info = touch_get_chip_info();
|
||||
if (info->chip_id != FTS4_I2C_CHIP_ID)
|
||||
return 1;
|
||||
|
||||
// Initialize touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
return touch_sense_enable();
|
||||
}
|
||||
|
||||
int touch_power_on()
|
||||
{
|
||||
// Configure Touscreen and GCAsic shared GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2; // Unused.
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||
|
||||
// Configure touchscreen Touch Reset pin.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
@@ -426,13 +433,13 @@ int touch_power_on()
|
||||
usleep(10000);
|
||||
|
||||
// Wait for the touchscreen module to get ready.
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
_touch_wait_event(FTS4_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
|
||||
// Check for forced boot time calibration.
|
||||
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
{
|
||||
u8 err[2];
|
||||
if (touch_panel_ito_test(err))
|
||||
if (!touch_panel_ito_test(err))
|
||||
if (!err[0] && !err[1])
|
||||
return touch_execute_autotune();
|
||||
}
|
||||
@@ -441,12 +448,12 @@ int touch_power_on()
|
||||
u32 retries = 3;
|
||||
while (retries)
|
||||
{
|
||||
if (touch_init())
|
||||
return 1;
|
||||
if (!touch_init())
|
||||
return 0;
|
||||
retries--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void touch_power_off()
|
||||
@@ -458,4 +465,4 @@ void touch_power_off()
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, false);
|
||||
|
||||
clock_disable_i2c(I2C_3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -22,92 +22,100 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define STMFTS_I2C_ADDR 0x49
|
||||
#define FTS4_I2C_ADDR 0x49
|
||||
|
||||
/* I2C commands */
|
||||
#define STMFTS_READ_INFO 0x80
|
||||
#define STMFTS_READ_STATUS 0x84
|
||||
#define STMFTS_READ_ONE_EVENT 0x85
|
||||
#define STMFTS_READ_ALL_EVENT 0x86
|
||||
#define STMFTS_LATEST_EVENT 0x87
|
||||
#define STMFTS_SLEEP_IN 0x90
|
||||
#define STMFTS_SLEEP_OUT 0x91
|
||||
#define STMFTS_MS_MT_SENSE_OFF 0x92
|
||||
#define STMFTS_MS_MT_SENSE_ON 0x93
|
||||
#define STMFTS_SS_HOVER_SENSE_OFF 0x94
|
||||
#define STMFTS_SS_HOVER_SENSE_ON 0x95
|
||||
#define STMFTS_LP_TIMER_CALIB 0x97
|
||||
#define STMFTS_MS_KEY_SENSE_OFF 0x9A
|
||||
#define STMFTS_MS_KEY_SENSE_ON 0x9B
|
||||
#define STMFTS_SYSTEM_RESET 0xA0
|
||||
#define STMFTS_CLEAR_EVENT_STACK 0xA1
|
||||
#define STMFTS_FULL_FORCE_CALIBRATION 0xA2
|
||||
#define STMFTS_MS_CX_TUNING 0xA3
|
||||
#define STMFTS_SS_CX_TUNING 0xA4
|
||||
#define STMFTS_ITO_CHECK 0xA7
|
||||
#define STMFTS_RELEASEINFO 0xAA
|
||||
#define STMFTS_WRITE_REG 0xB6
|
||||
#define STMFTS_SWITCH_SENSE_MODE 0xC3
|
||||
#define STMFTS_NOISE_WRITE 0xC7
|
||||
#define STMFTS_NOISE_READ 0xC8
|
||||
#define STMFTS_RW_FRAMEBUFFER_REG 0xD0
|
||||
#define STMFTS_SAVE_CX_TUNING 0xFC
|
||||
#define FTS4_I2C_CHIP_ID 0x3670
|
||||
|
||||
#define STMFTS_DETECTION_CONFIG 0xB0
|
||||
#define STMFTS_REQU_COMP_DATA 0xB8
|
||||
#define STMFTS_VENDOR 0xCF
|
||||
#define STMFTS_FLASH_UNLOCK 0xF7
|
||||
#define STMFTS_FLASH_WRITE_64K 0xF8
|
||||
#define STMFTS_FLASH_STATUS 0xF9
|
||||
#define STMFTS_FLASH_OP 0xFA
|
||||
#define STMFTS_UNK5 0x62
|
||||
/* I2C commands. */
|
||||
#define FTS4_CMD_READ_INFO 0x80
|
||||
#define FTS4_CMD_READ_STATUS 0x84
|
||||
#define FTS4_CMD_READ_ONE_EVENT 0x85
|
||||
#define FTS4_CMD_READ_ALL_EVENT 0x86
|
||||
#define FTS4_CMD_LATEST_EVENT 0x87 // Clears event stack.
|
||||
#define FTS4_CMD_SLEEP_IN 0x90
|
||||
#define FTS4_CMD_SLEEP_OUT 0x91
|
||||
#define FTS4_CMD_MS_MT_SENSE_OFF 0x92
|
||||
#define FTS4_CMD_MS_MT_SENSE_ON 0x93
|
||||
#define FTS4_CMD_SS_HOVER_SENSE_OFF 0x94
|
||||
#define FTS4_CMD_SS_HOVER_SENSE_ON 0x95
|
||||
#define FTS4_CMD_LP_TIMER_CALIB 0x97
|
||||
#define FTS4_CMD_MS_KEY_SENSE_OFF 0x9A
|
||||
#define FTS4_CMD_MS_KEY_SENSE_ON 0x9B
|
||||
#define FTS4_CMD_SYSTEM_RESET 0xA0
|
||||
#define FTS4_CMD_CLEAR_EVENT_STACK 0xA1
|
||||
#define FTS4_CMD_FULL_FORCE_CALIB 0xA2
|
||||
#define FTS4_CMD_MS_CX_TUNING 0xA3
|
||||
#define FTS4_CMD_SS_CX_TUNING 0xA4
|
||||
#define FTS4_CMD_ITO_CHECK 0xA7
|
||||
#define FTS4_CMD_RELEASEINFO 0xAA
|
||||
#define FTS4_CMD_HW_REG_READ 0xB6 // u16be address offset. Any size read.
|
||||
#define FTS4_CMD_HW_REG_WRITE FTS4_CMD_HW_REG_READ // u16be address offset, bytes to write.
|
||||
#define FTS4_CMD_SWITCH_SENSE_MODE 0xC3
|
||||
#define FTS4_CMD_NOISE_WRITE 0xC7
|
||||
#define FTS4_CMD_NOISE_READ 0xC8
|
||||
#define FTS4_CMD_FB_REG_READ 0xD0
|
||||
#define FTS4_CMD_FB_REG_WRITE FTS4_CMD_FB_REG_READ
|
||||
#define FTS4_CMD_SAVE_CX_TUNING 0xFC
|
||||
|
||||
/* cmd parameters */
|
||||
#define STMFTS_VENDOR_GPIO_STATE 0x01
|
||||
#define STMFTS_VENDOR_SENSE_MODE 0x02
|
||||
#define STMFTS_STYLUS_MODE 0x00
|
||||
#define STMFTS_FINGER_MODE 0x01
|
||||
#define STMFTS_HOVER_MODE 0x02
|
||||
#define FTS4_CMD_DETECTION_CONFIG 0xB0
|
||||
#define FTS4_CMD_REQ_CX_DATA 0xB8
|
||||
#define FTS4_CMD_VENDOR 0xCF
|
||||
#define FTS4_CMD_FLASH_UNLOCK 0xF7
|
||||
#define FTS4_CMD_FLASH_WRITE_64K 0xF8
|
||||
#define FTS4_CMD_FLASH_STATUS 0xF9
|
||||
#define FTS4_CMD_FLASH_OP 0xFA
|
||||
#define FTS4_CMD_UNK_62 0x62
|
||||
|
||||
/* events */
|
||||
#define STMFTS_EV_NO_EVENT 0x00
|
||||
#define STMFTS_EV_MULTI_TOUCH_DETECTED 0x02
|
||||
#define STMFTS_EV_MULTI_TOUCH_ENTER 0x03
|
||||
#define STMFTS_EV_MULTI_TOUCH_LEAVE 0x04
|
||||
#define STMFTS_EV_MULTI_TOUCH_MOTION 0x05
|
||||
#define STMFTS_EV_HOVER_ENTER 0x07
|
||||
#define STMFTS_EV_HOVER_LEAVE 0x08
|
||||
#define STMFTS_EV_HOVER_MOTION 0x09
|
||||
#define STMFTS_EV_KEY_STATUS 0x0e
|
||||
#define STMFTS_EV_ERROR 0x0f
|
||||
#define STMFTS_EV_NOISE_READ 0x17
|
||||
#define STMFTS_EV_NOISE_WRITE 0x18
|
||||
#define STMFTS_EV_VENDOR 0x20
|
||||
/* Command parameters. */
|
||||
#define FTS4_VENDOR_GPIO_STATE 0x01
|
||||
#define FTS4_VENDOR_SENSE_MODE 0x02
|
||||
#define FTS4_STYLUS_MODE 0x00
|
||||
#define FTS4_FINGER_MODE 0x01
|
||||
#define FTS4_HOVER_MODE 0x02
|
||||
|
||||
#define STMFTS_EV_CONTROLLER_READY 0x10
|
||||
#define STMFTS_EV_STATUS 0x16
|
||||
#define STMFTS_EV_DEBUG 0xDB
|
||||
/* HW Registers */
|
||||
#define FTS4_HW_REG_CHIP_ID_INFO 0x0004
|
||||
#define FTS4_HW_REG_EVENT_COUNT 0x0023
|
||||
#define FTS4_HW_REG_SYS_RESET 0x0028
|
||||
|
||||
#define STMFTS_EV_STATUS_MS_CX_TUNING_DONE 1
|
||||
#define STMFTS_EV_STATUS_SS_CX_TUNING_DONE 2
|
||||
#define STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE 4
|
||||
/* FB Addresses */
|
||||
#define FTS4_FB_REG_FW_INFO_ADDRESS 0x0060
|
||||
|
||||
/* multi touch related event masks */
|
||||
#define STMFTS_MASK_EVENT_ID 0x0F
|
||||
#define STMFTS_MASK_TOUCH_ID 0xF0
|
||||
#define STMFTS_MASK_LEFT_EVENT 0x0F
|
||||
#define STMFTS_MASK_X_MSB 0x0F
|
||||
#define STMFTS_MASK_Y_LSB 0xF0
|
||||
/* Events. */
|
||||
#define FTS4_EV_NO_EVENT 0x00
|
||||
#define FTS4_EV_MULTI_TOUCH_DETECTED 0x02
|
||||
#define FTS4_EV_MULTI_TOUCH_ENTER 0x03
|
||||
#define FTS4_EV_MULTI_TOUCH_LEAVE 0x04
|
||||
#define FTS4_EV_MULTI_TOUCH_MOTION 0x05
|
||||
#define FTS4_EV_HOVER_ENTER 0x07
|
||||
#define FTS4_EV_HOVER_LEAVE 0x08
|
||||
#define FTS4_EV_HOVER_MOTION 0x09
|
||||
#define FTS4_EV_KEY_STATUS 0x0E
|
||||
#define FTS4_EV_ERROR 0x0F
|
||||
#define FTS4_EV_CONTROLLER_READY 0x10
|
||||
#define FTS4_EV_STATUS 0x16
|
||||
#define FTS4_EV_NOISE_READ 0x17
|
||||
#define FTS4_EV_NOISE_WRITE 0x18
|
||||
#define FTS4_EV_VENDOR 0x20
|
||||
#define FTS4_EV_DEBUG 0xDB
|
||||
|
||||
/* key related event masks */
|
||||
#define STMFTS_MASK_KEY_NO_TOUCH 0x00
|
||||
#define STMFTS_MASK_KEY_MENU 0x01
|
||||
#define STMFTS_MASK_KEY_BACK 0x02
|
||||
/* FTS4_EV_STATUS Events. */
|
||||
#define FTS4_EV_STATUS_MS_CX_TUNING_DONE 0x01
|
||||
#define FTS4_EV_STATUS_SS_CX_TUNING_DONE 0x02
|
||||
#define FTS4_EV_STATUS_WRITE_CX_TUNE_DONE 0x04
|
||||
|
||||
#define STMFTS_EVENT_SIZE 8
|
||||
#define STMFTS_STACK_DEPTH 32
|
||||
#define STMFTS_DATA_MAX_SIZE (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
|
||||
#define STMFTS_MAX_FINGERS 10
|
||||
#define FTS4_EV_ERROR_ITO_TEST 0x05
|
||||
|
||||
/* Multi touch related event masks. */
|
||||
#define FTS4_MASK_EVENT_ID 0x0F
|
||||
#define FTS4_MASK_TOUCH_ID 0xF0
|
||||
#define FTS4_MASK_X_MSB 0x0F
|
||||
#define FTS4_MASK_Y_LSB 0xF0
|
||||
|
||||
#define FTS4_EVENT_SIZE 8
|
||||
#define FTS4_STACK_DEPTH 32 // Actual 128.
|
||||
#define FTS4_DATA_MAX_SIZE (FTS4_EVENT_SIZE * FTS4_STACK_DEPTH)
|
||||
#define FTS4_MAX_FINGERS 10
|
||||
|
||||
typedef enum _touch_ito_error {
|
||||
ITO_NO_ERROR = 0,
|
||||
@@ -130,15 +138,13 @@ typedef enum _touch_ito_error {
|
||||
ITO_MAX_ERR_REACHED = 0xFF
|
||||
} touch_ito_error;
|
||||
|
||||
typedef struct _touch_event {
|
||||
u8 raw[8];
|
||||
u16 type; // Event type.
|
||||
u16 x; // Horizontal coordinates.
|
||||
u16 y; // Vertical coordinates.
|
||||
u32 z;
|
||||
u8 fingers;
|
||||
typedef struct _touch_event_t {
|
||||
u8 raw[FTS4_EVENT_SIZE];
|
||||
u16 x, y; // Coordinates.
|
||||
u32 z; // Orientation.
|
||||
bool touch;
|
||||
} touch_event;
|
||||
int finger;
|
||||
} touch_event_t;
|
||||
|
||||
typedef struct _touch_panel_info_t
|
||||
{
|
||||
@@ -149,12 +155,13 @@ typedef struct _touch_panel_info_t
|
||||
char *vendor;
|
||||
} touch_panel_info_t;
|
||||
|
||||
typedef struct _touch_info {
|
||||
u16 chip_id;
|
||||
u16 fw_ver;
|
||||
u16 config_id;
|
||||
u16 config_ver;
|
||||
} touch_info;
|
||||
typedef struct _touch_info_t {
|
||||
u16 chip_id;
|
||||
u16 fw_ver;
|
||||
u16 config_id;
|
||||
u16 config_ver;
|
||||
bool clone;
|
||||
} touch_info_t;
|
||||
|
||||
typedef struct _touch_fw_info_t {
|
||||
u32 fw_id;
|
||||
@@ -162,15 +169,16 @@ typedef struct _touch_fw_info_t {
|
||||
u16 fw_rev;
|
||||
} touch_fw_info_t;
|
||||
|
||||
void touch_poll(touch_event *event);
|
||||
touch_event touch_poll_wait();
|
||||
int touch_poll(touch_event_t *event);
|
||||
touch_info_t *touch_get_chip_info();
|
||||
touch_panel_info_t *touch_get_panel_vendor();
|
||||
int touch_get_fw_info(touch_fw_info_t *fw);
|
||||
touch_info touch_get_info();
|
||||
int touch_get_event_count();
|
||||
int touch_panel_ito_test(u8 *err);
|
||||
int touch_execute_autotune();
|
||||
int touch_switch_sense_mode(u8 mode, bool gis_6_2);
|
||||
int touch_sense_enable();
|
||||
int touch_power_on();
|
||||
void touch_power_off();
|
||||
|
||||
#endif /* __TOUCH_H_ */
|
||||
#endif /* __TOUCH_H_ */
|
||||
|
||||
@@ -10,6 +10,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <utils/types.h>
|
||||
#include <fatfs_cfg.h>
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
@@ -23,14 +24,6 @@ typedef enum {
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
typedef enum {
|
||||
DRIVE_SD = 0,
|
||||
DRIVE_RAM = 1,
|
||||
DRIVE_EMMC = 2,
|
||||
DRIVE_BIS = 3,
|
||||
DRIVE_EMU = 4
|
||||
} DDRIVE;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
@@ -61,27 +54,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
#define SET_WRITE_PROTECT 6 /* Lock/Unlock media removal */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -39,10 +39,11 @@
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <utils/util.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
//#define EFSPRINTF(...)
|
||||
// #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
#define EFSPRINTF(...)
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@@ -473,6 +474,10 @@ static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-define
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if FF_SIMPLE_GPT
|
||||
static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7};
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* LFN/Directory working buffer */
|
||||
@@ -3319,15 +3324,28 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
}
|
||||
#if FF_SIMPLE_GPT
|
||||
if (fmt >= 2) {
|
||||
/* If GPT Check the first partition */
|
||||
/* If GPT, iterate over all part entries and check MS Basic partitions */
|
||||
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
|
||||
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
|
||||
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
|
||||
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
|
||||
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
|
||||
fs->part_type = 1;
|
||||
bsect = gpt_entry->lba_start;
|
||||
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
||||
DWORD cur_entry, ofs, part;
|
||||
part = LD2PT(vol);
|
||||
cur_entry = 0;
|
||||
for(i = 0; i < gpt_header->num_part_ents; i++){
|
||||
if (move_window(fs, gpt_header->part_ent_lba + i * sizeof(gpt_entry_t) / SS(fs))) return FR_DISK_ERR;
|
||||
ofs = i * sizeof(gpt_entry_t) % SS(fs);
|
||||
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win + ofs;
|
||||
if (!mem_cmp(gpt_entry->type_guid, GUID_MS_Basic, 16)){
|
||||
cur_entry++;
|
||||
bsect = gpt_entry->lba_start;
|
||||
fmt = bsect ? check_fs(fs, bsect) : 3;
|
||||
if(part == 0 && fmt <= 1) break;
|
||||
if(part != 0 && cur_entry == part) break;
|
||||
}
|
||||
}
|
||||
if(part && part != cur_entry){
|
||||
fmt = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3932,15 +3950,12 @@ FRESULT f_read_fast (
|
||||
{
|
||||
FRESULT res;
|
||||
FATFS *fs;
|
||||
UINT csize_bytes;
|
||||
DWORD clst;
|
||||
UINT count = 0;
|
||||
UINT csize_bytes, count;
|
||||
DWORD clst, work_bytes;
|
||||
FSIZE_t work_sector = 0;
|
||||
FSIZE_t sector_base = 0;
|
||||
BYTE *wbuff = (BYTE*)buff;
|
||||
|
||||
// TODO support sector reading inside a cluster
|
||||
|
||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||
EFSPRINTF("FOV");
|
||||
@@ -3950,9 +3965,15 @@ FRESULT f_read_fast (
|
||||
if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
||||
FSIZE_t remain = fp->obj.objsize - fp->fptr;
|
||||
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
|
||||
if (!btr)
|
||||
goto out;
|
||||
|
||||
csize_bytes = fs->csize * SS(fs);
|
||||
|
||||
//!TODO: support sector reading inside a cluster
|
||||
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
|
||||
if (csect) { EFSPRINTF("ICSR"); ABORT(fs, FR_INT_ERR); }
|
||||
|
||||
if (!fp->fptr) { /* On the top of the file? */
|
||||
clst = fp->obj.sclust; /* Follow from the origin */
|
||||
} else {
|
||||
@@ -3965,9 +3986,10 @@ FRESULT f_read_fast (
|
||||
fp->clust = clst; /* Set working cluster */
|
||||
|
||||
sector_base = clst2sect(fs, fp->clust);
|
||||
count += fs->csize;
|
||||
btr -= csize_bytes;
|
||||
fp->fptr += csize_bytes;
|
||||
work_bytes = MIN(btr, csize_bytes);
|
||||
count = work_bytes / SS(fs);
|
||||
fp->fptr += work_bytes;
|
||||
btr -= work_bytes;
|
||||
|
||||
while (btr) {
|
||||
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
|
||||
@@ -3978,26 +4000,27 @@ FRESULT f_read_fast (
|
||||
fp->clust = clst;
|
||||
|
||||
work_sector = clst2sect(fs, fp->clust);
|
||||
if ((work_sector - sector_base) == count) count += fs->csize;
|
||||
work_bytes = MIN(btr, csize_bytes);
|
||||
if ((work_sector - sector_base) == count) count += work_bytes / SS(fs);
|
||||
else {
|
||||
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
wbuff += count * SS(fs);
|
||||
|
||||
sector_base = work_sector;
|
||||
count = fs->csize;
|
||||
count = work_bytes / SS(fs);
|
||||
}
|
||||
|
||||
fp->fptr += MIN(btr, csize_bytes);
|
||||
btr -= MIN(btr, csize_bytes);
|
||||
|
||||
// TODO: what about if data is smaller than cluster?
|
||||
// Must read-write back that cluster.
|
||||
|
||||
if (!btr) { /* Final cluster/sectors read. */
|
||||
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
}
|
||||
fp->fptr += work_bytes;
|
||||
btr -= work_bytes;
|
||||
}
|
||||
|
||||
if (!btr) { /* Final cluster/sectors read. */
|
||||
if (work_bytes % SS(fs))
|
||||
count++; /* Read an extra block. Expects buffer being big enough. */
|
||||
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
}
|
||||
|
||||
out:
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
@@ -4157,15 +4180,12 @@ FRESULT f_write_fast (
|
||||
{
|
||||
FRESULT res;
|
||||
FATFS *fs;
|
||||
UINT csize_bytes;
|
||||
DWORD clst;
|
||||
UINT count = 0;
|
||||
UINT csize_bytes, count;
|
||||
DWORD clst, work_bytes;
|
||||
FSIZE_t work_sector = 0;
|
||||
FSIZE_t sector_base = 0;
|
||||
const BYTE *wbuff = (const BYTE*)buff;
|
||||
|
||||
// TODO support sector writing inside a cluster
|
||||
|
||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||
EFSPRINTF("FOV");
|
||||
@@ -4173,6 +4193,9 @@ FRESULT f_write_fast (
|
||||
}
|
||||
|
||||
if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
||||
if (!btw)
|
||||
goto out;
|
||||
|
||||
/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
|
||||
if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
|
||||
btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);
|
||||
@@ -4180,22 +4203,26 @@ FRESULT f_write_fast (
|
||||
|
||||
csize_bytes = fs->csize * SS(fs);
|
||||
|
||||
// TODO support sector writing inside a cluster
|
||||
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
|
||||
if (csect) { EFSPRINTF("ICSR"); ABORT(fs, FR_INT_ERR); }
|
||||
|
||||
if (!fp->fptr) { /* On the top of the file? */
|
||||
clst = fp->obj.sclust; /* Follow from the origin */
|
||||
} else {
|
||||
if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
|
||||
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
|
||||
}
|
||||
|
||||
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
|
||||
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
|
||||
|
||||
fp->clust = clst; /* Set working cluster */
|
||||
|
||||
sector_base = clst2sect(fs, fp->clust);
|
||||
count += fs->csize;
|
||||
btw -= csize_bytes;
|
||||
fp->fptr += csize_bytes;
|
||||
work_bytes = MIN(btw, csize_bytes);
|
||||
count = work_bytes / SS(fs);
|
||||
fp->fptr += work_bytes;
|
||||
btw -= work_bytes;
|
||||
|
||||
while (btw) {
|
||||
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
|
||||
@@ -4206,28 +4233,30 @@ FRESULT f_write_fast (
|
||||
fp->clust = clst;
|
||||
|
||||
work_sector = clst2sect(fs, fp->clust);
|
||||
if ((work_sector - sector_base) == count) count += fs->csize;
|
||||
work_bytes = MIN(btw, csize_bytes);
|
||||
if ((work_sector - sector_base) == count) count += work_bytes / SS(fs);
|
||||
else {
|
||||
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
wbuff += count * SS(fs);
|
||||
|
||||
sector_base = work_sector;
|
||||
count = fs->csize;
|
||||
count = work_bytes / SS(fs);
|
||||
}
|
||||
|
||||
fp->fptr += MIN(btw, csize_bytes);
|
||||
btw -= MIN(btw, csize_bytes);
|
||||
fp->fptr += work_bytes;
|
||||
btw -= work_bytes;
|
||||
}
|
||||
|
||||
// what about if data is smaller than cluster?
|
||||
// Probably must read-write back that cluster.
|
||||
if (!btw) { /* Final cluster/sectors write. */
|
||||
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
fp->flag &= (BYTE)~FA_DIRTY;
|
||||
}
|
||||
if (!btw) { /* Final cluster/sectors write. */
|
||||
if (work_bytes % SS(fs))
|
||||
count++; /* Write an extra block. Cluster is always > storage block. */
|
||||
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
fp->flag &= (BYTE)~FA_DIRTY;
|
||||
}
|
||||
|
||||
fp->flag |= FA_MODIFIED; /* Set file change flag */
|
||||
|
||||
out:
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
@@ -4698,13 +4727,20 @@ FRESULT f_lseek (
|
||||
|
||||
DWORD *f_expand_cltbl (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
UINT tblsz, /* Size of table */
|
||||
UINT tblsz, /* Size of table (2 DWORDs + 2 DWORDs per fragment) */
|
||||
FSIZE_t ofs /* File pointer from top of file */
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Cluster table structure:
|
||||
* Size (DWORD)
|
||||
* Padding (DWORD)
|
||||
* (Cluster Offset (DWORD) + Sequential clusters (DWORD)) * Fragments
|
||||
*/
|
||||
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
|
||||
if (!fp->cltbl) { /* Allocate memory for cluster link table */
|
||||
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
|
||||
if (!fp->cltbl) return (void *)0;
|
||||
fp->cltbl[0] = tblsz;
|
||||
}
|
||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||
@@ -6111,10 +6147,26 @@ FRESULT f_mkfs (
|
||||
for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */
|
||||
}
|
||||
n_clst = sz_vol / pau; /* Number of clusters */
|
||||
sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */
|
||||
sz_rsv = 32; /* Number of reserved sectors */
|
||||
sz_dir = 0; /* No static directory */
|
||||
if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||
while (1) {
|
||||
/* Do not account for reserved/root cluster on FAT size for better alignment. */
|
||||
sz_fat = (n_clst * 4 + ss - 1) / ss; /* FAT size [sector]. */
|
||||
sz_rsv = 2048; /* Number of reserved sectors. Use 1MB for better performance (for flash memory media) */
|
||||
sz_dir = 0; /* No static directory */
|
||||
if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||
|
||||
/* Align data base to erase block boundary (for flash memory media) */
|
||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||
b_fat += n; /* FAT32: Move FAT base */
|
||||
/* Make sure FAT base is aligned to reserved size for performance (PRF2SAFE min cluster alignment) */
|
||||
if ((b_fat & (sz_rsv - 1) || (n_fats == 2 && sz_fat & (sz_rsv - 1)))) {
|
||||
n_clst++; /* FAT size must always be bigger than real free size */
|
||||
continue;
|
||||
}
|
||||
sz_rsv += n;
|
||||
break;
|
||||
}
|
||||
} else { /* FAT volume */
|
||||
if (pau == 0) { /* au auto-selection */
|
||||
n = sz_vol / 0x1000; /* Volume size in unit of 4KS */
|
||||
@@ -6130,17 +6182,13 @@ FRESULT f_mkfs (
|
||||
sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */
|
||||
sz_rsv = 1; /* Number of reserved sectors */
|
||||
sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */
|
||||
}
|
||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||
|
||||
/* Align data base to erase block boundary (for flash memory media) */
|
||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
/* Align data base to erase block boundary (for flash memory media) */
|
||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
n--; sz_rsv++; b_fat++; /* FAT: Expand FAT size */
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
@@ -6183,7 +6231,7 @@ FRESULT f_mkfs (
|
||||
/* Create FAT VBR */
|
||||
mem_set(buf, 0, ss);
|
||||
/* Boot jump code (x86), OEM name */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.8.0", 11);
|
||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||
@@ -6240,21 +6288,10 @@ FRESULT f_mkfs (
|
||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||
}
|
||||
|
||||
/* Create PRF2SAFE info */
|
||||
/* Clear PRF2SAFE info so PrFILE2 can recreate it and upgrade it if old */
|
||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||
mem_set(buf, 0, ss);
|
||||
st_dword(buf + 0, 0x32465250); /* Magic PRF2 */
|
||||
st_dword(buf + 4, 0x45464153); /* Magic SAFE */
|
||||
buf[16] = 0x64; /* Record type */
|
||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
||||
if (sz_vol < 0x1000000) {
|
||||
st_dword(buf + 36, 21 + 1); /* 22 Entries. */
|
||||
st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */
|
||||
} else {
|
||||
st_dword(buf + 36, 21 + 2); /* 23 Entries. */
|
||||
st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */
|
||||
}
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
}
|
||||
|
||||
/* Initialize FAT area */
|
||||
@@ -6745,7 +6782,6 @@ int f_puts (
|
||||
{
|
||||
putbuff pb;
|
||||
|
||||
|
||||
if (str == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
@@ -6773,7 +6809,6 @@ int f_printf (
|
||||
DWORD v;
|
||||
TCHAR c, d, str[32], *p;
|
||||
|
||||
|
||||
if (fmt == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
|
||||
@@ -264,8 +264,10 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
#if FF_FASTFS /* buff needs to be block aligned. Intercluster data access is not supported. */
|
||||
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
|
||||
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
|
||||
#endif
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
@@ -287,7 +289,9 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
#if FF_FASTFS
|
||||
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
|
||||
#endif
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/
|
||||
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */
|
||||
#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */
|
||||
#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/
|
||||
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix keyb /*Repeated trigger period in long press [ms] */
|
||||
#define LV_INDEV_LONG_PRESS_TIME 5000 /*Long press time in milliseconds*/
|
||||
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix lv_kb /*Repeated trigger period in long press [ms] */
|
||||
|
||||
/*Color settings*/
|
||||
#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/
|
||||
@@ -346,7 +346,7 @@
|
||||
#define USE_LV_KB 0
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define USE_LV_CB 1
|
||||
#define USE_LV_CB 0
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#define USE_LV_LIST 1
|
||||
@@ -370,7 +370,7 @@
|
||||
#define USE_LV_SLIDER 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define USE_LV_SW 1
|
||||
#define USE_LV_SW 0
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
|
||||
@@ -316,7 +316,8 @@ static bool lv_task_exec(lv_task_t * lv_task_p)
|
||||
lv_task_p->last_run = lv_tick_get();
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
lv_task_p->task(lv_task_p->param);
|
||||
if (lv_task_p->task)
|
||||
lv_task_p->task(lv_task_p->param);
|
||||
|
||||
/*Delete if it was a one shot lv_task*/
|
||||
if(task_deleted == false) { /*The task might be deleted by itself as well*/
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lv_line.c
|
||||
*
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lv_slider.c
|
||||
@@ -437,16 +452,17 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
|
||||
lv_indev_get_point(param, &p);
|
||||
int16_t tmp = 0;
|
||||
if(w > h) {
|
||||
lv_coord_t knob_w = h;
|
||||
p.x -= slider->coords.x1 + h / 2; /*Modify the point to shift with half knob (important on the start and end)*/
|
||||
tmp = (int32_t)((int32_t) p.x * (ext->bar.max_value - ext->bar.min_value + 1)) / (w - knob_w);
|
||||
tmp += ext->bar.min_value;
|
||||
lv_coord_t knob_w = h;
|
||||
lv_coord_t offset = (ext->knob_in == 0) ? w : w - knob_w;
|
||||
p.x -= slider->coords.x1 + ((ext->knob_in == 0) ? 0 : knob_w / 2);
|
||||
tmp = ((int32_t)p.x * (ext->bar.max_value - ext->bar.min_value) + offset / 2) / offset;
|
||||
} else {
|
||||
lv_coord_t knob_h = w;
|
||||
p.y -= slider->coords.y1 + w / 2; /*Modify the point to shift with half knob (important on the start and end)*/
|
||||
tmp = (int32_t)((int32_t) p.y * (ext->bar.max_value - ext->bar.min_value + 1)) / (h - knob_h);
|
||||
tmp = ext->bar.max_value - tmp; /*Invert the value: smaller value means higher y*/
|
||||
lv_coord_t knob_h = w;
|
||||
lv_coord_t offset = (ext->knob_in == 0) ? h : h - knob_h;
|
||||
p.y -= slider->coords.y1 + ((ext->knob_in == 0) ? 0 : knob_h / 2);
|
||||
tmp = ((int32_t)p.y * (ext->bar.max_value - ext->bar.min_value) + offset / 2) / offset;
|
||||
}
|
||||
tmp += ext->bar.min_value;
|
||||
|
||||
if(tmp < ext->bar.min_value) tmp = ext->bar.min_value;
|
||||
else if(tmp > ext->bar.max_value) tmp = ext->bar.max_value;
|
||||
|
||||
@@ -82,13 +82,6 @@ typedef struct {
|
||||
} label;
|
||||
#endif
|
||||
|
||||
#if USE_LV_IMG != 0
|
||||
struct {
|
||||
lv_style_t *light;
|
||||
lv_style_t *dark;
|
||||
} img;
|
||||
#endif
|
||||
|
||||
#if USE_LV_LINE != 0
|
||||
struct {
|
||||
lv_style_t *decor;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -25,22 +25,27 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define DEF_RADIUS 4
|
||||
#define COLOR_SHADOW_LIGHT LV_COLOR_HEX(0xAAAAAA)
|
||||
#define COLOR_SHADOW_DARK LV_COLOR_HEX(0x1F1F1F)
|
||||
#define COLOR_HOS_TURQUOISE (lv_color_hsv_to_rgb(_hue, 100, 100)) // 0x00FFC9
|
||||
#define COLOR_HOS_TEAL_LIGHTER (lv_color_hsv_to_rgb(_hue, 100, 93)) // 0x00EDBA
|
||||
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
||||
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
||||
|
||||
#define COLOR_HOS_TURQUOISE (_hue ? lv_color_hsv_to_rgb(_hue, 100, 100) : lv_color_hsv_to_rgb(53, 8, 90)) // 0x00FFC9
|
||||
#define COLOR_HOS_TEAL_LIGHTER (_hue ? lv_color_hsv_to_rgb(_hue, 100, 93) : lv_color_hsv_to_rgb(53, 8, 81)) // 0x00EDBA
|
||||
#define COLOR_HOS_TEAL_LIGHT (_hue ? lv_color_hsv_to_rgb(_hue, 100, 72) : lv_color_hsv_to_rgb(53, 8, 65)) // 0x00B78F
|
||||
#define COLOR_HOS_TEAL (_hue ? lv_color_hsv_to_rgb(_hue, 100, 64) : lv_color_hsv_to_rgb(53, 8, 58)) // 0x00A273
|
||||
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
||||
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
||||
|
||||
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
|
||||
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
|
||||
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
|
||||
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
|
||||
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||
|
||||
#define COLOR_INACTIVE LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x171717) : 0x343434) // 0x444444.
|
||||
#define COLOR_BAR LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||
#define COLOR_PRESS LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x232323) : 0x404040) // 0x505050.
|
||||
#define COLOR_LINE LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x383838) : 0x555555) // 0x656565.
|
||||
|
||||
#define COLOR_SHADOW_LIGHT LV_COLOR_HEX(0xAAAAAA)
|
||||
#define COLOR_SHADOW LV_COLOR_HEX(theme_bg_color ? theme_bg_color : 0x181818) // 0x2D2D2D.
|
||||
#define COLOR_SHADOW_DARK LV_COLOR_HEX(theme_bg_color ? 0x1F1F1F : 0x0A0A0A)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -92,9 +97,9 @@ static void basic_init(void)
|
||||
lv_style_copy(&panel, &def);
|
||||
panel.body.radius = DEF_RADIUS;
|
||||
panel.body.main_color = COLOR_BG;
|
||||
panel.body.grad_color = COLOR_BG;
|
||||
panel.body.grad_color = panel.body.main_color;
|
||||
panel.body.border.width = 1;
|
||||
panel.body.border.color = COLOR_LIGHT_BORDER;
|
||||
panel.body.border.color = COLOR_BAR;
|
||||
panel.body.border.opa = LV_OPA_COVER;
|
||||
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
||||
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
@@ -106,7 +111,7 @@ static void basic_init(void)
|
||||
|
||||
lv_style_copy(&sb, &def);
|
||||
sb.body.main_color = LV_COLOR_BLACK;
|
||||
sb.body.grad_color = LV_COLOR_BLACK;
|
||||
sb.body.grad_color = sb.body.grad_color;
|
||||
sb.body.opa = LV_OPA_40;
|
||||
sb.body.padding.hor = LV_DPI / 25;
|
||||
|
||||
@@ -147,7 +152,7 @@ static void btn_init(void)
|
||||
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
||||
|
||||
lv_style_copy(&pr, &rel);
|
||||
pr.body.main_color = LV_COLOR_HEX(0x505050);
|
||||
pr.body.main_color = COLOR_PRESS;
|
||||
pr.body.grad_color = pr.body.main_color;
|
||||
pr.body.shadow.width = 0;
|
||||
pr.body.border.color = COLOR_HOS_TEAL_LIGHTER;
|
||||
@@ -159,7 +164,7 @@ static void btn_init(void)
|
||||
tgl_rel.body.border.width = 4;
|
||||
|
||||
lv_style_copy(&tgl_pr, &tgl_rel);
|
||||
tgl_pr.body.main_color = LV_COLOR_HEX(0x505050);
|
||||
tgl_pr.body.main_color = COLOR_PRESS;
|
||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||
tgl_pr.text.color = COLOR_HOS_TURQUOISE;
|
||||
tgl_pr.body.shadow.width = 0;
|
||||
@@ -201,30 +206,12 @@ static void label_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void img_init(void)
|
||||
{
|
||||
#if USE_LV_IMG != 0
|
||||
static lv_style_t img_light, img_dark;
|
||||
lv_style_copy(&img_light, &def);
|
||||
img_light.image.color = LV_COLOR_WHITE;
|
||||
img_light.image.intense = LV_OPA_80;
|
||||
|
||||
lv_style_copy(&img_dark, &def);
|
||||
img_dark.image.color = COLOR_BG_DARKER;
|
||||
img_dark.image.intense = LV_OPA_80;
|
||||
|
||||
|
||||
theme.img.light = &def;
|
||||
theme.img.dark = &def;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void line_init(void)
|
||||
{
|
||||
#if USE_LV_LINE != 0
|
||||
static lv_style_t line;
|
||||
lv_style_copy(&line, &def);
|
||||
line.line.color = LV_COLOR_HEX(0x656565);
|
||||
line.line.color = COLOR_LINE;
|
||||
theme.line.decor = &line;
|
||||
#endif
|
||||
}
|
||||
@@ -239,7 +226,7 @@ static void led_init(void)
|
||||
led.body.border.width = LV_DPI / 30;
|
||||
led.body.border.opa = LV_OPA_30;
|
||||
led.body.main_color = lv_color_hsv_to_rgb(_hue, 100, 100);
|
||||
led.body.grad_color = lv_color_hsv_to_rgb(_hue, 100, 100);
|
||||
led.body.grad_color = led.body.main_color;
|
||||
led.body.border.color = lv_color_hsv_to_rgb(_hue, 60, 60);
|
||||
led.body.shadow.color = lv_color_hsv_to_rgb(_hue, 100, 100);
|
||||
|
||||
@@ -253,7 +240,7 @@ static void bar_init(void)
|
||||
static lv_style_t bar_bg, bar_indic;
|
||||
|
||||
lv_style_copy(&bar_bg, &def);
|
||||
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
|
||||
bar_bg.body.main_color = COLOR_BAR;
|
||||
bar_bg.body.grad_color = bar_bg.body.main_color;
|
||||
bar_bg.body.radius = 3;
|
||||
bar_bg.body.border.width = 0;
|
||||
@@ -402,7 +389,7 @@ static void calendar_init(void)
|
||||
static lv_style_t week_box;
|
||||
lv_style_copy(&week_box, &def);
|
||||
week_box.body.main_color = lv_color_hsv_to_rgb(_hue, 40, 100);
|
||||
week_box.body.grad_color = lv_color_hsv_to_rgb(_hue, 40, 100);
|
||||
week_box.body.grad_color = week_box.body.main_color;
|
||||
week_box.body.padding.ver = LV_DPI / 20;
|
||||
week_box.body.padding.hor = theme.panel->body.padding.hor;
|
||||
week_box.body.border.color = theme.panel->body.border.color;
|
||||
@@ -413,7 +400,7 @@ static void calendar_init(void)
|
||||
static lv_style_t today_box;
|
||||
lv_style_copy(&today_box, &def);
|
||||
today_box.body.main_color = LV_COLOR_WHITE;
|
||||
today_box.body.grad_color = LV_COLOR_WHITE;
|
||||
today_box.body.grad_color = today_box.body.main_color;
|
||||
today_box.body.padding.ver = LV_DPI / 20;
|
||||
today_box.body.radius = 0;
|
||||
|
||||
@@ -541,7 +528,7 @@ static void mbox_init(void)
|
||||
lv_style_copy(&bg, theme.panel);
|
||||
bg.body.main_color = COLOR_BG_LIGHTER;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.shadow.color = COLOR_BG;
|
||||
bg.body.shadow.color = COLOR_SHADOW;
|
||||
bg.body.shadow.type = LV_SHADOW_FULL;
|
||||
bg.body.shadow.width = 8;
|
||||
|
||||
@@ -617,13 +604,13 @@ static void list_init(void)
|
||||
rel.body.padding.hor = LV_DPI / 8;
|
||||
rel.body.padding.ver = LV_DPI / 6;
|
||||
rel.body.radius = 0;
|
||||
rel.body.border.color = LV_COLOR_HEX(0x444444);
|
||||
rel.body.border.color = COLOR_INACTIVE;
|
||||
rel.body.border.width = 1;
|
||||
rel.body.border.part = LV_BORDER_BOTTOM;
|
||||
|
||||
lv_style_copy(&pr, &rel);
|
||||
pr.glass = 0;
|
||||
pr.body.main_color = LV_COLOR_HEX(0x505050);
|
||||
pr.body.main_color = COLOR_PRESS;
|
||||
pr.body.grad_color = pr.body.main_color;
|
||||
//pr.body.border.width = 1;
|
||||
pr.body.empty = 0;
|
||||
@@ -637,7 +624,7 @@ static void list_init(void)
|
||||
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
||||
|
||||
lv_style_copy(&tgl_pr, &tgl_rel);
|
||||
tgl_pr.body.main_color = LV_COLOR_HEX(0x505050);
|
||||
tgl_pr.body.main_color = COLOR_PRESS;
|
||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||
tgl_pr.body.border.width = 0;
|
||||
|
||||
@@ -692,7 +679,7 @@ static void roller_init(void)
|
||||
roller_bg.text.line_space = LV_DPI / 8;
|
||||
roller_bg.text.font = _font;
|
||||
roller_bg.glass = 0;
|
||||
roller_bg.text.color = LV_COLOR_HEX(0x444444);
|
||||
roller_bg.text.color = COLOR_INACTIVE;
|
||||
|
||||
lv_style_copy(&roller_sel, &roller_bg);
|
||||
roller_sel.text.color = COLOR_HOS_TURQUOISE;
|
||||
@@ -866,7 +853,6 @@ lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * f
|
||||
cont_init();
|
||||
btn_init();
|
||||
label_init();
|
||||
img_init();
|
||||
line_init();
|
||||
led_init();
|
||||
bar_init();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -35,14 +35,17 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
|
||||
#define COLOR_HOS_BG_BASE_BLACK 0x000000
|
||||
#define COLOR_BG_BASE_MIN 0x0B0B0B
|
||||
#define COLOR_BG_BASE_MAX 0xC7C7C7
|
||||
|
||||
#define COLOR_HOS_BG_DARKER 0x1B1B1B
|
||||
#define COLOR_HOS_BG_DARK 0x222222
|
||||
#define COLOR_HOS_BG 0x2D2D2D
|
||||
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
|
||||
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
|
||||
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
|
||||
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
|
||||
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
|
||||
#define COLOR_HOS_BG_RGB 0x2D2D2D
|
||||
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
|
||||
#define COLOR_HOS_BG_LIGHTER LV_COLOR_HEX(0x4D4D4D)
|
||||
|
||||
#define COLOR_HOS_TURQUOISE_EX(hue) (hue ? lv_color_hsv_to_rgb(hue, 100, 100) : lv_color_hsv_to_rgb(53, 8, 90)) // 0x00FFC9
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
||||
733
bdk/mem/emc.h
733
bdk/mem/emc.h
@@ -1,733 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-tegra/tegra21_emc.h
|
||||
*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019-2024, CTCaer.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _EMC_H_
|
||||
#define _EMC_H_
|
||||
|
||||
#define EMC_INTSTATUS 0x0
|
||||
#define EMC_DBG 0x8
|
||||
#define EMC_CFG 0xC
|
||||
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
|
||||
#define EMC_CFG_UPDATE 0x5f4
|
||||
#define EMC_ADR_CFG 0x10
|
||||
#define EMC_REFCTRL 0x20
|
||||
#define EMC_PIN 0x24
|
||||
#define EMC_TIMING_CONTROL 0x28
|
||||
#define EMC_RC 0x2c
|
||||
#define EMC_RFC 0x30
|
||||
#define EMC_RFCPB 0x590
|
||||
#define EMC_RAS 0x34
|
||||
#define EMC_RP 0x38
|
||||
#define EMC_R2W 0x3c
|
||||
#define EMC_W2R 0x40
|
||||
#define EMC_R2P 0x44
|
||||
#define EMC_W2P 0x48
|
||||
#define EMC_CCDMW 0x5c0
|
||||
#define EMC_RD_RCD 0x4c
|
||||
#define EMC_WR_RCD 0x50
|
||||
#define EMC_RRD 0x54
|
||||
#define EMC_REXT 0x58
|
||||
#define EMC_WDV 0x5c
|
||||
#define EMC_QUSE 0x60
|
||||
#define EMC_QRST 0x64
|
||||
#define EMC_ISSUE_QRST 0x428
|
||||
#define EMC_QSAFE 0x68
|
||||
#define EMC_RDV 0x6c
|
||||
#define EMC_REFRESH 0x70
|
||||
#define EMC_BURST_REFRESH_NUM 0x74
|
||||
#define EMC_PDEX2WR 0x78
|
||||
#define EMC_PDEX2RD 0x7c
|
||||
#define EMC_PDEX2CKE 0x118
|
||||
#define EMC_PCHG2PDEN 0x80
|
||||
#define EMC_ACT2PDEN 0x84
|
||||
#define EMC_AR2PDEN 0x88
|
||||
#define EMC_RW2PDEN 0x8c
|
||||
#define EMC_CKE2PDEN 0x11c
|
||||
#define EMC_TXSR 0x90
|
||||
#define EMC_TCKE 0x94
|
||||
#define EMC_TFAW 0x98
|
||||
#define EMC_TRPAB 0x9c
|
||||
#define EMC_TCLKSTABLE 0xa0
|
||||
#define EMC_TCLKSTOP 0xa4
|
||||
#define EMC_TREFBW 0xa8
|
||||
#define EMC_TPPD 0xac
|
||||
#define EMC_PDEX2MRR 0xb4
|
||||
#define EMC_ODT_WRITE 0xb0
|
||||
#define EMC_WEXT 0xb8
|
||||
#define EMC_CTT 0xBC
|
||||
#define EMC_RFC_SLR 0xc0
|
||||
#define EMC_MRS_WAIT_CNT2 0xc4
|
||||
#define EMC_MRS_WAIT_CNT 0xc8
|
||||
#define EMC_MRS 0xcc
|
||||
#define EMC_EMRS 0xd0
|
||||
#define EMC_REF 0xd4
|
||||
#define EMC_PRE 0xd8
|
||||
#define EMC_NOP 0xdc
|
||||
#define EMC_SELF_REF 0xe0
|
||||
#define EMC_DPD 0xe4
|
||||
#define EMC_MRW 0xe8
|
||||
#define EMC_MRR 0xec
|
||||
#define EMC_CMDQ 0xf0
|
||||
#define EMC_MC2EMCQ 0xf4
|
||||
#define EMC_FBIO_TWTM 0xF8
|
||||
#define EMC_FBIO_TRATM 0xFC
|
||||
#define EMC_FBIO_TWATM 0x108
|
||||
#define EMC_FBIO_TR2REF 0x10C
|
||||
#define EMC_FBIO_SPARE 0x100
|
||||
#define EMC_FBIO_CFG5 0x104
|
||||
#define EMC_FBIO_CFG6 0x114
|
||||
#define EMC_CFG_RSV 0x120
|
||||
#define EMC_ACPD_CONTROL 0x124
|
||||
#define EMC_MPC 0x128
|
||||
#define EMC_EMRS2 0x12c
|
||||
#define EMC_EMRS3 0x130
|
||||
#define EMC_MRW2 0x134
|
||||
#define EMC_MRW3 0x138
|
||||
#define EMC_MRW4 0x13c
|
||||
#define EMC_MRW5 0x4a0
|
||||
#define EMC_MRW6 0x4a4
|
||||
#define EMC_MRW7 0x4a8
|
||||
#define EMC_MRW8 0x4ac
|
||||
#define EMC_MRW9 0x4b0
|
||||
#define EMC_MRW10 0x4b4
|
||||
#define EMC_MRW11 0x4b8
|
||||
#define EMC_MRW12 0x4bc
|
||||
#define EMC_MRW13 0x4c0
|
||||
#define EMC_MRW14 0x4c4
|
||||
#define EMC_MRW15 0x4d0
|
||||
#define EMC_CFG_SYNC 0x4d4
|
||||
#define EMC_CLKEN_OVERRIDE 0x140
|
||||
#define EMC_R2R 0x144
|
||||
#define EMC_W2W 0x148
|
||||
#define EMC_EINPUT 0x14c
|
||||
#define EMC_EINPUT_DURATION 0x150
|
||||
#define EMC_PUTERM_EXTRA 0x154
|
||||
#define EMC_TCKESR 0x158
|
||||
#define EMC_TPD 0x15c
|
||||
#define EMC_STAT_CONTROL 0x160
|
||||
#define EMC_STAT_STATUS 0x164
|
||||
#define EMC_STAT_DRAM_CLOCK_LIMIT_LO 0x19c
|
||||
#define EMC_STAT_DRAM_CLOCK_LIMIT_HI 0x1a0
|
||||
#define EMC_STAT_DRAM_CLOCKS_LO 0x1a4
|
||||
#define EMC_STAT_DRAM_CLOCKS_HI 0x1a8
|
||||
#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO 0x1ac
|
||||
#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI 0x1b0
|
||||
#define EMC_STAT_DRAM_DEV0_READ_CNT_LO 0x1b4
|
||||
#define EMC_STAT_DRAM_DEV0_READ_CNT_HI 0x1b8
|
||||
#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO 0x1bc
|
||||
#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI 0x1c0
|
||||
#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO 0x1c4
|
||||
#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI 0x1c8
|
||||
#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO 0x1cc
|
||||
#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI 0x1d0
|
||||
#define EMC_STAT_DRAM_DEV0_REF_CNT_LO 0x1d4
|
||||
#define EMC_STAT_DRAM_DEV0_REF_CNT_HI 0x1d8
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1dc
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e0
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1e4
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e8
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1ec
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f0
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1f4
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f8
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x1fc
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x200
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x204
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x208
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x20c
|
||||
#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x210
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x214
|
||||
#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x218
|
||||
#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO 0x21c
|
||||
#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI 0x220
|
||||
#define EMC_STAT_DRAM_DEV0_DSR 0x224
|
||||
#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO 0x228
|
||||
#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI 0x22c
|
||||
#define EMC_STAT_DRAM_DEV1_READ_CNT_LO 0x230
|
||||
#define EMC_STAT_DRAM_DEV1_READ_CNT_HI 0x234
|
||||
#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO 0x238
|
||||
#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI 0x23c
|
||||
#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO 0x240
|
||||
#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI 0x244
|
||||
#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO 0x248
|
||||
#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI 0x24c
|
||||
#define EMC_STAT_DRAM_DEV1_REF_CNT_LO 0x250
|
||||
#define EMC_STAT_DRAM_DEV1_REF_CNT_HI 0x254
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x258
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x25c
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x260
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x264
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x268
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x26c
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x270
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x274
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x278
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x27c
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x280
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x284
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x288
|
||||
#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x28c
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x290
|
||||
#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x294
|
||||
#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO 0x298
|
||||
#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI 0x29c
|
||||
#define EMC_STAT_DRAM_DEV1_DSR 0x2a0
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc8c
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc90
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc94
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc98
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xc9c
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca0
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xca4
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca8
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcac
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb0
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcb4
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb8
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcbc
|
||||
#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc0
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcc4
|
||||
#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc8
|
||||
#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO 0xccc
|
||||
#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0
|
||||
#define EMC_STAT_DRAM_IO_DSR 0xcd4
|
||||
#define EMC_AUTO_CAL_CONFIG 0x2a4
|
||||
#define EMC_AUTO_CAL_CONFIG2 0x458
|
||||
#define EMC_AUTO_CAL_CONFIG3 0x45c
|
||||
#define EMC_AUTO_CAL_CONFIG4 0x5b0
|
||||
#define EMC_AUTO_CAL_CONFIG5 0x5b4
|
||||
#define EMC_AUTO_CAL_CONFIG6 0x5cc
|
||||
#define EMC_AUTO_CAL_CONFIG7 0x574
|
||||
#define EMC_AUTO_CAL_CONFIG8 0x2dc
|
||||
#define EMC_AUTO_CAL_CONFIG9 0x42C
|
||||
#define EMC_AUTO_CAL_VREF_SEL_0 0x2f8
|
||||
#define EMC_AUTO_CAL_VREF_SEL_1 0x300
|
||||
#define EMC_AUTO_CAL_INTERVAL 0x2a8
|
||||
#define EMC_AUTO_CAL_STATUS 0x2ac
|
||||
#define EMC_AUTO_CAL_STATUS2 0x3d4
|
||||
#define EMC_AUTO_CAL_CHANNEL 0x464
|
||||
#define EMC_PMACRO_RX_TERM 0xc48
|
||||
#define EMC_PMACRO_DQ_TX_DRV 0xc70
|
||||
#define EMC_PMACRO_CA_TX_DRV 0xc74
|
||||
#define EMC_PMACRO_CMD_TX_DRV 0xc4c
|
||||
#define EMC_PMACRO_AUTOCAL_CFG_0 0x700
|
||||
#define EMC_PMACRO_AUTOCAL_CFG_1 0x704
|
||||
#define EMC_PMACRO_AUTOCAL_CFG_2 0x708
|
||||
#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78
|
||||
#define EMC_PMACRO_ZCTRL 0xc44
|
||||
#define EMC_XM2COMPPADCTRL 0x30c
|
||||
#define EMC_XM2COMPPADCTRL2 0x578
|
||||
#define EMC_XM2COMPPADCTRL3 0x2f4
|
||||
#define EMC_COMP_PAD_SW_CTRL 0x57c
|
||||
#define EMC_REQ_CTRL 0x2b0
|
||||
#define EMC_EMC_STATUS 0x2b4
|
||||
#define EMC_STATUS_MRR_DIVLD BIT(20)
|
||||
#define EMC_CFG_2 0x2b8
|
||||
#define EMC_CFG_DIG_DLL 0x2bc
|
||||
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
||||
#define EMC_DIG_DLL_STATUS 0x2c4
|
||||
#define EMC_CFG_DIG_DLL_1 0x2c8
|
||||
#define EMC_RDV_MASK 0x2cc
|
||||
#define EMC_WDV_MASK 0x2d0
|
||||
#define EMC_RDV_EARLY_MASK 0x2d4
|
||||
#define EMC_RDV_EARLY 0x2d8
|
||||
#define EMC_WDV_CHK 0x4e0
|
||||
#define EMC_ZCAL_INTERVAL 0x2e0
|
||||
#define EMC_ZCAL_WAIT_CNT 0x2e4
|
||||
#define EMC_ZCAL_MRW_CMD 0x2e8
|
||||
#define EMC_ZQ_CAL 0x2ec
|
||||
#define EMC_SCRATCH0 0x324
|
||||
#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8
|
||||
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
|
||||
#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
|
||||
#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8
|
||||
#define EMC_SEL_DPD_CTRL 0x3d8
|
||||
#define EMC_FDPD_CTRL_DQ 0x310
|
||||
#define EMC_FDPD_CTRL_CMD 0x314
|
||||
#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
|
||||
#define EMC_REFCTRL2 0x580
|
||||
#define EMC_FBIO_CFG7 0x584
|
||||
#define EMC_DATA_BRLSHFT_0 0x588
|
||||
#define EMC_DATA_BRLSHFT_1 0x58c
|
||||
#define EMC_DQS_BRLSHFT_0 0x594
|
||||
#define EMC_DQS_BRLSHFT_1 0x598
|
||||
#define EMC_CMD_BRLSHFT_0 0x59c
|
||||
#define EMC_CMD_BRLSHFT_1 0x5a0
|
||||
#define EMC_CMD_BRLSHFT_2 0x5a4
|
||||
#define EMC_CMD_BRLSHFT_3 0x5a8
|
||||
#define EMC_QUSE_BRLSHFT_0 0x5ac
|
||||
#define EMC_QUSE_BRLSHFT_1 0x5b8
|
||||
#define EMC_QUSE_BRLSHFT_2 0x5bc
|
||||
#define EMC_QUSE_BRLSHFT_3 0x5c4
|
||||
#define EMC_FBIO_CFG8 0x5c8
|
||||
#define EMC_CMD_MAPPING_CMD0_0 0x380
|
||||
#define EMC_CMD_MAPPING_CMD0_1 0x384
|
||||
#define EMC_CMD_MAPPING_CMD0_2 0x388
|
||||
#define EMC_CMD_MAPPING_CMD1_0 0x38c
|
||||
#define EMC_CMD_MAPPING_CMD1_1 0x390
|
||||
#define EMC_CMD_MAPPING_CMD1_2 0x394
|
||||
#define EMC_CMD_MAPPING_CMD2_0 0x398
|
||||
#define EMC_CMD_MAPPING_CMD2_1 0x39c
|
||||
#define EMC_CMD_MAPPING_CMD2_2 0x3a0
|
||||
#define EMC_CMD_MAPPING_CMD3_0 0x3a4
|
||||
#define EMC_CMD_MAPPING_CMD3_1 0x3a8
|
||||
#define EMC_CMD_MAPPING_CMD3_2 0x3ac
|
||||
#define EMC_CMD_MAPPING_BYTE 0x3b0
|
||||
#define EMC_DYN_SELF_REF_CONTROL 0x3e0
|
||||
#define EMC_TXSRDLL 0x3e4
|
||||
#define EMC_CCFIFO_ADDR 0x3e8
|
||||
#define EMC_CCFIFO_DATA 0x3ec
|
||||
#define EMC_CCFIFO_STATUS 0x3f0
|
||||
#define EMC_SWIZZLE_RANK0_BYTE0 0x404
|
||||
#define EMC_SWIZZLE_RANK0_BYTE1 0x408
|
||||
#define EMC_SWIZZLE_RANK0_BYTE2 0x40c
|
||||
#define EMC_SWIZZLE_RANK0_BYTE3 0x410
|
||||
#define EMC_SWIZZLE_RANK1_BYTE0 0x418
|
||||
#define EMC_SWIZZLE_RANK1_BYTE1 0x41c
|
||||
#define EMC_SWIZZLE_RANK1_BYTE2 0x420
|
||||
#define EMC_SWIZZLE_RANK1_BYTE3 0x424
|
||||
#define EMC_TR_TIMING_0 0x3b4
|
||||
#define EMC_TR_CTRL_0 0x3b8
|
||||
#define EMC_TR_CTRL_1 0x3bc
|
||||
#define EMC_TR_DVFS 0x460
|
||||
#define EMC_SWITCH_BACK_CTRL 0x3c0
|
||||
#define EMC_TR_RDV 0x3c4
|
||||
#define EMC_TR_QPOP 0x3f4
|
||||
#define EMC_TR_RDV_MASK 0x3f8
|
||||
#define EMC_TR_QSAFE 0x3fc
|
||||
#define EMC_TR_QRST 0x400
|
||||
#define EMC_IBDLY 0x468
|
||||
#define EMC_OBDLY 0x46c
|
||||
#define EMC_TXDSRVTTGEN 0x480
|
||||
#define EMC_WE_DURATION 0x48c
|
||||
#define EMC_WS_DURATION 0x490
|
||||
#define EMC_WEV 0x494
|
||||
#define EMC_WSV 0x498
|
||||
#define EMC_CFG_3 0x49c
|
||||
#define EMC_CFG_PIPE_2 0x554
|
||||
#define EMC_CFG_PIPE_CLK 0x558
|
||||
#define EMC_CFG_PIPE_1 0x55c
|
||||
#define EMC_CFG_PIPE 0x560
|
||||
#define EMC_QPOP 0x564
|
||||
#define EMC_QUSE_WIDTH 0x568
|
||||
#define EMC_PUTERM_WIDTH 0x56c
|
||||
#define EMC_PROTOBIST_CONFIG_ADR_1 0x5d0
|
||||
#define EMC_PROTOBIST_CONFIG_ADR_2 0x5d4
|
||||
#define EMC_PROTOBIST_MISC 0x5d8
|
||||
#define EMC_PROTOBIST_WDATA_LOWER 0x5dc
|
||||
#define EMC_PROTOBIST_WDATA_UPPER 0x5e0
|
||||
#define EMC_PROTOBIST_RDATA 0x5ec
|
||||
#define EMC_DLL_CFG_0 0x5e4
|
||||
#define EMC_DLL_CFG_1 0x5e8
|
||||
#define EMC_TRAINING_CMD 0xe00
|
||||
#define EMC_TRAINING_CTRL 0xe04
|
||||
#define EMC_TRAINING_STATUS 0xe08
|
||||
#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c
|
||||
#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10
|
||||
#define EMC_TRAINING_QUSE_CTRL_MISC 0xe14
|
||||
#define EMC_TRAINING_WRITE_FINE_CTRL 0xe18
|
||||
#define EMC_TRAINING_WRITE_CTRL_MISC 0xe1c
|
||||
#define EMC_TRAINING_WRITE_VREF_CTRL 0xe20
|
||||
#define EMC_TRAINING_READ_FINE_CTRL 0xe24
|
||||
#define EMC_TRAINING_READ_CTRL_MISC 0xe28
|
||||
#define EMC_TRAINING_READ_VREF_CTRL 0xe2c
|
||||
#define EMC_TRAINING_CA_FINE_CTRL 0xe30
|
||||
#define EMC_TRAINING_CA_CTRL_MISC 0xe34
|
||||
#define EMC_TRAINING_CA_CTRL_MISC1 0xe38
|
||||
#define EMC_TRAINING_CA_VREF_CTRL 0xe3c
|
||||
#define EMC_TRAINING_CA_TADR_CTRL 0xe40
|
||||
#define EMC_TRAINING_SETTLE 0xe44
|
||||
#define EMC_TRAINING_DEBUG_CTRL 0xe48
|
||||
#define EMC_TRAINING_DEBUG_DQ0 0xe4c
|
||||
#define EMC_TRAINING_DEBUG_DQ1 0xe50
|
||||
#define EMC_TRAINING_DEBUG_DQ2 0xe54
|
||||
#define EMC_TRAINING_DEBUG_DQ3 0xe58
|
||||
#define EMC_TRAINING_MPC 0xe5c
|
||||
#define EMC_TRAINING_PATRAM_CTRL 0xe60
|
||||
#define EMC_TRAINING_PATRAM_DQ 0xe64
|
||||
#define EMC_TRAINING_PATRAM_DMI 0xe68
|
||||
#define EMC_TRAINING_VREF_SETTLE 0xe6c
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0 0xe70
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1 0xe74
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2 0xe78
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3 0xe7c
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC 0xe80
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0 0xe84
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1 0xe88
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2 0xe8c
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3 0xe90
|
||||
#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC 0xe94
|
||||
#define EMC_TRAINING_RW_OFFSET_IB_BYTE0 0xe98
|
||||
#define EMC_TRAINING_RW_OFFSET_IB_BYTE1 0xe9c
|
||||
#define EMC_TRAINING_RW_OFFSET_IB_BYTE2 0xea0
|
||||
#define EMC_TRAINING_RW_OFFSET_IB_BYTE3 0xea4
|
||||
#define EMC_TRAINING_RW_OFFSET_IB_MISC 0xea8
|
||||
#define EMC_TRAINING_RW_OFFSET_OB_BYTE0 0xeac
|
||||
#define EMC_TRAINING_RW_OFFSET_OB_BYTE1 0xeb0
|
||||
#define EMC_TRAINING_RW_OFFSET_OB_BYTE2 0xeb4
|
||||
#define EMC_TRAINING_RW_OFFSET_OB_BYTE3 0xeb8
|
||||
#define EMC_TRAINING_RW_OFFSET_OB_MISC 0xebc
|
||||
#define EMC_TRAINING_OPT_CA_VREF 0xec0
|
||||
#define EMC_TRAINING_OPT_DQ_OB_VREF 0xec4
|
||||
#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0 0xec8
|
||||
#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1 0xecc
|
||||
#define EMC_TRAINING_QUSE_VREF_CTRL 0xed0
|
||||
#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4
|
||||
#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8
|
||||
#define EMC_TRAINING_DRAMC_TIMING 0xedc
|
||||
#define EMC_PMACRO_DATA_PI_CTRL 0x110
|
||||
#define EMC_PMACRO_CMD_PI_CTRL 0x114
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_3 0x60c
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_4 0x610
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK0_5 0x614
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_0 0x620
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_1 0x624
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_2 0x628
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_3 0x62c
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630
|
||||
#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 0x684
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 0x688
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 0x68c
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 0x690
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 0x694
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 0x6a0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 0x6a4
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 0x6a8
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 0x6ac
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 0x6b0
|
||||
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 0x6b4
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 0x6c0
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 0x6c4
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 0x6c8
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 0x6cc
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4 0x6d0
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5 0x6d4
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 0x6e0
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 0x6e4
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 0x6e8
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 0x6ec
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4 0x6f0
|
||||
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5 0x6f4
|
||||
#define EMC_PMACRO_TX_PWRD_0 0x720
|
||||
#define EMC_PMACRO_TX_PWRD_1 0x724
|
||||
#define EMC_PMACRO_TX_PWRD_2 0x728
|
||||
#define EMC_PMACRO_TX_PWRD_3 0x72c
|
||||
#define EMC_PMACRO_TX_PWRD_4 0x730
|
||||
#define EMC_PMACRO_TX_PWRD_5 0x734
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_0 0x740
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_1 0x744
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_3 0x74c
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_2 0x748
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_4 0x750
|
||||
#define EMC_PMACRO_TX_SEL_CLK_SRC_5 0x754
|
||||
#define EMC_PMACRO_DDLL_BYPASS 0x760
|
||||
#define EMC_PMACRO_DDLL_PWRD_0 0x770
|
||||
#define EMC_PMACRO_DDLL_PWRD_1 0x774
|
||||
#define EMC_PMACRO_DDLL_PWRD_2 0x778
|
||||
#define EMC_PMACRO_CMD_CTRL_0 0x780
|
||||
#define EMC_PMACRO_CMD_CTRL_1 0x784
|
||||
#define EMC_PMACRO_CMD_CTRL_2 0x788
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0x800
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0x804
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0x808
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 0x80c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0x810
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0x814
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0x818
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 0x81c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0x820
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0x824
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0x828
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 0x82c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0x830
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0x834
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0x838
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 0x83c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0x840
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0x844
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0x848
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 0x84c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0x850
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0x854
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0x858
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 0x85c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0x860
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0x864
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0x868
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 0x86c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0x870
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0x874
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0x878
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 0x87c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 0x880
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 0x884
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 0x888
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 0x88c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 0x890
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 0x894
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 0x898
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 0x89c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 0x8a0
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 0x8a4
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 0x8a8
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 0x8ac
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 0x8b0
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 0x8b4
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 0x8b8
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 0x8bc
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0x900
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0x904
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0x908
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 0x90c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0x910
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0x914
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0x918
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 0x91c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0x920
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0x924
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0x928
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 0x92c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0x930
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0x934
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0x938
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 0x93c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0x940
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0x944
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0x948
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 0x94c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0x950
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0x954
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0x958
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 0x95c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0x960
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0x964
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0x968
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 0x96c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0x970
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0x974
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0x978
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 0x97c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 0x980
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 0x984
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 0x988
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 0x98c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 0x990
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 0x994
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 0x998
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 0x99c
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 0x9a0
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 0x9a4
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 0x9a8
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 0x9ac
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 0x9b0
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 0x9b4
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 0x9b8
|
||||
#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 0x9bc
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0xa00
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0xa04
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0xa08
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0xa10
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0xa14
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0xa18
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0xa20
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0xa24
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0xa28
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0xa30
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0xa34
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0xa38
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0xa40
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0xa44
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0xa48
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0xa50
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0xa54
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0xa58
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0xa60
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0xa64
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0xa68
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0xa70
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0xa74
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0xa78
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0 0xa80
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1 0xa84
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2 0xa88
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0 0xa90
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1 0xa94
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2 0xa98
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0 0xaa0
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1 0xaa4
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2 0xaa8
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0 0xab0
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1 0xab4
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2 0xab8
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0xb00
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0xb04
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0xb08
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0xb10
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0xb14
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0xb18
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0xb20
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0xb24
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0xb28
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0xb30
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0xb34
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0xb38
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0xb40
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0xb44
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0xb48
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0xb50
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0xb54
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0xb58
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0xb60
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0xb64
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0xb68
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0xb70
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0xb74
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0xb78
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0 0xb80
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1 0xb84
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2 0xb88
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0 0xb90
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1 0xb94
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2 0xb98
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0 0xba0
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1 0xba4
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2 0xba8
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0 0xbb0
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1 0xbb4
|
||||
#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2 0xbb8
|
||||
#define EMC_PMACRO_IB_VREF_DQ_0 0xbe0
|
||||
#define EMC_PMACRO_IB_VREF_DQ_1 0xbe4
|
||||
#define EMC_PMACRO_IB_VREF_DQ_2 0xbe8
|
||||
#define EMC_PMACRO_IB_VREF_DQS_0 0xbf0
|
||||
#define EMC_PMACRO_IB_VREF_DQS_1 0xbf4
|
||||
#define EMC_PMACRO_IB_VREF_DQS_2 0xbf8
|
||||
#define EMC_PMACRO_IB_RXRT 0xcf4
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_0 0xc00
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_1 0xc04
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_2 0xc08
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_3 0xc0c
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_4 0xc10
|
||||
#define EMC_PMACRO_DDLL_LONG_CMD_5 0xc14
|
||||
#define EMC_PMACRO_DDLL_SHORT_CMD_0 0xc20
|
||||
#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24
|
||||
#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28
|
||||
#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30
|
||||
#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34
|
||||
#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38
|
||||
#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0
|
||||
#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c
|
||||
#define EMC_PMACRO_PAD_CFG_CTRL 0xc40
|
||||
#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50
|
||||
#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54
|
||||
#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58
|
||||
#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c
|
||||
#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
|
||||
#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
|
||||
#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
|
||||
#define EMC_PMACRO_DSR_VTTGEN_CTRL0 0xC6C
|
||||
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
|
||||
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
|
||||
#define EMC_PMACRO_BRICK_MAPPING_2 0xc88
|
||||
#define EMC_PMACRO_DDLLCAL_CAL 0xce0
|
||||
#define EMC_PMACRO_DDLL_OFFSET 0xce4
|
||||
#define EMC_PMACRO_DDLL_PERIODIC_OFFSET 0xce8
|
||||
#define EMC_PMACRO_BRICK_CTRL_RFU1 0x330
|
||||
#define EMC_PMACRO_BRICK_CTRL_RFU2 0x334
|
||||
#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318
|
||||
#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
|
||||
#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
|
||||
#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_0 0xD40
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_1 0xD44
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_2 0xD48
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_3 0xD4C
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_4 0xD50
|
||||
#define EMC_PMACRO_PERBIT_FGCG_CTRL_5 0xD54
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_0 0xD60
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_1 0xD64
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_2 0xD68
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_3 0xD6C
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_4 0xD70
|
||||
#define EMC_PMACRO_PERBIT_RFU_CTRL_5 0xD74
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_0 0xD80
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_1 0xD84
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_2 0xD88
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_3 0xD8C
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_4 0xD90
|
||||
#define EMC_PMACRO_PERBIT_RFU1_CTRL_5 0xD94
|
||||
#define EMC_PMC_SCRATCH1 0x440
|
||||
#define EMC_PMC_SCRATCH2 0x444
|
||||
#define EMC_PMC_SCRATCH3 0x448
|
||||
|
||||
#define EMC_STATUS_UPDATE_TIMEOUT 1000
|
||||
|
||||
typedef enum _emc_mr_t
|
||||
{
|
||||
MR0_FEAT = 0,
|
||||
MR4_TEMP = 4,
|
||||
MR5_MAN_ID = 5,
|
||||
MR6_REV_ID1 = 6,
|
||||
MR7_REV_ID2 = 7,
|
||||
MR8_DENSITY = 8,
|
||||
} emc_mr_t;
|
||||
|
||||
enum
|
||||
{
|
||||
EMC_CHAN0 = 0,
|
||||
EMC_CHAN1 = 1
|
||||
};
|
||||
|
||||
typedef struct _emc_mr_chip_data_t
|
||||
{
|
||||
// Device 0.
|
||||
u8 rank0_ch0;
|
||||
u8 rank0_ch1;
|
||||
|
||||
// Device 1.
|
||||
u8 rank1_ch0;
|
||||
u8 rank1_ch1;
|
||||
} emc_mr_chip_data_t;
|
||||
|
||||
typedef struct _emc_mr_data_t
|
||||
{
|
||||
emc_mr_chip_data_t chip0;
|
||||
emc_mr_chip_data_t chip1;
|
||||
} emc_mr_data_t;
|
||||
|
||||
#endif
|
||||
1528
bdk/mem/emc_t210.h
Normal file
1528
bdk/mem/emc_t210.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,13 +19,15 @@
|
||||
#include "heap.h"
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define HEAP_USED_MAGIC 0x50414548 // "HEAP".
|
||||
|
||||
heap_t _heap;
|
||||
|
||||
static void _heap_create(void *start)
|
||||
{
|
||||
_heap.start = start;
|
||||
_heap.first = NULL;
|
||||
_heap.last = NULL;
|
||||
_heap.last = NULL;
|
||||
}
|
||||
|
||||
// Node info is before node address.
|
||||
@@ -40,7 +42,7 @@ static void *_heap_alloc(u32 size)
|
||||
if (!_heap.first)
|
||||
{
|
||||
node = (hnode_t *)_heap.start;
|
||||
node->used = 1;
|
||||
node->used = HEAP_USED_MAGIC;
|
||||
node->size = size;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
@@ -70,8 +72,8 @@ static void *_heap_alloc(u32 size)
|
||||
// create a new one and set the leftover size.
|
||||
if (new_size >= (sizeof(hnode_t) << 2))
|
||||
{
|
||||
new_node->size = new_size - sizeof(hnode_t);
|
||||
new_node->used = 0;
|
||||
new_node->size = new_size - sizeof(hnode_t);
|
||||
new_node->next = node->next;
|
||||
|
||||
// Check that we are not on first node.
|
||||
@@ -85,7 +87,7 @@ static void *_heap_alloc(u32 size)
|
||||
size += new_size;
|
||||
|
||||
node->size = size;
|
||||
node->used = 1;
|
||||
node->used = HEAP_USED_MAGIC;
|
||||
|
||||
return (void *)node + sizeof(hnode_t);
|
||||
}
|
||||
@@ -100,7 +102,7 @@ static void *_heap_alloc(u32 size)
|
||||
|
||||
// No unused node found, create a new one.
|
||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
|
||||
new_node->used = 1;
|
||||
new_node->used = HEAP_USED_MAGIC;
|
||||
new_node->size = size;
|
||||
new_node->prev = node;
|
||||
new_node->next = NULL;
|
||||
@@ -114,25 +116,40 @@ static void *_heap_alloc(u32 size)
|
||||
static void _heap_free(void *addr)
|
||||
{
|
||||
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
|
||||
|
||||
// Check if heap owns this address.
|
||||
if (addr < _heap.start || node->used != HEAP_USED_MAGIC)
|
||||
{
|
||||
//! BUGPRINTF("free error: addr %08p, used %08X!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
node->used = 0;
|
||||
node = _heap.first;
|
||||
|
||||
#ifndef BDK_MALLOC_NO_DEFRAG
|
||||
// Do simple defragmentation on next blocks.
|
||||
while (node)
|
||||
// Merge with previous node if empty.
|
||||
hnode_t *prev = node->prev;
|
||||
if (prev && !prev->used)
|
||||
{
|
||||
if (!node->used)
|
||||
{
|
||||
if (node->prev && !node->prev->used)
|
||||
{
|
||||
node->prev->size += node->size + sizeof(hnode_t);
|
||||
node->prev->next = node->next;
|
||||
prev->size += node->size + sizeof(hnode_t);
|
||||
prev->next = node->next;
|
||||
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
if (node->next)
|
||||
node->next->prev = prev;
|
||||
|
||||
// Set node to resized one.
|
||||
node = prev;
|
||||
}
|
||||
|
||||
// Merge with next node if empty.
|
||||
hnode_t *next = node->next;
|
||||
if (next && !next->used)
|
||||
{
|
||||
node->size += next->size + sizeof(hnode_t);
|
||||
node->next = next->next;
|
||||
|
||||
if (next->next)
|
||||
next->next->prev = node;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -152,24 +169,21 @@ void *malloc(u32 size)
|
||||
return _heap_alloc(size);
|
||||
}
|
||||
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(num * size);
|
||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
void *zalloc(u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(size);
|
||||
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
void *buf = (void *)_heap_alloc(size);
|
||||
memset(buf, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return buf;
|
||||
}
|
||||
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
return zalloc(num * size);
|
||||
}
|
||||
|
||||
void free(void *buf)
|
||||
{
|
||||
if (buf >= _heap.start)
|
||||
_heap_free(buf);
|
||||
_heap_free(buf);
|
||||
}
|
||||
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
|
||||
97
bdk/mem/mc.c
97
bdk/mem/mc.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -17,56 +17,88 @@
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <mem/mc.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/clock.h>
|
||||
|
||||
void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
|
||||
{
|
||||
MC(MC_SEC_CARVEOUT_BOM) = bom;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
|
||||
if (lock)
|
||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = 1;
|
||||
}
|
||||
#define HOS_WPR1_BASE 0x80020000
|
||||
|
||||
void mc_config_carveout()
|
||||
void mc_config_carveout_hos()
|
||||
{
|
||||
// Enable ACR GSR3.
|
||||
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
||||
// Enable ACR GSR3 and flush data to ram.
|
||||
*(u32 *)(HOS_WPR1_BASE + SZ_256K - sizeof(u32)) = ACR_GSC3_ENABLE_MAGIC;
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
// Set VPR CYA TRUSTED DEFAULT.
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = VPR_OVR0_CYA_TRUST_DEFAULT;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
|
||||
// Disable VPR carveout.
|
||||
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
|
||||
|
||||
// Configure TZDRAM carveout @ 0x90000000, 1MB.
|
||||
//mc_config_tzdram_carveout(0x90000000, 1, false);
|
||||
mc_config_tzdram_carveout(0, 0, true);
|
||||
// Disable TZDRAM carveout.
|
||||
MC(MC_SEC_CARVEOUT_BOM) = 0;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = 0;
|
||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = BIT(0);
|
||||
|
||||
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
||||
// Disable CPU FW carveout.
|
||||
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = BIT(0);
|
||||
|
||||
// Disable GEN1 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(0) |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
|
||||
// Enable GEN2 carveout as WPR1.
|
||||
MC(MC_SECURITY_CARVEOUT2_BOM) = HOS_WPR1_BASE;
|
||||
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = SZ_256K / SZ_128K;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||
MC(MC_SECURITY_CARVEOUT2_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(2) |
|
||||
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
// Prepare GEN3 carveout as WPR2.
|
||||
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||
MC(MC_SECURITY_CARVEOUT3_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(3) |
|
||||
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
// Disable GEN4 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||
SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_WR_NS;
|
||||
|
||||
// Disable GEN5 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||
SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
@@ -74,13 +106,14 @@ void mc_config_carveout()
|
||||
SEC_CARVEOUT_CFG_WR_NS;
|
||||
}
|
||||
|
||||
void mc_enable_ahb_redirect()
|
||||
// SDMMC, TSEC, XUSB and probably more need it to access < DRAM_START.
|
||||
void mc_enable_ahb_redirect(u32 offset)
|
||||
{
|
||||
// Enable ARC_CLK_OVR_ON.
|
||||
// Bypass ARC clock gating.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
||||
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
||||
MC(MC_IRAM_BOM) = IRAM_BASE;
|
||||
MC(MC_IRAM_TOM) = DRAM_START; // Default is only IRAM: 0x4003F000.
|
||||
MC(MC_IRAM_TOM) = DRAM_START - offset; // Default is only IRAM: 0x4003F000.
|
||||
}
|
||||
|
||||
void mc_disable_ahb_redirect()
|
||||
@@ -89,7 +122,7 @@ void mc_disable_ahb_redirect()
|
||||
MC(MC_IRAM_TOM) = 0;
|
||||
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
||||
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
||||
// Disable ARC_CLK_OVR_ON.
|
||||
// Set ARC clock gating to automatic.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
||||
}
|
||||
|
||||
@@ -109,15 +142,13 @@ void mc_enable()
|
||||
{
|
||||
// Reset EMC source to PLLP.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
|
||||
|
||||
// Enable and clear reset for memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
usleep(5);
|
||||
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
mc_enable_ahb_redirect();
|
||||
#else
|
||||
mc_disable_ahb_redirect();
|
||||
#endif
|
||||
// Enable redirection by default.
|
||||
mc_enable_ahb_redirect(1);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
#include <mem/mc_t210.h>
|
||||
|
||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
||||
void mc_config_carveout();
|
||||
void mc_config_carveout_finalize();
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_config_carveout_hos();
|
||||
void mc_enable_ahb_redirect(u32 offset);
|
||||
void mc_disable_ahb_redirect();
|
||||
bool mc_client_has_access(void *address);
|
||||
void mc_enable();
|
||||
|
||||
1670
bdk/mem/mc_t210.h
1670
bdk/mem/mc_t210.h
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -20,134 +20,146 @@
|
||||
#include "minerva.h"
|
||||
|
||||
#include <ianos/ianos.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define FREQ_NO_TABLE_MAX FREQ_408
|
||||
|
||||
#define TABLE_FREQ_KHZ_OFFSET 0x40
|
||||
#define TABLE_LA_REGS_T210_OFFSET 0x1284
|
||||
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
|
||||
#define LA_SDMMC1_INDEX 6
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
static bool no_table = false;
|
||||
static mtc_config_t *mtc_cfg = NULL;
|
||||
void (*mtc_call)(mtc_config_t *mtc_cfg, void *);
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
|
||||
u32 minerva_init()
|
||||
int minerva_init(minerva_str_t *mtc_str)
|
||||
{
|
||||
u32 tbl_idx = 0;
|
||||
|
||||
minerva_cfg = NULL;
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
//!TODO: Not supported on T210B01 yet.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
return 0;
|
||||
mtc_call = NULL;
|
||||
mtc_cfg = (mtc_config_t *)&mtc_str->mtc_cfg;
|
||||
no_table = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
|
||||
|
||||
#ifdef BDK_MINERVA_CFG_FROM_RAM
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
|
||||
mtc_cfg->mtc_table = (emc_table_t *)mtc_str->mtc_table;
|
||||
|
||||
// Check if Minerva is already initialized.
|
||||
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||
{
|
||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN; // Retrain if needed.
|
||||
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
// Load library and do a periodic training if needed.
|
||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
||||
mtc_call = (void *)ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)mtc_cfg);
|
||||
|
||||
return !minerva_cfg ? 1 : 0;
|
||||
return !mtc_call ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtc_config_t mtc_tmp;
|
||||
|
||||
mtc_tmp.mtc_table = mtc_cfg->mtc_table;
|
||||
mtc_tmp.sdram_id = fuse_read_dramid(false);
|
||||
mtc_tmp.init_done = MTC_NEW_MAGIC;
|
||||
// Initialize table.
|
||||
mtc_tmp.mtc_table = mtc_cfg->mtc_table;
|
||||
mtc_tmp.sdram_id = fuse_read_dramid(false);
|
||||
mtc_tmp.init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC;
|
||||
|
||||
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp);
|
||||
// Load library and get table.
|
||||
u32 ep_addr = ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)&mtc_tmp);
|
||||
|
||||
// Ensure that Minerva is new.
|
||||
// Ensure that Minerva is initialized.
|
||||
if (mtc_tmp.init_done == MTC_INIT_MAGIC)
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
mtc_call = (void *)ep_addr;
|
||||
else
|
||||
mtc_cfg->init_done = 0;
|
||||
|
||||
// Copy Minerva context to Nyx storage.
|
||||
if (minerva_cfg)
|
||||
if (mtc_call)
|
||||
memcpy(mtc_cfg, (void *)&mtc_tmp, sizeof(mtc_config_t));
|
||||
}
|
||||
#else
|
||||
// Fully initialize Minerva.
|
||||
memset(mtc_cfg, 0, sizeof(mtc_config_t));
|
||||
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
|
||||
// Initialize mtc table.
|
||||
mtc_cfg->mtc_table = mtc_str->mtc_table;
|
||||
mtc_cfg->sdram_id = fuse_read_dramid(false);
|
||||
mtc_cfg->init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC;
|
||||
|
||||
mtc_cfg->sdram_id = fuse_read_dramid(false);
|
||||
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
|
||||
u32 ep_addr = ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)mtc_cfg);
|
||||
|
||||
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
|
||||
// Ensure that Minerva is new.
|
||||
// Ensure that Minerva is initialized.
|
||||
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
mtc_call = (void *)ep_addr;
|
||||
else
|
||||
mtc_cfg->init_done = 0;
|
||||
#endif
|
||||
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call)
|
||||
return 1;
|
||||
|
||||
// Get current frequency
|
||||
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
|
||||
if (no_table)
|
||||
{
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
|
||||
break;
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
mtc_cfg->rate_from = FREQ_204;
|
||||
mtc_cfg->rate_to = FREQ_NO_TABLE_MAX;
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
|
||||
mtc_cfg->rate_to = FREQ_204;
|
||||
// Train frequencies.
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_from = FREQ_204;
|
||||
mtc_cfg->rate_to = FREQ_204;
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = FREQ_800;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = FREQ_1600;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
|
||||
// FSP WAR.
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
mtc_cfg->rate_to = FREQ_800;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
|
||||
// Switch to max.
|
||||
mtc_cfg->rate_to = FREQ_1600;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void minerva_change_freq(minerva_freq_t freq)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call)
|
||||
return;
|
||||
|
||||
// Clamp max allowed frequency when no table exists.
|
||||
if (no_table && freq > FREQ_NO_TABLE_MAX)
|
||||
freq = FREQ_NO_TABLE_MAX;
|
||||
|
||||
// Check if requested frequency is different. Do not allow otherwise because it will hang.
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
if (mtc_cfg->rate_from != freq)
|
||||
{
|
||||
mtc_cfg->rate_to = freq;
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = freq;
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void minerva_deinit()
|
||||
{
|
||||
if (!mtc_cfg)
|
||||
return;
|
||||
|
||||
minerva_change_freq(FREQ_204);
|
||||
mtc_cfg->init_done = 0;
|
||||
}
|
||||
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||
{
|
||||
|
||||
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
|
||||
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
|
||||
|
||||
@@ -166,12 +178,18 @@ void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||
}
|
||||
}
|
||||
|
||||
void minerva_prep_boot_freq()
|
||||
void minerva_prep_boot_hos()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
// Restore boot frequency for no table mode.
|
||||
if (no_table)
|
||||
{
|
||||
minerva_deinit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there's RAM OC. If not exit.
|
||||
if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
@@ -183,16 +201,15 @@ void minerva_prep_boot_freq()
|
||||
minerva_change_freq(FREQ_800);
|
||||
}
|
||||
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call || no_table)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Program SDMMC LA regs.
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
if (prg_sdmmc_la)
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
|
||||
// Add OC frequency.
|
||||
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
@@ -236,7 +253,7 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
|
||||
// Train frequency.
|
||||
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
}
|
||||
|
||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||
@@ -251,31 +268,28 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
|
||||
void minerva_periodic_training()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
if (mtc_cfg->rate_from == FREQ_1600)
|
||||
if (mtc_cfg->rate_from >= FREQ_1066)
|
||||
{
|
||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_call(mtc_cfg, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
emc_table_t *minerva_get_mtc_table()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call || no_table)
|
||||
return NULL;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->mtc_table;
|
||||
}
|
||||
|
||||
int minerva_get_mtc_table_entries()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
if (!mtc_call || no_table)
|
||||
return 0;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->table_entries;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define MTC_INIT_MAGIC 0x3043544D
|
||||
#define MTC_NEW_MAGIC 0x5243544D
|
||||
#define MTC_IRB_MAGIC 0x4943544D
|
||||
|
||||
#define EMC_PERIODIC_TRAIN_MS 250
|
||||
|
||||
@@ -41,6 +42,12 @@ typedef struct
|
||||
u32 init_done;
|
||||
} mtc_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mtc_config_t mtc_cfg;
|
||||
emc_table_t mtc_table[11]; // 10 + 1.
|
||||
} minerva_str_t;
|
||||
|
||||
enum train_mode_t
|
||||
{
|
||||
OP_SWITCH = 0,
|
||||
@@ -54,17 +61,23 @@ typedef enum
|
||||
{
|
||||
FREQ_204 = 204000,
|
||||
FREQ_408 = 408000,
|
||||
FREQ_666 = 665600,
|
||||
FREQ_800 = 800000,
|
||||
FREQ_1066 = 1065600,
|
||||
FREQ_1333 = 1331200,
|
||||
FREQ_1600 = 1600000
|
||||
FREQ_1600 = 1600000,
|
||||
|
||||
FREQ_MIN = FREQ_204,
|
||||
FREQ_MAX = FREQ_1600
|
||||
} minerva_freq_t;
|
||||
|
||||
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
u32 minerva_init();
|
||||
int minerva_init(minerva_str_t *mtc_str);
|
||||
void minerva_deinit();
|
||||
void minerva_change_freq(minerva_freq_t freq);
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01);
|
||||
void minerva_prep_boot_freq();
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom);
|
||||
void minerva_prep_boot_hos();
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la);
|
||||
void minerva_periodic_training();
|
||||
emc_table_t *minerva_get_mtc_table();
|
||||
int minerva_get_mtc_table_entries();
|
||||
|
||||
105
bdk/mem/sdram.c
105
bdk/mem/sdram.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <mem/mc.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <mem/sdram.h>
|
||||
#include <mem/sdram_param_t210.h>
|
||||
#include <mem/sdram_param_t210b01.h>
|
||||
@@ -85,9 +85,9 @@ static const u8 dram_encoding_t210b01[] = {
|
||||
#include "sdram_config.inl"
|
||||
#include "sdram_config_t210b01.inl"
|
||||
|
||||
static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)
|
||||
static int _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)
|
||||
{
|
||||
bool err = true;
|
||||
int err = 1;
|
||||
|
||||
for (s32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)
|
||||
{
|
||||
@@ -98,13 +98,13 @@ static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_st
|
||||
|
||||
if (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)
|
||||
{
|
||||
err = false;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (((EMC(reg_offset) & bit_mask) != 0) == updated_state)
|
||||
{
|
||||
err = false;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
usleep(1);
|
||||
@@ -182,41 +182,6 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
|
||||
return data;
|
||||
}
|
||||
|
||||
void sdram_src_pllc(bool enable)
|
||||
{
|
||||
static bool enabled = false;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210 || enable == enabled)
|
||||
return;
|
||||
|
||||
enabled = enable;
|
||||
|
||||
// Clear CC interrupt.
|
||||
EMC(EMC_INTSTATUS) = BIT(4);
|
||||
(void)EMC(EMC_INTSTATUS);
|
||||
|
||||
u32 clk_src_emc = _dram_cfg_08_10_12_14_samsung_hynix_4gb.emc_clock_source;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
// Check if clock source is not the expected one.
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) != clk_src_emc)
|
||||
return;
|
||||
|
||||
// Set source as PLLC_OUT0.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = 0x20188004;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore MC/EMC clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_src_emc;
|
||||
}
|
||||
|
||||
// Wait for CC interrupt.
|
||||
while (!(EMC(EMC_INTSTATUS) & BIT(4)))
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
static void _sdram_config_t210(const sdram_params_t210_t *params)
|
||||
{
|
||||
// VDDP Select.
|
||||
@@ -260,7 +225,7 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
|
||||
|
||||
u32 pllm_div = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLL_BASE_ENABLE;
|
||||
|
||||
u32 wait_end = get_tmr_us() + 300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & BIT(27)))
|
||||
@@ -1012,26 +977,26 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
|
||||
|
||||
// Program per bit pad macros.
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0) = params->emc_pmacro_perbit_rfu_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1) = params->emc_pmacro_perbit_rfu_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2) = params->emc_pmacro_perbit_rfu_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3) = params->emc_pmacro_perbit_rfu_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4) = params->emc_pmacro_perbit_rfu_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5) = params->emc_pmacro_perbit_rfu_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
||||
EMC(EMC_PMACRO_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl;
|
||||
EMC(EMC_PMACRO_CMD_PI_CTRL) = params->emc_pmacro_cmd_pi_ctrl;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0_B01) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1_B01) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2_B01) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3_B01) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4_B01) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5_B01) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0_B01) = params->emc_pmacro_perbit_rfu_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1_B01) = params->emc_pmacro_perbit_rfu_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2_B01) = params->emc_pmacro_perbit_rfu_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3_B01) = params->emc_pmacro_perbit_rfu_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4_B01) = params->emc_pmacro_perbit_rfu_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5_B01) = params->emc_pmacro_perbit_rfu_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0_B01) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1_B01) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2_B01) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3_B01) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4_B01) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5_B01) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
||||
EMC(EMC_PMACRO_DATA_PI_CTRL_B01) = params->emc_pmacro_data_pi_ctrl;
|
||||
EMC(EMC_PMACRO_CMD_PI_CTRL_B01) = params->emc_pmacro_cmd_pi_ctrl;
|
||||
|
||||
EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
|
||||
EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
|
||||
@@ -1220,7 +1185,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
if (params->emc_bct_spare8)
|
||||
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
||||
|
||||
EMC(EMC_AUTO_CAL_CONFIG9) = params->emc_auto_cal_config9;
|
||||
EMC(EMC_AUTO_CAL_CONFIG9_B01) = params->emc_auto_cal_config9;
|
||||
|
||||
// Program EMC timing configuration.
|
||||
EMC(EMC_CFG_2) = params->emc_cfg2;
|
||||
@@ -1240,11 +1205,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_RAS) = params->emc_ras;
|
||||
EMC(EMC_RP) = params->emc_rp;
|
||||
EMC(EMC_TPPD) = params->emc_tppd;
|
||||
EMC(EMC_CTT) = params->emc_trtm;
|
||||
EMC(EMC_FBIO_TWTM) = params->emc_twtm;
|
||||
EMC(EMC_FBIO_TRATM) = params->emc_tratm;
|
||||
EMC(EMC_FBIO_TWATM) = params->emc_twatm;
|
||||
EMC(EMC_FBIO_TR2REF) = params->emc_tr2ref;
|
||||
EMC(EMC_TRTM_B01) = params->emc_trtm;
|
||||
EMC(EMC_TWTM_B01) = params->emc_twtm;
|
||||
EMC(EMC_TRATM_B01) = params->emc_tratm;
|
||||
EMC(EMC_TWATM_B01) = params->emc_twatm;
|
||||
EMC(EMC_TR2REF_B01) = params->emc_tr2ref;
|
||||
EMC(EMC_R2R) = params->emc_r2r;
|
||||
EMC(EMC_W2W) = params->emc_w2w;
|
||||
EMC(EMC_R2W) = params->emc_r2w;
|
||||
@@ -1321,7 +1286,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
||||
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
||||
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
||||
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
||||
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL_0_B01) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
||||
|
||||
// Set pipe bypass enable bits before sending any DRAM commands.
|
||||
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
||||
@@ -1465,7 +1430,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
||||
|
||||
// Set untranslated region requirements.
|
||||
MC(MC_UNTRANSLATED_REGION_CHECK) = params->mc_untranslated_region_check;
|
||||
MC(MC_UNTRANSLATED_REGION_CHECK_B01) = params->mc_untranslated_region_check;
|
||||
|
||||
// Lock carveouts per BCT cfg.
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef _SDRAM_H_
|
||||
#define _SDRAM_H_
|
||||
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
|
||||
/*
|
||||
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
||||
@@ -135,7 +135,6 @@ void sdram_init();
|
||||
void *sdram_get_params_patched();
|
||||
void *sdram_get_params_t210b01();
|
||||
void sdram_lp0_save_params(const void *params);
|
||||
void sdram_src_pllc(bool enable);
|
||||
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -497,7 +497,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
.mc_emem_adr_cfg_bank_mask2 = 0x4B9C1000,
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
* size (in MBytes)
|
||||
*/
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||
|
||||
@@ -538,18 +538,32 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
.mc_clken_override = 0x00008000,
|
||||
|
||||
.mc_stat_control = 0x00000000,
|
||||
|
||||
/* VPR carveout configuration */
|
||||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343. New: 0xE4FACB43. + TSEC, NVENC.
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
|
||||
.mc_video_protect_vpr_override1 = 0x0000FED3, // Default: 0x00001ED3. New: 0x0000FED3. + TSECB, TSEC1, TSECB1.
|
||||
// Disable access:
|
||||
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||
// Enable access:
|
||||
// DC, DCB, HDA, VIC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||
// Disable access:
|
||||
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
|
||||
// Enable access:
|
||||
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||
.mc_video_protect_vpr_override1 = 0x0000FED3, // Stock/Reset: 0x00001ED3. HOS new: 0x0000FED3. + TSECB, TSEC1, TSECB1.
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
|
||||
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
|
||||
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||
|
||||
/* TZDRAM carveout configuration */
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
@@ -642,6 +656,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
/* Specifies data for patched boot rom write */
|
||||
.boot_rom_patch_data = 0x00000000,
|
||||
|
||||
/* CPU FW carveout configuration */
|
||||
.mc_mts_carveout_bom = 0xFFF00000,
|
||||
.mc_mts_carveout_adr_hi = 0x00000000,
|
||||
.mc_mts_carveout_size_mb = 0x00000000,
|
||||
@@ -670,5 +685,7 @@ static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
|
||||
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
|
||||
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
|
||||
{ 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
|
||||
{ 0x00000007, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_arb_timing_rfcpb) },
|
||||
{ 0x72A30504, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_arb_misc0) },
|
||||
};
|
||||
#undef DCFG_OFFSET_OF
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -550,7 +550,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
||||
.mc_emem_adr_cfg_bank_mask2 = 0x4B9C1000,
|
||||
/*
|
||||
* Specifies the value for MC_EMEM_CFG which holds the external memory
|
||||
* size (in KBytes)
|
||||
* size (in MBytes)
|
||||
*/
|
||||
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
|
||||
|
||||
@@ -595,14 +595,26 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343.
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B and TSECB, TSEC1, TSECB1.
|
||||
.mc_video_protect_vpr_override1 = 0x0600FED3, // Default: 0x06001ED3.
|
||||
// Disable access:
|
||||
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||
// Enable access:
|
||||
// DC, DCB, HDA, VIC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||
// Disable access:
|
||||
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR, SE2, SE2B. Plus TSECB, TSEC1, TSECB1.
|
||||
// Enable access:
|
||||
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||
.mc_video_protect_vpr_override1 = 0x0600FED3, // Reset: 0x06001ED3. HOS new: 0x0600FED3. + TSECB, TSEC1, TSECB1.
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
|
||||
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
|
||||
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||
|
||||
/* TZDRAM carveout configuration */
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -54,10 +54,12 @@
|
||||
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
|
||||
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
|
||||
|
||||
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
#define SMMU_PAYLOAD_EN_SHIFT 4
|
||||
#define SMMU_PAYLOAD_EN_SET 0x20
|
||||
#define SMMU_PAYLOAD_EN_UNSET 0x00
|
||||
|
||||
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
|
||||
static const u8 smmu_enable_payload[] = {
|
||||
static u8 smmu_enable_payload[] = {
|
||||
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
|
||||
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
|
||||
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
|
||||
@@ -67,6 +69,9 @@ static const u8 smmu_enable_payload[] = {
|
||||
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
|
||||
};
|
||||
|
||||
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
static bool smmu_enabled = false;
|
||||
|
||||
void *smmu_page_zalloc(u32 num)
|
||||
{
|
||||
void *page = smmu_heap;
|
||||
@@ -95,7 +100,6 @@ static void _smmu_flush_regs()
|
||||
|
||||
void smmu_flush_all()
|
||||
{
|
||||
|
||||
// Flush the entire page table cache.
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
_smmu_flush_regs();
|
||||
@@ -117,9 +121,7 @@ void smmu_init()
|
||||
|
||||
void smmu_enable()
|
||||
{
|
||||
static bool enabled = false;
|
||||
|
||||
if (enabled)
|
||||
if (smmu_enabled)
|
||||
return;
|
||||
|
||||
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||
@@ -129,7 +131,32 @@ void smmu_enable()
|
||||
|
||||
smmu_flush_all();
|
||||
|
||||
enabled = true;
|
||||
smmu_enabled = true;
|
||||
}
|
||||
|
||||
void smmu_disable()
|
||||
{
|
||||
if (!smmu_enabled)
|
||||
return;
|
||||
|
||||
// Set payload to disable SMMU.
|
||||
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_UNSET;
|
||||
|
||||
smmu_flush_all();
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
|
||||
msleep(100);
|
||||
ccplex_powergate_cpu0();
|
||||
|
||||
smmu_flush_all();
|
||||
|
||||
// Restore payload to SMMU enable.
|
||||
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_SET;
|
||||
|
||||
smmu_enabled = false;
|
||||
smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
}
|
||||
|
||||
void smmu_reset_heap()
|
||||
@@ -137,7 +164,7 @@ void smmu_reset_heap()
|
||||
smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
}
|
||||
|
||||
void *smmu_init_domain(u32 dev_base, u32 asid)
|
||||
void *smmu_domain_init(u32 dev_base, u32 asid)
|
||||
{
|
||||
void *ptb = _smmu_pdir_alloc();
|
||||
|
||||
@@ -152,7 +179,7 @@ void *smmu_init_domain(u32 dev_base, u32 asid)
|
||||
return ptb;
|
||||
}
|
||||
|
||||
void smmu_deinit_domain(u32 dev_base, u32 asid)
|
||||
void smmu_domain_deinit(u32 dev_base, u32 asid)
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = asid;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#ifndef _SMMU_H_
|
||||
#define _SMMU_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define MC_SMMU_AVPC_ASID 0x23C
|
||||
#define MC_SMMU_TSEC_ASID 0x294
|
||||
@@ -63,9 +65,12 @@ void *smmu_page_zalloc(u32 num);
|
||||
void smmu_flush_all();
|
||||
void smmu_init();
|
||||
void smmu_enable();
|
||||
void smmu_disable();
|
||||
void smmu_reset_heap();
|
||||
void *smmu_init_domain(u32 dev_base, u32 asid);
|
||||
void smmu_deinit_domain(u32 dev_base, u32 asid);
|
||||
void *smmu_domain_init(u32 dev_base, u32 asid);
|
||||
void smmu_domain_deinit(u32 dev_base, u32 asid);
|
||||
void smmu_domain_bypass(u32 dev_base, bool bypass);
|
||||
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
|
||||
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -29,6 +29,7 @@
|
||||
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
||||
|
||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||
#define SDRAM_PARAMS_SZ 0x838
|
||||
|
||||
/* start.S / exception_handlers.S */
|
||||
#define SYS_STACK_TOP_INIT 0x4003FF00
|
||||
@@ -36,7 +37,7 @@
|
||||
#define IRQ_STACK_TOP 0x40040000
|
||||
#define IPL_RELOC_ADDR 0x4003FF00
|
||||
#define IPL_RELOC_SZ 0x10
|
||||
#define EXCP_STORAGE_ADDR 0x4003FFF0
|
||||
#define EXCP_STORAGE_ADDR 0x4003FF10
|
||||
#define EXCP_STORAGE_SZ 0x10
|
||||
|
||||
/* --- DRAM START --- */
|
||||
@@ -47,45 +48,44 @@
|
||||
#define NYX_SZ_MAX SZ_16M
|
||||
/* --- Gap: 0x82000000 - 0x82FFFFFF --- */
|
||||
|
||||
/* Stack theoretical max: 33MB */
|
||||
#define IPL_STACK_TOP 0x83100000
|
||||
#define IPL_HEAP_START 0x84000000
|
||||
#define IPL_HEAP_SZ (SZ_512M - SZ_64M)
|
||||
// Heap buffer.
|
||||
#define IPL_HEAP_START 0x82000000
|
||||
#define IPL_HEAP_SZ (SZ_256M)
|
||||
|
||||
#define SMMU_HEAP_ADDR 0xA0000000
|
||||
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
|
||||
#define SMMU_HEAP_ADDR 0x92000000
|
||||
/* --- Gap: 1280MB 0x96000000 - 0xE4FFFFFF --- */
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
#define RAM_DISK_ADDR 0xA4000000
|
||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
||||
#define RAM_DISK2_SZ 0x21000000 // 528MB.
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xC5000000
|
||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||
#define NX_BIS_LOOKUP_ADDR 0xD6000000
|
||||
#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB.
|
||||
#define RAM_DISK_ADDR 0x95000000
|
||||
#define RAM_DISK_SZ 0x50000000 // 1280MB.
|
||||
|
||||
// L4T Kernel Panic Storage (PSTORE).
|
||||
#define PSTORE_ADDR 0xB0000000
|
||||
#define PSTORE_SZ SZ_2M
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xC7000000
|
||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||
#define NX_BIS_LOOKUP_ADDR 0xD8000000
|
||||
#define NX_BIS_LOOKUP_SZ 0x8000000 // 128MB. 512GB eMMC partition max.
|
||||
|
||||
//#define DRAM_LIB_ADDR 0xE0000000
|
||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||
|
||||
// SDMMC DMA buffers 1
|
||||
#define SDMMC_UPPER_BUFFER 0xE5000000
|
||||
#define SDMMC_UP_BUF_SZ SZ_128M
|
||||
// SDMMC DMA buffer. Used for unaligned DMA buffer address.
|
||||
#define SDMMC_ALT_DMA_BUFFER 0xE5000000
|
||||
#define SDMMC_ALT_DMA_BUF_SZ SZ_128M
|
||||
|
||||
// Nyx buffers.
|
||||
// Nyx buffers. !Do not change!
|
||||
#define NYX_STORAGE_ADDR 0xED000000
|
||||
#define NYX_STR_SZ SZ_16M
|
||||
#define NYX_RES_ADDR 0xEE000000
|
||||
#define NYX_RES_SZ SZ_16M
|
||||
|
||||
// SDMMC DMA buffers 2
|
||||
#define SDXC_BUF_ALIGNED 0xEF000000
|
||||
#define MIXD_BUF_ALIGNED 0xF0000000
|
||||
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||
// SDMMC Application DMA aligned buffers.
|
||||
#define SDXC_BUF_ALIGNED 0xEF000000 // Also used by UMS.
|
||||
#define EMMC_BUF_ALIGNED 0xF0000000
|
||||
#define MIXD_BUF_ALIGNED EMMC_BUF_ALIGNED
|
||||
#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
|
||||
|
||||
// Nyx LvGL buffers.
|
||||
@@ -94,7 +94,7 @@
|
||||
#define NYX_LV_MEM_ADR 0xF1400000
|
||||
#define NYX_LV_MEM_SZ 0x6600000 // 70MB.
|
||||
|
||||
// Framebuffer addresses.
|
||||
// Framebuffer addresses. !Do not change!
|
||||
#define IPL_FB_ADDRESS 0xF5A00000
|
||||
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
||||
#define LOG_FB_ADDRESS 0xF5E00000
|
||||
@@ -103,12 +103,6 @@
|
||||
#define NYX_FB2_ADDRESS 0xF6600000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
|
||||
/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */
|
||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
||||
#define DRAM_START2 0xFEB40000
|
||||
|
||||
// USB buffers.
|
||||
#define USBD_ADDR 0xFEF00000
|
||||
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
||||
@@ -119,6 +113,5 @@
|
||||
|
||||
// #define EXT_PAYLOAD_ADDR 0xC0000000
|
||||
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
// #define COREBOOT_ADDR (0xD0000000 - rom_size)
|
||||
|
||||
#endif
|
||||
|
||||
16
bdk/module.h
16
bdk/module.h
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Common Module Header
|
||||
* Copyright (c) 2018 M4xw
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -21,7 +22,7 @@
|
||||
#include <stddef.h>
|
||||
#include <mem/heap.h>
|
||||
|
||||
#define IANOS_EXT0 0x304E4149
|
||||
#define IANOS_EXT1 0x314E4149
|
||||
|
||||
// Module Callback
|
||||
typedef void (*cbMainModule_t)(const char *s);
|
||||
@@ -31,16 +32,15 @@ typedef int (*reg_voltage_set_t)(u32, u32);
|
||||
|
||||
typedef struct _bdkParams_t
|
||||
{
|
||||
void *gfxCon;
|
||||
void *gfxCtx;
|
||||
heap_t *sharedHeap;
|
||||
void *gfx_con;
|
||||
void *gfx_ctx;
|
||||
heap_t *heap;
|
||||
memcpy_t memcpy;
|
||||
memset_t memset;
|
||||
u32 extension_magic;
|
||||
reg_voltage_set_t reg_voltage_set;
|
||||
} *bdkParams_t;
|
||||
} bdk_params_t;
|
||||
|
||||
// Module Entrypoint
|
||||
typedef void (*moduleEntrypoint_t)(void *, bdkParams_t);
|
||||
// Module Caller.
|
||||
typedef void (*moduleEntrypoint)(void *, bdk_params_t *);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020-2023 CTCaer
|
||||
* Copyright (c) 2020-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -54,6 +54,15 @@
|
||||
|
||||
#define STATUS1_INSERT BIT(7) // Cable inserted.
|
||||
|
||||
#define VER_36 0x36
|
||||
#define MAN_ROHM 0x4B5
|
||||
#define DEV_BM92T 0x3B0
|
||||
|
||||
#define PDO_TYPE_FIXED 0
|
||||
#define PDO_TYPE_BATT 1
|
||||
#define PDO_TYPE_VAR 2
|
||||
#define PDO_TYPE_APDO 3
|
||||
|
||||
typedef struct _pd_object_t {
|
||||
unsigned int amp:10;
|
||||
unsigned int volt:10;
|
||||
@@ -63,24 +72,42 @@ typedef struct _pd_object_t {
|
||||
|
||||
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
|
||||
{
|
||||
memset(buf, 0, size);
|
||||
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
|
||||
}
|
||||
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
int bm92t36_get_version(u32 *value)
|
||||
{
|
||||
u8 buf[2];
|
||||
u16 version, man, dev;
|
||||
_bm92t36_read_reg(buf, 2, FW_TYPE_REG);
|
||||
version = (buf[0] << 4) | buf[1];
|
||||
_bm92t36_read_reg(buf, 2, MAN_ID_REG);
|
||||
man = (buf[1] << 8) | buf[0];
|
||||
_bm92t36_read_reg(buf, 2, DEV_ID_REG);
|
||||
dev = (buf[1] << 8) | buf[0];
|
||||
if (value)
|
||||
*value = (dev << 16) | version;
|
||||
|
||||
if (version == VER_36 && man == MAN_ROHM && dev == DEV_BM92T)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void bm92t36_get_source_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
{
|
||||
u8 buf[32];
|
||||
pd_object_t pdos[7];
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||
memcpy(pdos, &buf[1], 28);
|
||||
|
||||
@@ -90,15 +117,22 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
if (usb_pd->pdo_no > 7)
|
||||
usb_pd->pdo_no = 7;
|
||||
|
||||
u32 idx = 0;
|
||||
for (u32 i = 0; i < usb_pd->pdo_no; i++)
|
||||
{
|
||||
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
|
||||
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
|
||||
// Parse fixed type pdos only.
|
||||
if (pdos[i].type != PDO_TYPE_FIXED)
|
||||
continue;
|
||||
|
||||
usb_pd->pdos[idx].amperage = pdos[i].amp * 10;
|
||||
usb_pd->pdos[idx].voltage = (pdos[i].volt * 50) / 1000;
|
||||
idx++;
|
||||
}
|
||||
usb_pd->pdo_no = idx;
|
||||
|
||||
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
|
||||
memcpy(pdos, &buf[1], 4);
|
||||
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
|
||||
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
|
||||
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
|
||||
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct _usb_pd_objects_t
|
||||
usb_pd_object_t selected_pdo;
|
||||
} usb_pd_objects_t;
|
||||
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||
int bm92t36_get_version(u32 *value);
|
||||
void bm92t36_get_source_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -25,131 +25,144 @@ static u8 bq24193_get_reg(u8 reg)
|
||||
return i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, reg);
|
||||
}
|
||||
|
||||
int bq24193_get_version(u32 *value)
|
||||
{
|
||||
u16 data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
if (value)
|
||||
*value = data;
|
||||
|
||||
if (data == 0x2F)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
switch (prop) {
|
||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_InputSource);
|
||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 80 : 0;
|
||||
*value += ((data >> 1) & 1) ? 160 : 0;
|
||||
*value += ((data >> 2) & 1) ? 320 : 0;
|
||||
*value += ((data >> 3) & 1) ? 640 : 0;
|
||||
*value += 3880;
|
||||
switch (prop)
|
||||
{
|
||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_InputSource);
|
||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 80 : 0;
|
||||
*value += ((data >> 1) & 1) ? 160 : 0;
|
||||
*value += ((data >> 2) & 1) ? 320 : 0;
|
||||
*value += ((data >> 3) & 1) ? 640 : 0;
|
||||
*value += 3880;
|
||||
break;
|
||||
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
||||
data = bq24193_get_reg(BQ24193_InputSource);
|
||||
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 100;
|
||||
break;
|
||||
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
||||
data = bq24193_get_reg(BQ24193_InputSource);
|
||||
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 100;
|
||||
break;
|
||||
case 1:
|
||||
*value = 150;
|
||||
break;
|
||||
case 2:
|
||||
*value = 500;
|
||||
break;
|
||||
case 3:
|
||||
*value = 900;
|
||||
break;
|
||||
case 4:
|
||||
*value = 1200;
|
||||
break;
|
||||
case 5:
|
||||
*value = 1500;
|
||||
break;
|
||||
case 6:
|
||||
*value = 2000;
|
||||
break;
|
||||
case 7:
|
||||
*value = 3000;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
*value = 150;
|
||||
break;
|
||||
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_PORConfig);
|
||||
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
||||
*value *= 100;
|
||||
*value += 3000;
|
||||
case 2:
|
||||
*value = 500;
|
||||
break;
|
||||
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 64 : 0;
|
||||
*value += ((data >> 1) & 1) ? 128 : 0;
|
||||
*value += ((data >> 2) & 1) ? 256 : 0;
|
||||
*value += ((data >> 3) & 1) ? 512 : 0;
|
||||
*value += ((data >> 4) & 1) ? 1024 : 0;
|
||||
*value += ((data >> 5) & 1) ? 2048 : 0;
|
||||
*value += 512;
|
||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
||||
if (data)
|
||||
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
||||
case 3:
|
||||
*value = 900;
|
||||
break;
|
||||
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 16 : 0;
|
||||
*value += ((data >> 1) & 1) ? 32 : 0;
|
||||
*value += ((data >> 2) & 1) ? 64 : 0;
|
||||
*value += ((data >> 3) & 1) ? 128 : 0;
|
||||
*value += ((data >> 4) & 1) ? 256 : 0;
|
||||
*value += ((data >> 5) & 1) ? 512 : 0;
|
||||
*value += 3504;
|
||||
case 4:
|
||||
*value = 1200;
|
||||
break;
|
||||
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
if (data)
|
||||
*value = 300;
|
||||
else
|
||||
*value = 100;
|
||||
case 5:
|
||||
*value = 1500;
|
||||
break;
|
||||
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
||||
data = bq24193_get_reg(BQ24193_IRCompThermal);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 60;
|
||||
break;
|
||||
case 1:
|
||||
*value = 80;
|
||||
break;
|
||||
case 2:
|
||||
*value = 100;
|
||||
break;
|
||||
case 3:
|
||||
*value = 120;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
*value = 2000;
|
||||
break;
|
||||
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
||||
data = bq24193_get_reg(BQ24193_Status);
|
||||
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
||||
case 7:
|
||||
*value = 3000;
|
||||
break;
|
||||
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
||||
data = bq24193_get_reg(BQ24193_FaultReg);
|
||||
*value = data & BQ24193_FAULT_THERM_MASK;
|
||||
}
|
||||
break;
|
||||
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_PORConfig);
|
||||
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
||||
*value *= 100;
|
||||
*value += 3000;
|
||||
break;
|
||||
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 64 : 0;
|
||||
*value += ((data >> 1) & 1) ? 128 : 0;
|
||||
*value += ((data >> 2) & 1) ? 256 : 0;
|
||||
*value += ((data >> 3) & 1) ? 512 : 0;
|
||||
*value += ((data >> 4) & 1) ? 1024 : 0;
|
||||
*value += ((data >> 5) & 1) ? 2048 : 0;
|
||||
*value += 512;
|
||||
data = bq24193_get_reg(BQ24193_ChrgCurr);
|
||||
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
||||
if (data)
|
||||
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
||||
break;
|
||||
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
||||
*value = 0;
|
||||
*value += ((data >> 0) & 1) ? 16 : 0;
|
||||
*value += ((data >> 1) & 1) ? 32 : 0;
|
||||
*value += ((data >> 2) & 1) ? 64 : 0;
|
||||
*value += ((data >> 3) & 1) ? 128 : 0;
|
||||
*value += ((data >> 4) & 1) ? 256 : 0;
|
||||
*value += ((data >> 5) & 1) ? 512 : 0;
|
||||
*value += 3504;
|
||||
break;
|
||||
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
||||
data = bq24193_get_reg(BQ24193_ChrgVolt);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
if (data)
|
||||
*value = 300;
|
||||
else
|
||||
*value = 100;
|
||||
break;
|
||||
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
||||
data = bq24193_get_reg(BQ24193_IRCompThermal);
|
||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
*value = 60;
|
||||
break;
|
||||
case BQ24193_DevID: // Dev ID.
|
||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
||||
case 1:
|
||||
*value = 80;
|
||||
break;
|
||||
case BQ24193_ProductNumber: // Product number.
|
||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
||||
case 2:
|
||||
*value = 100;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
case 3:
|
||||
*value = 120;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
||||
data = bq24193_get_reg(BQ24193_Status);
|
||||
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
||||
break;
|
||||
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
||||
data = bq24193_get_reg(BQ24193_FaultReg);
|
||||
*value = data & BQ24193_FAULT_THERM_MASK;
|
||||
break;
|
||||
case BQ24193_DevID: // Dev ID.
|
||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
||||
break;
|
||||
case BQ24193_ProductNumber: // Product number.
|
||||
data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef __BQ24193_H_
|
||||
#define __BQ24193_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
// REG 0 masks.
|
||||
@@ -114,7 +116,8 @@ enum BQ24193_reg_prop {
|
||||
BQ24193_ProductNumber, // REG A.
|
||||
};
|
||||
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
||||
int bq24193_get_version(u32 *value);
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
||||
void bq24193_enable_charger();
|
||||
void bq24193_fake_battery_removal();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,7 +26,13 @@
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define BASE_SNS_UOHM 5000
|
||||
/* Board default values */
|
||||
#define BOARD_CGAIN 2 /* Actual: 1.99993 */
|
||||
#define BOARD_RSENSE_MOHM 5 /* 0.005 Ohm */
|
||||
#define ADJ_RSENSE_MOHM (BOARD_RSENSE_MOHM * BOARD_CGAIN) /* 0.01 Ohm */
|
||||
|
||||
/* Consider RepCap which is less then 10 units below FullCAP full */
|
||||
#define FULL_THRESHOLD 10
|
||||
|
||||
/* Status register bits */
|
||||
#define STATUS_POR_BIT BIT(1)
|
||||
@@ -45,12 +51,6 @@
|
||||
|
||||
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
|
||||
|
||||
static u32 battery_voltage = 0;
|
||||
u32 max17050_get_cached_batt_volt()
|
||||
{
|
||||
return battery_voltage;
|
||||
}
|
||||
|
||||
static u16 max17050_get_reg(u8 reg)
|
||||
{
|
||||
u16 data = 0;
|
||||
@@ -60,6 +60,18 @@ static u16 max17050_get_reg(u8 reg)
|
||||
return data;
|
||||
}
|
||||
|
||||
int max17050_get_version(u32 *value)
|
||||
{
|
||||
u16 data = max17050_get_reg(MAX17050_DevName);
|
||||
if (value)
|
||||
*value = data;
|
||||
|
||||
if (data == 0x00AC)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
{
|
||||
u16 data;
|
||||
@@ -88,7 +100,6 @@ int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
case MAX17050_VCELL: // Voltage now.
|
||||
data = max17050_get_reg(MAX17050_VCELL);
|
||||
*value = (data >> 3) * 625 / 1000; /* Units of LSB = 0.625mV */
|
||||
battery_voltage = *value;
|
||||
break;
|
||||
case MAX17050_AvgVCELL: // Voltage avg.
|
||||
data = max17050_get_reg(MAX17050_AvgVCELL);
|
||||
@@ -103,15 +114,15 @@ int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
break;
|
||||
case MAX17050_DesignCap: // Charge full design.
|
||||
data = max17050_get_reg(MAX17050_DesignCap);
|
||||
*value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
|
||||
*value = (u32)data * 5 / ADJ_RSENSE_MOHM; /* Units of LSB = 5uVh / Rsense = 0.5mAh */
|
||||
break;
|
||||
case MAX17050_FullCAP: // Charge full.
|
||||
data = max17050_get_reg(MAX17050_FullCAP);
|
||||
*value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
|
||||
*value = (u32)data * 5 / ADJ_RSENSE_MOHM; /* Units of LSB = 5uVh / Rsense = 0.5mAh */
|
||||
break;
|
||||
case MAX17050_RepCap: // Charge now.
|
||||
data = max17050_get_reg(MAX17050_RepCap);
|
||||
*value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
|
||||
*value = (u32)data * 5 / ADJ_RSENSE_MOHM; /* Units of LSB = 5uVh / Rsense = 0.5mAh */
|
||||
break;
|
||||
case MAX17050_TEMP: // Temp.
|
||||
data = max17050_get_reg(MAX17050_TEMP);
|
||||
@@ -120,16 +131,14 @@ int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
break;
|
||||
case MAX17050_Current: // Current now.
|
||||
data = max17050_get_reg(MAX17050_Current);
|
||||
*value = (s16)data;
|
||||
*value *= 1562500 / (MAX17050_BOARD_SNS_RESISTOR_UOHM * MAX17050_BOARD_CGAIN);
|
||||
*value = (int)(s16)data * 15625 / ADJ_RSENSE_MOHM / 10; /* Units of LSB = 1.5625uV / Rsense = 156.25uA */
|
||||
break;
|
||||
case MAX17050_AvgCurrent: // Current avg.
|
||||
data = max17050_get_reg(MAX17050_AvgCurrent);
|
||||
*value = (s16)data;
|
||||
*value *= 1562500 / (MAX17050_BOARD_SNS_RESISTOR_UOHM * MAX17050_BOARD_CGAIN);
|
||||
*value = (int)(s16)data * 15625 / ADJ_RSENSE_MOHM / 10; /* Units of LSB = 1.5625uV / Rsense = 156.25uA */
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -138,18 +147,14 @@ static int _max17050_write_verify_reg(u8 reg, u16 value)
|
||||
{
|
||||
int retries = 8;
|
||||
int ret;
|
||||
u16 read_value;
|
||||
|
||||
do
|
||||
{
|
||||
ret = i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);
|
||||
read_value = max17050_get_reg(reg);
|
||||
if (read_value != value)
|
||||
{
|
||||
ret = -1;
|
||||
retries--;
|
||||
}
|
||||
} while (retries && read_value != value);
|
||||
u16 read_value = max17050_get_reg(reg);
|
||||
if (!ret && read_value == value)
|
||||
break;
|
||||
} while (--retries);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -242,7 +247,7 @@ static void _max17050_set_por_bit(u16 value)
|
||||
_max17050_write_verify_reg(MAX17050_STATUS, value);
|
||||
}
|
||||
|
||||
int max17050_fix_configuration()
|
||||
void max17050_fix_configuration()
|
||||
{
|
||||
/* Init phase, set the POR bit */
|
||||
_max17050_set_por_bit(STATUS_POR_BIT);
|
||||
@@ -276,8 +281,6 @@ int max17050_fix_configuration()
|
||||
|
||||
// Sets POR, BI, BR.
|
||||
_max17050_set_por_bit(0x8801);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void max17050_dump_regs(void *buf)
|
||||
|
||||
@@ -25,17 +25,6 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
/* Board default values */
|
||||
#define MAX17050_BOARD_CGAIN 2 /* Actual: 1.99993 */
|
||||
#define MAX17050_BOARD_SNS_RESISTOR_UOHM 5000 /* 0.005 Ohm */
|
||||
|
||||
#define MAX17050_STATUS_BattAbsent BIT(3)
|
||||
|
||||
/* Consider RepCap which is less then 10 units below FullCAP full */
|
||||
#define MAX17050_FULL_THRESHOLD 10
|
||||
|
||||
#define MAX17050_CHARACTERIZATION_DATA_SIZE 48
|
||||
|
||||
#define MAXIM17050_I2C_ADDR 0x36
|
||||
|
||||
enum MAX17050_reg {
|
||||
@@ -130,9 +119,9 @@ enum MAX17050_reg {
|
||||
MAX17050_VFSOC = 0xFF,
|
||||
};
|
||||
|
||||
int max17050_get_version(u32 *value);
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||
int max17050_fix_configuration();
|
||||
void max17050_fix_configuration();
|
||||
void max17050_dump_regs(void *buf);
|
||||
u32 max17050_get_cached_batt_volt();
|
||||
|
||||
#endif /* __MAX17050_H_ */
|
||||
|
||||
@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
|
||||
|
||||
static const max77620_regulator_t _pmic_regulators[] = {
|
||||
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
|
||||
{ "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||
{ "sd1", 12500, 600000, 1125000, 1300000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
|
||||
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
|
||||
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
|
||||
@@ -137,7 +137,7 @@ static void _max7762x_set_reg(u8 addr, u8 reg, u8 val)
|
||||
u32 retries = 100;
|
||||
while (retries)
|
||||
{
|
||||
if (i2c_send_byte(I2C_5, addr, reg, val))
|
||||
if (!i2c_send_byte(I2C_5, addr, reg, val))
|
||||
break;
|
||||
|
||||
usleep(50);
|
||||
@@ -166,7 +166,7 @@ int max77620_regulator_get_status(u32 id)
|
||||
int max77620_regulator_config_fps(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_LDO8)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
@@ -177,22 +177,22 @@ int max77620_regulator_config_fps(u32 id)
|
||||
(reg->fps.pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) |
|
||||
(reg->fps.pd_period << MAX77620_FPS_PD_PERIOD_SHIFT));
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 uv)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (uv < reg->uv_min || uv > reg->uv_max)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
// Calculate voltage multiplier.
|
||||
u32 mult = (uv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
|
||||
@@ -209,7 +209,7 @@ int max7762x_regulator_set_voltage(u32 id, u32 uv)
|
||||
// Wait for ramp up/down delay.
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int max7762x_regulator_enable(u32 id, bool enable)
|
||||
@@ -220,7 +220,7 @@ int max7762x_regulator_enable(u32 id, bool enable)
|
||||
u8 enable_shift;
|
||||
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
@@ -252,12 +252,12 @@ int max7762x_regulator_enable(u32 id, bool enable)
|
||||
enable_shift = reg->enable.shift;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
// Read and enable/disable.
|
||||
u8 val = i2c_recv_byte(I2C_5, addr, reg_addr);
|
||||
@@ -272,7 +272,7 @@ int max7762x_regulator_enable(u32 id, bool enable)
|
||||
// Wait for enable/disable ramp delay.
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void max77620_config_gpio(u32 gpio_id, bool enable)
|
||||
@@ -327,7 +327,7 @@ void max77620_config_default()
|
||||
return;
|
||||
|
||||
// Set default voltages and enable regulators.
|
||||
for (u32 i = 1; i <= REGULATOR_LDO8; i++)
|
||||
for (u32 i = REGULATOR_SD1; i <= REGULATOR_LDO8; i++)
|
||||
{
|
||||
max77620_regulator_config_fps(i);
|
||||
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2019 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -23,7 +23,8 @@
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
int epoch_offset = 0;
|
||||
bool auto_dst = false;
|
||||
int epoch_offset = 0;
|
||||
|
||||
void max77620_rtc_prep_read()
|
||||
{
|
||||
@@ -39,20 +40,24 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
||||
|
||||
// Get control reg config.
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG);
|
||||
// TODO: Check for binary format also?
|
||||
// TODO: Make also sure it's binary format?
|
||||
|
||||
// Get time.
|
||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG) & 0x1F;
|
||||
time->hour = hour & 0x1F;
|
||||
|
||||
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
|
||||
time->hour = (time->hour & 0xF) + 12;
|
||||
if (!(val & MAX77620_RTC_24H))
|
||||
{
|
||||
time->hour = hour & 0xF;
|
||||
if (hour & MAX77620_RTC_HOUR_PM_MASK)
|
||||
time->hour += 12;
|
||||
}
|
||||
|
||||
// Get day of week. 1: Monday to 7: Sunday.
|
||||
time->weekday = 0;
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG);
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG) & 0x7F;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
time->weekday++;
|
||||
@@ -62,8 +67,9 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
||||
}
|
||||
|
||||
// Get date.
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DAY_REG) & 0x1F;
|
||||
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
||||
time->month++; // Normally minus 1, but everything else expects 1 as January.
|
||||
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
||||
}
|
||||
|
||||
@@ -126,7 +132,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
||||
time->day = day;
|
||||
|
||||
// Set weekday.
|
||||
time->weekday = 0; //! TODO.
|
||||
time->weekday = (day + 4) % 7;
|
||||
}
|
||||
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
||||
@@ -162,10 +168,21 @@ void max77620_rtc_get_time_adjusted(rtc_time_t *time)
|
||||
if (epoch_offset)
|
||||
{
|
||||
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
|
||||
|
||||
// Adjust for DST between 28 march and 28 october. Good enough to cover all years as week info is not valid.
|
||||
u16 md = (time->month << 8) | time->day;
|
||||
if (auto_dst && md >= 0x31C && md < 0xA1C)
|
||||
epoch += 3600;
|
||||
|
||||
max77620_rtc_epoch_to_date(epoch, time);
|
||||
}
|
||||
}
|
||||
|
||||
void max77620_rtc_set_auto_dst(bool enable)
|
||||
{
|
||||
auto_dst = enable;
|
||||
}
|
||||
|
||||
void max77620_rtc_set_epoch_offset(int offset)
|
||||
{
|
||||
epoch_offset = offset;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define MAX77620_RTC_WEEKDAY_REG 0x0A
|
||||
#define MAX77620_RTC_MONTH_REG 0x0B
|
||||
#define MAX77620_RTC_YEAR_REG 0x0C
|
||||
#define MAX77620_RTC_DATE_REG 0x0D
|
||||
#define MAX77620_RTC_DAY_REG 0x0D
|
||||
|
||||
#define MAX77620_ALARM1_SEC_REG 0x0E
|
||||
#define MAX77620_ALARM1_MIN_REG 0x0F
|
||||
@@ -111,6 +111,7 @@ void max77620_rtc_prep_read();
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
|
||||
void max77620_rtc_set_epoch_offset(int offset);
|
||||
void max77620_rtc_set_auto_dst(bool enable);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
|
||||
607
bdk/sec/se.c
607
bdk/sec/se.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "se.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
@@ -28,60 +27,54 @@
|
||||
|
||||
typedef struct _se_ll_t
|
||||
{
|
||||
vu32 num;
|
||||
vu32 addr;
|
||||
vu32 size;
|
||||
u32 num;
|
||||
u32 addr;
|
||||
u32 size;
|
||||
} se_ll_t;
|
||||
|
||||
se_ll_t ll_src, ll_dst;
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
|
||||
se_ll_t ll_src, ll_dst; // Must be u32 aligned.
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr;
|
||||
|
||||
static void _gf256_mul_x(void *block)
|
||||
static void _se_ls_1bit(void *buf)
|
||||
{
|
||||
u8 *pdata = (u8 *)block;
|
||||
u8 *block = (u8 *)buf;
|
||||
u32 carry = 0;
|
||||
|
||||
for (int i = 0xF; i >= 0; i--)
|
||||
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
|
||||
{
|
||||
u8 b = pdata[i];
|
||||
pdata[i] = (b << 1) | carry;
|
||||
u8 b = block[i];
|
||||
block[i] = (b << 1) | carry;
|
||||
carry = b >> 7;
|
||||
}
|
||||
|
||||
if (carry)
|
||||
pdata[0xF] ^= 0x87;
|
||||
block[SE_AES_BLOCK_SIZE - 1] ^= 0x87;
|
||||
}
|
||||
|
||||
static void _gf256_mul_x_le(void *block)
|
||||
static void _se_ls_1bit_le(void *buf)
|
||||
{
|
||||
u32 *pdata = (u32 *)block;
|
||||
u32 *block = (u32 *)buf;
|
||||
u32 carry = 0;
|
||||
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
{
|
||||
u32 b = pdata[i];
|
||||
pdata[i] = (b << 1) | carry;
|
||||
u32 b = block[i];
|
||||
block[i] = (b << 1) | carry;
|
||||
carry = b >> 31;
|
||||
}
|
||||
|
||||
if (carry)
|
||||
pdata[0x0] ^= 0x87;
|
||||
block[0x0] ^= 0x87;
|
||||
}
|
||||
|
||||
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
|
||||
static void _se_ll_set(se_ll_t *ll, u32 addr, u32 size)
|
||||
{
|
||||
ll->num = 0;
|
||||
ll->addr = addr;
|
||||
ll->size = size;
|
||||
ll->size = size & 0xFFFFFF;
|
||||
}
|
||||
|
||||
static void _se_ll_set(se_ll_t *src, se_ll_t *dst)
|
||||
{
|
||||
SE(SE_IN_LL_ADDR_REG) = (u32)src;
|
||||
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
|
||||
}
|
||||
|
||||
static int _se_wait()
|
||||
static int _se_op_wait()
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
@@ -95,69 +88,77 @@ static int _se_wait()
|
||||
(SE(SE_ERR_STATUS_REG) != 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// T210B01: IRAM/TZRAM/DRAM AHB coherency WAR.
|
||||
if (!tegra_t210 && ll_dst_ptr)
|
||||
// WAR: Coherency flushing.
|
||||
if (ll_dst_ptr)
|
||||
{
|
||||
u32 timeout = get_tmr_us() + 1000000;
|
||||
// Ensure data is out from SE.
|
||||
while (SE(SE_STATUS_REG) & SE_STATUS_MEM_IF_BUSY)
|
||||
if (tegra_t210)
|
||||
usleep(15); // Worst case scenario.
|
||||
else
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
usleep(1);
|
||||
// T210B01 has a status bit for that.
|
||||
u32 retries = 500000;
|
||||
while (SE(SE_STATUS_REG) & SE_STATUS_MEM_IF_BUSY)
|
||||
{
|
||||
if (!retries)
|
||||
return 1;
|
||||
usleep(1);
|
||||
retries--;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure data is out from AHB.
|
||||
if (ll_dst_ptr->addr >= DRAM_START)
|
||||
u32 retries = 500000;
|
||||
while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID)
|
||||
{
|
||||
timeout = get_tmr_us() + 200000;
|
||||
while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID)
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
usleep(1);
|
||||
}
|
||||
if (!retries)
|
||||
return 1;
|
||||
usleep(1);
|
||||
retries--;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _se_execute_finalize()
|
||||
{
|
||||
int res = _se_wait();
|
||||
int res = _se_op_wait();
|
||||
|
||||
// Invalidate data after OP is done.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
if (dst_size > SE_LL_MAX_SIZE || src_size > SE_LL_MAX_SIZE)
|
||||
return 1;
|
||||
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src_ptr = &ll_src;
|
||||
_se_ll_init(ll_src_ptr, (u32)src, src_size);
|
||||
_se_ll_set(ll_src_ptr, (u32)src, src_size);
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst_ptr = &ll_dst;
|
||||
_se_ll_init(ll_dst_ptr, (u32)dst, dst_size);
|
||||
_se_ll_set(ll_dst_ptr, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_src_ptr, ll_dst_ptr);
|
||||
// Set linked list pointers.
|
||||
SE(SE_IN_LL_ADDR_REG) = (u32)ll_src_ptr;
|
||||
SE(SE_OUT_LL_ADDR_REG) = (u32)ll_dst_ptr;
|
||||
|
||||
// Clear status.
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
@@ -169,7 +170,7 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
|
||||
if (is_oneshot)
|
||||
return _se_execute_finalize();
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
@@ -177,36 +178,58 @@ static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src,
|
||||
return _se_execute(op, dst, dst_size, src, src_size, true);
|
||||
}
|
||||
|
||||
static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
static int _se_execute_aes_oneshot(void *dst, const void *src, u32 size)
|
||||
{
|
||||
if (!src || !dst)
|
||||
return 0;
|
||||
// Set optional memory interface.
|
||||
if (dst >= (void *)DRAM_START && src >= (void *)DRAM_START)
|
||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_MEMIF(MEMIF_MCCIF);
|
||||
|
||||
u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
u32 size_aligned = ALIGN_DOWN(size, SE_AES_BLOCK_SIZE);
|
||||
u32 size_residue = size % SE_AES_BLOCK_SIZE;
|
||||
int res = 0;
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
// Handle initial aligned message.
|
||||
if (size_aligned)
|
||||
{
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (size >> 4) - 1;
|
||||
|
||||
memcpy(block, src, src_size);
|
||||
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
||||
memcpy(dst, block, dst_size);
|
||||
res = _se_execute_oneshot(SE_OP_START, dst, size_aligned, src, size_aligned);
|
||||
}
|
||||
|
||||
// Handle leftover partial message.
|
||||
if (!res && size_residue)
|
||||
{
|
||||
// Copy message to a block sized buffer in case it's partial.
|
||||
u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||
memcpy(block, src + size_aligned, size_residue);
|
||||
|
||||
// Use updated IV for CBC and OFB. Ignored on others.
|
||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1;
|
||||
|
||||
res = _se_execute_oneshot(SE_OP_START, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
|
||||
|
||||
// Copy result back.
|
||||
memcpy(dst + size_aligned, block, size_residue);
|
||||
}
|
||||
|
||||
free(block);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _se_aes_ctr_set(const void *ctr)
|
||||
static void _se_aes_counter_set(const void *ctr)
|
||||
{
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
u32 data[SE_AES_IV_SIZE / sizeof(u32)];
|
||||
memcpy(data, ctr, SE_AES_IV_SIZE);
|
||||
|
||||
for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++)
|
||||
SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i];
|
||||
SE(SE_CRYPTO_LINEAR_CTR_REG + sizeof(u32) * i) = data[i];
|
||||
}
|
||||
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||
{
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG + sizeof(u32) * rs) =
|
||||
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||
SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG;
|
||||
if (flags & SE_RSA_KEY_LOCK_FLAG)
|
||||
@@ -216,35 +239,37 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||
{
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags;
|
||||
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks) = ~flags;
|
||||
if (flags & SE_KEY_LOCK_FLAG)
|
||||
SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks);
|
||||
}
|
||||
|
||||
u32 se_key_acc_ctrl_get(u32 ks)
|
||||
{
|
||||
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
|
||||
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks);
|
||||
}
|
||||
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size)
|
||||
{
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
|
||||
memcpy(data, key, size);
|
||||
|
||||
for (u32 i = 0; i < (size / 4); i++)
|
||||
for (u32 i = 0; i < (size / sizeof(u32)); i++)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_set(u32 ks, const void *iv)
|
||||
void se_aes_iv_set(u32 ks, const void *iv, u32 size)
|
||||
{
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
memcpy(data, iv, SE_AES_IV_SIZE);
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
|
||||
memcpy(data, iv, size);
|
||||
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (size / sizeof(u32)); i++)
|
||||
{
|
||||
// QUAD UPDATED_IV bit is automatically set by PKT macro.
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
|
||||
}
|
||||
@@ -252,11 +277,12 @@ void se_aes_iv_set(u32 ks, const void *iv)
|
||||
|
||||
void se_aes_key_get(u32 ks, void *key, u32 size)
|
||||
{
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / 4];
|
||||
u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
|
||||
|
||||
for (u32 i = 0; i < (size / 4); i++)
|
||||
for (u32 i = 0; i < (size / sizeof(u32)); i++)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
|
||||
data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG);
|
||||
}
|
||||
|
||||
@@ -265,165 +291,130 @@ void se_aes_key_get(u32 ks, void *key, u32 size)
|
||||
|
||||
void se_aes_key_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / sizeof(u32)); i++)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
|
||||
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / sizeof(u32)); i++)
|
||||
{
|
||||
// QUAD UPDATED_IV bit is automatically set by PKT macro.
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_iv_updated_clear(u32 ks)
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed)
|
||||
{
|
||||
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1;
|
||||
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
|
||||
return _se_execute_oneshot(SE_OP_START, NULL, 0, seed, SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
int se_aes_crypt_ecb(u32 ks, int enc, void *dst, const void *src, u32 size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
|
||||
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BYPASS);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
|
||||
SE_CRYPTO_HASH(HASH_ENABLE);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BYPASS);
|
||||
}
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
|
||||
return _se_execute_aes_oneshot(dst, src, size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
int se_aes_crypt_cbc(u32 ks, int enc, void *dst, const void *src, u32 size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
}
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
}
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
|
||||
return _se_execute_aes_oneshot(dst, src, size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
|
||||
int se_aes_crypt_ofb(u32 ks, void *dst, const void *src, u32 size)
|
||||
{
|
||||
return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE);
|
||||
SE(SE_SPARE_REG) = SE_INPUT_NONCE_LE;
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
|
||||
return _se_execute_aes_oneshot(dst, src, size);
|
||||
}
|
||||
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, const void *src, u32 size, void *ctr)
|
||||
{
|
||||
SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
|
||||
SE(SE_SPARE_REG) = SE_INPUT_NONCE_LE;
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
|
||||
SE_CRYPTO_CTR_CNTN(1);
|
||||
_se_aes_ctr_set(ctr);
|
||||
|
||||
u32 src_size_aligned = src_size & 0xFFFFFFF0;
|
||||
u32 src_size_delta = src_size & 0xF;
|
||||
_se_aes_counter_set(ctr);
|
||||
|
||||
if (src_size_aligned)
|
||||
{
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_size - src_size_aligned && src_size_aligned < dst_size)
|
||||
return _se_execute_one_block(SE_OP_START, dst + src_size_aligned,
|
||||
MIN(src_size_delta, dst_size - src_size_aligned),
|
||||
src + src_size_aligned, src_size_delta);
|
||||
|
||||
return 1;
|
||||
return _se_execute_aes_oneshot(dst, src, size);
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||
int se_aes_crypt_xts_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||
u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
|
||||
u8 *tweak = (u8 *)tmp;
|
||||
u8 *pdst = (u8 *)dst;
|
||||
u8 *psrc = (u8 *)src;
|
||||
|
||||
// Generate tweak.
|
||||
for (int i = 0xF; i >= 0; i--)
|
||||
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
|
||||
{
|
||||
tweak[i] = sec & 0xFF;
|
||||
sec >>= 8;
|
||||
}
|
||||
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||
goto out;
|
||||
if (se_aes_crypt_ecb(tweak_ks, ENCRYPT, tweak, tweak, SE_AES_BLOCK_SIZE))
|
||||
return 1;
|
||||
|
||||
// We are assuming a 0x10-aligned sector size in this implementation.
|
||||
for (u32 i = 0; i < secsize / SE_AES_BLOCK_SIZE; i++)
|
||||
{
|
||||
for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
|
||||
pdst[j] = psrc[j] ^ tweak[j];
|
||||
if (!se_aes_crypt_block_ecb(crypt_ks, enc, pdst, pdst))
|
||||
goto out;
|
||||
|
||||
if (se_aes_crypt_ecb(crypt_ks, enc, pdst, pdst, SE_AES_BLOCK_SIZE))
|
||||
return 1;
|
||||
|
||||
for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
|
||||
pdst[j] = pdst[j] ^ tweak[j];
|
||||
_gf256_mul_x(tweak);
|
||||
|
||||
_se_ls_1bit(tweak);
|
||||
psrc += SE_AES_BLOCK_SIZE;
|
||||
pdst += SE_AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
free(tweak);
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size)
|
||||
int se_aes_crypt_xts_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size)
|
||||
{
|
||||
u32 *pdst = (u32 *)dst;
|
||||
u32 *psrc = (u32 *)src;
|
||||
@@ -431,18 +422,18 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
|
||||
|
||||
if (regen_tweak)
|
||||
{
|
||||
for (int i = 0xF; i >= 0; i--)
|
||||
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
|
||||
{
|
||||
tweak[i] = sec & 0xFF;
|
||||
sec >>= 8;
|
||||
}
|
||||
if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
|
||||
return 0;
|
||||
if (se_aes_crypt_ecb(tweak_ks, ENCRYPT, tweak, tweak, SE_AES_BLOCK_SIZE))
|
||||
return 1;
|
||||
}
|
||||
|
||||
// tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls.
|
||||
// tweak_exp allows using a saved tweak to reduce _se_ls_1bit_le calls.
|
||||
for (u32 i = 0; i < (tweak_exp << 5); i++)
|
||||
_gf256_mul_x_le(tweak);
|
||||
_se_ls_1bit_le(tweak);
|
||||
|
||||
u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4)));
|
||||
memcpy(orig_tweak, tweak, SE_KEY_128_SIZE);
|
||||
@@ -450,154 +441,181 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
|
||||
// We are assuming a 16 sector aligned size in this implementation.
|
||||
for (u32 i = 0; i < (sec_size >> 4); i++)
|
||||
{
|
||||
for (u32 j = 0; j < 4; j++)
|
||||
for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++)
|
||||
pdst[j] = psrc[j] ^ ptweak[j];
|
||||
|
||||
_gf256_mul_x_le(tweak);
|
||||
psrc += 4;
|
||||
pdst += 4;
|
||||
_se_ls_1bit_le(tweak);
|
||||
psrc += sizeof(u32);
|
||||
pdst += sizeof(u32);
|
||||
}
|
||||
|
||||
if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size))
|
||||
return 0;
|
||||
if (se_aes_crypt_ecb(crypt_ks, enc, dst, dst, sec_size))
|
||||
return 1;
|
||||
|
||||
pdst = (u32 *)dst;
|
||||
ptweak = (u32 *)orig_tweak;
|
||||
for (u32 i = 0; i < (sec_size >> 4); i++)
|
||||
{
|
||||
for (u32 j = 0; j < 4; j++)
|
||||
for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++)
|
||||
pdst[j] = pdst[j] ^ ptweak[j];
|
||||
|
||||
_gf256_mul_x_le(orig_tweak);
|
||||
pdst += 4;
|
||||
_se_ls_1bit_le(orig_tweak);
|
||||
pdst += sizeof(u32);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
|
||||
int se_aes_crypt_xts(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
|
||||
{
|
||||
u8 *pdst = (u8 *)dst;
|
||||
u8 *psrc = (u8 *)src;
|
||||
|
||||
for (u32 i = 0; i < num_secs; i++)
|
||||
if (!se_aes_xts_crypt_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
|
||||
return 0;
|
||||
if (se_aes_crypt_xts_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
|
||||
static void _se_sha_hash_256_get_hash(void *hash)
|
||||
{
|
||||
u32 hash32[SE_SHA_256_SIZE / 4];
|
||||
|
||||
// Backup message left.
|
||||
if (msg_left)
|
||||
{
|
||||
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
|
||||
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
|
||||
}
|
||||
|
||||
// Copy output hash.
|
||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
|
||||
u32 hash32[SE_SHA_256_SIZE / sizeof(u32)];
|
||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / sizeof(u32)); i++)
|
||||
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + sizeof(u32) * i));
|
||||
memcpy(hash, hash32, SE_SHA_256_SIZE);
|
||||
}
|
||||
|
||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
|
||||
static int _se_sha_hash_256(void *hash, u64 total_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
int res;
|
||||
u32 hash32[SE_SHA_256_SIZE / 4];
|
||||
|
||||
//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256.
|
||||
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
|
||||
return 0;
|
||||
|
||||
// Src size of 0 is not supported, so return null string sha256.
|
||||
// if (!src_size)
|
||||
// {
|
||||
// const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
// };
|
||||
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||
// return 1;
|
||||
// }
|
||||
if (!src_size)
|
||||
{
|
||||
const u8 null_hash[SE_SHA_256_SIZE] = {
|
||||
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
||||
0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
};
|
||||
memcpy(hash, null_hash, SE_SHA_256_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Increase leftover size if not last message. (Engine will always stop at src_size.)
|
||||
u32 msg_left = src_size;
|
||||
if (total_size < src_size)
|
||||
msg_left++;
|
||||
|
||||
// Setup config for SHA256.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_SHA_CONFIG_REG) = sha_cfg;
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
// Set total size to current buffer size if empty.
|
||||
if (!total_size)
|
||||
total_size = src_size;
|
||||
|
||||
// Set total size: BITS(src_size), up to 2 EB.
|
||||
// Set total size: BITS(total_size), up to 2 EB.
|
||||
SE(SE_SHA_MSG_LENGTH_0_REG) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LENGTH_1_REG) = (u32)(total_size >> 29);
|
||||
SE(SE_SHA_MSG_LENGTH_2_REG) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_3_REG) = 0;
|
||||
|
||||
// Set size left to hash.
|
||||
SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(total_size << 3);
|
||||
SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(total_size >> 29);
|
||||
// Set leftover size: BITS(src_size).
|
||||
SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(msg_left << 3);
|
||||
SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(msg_left >> 29);
|
||||
SE(SE_SHA_MSG_LEFT_2_REG) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_3_REG) = 0;
|
||||
|
||||
// If we hash in chunks, copy over the intermediate.
|
||||
if (sha_cfg == SHA_CONTINUE && msg_left)
|
||||
{
|
||||
// Restore message left to process.
|
||||
SE(SE_SHA_MSG_LEFT_0_REG) = msg_left[0];
|
||||
SE(SE_SHA_MSG_LEFT_1_REG) = msg_left[1];
|
||||
// Set config based on init or partial continuation.
|
||||
if (total_size == src_size || !total_size)
|
||||
SE(SE_SHA_CONFIG_REG) = SHA_INIT_HASH;
|
||||
else
|
||||
SE(SE_SHA_CONFIG_REG) = SHA_CONTINUE;
|
||||
|
||||
// Restore hash reg.
|
||||
memcpy(hash32, hash, SE_SHA_256_SIZE);
|
||||
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
|
||||
SE(SE_HASH_RESULT_REG + (i * 4)) = byte_swap_32(hash32[i]);
|
||||
}
|
||||
// Trigger the operation. src vs total size decides if it's partial.
|
||||
int res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
|
||||
|
||||
// Trigger the operation.
|
||||
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
|
||||
|
||||
if (is_oneshot)
|
||||
se_calc_sha256_get_hash(hash, msg_left);
|
||||
if (!res && is_oneshot)
|
||||
_se_sha_hash_256_get_hash(hash);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
|
||||
int se_sha_hash_256_async(void *hash, const void *src, u32 size)
|
||||
{
|
||||
return se_calc_sha256(hash, NULL, src, src_size, 0, SHA_INIT_HASH, true);
|
||||
return _se_sha_hash_256(hash, size, src, size, false);
|
||||
}
|
||||
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
||||
int se_sha_hash_256_oneshot(void *hash, const void *src, u32 size)
|
||||
{
|
||||
return _se_sha_hash_256(hash, size, src, size, true);
|
||||
}
|
||||
|
||||
int se_sha_hash_256_partial_start(void *hash, const void *src, u32 size, bool is_oneshot)
|
||||
{
|
||||
// Check if aligned SHA256 block size.
|
||||
if (size % SE_SHA2_MIN_BLOCK_SIZE)
|
||||
return 1;
|
||||
|
||||
return _se_sha_hash_256(hash, 0, src, size, is_oneshot);
|
||||
}
|
||||
|
||||
int se_sha_hash_256_partial_update(void *hash, const void *src, u32 size, bool is_oneshot)
|
||||
{
|
||||
// Check if aligned to SHA256 block size.
|
||||
if (size % SE_SHA2_MIN_BLOCK_SIZE)
|
||||
return 1;
|
||||
|
||||
return _se_sha_hash_256(hash, size - 1, src, size, is_oneshot);
|
||||
}
|
||||
|
||||
int se_sha_hash_256_partial_end(void *hash, u64 total_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
return _se_sha_hash_256(hash, total_size, src, src_size, is_oneshot);
|
||||
}
|
||||
|
||||
int se_sha_hash_256_finalize(void *hash)
|
||||
{
|
||||
int res = _se_execute_finalize();
|
||||
|
||||
se_calc_sha256_get_hash(hash, msg_left);
|
||||
_se_sha_hash_256_get_hash(hash);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_gen_prng128(void *dst)
|
||||
int se_rng_pseudo(void *dst, u32 size)
|
||||
{
|
||||
// Setup config for X931 PRNG.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
|
||||
//SE(SE_RNG_SRC_CONFIG_REG) =
|
||||
// SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE);
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG) = 1;
|
||||
// Setup config for SP 800-90 PRNG.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
|
||||
SE(SE_RNG_SRC_CONFIG_REG) |= SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE); // DRBG. Depends on ENTROPY clock.
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG) = 4096;
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1;
|
||||
u32 size_aligned = ALIGN_DOWN(size, SE_RNG_BLOCK_SIZE);
|
||||
u32 size_residue = size % SE_RNG_BLOCK_SIZE;
|
||||
int res = 0;
|
||||
|
||||
// Trigger the operation.
|
||||
return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0);
|
||||
// Handle initial aligned message.
|
||||
if (size_aligned)
|
||||
{
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (size >> 4) - 1;
|
||||
|
||||
res = _se_execute_oneshot(SE_OP_START, dst, size_aligned, NULL, 0);
|
||||
}
|
||||
|
||||
// Handle leftover partial message.
|
||||
if (!res && size_residue)
|
||||
{
|
||||
// Copy message to a block sized buffer in case it's partial.
|
||||
u32 block[SE_RNG_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1;
|
||||
|
||||
res = _se_execute_oneshot(SE_OP_START, block, SE_RNG_BLOCK_SIZE, NULL, 0);
|
||||
|
||||
// Copy result back.
|
||||
memcpy(dst + size_aligned, block, size_residue);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
void se_aes_ctx_get_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
{
|
||||
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
|
||||
|
||||
@@ -648,67 +666,66 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7);
|
||||
|
||||
// Decrypt context.
|
||||
se_aes_key_clear(3);
|
||||
se_aes_key_set(3, srk, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
||||
se_aes_crypt_cbc(3, DECRYPT, keys, keys, SE_AES_KEYSLOT_COUNT * keysize);
|
||||
se_aes_key_clear(3);
|
||||
}
|
||||
|
||||
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
|
||||
int se_aes_hash_cmac(u32 ks, void *hash, const void *src, u32 size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
|
||||
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
|
||||
u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0};
|
||||
u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
|
||||
u8 *subkey = (u8 *)tmp1;
|
||||
u8 *last_block = (u8 *)tmp2;
|
||||
|
||||
// Generate sub key (CBC with zeroed IV, basically ECB).
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
if (se_aes_crypt_cbc(ks, ENCRYPT, subkey, subkey, SE_KEY_128_SIZE))
|
||||
return 1;
|
||||
|
||||
// Generate sub key
|
||||
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
|
||||
goto out;
|
||||
// Generate K1 subkey.
|
||||
_se_ls_1bit(subkey);
|
||||
if (size & 0xF)
|
||||
_se_ls_1bit(subkey); // Convert to K2.
|
||||
|
||||
_gf256_mul_x(key);
|
||||
if (src_size & 0xF)
|
||||
_gf256_mul_x(key);
|
||||
// Switch to hash register. The rest of the config is already set.
|
||||
SE(SE_CONFIG_REG) |= SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_HASH(HASH_ENABLE);
|
||||
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
|
||||
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
|
||||
se_aes_iv_clear(ks);
|
||||
se_aes_iv_updated_clear(ks);
|
||||
|
||||
u32 num_blocks = (src_size + 0xf) >> 4;
|
||||
// Initial blocks.
|
||||
u32 num_blocks = (size + 0xF) >> 4;
|
||||
if (num_blocks > 1)
|
||||
{
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
|
||||
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
|
||||
goto out;
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = num_blocks - 2;
|
||||
|
||||
if (_se_execute_oneshot(SE_OP_START, NULL, 0, src, size))
|
||||
return 1;
|
||||
|
||||
// Use updated IV for next OP as a continuation.
|
||||
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
|
||||
}
|
||||
|
||||
if (src_size & 0xf)
|
||||
// Last block.
|
||||
if (size & 0xF)
|
||||
{
|
||||
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
|
||||
last_block[src_size & 0xf] = 0x80;
|
||||
}
|
||||
else if (src_size >= SE_AES_BLOCK_SIZE)
|
||||
{
|
||||
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
|
||||
memcpy(last_block, src + (size & (~0xF)), size & 0xF);
|
||||
last_block[size & 0xF] = 0x80;
|
||||
}
|
||||
else if (size >= SE_AES_BLOCK_SIZE)
|
||||
memcpy(last_block, src + size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
|
||||
|
||||
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
|
||||
last_block[i] ^= key[i];
|
||||
last_block[i] ^= subkey[i];
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
|
||||
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
|
||||
SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1;
|
||||
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
|
||||
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
|
||||
if (_se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE))
|
||||
return 1;
|
||||
|
||||
out:;
|
||||
free(key);
|
||||
free(last_block);
|
||||
return res;
|
||||
// Copy output hash.
|
||||
u32 *hash32 = (u32 *)hash;
|
||||
for (u32 i = 0; i < (SE_AES_CMAC_DIGEST_SIZE / sizeof(u32)); i++)
|
||||
hash32[i] = SE(SE_HASH_RESULT_REG + sizeof(u32) * i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
42
bdk/sec/se.h
42
bdk/sec/se.h
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
* Copyright (c) 2019-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -24,26 +24,32 @@
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags);
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||
u32 se_key_acc_ctrl_get(u32 ks);
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||
|
||||
/*! AES Key Management Functions */
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, const void *iv);
|
||||
void se_aes_iv_set(u32 ks, const void *iv, u32 size);
|
||||
void se_aes_key_get(u32 ks, void *key, u32 size);
|
||||
void se_aes_key_clear(u32 ks);
|
||||
void se_aes_iv_clear(u32 ks);
|
||||
void se_aes_iv_updated_clear(u32 ks);
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
|
||||
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
|
||||
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize);
|
||||
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
|
||||
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
|
||||
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
|
||||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
||||
int se_gen_prng128(void *dst);
|
||||
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed);
|
||||
void se_aes_ctx_get_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||
/*! Encryption Functions */
|
||||
int se_aes_crypt_ecb(u32 ks, int enc, void *dst, const void *src, u32 size);
|
||||
int se_aes_crypt_cbc(u32 ks, int enc, void *dst, const void *src, u32 size);
|
||||
int se_aes_crypt_ofb(u32 ks, void *dst, const void *src, u32 size);
|
||||
int se_aes_crypt_ctr(u32 ks, void *dst, const void *src, u32 size, void *ctr);
|
||||
int se_aes_crypt_xts_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize);
|
||||
int se_aes_crypt_xts_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
|
||||
int se_aes_crypt_xts(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
|
||||
/*! Hashing Functions */
|
||||
int se_sha_hash_256_async(void *hash, const void *src, u32 size);
|
||||
int se_sha_hash_256_oneshot(void *hash, const void *src, u32 size);
|
||||
int se_sha_hash_256_partial_start(void *hash, const void *src, u32 size, bool is_oneshot);
|
||||
int se_sha_hash_256_partial_update(void *hash, const void *src, u32 size, bool is_oneshot);
|
||||
int se_sha_hash_256_partial_end(void *hash, u64 total_size, const void *src, u32 src_size, bool is_oneshot);
|
||||
int se_sha_hash_256_finalize(void *hash);
|
||||
int se_aes_hash_cmac(u32 ks, void *hash, const void *src, u32 size);
|
||||
/*! Random Functions */
|
||||
int se_rng_pseudo(void *dst, u32 size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#define SE_AES_KEYSLOT_COUNT 16
|
||||
#define SE_RSA_KEYSLOT_COUNT 2
|
||||
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
|
||||
|
||||
#define SE_AES_BLOCK_SIZE 16
|
||||
#define SE_AES_IV_SIZE 16
|
||||
@@ -39,9 +38,10 @@
|
||||
#define SE_SHA_256_SIZE 32
|
||||
#define SE_SHA_384_SIZE 48
|
||||
#define SE_SHA_512_SIZE 64
|
||||
#define SE_RNG_IV_SIZE 16
|
||||
#define SE_RNG_DT_SIZE 16
|
||||
#define SE_RNG_KEY_SIZE 16
|
||||
#define SE_RNG_BLOCK_SIZE 16
|
||||
#define SE_RNG_IV_SIZE 16
|
||||
#define SE_RNG_DT_SIZE 16
|
||||
#define SE_RNG_KEY_SIZE 16
|
||||
#define SE_RNG_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE)
|
||||
|
||||
#define SE_AES_CMAC_DIGEST_SIZE 16
|
||||
@@ -50,6 +50,11 @@
|
||||
#define SE_RSA1536_DIGEST_SIZE 192
|
||||
#define SE_RSA2048_DIGEST_SIZE 256
|
||||
|
||||
#define SE_SHA2_MIN_BLOCK_SIZE 64
|
||||
#define SE_SHA2_MAX_BLOCK_SIZE 128
|
||||
|
||||
#define SE_LL_MAX_SIZE ALIGN_DOWN(0xFFFFFF, SE_SHA2_MAX_BLOCK_SIZE)
|
||||
|
||||
#define DECRYPT 0
|
||||
#define ENCRYPT 1
|
||||
|
||||
@@ -211,7 +216,7 @@
|
||||
#define SE_CRYPTO_LINEAR_CTR_REG 0x308
|
||||
#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4
|
||||
|
||||
#define SE_CRYPTO_BLOCK_COUNT_REG 0x318
|
||||
#define SE_CRYPTO_LAST_BLOCK_REG 0x318
|
||||
|
||||
#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C
|
||||
#define SE_KEYTABLE_PKT(x) ((x) << 0)
|
||||
@@ -321,8 +326,6 @@
|
||||
#define SE_CLK_OVR_ON BIT(2)
|
||||
|
||||
#define SE_SPARE_REG 0x80C
|
||||
#define SE_ERRATA_FIX_DISABLE 0
|
||||
#define SE_ERRATA_FIX_ENABLE 1
|
||||
#define SE_ECO(x) ((x) << 0)
|
||||
#define SE_INPUT_NONCE_LE BIT(0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,9 +44,9 @@ static int _tsec_dma_wait_idle()
|
||||
|
||||
while (!(TSEC(TSEC_DMATRFCMD) & TSEC_DMATRFCMD_IDLE))
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offset)
|
||||
@@ -91,13 +91,13 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
{
|
||||
// Disable all CCPLEX core rails.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE1, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE2, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE1, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE2, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE3, DISABLE);
|
||||
|
||||
// Enable AHB aperture and set it to full mmio.
|
||||
mc_enable_ahb_redirect();
|
||||
mc_enable_ahb_redirect(0);
|
||||
}
|
||||
|
||||
// Configure Falcon.
|
||||
@@ -116,7 +116,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_SWGEN1;
|
||||
TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN;
|
||||
if (!_tsec_dma_wait_idle())
|
||||
if (_tsec_dma_wait_idle())
|
||||
{
|
||||
res = -1;
|
||||
goto out;
|
||||
@@ -136,7 +136,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
|
||||
for (u32 addr = 0; addr < tsec_ctxt->size; addr += 0x100)
|
||||
{
|
||||
if (!_tsec_dma_pa_to_internal_100(false, addr, addr))
|
||||
if (_tsec_dma_pa_to_internal_100(false, addr, addr))
|
||||
{
|
||||
res = -2;
|
||||
goto out_free;
|
||||
@@ -146,7 +146,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
{
|
||||
// Init SMMU translation for TSEC.
|
||||
ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
ptb = smmu_domain_init(MC_SMMU_TSEC_ASID, 1);
|
||||
smmu_init();
|
||||
|
||||
// Enable SMMU.
|
||||
@@ -230,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
if (kidx != 8)
|
||||
{
|
||||
res = -6;
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
smmu_domain_deinit(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
@@ -241,7 +241,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
memcpy(tsec_keys, &key, 0x20);
|
||||
memcpy(tsec_ctxt->pkg1, iram, 0x30000);
|
||||
|
||||
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
|
||||
smmu_domain_deinit(MC_SMMU_TSEC_ASID, 1);
|
||||
|
||||
// for (int i = 0; i < kidx; i++)
|
||||
// gfx_printf("key %08X\n", key[i]);
|
||||
@@ -257,7 +257,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_tsec_dma_wait_idle())
|
||||
if (_tsec_dma_wait_idle())
|
||||
{
|
||||
res = -3;
|
||||
goto out_free;
|
||||
@@ -307,10 +307,8 @@ out:
|
||||
bpmp_mmu_enable();
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
// Re-enable AHB aperture.
|
||||
mc_enable_ahb_redirect();
|
||||
#endif
|
||||
mc_enable_ahb_redirect(1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -222,14 +222,17 @@ void bpmp_clk_rate_relaxed(bool enable)
|
||||
{
|
||||
// Restore to PLLP source during PLLC configuration.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT.
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY);
|
||||
usleep(100); // Wait a bit for clock source change.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // S1:H1:P3.
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE);
|
||||
}
|
||||
else if (bpmp_fid_current)
|
||||
{
|
||||
// Restore to PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // S1:H1:P4.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 and CLKM for idle.
|
||||
(void)CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY);
|
||||
usleep(100); // Wait a bit for clock source change.
|
||||
}
|
||||
}
|
||||
@@ -243,7 +246,7 @@ static const u8 pll_divn[] = {
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
92, // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
// Do not use for public releases!
|
||||
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||
};
|
||||
@@ -272,19 +275,19 @@ void bpmp_clk_rate_get()
|
||||
|
||||
void bpmp_clk_rate_set(bpmp_freq_t fid)
|
||||
{
|
||||
if (fid > (BPMP_CLK_MAX - 1))
|
||||
fid = BPMP_CLK_MAX - 1;
|
||||
if (fid >= BPMP_CLK_NUM)
|
||||
fid = BPMP_CLK_NUM - 1;
|
||||
|
||||
if (bpmp_fid_current == fid)
|
||||
return;
|
||||
|
||||
bpmp_fid_current = fid;
|
||||
|
||||
// Use default SCLK / HCLK / PCLK clocks.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
if (fid)
|
||||
{
|
||||
// Use default SCLK / HCLK / PCLK clocks.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
// Configure and enable PLLC.
|
||||
clock_enable_pllc(pll_divn[fid]);
|
||||
|
||||
@@ -293,9 +296,6 @@ void bpmp_clk_rate_set(bpmp_freq_t fid)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default SCLK / HCLK / PCLK clocks.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
// Disable PLLC to save power.
|
||||
clock_disable_pllc();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -51,7 +51,7 @@ typedef enum
|
||||
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_MAX
|
||||
BPMP_CLK_NUM
|
||||
} bpmp_freq_t;
|
||||
|
||||
typedef enum
|
||||
@@ -64,9 +64,14 @@ typedef enum
|
||||
BPMP_STATE_FIQ = BIT(3),
|
||||
} bpmp_state_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
#define BPMP_CLK_BIN0_BOOST BPMP_CLK_HYPER_BOOST
|
||||
#define BPMP_CLK_BIN1_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_BIN2_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_BIN3_BOOST BPMP_CLK_HIGH_BOOST
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_BIN3_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_BIN1_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_BIN0_BOOST
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply);
|
||||
|
||||
@@ -90,11 +90,11 @@ void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||
|
||||
// Enable CPU main rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, ENABLE);
|
||||
// Enable cluster 0 non-CPU rail.
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, ENABLE);
|
||||
// Enable CPU0 rail.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, ENABLE);
|
||||
|
||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||
@@ -115,7 +115,7 @@ void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||
}
|
||||
|
||||
// Tighten up the security aperture.
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
// MC(MC_TZ_SECURITY_CTRL) = TZ_SEC_CTRL_CPU_STRICT_TZ_APERTURE_CHECK;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
@@ -146,20 +146,18 @@ void ccplex_powergate_cpu0()
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
|
||||
// Set NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
|
||||
// Set MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Disable CE0.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||
// Disable cluster 0 non-CPU.
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, DISABLE);
|
||||
// Disable CPU rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, DISABLE);
|
||||
|
||||
clock_disable_coresight();
|
||||
|
||||
// Clear out MSELECT and CPU clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_CPUG);
|
||||
|
||||
_ccplex_disable_power();
|
||||
}
|
||||
|
||||
473
bdk/soc/clock.c
473
bdk/soc/clock.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -23,6 +23,33 @@
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sdmmc.h>
|
||||
|
||||
#define RST_DEV_L_SET CLK_RST_CONTROLLER_RST_DEV_L_SET
|
||||
#define RST_DEV_H_SET CLK_RST_CONTROLLER_RST_DEV_H_SET
|
||||
#define RST_DEV_U_SET CLK_RST_CONTROLLER_RST_DEV_U_SET
|
||||
#define RST_DEV_V_SET CLK_RST_CONTROLLER_RST_DEV_V_SET
|
||||
#define RST_DEV_W_SET CLK_RST_CONTROLLER_RST_DEV_W_SET
|
||||
#define RST_DEV_X_SET CLK_RST_CONTROLLER_RST_DEV_X_SET
|
||||
#define RST_DEV_Y_SET CLK_RST_CONTROLLER_RST_DEV_Y_SET
|
||||
|
||||
#define CLK_ENB_L_SET CLK_RST_CONTROLLER_CLK_ENB_L_SET
|
||||
#define CLK_ENB_H_SET CLK_RST_CONTROLLER_CLK_ENB_H_SET
|
||||
#define CLK_ENB_U_SET CLK_RST_CONTROLLER_CLK_ENB_U_SET
|
||||
#define CLK_ENB_V_SET CLK_RST_CONTROLLER_CLK_ENB_V_SET
|
||||
#define CLK_ENB_W_SET CLK_RST_CONTROLLER_CLK_ENB_W_SET
|
||||
#define CLK_ENB_X_SET CLK_RST_CONTROLLER_CLK_ENB_X_SET
|
||||
#define CLK_ENB_Y_SET CLK_RST_CONTROLLER_CLK_ENB_Y_SET
|
||||
|
||||
#define RST_DEV_H_CLR CLK_RST_CONTROLLER_RST_DEV_H_CLR
|
||||
#define CLK_ENB_H_CLR CLK_RST_CONTROLLER_CLK_ENB_H_CLR
|
||||
|
||||
typedef struct _clk_rst_mgd_t
|
||||
{
|
||||
u16 reset; // Reset SET.
|
||||
u16 enable; // Enable SET.
|
||||
u16 source;
|
||||
u8 index;
|
||||
} clk_rst_mgd_t;
|
||||
|
||||
typedef struct _clock_osc_t
|
||||
{
|
||||
u32 freq;
|
||||
@@ -31,8 +58,8 @@ typedef struct _clock_osc_t
|
||||
} clock_osc_t;
|
||||
|
||||
static const clock_osc_t _clock_osc_cnt[] = {
|
||||
{ 12000, 706, 757 },
|
||||
{ 13000, 766, 820 },
|
||||
{ 12000, 706, 757 },
|
||||
{ 13000, 766, 820 },
|
||||
{ 16800, 991, 1059 },
|
||||
{ 19200, 1133, 1210 },
|
||||
{ 26000, 1535, 1638 },
|
||||
@@ -40,110 +67,133 @@ static const clock_osc_t _clock_osc_cnt[] = {
|
||||
{ 48000, 2836, 3023 }
|
||||
};
|
||||
|
||||
/*
|
||||
* T210 rare HW Errata
|
||||
* A fraction of T210 silicon has an undocumented HW Errata on SDMMC clock state machine.
|
||||
* Specifically on enable when using the combo registers. Using SET/CLR variants is mandatory.
|
||||
*/
|
||||
static const clk_rst_mgd_t _clock_sdmmc[] = {
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1, CLK_L_SDMMC1 },
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2, CLK_L_SDMMC2 },
|
||||
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3, CLK_U_SDMMC3 },
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4, CLK_L_SDMMC4 },
|
||||
};
|
||||
|
||||
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clk_rst_t _clock_uart[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
|
||||
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
|
||||
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
|
||||
{ RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
// I2C Fout = Fin / (TLOW + THIGH + 2) / FM_DIV). Default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 6.
|
||||
static const clk_rst_t _clock_i2c[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
|
||||
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 6, CLK_I2C_SRC_DIV(4) }, // 4.8 MHz -> 100 KHz
|
||||
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 6, CLK_I2C_SRC_DIV(1) }, // 19.2 MHz -> 400 KHz
|
||||
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 6, CLK_I2C_SRC_DIV(1) }, // 19.2 MHz -> 400 KHz
|
||||
{ RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 6, CLK_I2C_SRC_DIV(4) }, // 4.8 MHz -> 100 KHz
|
||||
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 6, CLK_I2C_SRC_DIV(1) }, // 19.2 MHz -> 400 KHz
|
||||
{ RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 6, CLK_I2C_SRC_DIV(4) } // 4.8 MHz -> 100 KHz
|
||||
};
|
||||
|
||||
static clk_rst_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408MHz. Default: 408MHz. Max: 627.2 MHz.
|
||||
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408MHz.
|
||||
static clk_rst_t _clock_host1x = { // Has idle divisor.
|
||||
RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204MHz. Max: 408MHz.
|
||||
RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204 MHz. Max: 408 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_nvdec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2MHz.
|
||||
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_nvjpg = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
|
||||
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_vic = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
|
||||
static clk_rst_t _clock_vic = { // Has idle divisor.
|
||||
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0 // 24 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_NOT_USED, CLK_X_SOR0, 0, 0 // 24 MHz (safe).
|
||||
};
|
||||
static clk_rst_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204MHz.
|
||||
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_W_SET, CLK_ENB_W_SET, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136MHz.
|
||||
RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
|
||||
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
|
||||
};
|
||||
static clk_rst_t _clock_apbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204MHz.
|
||||
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 // Max: 204 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_ahbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0 // Max: 408 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_actmon = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2MHz.
|
||||
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_extperiph1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
|
||||
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_extperiph2 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0MHz
|
||||
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0 MHz
|
||||
};
|
||||
|
||||
void clock_enable(const clk_rst_t *clk)
|
||||
{
|
||||
const u32 module = BIT(clk->index);
|
||||
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->reset) = module;
|
||||
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
CLOCK(clk->enable + CLK_CLR_OFFSET) = module;
|
||||
|
||||
// Configure clock source if required.
|
||||
if (clk->source)
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
|
||||
CLOCK(clk->source) = (clk->clk_src << 29u) | clk->clk_div;
|
||||
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->enable) = module;
|
||||
usleep(2);
|
||||
|
||||
// Take clock off reset.
|
||||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||
CLOCK(clk->reset + CLK_CLR_OFFSET) = module;
|
||||
|
||||
// Commit changes.
|
||||
(void)CLOCK(clk->reset);
|
||||
}
|
||||
|
||||
void clock_disable(const clk_rst_t *clk)
|
||||
{
|
||||
const u32 module = BIT(clk->index);
|
||||
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->reset) = module;
|
||||
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
CLOCK(clk->enable + CLK_CLR_OFFSET) = module;
|
||||
}
|
||||
|
||||
void clock_enable_fuse(bool enable)
|
||||
@@ -159,7 +209,7 @@ void clock_enable_uart(u32 idx)
|
||||
|
||||
clock_enable(&_clock_uart[idx]);
|
||||
|
||||
// Restore OC.
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
@@ -172,15 +222,15 @@ void clock_disable_uart(u32 idx)
|
||||
|
||||
int clock_uart_use_src_div(u32 idx, u32 baud)
|
||||
{
|
||||
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||
u32 clk_src = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||
|
||||
if (baud == 3000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
|
||||
CLOCK(_clock_uart[idx].source) = clk_src | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
|
||||
else if (baud == 1000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
|
||||
CLOCK(_clock_uart[idx].source) = clk_src | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
|
||||
else
|
||||
{
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
|
||||
CLOCK(_clock_uart[idx].source) = clk_src | CLK_SRC_DIV(2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -190,7 +240,13 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
|
||||
|
||||
void clock_enable_i2c(u32 idx)
|
||||
{
|
||||
// Ease the stress to APB.
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
clock_enable(&_clock_i2c[idx]);
|
||||
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
void clock_disable_i2c(u32 idx)
|
||||
@@ -204,7 +260,7 @@ void clock_enable_se()
|
||||
|
||||
// Lock clock to always enabled if T210B01.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= 0x100;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= BIT(8);
|
||||
}
|
||||
|
||||
void clock_enable_tzram()
|
||||
@@ -215,6 +271,9 @@ void clock_enable_tzram()
|
||||
void clock_enable_host1x()
|
||||
{
|
||||
clock_enable(&_clock_host1x);
|
||||
|
||||
// Set idle frequency to 81.6 MHz.
|
||||
// CLOCK(_clock_host1x.clk_src) |= CLK_SRC_DIV(5) << 8;
|
||||
}
|
||||
|
||||
void clock_disable_host1x()
|
||||
@@ -259,6 +318,9 @@ void clock_enable_vic()
|
||||
|
||||
clock_enable(&_clock_vic);
|
||||
|
||||
// Set idle frequency to 136 MHz.
|
||||
// CLOCK(_clock_vic.clk_src) |= CLK_SRC_DIV(3) << 8;
|
||||
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
@@ -300,13 +362,13 @@ void clock_disable_sor1()
|
||||
|
||||
void clock_enable_kfuse()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_KFUSE);
|
||||
usleep(10); // Wait 10s to prevent glitching.
|
||||
CLOCK(RST_DEV_H_SET) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_ENB_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
CLOCK(CLK_ENB_H_SET) = BIT(CLK_H_KFUSE);
|
||||
usleep(10); // Wait 10us to prevent glitching.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
usleep(20); // Wait 20s fo kfuse hw to init.
|
||||
CLOCK(RST_DEV_H_CLR) = BIT(CLK_H_KFUSE);
|
||||
usleep(20); // Wait 20us for KFUSE HW to init.
|
||||
}
|
||||
|
||||
void clock_disable_kfuse()
|
||||
@@ -341,7 +403,7 @@ void clock_enable_pwm()
|
||||
|
||||
clock_enable(&_clock_pwm);
|
||||
|
||||
// Restore OC.
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
@@ -408,30 +470,45 @@ void clock_disable_extperiph2()
|
||||
clock_disable(&_clock_extperiph2);
|
||||
}
|
||||
|
||||
static void _clock_pll_wait_lock(u32 base, u32 max_delay)
|
||||
{
|
||||
for (u32 i = 0; i < max_delay; i++)
|
||||
{
|
||||
if (CLOCK(base) & PLL_BASE_LOCK)
|
||||
break;
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
usleep(2);
|
||||
}
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
||||
{
|
||||
u32 plld_div = (divp << 20) | (divn << 11) | 1;
|
||||
|
||||
// N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
|
||||
u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
|
||||
u32 misc = BIT(21) | BIT(19) | BIT(18) | BIT(16) | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
|
||||
if (lowpower && tegra_t210)
|
||||
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||
misc = BIT(21) | BIT(19) | BIT(18) | BIT(16) | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||
|
||||
// Set DISP1 clock source.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
|
||||
|
||||
// Set dividers and enable PLLD.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLL_BASE_ENABLE | PLL_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||
|
||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
||||
// Set PLLD_SDM_DIN and enable (T210) PLLD to DSI pads.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
_clock_pll_wait_lock(CLK_RST_CONTROLLER_PLLD_BASE, 1000);
|
||||
}
|
||||
|
||||
void clock_enable_pllx()
|
||||
{
|
||||
// Configure and enable PLLX if disabled.
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE.
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLL_BASE_ENABLE)) // PLLX_ENABLE.
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
||||
usleep(2);
|
||||
@@ -440,48 +517,50 @@ void clock_enable_pllx()
|
||||
const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz.
|
||||
|
||||
// Bypass dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | pllx_div_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_BYPASS | pllx_div_cfg;
|
||||
// Disable bypass
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg;
|
||||
// Set PLLX_LOCK_ENABLE.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN;
|
||||
// Enable PLLX.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | pllx_div_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_ENABLE | pllx_div_cfg;
|
||||
}
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK))
|
||||
;
|
||||
_clock_pll_wait_lock(CLK_RST_CONTROLLER_PLLX_BASE, 300);
|
||||
}
|
||||
|
||||
void clock_enable_pllc(u32 divn)
|
||||
{
|
||||
u32 enabled = CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLL_BASE_ENABLE;
|
||||
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||
|
||||
// Check if already enabled and configured.
|
||||
if ((CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_ENABLE) && (pll_divn_curr == divn))
|
||||
if (enabled && (pll_divn_curr == divn))
|
||||
return;
|
||||
|
||||
// Take PLLC out of reset and set basic misc parameters.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||
// WAR: Disable first to avoid HPLL overshoot.
|
||||
if (enabled)
|
||||
clock_disable_pllc();
|
||||
|
||||
// Take PLLC out of reset (misc) and set misc2 parameters.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = (0x8000 << 4); // PLLC_EXT_FRU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF << 8; // PLLC_FLL_LD_MEM.
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) &= ~PLLC_MISC1_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
// Set PLLC dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) = (divn << 10) | 4; // DIVM: 4, DIVP: 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) = (divn << 10) | 6; // DIVM: 6, DIVP: 1.
|
||||
|
||||
// Enable PLLC and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_LOCK))
|
||||
;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLL_BASE_ENABLE;
|
||||
_clock_pll_wait_lock(CLK_RST_CONTROLLER_PLLC_BASE, 300);
|
||||
|
||||
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 1 << 8;
|
||||
// Disable PLLC_OUT1, enable reset and set div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 0;
|
||||
|
||||
// Enable PLLC_OUT1 and bring it out of reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR;
|
||||
@@ -493,7 +572,7 @@ void clock_disable_pllc()
|
||||
// Disable PLLC and PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||
usleep(10);
|
||||
@@ -512,10 +591,10 @@ static void _clock_enable_pllc4(u32 mask)
|
||||
return;
|
||||
|
||||
// Enable Phase and Frequency lock detection.
|
||||
//CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLC4_BASE_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
@@ -523,11 +602,8 @@ static void _clock_enable_pllc4(u32 mask)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||
|
||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLLCX_BASE_LOCK))
|
||||
;
|
||||
|
||||
msleep(1); // Wait a bit for PLL to stabilize.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLL_BASE_ENABLE;
|
||||
_clock_pll_wait_lock(CLK_RST_CONTROLLER_PLLC4_BASE, 300 + 700);
|
||||
|
||||
pllc4_enabled |= PLLC4_ENABLED;
|
||||
}
|
||||
@@ -541,8 +617,8 @@ static void _clock_disable_pllc4(u32 mask)
|
||||
return;
|
||||
|
||||
// Disable PLLC4.
|
||||
msleep(1); // Wait at least 1ms to prevent glitching.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
usleep(100); // Wait at least 100us to prevent glitching.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLC4_BASE_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
@@ -555,14 +631,11 @@ void clock_enable_pllu()
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= BIT(29); // Disable reference clock.
|
||||
u32 pllu_cfg = (CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & 0xFFE00000) | BIT(24) | (1 << 16) | (0x19 << 8) | 2;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLL_BASE_ENABLE; // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = get_tmr_us() + 1300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
||||
if (get_tmr_us() > timeout)
|
||||
break;
|
||||
usleep(10);
|
||||
_clock_pll_wait_lock(CLK_RST_CONTROLLER_PLLU_BASE, 1000);
|
||||
usleep(8);
|
||||
|
||||
// Enable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) |= 0x2E00000;
|
||||
@@ -591,117 +664,52 @@ void clock_enable_utmipll()
|
||||
}
|
||||
}
|
||||
|
||||
static int _clock_sdmmc_is_reset(u32 id)
|
||||
static int _clock_sdmmc_in_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
return CLOCK(clk->reset) & BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->reset) = BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_reset(u32 id)
|
||||
static void _clock_sdmmc_clr_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->reset + CLK_CLR_OFFSET) = BIT(clk->index);
|
||||
}
|
||||
|
||||
static int _clock_sdmmc_is_enabled(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
return CLOCK(clk->enable) & BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->enable) = BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_enable(u32 id)
|
||||
static void _clock_sdmmc_clr_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->enable + CLK_CLR_OFFSET) = BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
@@ -709,7 +717,7 @@ static void _clock_sdmmc_config_legacy_tm()
|
||||
typedef struct _clock_sdmmc_t
|
||||
{
|
||||
u32 clock;
|
||||
u32 real_clock;
|
||||
u32 pclock;
|
||||
} clock_sdmmc_t;
|
||||
|
||||
static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||
@@ -719,16 +727,16 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 clock)
|
||||
{
|
||||
u32 divisor = 0;
|
||||
u32 source = SDMMC_CLOCK_SRC_PLLP_OUT0;
|
||||
u32 source = SDMMC_CLOCK_SRC_PLLP_OUT0;
|
||||
|
||||
if (id > SDMMC_4)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
// Get IO clock divisor.
|
||||
switch (val)
|
||||
switch (clock)
|
||||
{
|
||||
case 25000:
|
||||
*pclock = 24728;
|
||||
@@ -775,7 +783,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // CLK RST divisor is ignored.
|
||||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
@@ -791,8 +799,8 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
#endif
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[id].clock = val;
|
||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
||||
_clock_sdmmc_table[id].clock = clock;
|
||||
_clock_sdmmc_table[id].pclock = *pclock;
|
||||
|
||||
// Enable PLLC4 if in use by any SDMMC.
|
||||
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||
@@ -802,41 +810,39 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
_clock_sdmmc_config_legacy_tm();
|
||||
|
||||
// Set SDMMC clock.
|
||||
u32 src_div = (source << 29u) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
CLOCK(clk->source) = (source << 29u) | divisor;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val)
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock)
|
||||
{
|
||||
if (_clock_sdmmc_table[id].clock == val)
|
||||
if (_clock_sdmmc_table[id].clock == clock)
|
||||
{
|
||||
*pclock = _clock_sdmmc_table[id].real_clock;
|
||||
*pclock = _clock_sdmmc_table[id].pclock;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ease the stress to APB.
|
||||
if (id == SDMMC_1)
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_config_clock_host(pclock, id, val);
|
||||
_clock_sdmmc_clr_enable(id);
|
||||
|
||||
_clock_sdmmc_config_clock_host(pclock, id, clock);
|
||||
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
|
||||
// Commit changes.
|
||||
_clock_sdmmc_in_reset(id);
|
||||
|
||||
// Restore sys clock.
|
||||
if (id == SDMMC_1)
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,7 +851,7 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
// Get Card clock divisor.
|
||||
switch (type)
|
||||
{
|
||||
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||
*pclock = 26000;
|
||||
*pdivisor = 66;
|
||||
break;
|
||||
@@ -894,12 +900,12 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||
*pclock = 82000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
@@ -913,32 +919,41 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
}
|
||||
}
|
||||
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id)
|
||||
int clock_sdmmc_is_active(u32 id)
|
||||
{
|
||||
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
|
||||
return !_clock_sdmmc_in_reset(id) && _clock_sdmmc_is_enabled(id);
|
||||
}
|
||||
|
||||
void clock_sdmmc_enable(u32 id, u32 val)
|
||||
void clock_sdmmc_enable(u32 id, u32 clock)
|
||||
{
|
||||
u32 clock = 0;
|
||||
u32 pclock = 0;
|
||||
|
||||
if (_clock_sdmmc_is_enabled(id))
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
// Ease the stress to APB.
|
||||
if (id == SDMMC_1)
|
||||
bpmp_clk_rate_relaxed(true);
|
||||
|
||||
_clock_sdmmc_clr_enable(id);
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
||||
_clock_sdmmc_config_clock_host(&pclock, id, clock);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
// Wait 100 cycles for reset and for clocks to stabilize.
|
||||
usleep((100 * 1000 + clock - 1) / clock);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
|
||||
// Commit changes and wait 100 cycles for reset and for clocks to stabilize.
|
||||
_clock_sdmmc_in_reset(id);
|
||||
usleep((100 * 1000 + pclock - 1) / pclock);
|
||||
|
||||
_clock_sdmmc_clr_reset(id);
|
||||
_clock_sdmmc_in_reset(id);
|
||||
|
||||
// Restore sys clock.
|
||||
if (id == SDMMC_1)
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
|
||||
void clock_sdmmc_disable(u32 id)
|
||||
{
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
_clock_sdmmc_clr_enable(id);
|
||||
_clock_sdmmc_in_reset(id);
|
||||
_clock_disable_pllc4(BIT(id));
|
||||
}
|
||||
|
||||
|
||||
359
bdk/soc/clock.h
359
bdk/soc/clock.h
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -171,19 +171,17 @@
|
||||
#define CLK_NO_SOURCE 0x0
|
||||
#define CLK_NOT_USED 0x0
|
||||
|
||||
#define CLK_CLR_OFFSET 0x4
|
||||
|
||||
/*! PLL control and status bits */
|
||||
#define PLLX_BASE_LOCK BIT(27)
|
||||
#define PLLX_BASE_REF_DIS BIT(29)
|
||||
#define PLLX_BASE_ENABLE BIT(30)
|
||||
#define PLLX_BASE_BYPASS BIT(31)
|
||||
#define PLL_BASE_LOCK BIT(27)
|
||||
#define PLL_BASE_REF_DIS BIT(29)
|
||||
#define PLL_BASE_ENABLE BIT(30)
|
||||
#define PLL_BASE_BYPASS BIT(31)
|
||||
|
||||
#define PLLX_MISC_LOCK_EN BIT(18)
|
||||
#define PLLX_MISC3_IDDQ BIT(3)
|
||||
|
||||
#define PLLCX_BASE_LOCK BIT(27)
|
||||
#define PLLCX_BASE_REF_DIS BIT(29)
|
||||
#define PLLCX_BASE_ENABLE BIT(30)
|
||||
#define PLLCX_BASE_BYPASS BIT(31)
|
||||
|
||||
#define PLLA_OUT0_RSTN_CLR BIT(0)
|
||||
#define PLLA_OUT0_CLKEN BIT(1)
|
||||
#define PLLA_BASE_IDDQ BIT(25)
|
||||
@@ -201,7 +199,8 @@
|
||||
#define UTMIPLL_LOCK BIT(31)
|
||||
|
||||
/*! Clock source */
|
||||
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
|
||||
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
|
||||
#define CLK_I2C_SRC_DIV(d) ((d) ? ((u32)(((d) - 1))) : 0)
|
||||
|
||||
/*! PTO_CLK_CNT */
|
||||
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
|
||||
@@ -214,8 +213,8 @@
|
||||
#define PTO_DIV_SEL_MASK (3 << 23)
|
||||
#define PTO_DIV_SEL_GATED (0 << 23)
|
||||
#define PTO_DIV_SEL_DIV1 (1 << 23)
|
||||
#define PTO_DIV_SEL_DIV2_RISING (2 << 23)
|
||||
#define PTO_DIV_SEL_DIV2_FALLING (3 << 23)
|
||||
#define PTO_DIV_SEL_DIV4_RISING (2 << 23)
|
||||
#define PTO_DIV_SEL_DIV4_FALLING (3 << 23)
|
||||
#define PTO_DIV_SEL_CPU_EARLY (0 << 23)
|
||||
#define PTO_DIV_SEL_CPU_LATE (1 << 23)
|
||||
|
||||
@@ -382,22 +381,22 @@ typedef enum _clock_pto_id_t
|
||||
CLK_PTO_HDMI = 0xC2,
|
||||
|
||||
CLK_PTO_DISP2 = 0xC4,
|
||||
CLK_PTO_DISP1 = 0xC5,
|
||||
CLK_PTO_DISP1 = 0xC5, // Branches: 0xD5, 0xE5, 0xF5.
|
||||
|
||||
CLK_PTO_PLLD_OBS = 0xCA,
|
||||
CLK_PTO_PLLD_OBS = 0xCA, // Branches: 0xDA, 0xEA, 0xFA.
|
||||
CLK_PTO_PLLD2_PTO_OBS = 0xCC,
|
||||
CLK_PTO_PLLDP_OBS = 0xCE,
|
||||
CLK_PTO_PLLE_OBS = 0x10A,
|
||||
CLK_PTO_PLLU_OBS = 0x10C,
|
||||
CLK_PTO_PLLU_OBS = 0x10C, // Branches: 0x14C 0x18C 0x1CC.
|
||||
CLK_PTO_PLLREFE_OBS = 0x10E,
|
||||
|
||||
CLK_PTO_XUSB_FALCON = 0x110,
|
||||
CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
|
||||
CLK_PTO_XUSB_FALCON = 0x110, // Branches: 0x150 0x190 0x1D0.
|
||||
CLK_PTO_XUSB_CLK480M_HSIC = 0x111, // Branches: 0x151 0x191 0x1D1.
|
||||
CLK_PTO_USB_L0_RX = 0x112,
|
||||
CLK_PTO_USB_L3_RX = 0x113,
|
||||
CLK_PTO_USB_RX = 0x114,
|
||||
CLK_PTO_USB3_L0_TXCLKREF = 0x115,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
|
||||
@@ -419,12 +418,12 @@ typedef enum _clock_pto_id_t
|
||||
CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
|
||||
CLK_PTO_USB3_L7_RX = 0x12B,
|
||||
CLK_PTO_USB3_TX = 0x12C,
|
||||
CLK_PTO_UTMIP_PLL_PAD = 0x12D,
|
||||
CLK_PTO_UTMIP_PLL_PAD = 0x12D, // Branches: 0x16D 0x1AD 0x1ED.
|
||||
|
||||
CLK_PTO_XUSB_FS = 0x136,
|
||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
||||
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
||||
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
||||
CLK_PTO_XUSB_FS = 0x136, // Branches: 0x176 0x1B6 0x1F6.
|
||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137, // Branches: 0x177 0x1B7 0x1F7.
|
||||
CLK_PTO_XUSB_CORE_HOST = 0x138, // Branches: 0x178 0x1B8 0x1F8.
|
||||
CLK_PTO_XUSB_CORE_DEV = 0x139, // Branches: 0x179 0x1B9 0x1F9.
|
||||
|
||||
CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
|
||||
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
|
||||
@@ -449,13 +448,13 @@ typedef enum _clock_pto_id_t
|
||||
CLK_PTO_PLLC2_DIV2 = 0x58,
|
||||
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
||||
|
||||
CLK_PTO_PLLD_DIV2 = 0xCB,
|
||||
CLK_PTO_PLLD_DIV2 = 0xCB, // Branches: 0xDB, 0xEB, 0xFB.
|
||||
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
||||
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
||||
|
||||
CLK_PTO_PLLE_DIV2 = 0x10B,
|
||||
|
||||
CLK_PTO_PLLU_DIV2 = 0x10D,
|
||||
CLK_PTO_PLLU_DIV2 = 0x10D, // Branches: 0x14D 0x18D 0x1CD.
|
||||
|
||||
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
||||
} clock_pto_id_t;
|
||||
@@ -473,109 +472,85 @@ typedef enum _clock_pto_id_t
|
||||
|
||||
enum CLK_L_DEV
|
||||
{
|
||||
CLK_L_CPU = 0, // Only reset. Deprecated.
|
||||
CLK_L_BPMP = 1, // Only reset.
|
||||
CLK_L_SYS = 2, // Only reset.
|
||||
CLK_L_ISPB = 3,
|
||||
CLK_L_RTC = 4,
|
||||
CLK_L_TMR = 5,
|
||||
CLK_L_UARTA = 6,
|
||||
CLK_L_UARTB = 7,
|
||||
CLK_L_GPIO = 8,
|
||||
CLK_L_SDMMC2 = 9,
|
||||
CLK_L_SPDIF = 10,
|
||||
CLK_L_I2S2 = 11, // I2S1
|
||||
CLK_L_I2C1 = 12,
|
||||
CLK_L_NDFLASH = 13, // HIDDEN.
|
||||
CLK_L_SDMMC1 = 14,
|
||||
CLK_L_SDMMC4 = 15,
|
||||
CLK_L_TWC = 16, // HIDDEN.
|
||||
CLK_L_PWM = 17,
|
||||
CLK_L_I2S3 = 18,
|
||||
CLK_L_EPP = 19, // HIDDEN.
|
||||
CLK_L_VI = 20,
|
||||
CLK_L_2D = 21, // HIDDEN.
|
||||
CLK_L_USBD = 22,
|
||||
CLK_L_ISP = 23,
|
||||
CLK_L_3D = 24, // HIDDEN.
|
||||
CLK_L_IDE = 25, // RESERVED.
|
||||
CLK_L_DISP2 = 26,
|
||||
CLK_L_DISP1 = 27,
|
||||
CLK_L_HOST1X = 28,
|
||||
CLK_L_VCP = 29, // HIDDEN.
|
||||
CLK_L_I2S1 = 30, // I2S0
|
||||
CLK_L_BPMP_CACHE_CTRL = 31, // CONTROLLER
|
||||
CLK_L_CPU = 0, // Deprecated.
|
||||
CLK_L_BPMP = 1, // Only reset.
|
||||
CLK_L_SYS = 2, // Only reset.
|
||||
CLK_L_ISPB = 3,
|
||||
CLK_L_RTC = 4, // Only enable.
|
||||
CLK_L_TMR = 5,
|
||||
CLK_L_UARTA = 6,
|
||||
CLK_L_UARTB = 7,
|
||||
CLK_L_GPIO = 8,
|
||||
CLK_L_SDMMC2 = 9,
|
||||
CLK_L_SPDIF = 10, // Only enable.
|
||||
CLK_L_I2S2 = 11, // Only enable.
|
||||
CLK_L_I2C1 = 12,
|
||||
CLK_L_SDMMC1 = 14,
|
||||
CLK_L_SDMMC4 = 15,
|
||||
CLK_L_TWC = 16, // 3-Wire Controller. Deprecated.
|
||||
CLK_L_PWM = 17,
|
||||
CLK_L_I2S3 = 18, // Only enable.
|
||||
CLK_L_VI = 20,
|
||||
CLK_L_USBD = 22,
|
||||
CLK_L_ISP = 23,
|
||||
CLK_L_DISP2 = 26,
|
||||
CLK_L_DISP1 = 27,
|
||||
CLK_L_HOST1X = 28,
|
||||
CLK_L_I2S1 = 30, // Only enable.
|
||||
CLK_L_BPMP_CACHE_CTRL = 31, // Controller.
|
||||
};
|
||||
|
||||
enum CLK_H_DEV
|
||||
{
|
||||
CLK_H_MEM = 0, // MC.
|
||||
CLK_H_AHBDMA = 1,
|
||||
CLK_H_APBDMA = 2,
|
||||
//CLK_H_ = 3,
|
||||
CLK_H_KBC = 4, // HIDDEN.
|
||||
CLK_H_STAT_MON = 5,
|
||||
CLK_H_PMC = 6,
|
||||
CLK_H_FUSE = 7,
|
||||
CLK_H_KFUSE = 8,
|
||||
CLK_H_SPI1 = 9,
|
||||
CLK_H_SNOR = 10, // HIDDEN.
|
||||
CLK_H_JTAG2TBC = 11,
|
||||
CLK_H_MEM = 0, // MC.
|
||||
CLK_H_AHBDMA = 1,
|
||||
CLK_H_APBDMA = 2,
|
||||
CLK_H_STAT_MON = 5,
|
||||
CLK_H_PMC = 6, // Only enable.
|
||||
CLK_H_FUSE = 7,
|
||||
CLK_H_KFUSE = 8,
|
||||
CLK_H_SPI1 = 9,
|
||||
CLK_H_SPI2 = 12,
|
||||
CLK_H_XIO = 13, // HIDDEN.
|
||||
CLK_H_XIO = 13, // Misc IO. Deprecated?
|
||||
CLK_H_SPI3 = 14,
|
||||
CLK_H_I2C5 = 15,
|
||||
CLK_H_DSI = 16,
|
||||
CLK_H_TVO = 17, // RESERVED.
|
||||
CLK_H_HSI = 18, // HIDDEN.
|
||||
CLK_H_HDMI = 19, // HIDDEN.
|
||||
CLK_H_CSI = 20,
|
||||
CLK_H_TVDAC = 21, // RESERVED.
|
||||
CLK_H_I2C2 = 22,
|
||||
CLK_H_UARTC = 23,
|
||||
CLK_H_MIPI_CAL = 24,
|
||||
CLK_H_EMC = 25,
|
||||
CLK_H_USB2 = 26,
|
||||
CLK_H_USB3 = 27, // HIDDEN.
|
||||
CLK_H_MPE = 28, // HIDDEN.
|
||||
CLK_H_VDE = 29, // HIDDEN.
|
||||
CLK_H_BSEA = 30, // HIDDEN.
|
||||
CLK_H_BSEV = 31,
|
||||
};
|
||||
|
||||
enum CLK_U_DEV
|
||||
{
|
||||
CLK_U_SPEEDO = 0, // RESERVED.
|
||||
CLK_U_UARTD = 1,
|
||||
CLK_U_UARTE = 2, // HIDDEN.
|
||||
CLK_U_I2C3 = 3,
|
||||
CLK_U_SPI4 = 4,
|
||||
CLK_U_SDMMC3 = 5,
|
||||
CLK_U_PCIE = 6,
|
||||
CLK_U_OWR = 7, // RESERVED.
|
||||
CLK_U_AFI = 8,
|
||||
CLK_U_CSITE = 9,
|
||||
//CLK_U_SPEEDO = 0, // RESERVED. Old speedo ring oscillator.
|
||||
CLK_U_UARTD = 1,
|
||||
CLK_U_I2C3 = 3,
|
||||
CLK_U_SPI4 = 4,
|
||||
CLK_U_SDMMC3 = 5,
|
||||
CLK_U_PCIE = 6,
|
||||
CLK_U_OWR = 7, // 1-Wire Controller. Deprecated.
|
||||
CLK_U_AFI = 8,
|
||||
CLK_U_CSITE = 9,
|
||||
CLK_U_PCIEXCLK = 10, // Only reset.
|
||||
CLK_U_BPMPUCQ = 11, // HIDDEN.
|
||||
CLK_U_LA = 12,
|
||||
CLK_U_TRACECLKIN = 13, // HIDDEN.
|
||||
CLK_U_LA = 12, // DFD.
|
||||
CLK_U_SOC_THERM = 14,
|
||||
CLK_U_DTV = 15,
|
||||
CLK_U_NAND_SPEED = 16, // HIDDEN.
|
||||
CLK_U_DTV = 15, // Deprecated.
|
||||
CLK_U_I2C_SLOW = 17,
|
||||
CLK_U_DSIB = 18,
|
||||
CLK_U_TSEC = 19,
|
||||
CLK_U_IRAMA = 20,
|
||||
CLK_U_IRAMB = 21,
|
||||
CLK_U_IRAMC = 22,
|
||||
CLK_U_IRAMA = 20, // Only enable.
|
||||
CLK_U_IRAMB = 21, // Only enable.
|
||||
CLK_U_IRAMC = 22, // Only enable.
|
||||
CLK_U_IRAMD = 23, // EMUCIF ON RESET
|
||||
CLK_U_BPMP_CACHE_RAM = 24,
|
||||
CLK_U_BPMP_CACHE_RAM = 24, // Only enable.
|
||||
CLK_U_XUSB_HOST = 25,
|
||||
CLK_U_CLK_M_DOUBLER = 26,
|
||||
CLK_U_MSENC = 27, // HIDDEN.
|
||||
CLK_U_SUS_OUT = 28,
|
||||
CLK_U_DEV2_OUT = 29,
|
||||
CLK_U_DEV1_OUT = 30,
|
||||
CLK_U_SUS_OUT = 28, // Only enable. VI MCLK. Deprecated?
|
||||
CLK_U_DEV2_OUT = 29, // Only enable. DAP MCLK. Deprecated?
|
||||
CLK_U_DEV1_OUT = 30, // Only enable. DAP MCLK. Deprecated?
|
||||
CLK_U_XUSB_DEV = 31,
|
||||
};
|
||||
|
||||
@@ -583,133 +558,109 @@ enum CLK_V_DEV
|
||||
{
|
||||
CLK_V_CPUG = 0,
|
||||
CLK_V_CPULP = 1, // Reserved.
|
||||
CLK_V_3D2 = 2, // HIDDEN.
|
||||
CLK_V_MSELECT = 3,
|
||||
CLK_V_TSENSOR = 4,
|
||||
CLK_V_I2S4 = 5,
|
||||
CLK_V_I2S5 = 6,
|
||||
CLK_V_TSENSOR = 4, // Only enable.
|
||||
CLK_V_I2S4 = 5, // Only enable.
|
||||
CLK_V_I2S5 = 6, // Only enable.
|
||||
CLK_V_I2C4 = 7,
|
||||
CLK_V_SPI5 = 8, // HIDDEN.
|
||||
CLK_V_SPI6 = 9, // HIDDEN.
|
||||
CLK_V_AHUB = 10, // AUDIO.
|
||||
CLK_V_APB2APE = 11, // APBIF.
|
||||
CLK_V_DAM0 = 12, // HIDDEN.
|
||||
CLK_V_DAM1 = 13, // HIDDEN.
|
||||
CLK_V_DAM2 = 14, // HIDDEN.
|
||||
CLK_V_AHUB = 10, // AUDIO. Only enable.
|
||||
CLK_V_APB2APE = 11, // APBIF. Only enable.
|
||||
CLK_V_HDA2CODEC_2X = 15,
|
||||
CLK_V_ATOMICS = 16,
|
||||
//CLK_V_ = 17,
|
||||
//CLK_V_ = 18,
|
||||
//CLK_V_ = 19,
|
||||
//CLK_V_ = 20,
|
||||
//CLK_V_ = 21,
|
||||
CLK_V_SPDIF_DOUBLER = 22,
|
||||
CLK_V_SPDIF_DOUBLER = 22, // Only enable.
|
||||
CLK_V_ACTMON = 23,
|
||||
CLK_V_EXTPERIPH1 = 24,
|
||||
CLK_V_EXTPERIPH2 = 25,
|
||||
CLK_V_EXTPERIPH3 = 26,
|
||||
CLK_V_SATA_OOB = 27,
|
||||
CLK_V_SATA = 28,
|
||||
CLK_V_SATA_OOB = 27, // Only on T210.
|
||||
CLK_V_SATA = 28, // Only on T210.
|
||||
CLK_V_HDA = 29,
|
||||
CLK_V_TZRAM = 30, // HIDDEN.
|
||||
CLK_V_SE = 31, // HIDDEN.
|
||||
CLK_V_TZRAM = 30,
|
||||
CLK_V_SE = 31,
|
||||
};
|
||||
|
||||
enum CLK_W_DEV
|
||||
{
|
||||
CLK_W_HDA2HDMICODEC = 0,
|
||||
CLK_W_RESERVED0 = 1, //satacoldrstn
|
||||
CLK_W_PCIERX0 = 2,
|
||||
CLK_W_PCIERX1 = 3,
|
||||
CLK_W_PCIERX2 = 4,
|
||||
CLK_W_PCIERX3 = 5,
|
||||
CLK_W_PCIERX4 = 6,
|
||||
CLK_W_PCIERX5 = 7,
|
||||
CLK_W_CEC = 8,
|
||||
CLK_W_PCIE2_IOBIST = 9,
|
||||
CLK_W_EMC_IOBIST = 10,
|
||||
CLK_W_HDMI_IOBIST = 11, // HIDDEN.
|
||||
CLK_W_SATA_IOBIST = 12,
|
||||
CLK_W_MIPI_IOBIST = 13,
|
||||
CLK_W_HDA2HDMICODEC = 0,
|
||||
CLK_W_SATACOLD = 1, // Enable reserved. Unused.
|
||||
CLK_W_PCIERX0 = 2, // Reset reserved.
|
||||
CLK_W_PCIERX1 = 3, // Reset reserved.
|
||||
CLK_W_PCIERX2 = 4, // Reset reserved.
|
||||
CLK_W_PCIERX3 = 5, // Reset reserved.
|
||||
CLK_W_PCIERX4 = 6, // Reset reserved.
|
||||
CLK_W_PCIERX5 = 7, // Reset reserved.
|
||||
CLK_W_CEC = 8,
|
||||
CLK_W_PCIE2_IOBIST = 9, // Reset reserved.
|
||||
CLK_W_EMC_IOBIST = 10, // Reset reserved.
|
||||
CLK_W_SATA_IOBIST = 12, // Reset reserved.
|
||||
CLK_W_MIPI_IOBIST = 13, // Reset reserved.
|
||||
CLK_W_XUSB_PADCTL = 14, // Only reset.
|
||||
CLK_W_XUSB = 15,
|
||||
CLK_W_CILAB = 16,
|
||||
CLK_W_CILCD = 17,
|
||||
CLK_W_CILEF = 18,
|
||||
CLK_W_DSIA_LP = 19,
|
||||
CLK_W_DSIB_LP = 20,
|
||||
CLK_W_XUSB = 15, // Only enable.
|
||||
CLK_W_CILAB = 16, // Only enable.
|
||||
CLK_W_CILCD = 17, // Only enable.
|
||||
CLK_W_CILEF = 18, // Only enable.
|
||||
CLK_W_DSIA_LP = 19, // Only enable.
|
||||
CLK_W_DSIB_LP = 20, // Only enable.
|
||||
CLK_W_ENTROPY = 21,
|
||||
CLK_W_DDS = 22, // HIDDEN.
|
||||
//CLK_W_ = 23,
|
||||
CLK_W_DP2 = 24, // HIDDEN.
|
||||
CLK_W_AMX0 = 25, // HIDDEN.
|
||||
CLK_W_ADX0 = 26, // HIDDEN.
|
||||
CLK_W_DVFS = 27,
|
||||
CLK_W_XUSB_SS = 28,
|
||||
CLK_W_EMC_LATENCY = 29,
|
||||
CLK_W_MC1 = 30,
|
||||
//CLK_W_ = 31,
|
||||
CLK_W_EMC_LATENCY = 29, // Only enable.
|
||||
CLK_W_MC1 = 30, // Only enable.
|
||||
};
|
||||
|
||||
enum CLK_X_DEV
|
||||
{
|
||||
CLK_X_SPARE = 0,
|
||||
CLK_X_DMIC1 = 1,
|
||||
CLK_X_DMIC2 = 2,
|
||||
CLK_X_ETR = 3,
|
||||
CLK_X_CAM_MCLK = 4,
|
||||
CLK_X_CAM_MCLK2 = 5,
|
||||
CLK_X_I2C6 = 6,
|
||||
CLK_X_MC_CAPA = 7, // MC DAISY CHAIN1
|
||||
CLK_X_MC_CBPA = 8, // MC DAISY CHAIN2
|
||||
CLK_X_MC_CPU = 9,
|
||||
CLK_X_MC_BBC = 10,
|
||||
CLK_X_VIM2_CLK = 11,
|
||||
//CLK_X_ = 12,
|
||||
CLK_X_MIPIBIF = 13, //RESERVED
|
||||
CLK_X_EMC_DLL = 14,
|
||||
//CLK_X_ = 15,
|
||||
CLK_X_HDMI_AUDIO = 16, // HIDDEN.
|
||||
CLK_X_UART_FST_MIPI_CAL = 17,
|
||||
CLK_X_SPARE = 0,
|
||||
CLK_X_DMIC1 = 1, // Only enable.
|
||||
CLK_X_DMIC2 = 2, // Only enable.
|
||||
CLK_X_ETR = 3, // DFD.
|
||||
CLK_X_CAM_MCLK = 4, // Only enable.
|
||||
CLK_X_CAM_MCLK2 = 5, // Only enable.
|
||||
CLK_X_I2C6 = 6,
|
||||
CLK_X_MC_CAPA = 7, // MC Clients daisy chain 1. Only enable.
|
||||
CLK_X_MC_CBPA = 8, // MC Clients daisy chain 2. Only enable.
|
||||
CLK_X_MC_CPU = 9, // MC CPU. Only enable.
|
||||
CLK_X_MC_BBC = 10, // MC Backbone. Only enable.
|
||||
CLK_X_VIM2_CLK = 11, // Only enable.
|
||||
CLK_X_MIPIBIF = 13,
|
||||
CLK_X_EMC_DLL = 14, // Only enable.
|
||||
CLK_X_UART_FST_MIPI_CAL = 17, // Only enable.
|
||||
CLK_X_VIC = 18,
|
||||
//CLK_X_ = 19,
|
||||
CLK_X_ADX1 = 20, // HIDDEN.
|
||||
CLK_X_DPAUX = 21,
|
||||
CLK_X_SOR0 = 22,
|
||||
CLK_X_SOR1 = 23,
|
||||
CLK_X_GPU = 24,
|
||||
CLK_X_DBGAPB = 25,
|
||||
CLK_X_HPLL_ADSP = 26,
|
||||
CLK_X_PLLP_ADSP = 27,
|
||||
CLK_X_PLLA_ADSP = 28,
|
||||
CLK_X_PLLG_REF = 29,
|
||||
//CLK_X_ = 30,
|
||||
//CLK_X_ = 31,
|
||||
CLK_X_DBGAPB = 25, // Only enable.
|
||||
CLK_X_HPLL_ADSP = 26, // Only enable.
|
||||
CLK_X_PLLP_ADSP = 27, // Only enable.
|
||||
CLK_X_PLLA_ADSP = 28, // Only enable.
|
||||
CLK_X_PLLG_REF = 29, // Only enable.
|
||||
CLK_X_EQOS = 30, // T210B01 only.
|
||||
};
|
||||
|
||||
enum CLK_Y_DEV
|
||||
{
|
||||
CLK_Y_SPARE1 = 0,
|
||||
CLK_Y_SDMMC_LEGACY_TM = 1,
|
||||
CLK_Y_NVDEC = 2,
|
||||
CLK_Y_NVJPG = 3,
|
||||
CLK_Y_AXIAP = 4,
|
||||
CLK_Y_DMIC3 = 5,
|
||||
CLK_Y_APE = 6,
|
||||
CLK_Y_ADSP = 7,
|
||||
CLK_Y_MC_CDPA = 8, // MC DAISY CHAIN4
|
||||
CLK_Y_MC_CCPA = 9, // MC DAISY CHAIN3
|
||||
CLK_Y_MAUD = 10,
|
||||
//CLK_Y_ = 11,
|
||||
CLK_Y_SPARE1 = 0,
|
||||
CLK_Y_SDMMC_LEGACY_TM = 1, // Only enable.
|
||||
CLK_Y_NVDEC = 2,
|
||||
CLK_Y_NVJPG = 3,
|
||||
CLK_Y_AXIAP = 4, // DFD.
|
||||
CLK_Y_DMIC3 = 5, // Only enable.
|
||||
CLK_Y_APE = 6,
|
||||
CLK_Y_ADSP = 7,
|
||||
CLK_Y_MC_CDPA = 8, // MC Clients daisy chain 4. Only enable.
|
||||
CLK_Y_MC_CCPA = 9, // MC Clients daisy chain 3. Only enable.
|
||||
CLK_Y_MAUD = 10, // Only enable.
|
||||
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
|
||||
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
|
||||
CLK_Y_TSECB = 14,
|
||||
CLK_Y_DPAUX1 = 15,
|
||||
CLK_Y_VI_I2C = 16,
|
||||
CLK_Y_HSIC_TRK = 17,
|
||||
CLK_Y_USB2_TRK = 18,
|
||||
CLK_Y_HSIC_TRK = 17, // Only enable.
|
||||
CLK_Y_USB2_TRK = 18, // Only enable.
|
||||
CLK_Y_QSPI = 19,
|
||||
CLK_Y_UARTAPE = 20,
|
||||
CLK_Y_UARTAPE = 20, // Only enable.
|
||||
CLK_Y_ADSPINTF = 21, // Only reset.
|
||||
CLK_Y_ADSPPERIPH = 22, // Only reset.
|
||||
CLK_Y_ADSPDBG = 23, // Only reset.
|
||||
@@ -717,20 +668,20 @@ enum CLK_Y_DEV
|
||||
CLK_Y_ADSPSCU = 25, // Only reset.
|
||||
CLK_Y_ADSPNEON = 26,
|
||||
CLK_Y_NVENC = 27,
|
||||
CLK_Y_IQC2 = 28,
|
||||
CLK_Y_IQC1 = 29,
|
||||
CLK_Y_SOR_SAFE = 30,
|
||||
CLK_Y_PLLP_OUT_CPU = 31,
|
||||
CLK_Y_IQC2 = 28, // Only enable. (Audio.)
|
||||
CLK_Y_IQC1 = 29, // Only enable. (Audio.)
|
||||
CLK_Y_SOR_SAFE = 30, // Only enable.
|
||||
CLK_Y_PLLP_OUT_CPU = 31, // Only enable.
|
||||
};
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clk_rst_t
|
||||
{
|
||||
u16 reset;
|
||||
u16 enable;
|
||||
u16 reset; // Reset SET.
|
||||
u16 enable; // Enable SET.
|
||||
u16 source;
|
||||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 index:5;
|
||||
u8 clk_src:3;
|
||||
u8 clk_div;
|
||||
} clk_rst_t;
|
||||
|
||||
@@ -790,10 +741,10 @@ void clock_enable_pllu();
|
||||
void clock_disable_pllu();
|
||||
void clock_enable_utmipll();
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
int clock_sdmmc_is_active(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 clock);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
u32 clock_get_osc_freq();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -22,9 +22,12 @@
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/timer.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
static const u32 evp_thunk_template[] = {
|
||||
@@ -86,6 +89,14 @@ u32 fuse_read_odm_keygen_rev()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _dramid_8gb = false;
|
||||
|
||||
void fuse_force_8gb_dramid()
|
||||
{
|
||||
// Override fuse DRAM ID with a 8GB ID.
|
||||
_dramid_8gb = true;
|
||||
}
|
||||
|
||||
u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
@@ -104,11 +115,17 @@ u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
if (dramid > 7)
|
||||
dramid = 0;
|
||||
|
||||
if (_dramid_8gb)
|
||||
dramid = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dramid > 34)
|
||||
dramid = 8;
|
||||
|
||||
if (_dramid_8gb)
|
||||
dramid = 28;
|
||||
}
|
||||
|
||||
return dramid;
|
||||
@@ -171,22 +188,44 @@ void fuse_wait_idle()
|
||||
;
|
||||
}
|
||||
|
||||
void fuse_sense()
|
||||
{
|
||||
clock_enable_fuse(false);
|
||||
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & (~FUSE_CMD_MASK)) | FUSE_SENSE;
|
||||
usleep(1);
|
||||
|
||||
fuse_wait_idle();
|
||||
|
||||
FUSE(FUSE_PRIV2INTFC) = FUSE_PRIV2INTFC_SKIP_RECORDS | FUSE_PRIV2INTFC_START_DATA;
|
||||
usleep(1);
|
||||
|
||||
while (!(FUSE(FUSE_CTRL) & BIT(30)) || ((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
|
||||
;
|
||||
|
||||
|
||||
clock_enable_fuse(true);
|
||||
}
|
||||
|
||||
u32 fuse_read(u32 addr)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = addr;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
|
||||
fuse_wait_idle();
|
||||
|
||||
return FUSE(FUSE_RDATA);
|
||||
}
|
||||
|
||||
void fuse_read_array(u32 *words)
|
||||
u32 fuse_read_array(u32 *words)
|
||||
{
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
||||
FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM;
|
||||
|
||||
for (u32 i = 0; i < array_size; i++)
|
||||
words[i] = fuse_read(i);
|
||||
|
||||
return array_size;
|
||||
}
|
||||
|
||||
static u32 _parity32_even(const u32 *words, u32 count)
|
||||
|
||||
128
bdk/soc/fuse.h
128
bdk/soc/fuse.h
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -32,8 +32,12 @@
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_PRIV2INTFC_START_DATA BIT(0)
|
||||
#define FUSE_PRIV2INTFC_SKIP_RECORDS BIT(1)
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_PRIVKEY_DISABLE BIT(0)
|
||||
#define FUSE_PRIVKEY_TZ_STICKY_BIT BIT(4)
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
@@ -49,20 +53,20 @@
|
||||
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
|
||||
|
||||
/*! Fuse Cached registers */
|
||||
#define FUSE_RESERVED_ODM8_B01 0x98
|
||||
#define FUSE_RESERVED_ODM9_B01 0x9C
|
||||
#define FUSE_RESERVED_ODM10_B01 0xA0
|
||||
#define FUSE_RESERVED_ODM11_B01 0xA4
|
||||
#define FUSE_RESERVED_ODM12_B01 0xA8
|
||||
#define FUSE_RESERVED_ODM13_B01 0xAC
|
||||
#define FUSE_RESERVED_ODM14_B01 0xB0
|
||||
#define FUSE_RESERVED_ODM15_B01 0xB4
|
||||
#define FUSE_RESERVED_ODM16_B01 0xB8
|
||||
#define FUSE_RESERVED_ODM17_B01 0xBC
|
||||
#define FUSE_RESERVED_ODM18_B01 0xC0
|
||||
#define FUSE_RESERVED_ODM19_B01 0xC4
|
||||
#define FUSE_RESERVED_ODM20_B01 0xC8
|
||||
#define FUSE_RESERVED_ODM21_B01 0xCC
|
||||
#define FUSE_RESERVED_ODM8_B01 0x98 // FUSE_READ_TZ Group 0.
|
||||
#define FUSE_RESERVED_ODM9_B01 0x9C // FUSE_READ_TZ Group 0.
|
||||
#define FUSE_RESERVED_ODM10_B01 0xA0 // FUSE_READ_TZ Group 0.
|
||||
#define FUSE_RESERVED_ODM11_B01 0xA4 // FUSE_READ_TZ Group 0.
|
||||
#define FUSE_RESERVED_ODM12_B01 0xA8 // FUSE_READ_TZ Group 1? Is value -1?
|
||||
#define FUSE_RESERVED_ODM13_B01 0xAC // FUSE_READ_TZ Group 1? Is value -1?
|
||||
#define FUSE_RESERVED_ODM14_B01 0xB0 // FUSE_READ_TZ Group 1? Is value -1?
|
||||
#define FUSE_RESERVED_ODM15_B01 0xB4 // FUSE_READ_TZ Group 1? Is value -1?
|
||||
#define FUSE_RESERVED_ODM16_B01 0xB8 // FUSE_READ_TZ Group 2? Is value -1?
|
||||
#define FUSE_RESERVED_ODM17_B01 0xBC // FUSE_READ_TZ Group 2? Is value -1?
|
||||
#define FUSE_RESERVED_ODM18_B01 0xC0 // FUSE_READ_TZ Group 2.
|
||||
#define FUSE_RESERVED_ODM19_B01 0xC4 // FUSE_READ_TZ Group 2.
|
||||
#define FUSE_RESERVED_ODM20_B01 0xC8 // FUSE_READ_TZ Group 3.
|
||||
#define FUSE_RESERVED_ODM21_B01 0xCC // FUSE_READ_TZ Group 3.
|
||||
#define FUSE_KEK00_B01 0xD0
|
||||
#define FUSE_KEK01_B01 0xD4
|
||||
#define FUSE_KEK02_B01 0xD8
|
||||
@@ -84,9 +88,9 @@
|
||||
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
|
||||
#define FUSE_CPU_IDDQ_CALIB 0x118
|
||||
|
||||
#define FUSE_RESERVED_ODM22_B01 0x11C
|
||||
#define FUSE_RESERVED_ODM23_B01 0x120
|
||||
#define FUSE_RESERVED_ODM24_B01 0x124
|
||||
#define FUSE_RESERVED_ODM22_B01 0x11C // FUSE_READ_TZ Group 3.
|
||||
#define FUSE_RESERVED_ODM23_B01 0x120 // FUSE_READ_TZ Group 3.
|
||||
#define FUSE_RESERVED_ODM24_B01 0x124 // FUSE_READ_TZ Group 4.
|
||||
|
||||
#define FUSE_OPT_FT_REV 0x128
|
||||
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
|
||||
@@ -96,7 +100,7 @@
|
||||
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
|
||||
#define FUSE_SOC_IDDQ_CALIB 0x140
|
||||
|
||||
#define FUSE_RESERVED_ODM25_B01 0x144
|
||||
#define FUSE_RESERVED_ODM25_B01 0x144 // FUSE_READ_TZ Group 4.
|
||||
|
||||
#define FUSE_FA 0x148
|
||||
#define FUSE_RESERVED_PRODUCTION 0x14C
|
||||
@@ -113,14 +117,14 @@
|
||||
#define FUSE_PUBLIC_KEY5 0x178
|
||||
#define FUSE_PUBLIC_KEY6 0x17C
|
||||
#define FUSE_PUBLIC_KEY7 0x180
|
||||
#define FUSE_TSENSOR1_CALIB 0x184
|
||||
#define FUSE_TSENSOR2_CALIB 0x188
|
||||
#define FUSE_TSENSOR1_CALIB 0x184 // CPU1.
|
||||
#define FUSE_TSENSOR2_CALIB 0x188 // CPU2.
|
||||
|
||||
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
|
||||
|
||||
#define FUSE_OPT_CP_REV 0x190
|
||||
#define FUSE_OPT_CP_REV 0x190 // FUSE style revision - ATE. 0x101 0x100
|
||||
#define FUSE_OPT_PFG 0x194
|
||||
#define FUSE_TSENSOR0_CALIB 0x198
|
||||
#define FUSE_TSENSOR0_CALIB 0x198 // CPU0.
|
||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
|
||||
#define FUSE_SECURITY_MODE 0x1A0
|
||||
#define FUSE_PRIVATE_KEY0 0x1A4
|
||||
@@ -149,7 +153,7 @@
|
||||
#define FUSE_USB_CALIB 0x1F0
|
||||
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
|
||||
#define FUSE_PACKAGE_INFO 0x1FC
|
||||
#define FUSE_PACKAGE_INFO 0x1FC // 1: MID, 2: DSC.
|
||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||
#define FUSE_OPT_FAB_CODE 0x204
|
||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||
@@ -164,22 +168,22 @@
|
||||
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
|
||||
|
||||
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||
#define FUSE_TSENSOR3_CALIB 0x22C
|
||||
#define FUSE_TSENSOR3_CALIB 0x22C // CPU3.
|
||||
#define FUSE_CLOCK_BONDOUT0 0x230
|
||||
#define FUSE_CLOCK_BONDOUT1 0x234
|
||||
|
||||
#define FUSE_RESERVED_ODM26_B01 0x238
|
||||
#define FUSE_RESERVED_ODM27_B01 0x23C
|
||||
#define FUSE_RESERVED_ODM28_B01 0x240
|
||||
#define FUSE_RESERVED_ODM26_B01 0x238 // FUSE_READ_TZ Group 4.
|
||||
#define FUSE_RESERVED_ODM27_B01 0x23C // FUSE_READ_TZ Group 4.
|
||||
#define FUSE_RESERVED_ODM28_B01 0x240 // MAX77812 phase configuration. FUSE_READ_TZ Group 5.
|
||||
|
||||
#define FUSE_OPT_SAMPLE_TYPE 0x244
|
||||
#define FUSE_OPT_SUBREVISION 0x248
|
||||
#define FUSE_OPT_SUBREVISION 0x248 // "", "p", "q", "r". e.g: A01p.
|
||||
#define FUSE_OPT_SW_RESERVED_0 0x24C
|
||||
#define FUSE_OPT_SW_RESERVED_1 0x250
|
||||
#define FUSE_TSENSOR4_CALIB 0x254
|
||||
#define FUSE_TSENSOR5_CALIB 0x258
|
||||
#define FUSE_TSENSOR6_CALIB 0x25C
|
||||
#define FUSE_TSENSOR7_CALIB 0x260
|
||||
#define FUSE_TSENSOR4_CALIB 0x254 // GPU.
|
||||
#define FUSE_TSENSOR5_CALIB 0x258 // MEM0.
|
||||
#define FUSE_TSENSOR6_CALIB 0x25C // MEM1.
|
||||
#define FUSE_TSENSOR7_CALIB 0x260 // PLLX.
|
||||
#define FUSE_OPT_PRIV_SEC_DIS 0x264
|
||||
#define FUSE_PKC_DISABLE 0x268
|
||||
|
||||
@@ -196,10 +200,10 @@
|
||||
#define FUSE_OPT_FT_BIN 0x28C
|
||||
#define FUSE_OPT_DONE_MAP 0x290
|
||||
|
||||
#define FUSE_RESERVED_ODM29_B01 0x294
|
||||
#define FUSE_RESERVED_ODM29_B01 0x294 // FUSE_READ_TZ Group 5? Is value -1?
|
||||
|
||||
#define FUSE_APB2JTAG_DISABLE 0x298
|
||||
#define FUSE_ODM_INFO 0x29C
|
||||
#define FUSE_ODM_INFO 0x29C // Debug features disable.
|
||||
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
|
||||
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
|
||||
@@ -210,9 +214,12 @@
|
||||
#define FUSE_WOA_SKU_FLAG 0x2C0
|
||||
#define FUSE_ECO_RESERVE_1 0x2C4
|
||||
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
|
||||
#define FUSE_GPU_VPR_AUTO_FETCH_DIS BIT(0)
|
||||
#define FUSE_GPU_VPR_ENABLED BIT(1)
|
||||
#define FUSE_GPU_WPR_ENABLED BIT(2)
|
||||
#define FUSE_PRODUCTION_MONTH 0x2CC
|
||||
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
|
||||
#define FUSE_TSENSOR9_CALIB 0x2D4
|
||||
#define FUSE_TSENSOR9_CALIB 0x2D4 // AOTAG.
|
||||
#define FUSE_VMIN_CALIBRATION 0x2DC
|
||||
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
|
||||
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
|
||||
@@ -220,8 +227,8 @@
|
||||
#define FUSE_SECURE_PROVISION_INFO 0x2EC
|
||||
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
|
||||
#define FUSE_SPARE_ENDIS 0x2F4
|
||||
#define FUSE_ECO_RESERVE_0 0x2F8
|
||||
#define FUSE_RESERVED_CALIB0 0x304
|
||||
#define FUSE_ECO_RESERVE_0 0x2F8 // AID.
|
||||
#define FUSE_RESERVED_CALIB0 0x304 // GPCPLL ADC Calibration.
|
||||
#define FUSE_RESERVED_CALIB1 0x308
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
|
||||
@@ -239,7 +246,7 @@
|
||||
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
|
||||
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
|
||||
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
|
||||
#define FUSE_OPT_ROM_SVOP_SP_B01 0x334
|
||||
#define FUSE_OPT_RAM_SVOP_SP_B01 0x334
|
||||
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
|
||||
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
|
||||
@@ -248,7 +255,7 @@
|
||||
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
|
||||
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
|
||||
#define FUSE_USB_CALIB_EXT 0x350
|
||||
#define FUSE_RESERVED_FIELD 0x354
|
||||
#define FUSE_RESERVED_FIELD 0x354 // RMA.
|
||||
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
|
||||
#define FUSE_SPARE_BIT_0 0x380
|
||||
//...
|
||||
@@ -262,24 +269,24 @@
|
||||
#define FUSE_CMD_MASK 0x3
|
||||
|
||||
/*! Fuse status. */
|
||||
#define FUSE_STATUS_RESET 0
|
||||
#define FUSE_STATUS_POST_RESET 1
|
||||
#define FUSE_STATUS_LOAD_ROW0 2
|
||||
#define FUSE_STATUS_LOAD_ROW1 3
|
||||
#define FUSE_STATUS_IDLE 4
|
||||
#define FUSE_STATUS_READ_SETUP 5
|
||||
#define FUSE_STATUS_READ_STROBE 6
|
||||
#define FUSE_STATUS_SAMPLE_FUSES 7
|
||||
#define FUSE_STATUS_READ_HOLD 8
|
||||
#define FUSE_STATUS_FUSE_SRC_SETUP 9
|
||||
#define FUSE_STATUS_WRITE_SETUP 10
|
||||
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
|
||||
#define FUSE_STATUS_WRITE_PROGRAM 12
|
||||
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
|
||||
#define FUSE_STATUS_FUSE_SRC_HOLD 14
|
||||
#define FUSE_STATUS_LOAD_RIR 15
|
||||
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
|
||||
#define FUSE_STATUS_READ_DEASSERT_PD 17
|
||||
#define FUSE_STATUS_RESET 0
|
||||
#define FUSE_STATUS_POST_RESET 1
|
||||
#define FUSE_STATUS_LOAD_ROW0 2
|
||||
#define FUSE_STATUS_LOAD_ROW1 3
|
||||
#define FUSE_STATUS_IDLE 4
|
||||
#define FUSE_STATUS_READ_SETUP 5
|
||||
#define FUSE_STATUS_READ_STROBE 6
|
||||
#define FUSE_STATUS_SAMPLE_FUSES 7
|
||||
#define FUSE_STATUS_READ_HOLD 8
|
||||
#define FUSE_STATUS_FUSE_SRC_SETUP 9
|
||||
#define FUSE_STATUS_WRITE_SETUP 10
|
||||
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
|
||||
#define FUSE_STATUS_WRITE_PROGRAM 12
|
||||
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
|
||||
#define FUSE_STATUS_FUSE_SRC_HOLD 14
|
||||
#define FUSE_STATUS_LOAD_RIR 15
|
||||
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
|
||||
#define FUSE_STATUS_READ_DEASSERT_PD 17
|
||||
|
||||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
@@ -304,14 +311,17 @@ enum
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
u32 fuse_read_odm_keygen_rev();
|
||||
void fuse_force_8gb_dramid();
|
||||
u32 fuse_read_dramid(bool raw_id);
|
||||
u32 fuse_read_hw_state();
|
||||
u32 fuse_read_hw_type();
|
||||
int fuse_set_sbk();
|
||||
void fuse_wait_idle();
|
||||
void fuse_sense();
|
||||
u32 fuse_read(u32 addr);
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
void fuse_read_array(u32 *words);
|
||||
u32 fuse_read_array(u32 *words);
|
||||
bool fuse_check_patched_rcm();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -47,9 +47,6 @@
|
||||
#include <thermal/tmp451.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
u32 hw_rst_status;
|
||||
u32 hw_rst_reason;
|
||||
|
||||
@@ -77,10 +74,10 @@ static void _config_oscillators()
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
APB_MISC(APB_MISC_GP_ASDBGREG) = (APB_MISC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
@@ -155,16 +152,34 @@ static void _config_pmc_scratch()
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
static void _mbist_workaround()
|
||||
static void _mbist_workaround_bl()
|
||||
{
|
||||
// Make sure Audio clocks are enabled before accessing I2S.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
/*
|
||||
* DFT MBIST HW Errata for T210.
|
||||
* RAM Data corruption observed when MBIST_EN from DFT (Tegra X1 Si Errata)
|
||||
*
|
||||
* The MBIST_EN signals from the DFT logic can impact the functional logic of
|
||||
* internal rams after power-on since they are driven by non-resetable flops.
|
||||
* That can be worked around by enabling and then disabling the related clocks.
|
||||
*
|
||||
* The bootrom patches, already handle the LVL2 SLCG war by enabling all clocks
|
||||
* and all LVL2 CLK overrides (power saving disable).
|
||||
* The Bootloader then handles the IP block SLCG part and also restores the
|
||||
* state for the clocks/lvl2 slcg.
|
||||
* After these, per domain MBIST WAR is needed every time a domain gets
|
||||
* unpowergated if it was previously powergated.
|
||||
*
|
||||
* Affected power domains: all except IRAM and CCPLEX.
|
||||
*/
|
||||
|
||||
// Set mux output to SOR1 clock switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
|
||||
// Enabled PLLD and set csi to PLLD for test pattern generation.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
|
||||
// Set mux output to SOR1 clock switch (for VI).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) & ~BIT(14)) | BIT(15);
|
||||
// Enable PLLD and set csi to PLLD for test pattern generation (for VI).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= PLL_BASE_ENABLE | BIT(23);
|
||||
|
||||
// Make sure Audio clocks are enabled before accessing I2S.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||
|
||||
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
|
||||
@@ -172,78 +187,73 @@ static void _mbist_workaround()
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
usleep(2);
|
||||
|
||||
// I2S channels to master and disable SLCG.
|
||||
I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
|
||||
// Set SLCG overrides.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
|
||||
// Set I2S to master to enable clocks and set SLCG overrides.
|
||||
for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||
{
|
||||
I2S(I2S_CTRL + (i2s_idx << 8u)) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_DISABLE;
|
||||
}
|
||||
// Set SLCG overrides for DISPA and VIC.
|
||||
DISPLAY_A(DC_COM_DSC_TOP_CTL) |= BIT(2); // DSC_SLCG_OVERRIDE.
|
||||
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||
|
||||
// Wait a bit for MBIST_EN to get unstuck (1 cycle min).
|
||||
usleep(2);
|
||||
|
||||
// Reset SLCG to automatic mode.
|
||||
// for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||
// I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_ENABLE;
|
||||
// DISPLAY_A(DC_COM_DSC_TOP_CTL) &= ~BIT(2); // DSC_SLCG_OVERRIDE.
|
||||
// VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0;
|
||||
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
|
||||
|
||||
// Enable specific clocks and disable all others.
|
||||
// Disable all unneeded clocks that were enabled in bootrom.
|
||||
// CLK L Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
|
||||
BIT(CLK_H_PMC) |
|
||||
BIT(CLK_H_FUSE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = BIT(CLK_H_PMC) |
|
||||
BIT(CLK_H_FUSE);
|
||||
// CLK H Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
|
||||
BIT(CLK_L_RTC) |
|
||||
BIT(CLK_L_TMR) |
|
||||
BIT(CLK_L_GPIO) |
|
||||
BIT(CLK_L_BPMP_CACHE_CTRL);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = BIT(CLK_L_RTC) |
|
||||
BIT(CLK_L_TMR) |
|
||||
BIT(CLK_L_GPIO) |
|
||||
BIT(CLK_L_BPMP_CACHE_CTRL);
|
||||
// CLK U Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
|
||||
BIT(CLK_U_CSITE) |
|
||||
BIT(CLK_U_IRAMA) |
|
||||
BIT(CLK_U_IRAMB) |
|
||||
BIT(CLK_U_IRAMC) |
|
||||
BIT(CLK_U_IRAMD) |
|
||||
BIT(CLK_U_BPMP_CACHE_RAM);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = BIT(CLK_U_CSITE) |
|
||||
BIT(CLK_U_IRAMA) |
|
||||
BIT(CLK_U_IRAMB) |
|
||||
BIT(CLK_U_IRAMC) |
|
||||
BIT(CLK_U_IRAMD) |
|
||||
BIT(CLK_U_BPMP_CACHE_RAM);
|
||||
// CLK V Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
|
||||
BIT(CLK_V_MSELECT) |
|
||||
BIT(CLK_V_APB2APE) |
|
||||
BIT(CLK_V_SPDIF_DOUBLER) |
|
||||
BIT(CLK_V_SE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = BIT(CLK_V_MSELECT) |
|
||||
BIT(CLK_V_APB2APE) |
|
||||
BIT(CLK_V_SPDIF_DOUBLER) |
|
||||
BIT(CLK_V_SE);
|
||||
// CLK W Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
|
||||
BIT(CLK_W_PCIERX0) |
|
||||
BIT(CLK_W_PCIERX1) |
|
||||
BIT(CLK_W_PCIERX2) |
|
||||
BIT(CLK_W_PCIERX3) |
|
||||
BIT(CLK_W_PCIERX4) |
|
||||
BIT(CLK_W_PCIERX5) |
|
||||
BIT(CLK_W_ENTROPY) |
|
||||
BIT(CLK_W_MC1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = BIT(CLK_W_PCIERX0) |
|
||||
BIT(CLK_W_PCIERX1) |
|
||||
BIT(CLK_W_PCIERX2) |
|
||||
BIT(CLK_W_PCIERX3) |
|
||||
BIT(CLK_W_PCIERX4) |
|
||||
BIT(CLK_W_PCIERX5) |
|
||||
BIT(CLK_W_ENTROPY) |
|
||||
BIT(CLK_W_MC1);
|
||||
// CLK X Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
|
||||
BIT(CLK_X_MC_CAPA) |
|
||||
BIT(CLK_X_MC_CBPA) |
|
||||
BIT(CLK_X_MC_CPU) |
|
||||
BIT(CLK_X_MC_BBC) |
|
||||
BIT(CLK_X_GPU) |
|
||||
BIT(CLK_X_DBGAPB) |
|
||||
BIT(CLK_X_PLLG_REF);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = BIT(CLK_X_MC_CAPA) |
|
||||
BIT(CLK_X_MC_CBPA) |
|
||||
BIT(CLK_X_MC_CPU) |
|
||||
BIT(CLK_X_MC_BBC) |
|
||||
BIT(CLK_X_GPU) |
|
||||
BIT(CLK_X_DBGAPB) |
|
||||
BIT(CLK_X_PLLG_REF);
|
||||
// CLK Y Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
|
||||
BIT(CLK_Y_MC_CDPA) |
|
||||
BIT(CLK_Y_MC_CCPA);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = BIT(CLK_Y_MC_CDPA) |
|
||||
BIT(CLK_Y_MC_CCPA);
|
||||
|
||||
// Disable clock gate overrides.
|
||||
// Reset clock gate overrides to automatic mode.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
|
||||
@@ -252,10 +262,10 @@ static void _mbist_workaround()
|
||||
|
||||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= ~(BIT(15) | BIT(14)); // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
static void _config_se_brom()
|
||||
@@ -266,6 +276,9 @@ static void _config_se_brom()
|
||||
// Try to set SBK from fuses. If patched, skip.
|
||||
fuse_set_sbk();
|
||||
|
||||
// Make SBK unreadable.
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = FUSE_PRIVKEY_TZ_STICKY_BIT | FUSE_PRIVKEY_DISABLE;
|
||||
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
@@ -365,17 +378,16 @@ void hw_init()
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||
|
||||
// Bootrom stuff we skipped by going through rcm.
|
||||
// Bootrom stuff we might skipped by going through rcm.
|
||||
_config_se_brom();
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
|
||||
|
||||
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
|
||||
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
|
||||
|
||||
// Perform Memory Built-In Self Test WAR if T210.
|
||||
// Perform the bootloader part of the Memory Built-In Self Test WAR if T210.
|
||||
if (tegra_t210)
|
||||
_mbist_workaround();
|
||||
_mbist_workaround_bl();
|
||||
|
||||
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
|
||||
@@ -422,12 +434,13 @@ void hw_init()
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||
|
||||
// Power on T210B01 shadow TZRAM and lock the reg.
|
||||
// Disable T210B01 TZRAM power-gating and lock the reg.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
// This is not actually needed since it's done by bootrom. The read locks are extra.
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL_B01) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE_B01) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE_B01) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
}
|
||||
|
||||
// Set arbiter.
|
||||
@@ -455,9 +468,14 @@ void hw_init()
|
||||
#endif
|
||||
}
|
||||
|
||||
void hw_deinit(bool coreboot, u32 bl_magic)
|
||||
void hw_deinit(bool keep_display)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
// Seamless display or display power off.
|
||||
if (!keep_display)
|
||||
{
|
||||
display_end();
|
||||
clock_disable_host1x();
|
||||
}
|
||||
|
||||
// Scale down BPMP clock.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
@@ -472,9 +490,8 @@ void hw_deinit(bool coreboot, u32 bl_magic)
|
||||
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||
#endif
|
||||
|
||||
// set DRAM clock to 204MHz.
|
||||
minerva_change_freq(FREQ_204);
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
// Set DRAM clock to 204MHz.
|
||||
minerva_deinit();
|
||||
|
||||
// Flush/disable MMU cache.
|
||||
bpmp_mmu_disable();
|
||||
@@ -482,43 +499,10 @@ void hw_deinit(bool coreboot, u32 bl_magic)
|
||||
// Reset arbiter.
|
||||
hw_config_arbiter(true);
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
if (tegra_t210)
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to rerunning mbist war.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
}
|
||||
|
||||
// Do coreboot mitigations.
|
||||
if (coreboot)
|
||||
{
|
||||
msleep(10);
|
||||
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
// Disable Joy-con detect in order to restore UART TX.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
// Reinstate SD controller power.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
|
||||
}
|
||||
|
||||
// Seamless display or display power off.
|
||||
switch (bl_magic)
|
||||
{
|
||||
case BL_MAGIC_CRBOOT_SLD:;
|
||||
// Set pwm to 0%, switch to gpio mode and restore pwm duty.
|
||||
u32 brightness = display_get_backlight_brightness();
|
||||
display_backlight_brightness(0, 1000);
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
display_backlight_brightness(brightness, 0);
|
||||
break;
|
||||
case BL_MAGIC_L4TLDR_SLD:
|
||||
// Do not disable display or backlight at all.
|
||||
break;
|
||||
default:
|
||||
display_end();
|
||||
clock_disable_host1x();
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -20,14 +20,11 @@
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
|
||||
#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1.
|
||||
|
||||
extern u32 hw_rst_status;
|
||||
extern u32 hw_rst_reason;
|
||||
|
||||
void hw_init();
|
||||
void hw_deinit(bool coreboot, u32 magic);
|
||||
void hw_deinit(bool keep_display);
|
||||
void hw_config_arbiter(bool reset);
|
||||
u32 hw_get_chip_id();
|
||||
|
||||
|
||||
208
bdk/soc/i2c.c
208
bdk/soc/i2c.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -49,6 +49,9 @@
|
||||
#define I2C_TX_FIFO (0x50 / 4)
|
||||
#define I2C_RX_FIFO (0x54 / 4)
|
||||
|
||||
#define I2C_PACKET_TRANSFER_STATUS (0x58 / 4)
|
||||
#define PKT_TRANSFER_COMPLETE BIT(24)
|
||||
|
||||
#define I2C_FIFO_CONTROL (0x5C / 4)
|
||||
#define RX_FIFO_FLUSH BIT(0)
|
||||
#define TX_FIFO_FLUSH BIT(1)
|
||||
@@ -96,10 +99,10 @@ static void _i2c_load_cfg_wait(vu32 *base)
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
static int _i2c_send_normal(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
u32 tmp = 0;
|
||||
|
||||
@@ -129,25 +132,25 @@ static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & ~NORMAL_MODE_GO) | NORMAL_MODE_GO;
|
||||
|
||||
u32 timeout = get_tmr_us() + 200000; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
static int _i2c_recv_normal(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
@@ -161,17 +164,17 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on normal mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & ~NORMAL_MODE_GO) | NORMAL_MODE_GO;
|
||||
|
||||
u32 timeout = get_tmr_us() + 200000; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
u32 timeout = get_tmr_ms() + 100; // Actual for max 8 bytes at 100KHz is 0.74ms.
|
||||
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
|
||||
{
|
||||
if (get_tmr_us() > timeout)
|
||||
return 0;
|
||||
if (get_tmr_ms() > timeout)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||
if (size > 4)
|
||||
@@ -183,23 +186,18 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
else
|
||||
memcpy(buf, &tmp, size);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
static int _i2c_send_packet(u32 i2c_idx, const u8 *buf, u32 size, u32 dev_addr)
|
||||
{
|
||||
if (size > 32)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE;
|
||||
|
||||
@@ -213,31 +211,28 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on packet mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
|
||||
|
||||
u32 hdr[3];
|
||||
hdr[0] = I2C_PACKET_PROT_I2C;
|
||||
hdr[1] = size - 1;
|
||||
hdr[2] = I2C_HEADER_IE_ENABLE | I2C_HEADER_CONT_XFER | (dev_addr << 1);
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & ~NORMAL_MODE_GO) | PACKET_MODE_GO;
|
||||
|
||||
// Send header with request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
base[I2C_TX_FIFO] = I2C_PACKET_PROT_I2C;
|
||||
base[I2C_TX_FIFO] = size - 1;
|
||||
base[I2C_TX_FIFO] = I2C_HEADER_IE_ENABLE | I2C_HEADER_CONT_XFER | (dev_addr << 1);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 400;
|
||||
while (size)
|
||||
// Send data.
|
||||
u32 rem = size;
|
||||
while (rem)
|
||||
{
|
||||
if (base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
u32 snd_size = MIN(size, 4);
|
||||
memcpy(&tmp, buf, snd_size);
|
||||
base[I2C_TX_FIFO] = tmp;
|
||||
buf += snd_size;
|
||||
size -= snd_size;
|
||||
}
|
||||
u32 len = MIN(rem, sizeof(u32));
|
||||
u32 word = 0;
|
||||
memcpy(&word, buf, len);
|
||||
base[I2C_TX_FIFO] = word;
|
||||
buf += len;
|
||||
rem -= len;
|
||||
}
|
||||
|
||||
u32 timeout = get_tmr_ms() + 200;
|
||||
while (((base[I2C_PACKET_TRANSFER_STATUS] >> 4) & 0xFFF) != (size - 1))
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = 1;
|
||||
@@ -245,33 +240,27 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
||||
}
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
|
||||
// Check if no reply.
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
res = 1;
|
||||
|
||||
// Disable packet mode.
|
||||
// Wait for STOP and disable packet mode.
|
||||
usleep(20);
|
||||
base[I2C_CNFG] &= 0xFFFFF9FF;
|
||||
|
||||
// Disable interrupts.
|
||||
base[I2C_INT_EN] = 0;
|
||||
base[I2C_CNFG] &= ~(PACKET_MODE_GO | NORMAL_MODE_GO);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
||||
int i2c_xfer_packet(u32 i2c_idx, u32 dev_addr, const u8 *tx_buf, u32 tx_size, u8 *rx_buf, u32 rx_size)
|
||||
{
|
||||
if (size > 32)
|
||||
return 0;
|
||||
// Max 32 bytes TX/RX fifo.
|
||||
if (tx_size > 20 || rx_size > 32) // Header included.
|
||||
return 1;
|
||||
|
||||
int res = 0;
|
||||
|
||||
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
|
||||
|
||||
// Enable interrupts.
|
||||
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
|
||||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | RX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
|
||||
@@ -285,44 +274,51 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
||||
_i2c_load_cfg_wait(base);
|
||||
|
||||
// Initiate transaction on packet mode.
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & ~NORMAL_MODE_GO) | PACKET_MODE_GO;
|
||||
|
||||
// Send reg request.
|
||||
u32 hdr[3];
|
||||
hdr[0] = I2C_PACKET_PROT_I2C;
|
||||
hdr[1] = 1 - 1;
|
||||
hdr[2] = I2C_HEADER_REP_START | (dev_addr << 1);
|
||||
// Send header with send request.
|
||||
base[I2C_TX_FIFO] = I2C_PACKET_PROT_I2C;
|
||||
base[I2C_TX_FIFO] = tx_size - 1;
|
||||
base[I2C_TX_FIFO] = I2C_HEADER_REP_START | (dev_addr << 1);
|
||||
|
||||
// Send header with reg request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
base[I2C_TX_FIFO] = reg;
|
||||
// Send data.
|
||||
u32 tx_rem = tx_size;
|
||||
while (tx_rem)
|
||||
{
|
||||
u32 len = MIN(tx_rem, sizeof(u32));
|
||||
u32 word = 0;
|
||||
memcpy(&word, tx_buf, len);
|
||||
base[I2C_TX_FIFO] = word;
|
||||
tx_buf += len;
|
||||
tx_rem -= len;
|
||||
}
|
||||
|
||||
u32 timeout = get_tmr_ms() + 400;
|
||||
while (!(base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT))
|
||||
u32 timeout = get_tmr_ms() + 200;
|
||||
while (((base[I2C_PACKET_TRANSFER_STATUS] >> 4) & 0xFFF) != (tx_size - 1))
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
break;
|
||||
{
|
||||
res = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
// Send read request.
|
||||
hdr[1] = size - 1;
|
||||
hdr[2] = I2C_HEADER_READ | (dev_addr << 1);
|
||||
// Send header with receive request
|
||||
base[I2C_TX_FIFO] = I2C_PACKET_PROT_I2C;
|
||||
base[I2C_TX_FIFO] = rx_size - 1;
|
||||
base[I2C_TX_FIFO] = I2C_HEADER_READ | (dev_addr << 1);
|
||||
|
||||
// Send header with read request.
|
||||
base[I2C_TX_FIFO] = hdr[0];
|
||||
base[I2C_TX_FIFO] = hdr[1];
|
||||
base[I2C_TX_FIFO] = hdr[2];
|
||||
|
||||
timeout = get_tmr_ms() + 400;
|
||||
while (size)
|
||||
// Receive data.
|
||||
timeout = get_tmr_ms() + 200;
|
||||
while (rx_size)
|
||||
{
|
||||
if (base[I2C_FIFO_STATUS] & RX_FIFO_FULL_CNT)
|
||||
{
|
||||
u32 rcv_size = MIN(size, 4);
|
||||
u32 tmp = base[I2C_RX_FIFO];
|
||||
memcpy(buf, &tmp, rcv_size);
|
||||
buf += rcv_size;
|
||||
size -= rcv_size;
|
||||
u32 len = MIN(rx_size, sizeof(u32));
|
||||
u32 word = base[I2C_RX_FIFO];
|
||||
memcpy(rx_buf, &word, len);
|
||||
rx_buf += len;
|
||||
rx_size -= len;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timeout)
|
||||
@@ -332,15 +328,14 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
|
||||
}
|
||||
}
|
||||
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
|
||||
out:
|
||||
// Check if no reply.
|
||||
if (base[I2C_STATUS] & I2C_STATUS_NOACK)
|
||||
res = 1;
|
||||
|
||||
// Disable packet mode.
|
||||
// Wait for STOP and disable packet mode.
|
||||
usleep(20);
|
||||
base[I2C_CNFG] &= 0xFFFFF9FF;
|
||||
|
||||
// Disable interrupts.
|
||||
base[I2C_INT_EN] = 0;
|
||||
base[I2C_CNFG] &= ~(PACKET_MODE_GO | NORMAL_MODE_GO);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -366,42 +361,33 @@ void i2c_init(u32 i2c_idx)
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
}
|
||||
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr)
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
|
||||
{
|
||||
return _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||
}
|
||||
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 32)
|
||||
return 0;
|
||||
|
||||
return _i2c_send_pkt(i2c_idx, buf, size, dev_addr);
|
||||
return _i2c_send_packet(i2c_idx, buf, size, dev_addr);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
|
||||
return i2c_xfer_packet(i2c_idx, dev_addr, (u8 *)®, 1, buf, size);
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[8];
|
||||
|
||||
if (size > 7)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
u8 tmp[8];
|
||||
tmp[0] = reg;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
return _i2c_send_single(i2c_idx, dev_addr, tmp, size + 1);
|
||||
return _i2c_send_normal(i2c_idx, dev_addr, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
|
||||
{
|
||||
int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
|
||||
int res = _i2c_send_normal(i2c_idx, dev_addr, (u8 *)®, 1);
|
||||
if (!res)
|
||||
res = _i2c_recv_normal(i2c_idx, buf, size, dev_addr);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -28,8 +28,8 @@
|
||||
#define I2C_6 5
|
||||
|
||||
void i2c_init(u32 i2c_idx);
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
|
||||
int i2c_xfer_packet(u32 i2c_idx, u32 dev_addr, const u8 *tx_buf, u32 tx_size, u8 *rx_buf, u32 rx_size);
|
||||
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size);
|
||||
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
|
||||
|
||||
@@ -25,25 +25,25 @@ int kfuse_wait_ready()
|
||||
;
|
||||
|
||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kfuse_read(u32 *buf)
|
||||
{
|
||||
int res = 0;
|
||||
int res = 1;
|
||||
|
||||
clock_enable_kfuse();
|
||||
|
||||
if (!kfuse_wait_ready())
|
||||
if (kfuse_wait_ready())
|
||||
goto out;
|
||||
|
||||
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
|
||||
for (int i = 0; i < KFUSE_NUM_WORDS; i++)
|
||||
buf[i] = KFUSE(KFUSE_KEYS);
|
||||
|
||||
res = 1;
|
||||
res = 0;
|
||||
|
||||
out:
|
||||
clock_disable_kfuse();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -15,6 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
@@ -30,6 +31,13 @@ void pinmux_config_i2c(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;
|
||||
|
||||
// Detach I2C4 pins from I2C3 function.
|
||||
if (idx == I2C_3 || idx == I2C_4)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(I2C_4)) |= 1;
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(I2C_4)) |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void pinmux_config_i2s(u32 idx)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -75,10 +75,10 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) |= 0xFF000; // RW lock: 4-7
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_SE2_SRK_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1).
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9_B01) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1).
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_MISC_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10_B01) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always.
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_CARVEOUTS_L4T)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x5555; // W: 8-15 LP0 and Carveouts. Superseded by LP0 lock.
|
||||
@@ -87,47 +87,54 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
// They could also use the NS write disable registers instead.
|
||||
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS_B01)
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1) |= 0x583FF; // W lock: 24-33, 39-40, 42.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2) |= 0x1BE; // W lock: 44-48, 50-51.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3) = 0xFFFFFFFF; // W lock: 56-87.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4) |= 0xFFFFFFF; // W lock: 88-115.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5) |= 0xFFFFFFF8; // W lock: 123-151.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6) = 0xFFFFFFFF; // W lock: 152-183.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7) |= 0xFC00FFFF; // W lock: 184-199, 210-215.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8) |= 0xF; // W lock: 216-219.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0_B01) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1_B01) |= 0x583FF; // W lock: 24-33, 39-40, 42.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2_B01) |= 0x1BE; // W lock: 44-48, 50-51.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3_B01) = 0xFFFFFFFF; // W lock: 56-87.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4_B01) |= 0xFFFFFFF; // W lock: 88-115.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5_B01) |= 0xFFFFFFF8; // W lock: 123-151.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6_B01) = 0xFFFFFFFF; // W lock: 152-183.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7_B01) |= 0xFC00FFFF; // W lock: 184-199, 210-215.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8_B01) |= 0xF; // W lock: 216-219.
|
||||
}
|
||||
}
|
||||
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable)
|
||||
/*
|
||||
* !TODO: Non CCPLEX power domains power gating/ungating.
|
||||
* Power gating: clock should be in reset if enabled and then
|
||||
* pmc_domain_pwrgate_set is run.
|
||||
* Power ungating: run pmc_domain_pwrgate_set, enable clocks and keep in
|
||||
* reset, remove clamping, remove reset, run mbist war if T210 and then clocks
|
||||
* can be disabled.
|
||||
*/
|
||||
|
||||
int pmc_domain_pwrgate_set(pmc_power_rail_t part, u32 enable)
|
||||
{
|
||||
u32 part_mask = BIT(part);
|
||||
u32 desired_state = enable << part;
|
||||
|
||||
// Check if the partition has the state we want.
|
||||
// Check if the power domain has the state we want.
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
int retries = 5000;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & PMC_PWRGATE_TOGGLE_START)
|
||||
{
|
||||
usleep(1);
|
||||
i--;
|
||||
if (i < 1)
|
||||
return 0;
|
||||
if (--retries < 1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Toggle power gating.
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | PMC_PWRGATE_TOGGLE_START;
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
retries = 5000;
|
||||
while ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) != desired_state)
|
||||
{
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
break;
|
||||
usleep(1);
|
||||
i--;
|
||||
if (--retries < 1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
190
bdk/soc/pmc.h
190
bdk/soc/pmc.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -20,182 +20,7 @@
|
||||
#define _PMC_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_RTC_CLK_DIS BIT(1)
|
||||
#define PMC_CNTRL_RTC_RST BIT(2)
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
#define PMC_CNTRL_LATCHWAKE_EN BIT(5)
|
||||
#define PMC_CNTRL_BLINK_EN BIT(7)
|
||||
#define PMC_CNTRL_PWRREQ_OE BIT(9)
|
||||
#define PMC_CNTRL_SYSCLK_OE BIT(11)
|
||||
#define PMC_CNTRL_PWRGATE_DIS BIT(12)
|
||||
#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14)
|
||||
#define PMC_CNTRL_CPUPWRREQ_OE BIT(16)
|
||||
#define PMC_CNTRL_FUSE_OVERRIDE BIT(18)
|
||||
#define PMC_CNTRL_SHUTDOWN_OE BIT(22)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_MEM BIT(7)
|
||||
#define PMC_NO_IOPOWER_SDMMC1 BIT(12)
|
||||
#define PMC_NO_IOPOWER_SDMMC4 BIT(14)
|
||||
#define PMC_NO_IOPOWER_MEM_COMP BIT(16)
|
||||
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
|
||||
#define PMC_NO_IOPOWER_GPIO BIT(21)
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
|
||||
#define PMC_SCRATCH0_MODE_RCM BIT(1)
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
|
||||
#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
|
||||
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | \
|
||||
PMC_SCRATCH0_MODE_BOOTLOADER | \
|
||||
PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_BLINK_TIMER 0x40
|
||||
#define PMC_BLINK_ON(n) ((n & 0x7FFF))
|
||||
#define PMC_BLINK_FORCE BIT(15)
|
||||
#define PMC_BLINK_OFF(n) ((u32)(n & 0xFFFF) << 16)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0 // ODM data/config scratch.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_33V_SDMMC1 BIT(12)
|
||||
#define PMC_PWR_DET_33V_AUDIO_HV BIT(18)
|
||||
#define PMC_PWR_DET_33V_GPIO BIT(21)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_USB_AO 0xF0
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_PLLP_WB0_OVERRIDE 0xF8
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE_ENABLE BIT(11)
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 // "TPAN"
|
||||
#define APBDEV_PMC_SCRATCH39 0x138
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER BIT(22)
|
||||
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN BIT(10)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_FORCE_EN BIT(18)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(src) (((src) & 3) << 6)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(src) (((src) & 3) << 14)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_SRC_SEL(src) (((src) & 3) << 22)
|
||||
#define OSC_DIV1 0
|
||||
#define OSC_DIV2 1
|
||||
#define OSC_DIV4 2
|
||||
#define OSC_CAR 3
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define PMC_RST_STATUS_MASK 7
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
#define PMC_RST_STATUS_SW_MAIN 3
|
||||
#define PMC_RST_STATUS_LP0 4
|
||||
#define PMC_RST_STATUS_AOTAG 5
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define PMC_IO_DPD_REQ_DPD_IDLE (0 << 30u)
|
||||
#define PMC_IO_DPD_REQ_DPD_OFF (1 << 30u)
|
||||
#define PMC_IO_DPD_REQ_DPD_ON (2 << 30u)
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
|
||||
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_SCRATCH52 0x250
|
||||
#define APBDEV_PMC_SCRATCH53 0x254
|
||||
#define APBDEV_PMC_SCRATCH54 0x258
|
||||
#define APBDEV_PMC_SCRATCH55 0x25C
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_STICKY_BITS 0x2C0
|
||||
#define PMC_STICKY_BITS_HDA_LPBK_DIS BIT(0)
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT BIT(4)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH22 0x338 // AArch32 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH34 0x368 // AArch64 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH35 0x36C // AArch64 reset hi-address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define PMC_CNTRL2_WAKE_INT_EN BIT(0)
|
||||
#define PMC_CNTRL2_WAKE_DET_EN BIT(9)
|
||||
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
|
||||
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
|
||||
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
|
||||
#define APBDEV_PMC_FUSE_CONTROL 0x450
|
||||
#define PMC_FUSE_CONTROL_PS18_LATCH_SET BIT(8)
|
||||
#define PMC_FUSE_CONTROL_PS18_LATCH_CLR BIT(9)
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
|
||||
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define APBDEV_PMC_SCRATCH201 0x844
|
||||
#define APBDEV_PMC_SCRATCH250 0x908
|
||||
#define APBDEV_PMC_SECURE_SCRATCH108 0xB08
|
||||
#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH110 0xB10
|
||||
#define APBDEV_PMC_SECURE_SCRATCH112 0xB18
|
||||
#define APBDEV_PMC_SECURE_SCRATCH113 0xB1C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH114 0xB20
|
||||
#define APBDEV_PMC_SECURE_SCRATCH119 0xB34
|
||||
|
||||
// Only in T210B01.
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE0 0xA48
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE1 0xA4C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE2 0xA50
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE3 0xA54
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE4 0xA58
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE5 0xA5C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE6 0xA60
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE7 0xA64
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE8 0xA68
|
||||
#define APBDEV_PMC_LED_BREATHING_CTRL 0xB48
|
||||
#define PMC_LED_BREATHING_CTRL_ENABLE BIT(0)
|
||||
#define PMC_LED_BREATHING_CTRL_COUNTER1_EN BIT(1)
|
||||
#define APBDEV_PMC_LED_BREATHING_SLOPE_STEPS 0xB4C
|
||||
#define APBDEV_PMC_LED_BREATHING_ON_COUNTER 0xB50
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER1 0xB54
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER0 0xB58
|
||||
#define PMC_LED_BREATHING_COUNTER_HZ 32768
|
||||
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
|
||||
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
|
||||
#define PMC_LED_BREATHING_FSM_STS_IDLE 0
|
||||
#define PMC_LED_BREATHING_FSM_STS_UP_RAMP 1
|
||||
#define PMC_LED_BREATHING_FSM_STS_PLATEAU 2
|
||||
#define PMC_LED_BREATHING_FSM_STS_DOWN_RAMP 3
|
||||
#define PMC_LED_BREATHING_FSM_STS_SHORT_LOW_PERIOD 4
|
||||
#define PMC_LED_BREATHING_FSM_STS_LONG_LOW_PERIOD 5
|
||||
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
|
||||
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
|
||||
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
|
||||
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
|
||||
#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0)
|
||||
#define PMC_TZRAM_DISABLE_REG_READ BIT(1)
|
||||
#include <soc/pmc_t210.h>
|
||||
|
||||
typedef enum _pmc_sec_lock_t
|
||||
{
|
||||
@@ -217,19 +42,14 @@ typedef enum _pmc_sec_lock_t
|
||||
typedef enum _pmc_power_rail_t
|
||||
{
|
||||
POWER_RAIL_CRAIL = 0,
|
||||
POWER_RAIL_3D0 = 1,
|
||||
POWER_RAIL_VENC = 2,
|
||||
POWER_RAIL_VE = 2,
|
||||
POWER_RAIL_PCIE = 3,
|
||||
POWER_RAIL_VDEC = 4,
|
||||
POWER_RAIL_L2C = 5,
|
||||
POWER_RAIL_MPE = 6,
|
||||
POWER_RAIL_HEG = 7,
|
||||
POWER_RAIL_NVENC = 6,
|
||||
POWER_RAIL_SATA = 8,
|
||||
POWER_RAIL_CE1 = 9,
|
||||
POWER_RAIL_CE2 = 10,
|
||||
POWER_RAIL_CE3 = 11,
|
||||
POWER_RAIL_CELP = 12,
|
||||
POWER_RAIL_3D1 = 13,
|
||||
POWER_RAIL_CE0 = 14,
|
||||
POWER_RAIL_C0NC = 15,
|
||||
POWER_RAIL_C1NC = 16,
|
||||
@@ -249,6 +69,6 @@ typedef enum _pmc_power_rail_t
|
||||
} pmc_power_rail_t;
|
||||
|
||||
void pmc_scratch_lock(pmc_sec_lock_t lock_mask);
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable);
|
||||
int pmc_domain_pwrgate_set(pmc_power_rail_t part, u32 enable);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,564 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA210_PMC_H_
|
||||
#define _TEGRA210_PMC_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
struct tegra_pmc_regs
|
||||
{
|
||||
u32 cntrl;
|
||||
u32 sec_disable;
|
||||
u32 pmc_swrst;
|
||||
u32 wake_mask;
|
||||
u32 wake_lvl;
|
||||
u32 wake_status;
|
||||
u32 sw_wake_status;
|
||||
u32 dpd_pads_oride;
|
||||
u32 dpd_sample;
|
||||
u32 dpd_enable;
|
||||
u32 pwrgate_timer_off;
|
||||
u32 clamp_status;
|
||||
u32 pwrgate_toggle;
|
||||
u32 remove_clamping_cmd;
|
||||
u32 pwrgate_status;
|
||||
u32 pwrgood_timer;
|
||||
u32 blink_timer;
|
||||
u32 no_iopower;
|
||||
u32 pwr_det;
|
||||
u32 pwr_det_latch;
|
||||
u32 scratch0;
|
||||
u32 scratch1;
|
||||
u32 scratch2;
|
||||
u32 scratch3;
|
||||
u32 scratch4;
|
||||
u32 scratch5;
|
||||
u32 scratch6;
|
||||
u32 scratch7;
|
||||
u32 scratch8;
|
||||
u32 scratch9;
|
||||
u32 scratch10;
|
||||
u32 scratch11;
|
||||
u32 scratch12;
|
||||
u32 scratch13;
|
||||
u32 scratch14;
|
||||
u32 scratch15;
|
||||
u32 scratch16;
|
||||
u32 scratch17;
|
||||
u32 scratch18;
|
||||
u32 scratch19;
|
||||
u32 odmdata;
|
||||
u32 scratch21;
|
||||
u32 scratch22;
|
||||
u32 scratch23;
|
||||
u32 secure_scratch0;
|
||||
u32 secure_scratch1;
|
||||
u32 secure_scratch2;
|
||||
u32 secure_scratch3;
|
||||
u32 secure_scratch4;
|
||||
u32 secure_scratch5;
|
||||
u32 cpupwrgood_timer;
|
||||
u32 cpupwroff_timer;
|
||||
u32 pg_mask;
|
||||
u32 pg_mask_1;
|
||||
u32 auto_wake_lvl;
|
||||
u32 auto_wake_lvl_mask;
|
||||
u32 wake_delay;
|
||||
u32 pwr_det_val;
|
||||
u32 ddr_pwr;
|
||||
u32 usb_debounce_del;
|
||||
u32 usb_a0;
|
||||
u32 crypto_op;
|
||||
u32 pllp_wb0_override;
|
||||
u32 scratch24;
|
||||
u32 scratch25;
|
||||
u32 scratch26;
|
||||
u32 scratch27;
|
||||
u32 scratch28;
|
||||
u32 scratch29;
|
||||
u32 scratch30;
|
||||
u32 scratch31;
|
||||
u32 scratch32;
|
||||
u32 scratch33;
|
||||
u32 scratch34;
|
||||
u32 scratch35;
|
||||
u32 scratch36;
|
||||
u32 scratch37;
|
||||
u32 scratch38;
|
||||
u32 scratch39;
|
||||
u32 scratch40;
|
||||
u32 scratch41;
|
||||
u32 scratch42;
|
||||
u32 bondout_mirror[3];
|
||||
u32 sys_33v_en;
|
||||
u32 bondout_mirror_access;
|
||||
u32 gate;
|
||||
u32 wake2_mask;
|
||||
u32 wake2_lvl;
|
||||
u32 wake2_status;
|
||||
u32 sw_wake2_status;
|
||||
u32 auto_wake2_lvl_mask;
|
||||
u32 pg_mask_2;
|
||||
u32 pg_mask_ce1;
|
||||
u32 pg_mask_ce2;
|
||||
u32 pg_mask_ce3;
|
||||
u32 pwrgate_timer_ce[7];
|
||||
u32 pcx_edpd_cntrl;
|
||||
u32 osc_edpd_over;
|
||||
u32 clk_out_cntrl;
|
||||
u32 sata_pwrgt;
|
||||
u32 sensor_ctrl;
|
||||
u32 rst_status;
|
||||
u32 io_dpd_req;
|
||||
u32 io_dpd_status;
|
||||
u32 io_dpd2_req;
|
||||
u32 io_dpd2_status;
|
||||
u32 sel_dpd_tim;
|
||||
u32 vddp_sel;
|
||||
u32 ddr_cfg;
|
||||
u32 e_no_vttgen;
|
||||
u8 _rsv0[4];
|
||||
u32 pllm_wb0_override_freq;
|
||||
u32 test_pwrgate;
|
||||
u32 pwrgate_timer_mult;
|
||||
u32 dis_sel_dpd;
|
||||
u32 utmip_uhsic_triggers;
|
||||
u32 utmip_uhsic_saved_state;
|
||||
u32 utmip_pad_cfg;
|
||||
u32 utmip_term_pad_cfg;
|
||||
u32 utmip_uhsic_sleep_cfg;
|
||||
u32 utmip_uhsic_sleepwalk_cfg;
|
||||
u32 utmip_sleepwalk_p[3];
|
||||
u32 uhsic_sleepwalk_p0;
|
||||
u32 utmip_uhsic_status;
|
||||
u32 utmip_uhsic_fake;
|
||||
u32 bondout_mirror3[5 - 3];
|
||||
u32 secure_scratch6;
|
||||
u32 secure_scratch7;
|
||||
u32 scratch43;
|
||||
u32 scratch44;
|
||||
u32 scratch45;
|
||||
u32 scratch46;
|
||||
u32 scratch47;
|
||||
u32 scratch48;
|
||||
u32 scratch49;
|
||||
u32 scratch50;
|
||||
u32 scratch51;
|
||||
u32 scratch52;
|
||||
u32 scratch53;
|
||||
u32 scratch54;
|
||||
u32 scratch55;
|
||||
u32 scratch0_eco;
|
||||
u32 por_dpd_ctrl;
|
||||
u32 scratch2_eco;
|
||||
u32 utmip_uhsic_line_wakeup;
|
||||
u32 utmip_bias_master_cntrl;
|
||||
u32 utmip_master_config;
|
||||
u32 td_pwrgate_inter_part_timer;
|
||||
u32 utmip_uhsic2_triggers;
|
||||
u32 utmip_uhsic2_saved_state;
|
||||
u32 utmip_uhsic2_sleep_cfg;
|
||||
u32 utmip_uhsic2_sleepwalk_cfg;
|
||||
u32 uhsic2_sleepwalk_p1;
|
||||
u32 utmip_uhsic2_status;
|
||||
u32 utmip_uhsic2_fake;
|
||||
u32 utmip_uhsic2_line_wakeup;
|
||||
u32 utmip_master2_config;
|
||||
u32 utmip_uhsic_rpd_cfg;
|
||||
u32 pg_mask_ce0;
|
||||
u32 pg_mask3[5 - 3];
|
||||
u32 pllm_wb0_override2;
|
||||
u32 tsc_mult;
|
||||
u32 cpu_vsense_override;
|
||||
u32 glb_amap_cfg;
|
||||
u32 sticky_bits;
|
||||
u32 sec_disable2;
|
||||
u32 weak_bias;
|
||||
u32 reg_short;
|
||||
u32 pg_mask_andor;
|
||||
u8 _rsv1[0x2c];
|
||||
u32 secure_scratch8; /* offset 0x300 */
|
||||
u32 secure_scratch9;
|
||||
u32 secure_scratch10;
|
||||
u32 secure_scratch11;
|
||||
u32 secure_scratch12;
|
||||
u32 secure_scratch13;
|
||||
u32 secure_scratch14;
|
||||
u32 secure_scratch15;
|
||||
u32 secure_scratch16;
|
||||
u32 secure_scratch17;
|
||||
u32 secure_scratch18;
|
||||
u32 secure_scratch19;
|
||||
u32 secure_scratch20;
|
||||
u32 secure_scratch21;
|
||||
u32 secure_scratch22;
|
||||
u32 secure_scratch23;
|
||||
u32 secure_scratch24;
|
||||
u32 secure_scratch25;
|
||||
u32 secure_scratch26;
|
||||
u32 secure_scratch27;
|
||||
u32 secure_scratch28;
|
||||
u32 secure_scratch29;
|
||||
u32 secure_scratch30;
|
||||
u32 secure_scratch31;
|
||||
u32 secure_scratch32;
|
||||
u32 secure_scratch33;
|
||||
u32 secure_scratch34;
|
||||
u32 secure_scratch35;
|
||||
u32 secure_scratch36;
|
||||
u32 secure_scratch37;
|
||||
u32 secure_scratch38;
|
||||
u32 secure_scratch39;
|
||||
u32 secure_scratch40;
|
||||
u32 secure_scratch41;
|
||||
u32 secure_scratch42;
|
||||
u32 secure_scratch43;
|
||||
u32 secure_scratch44;
|
||||
u32 secure_scratch45;
|
||||
u32 secure_scratch46;
|
||||
u32 secure_scratch47;
|
||||
u32 secure_scratch48;
|
||||
u32 secure_scratch49;
|
||||
u32 secure_scratch50;
|
||||
u32 secure_scratch51;
|
||||
u32 secure_scratch52;
|
||||
u32 secure_scratch53;
|
||||
u32 secure_scratch54;
|
||||
u32 secure_scratch55;
|
||||
u32 secure_scratch56;
|
||||
u32 secure_scratch57;
|
||||
u32 secure_scratch58;
|
||||
u32 secure_scratch59;
|
||||
u32 secure_scratch60;
|
||||
u32 secure_scratch61;
|
||||
u32 secure_scratch62;
|
||||
u32 secure_scratch63;
|
||||
u32 secure_scratch64;
|
||||
u32 secure_scratch65;
|
||||
u32 secure_scratch66;
|
||||
u32 secure_scratch67;
|
||||
u32 secure_scratch68;
|
||||
u32 secure_scratch69;
|
||||
u32 secure_scratch70;
|
||||
u32 secure_scratch71;
|
||||
u32 secure_scratch72;
|
||||
u32 secure_scratch73;
|
||||
u32 secure_scratch74;
|
||||
u32 secure_scratch75;
|
||||
u32 secure_scratch76;
|
||||
u32 secure_scratch77;
|
||||
u32 secure_scratch78;
|
||||
u32 secure_scratch79;
|
||||
u32 _rsv0x420[8];
|
||||
u32 cntrl2; /* 0x440 */
|
||||
u32 _rsv0x444[2];
|
||||
u32 event_counter; /* 0x44C */
|
||||
u32 fuse_control;
|
||||
u32 scratch1_eco;
|
||||
u32 _rsv0x458[1];
|
||||
u32 io_dpd3_req; /* 0x45C */
|
||||
u32 io_dpd3_status;
|
||||
u32 io_dpd4_req;
|
||||
u32 io_dpd4_status;
|
||||
u32 _rsv0x46C[30];
|
||||
u32 ddr_cntrl; /* 0x4E4 */
|
||||
u32 _rsv0x4E8[70];
|
||||
u32 scratch56; /* 0x600 */
|
||||
u32 scratch57;
|
||||
u32 scratch58;
|
||||
u32 scratch59;
|
||||
u32 scratch60;
|
||||
u32 scratch61;
|
||||
u32 scratch62;
|
||||
u32 scratch63;
|
||||
u32 scratch64;
|
||||
u32 scratch65;
|
||||
u32 scratch66;
|
||||
u32 scratch67;
|
||||
u32 scratch68;
|
||||
u32 scratch69;
|
||||
u32 scratch70;
|
||||
u32 scratch71;
|
||||
u32 scratch72;
|
||||
u32 scratch73;
|
||||
u32 scratch74;
|
||||
u32 scratch75;
|
||||
u32 scratch76;
|
||||
u32 scratch77;
|
||||
u32 scratch78;
|
||||
u32 scratch79;
|
||||
u32 scratch80;
|
||||
u32 scratch81;
|
||||
u32 scratch82;
|
||||
u32 scratch83;
|
||||
u32 scratch84;
|
||||
u32 scratch85;
|
||||
u32 scratch86;
|
||||
u32 scratch87;
|
||||
u32 scratch88;
|
||||
u32 scratch89;
|
||||
u32 scratch90;
|
||||
u32 scratch91;
|
||||
u32 scratch92;
|
||||
u32 scratch93;
|
||||
u32 scratch94;
|
||||
u32 scratch95;
|
||||
u32 scratch96;
|
||||
u32 scratch97;
|
||||
u32 scratch98;
|
||||
u32 scratch99;
|
||||
u32 scratch100;
|
||||
u32 scratch101;
|
||||
u32 scratch102;
|
||||
u32 scratch103;
|
||||
u32 scratch104;
|
||||
u32 scratch105;
|
||||
u32 scratch106;
|
||||
u32 scratch107;
|
||||
u32 scratch108;
|
||||
u32 scratch109;
|
||||
u32 scratch110;
|
||||
u32 scratch111;
|
||||
u32 scratch112;
|
||||
u32 scratch113;
|
||||
u32 scratch114;
|
||||
u32 scratch115;
|
||||
u32 scratch116;
|
||||
u32 scratch117;
|
||||
u32 scratch118;
|
||||
u32 scratch119;
|
||||
u32 scratch120; /* 0x700 */
|
||||
u32 scratch121;
|
||||
u32 scratch122;
|
||||
u32 scratch123;
|
||||
u32 scratch124;
|
||||
u32 scratch125;
|
||||
u32 scratch126;
|
||||
u32 scratch127;
|
||||
u32 scratch128;
|
||||
u32 scratch129;
|
||||
u32 scratch130;
|
||||
u32 scratch131;
|
||||
u32 scratch132;
|
||||
u32 scratch133;
|
||||
u32 scratch134;
|
||||
u32 scratch135;
|
||||
u32 scratch136;
|
||||
u32 scratch137;
|
||||
u32 scratch138;
|
||||
u32 scratch139;
|
||||
u32 scratch140;
|
||||
u32 scratch141;
|
||||
u32 scratch142;
|
||||
u32 scratch143;
|
||||
u32 scratch144;
|
||||
u32 scratch145;
|
||||
u32 scratch146;
|
||||
u32 scratch147;
|
||||
u32 scratch148;
|
||||
u32 scratch149;
|
||||
u32 scratch150;
|
||||
u32 scratch151;
|
||||
u32 scratch152;
|
||||
u32 scratch153;
|
||||
u32 scratch154;
|
||||
u32 scratch155;
|
||||
u32 scratch156;
|
||||
u32 scratch157;
|
||||
u32 scratch158;
|
||||
u32 scratch159;
|
||||
u32 scratch160;
|
||||
u32 scratch161;
|
||||
u32 scratch162;
|
||||
u32 scratch163;
|
||||
u32 scratch164;
|
||||
u32 scratch165;
|
||||
u32 scratch166;
|
||||
u32 scratch167;
|
||||
u32 scratch168;
|
||||
u32 scratch169;
|
||||
u32 scratch170;
|
||||
u32 scratch171;
|
||||
u32 scratch172;
|
||||
u32 scratch173;
|
||||
u32 scratch174;
|
||||
u32 scratch175;
|
||||
u32 scratch176;
|
||||
u32 scratch177;
|
||||
u32 scratch178;
|
||||
u32 scratch179;
|
||||
u32 scratch180;
|
||||
u32 scratch181;
|
||||
u32 scratch182;
|
||||
u32 scratch183;
|
||||
u32 scratch184;
|
||||
u32 scratch185;
|
||||
u32 scratch186;
|
||||
u32 scratch187;
|
||||
u32 scratch188;
|
||||
u32 scratch189;
|
||||
u32 scratch190;
|
||||
u32 scratch191;
|
||||
u32 scratch192;
|
||||
u32 scratch193;
|
||||
u32 scratch194;
|
||||
u32 scratch195;
|
||||
u32 scratch196;
|
||||
u32 scratch197;
|
||||
u32 scratch198;
|
||||
u32 scratch199;
|
||||
u32 scratch200;
|
||||
u32 scratch201;
|
||||
u32 scratch202;
|
||||
u32 scratch203;
|
||||
u32 scratch204;
|
||||
u32 scratch205;
|
||||
u32 scratch206;
|
||||
u32 scratch207;
|
||||
u32 scratch208;
|
||||
u32 scratch209;
|
||||
u32 scratch210;
|
||||
u32 scratch211;
|
||||
u32 scratch212;
|
||||
u32 scratch213;
|
||||
u32 scratch214;
|
||||
u32 scratch215;
|
||||
u32 scratch216;
|
||||
u32 scratch217;
|
||||
u32 scratch218;
|
||||
u32 scratch219;
|
||||
u32 scratch220;
|
||||
u32 scratch221;
|
||||
u32 scratch222;
|
||||
u32 scratch223;
|
||||
u32 scratch224;
|
||||
u32 scratch225;
|
||||
u32 scratch226;
|
||||
u32 scratch227;
|
||||
u32 scratch228;
|
||||
u32 scratch229;
|
||||
u32 scratch230;
|
||||
u32 scratch231;
|
||||
u32 scratch232;
|
||||
u32 scratch233;
|
||||
u32 scratch234;
|
||||
u32 scratch235;
|
||||
u32 scratch236;
|
||||
u32 scratch237;
|
||||
u32 scratch238;
|
||||
u32 scratch239;
|
||||
u32 scratch240;
|
||||
u32 scratch241;
|
||||
u32 scratch242;
|
||||
u32 scratch243;
|
||||
u32 scratch244;
|
||||
u32 scratch245;
|
||||
u32 scratch246;
|
||||
u32 scratch247;
|
||||
u32 scratch248;
|
||||
u32 scratch249;
|
||||
u32 scratch250;
|
||||
u32 scratch251;
|
||||
u32 scratch252;
|
||||
u32 scratch253;
|
||||
u32 scratch254;
|
||||
u32 scratch255;
|
||||
u32 scratch256;
|
||||
u32 scratch257;
|
||||
u32 scratch258;
|
||||
u32 scratch259;
|
||||
u32 scratch260;
|
||||
u32 scratch261;
|
||||
u32 scratch262;
|
||||
u32 scratch263;
|
||||
u32 scratch264;
|
||||
u32 scratch265;
|
||||
u32 scratch266;
|
||||
u32 scratch267;
|
||||
u32 scratch268;
|
||||
u32 scratch269;
|
||||
u32 scratch270;
|
||||
u32 scratch271;
|
||||
u32 scratch272;
|
||||
u32 scratch273;
|
||||
u32 scratch274;
|
||||
u32 scratch275;
|
||||
u32 scratch276;
|
||||
u32 scratch277;
|
||||
u32 scratch278;
|
||||
u32 scratch279;
|
||||
u32 scratch280;
|
||||
u32 scratch281;
|
||||
u32 scratch282;
|
||||
u32 scratch283;
|
||||
u32 scratch284;
|
||||
u32 scratch285;
|
||||
u32 scratch286;
|
||||
u32 scratch287;
|
||||
u32 scratch288;
|
||||
u32 scratch289;
|
||||
u32 scratch290;
|
||||
u32 scratch291;
|
||||
u32 scratch292;
|
||||
u32 scratch293;
|
||||
u32 scratch294;
|
||||
u32 scratch295;
|
||||
u32 scratch296;
|
||||
u32 scratch297;
|
||||
u32 scratch298;
|
||||
u32 scratch299; /* 0x9CC */
|
||||
u32 _rsv0x9D0[50];
|
||||
u32 secure_scratch80; /* 0xa98 */
|
||||
u32 secure_scratch81;
|
||||
u32 secure_scratch82;
|
||||
u32 secure_scratch83;
|
||||
u32 secure_scratch84;
|
||||
u32 secure_scratch85;
|
||||
u32 secure_scratch86;
|
||||
u32 secure_scratch87;
|
||||
u32 secure_scratch88;
|
||||
u32 secure_scratch89;
|
||||
u32 secure_scratch90;
|
||||
u32 secure_scratch91;
|
||||
u32 secure_scratch92;
|
||||
u32 secure_scratch93;
|
||||
u32 secure_scratch94;
|
||||
u32 secure_scratch95;
|
||||
u32 secure_scratch96;
|
||||
u32 secure_scratch97;
|
||||
u32 secure_scratch98;
|
||||
u32 secure_scratch99;
|
||||
u32 secure_scratch100;
|
||||
u32 secure_scratch101;
|
||||
u32 secure_scratch102;
|
||||
u32 secure_scratch103;
|
||||
u32 secure_scratch104;
|
||||
u32 secure_scratch105;
|
||||
u32 secure_scratch106;
|
||||
u32 secure_scratch107;
|
||||
u32 secure_scratch108;
|
||||
u32 secure_scratch109;
|
||||
u32 secure_scratch110;
|
||||
u32 secure_scratch111;
|
||||
u32 secure_scratch112;
|
||||
u32 secure_scratch113;
|
||||
u32 secure_scratch114;
|
||||
u32 secure_scratch115;
|
||||
u32 secure_scratch116;
|
||||
u32 secure_scratch117;
|
||||
u32 secure_scratch118;
|
||||
u32 secure_scratch119;
|
||||
};
|
||||
|
||||
#endif /* _TEGRA210_PMC_H_ */
|
||||
1428
bdk/soc/pmc_t210.h
Normal file
1428
bdk/soc/pmc_t210.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,7 @@
|
||||
#define SOR1_BASE 0x54580000
|
||||
#define GPU_BASE 0x57000000
|
||||
#define GPU_USER_BASE 0x58000000
|
||||
#define PG_BASE 0x60000000
|
||||
#define RES_SEMAPH_BASE 0x60001000
|
||||
#define ARB_SEMAPH_BASE 0x60002000
|
||||
#define ARB_PRI_BASE 0x60003000
|
||||
@@ -68,6 +69,8 @@
|
||||
#define ATOMICS_BASE 0x70016000
|
||||
#define MC_BASE 0x70019000
|
||||
#define EMC_BASE 0x7001B000
|
||||
#define MC0_BASE 0x7001C000
|
||||
#define MC1_BASE 0x7001D000
|
||||
#define EMC0_BASE 0x7001E000
|
||||
#define EMC1_BASE 0x7001F000
|
||||
#define XUSB_HOST_BASE 0x70090000
|
||||
@@ -85,6 +88,7 @@
|
||||
#define AXBAR_BASE 0x702D0800
|
||||
#define I2S_BASE 0x702D1000
|
||||
#define ADMA_BASE 0x702E2000
|
||||
#define AMC_BASE 0x702EF000
|
||||
#define SE2_BASE 0x70412000
|
||||
#define SE_PKA1_BASE 0x70420000
|
||||
#define TZRAM_BASE 0x7C010000
|
||||
@@ -102,9 +106,9 @@
|
||||
#define MSELECT(off) MMIO_REG32(MSELECT_BASE, off)
|
||||
#define DPAUX1(off) MMIO_REG32(DPAUX1_BASE, off)
|
||||
#define TSEC2(off) MMIO_REG32(TSEC2_BASE, off)
|
||||
#define DISPLAY_A(off) MMIO_REG32(DISPLAY_A_BASE, off)
|
||||
#define DISPLAY_B(off) MMIO_REG32(DISPLAY_B_BASE, off)
|
||||
#define DSI(off) MMIO_REG32(DSI_BASE, off)
|
||||
#define DISPLAY_A(off) MMIO_REG32(DISPLAY_A_BASE, (off) << 2u)
|
||||
#define DISPLAY_B(off) MMIO_REG32(DISPLAY_B_BASE, (off) << 2u)
|
||||
#define DSI(off) MMIO_REG32(DSI_BASE, (off) << 2u)
|
||||
#define VIC(off) MMIO_REG32(VIC_BASE, off)
|
||||
#define NVJPG(off) MMIO_REG32(NVJPG_BASE, off)
|
||||
#define NVDEC(off) MMIO_REG32(NVDEC_BASE, off)
|
||||
@@ -113,6 +117,7 @@
|
||||
#define SOR1(off) MMIO_REG32(SOR1_BASE, off)
|
||||
#define GPU(off) MMIO_REG32(GPU_BASE, off)
|
||||
#define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
|
||||
#define PG(off) MMIO_REG32(PG_BASE, off)
|
||||
#define ARB_PRI(off) MMIO_REG32(ARB_PRI_BASE, off)
|
||||
#define ICTLR(cidx, off) MMIO_REG32(ICTLR_BASE + (0x100 * (cidx)), off)
|
||||
#define TMR(off) MMIO_REG32(TMR_BASE, off)
|
||||
@@ -139,6 +144,8 @@
|
||||
#define SE(off) MMIO_REG32(SE_BASE, off)
|
||||
#define MC(off) MMIO_REG32(MC_BASE, off)
|
||||
#define EMC(off) MMIO_REG32(EMC_BASE, off)
|
||||
#define MC_CH0(off) MMIO_REG32(MC0_BASE, off)
|
||||
#define MC_CH1(off) MMIO_REG32(MC1_BASE, off)
|
||||
#define EMC_CH0(off) MMIO_REG32(EMC0_BASE, off)
|
||||
#define EMC_CH1(off) MMIO_REG32(EMC1_BASE, off)
|
||||
#define XUSB_HOST(off) MMIO_REG32(XUSB_HOST_BASE, off)
|
||||
@@ -147,10 +154,11 @@
|
||||
#define XUSB_DEV_XHCI(off) MMIO_REG32(XUSB_DEV_BASE, off)
|
||||
#define XUSB_DEV_PCI(off) MMIO_REG32(XUSB_DEV_BASE + 0x8000, off)
|
||||
#define XUSB_DEV_DEV(off) MMIO_REG32(XUSB_DEV_BASE + 0x9000, off)
|
||||
#define MIPI_CAL(off) MMIO_REG32(MIPI_CAL_BASE, off)
|
||||
#define MIPI_CAL(off) MMIO_REG32(MIPI_CAL_BASE, (off) << 2u)
|
||||
#define CL_DVFS(off) MMIO_REG32(CL_DVFS_BASE, off)
|
||||
#define I2S(off) MMIO_REG32(I2S_BASE, off)
|
||||
#define ADMA(off) MMIO_REG32(ADMA_BASE, off)
|
||||
#define AMC(off) MMIO_REG32(AMC_BASE, off)
|
||||
#define SE2(off) MMIO_REG32(SE2_BASE, off)
|
||||
#define SE_PKA1(off) MMIO_REG32(SE_PKA1_BASE, off)
|
||||
#define USB(off) MMIO_REG32(USB_BASE, off)
|
||||
@@ -199,7 +207,7 @@
|
||||
/*! AHB Gizmo registers. */
|
||||
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
|
||||
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
|
||||
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
|
||||
#define AHB_GIZMO_AHB_MEM 0x10
|
||||
@@ -210,7 +218,7 @@
|
||||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_USB3 0x80 // Doesn't exist on T21x??
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
@@ -219,9 +227,9 @@
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB. Doesn't exist on T210B01.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC
|
||||
@@ -295,8 +303,10 @@
|
||||
#define IPATCH_CAM_ENTRIES 12
|
||||
|
||||
/*! I2S registers. */
|
||||
#define I2S1_CG 0x88
|
||||
#define I2S1_CTRL 0xA0
|
||||
#define I2S_CG 0x88
|
||||
#define I2S_CTRL 0xA0
|
||||
#define I2S1_CG I2S_CG
|
||||
#define I2S1_CTRL I2S_CTRL
|
||||
#define I2S2_CG 0x188
|
||||
#define I2S2_CTRL 0x1A0
|
||||
#define I2S3_CG 0x288
|
||||
@@ -305,8 +315,9 @@
|
||||
#define I2S4_CTRL 0x3A0
|
||||
#define I2S5_CG 0x488
|
||||
#define I2S5_CTRL 0x4A0
|
||||
#define I2S_CG_SLCG_ENABLE BIT(0)
|
||||
#define I2S_CTRL_MASTER_EN BIT(10)
|
||||
#define I2S_CG_SLCG_DISABLE 0
|
||||
#define I2S_CG_SLCG_ENABLE BIT(0)
|
||||
#define I2S_CTRL_MASTER_EN BIT(10)
|
||||
|
||||
/*! PWM registers. */
|
||||
#define PWM_CONTROLLER_PWM_CSR_0 0x00
|
||||
@@ -374,4 +385,12 @@
|
||||
#define NVDEC_SA_KEYSLOT_OTF 0x210C
|
||||
#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118
|
||||
#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C
|
||||
|
||||
/* PG registers */
|
||||
#define PG_UP_TAG 0x0 // Changes depending on what does the reg read request.
|
||||
#define TAG_PID_CCPLEX 0x55555555
|
||||
#define TAG_PID_BPMP 0xAAAAAAAA
|
||||
#define TAG_PID_COP2 0x99999999
|
||||
#define TAG_PID_OTHER 0xCCCCCCCC
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_ADDR 0x4003FF18
|
||||
#define EXCP_TYPE_WDT 0x544457 // "WDT".
|
||||
|
||||
#define USE_RTC_TIMER
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
#define UART_MCR_CTS_EN BIT(5)
|
||||
#define UART_MCR_RTS_EN BIT(6)
|
||||
|
||||
#define UART_FIFO_SIZE 36
|
||||
|
||||
typedef struct _uart_t
|
||||
{
|
||||
/* 0x00 */ vu32 UART_THR_DLAB;
|
||||
|
||||
277
bdk/storage/boot_storage.c
Normal file
277
bdk/storage/boot_storage.c
Normal file
@@ -0,0 +1,277 @@
|
||||
#include "boot_storage.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <fatfs_cfg.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <utils/types.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEV_INVALID 0xff
|
||||
|
||||
static FATFS boot_storage_fs;
|
||||
static BYTE drive_cur = -1;
|
||||
static BYTE drive = -1;
|
||||
|
||||
static const char* drive_base_paths[] = {
|
||||
[DRIVE_SD] = "sd:",
|
||||
[DRIVE_BOOT1] = "boot1_:",
|
||||
[DRIVE_BOOT1_1MB] = "boot1_1mb:",
|
||||
[DRIVE_EMMC] = "emmc:",
|
||||
};
|
||||
|
||||
static bool _is_eligible(){
|
||||
if(f_stat(".no_boot_storage", NULL) == FR_OK){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool boot_storage_get_mounted(){
|
||||
switch(drive_cur){
|
||||
case DRIVE_SD:
|
||||
return sd_get_card_mounted();
|
||||
case DRIVE_EMMC:
|
||||
return emmc_get_mounted();
|
||||
case DRIVE_BOOT1:
|
||||
case DRIVE_BOOT1_1MB:
|
||||
return drive_cur != DEV_INVALID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool boot_storage_get_initialized(){
|
||||
switch(drive_cur){
|
||||
case DRIVE_BOOT1:
|
||||
case DRIVE_EMMC:
|
||||
case DRIVE_BOOT1_1MB:
|
||||
return emmc_get_initialized();
|
||||
case DRIVE_SD:
|
||||
return sd_get_card_initialized();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _boot_storage_initialize(){
|
||||
switch(drive_cur){
|
||||
case DRIVE_BOOT1:
|
||||
case DRIVE_EMMC:
|
||||
case DRIVE_BOOT1_1MB:
|
||||
return emmc_initialize(false);
|
||||
case DRIVE_SD:
|
||||
return sd_initialize(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void _boot_storage_end(bool deinit){
|
||||
BYTE prev_drive = drive_cur;
|
||||
|
||||
if(boot_storage_get_mounted()){
|
||||
switch(drive_cur){
|
||||
case DRIVE_SD:
|
||||
sd_unmount();
|
||||
break;
|
||||
case DRIVE_EMMC:
|
||||
emmc_unmount();
|
||||
break;
|
||||
case DRIVE_BOOT1:
|
||||
case DRIVE_BOOT1_1MB:
|
||||
f_mount(NULL, drive_base_paths[drive_cur], 0);
|
||||
}
|
||||
drive_cur = DEV_INVALID;
|
||||
}
|
||||
|
||||
if(deinit){
|
||||
switch(prev_drive){
|
||||
case DRIVE_SD:
|
||||
sd_end();
|
||||
break;
|
||||
case DRIVE_EMMC:
|
||||
case DRIVE_BOOT1:
|
||||
case DRIVE_BOOT1_1MB:
|
||||
emmc_end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void boot_storage_unmount(){
|
||||
_boot_storage_end(false);
|
||||
}
|
||||
|
||||
void boot_storage_end(){
|
||||
_boot_storage_end(true);
|
||||
}
|
||||
|
||||
u8 boot_storage_get_drive(){
|
||||
return drive;
|
||||
}
|
||||
|
||||
static bool _boot_storage_mount(){
|
||||
// may want to check sd card first and prioritize it
|
||||
|
||||
FRESULT res;
|
||||
|
||||
bool prev_emmc_initialized = emmc_get_initialized();
|
||||
bool prev_sd_initialized = sd_get_card_initialized();
|
||||
|
||||
if(!prev_emmc_initialized && !emmc_initialize(false)){
|
||||
goto emmc_init_fail;
|
||||
}
|
||||
|
||||
static const BYTE emmc_drives[] = {DRIVE_BOOT1_1MB, DRIVE_BOOT1};
|
||||
|
||||
for(BYTE i = 0; i < ARRAY_SIZE(emmc_drives); i++){
|
||||
res = f_mount(&boot_storage_fs, drive_base_paths[emmc_drives[i]], true);
|
||||
if(res == FR_OK){
|
||||
res = f_chdrive(drive_base_paths[emmc_drives[i]]);
|
||||
if(res == FR_OK && _is_eligible()){
|
||||
drive_cur = emmc_drives[i];
|
||||
drive = drive_cur;
|
||||
break;
|
||||
}else{
|
||||
f_mount(NULL, drive_base_paths[emmc_drives[i]],false);
|
||||
res = FR_INVALID_DRIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(res != FR_OK){
|
||||
if(!prev_emmc_initialized) {
|
||||
emmc_end();
|
||||
}
|
||||
}
|
||||
|
||||
if(res == FR_OK){
|
||||
return true;
|
||||
}
|
||||
|
||||
emmc_init_fail:
|
||||
if(!emmc_initialize(false)){
|
||||
goto emmc_init_fail2;
|
||||
}
|
||||
|
||||
if(!emmc_mount()){
|
||||
if(!prev_emmc_initialized) {
|
||||
emmc_end();
|
||||
}
|
||||
goto emmc_init_fail2;
|
||||
}
|
||||
|
||||
res = f_chdrive(drive_base_paths[DRIVE_EMMC]);
|
||||
|
||||
if(res == FR_OK && _is_eligible()){
|
||||
drive_cur = DRIVE_EMMC;
|
||||
drive = drive_cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
emmc_init_fail2:
|
||||
if(!sd_initialize(false)){
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(!sd_mount()){
|
||||
if(!prev_sd_initialized) {
|
||||
sd_end();
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = f_chdrive(drive_base_paths[DRIVE_SD]);
|
||||
|
||||
if(res == FR_OK && _is_eligible()){
|
||||
drive_cur = DRIVE_SD;
|
||||
drive = drive_cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!prev_sd_initialized) {
|
||||
sd_end();
|
||||
}
|
||||
|
||||
out:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool boot_storage_mount(){
|
||||
bool mounted = boot_storage_get_mounted();
|
||||
bool initialized = boot_storage_get_initialized();
|
||||
bool res = mounted && initialized;
|
||||
if(!mounted){
|
||||
// not mounted. mounting will also initialize.
|
||||
res = _boot_storage_mount();
|
||||
}else if(!initialized){
|
||||
res = _boot_storage_initialize();
|
||||
}
|
||||
|
||||
if(res){
|
||||
res = f_chdrive(drive_base_paths[drive_cur]) == FR_OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void *boot_storage_file_read(const char *path, u32 *fsize)
|
||||
{
|
||||
FIL fp;
|
||||
if (!boot_storage_get_mounted())
|
||||
return NULL;
|
||||
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||
return NULL;
|
||||
|
||||
u32 size = f_size(&fp);
|
||||
if (fsize)
|
||||
*fsize = size;
|
||||
|
||||
void *buf = malloc(size);
|
||||
|
||||
if (f_read(&fp, buf, size, NULL) != FR_OK)
|
||||
{
|
||||
free(buf);
|
||||
f_close(&fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int boot_storage_save_to_file(const void *buf, u32 size, const char *filename)
|
||||
{
|
||||
FIL fp;
|
||||
u32 res = 0;
|
||||
if (!boot_storage_get_mounted())
|
||||
return FR_DISK_ERR;
|
||||
|
||||
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res)
|
||||
{
|
||||
EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename);
|
||||
return res;
|
||||
}
|
||||
|
||||
f_write(&fp, buf, size, NULL);
|
||||
f_close(&fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FATFS *boot_storage_get_fs() {
|
||||
switch(drive_cur){
|
||||
case DRIVE_BOOT1:
|
||||
return &boot_storage_fs;
|
||||
case DRIVE_EMMC:
|
||||
return &emmc_fs;
|
||||
case DRIVE_BOOT1_1MB:
|
||||
return &boot_storage_fs;
|
||||
case DRIVE_SD:
|
||||
return &sd_fs;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
24
bdk/storage/boot_storage.h
Normal file
24
bdk/storage/boot_storage.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _BOOT_STORAGE_H
|
||||
#define _BOOT_STORAGE_H
|
||||
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
// check if boot1 (1mb), boot1, gpp, sd (in that order) have fat32 partition,
|
||||
// mount the partition and set the current drive to it
|
||||
bool boot_storage_mount();
|
||||
|
||||
void boot_storage_unmount();
|
||||
void boot_storage_end();
|
||||
|
||||
bool boot_storage_get_mounted();
|
||||
bool boot_storage_get_initialized();
|
||||
|
||||
void *boot_storage_file_read(const char *path, u32 *fsize);
|
||||
int boot_storage_save_to_file(const void *buf, u32 size, const char *filename);
|
||||
|
||||
FATFS *boot_storage_get_fs();
|
||||
|
||||
u8 boot_storage_get_drive();
|
||||
|
||||
#endif
|
||||
@@ -21,10 +21,14 @@
|
||||
#include <mem/heap.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <utils/list.h>
|
||||
#include <storage/emummc_file_based.h>
|
||||
|
||||
static u16 emmc_errors[3] = { 0 }; // Init and Read/Write errors.
|
||||
static u32 emmc_mode = EMMC_MMC_HS400;
|
||||
static bool emmc_init_done = false;
|
||||
static bool emmc_mounted = false;
|
||||
|
||||
sdmmc_t emmc_sdmmc;
|
||||
sdmmc_storage_t emmc_storage;
|
||||
@@ -61,7 +65,26 @@ u32 emmc_get_mode()
|
||||
return emmc_mode;
|
||||
}
|
||||
|
||||
void emmc_end() { sdmmc_storage_end(&emmc_storage); }
|
||||
static void _emmc_deinit(bool deinit){
|
||||
if(emmc_init_done){
|
||||
// TODO: Allow unmount even when not init'd?
|
||||
if(emmc_mounted){
|
||||
f_mount(NULL, "emmc:", 0);
|
||||
}
|
||||
|
||||
if(deinit){
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
emmc_init_done = false;
|
||||
}
|
||||
}
|
||||
emmc_mounted = false;
|
||||
}
|
||||
|
||||
void emmc_end() { _emmc_deinit(true); }
|
||||
|
||||
bool emmc_get_initialized(){
|
||||
return emmc_init_done;
|
||||
}
|
||||
|
||||
int emmc_init_retry(bool power_cycle)
|
||||
{
|
||||
@@ -97,7 +120,13 @@ int emmc_init_retry(bool power_cycle)
|
||||
emmc_mode = EMMC_MMC_HS400;
|
||||
}
|
||||
|
||||
return sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
|
||||
int res = sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
|
||||
if(res){
|
||||
emmc_init_done = true;
|
||||
}else{
|
||||
emmc_init_done = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool emmc_initialize(bool power_cycle)
|
||||
@@ -212,6 +241,14 @@ int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *bu
|
||||
#endif
|
||||
}
|
||||
|
||||
sdmmc_storage_t *emmc_part_get_storage(){
|
||||
#ifdef BDK_EMUMMC_ENABLE
|
||||
return emummc_get_storage();
|
||||
#else
|
||||
return &emmc_storage;
|
||||
#endif
|
||||
}
|
||||
|
||||
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1)
|
||||
{
|
||||
if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD)
|
||||
@@ -225,3 +262,44 @@ void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1)
|
||||
*mod1 = 0x84;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool emmc_mount()
|
||||
{
|
||||
if (emmc_init_done && emmc_mounted)
|
||||
return true;
|
||||
|
||||
int res = 0;
|
||||
|
||||
if (!emmc_init_done)
|
||||
res = !emmc_initialize(false);
|
||||
|
||||
if (res)
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
EPRINTF("Failed to init eMMC.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!emmc_mounted)
|
||||
res = f_mount(&emmc_fs, "emmc:", 1); // Volume 0 is SD.
|
||||
if (res == FR_OK)
|
||||
{
|
||||
emmc_mounted = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
EPRINTFARGS("Failed to mount eMMC (FatFS Error %d).\nMake sure that a FAT partition exists..", res);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool emmc_get_mounted(){
|
||||
return emmc_mounted;
|
||||
}
|
||||
|
||||
void emmc_unmount() { _emmc_deinit(false); }
|
||||
@@ -65,12 +65,17 @@ int emmc_init_retry(bool power_cycle);
|
||||
bool emmc_initialize(bool power_cycle);
|
||||
int emmc_set_partition(u32 partition);
|
||||
void emmc_end();
|
||||
bool emmc_mount();
|
||||
void emmc_unmount();
|
||||
bool emmc_get_initialized();
|
||||
bool emmc_get_mounted();
|
||||
|
||||
void emmc_gpt_parse(link_t *gpt);
|
||||
void emmc_gpt_free(link_t *gpt);
|
||||
emmc_part_t *emmc_part_find(link_t *gpt, const char *name);
|
||||
int emmc_part_read(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
|
||||
int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
|
||||
sdmmc_storage_t *emmc_part_get_storage();
|
||||
|
||||
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1);
|
||||
|
||||
|
||||
233
bdk/storage/emummc_file_based.c
Normal file
233
bdk/storage/emummc_file_based.c
Normal file
@@ -0,0 +1,233 @@
|
||||
#include "emummc_file_based.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
// TODO: fast read/writes
|
||||
|
||||
static FIL active_file;
|
||||
// -0xff: none, -1: boot 0, -2: boot1, 0+: gpp
|
||||
static s32 active_file_idx;
|
||||
static char file_based_base_path[0x80];
|
||||
static u32 file_part_sz_sct;
|
||||
static u32 active_part;
|
||||
static u32 file_based_base_path_len;
|
||||
|
||||
static int _emummc_storage_file_based_read_write_single(u32 sector, u32 num_sectors, void *buf, bool is_write){
|
||||
#if FF_FS_READONLY == 1
|
||||
if(is_write){
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
int res = f_lseek(&active_file, (u64)sector << 9);
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
if(is_write){
|
||||
res = f_write(&active_file, buf, (u64)num_sectors << 9, NULL);
|
||||
}else{
|
||||
res = f_read(&active_file, buf, (u64)num_sectors << 9, NULL);
|
||||
}
|
||||
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
static int _emummc_storage_file_based_change_file(const char *name, s32 idx){
|
||||
int res;
|
||||
|
||||
if(active_file_idx == idx){
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
if(active_file_idx != -0xff){
|
||||
f_close(&active_file);
|
||||
active_file_idx = -0xff;
|
||||
}
|
||||
|
||||
strcpy(file_based_base_path + file_based_base_path_len, name);
|
||||
|
||||
|
||||
#if FF_FS_READONLY == 1
|
||||
res = f_open(&active_file, file_based_base_path, FA_READ);
|
||||
#else
|
||||
res = f_open(&active_file, file_based_base_path, FA_READ | FA_WRITE);
|
||||
#endif
|
||||
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
active_file_idx = idx;
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
static int _emummc_storage_file_based_read_write(u32 sector, u32 num_sectors, void *buf, bool is_write){
|
||||
#if FF_FS_READONLY == 1
|
||||
if(is_write){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(file_part_sz_sct == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
if(active_part == 1){
|
||||
// boot0
|
||||
res = _emummc_storage_file_based_change_file("BOOT0", -1);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
res = _emummc_storage_file_based_read_write_single(sector, num_sectors, buf, is_write);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
f_sync(&active_file);
|
||||
return 1;
|
||||
}else if(active_part == 2){
|
||||
// boot1
|
||||
res = _emummc_storage_file_based_change_file("BOOT1", -2);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
res = _emummc_storage_file_based_read_write_single(sector, num_sectors, buf, is_write) == FR_OK;
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
f_sync(&active_file);
|
||||
return 1;
|
||||
}else if(active_part == 0){
|
||||
// GPP
|
||||
if(file_part_sz_sct == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 scts_left = num_sectors;
|
||||
u32 cur_sct = sector;
|
||||
while(scts_left){
|
||||
// offset within file
|
||||
u32 offset = cur_sct % file_part_sz_sct;
|
||||
// read up to start of next file or sectors left, whatever is less
|
||||
u32 sct_cnt = file_part_sz_sct - offset;
|
||||
sct_cnt = MIN(sct_cnt, scts_left);
|
||||
|
||||
u32 file_idx = cur_sct / file_part_sz_sct;
|
||||
|
||||
if((s32)file_idx != active_file_idx){
|
||||
char name[3] = "";
|
||||
if(file_idx < 10){
|
||||
strcpy(name, "0");
|
||||
}
|
||||
itoa(file_idx, name + strlen(name), 10);
|
||||
|
||||
|
||||
res = _emummc_storage_file_based_change_file(name, file_idx);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
res = _emummc_storage_file_based_read_write_single(offset, sct_cnt, buf + ((u64)(num_sectors - scts_left) << 9), is_write);
|
||||
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur_sct += sct_cnt;
|
||||
scts_left -= sct_cnt;
|
||||
}
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
f_sync(&active_file);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emummc_storage_file_base_set_partition(u32 partition){
|
||||
active_part = partition;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int emummc_storage_file_based_init(const char *path){
|
||||
strcpy(file_based_base_path, path);
|
||||
file_based_base_path_len = strlen(file_based_base_path);
|
||||
strcat(file_based_base_path + file_based_base_path_len, "00");
|
||||
|
||||
active_part = 0;
|
||||
|
||||
FILINFO fi;
|
||||
if(f_stat(file_based_base_path, &fi) != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_part_sz_sct = 0;
|
||||
if(fi.fsize){
|
||||
file_part_sz_sct = fi.fsize >> 9;
|
||||
}
|
||||
|
||||
active_file_idx = -0xff;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void emummc_storage_file_based_end(){
|
||||
if(active_file_idx != -0xff){
|
||||
f_close(&active_file);
|
||||
}
|
||||
active_file_idx = -0xff;
|
||||
file_based_base_path[0] = '\0';
|
||||
file_part_sz_sct = 0;
|
||||
}
|
||||
|
||||
#if FF_FS_READONLY == 0
|
||||
int emummc_storage_file_based_write(u32 sector, u32 num_sectors, void *buf){
|
||||
return _emummc_storage_file_based_read_write(sector, num_sectors, buf, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
int emummc_storage_file_based_read(u32 sector, u32 num_sectors, void *buf){
|
||||
return _emummc_storage_file_based_read_write(sector, num_sectors, buf, false);
|
||||
}
|
||||
|
||||
u32 emummc_storage_file_based_get_total_gpp_size(const char *path){
|
||||
u32 path_len = strlen(path);
|
||||
u32 total_size_sct = 0;
|
||||
char file_path[0x80];
|
||||
u32 cur_idx = 0;
|
||||
int res;
|
||||
|
||||
strcpy(file_path, path);
|
||||
strcpy(file_path + path_len, "00");
|
||||
|
||||
FILINFO fi;
|
||||
res = f_stat(file_path, &fi);
|
||||
|
||||
while(res == FR_OK){
|
||||
cur_idx++;
|
||||
total_size_sct += fi.fsize >> 9;
|
||||
|
||||
char name[3] = "0";
|
||||
if(cur_idx >= 10){
|
||||
name[0] = '\0';
|
||||
}
|
||||
itoa(cur_idx, name + strlen(name), 10);
|
||||
|
||||
strcpy(file_path + path_len, name);
|
||||
|
||||
res = f_stat(file_path, &fi);
|
||||
}
|
||||
|
||||
return total_size_sct;
|
||||
}
|
||||
14
bdk/storage/emummc_file_based.h
Normal file
14
bdk/storage/emummc_file_based.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _EMUMMC_FILE_BASED_H
|
||||
#define _EMUMMC_FILE_BASED_H
|
||||
|
||||
#include <bdk.h>
|
||||
|
||||
int emummc_storage_file_base_set_partition(u32 partition);
|
||||
int emummc_storage_file_based_init(const char *path);
|
||||
void emummc_storage_file_based_end();
|
||||
int emummc_storage_file_based_write(u32 sector, u32 num_sectors, void *buf);
|
||||
int emummc_storage_file_based_read(u32 sector, u32 num_sectors, void *buf);
|
||||
u32 emummc_storage_file_based_get_total_gpp_size(const char *path);
|
||||
sdmmc_storage_t *emummc_get_storage();
|
||||
|
||||
#endif
|
||||
184
bdk/storage/file_based_storage.c
Normal file
184
bdk/storage/file_based_storage.c
Normal file
@@ -0,0 +1,184 @@
|
||||
#include "file_based_storage.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct{
|
||||
FIL active_file;
|
||||
s32 active_file_idx;
|
||||
char base_path[0x80];
|
||||
u32 part_sz_sct;
|
||||
u32 base_path_len;
|
||||
}file_based_storage_ctxt_t;
|
||||
|
||||
static file_based_storage_ctxt_t ctx;
|
||||
|
||||
int file_based_storage_init(const char *base_path) {
|
||||
ctx.active_file_idx = -0xff;
|
||||
ctx.base_path_len = strlen(base_path);
|
||||
|
||||
strcpy(ctx.base_path, base_path);
|
||||
strcat(ctx.base_path, "00");
|
||||
|
||||
FILINFO fi;
|
||||
if(f_stat(ctx.base_path, &fi) != FR_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fi.fsize) {
|
||||
ctx.part_sz_sct = fi.fsize >> 9;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
ctx.part_sz_sct = fi.fsize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void file_based_storage_end() {
|
||||
if(ctx.active_file_idx != -0xff) {
|
||||
f_close(&ctx.active_file);
|
||||
}
|
||||
ctx.active_file_idx = -0xff;
|
||||
ctx.part_sz_sct = 0;
|
||||
}
|
||||
|
||||
static int file_based_storage_change_file(const char *name, s32 idx) {
|
||||
int res;
|
||||
|
||||
if(ctx.active_file_idx == idx){
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
if(ctx.active_file_idx != -0xff){
|
||||
f_close(&ctx.active_file);
|
||||
ctx.active_file_idx = -0xff;
|
||||
}
|
||||
|
||||
strcpy(ctx.base_path + ctx.base_path_len, name);
|
||||
|
||||
#if FF_FS_READONLY == 1
|
||||
res = f_open(&ctx.active_file, ctx.base_path, FA_READ);
|
||||
#else
|
||||
res = f_open(&ctx.active_file, ctx.base_path, FA_READ | FA_WRITE);
|
||||
#endif
|
||||
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
ctx.active_file_idx = idx;
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
static int file_based_storage_readwrite_single(u32 sector, u32 num_sectors, void *buf, bool is_write){
|
||||
#if FF_FS_READONLY == 1
|
||||
if(is_write){
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
int res = f_lseek(&ctx.active_file, (u64)sector << 9);
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
if(is_write){
|
||||
res = f_write(&ctx.active_file, buf, (u64)num_sectors << 9, NULL);
|
||||
}else{
|
||||
res = f_read(&ctx.active_file, buf, (u64)num_sectors << 9, NULL);
|
||||
}
|
||||
|
||||
if(res != FR_OK){
|
||||
return res;
|
||||
}
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
int file_based_storage_readwrite(u32 sector, u32 num_sectors, void *buf, bool is_write) {
|
||||
#if FF_FS_READONLY == 1
|
||||
if(is_write){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ctx.part_sz_sct == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
u32 scts_left = num_sectors;
|
||||
u32 cur_sct = sector;
|
||||
|
||||
while(scts_left){
|
||||
u32 offset = cur_sct % ctx.part_sz_sct;
|
||||
u32 sct_cnt = ctx.part_sz_sct - offset;
|
||||
sct_cnt = MIN(scts_left, sct_cnt);
|
||||
|
||||
u32 file_idx = cur_sct / ctx.part_sz_sct;
|
||||
|
||||
if((s32) file_idx != ctx.active_file_idx) {
|
||||
char name[3];
|
||||
if(file_idx < 10){
|
||||
strcpy(name, "0");
|
||||
}
|
||||
itoa(file_idx, name + strlen(name), 10);
|
||||
|
||||
res = file_based_storage_change_file(name, file_idx);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
res = file_based_storage_readwrite_single(offset, sct_cnt, buf + ((u64)(num_sectors - scts_left) << 9), is_write);
|
||||
if(res != FR_OK){
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur_sct += sct_cnt;
|
||||
scts_left -= sct_cnt;
|
||||
}
|
||||
|
||||
f_sync(&ctx.active_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int file_based_storage_read(u32 sector, u32 num_sectors, void *buf) {
|
||||
return file_based_storage_readwrite(sector, num_sectors, buf, false);
|
||||
}
|
||||
|
||||
int file_based_storage_write(u32 sector, u32 num_sectors, void *buf) {
|
||||
return file_based_storage_readwrite(sector, num_sectors, buf, true);
|
||||
}
|
||||
|
||||
u32 file_based_storage_get_total_size() {
|
||||
u32 total_size_sct = 0;
|
||||
char file_path[0x80];
|
||||
u32 cur_idx = 0;
|
||||
int res;
|
||||
|
||||
strcpy(file_path, ctx.base_path);
|
||||
strcpy(file_path + ctx.base_path_len, "00");
|
||||
|
||||
FILINFO fi;
|
||||
res = f_stat(file_path, &fi);
|
||||
|
||||
while(res == FR_OK){
|
||||
cur_idx++;
|
||||
total_size_sct += fi.fsize >> 9;
|
||||
|
||||
char name[3] = "0";
|
||||
if(cur_idx >= 10){
|
||||
name[0] = '\0';
|
||||
}
|
||||
itoa(cur_idx, name + strlen(name), 10);
|
||||
|
||||
strcpy(file_path + ctx.base_path_len, name);
|
||||
|
||||
res = f_stat(file_path, &fi);
|
||||
}
|
||||
|
||||
return total_size_sct;
|
||||
}
|
||||
15
bdk/storage/file_based_storage.h
Normal file
15
bdk/storage/file_based_storage.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _FILE_BASED_STORAGE_H
|
||||
#define _FILE_BASED_STORAGE_H
|
||||
|
||||
#include <bdk.h>
|
||||
|
||||
|
||||
int file_based_storage_init(const char *base_path);
|
||||
void file_based_storage_end();
|
||||
|
||||
int file_based_storage_read(u32 sector, u32 num_sectors, void *buf);
|
||||
int file_based_storage_write(u32 sector, u32 num_sectors, void *buf);
|
||||
|
||||
u32 file_based_storage_get_total_size();
|
||||
|
||||
#endif
|
||||
39
bdk/storage/mbr_gpt.c
Normal file
39
bdk/storage/mbr_gpt.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "mbr_gpt.h"
|
||||
#include <utils/types.h>
|
||||
#include <string.h>
|
||||
|
||||
bool mbr_has_gpt(const mbr_t *mbr){
|
||||
for(u32 i = 0; i < 4; i++){
|
||||
if(mbr->partitions[i].type == 0xee){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void wctombs(const u16 *src, char *dest, u32 len_max){
|
||||
const u16 *cur = src;
|
||||
do{
|
||||
*dest++ = *cur & 0xff;
|
||||
len_max--;
|
||||
}while(*cur++ && len_max);
|
||||
}
|
||||
|
||||
void ctowcs(const char *src, u16 *dest, u32 len_max){
|
||||
const char *cur = src;
|
||||
do{
|
||||
*dest++ = *cur;
|
||||
len_max--;
|
||||
}while(*cur++ && len_max);
|
||||
}
|
||||
|
||||
s32 gpt_get_part_by_name(gpt_t *gpt, const char* name, s32 prev){
|
||||
u16 wc_name[36];
|
||||
ctowcs(name, wc_name, 36);
|
||||
for(s32 i = prev + 1; i < (s32)gpt->header.num_part_ents && i < 128; i++){
|
||||
if(!memcmp(wc_name, gpt->entries[i].name, strlen(name) * 2)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -81,4 +81,10 @@ typedef struct _gpt_t
|
||||
gpt_entry_t entries[128];
|
||||
} gpt_t;
|
||||
|
||||
bool mbr_has_gpt(const mbr_t *mbr);
|
||||
void wctombs(const u16 *src, char *dest, u32 len_max);
|
||||
void ctowcs(const char *src, u16 *dest, u32 len_max);
|
||||
s32 gpt_get_part_by_name(gpt_t *gpt, const char* name, s32 prev);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,454 +0,0 @@
|
||||
/*
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
* Copyright 2018-2021 CTCaer
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Many thanks to Alessandro Rubini and Jonathan Corbet!
|
||||
*
|
||||
* Based strongly on code by:
|
||||
*
|
||||
* Author: Yong-iL Joh <tolkien@mizi.com>
|
||||
*
|
||||
* Author: Andrew Christian
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef MMC_H
|
||||
#define MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
#define MMC_GO_IDLE_STATE 0 /* bc */
|
||||
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
|
||||
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
|
||||
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
|
||||
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
|
||||
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
|
||||
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
|
||||
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
|
||||
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
|
||||
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
|
||||
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
|
||||
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
|
||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
||||
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
|
||||
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
|
||||
|
||||
/* class 2 */
|
||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
||||
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||
|
||||
/* class 3 */
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
|
||||
|
||||
/* class 4 */
|
||||
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||
|
||||
/* class 6 */
|
||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
||||
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE 38 /* ac R1b */
|
||||
|
||||
/* class 9 */
|
||||
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
|
||||
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
|
||||
|
||||
/* class 7 */
|
||||
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
|
||||
|
||||
/* class 8 */
|
||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||
|
||||
#define MMC_VENDOR_60_CMD 60 /* Vendor Defined */
|
||||
#define MMC_VENDOR_61_CMD 61 /* Vendor Defined */
|
||||
#define MMC_VENDOR_62_CMD 62 /* Vendor Defined */
|
||||
#define MMC_VENDOR_63_CMD 63 /* Vendor Defined */
|
||||
|
||||
/* class 11 */
|
||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
|
||||
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
* MMC status in R1, for native mode (SPI bits are different)
|
||||
* Type
|
||||
* e : error bit
|
||||
* s : status bit
|
||||
* r : detected and set for the actual command response
|
||||
* x : detected and set during command execution. the host must poll
|
||||
* the card by sending status command in order to read these bits.
|
||||
* Clear condition
|
||||
* a : according to the card state
|
||||
* b : always related to the previous command. Reception of a valid
|
||||
* command will clear it (with a delay of one command)
|
||||
* c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
|
||||
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
|
||||
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
|
||||
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
|
||||
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
|
||||
#define R1_CC_ERROR (1 << 20) /* erx, c */
|
||||
#define R1_ERROR (1 << 19) /* erx, c */
|
||||
#define R1_UNDERRUN (1 << 18) /* ex, c */
|
||||
#define R1_OVERRUN (1 << 17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) ((x) & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
#define R1_APP_CMD (1 << 5) /* sr, c */
|
||||
#define R1_SKIP_STATE_CHECK (1 << 4) /* Custom state to skip expected state check */
|
||||
#define R1_AKE_SEQ_ERROR (1 << 3)
|
||||
|
||||
/* R1_CURRENT_STATE 12:9 */
|
||||
#define R1_STATE(x) ((x) << 9)
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
#define R1_STATE_STBY 3
|
||||
#define R1_STATE_TRAN 4
|
||||
#define R1_STATE_DATA 5
|
||||
#define R1_STATE_RCV 6
|
||||
#define R1_STATE_PRG 7
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
#define R1_SPI_IDLE (1 << 0)
|
||||
#define R1_SPI_ERASE_RESET (1 << 1)
|
||||
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
|
||||
#define R1_SPI_COM_CRC (1 << 3)
|
||||
#define R1_SPI_ERASE_SEQ (1 << 4)
|
||||
#define R1_SPI_ADDRESS (1 << 5)
|
||||
#define R1_SPI_PARAMETER (1 << 6)
|
||||
/* R1 bit 7 is always zero */
|
||||
#define R2_SPI_CARD_LOCKED (1 << 8)
|
||||
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
|
||||
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
|
||||
#define R2_SPI_ERROR (1 << 10)
|
||||
#define R2_SPI_CC_ERROR (1 << 11)
|
||||
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
|
||||
#define R2_SPI_WP_VIOLATION (1 << 13)
|
||||
#define R2_SPI_ERASE_PARAM (1 << 14)
|
||||
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
|
||||
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */
|
||||
#define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
|
||||
#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */
|
||||
#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
|
||||
/* (CMD11) */
|
||||
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
|
||||
/* (CMD16,17,18) */
|
||||
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
|
||||
/* (CMD20) */
|
||||
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
|
||||
/* (CMD16,24,25,26,27) */
|
||||
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
|
||||
/* (CMD32,33,34,35,36,37,38,39) */
|
||||
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
|
||||
/* (CMD28,29,30) */
|
||||
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
|
||||
/* (CMD16,CMD42) */
|
||||
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
|
||||
/* (CMD55,56,57,ACMD*) */
|
||||
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
|
||||
/* (CMD5,39,40,52,53) */
|
||||
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
|
||||
/* (CMD6,34,35,36,37,50) */
|
||||
/* (11) Reserved */
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
|
||||
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
|
||||
|
||||
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
|
||||
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
|
||||
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
|
||||
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
|
||||
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
|
||||
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
|
||||
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
|
||||
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
|
||||
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
|
||||
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
|
||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||
#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */
|
||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||
#define EXT_CSD_BKOPS_EN 163 /* R/W */
|
||||
#define EXT_CSD_BKOPS_START 164 /* W */
|
||||
#define EXT_CSD_SANITIZE_START 165 /* W */
|
||||
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
|
||||
#define EXT_CSD_RPMB_MULT 168 /* RO */
|
||||
#define EXT_CSD_FW_CONFIG 169 /* R/W */
|
||||
#define EXT_CSD_BOOT_WP 173 /* R/W */
|
||||
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
|
||||
#define EXT_CSD_PART_CONFIG 179 /* R/W */
|
||||
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
|
||||
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
|
||||
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
|
||||
#define EXT_CSD_HS_TIMING 185 /* R/W */
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
#define EXT_CSD_REV 192 /* RO */
|
||||
#define EXT_CSD_STRUCTURE 194 /* RO */
|
||||
#define EXT_CSD_CARD_TYPE 196 /* RO */
|
||||
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
|
||||
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
|
||||
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
|
||||
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
|
||||
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
|
||||
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
|
||||
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
|
||||
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
|
||||
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
|
||||
#define EXT_CSD_BOOT_MULT 226 /* RO */
|
||||
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
|
||||
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
|
||||
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
|
||||
#define EXT_CSD_TRIM_MULT 232 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
|
||||
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
|
||||
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
|
||||
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
|
||||
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
|
||||
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
|
||||
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
|
||||
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
|
||||
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
|
||||
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
|
||||
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
|
||||
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
|
||||
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
|
||||
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
|
||||
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||
|
||||
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
|
||||
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||
|
||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
|
||||
|
||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
|
||||
EXT_CSD_CARD_TYPE_HS_52)
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.8V or 3V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
||||
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
|
||||
/* SDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
||||
|
||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
|
||||
|
||||
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
|
||||
#define EXT_CSD_TIMING_HS 1 /* High speed */
|
||||
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
|
||||
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
|
||||
|
||||
#define EXT_CSD_SEC_ER_EN (1<<0)
|
||||
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
|
||||
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
|
||||
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
|
||||
|
||||
#define EXT_CSD_RST_N_EN_MASK 0x3
|
||||
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
|
||||
|
||||
#define EXT_CSD_NO_POWER_NOTIFICATION 0
|
||||
#define EXT_CSD_POWER_ON 1
|
||||
#define EXT_CSD_POWER_OFF_SHORT 2
|
||||
#define EXT_CSD_POWER_OFF_LONG 3
|
||||
|
||||
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
|
||||
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
|
||||
|
||||
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS (1<<0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
|
||||
#define EXT_CSD_PACKED_FAILURE (1<<3)
|
||||
|
||||
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_OK 0x0
|
||||
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
|
||||
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
|
||||
#define EXT_CSD_BKOPS_CRITICAL 0x3
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
|
||||
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
|
||||
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
#define MMC_DISCARD_ARG 0x00000003
|
||||
#define MMC_SECURE_TRIM1_ARG 0x80000001
|
||||
#define MMC_SECURE_TRIM2_ARG 0x80008000
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
/*
|
||||
* Vendor definitions and structs
|
||||
*/
|
||||
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
|
||||
|
||||
#endif /* MMC_H */
|
||||
433
bdk/storage/mmc_def.h
Normal file
433
bdk/storage/mmc_def.h
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
* Copyright 2018-2026 CTCaer
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Many thanks to Alessandro Rubini and Jonathan Corbet!
|
||||
*
|
||||
* Based strongly on code by:
|
||||
*
|
||||
* Author: Yong-iL Joh <tolkien@mizi.com>
|
||||
*
|
||||
* Author: Andrew Christian
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef MMC_H
|
||||
#define MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
#define MMC_GO_IDLE_STATE 0 /* bc */
|
||||
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
|
||||
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
|
||||
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
|
||||
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
|
||||
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
|
||||
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
|
||||
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
|
||||
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
|
||||
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
|
||||
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
|
||||
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
|
||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
||||
|
||||
/* class 2 */
|
||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
||||
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||
|
||||
/* class 3 */
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
|
||||
|
||||
/* class 4 */
|
||||
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||
#define MMC_SET_TIME 49 /* adtc R1 */
|
||||
|
||||
/* class 6 */
|
||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
||||
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||
#define MMC_SEND_WR_PROTECT_TYPE 31 /* adtc [31:0] wpdata addr R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE 38 /* ac R1b */
|
||||
|
||||
/* class 9 */
|
||||
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
|
||||
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
|
||||
|
||||
/* class 7 */
|
||||
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
|
||||
|
||||
/* class 8 */
|
||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||
|
||||
/* class 10 */
|
||||
#define MMC_PROTOCOL_RD 53 /* adtc R1 */
|
||||
#define MMC_PROTOCOL_WR 54 /* adtc R1 */
|
||||
|
||||
/* class 11 */
|
||||
#define MMC_QUEUED_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||
#define MMC_QUEUED_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
|
||||
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
/* class 12 */
|
||||
#define MMC_VENDOR_CMD_60 60 /* Vendor Defined */
|
||||
#define MMC_VENDOR_CMD_61 61 /* Vendor Defined */
|
||||
#define MMC_VENDOR_CMD_62 62 /* Vendor Defined */
|
||||
#define MMC_VENDOR_CMD_63 63 /* Vendor Defined */
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
* MMC status in R1, for native mode (SPI bits are different)
|
||||
* Type
|
||||
* e : error bit
|
||||
* s : status bit
|
||||
* r : detected and set for the actual command response
|
||||
* x : detected and set during command execution. the host must poll
|
||||
* the card by sending status command in order to read these bits.
|
||||
* Clear condition
|
||||
* a : according to the card state
|
||||
* b : always related to the previous command. Reception of a valid
|
||||
* command will clear it (with a delay of one command)
|
||||
* c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
|
||||
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
|
||||
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
|
||||
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
|
||||
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
|
||||
#define R1_CC_ERROR (1 << 20) /* erx, c */
|
||||
#define R1_ERROR (1 << 19) /* erx, c */
|
||||
#define R1_UNDERRUN (1 << 18) /* ex, c */
|
||||
#define R1_OVERRUN (1 << 17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) ((x) & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
#define R1_APP_CMD (1 << 5) /* sr, c */
|
||||
#define R1_SKIP_STATE_CHECK (1 << 4) /* Custom state to skip expected state check */
|
||||
#define R1_AKE_SEQ_ERROR (1 << 3)
|
||||
|
||||
/* R1_CURRENT_STATE 12:9 */
|
||||
#define R1_STATE(x) ((x) << 9)
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
#define R1_STATE_STBY 3
|
||||
#define R1_STATE_TRAN 4
|
||||
#define R1_STATE_DATA 5
|
||||
#define R1_STATE_RCV 6
|
||||
#define R1_STATE_PRG 7
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_OCR_VCCQ_18 (1 << 7) /* Card VDD voltage 1.8 */
|
||||
#define MMC_OCR_VCCQ_20_26 (0x7F << 8) /* Card VDD voltage 2.0 ~ 2.6 */
|
||||
#define MMC_OCR_VCCQ_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
|
||||
#define MMC_OCR_HCS (2 << 29) /* Host Capacity status bit */
|
||||
#define MMC_OCR_CCS MMC_OCR_HCS /* Card Capacity status bit */
|
||||
#define MMC_OCR_BUSY (1 << 31) /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
|
||||
/* (CMD11) */
|
||||
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
|
||||
/* (CMD16,17,18) */
|
||||
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
|
||||
/* (CMD20) */
|
||||
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
|
||||
/* (CMD16,24,25,26,27) */
|
||||
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
|
||||
/* (CMD32,33,34,35,36,37,38,39) */
|
||||
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
|
||||
/* (CMD28,29,30) */
|
||||
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
|
||||
/* (CMD16,CMD42) */
|
||||
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
|
||||
/* (CMD55,56,57,ACMD*) */
|
||||
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
|
||||
/* (CMD5,39,40,52,53) */
|
||||
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
|
||||
/* (CMD6,34,35,36,37,50) */
|
||||
/* (11) Reserved */
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
|
||||
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
|
||||
|
||||
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
|
||||
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
|
||||
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
|
||||
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
|
||||
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
|
||||
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
|
||||
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
|
||||
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
|
||||
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
|
||||
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
|
||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||
#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */
|
||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||
#define EXT_CSD_BKOPS_EN 163 /* R/W */
|
||||
#define EXT_CSD_BKOPS_START 164 /* W */
|
||||
#define EXT_CSD_SANITIZE_START 165 /* W */
|
||||
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
|
||||
#define EXT_CSD_RPMB_MULT 168 /* RO */
|
||||
#define EXT_CSD_FW_CONFIG 169 /* R/W */
|
||||
#define EXT_CSD_BOOT_WP 173 /* R/W */
|
||||
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
|
||||
#define EXT_CSD_PART_CONFIG 179 /* R/W */
|
||||
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
|
||||
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
|
||||
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
|
||||
#define EXT_CSD_HS_TIMING 185 /* R/W */
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
#define EXT_CSD_REV 192 /* RO */
|
||||
#define EXT_CSD_STRUCTURE 194 /* RO */
|
||||
#define EXT_CSD_CARD_TYPE 196 /* RO */
|
||||
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
|
||||
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
|
||||
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
|
||||
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
|
||||
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
|
||||
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
|
||||
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
|
||||
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
|
||||
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
|
||||
#define EXT_CSD_BOOT_MULT 226 /* RO */
|
||||
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
|
||||
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
|
||||
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
|
||||
#define EXT_CSD_TRIM_MULT 232 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
|
||||
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
|
||||
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
|
||||
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
|
||||
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
|
||||
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
|
||||
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
|
||||
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
|
||||
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
|
||||
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
|
||||
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
|
||||
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
|
||||
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
|
||||
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
|
||||
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||
|
||||
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
|
||||
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||
|
||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
|
||||
|
||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | EXT_CSD_CARD_TYPE_HS_52)
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.8V or 3V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
|
||||
/* SDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
||||
|
||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
|
||||
|
||||
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
|
||||
#define EXT_CSD_TIMING_HS 1 /* High speed */
|
||||
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
|
||||
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
|
||||
|
||||
#define EXT_CSD_SEC_ER_EN (1<<0)
|
||||
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
|
||||
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
|
||||
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
|
||||
|
||||
#define EXT_CSD_RST_N_EN_MASK 0x3
|
||||
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
|
||||
|
||||
#define EXT_CSD_NO_POWER_NOTIFICATION 0
|
||||
#define EXT_CSD_POWER_ON 1
|
||||
#define EXT_CSD_POWER_OFF_SHORT 2
|
||||
#define EXT_CSD_POWER_OFF_LONG 3
|
||||
|
||||
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
|
||||
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
|
||||
|
||||
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS (1<<0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
|
||||
#define EXT_CSD_PACKED_FAILURE (1<<3)
|
||||
|
||||
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_OK 0x0
|
||||
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
|
||||
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
|
||||
#define EXT_CSD_BKOPS_CRITICAL 0x3
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_MANUAL 0x01 /* STICKY! */
|
||||
#define EXT_CSD_BKOPS_AUTO 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
|
||||
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
#define MMC_DISCARD_ARG 0x00000003
|
||||
#define MMC_SECURE_TRIM1_ARG 0x80000001
|
||||
#define MMC_SECURE_TRIM2_ARG 0x80008000
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
/*
|
||||
* Vendor definitions and structs
|
||||
*/
|
||||
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
|
||||
|
||||
#endif /* MMC_H */
|
||||
@@ -17,6 +17,9 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <stdlib.h>
|
||||
#include <storage/nx_emmc_bis.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory_map.h>
|
||||
@@ -26,6 +29,7 @@
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <storage/emummc_file_based.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BIS_CLUSTER_SECTORS 32
|
||||
@@ -56,6 +60,8 @@ static u32 emu_offset = 0;
|
||||
static emmc_part_t *system_part = NULL;
|
||||
static u32 *cache_lookup_tbl = (u32 *)NX_BIS_LOOKUP_ADDR;
|
||||
static bis_cache_t *bis_cache = (bis_cache_t *)NX_BIS_CACHE_ADDR;
|
||||
static sdmmc_storage_t *emu_storage = NULL;
|
||||
static bool file_based = false;
|
||||
|
||||
static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush)
|
||||
{
|
||||
@@ -91,14 +97,18 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush
|
||||
}
|
||||
|
||||
// Encrypt cluster.
|
||||
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, ENCRYPT, cluster, tweak, true, sector_in_cluster, bis_cache->dma_buff, buff, count * EMMC_BLOCKSIZE))
|
||||
if (se_aes_crypt_xts_sec_nx(ks_tweak, ks_crypt, ENCRYPT, cluster, tweak, true, sector_in_cluster, bis_cache->dma_buff, buff, count * EMMC_BLOCKSIZE))
|
||||
return 1; // Encryption error.
|
||||
|
||||
// If not reading from cache, do a regular read and decrypt.
|
||||
if (!emu_offset)
|
||||
if(emu_storage){
|
||||
res = sdmmc_storage_write(emu_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}else if(file_based){
|
||||
res = emummc_storage_file_based_write(system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}else{
|
||||
res = emmc_part_write(system_part, sector, count, bis_cache->dma_buff);
|
||||
else
|
||||
res = sdmmc_storage_write(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}
|
||||
|
||||
if (!res)
|
||||
return 1; // R/W error.
|
||||
|
||||
@@ -155,10 +165,13 @@ static int nx_emmc_bis_read_block_normal(u32 sector, u32 count, void *buff)
|
||||
u32 sector_in_cluster = sector % BIS_CLUSTER_SECTORS;
|
||||
|
||||
// If not reading from cache, do a regular read and decrypt.
|
||||
if (!emu_offset)
|
||||
if(emu_storage){
|
||||
res = sdmmc_storage_read(emu_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}else if(file_based){
|
||||
res = emummc_storage_file_based_read(system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}else{
|
||||
res = emmc_part_read(system_part, sector, count, bis_cache->dma_buff);
|
||||
else
|
||||
res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff);
|
||||
}
|
||||
if (!res)
|
||||
return 1; // R/W error.
|
||||
|
||||
@@ -177,7 +190,7 @@ static int nx_emmc_bis_read_block_normal(u32 sector, u32 count, void *buff)
|
||||
tweak_exp = sector_in_cluster;
|
||||
|
||||
// Maximum one cluster (1 XTS crypto block 16KB).
|
||||
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, prev_cluster, tweak, regen_tweak, tweak_exp, buff, bis_cache->dma_buff, count * EMMC_BLOCKSIZE))
|
||||
if (se_aes_crypt_xts_sec_nx(ks_tweak, ks_crypt, DECRYPT, prev_cluster, tweak, regen_tweak, tweak_exp, buff, bis_cache->dma_buff, count * EMMC_BLOCKSIZE))
|
||||
return 1; // R/W error.
|
||||
|
||||
prev_sector = sector + count - 1;
|
||||
@@ -212,15 +225,19 @@ static int nx_emmc_bis_read_block_cached(u32 sector, u32 count, void *buff)
|
||||
cache_lookup_tbl[cluster] = bis_cache->top_idx;
|
||||
|
||||
// Read the whole cluster the sector resides in.
|
||||
if (!emu_offset)
|
||||
if (emu_storage){
|
||||
res = sdmmc_storage_read(emu_storage, emu_offset + system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
|
||||
}else if(file_based){
|
||||
res = emummc_storage_file_based_read(system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
|
||||
}else{
|
||||
res = emmc_part_read(system_part, cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
|
||||
else
|
||||
res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff);
|
||||
}
|
||||
|
||||
if (!res)
|
||||
return 1; // R/W error.
|
||||
|
||||
// Decrypt cluster.
|
||||
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, cluster, cache_tweak, true, 0, bis_cache->dma_buff, bis_cache->dma_buff, BIS_CLUSTER_SIZE))
|
||||
if (se_aes_crypt_xts_sec_nx(ks_tweak, ks_crypt, DECRYPT, cluster, cache_tweak, true, 0, bis_cache->dma_buff, bis_cache->dma_buff, BIS_CLUSTER_SIZE))
|
||||
return 1; // Decryption error.
|
||||
|
||||
// Copy to cluster cache.
|
||||
@@ -292,10 +309,11 @@ int nx_emmc_bis_write(u32 sector, u32 count, void *buff)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset)
|
||||
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, sdmmc_storage_t *storage, u32 emummc_offset)
|
||||
{
|
||||
system_part = part;
|
||||
emu_offset = emummc_offset;
|
||||
emu_storage = storage;
|
||||
|
||||
_nx_emmc_bis_cluster_cache_init(enable_cache);
|
||||
|
||||
@@ -318,8 +336,31 @@ void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset)
|
||||
system_part = NULL;
|
||||
}
|
||||
|
||||
void nx_emmc_bis_init_file_based(emmc_part_t *part, bool enable_cache, const char *base_path){
|
||||
emummc_storage_file_based_init(base_path);
|
||||
file_based = true;
|
||||
|
||||
nx_emmc_bis_init(part, enable_cache, NULL, 0);
|
||||
}
|
||||
|
||||
void nx_emmc_bis_end()
|
||||
{
|
||||
_nx_emmc_bis_flush_cache();
|
||||
|
||||
if(file_based){
|
||||
emummc_storage_file_based_end();
|
||||
}
|
||||
|
||||
system_part = NULL;
|
||||
emu_storage = NULL;
|
||||
emu_offset = 0;
|
||||
file_based = false;
|
||||
}
|
||||
|
||||
sdmmc_storage_t *nx_emmc_bis_get_storage(){
|
||||
if(emu_storage == &emmc_storage){
|
||||
return &emmc_storage;
|
||||
}else{
|
||||
return emmc_part_get_storage();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc.h>
|
||||
|
||||
#define NAND_PATROL_SECTOR 0xC20
|
||||
|
||||
typedef struct _nx_emmc_cal0_spk_t
|
||||
{
|
||||
u16 unk0;
|
||||
@@ -65,13 +67,18 @@ typedef struct _nx_emmc_cal0_spk_t
|
||||
|
||||
typedef struct _nx_emmc_cal0_t
|
||||
{
|
||||
// Header.
|
||||
u32 magic; // 'CAL0'.
|
||||
u32 version;
|
||||
u32 body_size;
|
||||
u16 model;
|
||||
u16 update_cnt;
|
||||
u8 pad_crc16_0[0x10];
|
||||
u8 pad_crc16_hdr[0x10];
|
||||
|
||||
// SHA256 for body.
|
||||
u8 body_sha256[0x20];
|
||||
|
||||
// Body.
|
||||
char cfg_id1[0x1E];
|
||||
u8 crc16_pad1[2];
|
||||
u8 rsvd0[0x20];
|
||||
@@ -225,11 +232,15 @@ typedef struct _nx_emmc_cal0_t
|
||||
|
||||
// 10.0.0 and up.
|
||||
u8 console_6axis_sensor_mount_type;
|
||||
u8 crc16_pad61[0xF];
|
||||
} __attribute__((packed)) nx_emmc_cal0_t;
|
||||
|
||||
int nx_emmc_bis_read(u32 sector, u32 count, void *buff);
|
||||
int nx_emmc_bis_write(u32 sector, u32 count, void *buff);
|
||||
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset);
|
||||
// when storage == NULL, use active emummc config, otherwise, access storage at offset
|
||||
void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, sdmmc_storage_t *storage, u32 emummc_offset);
|
||||
void nx_emmc_bis_init_file_based(emmc_part_t *part, bool enable_cache, const char *base_path);
|
||||
void nx_emmc_bis_end();
|
||||
sdmmc_storage_t *nx_emmc_bis_get_storage();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,7 @@ int ram_disk_init(void *ram_fs, u32 ramdisk_size)
|
||||
disk_set_info(DRIVE_RAM, SET_SECTOR_COUNT, &ramdisk_size);
|
||||
|
||||
// Unmount ramdisk.
|
||||
f_mount(NULL, "ram:", 1);
|
||||
f_unmount("ram:");
|
||||
|
||||
// Format as exFAT w/ 32KB cluster with no MBR.
|
||||
res = f_mkfs("ram:", FM_EXFAT | FM_SFD, RAMDISK_CLUSTER_SZ, buf, 0x400000);
|
||||
|
||||
@@ -199,7 +199,7 @@ bool sd_mount()
|
||||
else
|
||||
{
|
||||
if (!sd_mounted)
|
||||
res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD.
|
||||
res = f_mount(&sd_fs, "sd:", 1); // Volume 0 is SD.
|
||||
if (res == FR_OK)
|
||||
{
|
||||
sd_mounted = true;
|
||||
@@ -227,7 +227,7 @@ static void _sd_deinit(bool deinit)
|
||||
if (sd_init_done)
|
||||
{
|
||||
if (sd_mounted)
|
||||
f_mount(NULL, "0:", 1); // Volume 0 is SD.
|
||||
f_unmount("sd:"); // Volume 0 is SD.
|
||||
|
||||
if (deinit)
|
||||
{
|
||||
@@ -246,14 +246,30 @@ bool sd_is_gpt()
|
||||
return sd_fs.part_type;
|
||||
}
|
||||
|
||||
|
||||
void *sd_file_read(const char *path, u32 *fsize)
|
||||
{
|
||||
FIL fp;
|
||||
if (!sd_get_card_mounted())
|
||||
return NULL;
|
||||
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||
char *cwd = (char*)malloc(0x200);
|
||||
|
||||
if(f_getcwd(cwd, 0x200) != FR_OK){
|
||||
free(cwd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(f_chdrive("sd:") != FR_OK){
|
||||
free(cwd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK){
|
||||
f_chdrive(cwd);
|
||||
free(cwd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 size = f_size(&fp);
|
||||
if (fsize)
|
||||
@@ -263,13 +279,17 @@ void *sd_file_read(const char *path, u32 *fsize)
|
||||
|
||||
if (f_read(&fp, buf, size, NULL) != FR_OK)
|
||||
{
|
||||
f_chdrive(cwd);
|
||||
free(buf);
|
||||
free(cwd);
|
||||
f_close(&fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f_chdrive(cwd);
|
||||
f_close(&fp);
|
||||
free(cwd);
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -281,13 +301,33 @@ int sd_save_to_file(const void *buf, u32 size, const char *filename)
|
||||
if (!sd_get_card_mounted())
|
||||
return FR_DISK_ERR;
|
||||
|
||||
char *cwd = malloc(0x200);
|
||||
|
||||
res = f_getcwd(cwd, 0x200);
|
||||
|
||||
if(res != FR_OK){
|
||||
free(cwd);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = f_chdrive("sd:");
|
||||
|
||||
if(res != FR_OK){
|
||||
free(cwd);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res)
|
||||
{
|
||||
EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename);
|
||||
f_chdrive(cwd);
|
||||
free(cwd);
|
||||
return res;
|
||||
}
|
||||
|
||||
f_chdrive(cwd);
|
||||
free(cwd);
|
||||
f_write(&fp, buf, size, NULL);
|
||||
f_close(&fp);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -11,47 +11,96 @@
|
||||
#ifndef SD_DEF_H
|
||||
#define SD_DEF_H
|
||||
|
||||
/* SD commands type argument response */
|
||||
/* SD commands type argument response */
|
||||
/* class 0 */
|
||||
/* This is basically the same command as for MMC with some quirks. */
|
||||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
||||
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
||||
/* class 10 */
|
||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||
#define SD_VOLTAGE_SWITCH 11 /* ac R1 */
|
||||
/* Class 1 */
|
||||
#define SD_Q_MANAGEMENT 43 /* ac R1b */
|
||||
#define SD_Q_TASK_INFO_A 44 /* ac R1 */
|
||||
#define SD_Q_TASK_INFO_B 45 /* ac R1 */
|
||||
#define SD_Q_RD_TASK 46 /* adtc R1 */
|
||||
#define SD_Q_WR_TASK 47 /* adtc R1 */
|
||||
/* Class 2 */
|
||||
#define SD_SEND_TUNING_BLOCK 19 /* ac R1b */
|
||||
#define SD_SPEED_CLASS_CONTROL 20 /* ac [31:0] R1 */
|
||||
#define SD_ADDRESS_EXTENSION 22 /* ac [5:0] UC ext addr R1 */
|
||||
/* class 5 */
|
||||
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
|
||||
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
||||
/* Class 9 */
|
||||
#define SD_IO_SEND_OP_COND 5 /* bcr [31:0] OCR R4 */
|
||||
#define SD_IO_RW_DIRECT 52 /* ac R5 */
|
||||
#define SD_IO_RW_EXTENDED 53 /* adtc R5 */
|
||||
/* class 10 */
|
||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||
#define SD_CMD_SYSTEM_34 34 /* cmd system defined */
|
||||
#define SD_CMD_SYSTEM_35 35 /* cmd system defined */
|
||||
#define SD_CMD_SYSTEM_36 36 /* cmd system defined */
|
||||
#define SD_CMD_SYSTEM_37 37 /* cmd system defined */
|
||||
#define SD_CMD_SYSTEM_50 50 /* cmd system defined */
|
||||
#define SD_CMD_SYSTEM_57 57 /* cmd system defined */
|
||||
/* class 11 */
|
||||
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
|
||||
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
|
||||
#define SD_READ_EXTR_MULTI 58 /* adtc [31:0] R1 */
|
||||
#define SD_WRITE_EXTR_MULTI 59 /* adtc [31:0] R1 */
|
||||
#define SD_VENDOR_CMD_60 60 /* vendor defined */
|
||||
#define SD_VENDOR_CMD_61 61 /* vendor defined */
|
||||
#define SD_VENDOR_CMD_62 62 /* vendor defined */
|
||||
#define SD_VENDOR_CMD_63 63 /* vendor defined */
|
||||
|
||||
/* Application commands */
|
||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
||||
#define SD_APP_SD_STATUS 13 /* adtc R1 */
|
||||
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
|
||||
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
|
||||
#define SD_APP_SEND_NUM_WR_BLOCKS 22 /* adtc R1 */
|
||||
#define SD_APP_SET_WR_BLK_ERASE_COUNT 23 /* ac R1 */
|
||||
#define SD_APP_SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */
|
||||
#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */
|
||||
#define SD_APP_SEND_SCR 51 /* adtc R1 */
|
||||
|
||||
/* Application secure commands */
|
||||
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
|
||||
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
|
||||
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
|
||||
#define SD_APP_SECURE_ERASE 38 /* adtc R1b */
|
||||
#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */
|
||||
#define SD_APP_GET_MID 44 /* adtc R1 */
|
||||
#define SD_APP_SET_CER_RN1 45 /* adtc R1 */
|
||||
#define SD_APP_GET_CER_RN2 46 /* adtc R1 */
|
||||
#define SD_APP_SET_CER_RES2 47 /* adtc R1 */
|
||||
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
|
||||
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
|
||||
/* Application sd secure commands */
|
||||
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
|
||||
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
|
||||
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
|
||||
#define SD_APP_SECURE_ERASE 38 /* adtc R1b */
|
||||
#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */
|
||||
#define SD_APP_GET_MID 44 /* adtc R1 */
|
||||
#define SD_APP_SET_CER_RN1 45 /* adtc R1 */
|
||||
#define SD_APP_GET_CER_RN2 46 /* adtc R1 */
|
||||
#define SD_APP_SET_CER_RES2 47 /* adtc R1 */
|
||||
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
|
||||
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
|
||||
|
||||
/* ICR bit definitions */
|
||||
#define SD_ICR_PATTERN 0xAA /* Check pattern */
|
||||
#define SD_ICR_VHS_27_36 (1U << 8) /* VDD IO voltage 2.7 ~ 3.6 */
|
||||
#define SD_ICR_VHS_170_195 (2U << 8) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only) */
|
||||
#define SD_ICR_PCIE (1U << 12) /* PCIE availability */
|
||||
#define SD_ICR_PCIE_12 (1U << 13) /* PCIE IO voltage 1.2 */
|
||||
|
||||
/* OCR bit definitions */
|
||||
#define SD_OCR_VDD_18 (1U << 7) /* VDD voltage 1.8 */
|
||||
#define SD_VHS_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
|
||||
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||
#define SD_OCR_VDD_170_195 (1U << 7) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only or support) */
|
||||
#define SD_OCR_VDD_27_28 (1U << 15) /* VDD IO voltage 2.7 ~ 2.8 */
|
||||
#define SD_OCR_VDD_28_29 (1U << 16) /* VDD IO voltage 2.8 ~ 2.9 */
|
||||
#define SD_OCR_VDD_29_30 (1U << 17) /* VDD IO voltage 2.9 ~ 3.0 */
|
||||
#define SD_OCR_VDD_30_31 (1U << 18) /* VDD IO voltage 3.0 ~ 3.1 */
|
||||
#define SD_OCR_VDD_31_32 (1U << 19) /* VDD IO voltage 3.1 ~ 3.2 */
|
||||
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD IO voltage 3.2 ~ 3.3 */
|
||||
#define SD_OCR_VDD_33_34 (1U << 21) /* VDD IO voltage 3.3 ~ 3.4 */
|
||||
#define SD_OCR_VDD_34_35 (1U << 22) /* VDD IO voltage 3.4 ~ 3.5 */
|
||||
#define SD_OCR_VDD_35_36 (1U << 23) /* VDD IO voltage 3.5 ~ 3.6 */
|
||||
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
|
||||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||
#define SD_OCR_XPC (1U << 28) /* SDXC power control */
|
||||
#define SD_OCR_CCS (1U << 30) /* Card Capacity Status */
|
||||
#define SD_OCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||
#define SD_OCR_HO2T (1U << 27) /* SDUC support */
|
||||
#define SD_OCR_CO2T SD_OCR_HO2T /* SDUC Status */
|
||||
#define SD_OCR_XPC (1U << 28) /* SDXC power control - Max Performance */
|
||||
#define SD_OCR_FB (1U << 29) /* eSD Fast Boot Support */
|
||||
#define SD_OCR_UHSII (1U << 29) /* UHS-II Card Status */
|
||||
#define SD_OCR_HCS (1U << 30) /* Host Capacity Support */
|
||||
#define SD_OCR_CCS SD_OCR_HCS /* Card Capacity Status */
|
||||
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
|
||||
|
||||
/*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -24,13 +24,20 @@
|
||||
|
||||
#define SDMMC_CMD_BLOCKSIZE 64
|
||||
#define SDMMC_DAT_BLOCKSIZE 512
|
||||
#define SDMMC_HMAX_BLOCKNUM 0xFFFF // HW max.
|
||||
#define SDMMC_AMAX_BLOCKNUM 0xF000 // Aligned max.
|
||||
|
||||
extern u32 sd_power_cycle_time_start;
|
||||
|
||||
typedef enum _sdmmc_type
|
||||
{
|
||||
MMC_SD = 0,
|
||||
MMC_EMMC = 1,
|
||||
MMC_SD = 0,
|
||||
MMC_EMMC = 1,
|
||||
MMC_EMUMMC_FILE = 2,
|
||||
MMC_EMUMMC_RAW_SD = 3,
|
||||
MMC_EMUMMC_RAW_EMMC = 4,
|
||||
MMC_EMUMMC_FILE_EMMC = 5,
|
||||
MMC_FILE_BASED = 6,
|
||||
|
||||
EMMC_GPP = 0,
|
||||
EMMC_BOOT0 = 1,
|
||||
@@ -115,15 +122,16 @@ typedef struct _mmc_sandisk_report_t
|
||||
|
||||
typedef struct _mmc_cid
|
||||
{
|
||||
u32 manfid;
|
||||
u32 manfid; // SDA assigned.
|
||||
u8 prod_name[8];
|
||||
u32 serial;
|
||||
u16 oemid;
|
||||
u16 oemid; // SDA assigned.
|
||||
u16 year;
|
||||
u8 prv;
|
||||
u8 hwrev;
|
||||
u8 fwrev;
|
||||
u8 month;
|
||||
u32 rsvd;
|
||||
} mmc_cid_t;
|
||||
|
||||
typedef struct _mmc_csd
|
||||
@@ -141,9 +149,8 @@ typedef struct _mmc_csd
|
||||
|
||||
typedef struct _mmc_ext_csd
|
||||
{
|
||||
//u8 bkops; /* background support bit */
|
||||
//u8 bkops_en; /* manual bkops enable bit */
|
||||
//u8 bkops_status; /* 246 */
|
||||
u8 bkops; /* background support bit */
|
||||
u8 bkops_en; /* manual bkops enable bit */
|
||||
u8 rev;
|
||||
u8 ext_struct; /* 194 */
|
||||
u8 card_type; /* 196 */
|
||||
@@ -160,9 +167,10 @@ typedef struct _mmc_ext_csd
|
||||
typedef struct _sd_scr
|
||||
{
|
||||
u8 sda_vsn;
|
||||
u8 sda_spec3;
|
||||
u8 sda_spec;
|
||||
u8 bus_widths;
|
||||
u8 cmds;
|
||||
u32 vendor;
|
||||
} sd_scr_t;
|
||||
|
||||
typedef struct _sd_ssr
|
||||
@@ -174,30 +182,18 @@ typedef struct _sd_ssr
|
||||
u8 app_class;
|
||||
u8 au_size;
|
||||
u8 uhs_au_size;
|
||||
u8 perf_enhance;
|
||||
u32 protected_size;
|
||||
} sd_ssr_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
typedef struct _sdmmc_storage_t
|
||||
typedef struct _sd_ext_reg_t
|
||||
{
|
||||
sdmmc_t *sdmmc;
|
||||
u32 rca;
|
||||
int has_sector_access;
|
||||
u32 sec_cnt;
|
||||
int is_low_voltage;
|
||||
u32 partition;
|
||||
int initialized;
|
||||
u32 card_power_limit;
|
||||
u8 raw_cid[0x10];
|
||||
u8 raw_csd[0x10];
|
||||
u8 raw_scr[8];
|
||||
u8 raw_ssr[0x40];
|
||||
mmc_cid_t cid;
|
||||
mmc_csd_t csd;
|
||||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
sd_ssr_t ssr;
|
||||
} sdmmc_storage_t;
|
||||
u8 cmdq;
|
||||
u8 cmdq_ext;
|
||||
u8 cache;
|
||||
u8 cache_ext;
|
||||
int valid;
|
||||
} sd_ext_reg_t;
|
||||
|
||||
typedef struct _sd_func_modes_t
|
||||
{
|
||||
@@ -207,6 +203,64 @@ typedef struct _sd_func_modes_t
|
||||
u16 power_limit;
|
||||
} sd_func_modes_t;
|
||||
|
||||
typedef struct _sd_vendor_info_t
|
||||
{
|
||||
// CID Reserved.
|
||||
u8 cid_rsvd; // 4-bit.
|
||||
|
||||
// CSD Reserved.
|
||||
u8 csd_rsvd8_9; // 2-bit.
|
||||
u8 csd_rsvd16_20; // 5-bit.
|
||||
u8 csd_rsvd29_30; // 2-bit.
|
||||
u8 csd_rsvd120_125; // 6-bit.
|
||||
|
||||
u32 scr_vendor;
|
||||
u8 scr_rsvd; // 2-bit.
|
||||
|
||||
u32 ssr_vendor0_31;
|
||||
u32 ssr_vendor32_63;
|
||||
u32 ssr_vendor64_95;
|
||||
u32 ssr_vendor96_127;
|
||||
u32 ssr_vendor128_159;
|
||||
u32 ssr_vendor160_191;
|
||||
u32 ssr_vendor192_223;
|
||||
u32 ssr_vendor224_255;
|
||||
u32 ssr_vendor256_287;
|
||||
u32 ssr_vendor288_311; // 24-bit.
|
||||
|
||||
u16 ssr_rsvd314_327; // 14-bit.
|
||||
u8 ssr_rsvd340_345; // 6-bit.
|
||||
u8 ssr_rsvd378_383; // 6-bit.
|
||||
u8 ssr_rsvd424_427; // 4-bit.
|
||||
u8 ssr_rsvd496_501; // 6-bit.
|
||||
} sd_vendor_info_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
typedef struct _sdmmc_storage_t
|
||||
{
|
||||
sdmmc_t *sdmmc;
|
||||
|
||||
int initialized;
|
||||
int is_low_voltage;
|
||||
int has_sector_access;
|
||||
int has_pcie;
|
||||
u32 rca;
|
||||
u32 sec_cnt;
|
||||
u32 partition;
|
||||
u32 max_power;
|
||||
u8 raw_cid[0x10] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN)));
|
||||
u8 raw_csd[0x10] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN)));
|
||||
u8 raw_scr[8] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN)));
|
||||
u8 raw_ssr[SDMMC_CMD_BLOCKSIZE] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN)));
|
||||
u8 raw_ext_csd[SDMMC_DAT_BLOCKSIZE] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN)));
|
||||
mmc_cid_t cid;
|
||||
mmc_csd_t csd;
|
||||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
sd_ssr_t ssr;
|
||||
sd_ext_reg_t ser;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
||||
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
@@ -216,14 +270,22 @@ void sdmmc_storage_init_wait_sd();
|
||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type);
|
||||
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
||||
|
||||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
||||
int sdmmc_storage_gen_cmd(sdmmc_storage_t *storage, u32 arg, void *buf);
|
||||
int sdmmc_storage_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
||||
|
||||
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf);
|
||||
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
|
||||
|
||||
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf);
|
||||
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
|
||||
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_get_scr(sdmmc_storage_t *storage);
|
||||
u8 sd_storage_get_scr_sda_ver(sdmmc_storage_t *storage);
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage);
|
||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
||||
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf);
|
||||
bool sd_storage_get_ddr200_support(sdmmc_storage_t *storage);
|
||||
|
||||
void sd_storage_get_vendor_info(sdmmc_storage_t *storage, sd_vendor_info_t *info);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/mmc_def.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <power/max7762x.h>
|
||||
@@ -115,7 +115,7 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
u32 tap_val = 0;
|
||||
|
||||
if (type == SDHCI_TIMING_MMC_HS400)
|
||||
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8);
|
||||
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & ~0x3F00) | (dqs_trim_val << 8);
|
||||
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
@@ -129,7 +129,7 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
else
|
||||
tap_val = sdmmc->t210b01 ? 11 : tap_values_t210[sdmmc->id];
|
||||
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & ~0xFF0000) | (tap_val << 16);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -144,16 +144,16 @@ static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
switch (sdmmc->id)
|
||||
{
|
||||
case SDMMC_1: // 33 Ohm 2X Driver.
|
||||
case SDMMC_1: // 50 Ohm 2X Driver.
|
||||
if (power == SDMMC_POWER_OFF)
|
||||
break;
|
||||
u32 sdmmc1_pad_cfg = APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xF8080FFF;
|
||||
if (sdmmc->t210b01)
|
||||
sdmmc1_pad_cfg |= (0x808 << 12); // Up: 8, Dn: 8. For 33 ohm.
|
||||
sdmmc1_pad_cfg |= (0x808 << 12); // Up: 8, Dn: 8. For 50 ohm.
|
||||
else if (power == SDMMC_POWER_1_8)
|
||||
sdmmc1_pad_cfg |= (0xB0F << 12); // Up: 11, Dn: 15. For 33 ohm.
|
||||
sdmmc1_pad_cfg |= (0xB0F << 12); // Up: 11, Dn: 15. For 50 ohm.
|
||||
else if (power == SDMMC_POWER_3_3)
|
||||
sdmmc1_pad_cfg |= (0xC0C << 12); // Up: 12, Dn: 12. For 33 ohm.
|
||||
sdmmc1_pad_cfg |= (0xC0C << 12); // Up: 12, Dn: 12. For 50 ohm.
|
||||
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg;
|
||||
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
|
||||
break;
|
||||
@@ -212,7 +212,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
||||
// Use 0x1F mask for all.
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
|
||||
if (!autocal_pu_status)
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1);
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1); // Or resistance is extreme.
|
||||
else if (autocal_pu_status == 0x1F)
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
|
||||
#endif
|
||||
@@ -394,8 +394,8 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
|
||||
static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
|
||||
{
|
||||
// Recalibrate conditionally.
|
||||
if (sdmmc->manual_cal && !sdmmc->powersave_enabled)
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && !sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
if (!sdmmc->powersave_enabled)
|
||||
@@ -414,8 +414,8 @@ static void _sdmmc_card_clock_disable(sdmmc_t *sdmmc)
|
||||
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
|
||||
{
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && !powersave_enable && sdmmc->card_clock_enabled)
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && !powersave_enable && sdmmc->card_clock_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
sdmmc->powersave_enabled = powersave_enable;
|
||||
@@ -431,41 +431,22 @@ void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
if (size < 4)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->regs->rspreg0;
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
rsp[0] = sdmmc->regs->rspreg[0];
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
if (size < 0x10)
|
||||
return 0;
|
||||
// CRC is stripped, so shifting is needed.
|
||||
u32 tempreg;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
tempreg = sdmmc->regs->rspreg3;
|
||||
break;
|
||||
case 1:
|
||||
tempreg = sdmmc->regs->rspreg2;
|
||||
break;
|
||||
case 2:
|
||||
tempreg = sdmmc->regs->rspreg1;
|
||||
break;
|
||||
case 3:
|
||||
tempreg = sdmmc->regs->rspreg0;
|
||||
break;
|
||||
}
|
||||
u32 tempreg = sdmmc->regs->rspreg[3 - i];
|
||||
rsp[i] = tempreg << 8;
|
||||
|
||||
if (i != 0)
|
||||
@@ -480,7 +461,7 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
{
|
||||
if (!rsp || sdmmc->expected_rsp_type != type)
|
||||
return 0;
|
||||
@@ -489,20 +470,14 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
|
||||
{
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
if (size < 4)
|
||||
return 0;
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
if (size < 16)
|
||||
return 0;
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
rsp[1] = sdmmc->rsp[1];
|
||||
rsp[2] = sdmmc->rsp[2];
|
||||
rsp[3] = sdmmc->rsp[3];
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
rsp[i] = sdmmc->rsp[i];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -585,8 +560,8 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, const sdmmc_cmd_t *cmd, bool is_data_
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
if (cmd->check_busy)
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
else
|
||||
@@ -637,7 +612,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd, u32 tap)
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
// Set tap if manual tuning.
|
||||
if (tap != HW_TAP_TUNING)
|
||||
if (tap != SDMMC_HW_TAP_TUNING)
|
||||
{
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap << 16);
|
||||
@@ -687,7 +662,7 @@ typedef struct _sdmmc_manual_tuning_t
|
||||
|
||||
static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *tuning)
|
||||
{
|
||||
u32 tap_start = INVALID_TAP;
|
||||
u32 tap_start = SDMMC_INVALID_TAP;
|
||||
u32 win_size = 0;
|
||||
u32 best_tap = 0;
|
||||
u32 best_size = 0;
|
||||
@@ -698,14 +673,14 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
|
||||
u32 stable = tuning->result[i / 32] & BIT(i % 32);
|
||||
if (stable && !iter_end)
|
||||
{
|
||||
if (tap_start == INVALID_TAP)
|
||||
if (tap_start == SDMMC_INVALID_TAP)
|
||||
tap_start = i;
|
||||
|
||||
win_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tap_start != INVALID_TAP)
|
||||
if (tap_start != SDMMC_INVALID_TAP)
|
||||
{
|
||||
u32 tap_end = !iter_end ? (i - 1) : i;
|
||||
|
||||
@@ -716,7 +691,7 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
|
||||
best_size = win_size + iter_end;
|
||||
}
|
||||
|
||||
tap_start = INVALID_TAP;
|
||||
tap_start = SDMMC_INVALID_TAP;
|
||||
win_size = 0;
|
||||
}
|
||||
}
|
||||
@@ -724,7 +699,7 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
|
||||
|
||||
|
||||
// Check if failed or window too small.
|
||||
if (!best_tap || best_size < SAMPLING_WINDOW_SIZE_MIN)
|
||||
if (!best_tap || best_size < SDMMC_SAMPLE_WIN_SIZE_MIN)
|
||||
return 0;
|
||||
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
@@ -824,7 +799,7 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
|
||||
|
||||
for (u32 i = 0; i < num_iter; i++)
|
||||
{
|
||||
_sdmmc_tuning_execute_once(sdmmc, cmd, HW_TAP_TUNING);
|
||||
_sdmmc_tuning_execute_once(sdmmc, cmd, SDMMC_HW_TAP_TUNING);
|
||||
|
||||
if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))
|
||||
break;
|
||||
@@ -915,6 +890,7 @@ static void _sdmmc_enable_interrupts(sdmmc_t *sdmmc)
|
||||
sdmmc->regs->errintstsen |= SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR;
|
||||
sdmmc->regs->norintsts = sdmmc->regs->norintsts;
|
||||
sdmmc->regs->errintsts = sdmmc->regs->errintsts;
|
||||
sdmmc->error_sts = 0;
|
||||
}
|
||||
|
||||
static void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)
|
||||
@@ -928,7 +904,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
u16 norintsts = sdmmc->regs->norintsts;
|
||||
u16 errintsts = sdmmc->regs->errintsts;
|
||||
|
||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
DPRINTF("norintsts %04X, errintsts %04X\n", norintsts, errintsts);
|
||||
|
||||
if (pout)
|
||||
*pout = norintsts;
|
||||
@@ -937,8 +913,9 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
if (norintsts & SDHCI_INT_ERROR)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
|
||||
EPRINTFARGS("SDMMC%d: intsts %04X, errintsts %04X", sdmmc->id + 1, norintsts, errintsts);
|
||||
#endif
|
||||
sdmmc->error_sts = errintsts;
|
||||
sdmmc->regs->errintsts = errintsts;
|
||||
return SDMMC_MASKINT_ERROR;
|
||||
}
|
||||
@@ -993,7 +970,7 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
_sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1);
|
||||
_sdmmc_cache_rsp(sdmmc, rsp, SDMMC_RSP_TYPE_1);
|
||||
|
||||
return _sdmmc_wait_card_busy(sdmmc);
|
||||
}
|
||||
@@ -1003,8 +980,8 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
||||
if (!sdmmc->card_clock_enabled)
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
bool should_disable_sd_clock = false;
|
||||
@@ -1031,8 +1008,8 @@ static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, const sdmmc_req_t
|
||||
return 0;
|
||||
|
||||
u32 blkcnt = req->num_sectors;
|
||||
if (blkcnt >= 0xFFFF)
|
||||
blkcnt = 0xFFFF;
|
||||
if (blkcnt >= SDMMC_HMAX_BLOCKNUM)
|
||||
blkcnt = SDMMC_HMAX_BLOCKNUM;
|
||||
u32 admaaddr = (u32)req->buf;
|
||||
|
||||
// Check alignment.
|
||||
@@ -1120,7 +1097,7 @@ static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
|
||||
|
||||
static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)
|
||||
{
|
||||
int has_req_or_check_busy = req || cmd->check_busy;
|
||||
bool has_req_or_check_busy = req || cmd->check_busy;
|
||||
if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, has_req_or_check_busy))
|
||||
return 0;
|
||||
|
||||
@@ -1147,7 +1124,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
if (!_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type);
|
||||
EPRINTFARGS("SDMMC%d: Wrong Response type %d!", sdmmc->id + 1, cmd->rsp_type);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1158,13 +1135,13 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
EPRINTFARGS("SDMMC%d: Transfer error!", sdmmc->id + 1);
|
||||
#endif
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
sdmmc->regs->rspreg[0], sdmmc->regs->rspreg[1], sdmmc->regs->rspreg[2], sdmmc->regs->rspreg[3]);
|
||||
if (result)
|
||||
{
|
||||
if (cmd->rsp_type)
|
||||
{
|
||||
sdmmc->expected_rsp_type = cmd->rsp_type;
|
||||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
|
||||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, cmd->rsp_type);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
if (!result)
|
||||
EPRINTFARGS("SDMMC%d: Unknown response type!", sdmmc->id + 1);
|
||||
@@ -1193,10 +1170,10 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
*blkcnt_out = blkcnt;
|
||||
|
||||
if (req->is_auto_stop_trn)
|
||||
sdmmc->rsp3 = sdmmc->regs->rspreg3;
|
||||
sdmmc->stop_trn_rsp = sdmmc->regs->rspreg[3];
|
||||
}
|
||||
|
||||
if (cmd->check_busy || req)
|
||||
if (has_req_or_check_busy)
|
||||
{
|
||||
result = _sdmmc_wait_card_busy(sdmmc);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
@@ -1248,7 +1225,7 @@ static void _sdmmc_config_sdmmc1_pads(bool discharge)
|
||||
u32 level = GPIO_LOW;
|
||||
u32 output = GPIO_OUTPUT_DISABLE;
|
||||
|
||||
// Set values for dicharging.
|
||||
// Set values for discharging.
|
||||
if (discharge)
|
||||
{
|
||||
function = GPIO_MODE_GPIO;
|
||||
@@ -1304,7 +1281,7 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
|
||||
// Enable SD card power. Powers LDO2 also.
|
||||
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2;
|
||||
gpio_direction_output(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
|
||||
usleep(10000);
|
||||
usleep(10000); // Minimum 3 to 10 ms.
|
||||
|
||||
// Inform IO pads that voltage is gonna be 3.3V.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
|
||||
@@ -1385,7 +1362,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
||||
if (sdmmc->t210b01)
|
||||
vref_sel = 0;
|
||||
else
|
||||
sdmmc->manual_cal = 1;
|
||||
sdmmc->periodic_calibration = 1;
|
||||
break;
|
||||
|
||||
case SDMMC_2:
|
||||
@@ -1395,7 +1372,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
||||
}
|
||||
|
||||
// Disable clock if enabled.
|
||||
if (clock_sdmmc_is_not_reset_and_enabled(id))
|
||||
if (clock_sdmmc_is_active(id))
|
||||
{
|
||||
_sdmmc_card_clock_disable(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
@@ -1419,6 +1396,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
||||
if (!_sdmmc_autocal_config_offset(sdmmc, power))
|
||||
return 0;
|
||||
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
// Calibrate pads.
|
||||
_sdmmc_autocal_execute(sdmmc, power);
|
||||
|
||||
@@ -1506,8 +1485,8 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
||||
if (!sdmmc->card_clock_enabled)
|
||||
return 0;
|
||||
|
||||
// Recalibrate periodically for SDMMC1.
|
||||
if (sdmmc->manual_cal && sdmmc->powersave_enabled)
|
||||
// Recalibrate periodically if needed.
|
||||
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
|
||||
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
|
||||
|
||||
int should_disable_sd_clock = 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -37,8 +37,8 @@
|
||||
#define SDMMC_RSP_TYPE_1 1
|
||||
#define SDMMC_RSP_TYPE_2 2
|
||||
#define SDMMC_RSP_TYPE_3 3
|
||||
#define SDMMC_RSP_TYPE_4 4
|
||||
#define SDMMC_RSP_TYPE_5 5
|
||||
#define SDMMC_RSP_TYPE_6 4
|
||||
#define SDMMC_RSP_TYPE_7 5
|
||||
|
||||
/*! SDMMC bus widths. */
|
||||
#define SDMMC_BUS_WIDTH_1 0
|
||||
@@ -101,6 +101,7 @@
|
||||
#define SDHCI_CMD_TYPE_SUSPEND (1U << 6)
|
||||
#define SDHCI_CMD_TYPE_RESUME (2U << 6)
|
||||
#define SDHCI_CMD_TYPE_ABORT (3U << 6)
|
||||
#define SDHCI_CMD_SPI_CS_LOW BIT(7)
|
||||
#define SDHCI_CMD_IDX(cmd) ((cmd) << 8)
|
||||
|
||||
|
||||
@@ -170,10 +171,10 @@
|
||||
#define SDHCI_INT_ERROR BIT(15)
|
||||
|
||||
/*! SDMMC error interrupt status and control. 0x32/0x36. */
|
||||
#define SDHCI_ERR_INT_TIMEOUT BIT(0)
|
||||
#define SDHCI_ERR_INT_CRC BIT(1)
|
||||
#define SDHCI_ERR_INT_END_BIT BIT(2)
|
||||
#define SDHCI_ERR_INT_INDEX BIT(3)
|
||||
#define SDHCI_ERR_INT_CMD_TIMEOUT BIT(0)
|
||||
#define SDHCI_ERR_INT_CMD_CRC BIT(1)
|
||||
#define SDHCI_ERR_INT_CMD_END_BIT BIT(2)
|
||||
#define SDHCI_ERR_INT_CMD_INDEX BIT(3)
|
||||
#define SDHCI_ERR_INT_DATA_TIMEOUT BIT(4)
|
||||
#define SDHCI_ERR_INT_DATA_CRC BIT(5)
|
||||
#define SDHCI_ERR_INT_DATA_END_BIT BIT(6)
|
||||
@@ -190,8 +191,8 @@
|
||||
#define SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR \
|
||||
(SDHCI_ERR_INT_AUTO_CMD12 | SDHCI_ERR_INT_DATA_END_BIT | \
|
||||
SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \
|
||||
SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \
|
||||
SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT)
|
||||
SDHCI_ERR_INT_CMD_INDEX | SDHCI_ERR_INT_CMD_END_BIT | \
|
||||
SDHCI_ERR_INT_CMD_CRC | SDHCI_ERR_INT_CMD_TIMEOUT)
|
||||
|
||||
/*! Host Capability 1. 0x40. */
|
||||
#define SDHCI_CAP_TM_CLK_FREQ_MASK 0x3F
|
||||
@@ -273,9 +274,11 @@
|
||||
/*! Helper for SWITCH command argument. */
|
||||
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
|
||||
|
||||
#define HW_TAP_TUNING 0x100
|
||||
#define INVALID_TAP 0x100
|
||||
#define SAMPLING_WINDOW_SIZE_MIN 8
|
||||
#define SDMMC_HW_TAP_TUNING 0x100
|
||||
#define SDMMC_INVALID_TAP 0x100
|
||||
#define SDMMC_SAMPLE_WIN_SIZE_MIN 8
|
||||
|
||||
#define SDMMC_ADMA_ADDR_ALIGN 8
|
||||
|
||||
/*! SDMMC controller context. */
|
||||
typedef struct _sdmmc_t
|
||||
@@ -285,14 +288,15 @@ typedef struct _sdmmc_t
|
||||
u32 card_clock;
|
||||
u32 clock_stopped;
|
||||
int powersave_enabled;
|
||||
int manual_cal;
|
||||
int periodic_calibration;
|
||||
int card_clock_enabled;
|
||||
int venclkctl_set;
|
||||
u32 venclkctl_tap;
|
||||
u32 expected_rsp_type;
|
||||
u32 dma_addr_next;
|
||||
u32 rsp[4];
|
||||
u32 rsp3;
|
||||
u32 stop_trn_rsp;
|
||||
u32 error_sts;
|
||||
int t210b01;
|
||||
} sdmmc_t;
|
||||
|
||||
@@ -323,7 +327,7 @@ void sdmmc_save_tap_value(sdmmc_t *sdmmc);
|
||||
void sdmmc_setup_drv_type(sdmmc_t *sdmmc, u32 type);
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable);
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
|
||||
int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type);
|
||||
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd);
|
||||
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
|
||||
bool sdmmc_get_sd_inserted();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -39,10 +39,7 @@ typedef struct _t210_sdmmc_t
|
||||
/* 0x08 */ vu32 argument;
|
||||
/* 0x0C */ vu16 trnmod;
|
||||
/* 0x0E */ vu16 cmdreg;
|
||||
/* 0x10 */ vu32 rspreg0;
|
||||
/* 0x14 */ vu32 rspreg1;
|
||||
/* 0x18 */ vu32 rspreg2;
|
||||
/* 0x1C */ vu32 rspreg3;
|
||||
/* 0x10 */ vu32 rspreg[4];
|
||||
/* 0x20 */ vu32 bdata; // Buffer data port.
|
||||
/* 0x24 */ vu32 prnsts;
|
||||
/* 0x28 */ vu8 hostctl;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user