diff --git a/.gitignore b/.gitignore
index f634a9b..de2d046 100755
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,6 @@ output/*
loader/payload_00.h
loader/payload_01.h
tools/bin2c/bin2c
+tools/bin2c/bin2c.exe
tools/lz/lz77
+tools/lz/lz77.exe
diff --git a/Makefile b/Makefile
index 09a5e16..be95d5c 100755
--- a/Makefile
+++ b/Makefile
@@ -25,16 +25,17 @@ VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
start.o exception_handlers.o \
main.o heap.o \
- gfx.o tui.o \
- fe_emmc_tools.o fe_info.o fe_tools.o \
+ gfx.o logos.o tui.o \
+ l4t.o fe_info.o fe_tools.o \
)
# Hardware.
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
- bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
- pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
- fuse.o kfuse.o minerva.o \
- sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o nx_sd.o \
+ 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 \
)
@@ -47,7 +48,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
# Horizon.
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
- hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o sept.o \
+ hos.o hos_config.o pkg1.o pkg2.o pkg3.o pkg2_ini_kippatch.o secmon_exo.o \
)
# Libraries.
@@ -63,18 +64,27 @@ FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"'
################################################################################
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
-CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
-CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
+CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_VER_RL=$(BLVERSION_REL)
+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_WATCHDOG_FIQ_ENABLE -DBDK_RESTART_BL_ON_WDT
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
#CUSTOMDEFINES += -DDEBUG
# 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
-ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
-CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
+#TODO: Considering reinstating some of these when pointer warnings have been fixed.
+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 $(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/*)
@@ -91,19 +101,18 @@ TOOLS := $(TOOLSLZ) $(TOOLSB2C)
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:
+clean: $(TOOLS)
@rm -rf $(OBJS)
@rm -rf $(BUILDDIR)
@rm -rf $(OUTPUTDIR)
@@ -116,7 +125,7 @@ $(NYXDIR):
$(LDRDIR): $(TARGET).bin
@$(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
@@ -129,11 +138,11 @@ $(TOOLS):
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
- $(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
+ @$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
- @echo "hekate was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
+ @printf "$(TARGET) was built with the following flags:\nCFLAGS: $(CFLAGS)\nLDFLAGS: $(LDFLAGS)\n"
$(BUILDDIR)/$(TARGET)/%.o: %.c
@echo Building $@
diff --git a/README.md b/README.md
index 3d4068a..6101ca1 100644
--- a/README.md
+++ b/README.md
@@ -6,33 +6,62 @@
Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many more.
+
+- [Features](#features)
+- [Bootloader folders and files](#bootloader-folders-and-files)
+- [Bootloader configuration](#bootloader-configuration)
+ * [hekate global Configuration keys/values](#hekate-global-configuration-keysvalues-when-entry-is-config)
+ * [Boot entry key/value combinations](#boot-entry-keyvalue-combinations)
+ * [Boot entry key/value combinations for Exosphère](#boot-entry-keyvalue-combinations-for-exosphère)
+ * [Payload storage](#payload-storage)
+ * [Nyx Configuration keys/values](#nyx-configuration-keysvalues-nyxini)
+
+
+
+## Features
+
+- **Fully Configurable and Graphical** with Touchscreen and Joycon input support
+- **Launcher Style, Background and Color Themes**
+- **HOS (Switch OS) Bootloader** -- For CFW Sys/Emu, OFW Sys and Stock Sys
+- **Android & Linux Bootloader**
+- **Payload Launcher**
+- **eMMC/emuMMC Backup/Restore Tools**
+- **SD Card Partition Manager** -- Prepares and formats SD Card for any combo of HOS (Sys/emuMMC), Android and Linux
+- **emuMMC Creation & Manager** -- Can also migrate and fix existing emuMMC
+- **Switch Android & Linux flasher**
+- **USB Mass Storage (UMS) for SD/eMMC/emuMMC** -- Converts Switch into a SD Card Reader
+- **USB Gamepad** -- Converts Switch with Joycon into a USB HID Gamepad
+- **Hardware and Peripherals info** (SoC, Fuses, RAM, Display, Touch, eMMC, SD, Battery, PSU, Charger)
+- **Many other tools** like Archive Bit Fixer, Touch Calibration, SD/eMMC Benchmark, AutoRCM enabler and more
+
+
## Bootloader folders and files
| Folder/File | Description |
| ------------------------ | --------------------------------------------------------------------- |
| bootloader | Main folder. |
-| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
-| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
+| \|__ bootlogo.bmp | It is used if no `logopath` key is found. User provided. Can be skipped. |
+| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries in `Launch` menu. |
+| \|__ nyx.ini | Nyx GUI configuration |
| \|__ patches.ini | Add external patches. Can be skipped. A template can be found [here](./res/patches_template.ini) |
-| \|__ update.bin | If newer, it is loaded at boot. For modchips. Auto updated. Can be skipped. |
-| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
+| \|__ update.bin | If newer, it is loaded at boot. Normally for modchips. Auto updated and created at first boot. |
+| bootloader/ini/ | For individual inis. `More configs` menu. Autoboot is supported. |
| bootloader/res/ | Nyx user resources. Icons and more. |
-| \|__ background.bmp | Nyx - custom background. |
+| \|__ background.bmp | Nyx - Custom background. User provided. |
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
-| \|__ icon_lakka.bmp | Nyx - Default icon for Lakka. |
-| bootloader/sys/ | For system modules. |
-| \|__ 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 - Our GUI. Important! |
-| \|__ res.pak | Nyx resources package. 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 payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
-| bootloader/libtools/ | Future reserved |
-| sept | Sept folder. This must always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. |
+| 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 |
-**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
## Bootloader configuration
@@ -43,63 +72,75 @@ The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is prese
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
-You can find a template [Here](./res/hekate_ipl_template.ini)
+**You can find a template [Here](./res/hekate_ipl_template.ini)**
-### Global Configuration keys/values when boot entry is **config**:
+### hekate Global Configuration keys/values (when entry is *[config]*):
-| Config option | Description |
-| ------------------ | ---------------------------------------------------------- |
-| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
+| 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. |
+| 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. |
-
-
-### Nyx Global Configuration keys/values for (nyx.ini):
-
-| Config option | Description |
-| ------------------ | ---------------------------------------------------------- |
-| themecolor=167 | Sets Nyx color of text highlights. |
-| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
-| 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). |
-| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
-| jcdisable=0 | 1: Disables Joycon driver completely. |
-| newpowersave=1 | 0: Timer based, 1: DRAM frequency based (Better). Use 0 if Nyx hangs. |
+| backlight=100 | Screen backlight level. 0-255. |
### Boot entry key/value combinations:
| Config option | Description |
| ---------------------- | ---------------------------------------------------------- |
-| warmboot={SD path} | Replaces the warmboot binary |
-| secmon={SD path} | Replaces the security monitor binary |
-| kernel={SD path} | Replaces the kernel binary |
-| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
-| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
-| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. |
-| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
-| exofatal={SD path} | Replaces the exosphere fatal binary for Mariko |
-| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
-| fullsvcperm=1 | Disables SVC verification (full services permission) |
-| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
-| atmosphere=1 | Enables Atmosphère patching. |
-| emupath={SD folder} | 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. |
+| warmboot={FILE path} | Replaces the warmboot binary |
+| secmon={FILE path} | Replaces the security monitor binary |
+| 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. |
+| 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. 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 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=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`. |
-| id=idname | Identifies boot entry for forced boot via id. Max 7 chars. |
-| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
-| logopath={SD path} | If no logopath, `bootloader/bootlogo.bmp` will be used if exists. If logopath exists, it will load the specified bitmap. |
-| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
+| 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. |
+| 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. |
+| ---------------------- | ---------------------------------------------------------- |
+| l4t=1 | L4T Linux/Android native launching. |
+| boot_prefixes={FOLDER path} | L4T bootstack directory. |
+| ram_oc=0 | L4T RAM Overclocking. Check README_CONFIG.txt for more info. |
+| 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]`. |
+| id=IDNAME | Identifies boot entry for forced boot via id. Max 7 chars. |
+| logopath={FILE path} | If it exists, it will load the specified bitmap. Otherwise `bootloader/bootlogo.bmp` will be used if exists |
+| icon={FILE path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise defaults will be used. |
-### Boot entry key/value Exosphère combinations:
+**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
+
+**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 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:
| Config option | Description |
| ---------------------- | ---------------------------------------------------------- |
@@ -107,52 +148,70 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
| 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. |
-**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
+**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
-**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`.
-You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
-**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include 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).
+**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:
-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 |
| ----------------------- | ----------------------------------------------------------------- |
-| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit7: `sept run`. |
-| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
+| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`. |
+| '0x95' autoboot | If `Force AutoBoot`, 0: Force go to menu, else boot that entry. |
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
-| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`, bit7: `Run Dump pkg1/2`. |
+| '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' 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. |
-If the main .ini is not found, it is created on the first hekate boot.
+### Nyx Configuration keys/values (nyx.ini):
+
+| Config option | Description |
+| ------------------ | ---------------------------------------------------------- |
+| themebg=2d2d2d | Sets Nyx background color in HEX. EXPERIMENTAL. |
+| 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 |
+| 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 ------- |
+| 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. |
```
hekate (c) 2018, naehrwert, st4rk.
- (c) 2018-2020, CTCaer.
+ (c) 2018-2025, CTCaer.
-Nyx GUI (c) 2019-2020, CTCaer.
+Nyx GUI (c) 2019-2025, CTCaer.
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
Open source and free packages used:
- - FatFs R0.13a, Copyright (c) 2017, ChaN
- - bcl-1.2.0, Copyright (c) 2003-2006, Marcus Geelnard
- - Atmosphère (Exosphere types/panic, prc id kernel patches),
- Copyright (c) 2018-2019, Atmosphère-NX
- - elfload, Copyright (c) 2014 Owen Shepherd, Copyright (c) 2018 M4xw
- - Littlev Graphics Library, Copyright (c) 2016 Gabor Kiss-Vamosi
+ - Littlev Graphics Library,
+ Copyright (c) 2016-2018 Gabor Kiss-Vamosi
+ - FatFs R0.13c,
+ Copyright (c) 2006-2018, ChaN
+ Copyright (c) 2018-2022, CTCaer
+ - bcl-1.2.0,
+ Copyright (c) 2003-2006, Marcus Geelnard
+ - blz,
+ Copyright (c) 2018, SciresM
+ - elfload,
+ Copyright (c) 2014 Owen Shepherd,
+ Copyright (c) 2018 M4xw
___
.-' `'.
diff --git a/README_BOOTLOGO.md b/README_BOOTLOGO.md
index 40d81f8..0a2b2bc 100644
--- a/README_BOOTLOGO.md
+++ b/README_BOOTLOGO.md
@@ -4,13 +4,16 @@ The bootlogo can be any size with a maximum of 720 x 1280.
When it's smaller than 720 x 1280, it is automatically centered and the background takes the color of the first pixel.
-When saving a landscape bootlogo, it should be rotated 90 degrees counterclockwise.
+The process is to create a landscape bootlogo and then rotate it 90 degrees counterclockwise.
Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are not supported for performance reasons.
## How to configure
-If the custom logo option is enabled, it will try to load /bootlogo.bmp. If this is not found, the default hekate's logo will be used.
+If a boot entry specifies a custom logo path (`logopath=`), this one will be loaded.
-If a boot entry specifies a custom logo path, this is one will be loaded. Again if this is not found, bootlogo.bmp will be loaded and if that fails, hekate's built-in will be used.
\ No newline at end of file
+If the above is not found or the format is not correct, it will try to load `bootloader/bootlogo.bmp`.
+If this is not found, the default hekate logo will be used.
+
+(`bootloader/bootlogo.bmp` is basically like a global bootlogo.)
diff --git a/Versions.inc b/Versions.inc
index 52cfef0..c2278c1 100644
--- a/Versions.inc
+++ b/Versions.inc
@@ -1,11 +1,11 @@
# IPL Version.
-BLVERSION_MAJOR := 5
-BLVERSION_MINOR := 5
+BLVERSION_MAJOR := 6
+BLVERSION_MINOR := 3
BLVERSION_HOTFX := 1
-BLVERSION_RSVD := 0
+BLVERSION_REL := 0
# Nyx Version.
-NYXVERSION_MAJOR := 0
-NYXVERSION_MINOR := 9
-NYXVERSION_HOTFX := 7
-NYXVERSION_RSVD := 0
+NYXVERSION_MAJOR := 1
+NYXVERSION_MINOR := 7
+NYXVERSION_HOTFX := 0
+NYXVERSION_REL := 0
diff --git a/bdk/bdk.h b/bdk/bdk.h
new file mode 100644
index 0000000..1d8a05e
--- /dev/null
+++ b/bdk/bdk.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2022 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 .
+ */
+
+#ifndef BDK_H
+#define BDK_H
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#endif
diff --git a/bdk/display/di.c b/bdk/display/di.c
new file mode 100644
index 0000000..3eaf922
--- /dev/null
+++ b/bdk/display/di.c
@@ -0,0 +1,1033 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * 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,
+ * 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 .
+ */
+
+#include
+
+#include "di.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "di.inl"
+
+extern volatile nyx_storage_t *nyx_str;
+
+static u32 _display_id = 0;
+static u32 _dsi_bl = -1;
+static bool _nx_aula = false;
+
+static void _display_panel_and_hw_end(bool no_panel_deinit);
+
+void display_enable_interrupt(u32 intr)
+{
+ DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) |= intr;
+}
+
+void display_disable_interrupt(u32 intr)
+{
+ DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) &= ~intr;
+ DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
+}
+
+void display_wait_interrupt(u32 intr)
+{
+ DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
+
+ // Interrupts are masked. Poll status register for checking if fired.
+ while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & intr))
+ ;
+}
+
+static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
+{
+ u32 end = get_tmr_us() + timeout;
+ while (get_tmr_us() < end && DSI(off) & mask)
+ ;
+ usleep(5);
+}
+
+static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
+{
+ DSI(_DSIREG(DSI_WR_DATA)) = (param << 8) | cmd;
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+
+ if (wait)
+ usleep(wait);
+}
+
+static void _display_dsi_wait_vblank(bool enable)
+{
+ if (enable)
+ {
+ // Enable vblank interrupt.
+ display_enable_interrupt(DC_CMD_INT_FRAME_END_INT);
+
+ // Use the 4th line to transmit the host cmd packet.
+ DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
+
+ // Wait for vblank before starting the transfer.
+ display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
+ }
+ else
+ {
+ // Wait for vblank before resetting sync points.
+ display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
+ usleep(14);
+
+ // Reset all states of syncpt block.
+ DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
+ usleep(300); // Stabilization delay.
+
+ // Clear syncpt block reset.
+ DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
+ usleep(300); // Stabilization delay.
+
+ // Restore video mode and host control.
+ DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
+
+ // Disable and clear vblank interrupt.
+ display_disable_interrupt(DC_CMD_INT_FRAME_END_INT);
+ }
+}
+
+static void _display_dsi_read_rx_fifo(u32 *data)
+{
+ u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
+ if (fifo_count)
+ DSI(_DSIREG(DSI_TRIGGER)) = 0;
+
+ for (u32 i = 0; i < fifo_count; i++)
+ {
+ // Read or Drain RX FIFO.
+ if (data)
+ data[i] = DSI(_DSIREG(DSI_RD_DATA));
+ else
+ (void)DSI(_DSIREG(DSI_RD_DATA));
+ }
+}
+
+int display_dsi_read(u8 cmd, u32 len, void *data)
+{
+ int res = 0;
+ u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
+
+ // Drain RX FIFO.
+ _display_dsi_read_rx_fifo(NULL);
+
+ // Set reply size.
+ _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
+ _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
+
+ // Request register read.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
+ _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
+
+ // Transfer bus control to device for transmitting the reply.
+ DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_IMM_BTA;
+
+ // Wait for reply to complete. DSI_HOST_CONTROL_IMM_BTA bit acts as a DSI host read busy.
+ _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
+
+ // Wait a bit for the reply.
+ usleep(5000);
+
+ // Read RX FIFO.
+ _display_dsi_read_rx_fifo(fifo);
+
+ // Parse packet and copy over the data.
+ if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
+ {
+ // Act based on reply type.
+ switch (fifo[1] & 0xFF)
+ {
+ case GEN_LONG_RD_RES:
+ case DCS_LONG_RD_RES:
+ memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
+ break;
+
+ case GEN_1_BYTE_SHORT_RD_RES:
+ case DCS_1_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 1);
+ break;
+
+ case GEN_2_BYTE_SHORT_RD_RES:
+ case DCS_2_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 2);
+ break;
+
+ case ACK_ERROR_RES:
+ default:
+ res = 1;
+ break;
+ }
+ }
+ else
+ res = 1;
+
+ return res;
+}
+
+int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
+{
+ int res = 0;
+ u32 host_control = 0;
+ u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
+
+ // Drain RX FIFO.
+ _display_dsi_read_rx_fifo(NULL);
+
+ // Save host control and enable host cmd packets during video.
+ host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
+
+ _display_dsi_wait_vblank(true);
+
+ // Set reply size.
+ _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
+ _display_dsi_wait(0, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
+
+ // Request register read.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
+ _display_dsi_wait(0, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
+
+ _display_dsi_wait_vblank(false);
+
+ // Transfer bus control to device for transmitting the reply.
+ DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_IMM_BTA;
+
+ // Wait for reply to complete. DSI_HOST_CONTROL_IMM_BTA bit acts as a DSI host read busy.
+ _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
+
+ // Wait a bit for the reply.
+ usleep(5000);
+
+ // Read RX FIFO.
+ _display_dsi_read_rx_fifo(fifo);
+
+ // Parse packet and copy over the data.
+ if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
+ {
+ // Act based on reply type.
+ switch (fifo[1] & 0xFF)
+ {
+ case GEN_LONG_RD_RES:
+ case DCS_LONG_RD_RES:
+ memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
+ break;
+
+ case GEN_1_BYTE_SHORT_RD_RES:
+ case DCS_1_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 1);
+ break;
+
+ case GEN_2_BYTE_SHORT_RD_RES:
+ case DCS_2_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 2);
+ break;
+
+ case ACK_ERROR_RES:
+ default:
+ res = 1;
+ break;
+ }
+ }
+ else
+ res = 1;
+
+ // Restore host control.
+ DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
+
+ return res;
+}
+
+void display_dsi_write(u8 cmd, u32 len, void *data)
+{
+ u32 host_control;
+ u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
+ u8 *fifo8 = (u8 *)fifo32;
+
+ // Prepare data for long write.
+ if (len >= 2)
+ {
+ memcpy(&fifo8[5], data, len);
+ memset(&fifo8[5] + len, 0, len % sizeof(u32));
+ len++; // Increase length by CMD.
+ }
+
+ // Save host control.
+ host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
+
+ // Enable host transfer trigger.
+ DSI(_DSIREG(DSI_HOST_CONTROL)) = (host_control & ~(DSI_HOST_CONTROL_TX_TRIG_MASK)) | DSI_HOST_CONTROL_TX_TRIG_HOST;
+
+ switch (len)
+ {
+ case 0:
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
+ break;
+
+ case 1:
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
+ break;
+
+ default:
+ fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
+ fifo8[4] = cmd;
+ len += sizeof(u32); // Increase length by length word and DCS CMD.
+ for (u32 i = 0; i < (ALIGN(len, sizeof(u32)) / sizeof(u32)); i++)
+ DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ break;
+ }
+
+ // Wait for the write to happen.
+ _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST);
+
+ // Restore host control.
+ DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
+}
+
+void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
+{
+ u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
+ u8 *fifo8 = (u8 *)fifo32;
+
+ // Prepare data for long write.
+ if (len >= 2)
+ {
+ memcpy(&fifo8[5], data, len);
+ memset(&fifo8[5] + len, 0, len % sizeof(u32));
+ len++; // Increase length by CMD.
+ }
+
+ _display_dsi_wait_vblank(true);
+
+ switch (len)
+ {
+ case 0:
+ DSI(_DSIREG(DSI_WR_DATA)) = (cmd << 8) | MIPI_DSI_DCS_SHORT_WRITE;
+ break;
+
+ case 1:
+ DSI(_DSIREG(DSI_WR_DATA)) = ((cmd | (*(u8 *)data << 8)) << 8) | MIPI_DSI_DCS_SHORT_WRITE_PARAM;
+ break;
+
+ default:
+ fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
+ fifo8[4] = cmd;
+ len += sizeof(u32); // Increase length by length word and DCS CMD.
+ for (u32 i = 0; i < (ALIGN(len, sizeof(u32)) / sizeof(u32)); i++)
+ DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
+ break;
+ }
+
+ _display_dsi_wait_vblank(false);
+}
+
+void display_init()
+{
+ // Get Hardware type, as it's used in various DI functions.
+ _nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA;
+
+ // Check if display is already initialized.
+ if (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_DISP1))
+ _display_panel_and_hw_end(true);
+
+ // Get Chip ID.
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+
+ // Enable DSI AVDD.
+ max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
+ max7762x_regulator_enable(REGULATOR_LDO0, true);
+
+ // Enable Display Interface specific clocks.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_DISP1);
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1);
+
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = CLK_SRC_DIV(6); // Set PLLP_OUT3 and div 6 (68MHz).
+
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
+
+ // Bring every IO rail out of deep power down.
+ PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
+ PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
+
+ // Configure LCD/BL pins.
+ if (!_nx_aula)
+ {
+ // Configure LCD pins.
+ PINMUX_AUX(PINMUX_AUX_NFC_EN) = PINMUX_PULL_DOWN;
+ PINMUX_AUX(PINMUX_AUX_NFC_INT) = PINMUX_PULL_DOWN;
+
+ // Configure Backlight pins.
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_PULL_DOWN;
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) = PINMUX_PULL_DOWN;
+
+ // Enable LCD AVDD.
+ gpio_direction_output(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_HIGH);
+ usleep(10000); // Wait minimum 4.2ms to stabilize.
+
+ // Configure Backlight PWM/EN pins (BL PWM, BL EN).
+ gpio_direction_output(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1, GPIO_LOW);
+
+ // Enable Backlight power.
+ gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
+ }
+
+ // Configure LCD RST pin.
+ PINMUX_AUX(PINMUX_AUX_LCD_RST) = PINMUX_PULL_DOWN;
+ gpio_direction_output(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW);
+
+ // Power up supply regulator for display interface.
+ MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
+
+ if (!tegra_t210)
+ {
+ MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
+ APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
+ }
+
+ // Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
+ // T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
+ // T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
+ clock_enable_plld(3, 20, true, tegra_t210);
+
+ // Setup Display Interface initial window configuration.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, ARRAY_SIZE(_di_dc_setup_win_config));
+
+ // Setup dsi init sequence packets.
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_reset_config0, ARRAY_SIZE(_di_dsi_seq_pkt_reset_config0));
+ DSI(_DSIREG(tegra_t210 ? DSI_INIT_SEQ_DATA_15 : DSI_INIT_SEQ_DATA_15_B01)) = 0;
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_reset_config1, ARRAY_SIZE(_di_dsi_seq_pkt_reset_config1));
+
+ // Reset pad trimmers for T210B01.
+ if (!tegra_t210)
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, ARRAY_SIZE(_di_dsi_init_pads_t210b01));
+
+ // Setup init seq packet lengths, timings and power on DSI.
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_init_config, ARRAY_SIZE(_di_dsi_init_config));
+ usleep(10000);
+
+ // Enable LCD Reset.
+ gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
+ usleep(60000);
+
+ // Setup DSI device takeover timeout.
+ DSI(_DSIREG(DSI_BTA_TIMING)) = _nx_aula ? 0x40103 : 0x50204;
+
+ // Get Display ID.
+ _display_id = 0xCCCCCC;
+ for (u32 i = 0; i < 3; i++)
+ {
+ if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id))
+ break;
+
+ usleep(10000);
+ }
+
+ // Save raw Display ID to Nyx storage.
+ nyx_str->info.disp_id = _display_id;
+
+ // Decode Display ID.
+ _display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
+
+ if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
+ _display_id = PANEL_JDI_XXX062M;
+
+ // For Aula ensure that we have a compatible panel id.
+ if (_nx_aula && _display_id == 0xCCCC)
+ _display_id = PANEL_SAM_AMS699VC01;
+
+ // Initialize display panel.
+ switch (_display_id)
+ {
+ case PANEL_SAM_AMS699VC01:
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
+ // Set color mode to basic (natural). Stock is Saturated (0x00). (Reset value is 0x20).
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+ MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_BASIC << 8), 0);
+ // Enable backlight and smooth PWM.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+ MIPI_DCS_SET_CONTROL_DISPLAY | ((DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL) << 8), 0);
+
+ // Unlock Level 2 registers.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x539; // MIPI_DSI_DCS_LONG_WRITE: 5 bytes.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x5A5A5AE2; // MIPI_DCS_PRIV_SM_SET_REGS_LOCK: Unlock Level 2 registers.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x5A;
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+
+ // Set registers offset and set PWM transition to 6 frames (100ms).
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_PRIV_SM_SET_REG_OFFSET | (7 << 8), 0);
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_PRIV_SM_SET_ELVSS | (6 << 8), 0);
+
+ // Relock Level 2 registers.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x539; // MIPI_DSI_DCS_LONG_WRITE: 5 bytes.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0xA55A5AE2; // MIPI_DCS_PRIV_SM_SET_REGS_LOCK: Lock Level 2 registers.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0xA5;
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+
+ // Set backlight to 0%.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x339; // MIPI_DSI_DCS_LONG_WRITE: 3 bytes.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x000051; // MIPI_DCS_SET_BRIGHTNESS 0000: 0%. FF07: 100%.
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ usleep(5000);
+ _dsi_bl = 0;
+ break;
+
+ case PANEL_JDI_XXX062M:
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, ARRAY_SIZE(_di_dsi_panel_init_config_jdi));
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
+ break;
+
+ case PANEL_INL_P062CCA_AZ1:
+ case PANEL_AUO_A062TAN01:
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
+
+ // Unlock extension cmds.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ usleep(5000);
+
+ // Set Power control.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
+ if (_display_id == PANEL_INL_P062CCA_AZ1)
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
+ else // PANEL_AUO_A062TAN01.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ usleep(5000);
+ break;
+
+ case PANEL_INL_2J055IA_27A:
+ case PANEL_AUO_A055TAN01:
+ case PANEL_SHP_LQ055T1SW10:
+ default: // Allow spare part displays to work.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
+ break;
+ }
+
+ // Unblank display.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
+
+ // Setup final dsi clock.
+ // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI): 234.0 MHz.
+ clock_enable_plld(1, 24, false, tegra_t210);
+
+ // Finalize DSI init packet sequence configuration.
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_video_non_burst_no_eot_config, ARRAY_SIZE(_di_dsi_seq_pkt_video_non_burst_no_eot_config));
+
+ // Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate.
+ DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
+
+ // Set DSI mode to HOST.
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_host_mode_config, ARRAY_SIZE(_di_dsi_host_mode_config));
+ usleep(10000);
+
+ /*
+ * Calibrate display communication pads.
+ * When switching to the 16ff pad brick, the clock lane termination control
+ * is separated from data lane termination. This change of the mipi cal
+ * brings in a bug that the DSI pad clock termination code can't be loaded
+ * in one time calibration on T210B01. Trigger calibration twice.
+ */
+ reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, ARRAY_SIZE(_di_mipi_pad_cal_config));
+ for (u32 i = 0; i < 2; i++)
+ {
+ // Set MIPI bias pad config.
+ MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
+ MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
+
+ // Set pad trimmers and set MIPI DSI cal offsets.
+ if (tegra_t210)
+ {
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, ARRAY_SIZE(_di_dsi_pad_cal_config_t210));
+ reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210));
+ }
+ else
+ {
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, ARRAY_SIZE(_di_dsi_pad_cal_config_t210b01));
+ reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210b01, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210b01));
+ }
+
+ // Reset all unused MIPI cal offsets.
+ reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_unused_config, ARRAY_SIZE(_di_mipi_dsi_cal_unused_config));
+
+ // Set Prescale/filter and start calibration.
+ MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_CAL_CTRL)) = 0x2A000001;
+ }
+ usleep(10000);
+
+ // Enable video display controller.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, ARRAY_SIZE(_di_dc_video_enable_config));
+}
+
+void display_backlight_pwm_init()
+{
+ if (_display_id == PANEL_SAM_AMS699VC01)
+ return;
+
+ // Enable PWM clock.
+ clock_enable_pwm();
+
+ // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
+ PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN;
+
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
+ usleep(2);
+
+ gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
+}
+
+void display_backlight(bool enable)
+{
+ // Backlight PWM GPIO.
+ gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW);
+}
+
+static void _display_dsi_backlight_brightness(u32 duty)
+{
+ if (_dsi_bl == duty)
+ return;
+
+ // Convert duty to candela.
+ u32 candela = duty * PANEL_SM_BL_CANDELA_MAX / 255;
+
+ u16 bl_ctrl = byte_swap_16((u16)candela);
+ display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
+
+ // Wait for backlight to completely turn off. 6 frames.
+ if (!duty)
+ usleep(100000);
+
+ _dsi_bl = duty;
+}
+
+static void _display_pwm_backlight_brightness(u32 duty, u32 step_delay)
+{
+ u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
+ if (duty == old_value)
+ return;
+
+ if (old_value < duty)
+ {
+ for (u32 i = old_value; i < duty + 1; i++)
+ {
+ PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
+ usleep(step_delay);
+ }
+ }
+ else
+ {
+ for (u32 i = old_value; i > duty; i--)
+ {
+ PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
+ usleep(step_delay);
+ }
+ }
+ if (!duty)
+ PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
+}
+
+void display_backlight_brightness(u32 brightness, u32 step_delay)
+{
+ if (brightness > 255)
+ brightness = 255;
+
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ _display_pwm_backlight_brightness(brightness, step_delay);
+ else
+ _display_dsi_backlight_brightness(brightness);
+}
+
+u32 display_get_backlight_brightness()
+{
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
+ else
+ return _dsi_bl;
+}
+
+static void _display_panel_and_hw_end(bool no_panel_deinit)
+{
+ if (no_panel_deinit)
+ goto skip_panel_deinit;
+
+ display_backlight_brightness(0, 1000);
+
+ // Enable host cmd packets during video.
+ DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
+
+ // Blank display.
+ DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
+
+ // Wait for 5 frames (HOST1X_CH0_SYNC_SYNCPT_9).
+ // Not here. Wait for 1 frame manually.
+ usleep(20000);
+
+ // Propagate changes to all register buffers and disable host cmd packets during video.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX_ACTIVE | WRITE_MUX_ACTIVE;
+ DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
+
+ // De-initialize video controller.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, ARRAY_SIZE(_di_dc_video_disable_config));
+
+ // Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
+ // T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
+ // T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
+ clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210);
+
+ // Set timings for lowpower clocks.
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, ARRAY_SIZE(_di_dsi_timing_deinit_config));
+
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ usleep(10000);
+
+ // De-initialize display panel.
+ switch (_display_id)
+ {
+ case PANEL_JDI_XXX062M:
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, ARRAY_SIZE(_di_dsi_panel_deinit_config_jdi));
+ break;
+
+ case PANEL_AUO_A062TAN01:
+ reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, ARRAY_SIZE(_di_dsi_panel_deinit_config_auo));
+ usleep(5000);
+ break;
+
+ case PANEL_INL_2J055IA_27A:
+ case PANEL_AUO_A055TAN01:
+ case PANEL_SHP_LQ055T1SW10:
+ // Unlock extension cmds.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ usleep(5000);
+
+ // Set Power control.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
+ if (_display_id == PANEL_INL_2J055IA_27A)
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
+ else if (_display_id == PANEL_AUO_A055TAN01)
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
+ else // PANEL_SHP_LQ055T1SW10.
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40).
+ if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01)
+ {
+ // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
+ }
+ else // PANEL_SHP_LQ055T1SW10.
+ {
+ // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG).
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209;
+ DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
+ }
+ DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
+ usleep(5000);
+ break;
+
+ case PANEL_INL_P062CCA_AZ1:
+ case PANEL_SAM_AMS699VC01:
+ default:
+ break;
+ }
+
+ // Blank - powerdown.
+ _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE,
+ (_display_id == PANEL_SAM_AMS699VC01) ? 120000 : 50000);
+
+skip_panel_deinit:
+ // Disable LCD power pins.
+ gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
+ usleep(10000);
+
+ if (!_nx_aula) // HOS uses panel id.
+ {
+ gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD AVDD -5.4V disable.
+ gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD AVDD +5.4V disable.
+
+ // Make sure LCD PWM backlight pin is in PWM0 mode.
+ gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode.
+ }
+ usleep(10000);
+
+ // Disable Display Interface specific clocks.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_DISP1);
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_DISP1);
+
+ // Power down pads.
+ DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) |
+ DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
+ DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
+
+ // Disable DSI AVDD.
+ max7762x_regulator_enable(REGULATOR_LDO0, false);
+}
+
+void display_end() { _display_panel_and_hw_end(false); };
+
+u16 display_get_decoded_panel_id()
+{
+ return _display_id;
+}
+
+void display_set_decoded_panel_id(u32 id)
+{
+ // Get Hardware type, as it's used in various DI functions.
+ _nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA;
+
+ // Decode Display ID.
+ _display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
+
+ if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
+ _display_id = PANEL_JDI_XXX062M;
+
+ // For Aula ensure that we have a compatible panel id.
+ if (_nx_aula && _display_id == 0xCCCC)
+ _display_id = PANEL_SAM_AMS699VC01;
+}
+
+void display_color_screen(u32 color)
+{
+ // Disable all windows.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_win_one_color, ARRAY_SIZE(_di_win_one_color));
+
+ // Configure display to show single color.
+ DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ;
+ usleep(35000); // Wait 2 frames. No need on Aula.
+
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ display_backlight(true);
+ else
+ display_backlight_brightness(150, 0);
+}
+
+u32 *display_init_window_a_pitch()
+{
+ // Sanitize framebuffer area.
+ memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ);
+
+ // This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch, ARRAY_SIZE(_di_winA_pitch));
+ //usleep(35000); // Wait 2 frames. No need on Aula.
+
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+}
+
+u32 *display_init_window_a_pitch_vic()
+{
+ // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ usleep(8000); // Wait half frame for PWM to apply.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_vic, ARRAY_SIZE(_di_winA_pitch_vic));
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ usleep(35000); // Wait 2 frames.
+
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+}
+
+u32 *display_init_window_a_pitch_inv()
+{
+ // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_inv, ARRAY_SIZE(_di_winA_pitch_inv));
+ usleep(35000); // Wait 2 frames. No need on Aula.
+
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+}
+
+u32 *display_init_window_a_block()
+{
+ // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280.
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_block, ARRAY_SIZE(_di_winA_block));
+ usleep(35000); // Wait 2 frames. No need on Aula.
+
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+}
+
+u32 *display_init_window_d_console()
+{
+ // This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winD_log, ARRAY_SIZE(_di_winD_log));
+
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+}
+
+void display_window_disable(u32 window)
+{
+ // Select window C.
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
+
+ // Disable window C.
+ DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
+}
+
+void display_set_framebuffer(u32 window, void *fb)
+{
+ // Select window.
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
+
+ // Set new fb address.
+ DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
+}
+
+void display_move_framebuffer(u32 window, void *fb)
+{
+ // Select window.
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
+
+ // Get current framebuffer address.
+ const void *fb_curr = (void *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
+ u32 win_size = DISPLAY_A(_DIREG(DC_WIN_PRESCALED_SIZE));
+ win_size = (win_size & 0x7FFF) * ((win_size >> 16) & 0x1FFF);
+
+ // Copy fb over.
+ memcpy(fb, fb_curr, win_size);
+
+ // Set new fb address.
+ DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
+}
+
+void display_window_d_console_enable()
+{
+ // Only update active registers on vsync.
+ DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) & ~WIN_D_ACT_HCNTR_SEL;
+
+ // Select window D.
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
+
+ // Enable and setup window D.
+ DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE;
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80; // X: -128.
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+
+ // Pull-down effect.
+ for (u32 i = 0xFF80; i < 0x10000; i++)
+ {
+ // Set window position.
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+ usleep(1000);
+ }
+
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+}
+
+void display_window_d_console_disable()
+{
+ // Select window D.
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
+
+ // Pull-up effect.
+ for (u32 i = 0xFFFF; i > 0xFF7F; i--)
+ {
+ // Set window position.
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+ usleep(500);
+ }
+
+ // Disable window D.
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
+ DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+}
+
+void display_cursor_init(void *crs_fb, u32 size)
+{
+ // Setup cursor.
+ DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
+ DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = CURSOR_BLEND_R8G8B8A8 |
+ CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) |
+ CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
+
+ // Enable cursor window.
+ DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
+
+void display_cursor_set_pos(u32 x, u32 y)
+{
+ // Set cursor position.
+ DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
+
+void display_cursor_deinit()
+{
+ DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
+ DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
+
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
diff --git a/bdk/gfx/di.h b/bdk/display/di.h
similarity index 65%
rename from bdk/gfx/di.h
rename to bdk/display/di.h
index a6d34a6..9a35d4f 100644
--- a/bdk/gfx/di.h
+++ b/bdk/display/di.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 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,6 +24,11 @@
#define DSI_VIDEO_DISABLED 0
#define DSI_VIDEO_ENABLED 1
+#define WINDOW_A 0
+#define WINDOW_B 1
+#define WINDOW_C 2
+#define WINDOW_D 3
+
/*! Display registers. */
#define _DIREG(reg) ((reg) * 4)
@@ -43,13 +48,17 @@
// DC_CMD non-shadowed command/sync registers.
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
+#define SYNCPT_GENERAL_INDX(x) (((x) & 0xFF) << 0)
+#define SYNCPT_GENERAL_COND(x) (((x) & 0xFF) << 8)
+#define COND_REG_WR_SAFE 3
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
#define SYNCPT_CNTRL_SOFT_RESET BIT(0)
#define SYNCPT_CNTRL_NO_STALL BIT(8)
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
-#define SYNCPT_VSYNC_ENABLE BIT(8)
+#define SYNCPT_VSYNC_INDX(x) (((x) & 0xFF) << 0)
+#define SYNCPT_VSYNC_ENABLE BIT(8)
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
@@ -72,19 +81,25 @@
#define DC_CMD_INT_MASK 0x38
#define DC_CMD_INT_ENABLE 0x39
#define DC_CMD_INT_FRAME_END_INT BIT(1)
+#define DC_CMD_INT_V_BLANK_INT BIT(2)
+#define DC_CMD_INT_POLARITY 0x3B
#define DC_CMD_STATE_ACCESS 0x40
-#define READ_MUX BIT(0)
-#define WRITE_MUX BIT(2)
+#define READ_MUX_ASSEMBLY 0x0
+#define WRITE_MUX_ASSEMBLY 0x0
+#define READ_MUX_ACTIVE BIT(0)
+#define WRITE_MUX_ACTIVE BIT(2)
#define DC_CMD_STATE_CONTROL 0x41
#define GENERAL_ACT_REQ BIT(0)
+#define WIN_ACT_REQ 1
#define WIN_A_ACT_REQ BIT(1)
#define WIN_B_ACT_REQ BIT(2)
#define WIN_C_ACT_REQ BIT(3)
#define WIN_D_ACT_REQ BIT(4)
#define CURSOR_ACT_REQ BIT(7)
#define GENERAL_UPDATE BIT(8)
+#define WIN_UPDATE 9
#define WIN_A_UPDATE BIT(9)
#define WIN_B_UPDATE BIT(10)
#define WIN_C_UPDATE BIT(11)
@@ -93,12 +108,19 @@
#define NC_HOST_TRIG BIT(24)
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
+#define WINDOW_SELECT 4
#define WINDOW_A_SELECT BIT(4)
#define WINDOW_B_SELECT BIT(5)
#define WINDOW_C_SELECT BIT(6)
#define WINDOW_D_SELECT BIT(7)
-#define DC_CMD_REG_ACT_CONTROL 0x043
+#define DC_CMD_REG_ACT_CONTROL 0x43
+#define GENERAL_ACT_HCNTR_SEL BIT(0)
+#define WIN_A_ACT_HCNTR_SEL BIT(2)
+#define WIN_B_ACT_HCNTR_SEL BIT(4)
+#define WIN_C_ACT_HCNTR_SEL BIT(6)
+#define CURSOR_ACT_HCNTR_SEL BIT(7)
+#define WIN_D_ACT_HCNTR_SEL BIT(10)
// DC_D_WIN_DD window D instance of DC_WIN
#define DC_D_WIN_DD_WIN_OPTIONS 0x80
@@ -124,6 +146,32 @@
#define DC_COM_CRC_CONTROL 0x300
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
+#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
+
+// CMU registers.
+#define DC_COM_CMU_CSC_KRR 0x32A
+#define DC_COM_CMU_CSC_KGR 0x32B
+#define DC_COM_CMU_CSC_KBR 0x32C
+#define DC_COM_CMU_CSC_KRG 0x32D
+#define DC_COM_CMU_CSC_KGG 0x32E
+#define DC_COM_CMU_CSC_KBG 0x32F
+#define DC_COM_CMU_CSC_KRB 0x330
+#define DC_COM_CMU_CSC_KGB 0x331
+#define DC_COM_CMU_CSC_KBB 0x332
+#define DC_COM_CMU_LUT1 0x336
+#define LUT1_ADDR(x) ((x) & 0xFF)
+#define LUT1_DATA(x) (((x) & 0xFFF) << 16)
+#define LUT1_READ_DATA(x) (((x) >> 16) & 0xFFF)
+#define DC_COM_CMU_LUT2 0x337
+#define LUT2_ADDR(x) ((x) & 0x3FF)
+#define LUT2_DATA(x) (((x) & 0xFF) << 16)
+#define LUT2_READ_DATA(x) (((x) >> 16) & 0xFF)
+#define DC_COM_CMU_LUT1_READ 0x338
+#define LUT1_READ_ADDR(x) (((x) & 0xFF) << 8)
+#define LUT1_READ_EN BIT(0)
+#define DC_COM_CMU_LUT2_READ 0x339
+#define LUT2_READ_ADDR(x) (((x) & 0x3FF) << 8)
+#define LUT2_READ_EN BIT(0)
#define DC_COM_DSC_TOP_CTL 0x33E
@@ -139,15 +187,32 @@
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
+
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
+#define VSYNC_H_POSITION(x) (((x) & 0x1FFF) << 0)
+
#define DC_DISP_REF_TO_SYNC 0x406
+#define H_REF_TO_SYNC(x) (((x) & 0x1FFF) << 0) // Min 0 pixel clock.
+#define V_REF_TO_SYNC(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
+
#define DC_DISP_SYNC_WIDTH 0x407
+#define H_SYNC_WIDTH(x) (((x) & 0x1FFF) << 0) // Min 1 pixel clock.
+#define V_SYNC_WIDTH(x) (((x) & 0x1FFF) << 16) // Min 1 line clock.
+
#define DC_DISP_BACK_PORCH 0x408
+#define H_BACK_PORCH(x) (((x) & 0x1FFF) << 0)
+#define V_BACK_PORCH(x) (((x) & 0x1FFF) << 16)
+
#define DC_DISP_ACTIVE 0x409
+#define H_DISP_ACTIVE(x) (((x) & 0x1FFF) << 0) // Min 16 pixel clock.
+#define V_DISP_ACTIVE(x) (((x) & 0x1FFF) << 16) // Min 16 line clock.
+
#define DC_DISP_FRONT_PORCH 0x40A
+#define H_FRONT_PORCH(x) (((x) & 0x1FFF) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1
+#define V_FRONT_PORCH(x) (((x) & 0x1FFF) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
-#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
+#define SHIFT_CLK_DIVIDER(x) ((x) & 0xFF)
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
@@ -178,11 +243,7 @@
#define DISP_ORDER_BLUE_RED (1 << 9)
#define DC_DISP_DISP_COLOR_CONTROL 0x430
-#define DITHER_CONTROL_MASK (3 << 8)
-#define DITHER_CONTROL_DISABLE (0 << 8)
-#define DITHER_CONTROL_ORDERED (2 << 8)
-#define DITHER_CONTROL_ERRDIFF (3 << 8)
-#define BASE_COLOR_SIZE_MASK (0xf << 0)
+#define BASE_COLOR_SIZE_MASK (0xF << 0)
#define BASE_COLOR_SIZE_666 (0 << 0)
#define BASE_COLOR_SIZE_111 (1 << 0)
#define BASE_COLOR_SIZE_222 (2 << 0)
@@ -192,6 +253,13 @@
#define BASE_COLOR_SIZE_565 (6 << 0)
#define BASE_COLOR_SIZE_332 (7 << 0)
#define BASE_COLOR_SIZE_888 (8 << 0)
+#define DITHER_CONTROL_MASK (3 << 8)
+#define DITHER_CONTROL_DISABLE (0 << 8)
+#define DITHER_CONTROL_ORDERED (2 << 8)
+#define DITHER_CONTROL_ERRDIFF (3 << 8)
+#define DISP_COLOR_SWAP BIT(16)
+#define BLANK_COLOR_WHITE BIT(17)
+#define CMU_ENABLE BIT(20)
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
#define SC0_H_QUALIFIER_NONE BIT(0)
@@ -213,6 +281,7 @@
#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 CURSOR_CLIPPING(w) ((w) << 28)
#define CURSOR_CLIP_WIN_A 1
#define CURSOR_CLIP_WIN_B 2
@@ -224,6 +293,7 @@
#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_START_ADDR_HI_NS 0x4ED
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
#define CURSOR_BLEND_2BIT (0 << 24)
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
@@ -239,32 +309,44 @@
#define DC_DISP_SD_BL_CONTROL 0x4DC
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
-#define DC_WIN_CSC_YOF 0x611
-#define DC_WIN_CSC_KYRGB 0x612
-#define DC_WIN_CSC_KUR 0x613
-#define DC_WIN_CSC_KVR 0x614
-#define DC_WIN_CSC_KUG 0x615
-#define DC_WIN_CSC_KVG 0x616
-#define DC_WIN_CSC_KUB 0x617
-#define DC_WIN_CSC_KVB 0x618
+#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)
+#define DC_WINC_PALETTE_COLOR_EXT 0x600
+
+#define DC_WINC_H_FILTER_P(p) (0x601 + (p))
+#define DC_WINC_V_FILTER_P(p) (0x619 + (p))
+#define DC_WINC_H_FILTER_HI_P(p) (0x629 + (p))
+
+#define DC_WINC_CSC_YOF 0x611
+#define DC_WINC_CSC_KYRGB 0x612
+#define DC_WINC_CSC_KUR 0x613
+#define DC_WINC_CSC_KVR 0x614
+#define DC_WINC_CSC_KUG 0x615
+#define DC_WINC_CSC_KVG 0x616
+#define DC_WINC_CSC_KUB 0x617
+#define DC_WINC_CSC_KVB 0x618
#define DC_WIN_AD_WIN_OPTIONS 0xB80
#define DC_WIN_BD_WIN_OPTIONS 0xD80
#define DC_WIN_CD_WIN_OPTIONS 0xF80
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
#define DC_WIN_WIN_OPTIONS 0x700
-#define H_DIRECTION BIT(0)
-#define V_DIRECTION BIT(2)
-#define SCAN_COLUMN BIT(4)
-#define COLOR_EXPAND BIT(6)
-#define CSC_ENABLE BIT(18)
-#define WIN_ENABLE BIT(30)
+#define H_DIRECTION BIT(0)
+#define V_DIRECTION BIT(2)
+#define SCAN_COLUMN BIT(4)
+#define COLOR_EXPAND BIT(6)
+#define H_FILTER_ENABLE BIT(8)
+#define V_FILTER_ENABLE BIT(10)
+#define COLOR_PALETTE_ENABLE BIT(16)
+#define CSC_ENABLE BIT(18)
+#define DV_ENABLE BIT(20)
+#define WIN_ENABLE BIT(30)
+#define H_FILTER_EXPAND BIT(31)
#define DC_WIN_BUFFER_CONTROL 0x702
#define BUFFER_CONTROL_HOST 0
#define BUFFER_CONTROL_VI 1
-#define BUFFER_CONTROL_EPP 2
-#define BUFFER_CONTROL_MPEGE 3
#define BUFFER_CONTROL_SB2D 4
#define DC_WIN_COLOR_DEPTH 0x703
@@ -290,34 +372,55 @@
#define WIN_COLOR_DEPTH_YUV422R 0x17
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
#define WIN_COLOR_DEPTH_YUV422RA 0x19
+#define WIN_COLOR_DEPTH_X1R5G5B5 0x1E
+#define WIN_COLOR_DEPTH_R5G5B5X1 0x1F
+#define WIN_COLOR_DEPTH_X1B5G5R5 0x20
+#define WIN_COLOR_DEPTH_B5G5R5X1 0x21
+#define WIN_COLOR_DEPTH_YCbCr444P 0x29
+#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A
+#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B
+#define WIN_COLOR_DEPTH_YCrCb422SP 0x2C
+#define WIN_COLOR_DEPTH_YCbCr422SP 0x2D
+#define WIN_COLOR_DEPTH_YUV444P 0x34
+#define WIN_COLOR_DEPTH_YVU420SP 0x35
+#define WIN_COLOR_DEPTH_YUV420SP 0x36
+#define WIN_COLOR_DEPTH_YVU422SP 0x37
+#define WIN_COLOR_DEPTH_YUV422SP 0x38
+#define WIN_COLOR_DEPTH_YVU444SP 0x3B
+#define WIN_COLOR_DEPTH_YUV444SP 0x3C
#define DC_WIN_POSITION 0x704
-#define H_POSITION(x) (((x) & 0xFfff) << 0)
-#define V_POSITION(x) (((x) & 0x1fff) << 16)
+#define H_POSITION(x) (((x) & 0xFFFF) << 0) // Support negative.
+#define V_POSITION(x) (((x) & 0xFFFF) << 16) // Support negative.
#define DC_WIN_SIZE 0x705
-#define H_SIZE(x) (((x) & 0x1fff) << 0)
-#define V_SIZE(x) (((x) & 0x1fff) << 16)
+#define H_SIZE(x) (((x) & 0x1FFF) << 0)
+#define V_SIZE(x) (((x) & 0x1FFF) << 16)
#define DC_WIN_PRESCALED_SIZE 0x706
-#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
-#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
+#define H_PRESCALED_SIZE(x) (((x) & 0x7FFF) << 0)
+#define V_PRESCALED_SIZE(x) (((x) & 0x1FFF) << 16)
#define DC_WIN_H_INITIAL_DDA 0x707
#define DC_WIN_V_INITIAL_DDA 0x708
#define DC_WIN_DDA_INC 0x709
-#define H_DDA_INC(x) (((x) & 0xffff) << 0)
-#define V_DDA_INC(x) (((x) & 0xffff) << 16)
+#define H_DDA_INC(x) (((x) & 0xFFFF) << 0)
+#define V_DDA_INC(x) (((x) & 0xFFFF) << 16)
#define DC_WIN_LINE_STRIDE 0x70A
#define LINE_STRIDE(x) (x)
-#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
+#define UV_LINE_STRIDE(x) (((x) & 0xFFFF) << 16)
+
#define DC_WIN_DV_CONTROL 0x70E
+#define DV_CTRL_R(r) (((r) & 7) << 16)
+#define DV_CTRL_G(g) (((g) & 7) << 8)
+#define DV_CTRL_B(b) (((b) & 7) << 0)
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
-#define WIN_K1(x) (((x) & 0xff) << 8)
-#define WIN_K2(x) (((x) & 0xff) << 16)
+#define WIN_BLEND_DEPTH(x) (((x) & 0xFF) << 0)
+#define WIN_K1(x) (((x) & 0xFF) << 8)
+#define WIN_K2(x) (((x) & 0xFF) << 16)
#define WIN_BLEND_ENABLE (0 << 24)
#define WIN_BLEND_BYPASS (1 << 24)
@@ -348,8 +451,8 @@
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_K2 (3 << 12)
#define DC_WINBUF_BLEND_ALPHA_1BIT 0x719
-#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xff) << 0)
-#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xff) << 8)
+#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xFF) << 0)
+#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xFF) << 8)
/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
#define DC_WINBUF_START_ADDR 0x800
@@ -361,6 +464,8 @@
#define BLOCK (2 << 0)
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
+#define DC_WINBUF_MEMFETCH_CONTROL 0x82B
+
/*! Display serial interface registers. */
#define _DSIREG(reg) ((reg) * 4)
@@ -386,6 +491,7 @@
#define DSI_HOST_CONTROL_FIFO_SEL BIT(4)
#define DSI_HOST_CONTROL_HS BIT(5)
#define DSI_HOST_CONTROL_RAW BIT(6)
+#define DSI_HOST_CONTROL_TX_TRIG_MASK (3 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
@@ -414,6 +520,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
@@ -433,30 +540,34 @@
#define DSI_PKT_SEQ_5_LO 0x2D
#define DSI_PKT_SEQ_5_HI 0x2E
#define DSI_DCS_CMDS 0x33
+
#define DSI_PKT_LEN_0_1 0x34
#define DSI_PKT_LEN_2_3 0x35
#define DSI_PKT_LEN_4_5 0x36
#define DSI_PKT_LEN_6_7 0x37
+#define PKT0_LEN(x) (((x) & 0xFFFF) << 0)
+#define PKT1_LEN(x) (((x) & 0xFFFF) << 16)
+
#define DSI_PHY_TIMING_0 0x3C
#define DSI_PHY_TIMING_1 0x3D
#define DSI_PHY_TIMING_2 0x3E
#define DSI_BTA_TIMING 0x3F
#define DSI_TIMEOUT_0 0x44
-#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
-#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
+#define DSI_TIMEOUT_HTX(x) (((x) & 0xFFFF) << 0)
+#define DSI_TIMEOUT_LRX(x) (((x) & 0xFFFF) << 16)
#define DSI_TIMEOUT_1 0x45
-#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
-#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
+#define DSI_TIMEOUT_TA(x) (((x) & 0xFFFF) << 0)
+#define DSI_TIMEOUT_PR(x) (((x) & 0xFFFF) << 16)
#define DSI_TO_TALLY 0x46
#define DSI_PAD_CONTROL_0 0x4B
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
-#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
+#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xF) << 0)
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
-#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
+#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xF) << 16)
#define DSI_PAD_CONTROL_CD 0x4C
#define DSI_VIDEO_MODE_CONTROL 0x4E
@@ -547,17 +658,17 @@
#define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID.
#define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID.
#define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID.
-#define MIPI_DCS_GET_NUM_ERRORS 0x05
+#define MIPI_DCS_GET_NUM_ERRORS 0x05 // 1 byte.
#define MIPI_DCS_GET_RED_CHANNEL 0x06
#define MIPI_DCS_GET_GREEN_CHANNEL 0x07
#define MIPI_DCS_GET_BLUE_CHANNEL 0x08
-#define MIPI_DCS_GET_DISPLAY_STATUS 0x09
-#define MIPI_DCS_GET_POWER_MODE 0x0A
-#define MIPI_DCS_GET_ADDRESS_MODE 0x0B
-#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C
-#define MIPI_DCS_GET_DISPLAY_MODE 0x0D
-#define MIPI_DCS_GET_SIGNAL_MODE 0x0E
-#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F
+#define MIPI_DCS_GET_DISPLAY_STATUS 0x09 // 4 bytes.
+#define MIPI_DCS_GET_POWER_MODE 0x0A // 1 byte. 2: DISON, 3: NORON, 4: SLPOUT, 7: BSTON.
+#define MIPI_DCS_GET_ADDRESS_MODE 0x0B // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
+#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C // 1 byte. 4-6: DPI.
+#define MIPI_DCS_GET_DISPLAY_MODE 0x0D // 1 byte. 0-2: GCS, 3: ALLPOFF, 4: ALLPON, 5: INVON.
+#define MIPI_DCS_GET_SIGNAL_MODE 0x0E // 1 byte. 0: EODSI, 2: DEON, 3: PCLKON, 4: VSON, 5: HSON, 7: TEON.
+#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F // 1 byte. 6: FUNDT, 7: REGLD.
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
#define MIPI_DCS_ENTER_PARTIAL_MODE 0x12
@@ -567,7 +678,7 @@
#define MIPI_DCS_ALL_PIXELS_OFF 0x22
#define MIPI_DCS_ALL_PIXELS_ON 0x23
#define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer.
-#define MIPI_DCS_SET_GAMMA_CURVE 0x26
+#define MIPI_DCS_SET_GAMMA_CURVE 0x26 // 1 byte. 0-7: GC.
#define MIPI_DCS_SET_DISPLAY_OFF 0x28
#define MIPI_DCS_SET_DISPLAY_ON 0x29
#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A
@@ -580,11 +691,11 @@
#define MIPI_DCS_SET_SCROLL_AREA 0x33
#define MIPI_DCS_SET_TEAR_OFF 0x34
#define MIPI_DCS_SET_TEAR_ON 0x35
-#define MIPI_DCS_SET_ADDRESS_MODE 0x36
+#define MIPI_DCS_SET_ADDRESS_MODE 0x36 // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
#define MIPI_DCS_SET_SCROLL_START 0x37
#define MIPI_DCS_EXIT_IDLE_MODE 0x38
#define MIPI_DCS_ENTER_IDLE_MODE 0x39
-#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A
+#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A // 1 byte. 4-6: DPI.
#define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C
#define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E
#define MIPI_DCS_GET_3D_CONTROL 0x3F
@@ -593,26 +704,40 @@
#define MIPI_DCS_GET_SCANLINE 0x45
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
-#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL.
-#define MIPI_DCS_GET_BRIGHTNESS 0x52
-#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53
-#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54
-#define MIPI_DCS_SET_CABC_VALUE 0x55
-#define MIPI_DCS_GET_CABC_VALUE 0x56
-#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E
-#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F
+#define MIPI_DSI_AREA_COLOR_MODE 0x4C
+#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. 1 byte. 0-7: DBV.
+#define MIPI_DCS_GET_BRIGHTNESS 0x52 // 1 byte. 0-7: DBV.
+#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
+#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
+#define MIPI_DCS_SET_CABC_VALUE 0x55 // 1 byte. 0-32: C, 4-7: C.
+#define MIPI_DCS_GET_CABC_VALUE 0x56 // 1 byte. 0-32: C, 4-7: C.
+#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E // 1 byte. 0-7: CMB.
+#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F // 1 byte. 0-7: CMB.
+#define MIPI_DCS_GET_AUTO_BRI_DIAG_RES 0x68 // 1 byte. 6-7: D.
#define MIPI_DCS_READ_DDB_START 0xA1
-#define MIPI_DCS_READ_DDB_CONTINUE 0xA8
+#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
/*! MIPI DCS Panel Private CMDs. */
-#define MIPI_DCS_PRIV_UNK_A0 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
-#define MIPI_DCS_PRIV_SET_EXTC 0xB9
+#define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands.
#define MIPI_DCS_PRIV_UNK_BD 0xBD
#define MIPI_DCS_PRIV_UNK_D5 0xD5
#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_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.
+
+/*! MIPI DCS Panel Private CMDs PAGE 1. */
+#define MIPI_DCS_PRIV_GET_DISPLAY_ID4 0x00
+#define MIPI_DCS_PRIV_GET_DISPLAY_ID5 0x01
+#define MIPI_DCS_PRIV_GET_DISPLAY_ID6 0x02
/*! MIPI DCS CMD Defines. */
#define DCS_POWER_MODE_DISPLAY_ON BIT(2)
@@ -640,24 +765,59 @@
#define DCS_GAMMA_CURVE_GC2_1_0 BIT(2)
#define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more?
+#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. Based on Vivid but over-saturated.
+#define DCS_SM_COLOR_MODE_WASHED 0x45
+#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.. 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)
+
+#define PANEL_SM_BL_CANDELA_MAX 2047
/* Switch Panels:
*
- * 6.2" panels for Icosa and Iowa skus:
+ * 6.2" panels for Icosa and Iowa SKUs:
* [10] 81 [26]: JDI LPM062M326A
* [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
- * [20] 95 [0F]: InnoLux P062CCA-AZ2
+ * [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
+ * [20] 96 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
+ * [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]
*
- * 5.5" panels for Hoag skus:
- * [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
- * [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID]
- * [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
+ *
+ * 5.5" panels for Hoag SKU:
+ * [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) (6203B001P4000)
+ * [20] 95 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [20] 96 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
+ * [30] 93 [10]: AUO A055TAN01 (59.05A30.001)
+ * [30] 94 [10]: AUO A055TAN02 (59.05A30.002)
+ * [30] 95 [10]: AUO A055TAN03 (59.05A30.003)
+ * [40] 94 [10]: Sharp LQ055T1SW10 (Rev P)
+ *
+ *
+ * 7.0" OLED panels for Aula SKU:
+ * [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5)
*/
/* Display ID Decoding:
@@ -670,13 +830,13 @@
* 10h: Japan Display Inc.
* 20h: InnoLux Corporation
* 30h: AU Optronics
- * 40h: Unknown1
- * 50h: Unknown2 (OLED? Samsung? LG?)
+ * 40h: Sharp
+ * 50h: Samsung
*
* Boards, Panel Size:
* 0Fh: Icosa/Iowa, 6.2"
* 10h: Hoag, 5.5"
- * 20h: Unknown, x.x"
+ * 20h: Aula, 7.0"
*/
enum
@@ -688,36 +848,60 @@ enum
PANEL_AUO_A062TAN01 = 0x0F30,
PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030,
- PANEL_V40_55_UNK = 0x1040
+ PANEL_SHP_LQ055T1SW10 = 0x1040,
+ PANEL_SAM_AMS699VC01 = 0x2050,
+
+ // Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
+ 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
};
void display_init();
void display_backlight_pwm_init();
void display_end();
+/*! Interrupt management. */
+void display_enable_interrupt(u32 intr);
+void display_disable_interrupt(u32 intr);
+void display_wait_interrupt(u32 intr);
+
/*! Get/Set Display panel ID. */
u16 display_get_decoded_panel_id();
void display_set_decoded_panel_id(u32 id);
+/*! MIPI DCS register management */
+int display_dsi_read(u8 cmd, u32 len, void *data);
+int display_dsi_vblank_read(u8 cmd, u32 len, void *data);
+void display_dsi_write(u8 cmd, u32 len, void *data);
+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. */
void display_backlight(bool enable);
void display_backlight_brightness(u32 brightness, u32 step_delay);
+u32 display_get_backlight_brightness();
-/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
-u32 *display_init_framebuffer_pitch();
-u32 *display_init_framebuffer_pitch_inv();
-u32 *display_init_framebuffer_block();
-u32 *display_init_framebuffer_log();
-void display_activate_console();
-void display_deactivate_console();
-void display_init_cursor(void *crs_fb, u32 size);
-void display_set_pos_cursor(u32 x, u32 y);
-void display_deinit_cursor();
+u32 *display_init_window_a_pitch();
+u32 *display_init_window_a_pitch_vic();
+u32 *display_init_window_a_pitch_inv();
+u32 *display_init_window_a_block();
+u32 *display_init_window_d_console();
-void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled);
-int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled);
+void display_window_disable(u32 window);
+
+void display_set_framebuffer(u32 window, void *fb);
+void display_move_framebuffer(u32 window, void *fb);
+
+void display_window_d_console_enable();
+void display_window_d_console_disable();
+
+void display_cursor_init(void *crs_fb, u32 size);
+void display_cursor_set_pos(u32 x, u32 y);
+void display_cursor_deinit();
#endif
diff --git a/bdk/gfx/di.inl b/bdk/display/di.inl
similarity index 50%
rename from bdk/gfx/di.inl
rename to bdk/display/di.inl
index f98c5c7..d74130e 100644
--- a/bdk/gfx/di.inl
+++ b/bdk/display/di.inl
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
-* Copyright (c) 2018-2020 CTCaer
+* Copyright (c) 2018-2024 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,122 +15,66 @@
* along with this program. If not, see .
*/
-//Display A config.
-static const cfg_op_t _display_dc_setup_win_config[94] = {
- {DC_CMD_STATE_ACCESS, 0},
+// Display A config.
+static const reg_cfg_t _di_dc_setup_win_config[] = {
+ {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, 0x54}, // Select H counter for win A/B/C.
+ {DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
- {DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
- {DC_CMD_STATE_ACCESS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | SYNCPT_VSYNC_INDX(9)},
+ {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 */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
/* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
+ {DC_WINC_CSC_YOF, 0xF0},
+ {DC_WINC_CSC_KYRGB, 0x12A},
+ {DC_WINC_CSC_KUR, 0},
+ {DC_WINC_CSC_KVR, 0x198},
+ {DC_WINC_CSC_KUG, 0x39B},
+ {DC_WINC_CSC_KVG, 0x32F},
+ {DC_WINC_CSC_KUB, 0x204},
+ {DC_WINC_CSC_KVB, 0},
/* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- /* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
- /* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- /* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
- /* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
+
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
- {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
+ {DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
{DC_COM_CRC_CONTROL, 0},
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
+ {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},
+ {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
+ {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}
};
-//DSI Init config.
-static const cfg_op_t _display_dsi_init_config_part1[8] = {
+// DSI Init config.
+static const reg_cfg_t _di_dsi_seq_pkt_reset_config0[] = {
{DSI_WR_DATA, 0},
{DSI_INT_ENABLE, 0},
{DSI_INT_STATUS, 0},
- {DSI_INT_MASK, 0},
+ {DSI_INT_MASK, 0},
{DSI_INIT_SEQ_DATA_0, 0},
{DSI_INIT_SEQ_DATA_1, 0},
{DSI_INIT_SEQ_DATA_2, 0},
{DSI_INIT_SEQ_DATA_3, 0}
};
-static const cfg_op_t _display_dsi_init_config_part2[14] = {
+static const reg_cfg_t _di_dsi_seq_pkt_reset_config1[] = {
{DSI_DCS_CMDS, 0},
{DSI_PKT_SEQ_0_LO, 0},
{DSI_PKT_SEQ_1_LO, 0},
@@ -146,7 +90,7 @@ static const cfg_op_t _display_dsi_init_config_part2[14] = {
{DSI_PKT_SEQ_5_HI, 0},
{DSI_CONTROL, 0}
};
-static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
+static const reg_cfg_t _di_dsi_init_pads_t210b01[] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 0},
{DSI_PAD_CONTROL_3, 0},
@@ -155,55 +99,63 @@ static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
{DSI_PAD_CONTROL_6_B01, 0},
{DSI_PAD_CONTROL_7_B01, 0}
};
-static const cfg_op_t _display_dsi_init_config_part4[10] = {
+static const reg_cfg_t _di_dsi_init_config[] = {
{DSI_PAD_CONTROL_CD, 0},
- {DSI_SOL_DELAY, 0x18},
- {DSI_MAX_THRESHOLD, 0x1E0},
+ {DSI_SOL_DELAY, 24},
+ {DSI_MAX_THRESHOLD, 480},
{DSI_TRIGGER, 0},
{DSI_INIT_SEQ_CONTROL, 0},
+
{DSI_PKT_LEN_0_1, 0},
{DSI_PKT_LEN_2_3, 0},
{DSI_PKT_LEN_4_5, 0},
{DSI_PKT_LEN_6_7, 0},
- {DSI_PAD_CONTROL_1, 0}
-};
-static const cfg_op_t _display_dsi_init_config_part5[12] = {
+
+ {DSI_PAD_CONTROL_1, 0},
+
+ /* DSI PHY timings */
+ {DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
- {DSI_BTA_TIMING, 0x190A14},
+ {DSI_BTA_TIMING, 0x190A14},
+ /* DSI timeout */
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
- {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
- {DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
+
+ {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_PAD_CONTROL_1, 0}
-};
-static const cfg_op_t _display_dsi_init_config_part6[14] = {
+ {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_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_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_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
- {DSI_MAX_THRESHOLD, 0x40},
+ {DSI_MAX_THRESHOLD, 64},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
-//DSI panel config.
-static const cfg_op_t _display_init_config_jdi[43] = {
- {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
+// DSI panel JDI config.
+static const reg_cfg_t _di_dsi_panel_init_config_jdi[] = {
+ {DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST},
- {DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
+ {DSI_WR_DATA, 0xBD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes.
{DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8.
@@ -245,14 +197,20 @@ static const cfg_op_t _display_init_config_jdi[43] = {
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
-//DSI packet config.
-static const cfg_op_t _display_dsi_packet_config[19] = {
+// DSI 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_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30172},
- {DSI_BTA_TIMING, 0x190A14},
+ {DSI_BTA_TIMING, 0x190A14},
+ /* DSI timeout */
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
- {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
+
{DSI_PKT_SEQ_0_LO, 0x40000208},
{DSI_PKT_SEQ_2_LO, 0x40000308},
{DSI_PKT_SEQ_4_LO, 0x40000308},
@@ -261,66 +219,66 @@ static const cfg_op_t _display_dsi_packet_config[19] = {
{DSI_PKT_SEQ_3_HI, 0x2CC},
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
{DSI_PKT_SEQ_5_HI, 0x2CC},
- {DSI_PKT_LEN_0_1, 0xCE0000},
- {DSI_PKT_LEN_2_3, 0x87001A2},
- {DSI_PKT_LEN_4_5, 0x190},
- {DSI_PKT_LEN_6_7, 0x190},
+ {DSI_PKT_LEN_0_1, PKT1_LEN(206) | PKT0_LEN(0)},
+ {DSI_PKT_LEN_2_3, PKT1_LEN(2160) | PKT0_LEN(418)},
+ {DSI_PKT_LEN_4_5, PKT1_LEN(0) | PKT0_LEN(400)},
+ {DSI_PKT_LEN_6_7, PKT1_LEN(0) | PKT0_LEN(400)},
{DSI_HOST_CONTROL, 0}
};
-//DSI mode config.
-static const cfg_op_t _display_dsi_mode_config[10] = {
+// DSI mode config.
+static const reg_cfg_t _di_dsi_host_mode_config[] = {
{DSI_TRIGGER, 0},
{DSI_CONTROL, 0},
{DSI_SOL_DELAY, 6},
- {DSI_MAX_THRESHOLD, 0x1E0},
+ {DSI_MAX_THRESHOLD, 480},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
- {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
- {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
- {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
};
-//MIPI CAL config.
-static const cfg_op_t _display_mipi_pad_cal_config[4] = {
+// MIPI CAL config.
+static const reg_cfg_t _di_mipi_pad_cal_config[] = {
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
};
-//DSI config.
-static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
+// DSI pad config.
+static const reg_cfg_t _di_dsi_pad_cal_config_t210[] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 0},
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
{DSI_PAD_CONTROL_4, 0}
};
-static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = {
- {DSI_PAD_CONTROL_1, 0},
- {DSI_PAD_CONTROL_2, 0},
- {DSI_PAD_CONTROL_3, 0},
- {DSI_PAD_CONTROL_4, 0x77777},
+static const reg_cfg_t _di_dsi_pad_cal_config_t210b01[] = {
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PAD_CONTROL_2, 0},
+ {DSI_PAD_CONTROL_3, 0},
+ {DSI_PAD_CONTROL_4, 0x77777},
{DSI_PAD_CONTROL_5_B01, 0x77777},
- {DSI_PAD_CONTROL_6_B01, 0x1111},
+ {DSI_PAD_CONTROL_6_B01, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)},
{DSI_PAD_CONTROL_7_B01, 0}
};
-//MIPI CAL config.
-static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
+// MIPI CAL config.
+static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210[] = {
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
};
-static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = {
+static const reg_cfg_t _di_mipi_dsi_cal_prod_config_t210b01[] = {
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
};
-static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
+static const reg_cfg_t _di_mipi_dsi_cal_unused_config[] = {
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
@@ -331,201 +289,88 @@ static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
- {MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
- {MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001}
+ {MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0}
};
-//Display A config.
-static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
- {DC_CMD_STATE_ACCESS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- /* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
- /* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- /* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
- /* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_DV_CONTROL, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- /* Setup default YUV colorspace conversion coefficients */
- {DC_WIN_CSC_YOF, 0xF0},
- {DC_WIN_CSC_KYRGB, 0x12A},
- {DC_WIN_CSC_KUR, 0},
- {DC_WIN_CSC_KVR, 0x198},
- {DC_WIN_CSC_KUG, 0x39B},
- {DC_WIN_CSC_KVG, 0x32F},
- {DC_WIN_CSC_KUB, 0x204},
- {DC_WIN_CSC_KVB, 0},
- /* End of color coefficients */
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
- {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
- {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
- {DC_COM_PIN_OUTPUT_POLARITY(3), 0},
- {DC_DISP_BLEND_BACKGROUND_COLOR, 0},
- {DC_COM_CRC_CONTROL, 0},
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
- {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
- {DC_CMD_STATE_ACCESS, 0},
-
- /* Set Display timings
- *
- * DC_DISP_REF_TO_SYNC:
- * V_REF_TO_SYNC - 1
- * H_REF_TO_SYNC - 0
- *
- * DC_DISP_SYNC_WIDTH:
- * V_SYNC_WIDTH - 1
- * H_SYNC_WIDTH - 72
- *
- * DC_DISP_BACK_PORCH:
- * V_BACK_PORCH - 9
- * H_BACK_PORCH - 72
- *
- * DC_DISP_ACTIVE:
- * V_DISP_ACTIVE - 1280
- * H_DISP_ACTIVE - 720
- *
- * DC_DISP_FRONT_PORCH:
- * V_FRONT_PORCH - 10
- * H_FRONT_PORCH - 136
- */
- {DC_DISP_DISP_TIMING_OPTIONS, 0},
- {DC_DISP_REF_TO_SYNC, 0x10000},
- {DC_DISP_SYNC_WIDTH, 0x10048},
- {DC_DISP_BACK_PORCH, 0x90048},
- {DC_DISP_ACTIVE, 0x50002D0},
- {DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
+// Display A enable config.
+static const reg_cfg_t _di_dc_video_enable_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)},
+ {DC_DISP_SYNC_WIDTH, V_SYNC_WIDTH(1) | H_SYNC_WIDTH(72)},
+ {DC_DISP_BACK_PORCH, V_BACK_PORCH(9) | H_BACK_PORCH(72)},
+ {DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
+ {DC_DISP_ACTIVE, V_DISP_ACTIVE(1280) | H_DISP_ACTIVE(720)},
/* End of Display timings */
{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_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_DISP_DISP_CLOCK_CONTROL, 0},
- {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0},
+
+ /* Start continuous display. */
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
- {DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
- {DC_DISP_FRONT_PORCH, 0xA0088},
- {DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
- {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
- {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
+ {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_CMD_STATE_ACCESS, 0},
- {DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
- {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
- {DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
+
+ {DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)}, // 4: div3.
};
-////Display A config.
-static const cfg_op_t _display_video_disp_controller_disable_config[17] = {
- {DC_DISP_FRONT_PORCH, 0xA0088},
+// Display A disable config.
+static const reg_cfg_t _di_dc_video_disable_config[] = {
{DC_CMD_INT_MASK, 0},
- {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
{DC_CMD_INT_ENABLE, 0},
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
+
+ /* Stop display. */
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
- {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
- {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
+ {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},
+ // TODO: LCD panels should sleep for 40ms here.
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
};
-//DSI config.
-static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
+// DSI deinit config.
+static const reg_cfg_t _di_dsi_timing_deinit_config[] = {
{DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0},
- {DSI_PHY_TIMING_0, 0x6070601},
+
+ /* DSI PHY timings */
+ {DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118},
- {DSI_BTA_TIMING, 0x190A14},
- {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
- {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
+ {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, 0x40},
+ {DSI_MAX_THRESHOLD, 64},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
-//DSI config (if ver == 0x10).
-static const cfg_op_t _display_deinit_config_jdi[22] = {
+// 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.
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST},
@@ -550,7 +395,8 @@ static const cfg_op_t _display_deinit_config_jdi[22] = {
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
-static const cfg_op_t _display_deinit_config_auo[37] = {
+// DSI panel AUO deinit config.
+static const reg_cfg_t _di_dsi_panel_deinit_config_auo[] = {
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST},
@@ -591,156 +437,137 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
-static const cfg_op_t _display_init_config_invert[3] = {
+/*
+static const reg_cfg_t _di_init_config_invert[] = {
{DSI_WR_DATA, 0x239},
{DSI_WR_DATA, 0x02C1}, // INV_EN.
{DSI_TRIGGER, DSI_TRIGGER_HOST},
};
+*/
-//Display A config.
-static const cfg_op_t cfg_display_one_color[8] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+// Display A Window A one color config.
+static const reg_cfg_t _di_win_one_color[] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
};
-//Display A config linear pitch.
-static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
+// Display A Window A linear pitch config.
+static const reg_cfg_t _di_winA_pitch[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
- {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
- {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
- {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
{DC_WINBUF_SURFACE_KIND, PITCH},
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0},
{DC_WINBUF_ADDR_V_OFFSET, 0},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
-//Display A config linear pitch inverse + Win D support.
-static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
+// Display A Window A linear pitch + Win D support config.
+static const reg_cfg_t _di_winA_pitch_vic[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
- {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
- {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
- {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
+ {DC_WINBUF_SURFACE_KIND, PITCH},
+ {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0},
+ {DC_WINBUF_ADDR_V_OFFSET, 0},
+ {DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
+};
+
+// Display A Window A linear pitch inverse + Win D support config.
+static const reg_cfg_t _di_winA_pitch_inv[] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
{DC_WINBUF_SURFACE_KIND, PITCH},
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC.
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
-//Display A config block linear.
-static const cfg_op_t cfg_display_framebuffer_block[34] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
- {DC_WIN_WIN_OPTIONS, 0},
+// Display A Window A block linear config.
+static const reg_cfg_t _di_winA_block[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
- {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
- {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
- {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK},
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
- {DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC.
+ {DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC. Block in HOS: 0x13FF.
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
-//Display D config.
-static const cfg_op_t cfg_display_framebuffer_log[20] = {
+// Display A Window D config.
+static const reg_cfg_t _di_winD_log[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
- {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
- {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
- {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
{DC_WINBUF_SURFACE_KIND, PITCH},
{DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0},
{DC_WINBUF_ADDR_V_OFFSET, 0},
- {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)},
+ {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)},
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
- {DC_WIN_WIN_OPTIONS, 0}, // Enable window DD.
- {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
- {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ},
};
diff --git a/bdk/display/vic.c b/bdk/display/vic.c
new file mode 100644
index 0000000..1044448
--- /dev/null
+++ b/bdk/display/vic.c
@@ -0,0 +1,560 @@
+/*
+ * VIC driver for Tegra X1
+ *
+ * Copyright (c) 2018-2024 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 .
+ */
+
+#include
+
+#include "vic.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* VIC Private registers */
+#define PVIC_FALCON_PA_OFFSET 0x1000
+#define PVIC_FALCON_ADDR 0x10AC
+#define PVIC_FALCON_IDLESTATE 0x104C
+
+/* VIC Control and Status registers. */
+/* Fetch Control registers. */
+#define VIC_FC_COMPOSE 0x10000
+#define COMPOSE_START BIT(0)
+
+#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00
+
+#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04
+#define SLOT_ENABLE BIT(0)
+#define FIELD_CURRENT_ENABLE BIT(8)
+
+#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_128BX2 3 // Block Linear, Pitch.
+#define OUTPUT_FLIP_X BIT(20)
+#define OUTPUT_FLIP_Y BIT(21)
+#define OUTPUT_TRANSPOSE BIT(22)
+
+#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10
+#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14
+#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18
+#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C
+#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20
+#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30
+#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34
+#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38
+#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C
+#define VIC_FC_SLOT_MAP 0x10C00
+
+#define VIC_FC_FCE_CTRL 0x11000
+#define START_TRIGGER BIT(0)
+#define HALT_TRIGGER BIT(1)
+#define CLEAR_ERROR BIT(8)
+
+#define VIC_FC_FCE_UCODE_ADDR 0x11200
+#define VIC_FC_FCE_UCODE_INST 0x11300
+
+/* Surface List registers. */
+#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100
+#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200
+#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300
+#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400
+#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500
+#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600
+
+/* Surface Cache registers. */
+#define VIC_SC_PRAMBASE 0x14000
+#define VIC_SC_PRAMSIZE 0x14100
+#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100)
+
+/* Blending Output registers. */
+#define VIC_BL_TARGET_BASADR 0x22000
+#define VIC_BL_CONFIG 0x22800
+#define SUBPARTITION_MODE BIT(0)
+#define PROCESS_CFG_STRUCT_TRIGGER BIT(2)
+#define SLOTMASK(n) ((n) << 8)
+
+#define VIC_BL_CFG_STRUCT_CFG0 0x22C00
+#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04
+#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08
+#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C
+#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10
+#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14
+
+// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0.
+#define BLK_KIND(n) ((n) << 8)
+#define BLK_KIND_PITCH 0
+#define BLK_KIND_GENERIC_16BX2 1
+#define BLK_HEIGHT(n) ((n) << 12)
+#define BLK_HEIGHT_ONE_GOB 0
+#define BLK_HEIGHT_SIXTEEN_GOBS 4
+
+// Generic size macros.
+#define SIZE_WIDTH(n) (((n) - 1) << 0)
+#define SIZE_HEIGHT(n) (((n) - 1) << 16)
+#define RECT_LEFT(n) ((n) << 0)
+#define RECT_RIGHT(n) (((n) - 1) << 16)
+#define RECT_TOP(n) ((n) << 0)
+#define RECT_BOTTOM(n) (((n) - 1) << 16)
+
+#define FORMAT_PROGRESSIVE 0
+#define SOFT_CLAMP_MIN 0
+#define SOFT_CLAMP_MAX 0x3FFu
+#define ALPHA_1_0 0x3FFu
+
+typedef struct _OutputConfig {
+ u64 AlphaFillMode:3;
+ u64 AlphaFillSlot:3;
+ u64 BackgroundAlpha:10;
+ u64 BackgroundR:10;
+ u64 BackgroundG:10;
+ u64 BackgroundB:10;
+ u64 RegammaMode:2;
+ u64 OutputFlipX:1;
+ u64 OutputFlipY:1;
+ u64 OutputTranspose:1;
+ u64 rsvd1:1;
+ u64 rsvd2:12;
+ u64 TargetRectLeft:14;
+ u64 rsvd3:2;
+ u64 TargetRectRight:14;
+ u64 rsvd4:2;
+ u64 TargetRectTop:14;
+ u64 rsvd5:2;
+ u64 TargetRectBottom:14;
+ u64 rsvd6:2;
+} OutputConfig;
+
+typedef struct _OutputSurfaceConfig {
+ u64 OutPixelFormat:7;
+ u64 OutChromaLocHoriz:2;
+ u64 OutChromaLocVert:2;
+ u64 OutBlkKind:4;
+ u64 OutBlkHeight:4;
+ u64 rsvd0:3;
+ u64 rsvd1:10;
+ u64 OutSurfaceWidth:14;
+ u64 OutSurfaceHeight:14;
+ u64 rsvd2:4;
+ u64 OutLumaWidth:14;
+ u64 OutLumaHeight:14;
+ u64 rsvd3:4;
+ u64 OutChromaWidth:14;
+ u64 OutChromaHeight:14;
+ u64 rsvd4:4;
+} OutputSurfaceConfig;
+
+typedef struct _SlotConfig {
+ u64 SlotEnable:1;
+ u64 DeNoise:1;
+ u64 AdvancedDenoise:1;
+ u64 CadenceDetect:1;
+ u64 MotionMap:1;
+ u64 MMapCombine:1;
+ u64 IsEven:1;
+ u64 ChromaEven:1;
+ u64 CurrentFieldEnable:1;
+ u64 PrevFieldEnable:1;
+ u64 NextFieldEnable:1;
+ u64 NextNrFieldEnable:1;
+ u64 CurMotionFieldEnable:1;
+ u64 PrevMotionFieldEnable:1;
+ u64 PpMotionFieldEnable:1;
+ u64 CombMotionFieldEnable:1;
+ u64 FrameFormat:4;
+ u64 FilterLengthY:2;
+ u64 FilterLengthX:2;
+ u64 Panoramic:12;
+ u64 rsvd1:22;
+ u64 DetailFltClamp:6;
+ u64 FilterNoise:10;
+ u64 FilterDetail:10;
+ u64 ChromaNoise:10;
+ u64 ChromaDetail:10;
+ u64 DeinterlaceMode:4;
+ u64 MotionAccumWeight:3;
+ u64 NoiseIir:11;
+ u64 LightLevel:4;
+ u64 rsvd4:2;
+ u64 SoftClampLow:10;
+ u64 SoftClampHigh:10;
+ u64 rsvd5:3;
+ u64 rsvd6:9;
+ u64 PlanarAlpha:10;
+ u64 ConstantAlpha:1;
+ u64 StereoInterleave:3;
+ u64 ClipEnabled:1;
+ u64 ClearRectMask:8;
+ u64 DegammaMode:2;
+ u64 rsvd7:1;
+ u64 DecompressEnable:1;
+ u64 rsvd9:5;
+ u64 DecompressCtbCount:8;
+ u64 DecompressZbcColor:32;
+ u64 rsvd12:24;
+ u64 SourceRectLeft:30;
+ u64 rsvd14:2;
+ u64 SourceRectRight:30;
+ u64 rsvd15:2;
+ u64 SourceRectTop:30;
+ u64 rsvd16:2;
+ u64 SourceRectBottom:30;
+ u64 rsvd17:2;
+ u64 DestRectLeft:14;
+ u64 rsvd18:2;
+ u64 DestRectRight:14;
+ u64 rsvd19:2;
+ u64 DestRectTop:14;
+ u64 rsvd20:2;
+ u64 DestRectBottom:14;
+ u64 rsvd21:2;
+ u64 rsvd22:32;
+ u64 rsvd23:32;
+} SlotConfig;
+
+typedef struct _SlotSurfaceConfig {
+ u64 SlotPixelFormat:7;
+ u64 SlotChromaLocHoriz:2;
+ u64 SlotChromaLocVert:2;
+ u64 SlotBlkKind:4;
+ u64 SlotBlkHeight:4;
+ u64 SlotCacheWidth:3;
+ u64 rsvd0:10;
+ u64 SlotSurfaceWidth:14;
+ u64 SlotSurfaceHeight:14;
+ u64 rsvd1:4;
+ u64 SlotLumaWidth:14;
+ u64 SlotLumaHeight:14;
+ u64 rsvd2:4;
+ u64 SlotChromaWidth:14;
+ u64 SlotChromaHeight:14;
+ u64 rsvd3:4;
+} SlotSurfaceConfig;
+
+typedef struct _SlotStruct {
+ SlotConfig slot_cfg;
+ SlotSurfaceConfig slot_sfc_cfg;
+
+ // No need to configure. Reset to zeros.
+ u8 lumaKeyStruct[0x10];
+ u8 colorMatrixStruct[0x20];
+ u8 gamutMatrixStruct[0x20];
+ u8 blendingSlotStruct[0x10];
+} SlotStruct;
+
+typedef struct _vic_config_t {
+ // No need to configure. Reset to zeros.
+ u8 pipeConfig[0x10];
+
+ OutputConfig out_cfg;
+ OutputSurfaceConfig out_sfc_cfg;
+
+ // No need to configure. Reset to zeros.
+ u8 out_color_matrix[0x20];
+ u8 clear_rect[0x10 * 4];
+
+ SlotStruct slots[8];
+} vic_config_t;
+
+// VIC Fetch Control Engine microcode. Dumped from L4T r33.
+u8 vic_fce_ucode[] = {
+ 0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00,
+ 0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00,
+ 0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00,
+ 0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00,
+ 0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00,
+ 0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
+ 0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00,
+ 0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00,
+ 0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00,
+ 0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00,
+ 0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00,
+ 0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00,
+ 0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00,
+ 0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00,
+ 0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00,
+ 0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00,
+ 0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00,
+ 0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00,
+ 0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00,
+ 0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00,
+ 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00,
+ 0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00,
+ 0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00,
+ 0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00,
+ 0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00,
+ 0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00,
+ 0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00,
+ 0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00,
+ 0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00,
+ 0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00,
+ 0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00,
+ 0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00,
+ 0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00,
+ 0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00,
+ 0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00,
+ 0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00,
+ 0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00,
+ 0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00,
+ 0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00,
+ 0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00,
+ 0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
+ 0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00,
+ 0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00,
+ 0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
+ 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00,
+ 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
+ 0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00,
+ 0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00,
+ 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00,
+ 0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00,
+ 0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00,
+ 0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00,
+ 0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00,
+ 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00,
+ 0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00,
+ 0x6F, 0x00, 0x00, 0x00
+};
+
+vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0};
+
+u32 _vic_read_priv(u32 addr)
+{
+ u32 addr_lsb = addr & 0xFF;
+
+ // Set address LSB.
+ if (addr_lsb)
+ VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
+
+ // Set address.
+ u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6));
+
+ // Unset address LSB.
+ if (addr_lsb)
+ VIC(PVIC_FALCON_ADDR) = 0;
+
+ return val;
+}
+
+static void _vic_write_priv(u32 addr, u32 data)
+{
+ u32 addr_lsb = addr & 0xFF;
+
+ // Set address LSB.
+ if (addr_lsb)
+ VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
+
+ // Set address.
+ VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data;
+
+ // Unset address LSB.
+ if (addr_lsb)
+ VIC(PVIC_FALCON_ADDR) = 0;
+}
+
+static int _vic_wait_idle()
+{
+ u32 timeout_count = 15000; // 150ms.
+
+ while (VIC(PVIC_FALCON_IDLESTATE))
+ {
+ usleep(10);
+
+ timeout_count--;
+ if (!timeout_count)
+ return -1;
+ };
+
+ return 0;
+}
+
+void vic_set_surface(const vic_surface_t *sfc)
+{
+ u32 flip_x = 0;
+ u32 flip_y = 0;
+ u32 swap_xy = 0;
+ u32 const_alpha = 0;
+
+ u32 width = sfc->width;
+ u32 height = sfc->height;
+ u32 pix_fmt = sfc->pix_fmt;
+ u32 src_buf = sfc->src_buf;
+ u32 dst_buf = sfc->dst_buf;
+
+ // Get format alpha type.
+ switch (sfc->pix_fmt)
+ {
+ case VIC_PIX_FORMAT_L8:
+ case VIC_PIX_FORMAT_X1B5G5R5:
+ case VIC_PIX_FORMAT_B5G5R5X1:
+ case VIC_PIX_FORMAT_X8B8G8R8:
+ case VIC_PIX_FORMAT_X8R8G8B8:
+ case VIC_PIX_FORMAT_B8G8R8X8:
+ case VIC_PIX_FORMAT_R8G8B8X8:
+ const_alpha = 1;
+ break;
+
+ case VIC_PIX_FORMAT_A8B8G8R8:
+ case VIC_PIX_FORMAT_A8R8G8B8:
+ case VIC_PIX_FORMAT_B8G8R8A8:
+ case VIC_PIX_FORMAT_R8G8B8A8:
+ default:
+ break;
+ }
+
+ // Get rotation parameters.
+ switch (sfc->rotation)
+ {
+ case VIC_ROTATION_90:
+ swap_xy = 1;
+ break;
+
+ case VIC_ROTATION_180:
+ flip_x = 1;
+ flip_y = 1;
+ break;
+
+ case VIC_ROTATION_270:
+ flip_x = 1;
+ swap_xy = 1;
+ break;
+
+ case VIC_ROTATION_0:
+ default:
+ break;
+ }
+
+ // Set output surface format.
+ vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt;
+ vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH;
+ vic_cfg.out_sfc_cfg.OutBlkHeight = 0;
+
+ // Set output rotation/flip.
+ vic_cfg.out_cfg.OutputFlipX = flip_x;
+ vic_cfg.out_cfg.OutputFlipY = flip_y;
+ vic_cfg.out_cfg.OutputTranspose = swap_xy;
+
+ // Set output surface resolution.
+ vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1;
+ vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1;
+ vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1;
+ vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1;
+
+ // Set output destination rectangle. Anything outside will not be touched at output buffer.
+ vic_cfg.out_cfg.TargetRectLeft = 0;
+ vic_cfg.out_cfg.TargetRectRight = width - 1;
+ vic_cfg.out_cfg.TargetRectTop = 0;
+ vic_cfg.out_cfg.TargetRectBottom = height - 1;
+
+ // Initialize slot parameters.
+ vic_cfg.slots[0].slot_cfg.SlotEnable = 1;
+ vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN;
+ vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX;
+ vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0;
+ vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha;
+ vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE;
+
+ // Set input source rectangle.
+ vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0;
+ vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16;
+ vic_cfg.slots[0].slot_cfg.SourceRectTop = 0;
+ vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16;
+
+ // Set input destination rectangle.
+ vic_cfg.slots[0].slot_cfg.DestRectLeft = 0;
+ vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1);
+ vic_cfg.slots[0].slot_cfg.DestRectTop = 0;
+ vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1);
+
+ // Set input surface format.
+ vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4;
+
+ // Set input surface resolution.
+ vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1;
+ vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1;
+
+ // Flush data.
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
+
+ // Set parameters base and size. Causes a parse by surface cache.
+ _vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8);
+ _vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
+
+ // Wait for surface cache to get ready.
+ _vic_wait_idle();
+
+ // Set slot mapping.
+ _vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
+
+ // Set input surface buffer.
+ _vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8);
+
+ // Set output surface buffer.
+ _vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8);
+
+ // Set blending config and push changes to surface cache.
+ _vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
+
+ // Wait for surface cache to get ready.
+ _vic_wait_idle();
+}
+
+int vic_compose()
+{
+ // Wait for surface cache to get ready. Otherwise VIC will hang.
+ int res = _vic_wait_idle();
+
+ // Start composition of a single frame.
+ _vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
+
+ return res;
+}
+
+int vic_init()
+{
+ clock_enable_vic();
+
+ // Load Fetch Control Engine microcode.
+ for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
+ {
+ _vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32)));
+ _vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]);
+ }
+
+ // Start Fetch Control Engine.
+ _vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
+
+ return _vic_wait_idle();
+}
+
+void vic_end()
+{
+ clock_disable_vic();
+}
diff --git a/bdk/display/vic.h b/bdk/display/vic.h
new file mode 100644
index 0000000..20fbe6c
--- /dev/null
+++ b/bdk/display/vic.h
@@ -0,0 +1,66 @@
+/*
+ * VIC driver for Tegra X1
+ *
+ * Copyright (c) 2018-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 .
+ */
+
+#ifndef _VIC_H_
+#define _VIC_H_
+
+#include
+
+#define VIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
+
+typedef enum _vic_rotation_t
+{
+ VIC_ROTATION_0 = 0,
+ VIC_ROTATION_90 = 1,
+ VIC_ROTATION_180 = 2,
+ VIC_ROTATION_270 = 3,
+} vic_rotation_t;
+
+typedef enum _vic_pix_format_t
+{
+ VIC_PIX_FORMAT_L8 = 1, // 8-bit LUT.
+ VIC_PIX_FORMAT_X1B5G5R5 = 21, // 16-bit XBGR.
+ VIC_PIX_FORMAT_B5G5R5X1 = 23, // 16-bit BGRX.
+
+ VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
+ VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
+ VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
+ VIC_PIX_FORMAT_R8G8B8A8 = 34, // 32-bit RGBA.
+
+ VIC_PIX_FORMAT_X8B8G8R8 = 35, // 32-bit XBGR.
+ VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
+ VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
+ VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
+} vic_pix_format_t;
+
+typedef struct _vic_surface_t
+{
+ u32 src_buf;
+ u32 dst_buf;
+ u32 width;
+ u32 height;
+ u32 pix_fmt;
+ u32 rotation;
+} vic_surface_t;
+
+void vic_set_surface(const vic_surface_t *sfc);
+int vic_compose();
+int vic_init();
+void vic_end();
+
+#endif
diff --git a/bdk/exception_handlers.S b/bdk/exception_handlers.S
index 97d1ec6..2f38bb3 100644
--- a/bdk/exception_handlers.S
+++ b/bdk/exception_handlers.S
@@ -97,6 +97,10 @@ _irq_setup:
MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
LDR SP, =0x40040000
+ /* Setup FIQ stack pointer */
+ MSR CPSR, #(MODE_FIQ | IRQ | FIQ) /* FIQ mode, IRQ/FIQ disabled */
+ LDR SP, =0x40040000
+
/* Setup SYS stack pointer */
MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
@@ -111,7 +115,9 @@ _irq_setup:
B ipl_main
B .
-_reset:
+.globl excp_reset
+.type excp_reset, %function
+excp_reset:
LDR R0, =EXCP_EN_ADDR
LDR R1, =0x30505645 /* EVP0 */
STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
@@ -129,25 +135,25 @@ _reset_handler:
LDR R0, =EXCP_TYPE_ADDR
LDR R1, =0x545352 /* RST */
STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
- B _reset
+ B excp_reset
_undefined_handler:
LDR R0, =EXCP_TYPE_ADDR
LDR R1, =0x464455 /* UDF */
STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
- B _reset
+ B excp_reset
_prefetch_abort_handler:
LDR R0, =EXCP_TYPE_ADDR
LDR R1, =0x54424150 /* PABT */
STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
- B _reset
+ B excp_reset
_data_abort_handler:
LDR R0, =EXCP_TYPE_ADDR
LDR R1, =0x54424144 /* DABT */
STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
- B _reset
+ B excp_reset
.globl irq_enable_cpu_irq_exceptions
.type irq_enable_cpu_irq_exceptions, %function
diff --git a/bdk/fatfs_cfg.h b/bdk/fatfs_cfg.h
index a12585f..77b26dd 100644
--- a/bdk/fatfs_cfg.h
+++ b/bdk/fatfs_cfg.h
@@ -17,8 +17,12 @@
#ifndef _FATFS_CFG_H_
#define _FATFS_CFG_H_
+// define FFCFG_INC in a project to use a specific FatFS configuration.
+// Example: FFCFG_INC := '"../$(PROJECT_DIR)/libs/fatfs/ffconf.h"'
#ifdef FFCFG_INC
#include FFCFG_INC
+#else
+#include "fatfs_conf.h"
#endif
#endif
diff --git a/bdk/fatfs_conf.h b/bdk/fatfs_conf.h
new file mode 100644
index 0000000..e87219d
--- /dev/null
+++ b/bdk/fatfs_conf.h
@@ -0,0 +1,305 @@
+/*---------------------------------------------------------------------------/
+/ FatFs Functional Configurations
+/---------------------------------------------------------------------------*/
+
+#define FFCONF_DEF 86604 /* Revision ID */
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_READONLY 0
+/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+/ Read-only configuration removes writing API functions, f_write(), f_sync(),
+/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+/ and optional writing functions as well. */
+
+
+#define FF_FS_MINIMIZE 0
+/* This option defines minimization level to remove some basic API functions.
+/
+/ 0: Basic functions are fully enabled.
+/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
+/ are removed.
+/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+/ 3: f_lseek() function is removed in addition to 2. */
+
+
+#define FF_USE_STRFUNC 2
+/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
+/
+/ 0: Disable string functions.
+/ 1: Enable without LF-CRLF conversion.
+/ 2: Enable with LF-CRLF conversion. */
+
+
+#define FF_USE_FIND 1
+/* This option switches filtered directory read functions, f_findfirst() and
+/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
+
+
+#define FF_USE_MKFS 0
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+#if FF_USE_MKFS
+#define FF_MKFS_LABEL "SWITCH SD "
+#endif
+/* This sets FAT/FAT32 label. Exactly 11 characters, all caps. */
+
+
+#define FF_USE_FASTSEEK 0
+/* This option switches fast seek function. (0:Disable or 1:Enable) */
+
+#define FF_FASTFS 0
+#if FF_FASTFS
+#undef FF_USE_FASTSEEK
+#define FF_USE_FASTSEEK 1
+#endif
+/* This option switches fast access to chained clusters. (0:Disable or 1:Enable) */
+
+
+#define FF_SIMPLE_GPT 1
+/* This option switches support for the first GPT partition. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_EXPAND 0
+/* This option switches f_expand function. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_CHMOD 1
+/* This option switches attribute manipulation functions, f_chmod() and f_utime().
+/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
+
+
+#define FF_USE_LABEL 0
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/ (0:Disable or 1:Enable) */
+
+
+#define FF_USE_FORWARD 0
+/* This option switches f_forward() function. (0:Disable or 1:Enable) */
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_CODE_PAGE 850
+/* This option specifies the OEM code page to be used on the target system.
+/ Incorrect code page setting can cause a file open failure.
+/
+/ 437 - U.S.
+/ 720 - Arabic
+/ 737 - Greek
+/ 771 - KBL
+/ 775 - Baltic
+/ 850 - Latin 1
+/ 852 - Latin 2
+/ 855 - Cyrillic
+/ 857 - Turkish
+/ 860 - Portuguese
+/ 861 - Icelandic
+/ 862 - Hebrew
+/ 863 - Canadian French
+/ 864 - Arabic
+/ 865 - Nordic
+/ 866 - Russian
+/ 869 - Greek 2
+/ 932 - Japanese (DBCS)
+/ 936 - Simplified Chinese (DBCS)
+/ 949 - Korean (DBCS)
+/ 950 - Traditional Chinese (DBCS)
+/ 0 - Include all code pages above and configured by f_setcp()
+*/
+
+
+#define FF_USE_LFN 3
+#define FF_MAX_LFN 255
+/* The FF_USE_LFN switches the support for LFN (long file name).
+/
+/ 0: Disable LFN. FF_MAX_LFN has no effect.
+/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
+/ 2: Enable LFN with dynamic working buffer on the STACK.
+/ 3: Enable LFN with dynamic working buffer on the HEAP.
+/
+/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
+/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
+/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
+/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
+/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
+/ specification.
+/ When use stack for the working buffer, take care on stack overflow. When use heap
+/ memory for the working buffer, memory management functions, ff_memalloc() and
+/ ff_memfree() in ffsystem.c, need to be added to the project. */
+
+
+#define FF_LFN_UNICODE 0
+/* This option switches the character encoding on the API when LFN is enabled.
+/
+/ 0: ANSI/OEM in current CP (TCHAR = char)
+/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
+/ 2: Unicode in UTF-8 (TCHAR = char)
+/ 3: Unicode in UTF-32 (TCHAR = DWORD)
+/
+/ Also behavior of string I/O functions will be affected by this option.
+/ When LFN is not enabled, this option has no effect. */
+
+
+#define FF_LFN_BUF 255
+#define FF_SFN_BUF 12
+/* This set of options defines size of file name members in the FILINFO structure
+/ which is used to read out directory items. These values should be suffcient for
+/ the file names to read. The maximum possible length of the read file name depends
+/ on character encoding. When LFN is not enabled, these options have no effect. */
+
+
+#define FF_STRF_ENCODE 0
+/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
+/ f_putc(), f_puts and f_printf() convert the character encoding in it.
+/ This option selects assumption of character encoding ON THE FILE to be
+/ read/written via those functions.
+/
+/ 0: ANSI/OEM in current CP
+/ 1: Unicode in UTF-16LE
+/ 2: Unicode in UTF-16BE
+/ 3: Unicode in UTF-8
+*/
+
+
+#define FF_FS_RPATH 0
+/* This option configures support for relative path.
+/
+/ 0: Disable relative path and remove related functions.
+/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
+/ 2: f_getcwd() function is available in addition to 1.
+*/
+
+
+/*---------------------------------------------------------------------------/
+/ Drive/Volume Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_VOLUMES 1
+/* Number of volumes (logical drives) to be used. (1-10) */
+
+
+#define FF_STR_VOLUME_ID 0
+#define FF_VOLUME_STRS "sd"
+/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
+/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
+/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
+/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
+/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
+/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
+/ not defined, a user defined volume string table needs to be defined as:
+/
+/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
+/ Order is important. Any change to order, must also be reflected to diskio drive enum.
+*/
+
+
+#define FF_MULTI_PARTITION 0
+/* This option switches support for multiple volumes on the physical drive.
+/ By default (0), each logical drive number is bound to the same physical drive
+/ number and only an FAT volume found on the physical drive will be mounted.
+/ When this function is enabled (1), each logical drive number can be bound to
+/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
+/ funciton will be available. */
+
+
+#define FF_MIN_SS 512
+#define FF_MAX_SS 512
+/* This set of options configures the range of sector size to be supported. (512,
+/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
+/ harddisk. But a larger value may be required for on-board flash memory and some
+/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
+/ for variable sector size mode and disk_ioctl() function needs to implement
+/ GET_SECTOR_SIZE command. */
+
+
+#define FF_USE_TRIM 0
+/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
+/ To enable Trim function, also CTRL_TRIM command should be implemented to the
+/ disk_ioctl() function. */
+
+
+#define FF_FS_NOFSINFO 1
+/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
+/ option, and f_getfree() function at first time after volume mount will force
+/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
+/
+/ bit0=0: Use free cluster count in the FSINFO if available.
+/ bit0=1: Do not trust free cluster count in the FSINFO.
+/ bit1=0: Use last allocated cluster number in the FSINFO if available.
+/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
+*/
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_TINY 0
+/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
+/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
+/ Instead of private sector buffer eliminated from the file object, common sector
+/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
+
+
+#define FF_FS_EXFAT 1
+/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
+/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
+/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
+
+
+#define FF_FS_NORTC 1
+#define FF_NORTC_MON 1
+#define FF_NORTC_MDAY 1
+#define FF_NORTC_YEAR 2022
+/* The option FF_FS_NORTC switches timestamp function. If the system does not have
+/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
+/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
+/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
+/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
+/ added to the project to read current time form real-time clock. FF_NORTC_MON,
+/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
+/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
+
+
+#define FF_FS_LOCK 0
+/* The option FF_FS_LOCK switches file lock function to control duplicated file open
+/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
+/ is 1.
+/
+/ 0: Disable file lock function. To avoid volume corruption, application program
+/ should avoid illegal open, remove and rename to the open objects.
+/ >0: Enable file lock function. The value defines how many files/sub-directories
+/ can be opened simultaneously under file lock control. Note that the file
+/ lock control is independent of re-entrancy. */
+
+
+/* #include // O/S definitions */
+#define FF_FS_REENTRANT 0
+#define FF_FS_TIMEOUT 1000
+#define FF_SYNC_t HANDLE
+/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
+/ module itself. Note that regardless of this option, file access to different
+/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
+/ and f_fdisk() function, are always not re-entrant. Only file/directory access
+/ to the same volume is under control of this function.
+/
+/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
+/ 1: Enable re-entrancy. Also user provided synchronization handlers,
+/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
+/ function, must be added to the project. Samples are available in
+/ option/syscall.c.
+/
+/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
+/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
+/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
+/ included somewhere in the scope of ff.h. */
+
+
+
+/*--- End of configuration options ---*/
diff --git a/bdk/gfx/di.c b/bdk/gfx/di.c
deleted file mode 100644
index 09b0496..0000000
--- a/bdk/gfx/di.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 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 .
- */
-
-#include
-
-#include "di.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "di.inl"
-
-extern volatile nyx_storage_t *nyx_str;
-
-static u32 _display_id = 0;
-
-static void _display_panel_and_hw_end(bool no_panel_deinit);
-
-static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
-{
- u32 end = get_tmr_us() + timeout;
- while (get_tmr_us() < end && DSI(off) & mask)
- ;
- usleep(5);
-}
-
-static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
-{
- DSI(_DSIREG(DSI_WR_DATA)) = (param << 8) | cmd;
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
-
- if (wait)
- usleep(wait);
-}
-
-static void _display_dsi_read_rx_fifo(u32 *data)
-{
- u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
- for (u32 i = 0; i < fifo_count; i++)
- {
- // Read or Drain RX FIFO.
- if (data)
- data[i] = DSI(_DSIREG(DSI_RD_DATA));
- else
- (void)DSI(_DSIREG(DSI_RD_DATA));
- }
-}
-
-int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
-{
- int res = 0;
- u32 host_control = 0;
- u32 cmd_timeout = video_enabled ? 0 : 250000;
- u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
-
- // Drain RX FIFO.
- _display_dsi_read_rx_fifo(NULL);
-
- // Save host control and enable host cmd packets during video.
- if (video_enabled)
- {
- host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
-
- // Enable vblank interrupt.
- DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
-
- // Use the 4th line to transmit the host cmd packet.
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
-
- // Wait for vblank before starting the transfer.
- DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
- while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
- ;
- }
-
- // Set reply size.
- _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
- _display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
-
- // Request register read.
- _display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
- _display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
-
- // Transfer bus control to device for transmitting the reply.
- u32 high_speed = video_enabled ? DSI_HOST_CONTROL_HS : 0;
- DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC | high_speed;
- _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
-
- // Wait a bit for the reply.
- usleep(5000);
-
- // Read RX FIFO.
- _display_dsi_read_rx_fifo(fifo);
-
- // Parse packet and copy over the data.
- if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
- {
- // Act based on reply type.
- switch (fifo[1] & 0xFF)
- {
- case GEN_LONG_RD_RES:
- case DCS_LONG_RD_RES:
- memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
- break;
-
- case GEN_1_BYTE_SHORT_RD_RES:
- case DCS_1_BYTE_SHORT_RD_RES:
- memcpy(data, &fifo[2], 1);
- break;
-
- case GEN_2_BYTE_SHORT_RD_RES:
- case DCS_2_BYTE_SHORT_RD_RES:
- memcpy(data, &fifo[2], 2);
- break;
- case ACK_ERROR_RES:
- default:
- res = 1;
- break;
- }
- }
-
- // Disable host cmd packets during video and restore host control.
- if (video_enabled)
- {
- // Wait for vblank before reseting sync points.
- DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
- while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
- ;
-
- // Reset all states of syncpt block.
- DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
- usleep(300); // Stabilization delay.
-
- // Clear syncpt block reset.
- DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
- usleep(300); // Stabilization delay.
-
- // Restore video mode and host control.
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
- DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
-
- // Disable and clear vblank interrupt.
- DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
- DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
- }
-
- return res;
-}
-
-void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
-{
- u32 host_control;
- u32 fifo32[DSI_STATUS_RX_FIFO_SIZE] = {0};
- u8 *fifo8 = (u8 *)fifo32;
-
- // Enable host cmd packets during video and save host control.
- if (video_enabled)
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
- host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
-
- // Enable host transfer trigger.
- DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_TX_TRIG_HOST;
-
- switch (len)
- {
- case 0:
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
- break;
-
- case 1:
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
- break;
-
- default:
- fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
- fifo8[4] = cmd;
- memcpy(&fifo8[5], data, len);
- len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
- for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
- DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
- break;
- }
-
- // Wait for the write to happen.
- _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST);
-
- // Disable host cmd packets during video and restore host control.
- if (video_enabled)
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
- DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
-}
-
-void display_init()
-{
- // Check if display is already initialized.
- if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & BIT(CLK_L_DISP1))
- _display_panel_and_hw_end(true);
-
- // Get Chip ID.
- bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
-
- // T210B01: Power on SD2 regulator for supplying LDO0.
- if (!tegra_t210)
- {
- // Set SD2 regulator voltage.
- max77620_regulator_set_voltage(REGULATOR_SD2, 1325000);
-
- // Set slew rate and enable SD2 regulator.
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
- max77620_regulator_enable(REGULATOR_SD2, 1);
-
- }
-
- // Enable power to display panel controller.
- max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.
- if (tegra_t210)
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7,
- MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); // T210: LD0 -> GPIO7 -> Display panel.
-
- // Enable Display Interface specific clocks.
- CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
-
- CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
-
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
-
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
-
- // Bring every IO rail out of deep power down.
- PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
- PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
-
- // Configure LCD pins.
- PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
- PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
- PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
-
- // Configure Backlight pins.
- PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
- PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
-
- // Set LCD +-5V pins mode and direction
- gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE);
-
- // Enable LCD power.
- gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable.
- usleep(10000);
- gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable.
- usleep(10000);
-
- // Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST).
- gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
-
- // Enable Backlight power.
- gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
-
- // Power up supply regulator for display interface.
- MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
-
- if (!tegra_t210)
- {
- MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
- APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
- }
-
- // Set DISP1 clock source and parent clock.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT.
- u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 96 MHz.
- CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
-
- if (tegra_t210)
- {
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK.
- }
- else
- {
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // PLLD_ENABLE_CLK.
- }
-
- // Setup Display Interface initial window configuration.
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
-
- // Setup display communication interfaces.
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8);
- if (tegra_t210)
- DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
- else
- DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part2, 14);
- if (!tegra_t210)
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part3_t210b01, 7);
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part4, 10);
- DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part5, 12);
- DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
- exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part6, 14);
- usleep(10000);
-
- // Enable LCD Reset.
- gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
- usleep(60000);
-
- // Setup DSI device takeover timeout.
- DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
-
-#if 0
- // Get Display ID.
- _display_id = 0xCCCCCC;
- display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED);
-#else
- // Set reply size.
- _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0);
- _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
-
- // Request register read.
- _display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0);
- _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
-
- // Transfer bus control to device for transmitting the reply.
- DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
- _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
-
- // Wait a bit for the reply.
- usleep(5000);
-
- // MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 x u32.
- for (u32 i = 0; i < 3; i++)
- _display_id = DSI(_DSIREG(DSI_RD_DATA)) & 0xFFFFFF; // Skip ack and msg type info and get the payload (display id).
-#endif
- // Save raw Display ID to Nyx storage.
- nyx_str->info.disp_id = _display_id;
-
- // Decode Display ID.
- _display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
-
- if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
- _display_id = PANEL_JDI_XXX062M;
-
- // Initialize display panel.
- switch (_display_id)
- {
- case PANEL_JDI_XXX062M:
- exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
- break;
-
- case PANEL_INL_P062CCA_AZ1:
- case PANEL_AUO_A062TAN01:
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
-
- // Unlock extension cmds.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
- usleep(5000);
-
- // Set Power control.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
- if (_display_id == PANEL_INL_P062CCA_AZ1)
- DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
- else // PANEL_AUO_A062TAN01.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
- DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
- usleep(5000);
- break;
-
- case PANEL_INL_2J055IA_27A:
- case PANEL_AUO_A055TAN01:
- case PANEL_V40_55_UNK:
- default: // Allow spare part displays to work.
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
- break;
- }
-
- // Unblank display.
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
-
- // Configure PLLD for DISP1.
- plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 230.4 MHz.
- CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
-
- if (tegra_t210)
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP
- else
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
- CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
-
- // Finalize DSI configuration.
- DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
- DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
- exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19);
- // Set pixel clock dividers: 230.4 / 3 / 1 = 76.8 MHz. 60 Hz.
- DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
- exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
- usleep(10000);
-
- // Calibrate display communication pads.
- u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko.
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4);
- for (u32 i = 0; i < loops; i++)
- {
- // Set MIPI bias pad config.
- MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
- MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
-
- // Set pad trimmers and set MIPI DSI cal offsets.
- if (tegra_t210)
- {
- exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210, 4);
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210, 4);
- }
- else
- {
- exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210b01, 7);
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210b01, 4);
- }
-
- // Set the rest of MIPI cal offsets and apply calibration.
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
- }
- usleep(10000);
-
- // Enable video display controller.
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113);
-}
-
-void display_backlight_pwm_init()
-{
- clock_enable_pwm();
-
- PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
-
- PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
- gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
-}
-
-void display_backlight(bool enable)
-{
- gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
-}
-
-void display_backlight_brightness(u32 brightness, u32 step_delay)
-{
- u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
- if (brightness == old_value)
- return;
-
- if (brightness > 255)
- brightness = 255;
-
- if (old_value < brightness)
- {
- for (u32 i = old_value; i < brightness + 1; i++)
- {
- PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
- usleep(step_delay);
- }
- }
- else
- {
- for (u32 i = old_value; i > brightness; i--)
- {
- PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
- usleep(step_delay);
- }
- }
- if (!brightness)
- PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
-}
-
-static void _display_panel_and_hw_end(bool no_panel_deinit)
-{
- if (no_panel_deinit)
- goto skip_panel_deinit;
-
- display_backlight_brightness(0, 1000);
-
- // Enable host cmd packets during video.
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
-
- // Blank display.
- DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
-
- // Propagate changes to all register buffers and disable host cmd packets during video.
- DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
- DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
-
- // De-initialize video controller.
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17);
- exec_cfg((u32 *)DSI_BASE, _display_dsi_timing_deinit_config, 16);
- usleep(10000);
-
- // De-initialize display panel.
- switch (_display_id)
- {
- case PANEL_JDI_XXX062M:
- exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
- break;
-
- case PANEL_AUO_A062TAN01:
- exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
- break;
-
- case PANEL_INL_2J055IA_27A:
- case PANEL_AUO_A055TAN01:
- case PANEL_V40_55_UNK:
- // Unlock extension cmds.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
- usleep(5000);
-
- // Set Power control.
- DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
- if (_display_id == PANEL_INL_2J055IA_27A)
- DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
- else if (_display_id == PANEL_AUO_A055TAN01)
- DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
- else // PANEL_V40_55_UNK.
- DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40).
- if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01)
- {
- // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
- DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
- DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
- }
- else // PANEL_V40_55_UNK.
- {
- // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG).
- DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209;
- DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
- }
- DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
- usleep(5000);
- break;
-
- case PANEL_INL_P062CCA_AZ1:
- default:
- break;
- }
-
- // Blank - powerdown.
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000);
-
-skip_panel_deinit:
- // Disable LCD power pins.
- gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
- usleep(10000);
- gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable.
- usleep(10000);
- gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable.
- usleep(10000);
-
- // Disable Display Interface specific clocks.
- CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
- CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
-
- // Power down pads.
- DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
- DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
-
- // Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
- gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
- PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;
- PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
-}
-
-void display_end() { _display_panel_and_hw_end(false); };
-
-u16 display_get_decoded_panel_id()
-{
- return _display_id;
-}
-
-void display_set_decoded_panel_id(u32 id)
-{
- // Decode Display ID.
- _display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
-
- if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
- _display_id = PANEL_JDI_XXX062M;
-}
-
-void display_color_screen(u32 color)
-{
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
-
- // Configure display to show single color.
- DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
- usleep(35000);
-
- display_backlight(true);
-}
-
-u32 *display_init_framebuffer_pitch()
-{
- // Sanitize framebuffer area.
- memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
-
- // This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
- usleep(35000);
-
- return (u32 *)IPL_FB_ADDRESS;
-}
-
-u32 *display_init_framebuffer_pitch_inv()
-{
- // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
-
- usleep(35000);
-
- return (u32 *)NYX_FB_ADDRESS;
-}
-
-u32 *display_init_framebuffer_block()
-{
- // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34);
-
- usleep(35000);
-
- return (u32 *)NYX_FB_ADDRESS;
-}
-
-u32 *display_init_framebuffer_log()
-{
- // This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
-
- return (u32 *)LOG_FB_ADDRESS;
-}
-
-void display_activate_console()
-{
- DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
- DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
- DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
-
- for (u32 i = 0xFF80; i < 0x10000; i++)
- {
- DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
- usleep(1000);
- }
-
- DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
-}
-
-void display_deactivate_console()
-{
- DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
-
- for (u32 i = 0xFFFF; i > 0xFF7F; i--)
- {
- DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
- usleep(500);
- }
-
- DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
- DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD.
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
-}
-
-void display_init_cursor(void *crs_fb, u32 size)
-{
- // Setup cursor.
- DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
- DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) =
- CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
-
- DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
-
- // Arm and activate changes.
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
-}
-
-void display_set_pos_cursor(u32 x, u32 y)
-{
- DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
-
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
-}
-
-void display_deinit_cursor()
-{
- DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
- DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
-}
diff --git a/bdk/ianos/elfload/elf.h b/bdk/ianos/elfload/elf.h
index 196cf87..2a7111e 100644
--- a/bdk/ianos/elfload/elf.h
+++ b/bdk/ianos/elfload/elf.h
@@ -29,33 +29,34 @@
#ifndef ELF_H
#define ELF_H
-#include
-typedef uint8_t Elf_Byte;
+#include
-typedef uint32_t Elf32_Addr; /* Unsigned program address */
-typedef uint32_t Elf32_Off; /* Unsigned file offset */
-typedef int32_t Elf32_Sword; /* Signed large integer */
-typedef uint32_t Elf32_Word; /* Unsigned large integer */
-typedef uint16_t Elf32_Half; /* Unsigned medium integer */
+typedef u8 Elf_Byte;
-typedef uint64_t Elf64_Addr;
-typedef uint64_t Elf64_Off;
-typedef int32_t Elf64_Shalf;
+typedef u32 Elf32_Addr; /* Unsigned program address */
+typedef u32 Elf32_Off; /* Unsigned file offset */
+typedef s32 Elf32_Sword; /* Signed large integer */
+typedef u32 Elf32_Word; /* Unsigned large integer */
+typedef u16 Elf32_Half; /* Unsigned medium integer */
+
+typedef u64 Elf64_Addr;
+typedef u64 Elf64_Off;
+typedef s32 Elf64_Shalf;
#ifdef __alpha__
-typedef int64_t Elf64_Sword;
-typedef uint64_t Elf64_Word;
+typedef s64 Elf64_Sword;
+typedef u64 Elf64_Word;
#else
-typedef int32_t Elf64_Sword;
-typedef uint32_t Elf64_Word;
+typedef s32 Elf64_Sword;
+typedef u32 Elf64_Word;
#endif
-typedef int64_t Elf64_Sxword;
-typedef uint64_t Elf64_Xword;
+typedef s64 Elf64_Sxword;
+typedef u64 Elf64_Xword;
-typedef uint32_t Elf64_Half;
-typedef uint16_t Elf64_Quarter;
+typedef u32 Elf64_Half;
+typedef u16 Elf64_Quarter;
/*
* e_ident[] identification indexes
@@ -376,7 +377,7 @@ typedef struct
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF)
-#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t))
+#define ELF64_R_INFO(s, t) (((s) << 32) + (u32)(t))
#if defined(__mips64__) && defined(__MIPSEL__)
/*
@@ -389,7 +390,7 @@ typedef struct
#undef ELF64_R_INFO
#define ELF64_R_TYPE(info) (swap32((info) >> 32))
#define ELF64_R_SYM(info) ((info)&0xFFFFFFFF)
-#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))
+#define ELF64_R_INFO(s, t) (((u64)swap32(t) << 32) + (u32)(s))
#endif /* __mips64__ && __MIPSEL__ */
/* Program Header */
@@ -444,7 +445,7 @@ typedef struct
/* Dynamic structure */
typedef struct
{
- Elf32_Sword d_tag; /* controls meaning of d_val */
+ Elf32_Word d_tag; /* controls meaning of d_val */
union {
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
diff --git a/bdk/ianos/elfload/elfload.c b/bdk/ianos/elfload/elfload.c
index 16f8200..daf561a 100644
--- a/bdk/ianos/elfload/elfload.c
+++ b/bdk/ianos/elfload/elfload.c
@@ -25,7 +25,7 @@ el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)
}
#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))
-el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)
+el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i)
{
el_status rv = EL_OK;
for (; *i < ctx->ehdr.e_phnum; (*i)++)
@@ -44,7 +44,7 @@ el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)
}
#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize))
-el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i)
+el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, u32 type, unsigned *i)
{
el_status rv = EL_OK;
@@ -213,7 +213,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloc)
return rv;
}
-el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)
+el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 tag)
{
el_status rv = EL_OK;
size_t ndyn = ctx->dynsize / sizeof(Elf_Dyn);
@@ -231,7 +231,7 @@ el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)
return EL_OK;
}
-el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type)
+el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type)
{
el_status rv = EL_OK;
diff --git a/bdk/ianos/elfload/elfload.h b/bdk/ianos/elfload/elfload.h
index 2b9bb67..0a73e05 100644
--- a/bdk/ianos/elfload/elfload.h
+++ b/bdk/ianos/elfload/elfload.h
@@ -22,8 +22,6 @@
#include "elfarch.h"
#include "elf.h"
-#include
-
#ifdef DEBUG
#include
#define EL_DEBUG(format, ...) \
@@ -100,7 +98,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloccb);
* If the end of the phdrs table was reached, *i is set to -1 and the contents
* of *phdr are undefined
*/
-el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i);
+el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i);
/* Relocate the loaded executable */
el_status el_relocate(el_ctx *ctx);
@@ -108,7 +106,7 @@ el_status el_relocate(el_ctx *ctx);
/* find a dynamic table entry
* returns the entry on success, dyn->d_tag = DT_NULL on failure
*/
-el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type);
+el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 type);
typedef struct
{
@@ -122,6 +120,6 @@ typedef struct
* pass DT_REL or DT_RELA for type
* sets ri->entrysize = 0 if not found
*/
-el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type);
+el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type);
#endif
diff --git a/bdk/ianos/elfload/elfreloc_aarch64.c b/bdk/ianos/elfload/elfreloc_aarch64.c
index bbb0ce4..736ad46 100644
--- a/bdk/ianos/elfload/elfreloc_aarch64.c
+++ b/bdk/ianos/elfload/elfreloc_aarch64.c
@@ -23,9 +23,9 @@
el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)
{
- uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
- uint32_t type = ELF_R_TYPE(rel->r_info);
- uint32_t sym = ELF_R_SYM(rel->r_info);
+ uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr);
+ u32 type = ELF_R_TYPE(rel->r_info);
+ u32 sym = ELF_R_SYM(rel->r_info);
switch (type)
{
@@ -53,9 +53,9 @@ el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
{
- uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);
- uint32_t type = ELF_R_TYPE(rel->r_info);
- uint32_t sym = ELF_R_SYM(rel->r_info);
+ uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr);
+ u32 type = ELF_R_TYPE(rel->r_info);
+ u32 sym = ELF_R_SYM(rel->r_info);
switch (type)
{
diff --git a/bdk/ianos/elfload/elfreloc_arm.c b/bdk/ianos/elfload/elfreloc_arm.c
index 8b905cb..77ce654 100644
--- a/bdk/ianos/elfload/elfreloc_arm.c
+++ b/bdk/ianos/elfload/elfreloc_arm.c
@@ -20,9 +20,9 @@
el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)
{
- uint32_t sym = ELF_R_SYM(rel->r_info); // Symbol offset
- uint32_t type = ELF_R_TYPE(rel->r_info); // Relocation Type
- uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr
+ u32 sym = ELF_R_SYM(rel->r_info); // Symbol offset
+ u32 type = ELF_R_TYPE(rel->r_info); // Relocation Type
+ uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr); // Target Addr
#if 0 // For later symbol usage
Elf32_Sym *elfSym;
diff --git a/bdk/ianos/ianos.c b/bdk/ianos/ianos.c
index 5eca1b6..99a996d 100644
--- a/bdk/ianos/ianos.c
+++ b/bdk/ianos/ianos.c
@@ -21,7 +21,8 @@
#include "elfload/elfload.h"
#include
#include
-#include
+#include
+#include
#include
#include
@@ -43,6 +44,10 @@ static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
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);
}
@@ -69,19 +74,16 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
el_ctx ctx;
uintptr_t epaddr = 0;
- if (!sd_mount())
- goto elfLoadFinalOut;
-
// Read library.
fileBuf = sd_file_read(path, NULL);
if (!fileBuf)
- goto elfLoadFinalOut;
+ goto out;
ctx.pread = _ianos_read_cb;
if (el_init(&ctx))
- goto elfLoadFinalOut;
+ goto out;
// Set our relocated library's buffer.
switch (type & 0xFFFF)
@@ -95,15 +97,15 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
}
if (!elfBuf)
- goto elfLoadFinalOut;
+ goto out;
// Load and relocate library.
ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;
if (el_load(&ctx, _ianos_alloc_cb))
- goto elfFreeOut;
+ goto out_free;
if (el_relocate(&ctx))
- goto elfFreeOut;
+ goto out_free;
// Launch.
epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;
@@ -111,11 +113,11 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
_ianos_call_ep(ep, moduleConfig);
-elfFreeOut:
+out_free:
free(fileBuf);
elfBuf = NULL;
fileBuf = NULL;
-elfLoadFinalOut:
+out:
return epaddr;
}
\ No newline at end of file
diff --git a/bdk/input/als.c b/bdk/input/als.c
index 82a4a34..277f0d5 100644
--- a/bdk/input/als.c
+++ b/bdk/input/als.c
@@ -17,102 +17,138 @@
*/
#include "als.h"
-#include
+#include
#include
#include
#include
#include
-#define HOS_GAIN BH1730_GAIN_64X
-#define HOS_ITIME 38
+#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
+#define BH1730_DEFAULT_ICYCLE 38
-void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime)
+#define BH1730_INTERNAL_CLOCK_NS 2800
+#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
+#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
+
+#define BH1730_DEFAULT_ITIME_MS 100
+
+#define BH1730_LUX_MULTIPLIER 3600
+#define BH1730_LUX_MULTIPLIER_AULA 1410
+
+#define BH1730_LUX_MAX 100000
+
+typedef struct _opt_win_cal_t
{
- 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 - itime));
+ u32 rc;
+ u32 cv;
+ u32 ci;
+} opt_win_cal_t;
- als_val->gain = gain;
- als_val->itime = itime;
+// Nintendo Switch Icosa/Iowa Optical Window calibration.
+static const opt_win_cal_t opt_win_cal_default[] = {
+ { 500, 5002, 7502 },
+ { 754, 2250, 2000 },
+ { 1029, 1999, 1667 },
+ { 1373, 884, 583 },
+ { 1879, 309, 165 }
+};
+
+// Nintendo Switch Aula Optical Window calibration.
+static const opt_win_cal_t opt_win_cal_aula[] = {
+ { 231, 9697, 30300 },
+ { 993, 3333, 2778 },
+ { 1478, 1621, 1053 },
+ { 7500, 81, 10 }
+};
+
+static const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
+
+void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
+{
+ if (gain > BH1730_GAIN_128X)
+ gain = BH1730_GAIN_128X;
+
+ if (!cycle)
+ cycle = 1;
+
+ 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));
+
+ als_ctxt->gain = gain;
+ als_ctxt->cycle = cycle;
}
-void get_als_lux(als_table_t *als_val)
+void get_als_lux(als_ctxt_t *als_ctxt)
{
u32 data[2];
- float pre_gain_lux;
- float visible_light;
- float ir_light;
- float light_ratio;
+ u32 vi_light;
+ u32 ir_light;
+ u64 lux = 0;
+ u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
- u8 adc_ready = 0;
- u8 retries = 100;
-
- const float als_gain_idx_tbl[4] = { 1.0, 2.0, 64.0, 128.0 };
- const float als_norm_res = 100.0;
- const float als_multiplier = 3.6;
- const float als_tint = 2.7;
-
- // Wait for ADC to prepare new data.
- while (!(adc_ready & BH1730_CTL_ADC_VALID) && retries)
- {
- retries--;
- adc_ready = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG));
- }
-
- // Get visible and ir light raw data.
+ // Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
- (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
+ (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
- (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
+ (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
- als_val->over_limit = data[0] > 65534 || data[1] > 65534;
- als_val->vi_light = data[0];
- als_val->ir_light = data[1];
+ vi_light = data[0];
+ ir_light = data[1];
- if (!data[0] || !retries)
+ als_ctxt->vi_light = vi_light;
+ als_ctxt->ir_light = ir_light;
+ als_ctxt->over_limit = vi_light > 65534 || ir_light > 65534;
+
+ if (!vi_light)
{
- als_val->lux = 0.0;
+ als_ctxt->lux = 0;
return;
}
- visible_light = (float)data[0];
- ir_light = (float)data[1];
- light_ratio = (float)data[1] / (float)data[0];
+ // Set calibration parameters.
+ u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
+ u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
+ const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
- // The following are specific to the light filter Switch uses.
- if (light_ratio < 0.5)
- pre_gain_lux = visible_light * 5.002 - ir_light * 7.502;
- else if (light_ratio < 0.754)
- pre_gain_lux = visible_light * 2.250 - ir_light * 2.000;
- else if (light_ratio < 1.029)
- pre_gain_lux = visible_light * 1.999 - ir_light * 1.667;
- else if (light_ratio < 1.373)
- pre_gain_lux = visible_light * 0.884 - ir_light * 0.583;
- else if (light_ratio < 1.879)
- pre_gain_lux = visible_light * 0.309 - ir_light * 0.165;
- else pre_gain_lux = 0.0;
+ // Apply optical window calibration coefficients.
+ for (u32 i = 0; i < opt_win_cal_count; i++)
+ {
+ if (1000 * ir_light / vi_light < opt_win_cal[i].rc)
+ {
+ lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
+ break;
+ }
+ }
- als_val->lux = (pre_gain_lux / als_gain_idx_tbl[als_val->gain]) * (als_norm_res / ((float)als_val->itime * als_tint)) * als_multiplier;
+ lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
+ lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
+ lux /= 1000;
+
+ if (lux > BH1730_LUX_MAX)
+ lux = BH1730_LUX_MAX;
+
+ als_ctxt->lux = lux;
}
-u8 als_init(als_table_t *als_val)
+u8 als_power_on(als_ctxt_t *als_ctxt)
{
+ // Enable power to ALS IC.
+ max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
+ max7762x_regulator_enable(REGULATOR_LDO6, true);
+
+ // Init I2C2.
pinmux_config_i2c(I2C_2);
clock_enable_i2c(I2C_2);
i2c_init(I2C_2);
- max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
- (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
-
+ // Initialize ALS.
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
- i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), HOS_GAIN);
- i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - HOS_ITIME));
- i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
- als_val->gain = HOS_GAIN;
- als_val->itime = HOS_ITIME;
+ set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
+
+ i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
return id;
}
diff --git a/bdk/input/als.h b/bdk/input/als.h
index 09adcb6..0ce0956 100644
--- a/bdk/input/als.h
+++ b/bdk/input/als.h
@@ -48,18 +48,18 @@
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
-typedef struct _als_table_t
+typedef struct _als_ctxt_t
{
- float lux;
+ u32 lux;
bool over_limit;
- u32 vi_light;
- u32 ir_light;
- u8 gain;
- u8 itime;
-} als_table_t;
+ u32 vi_light;
+ u32 ir_light;
+ u8 gain;
+ u8 cycle;
+} als_ctxt_t;
-void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
-void get_als_lux(als_table_t *als_val);
-u8 als_init(als_table_t *als_val);
+void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
+void get_als_lux(als_ctxt_t *als_ctxt);
+u8 als_power_on(als_ctxt_t *als_ctxt);
#endif /* __ALS_H_ */
diff --git a/bdk/input/joycon.c b/bdk/input/joycon.c
index 7be5f2d..5e3243e 100644
--- a/bdk/input/joycon.c
+++ b/bdk/input/joycon.c
@@ -1,7 +1,7 @@
/*
* Joy-Con UART driver for Nintendo Switch
*
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2024 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,14 +22,13 @@
#include
#include
#include
-#include
#include
#include
#include
#include
+#include
#include
#include
-#include
// For disabling driver when logging is enabled.
#include
@@ -39,8 +38,18 @@
#define JC_WIRED_INIT_REPLY 0x94
#define JC_INIT_HANDSHAKE 0xA5
-#define JC_WIRED_CMD_MAC 0x01
-#define JC_WIRED_CMD_10 0x10
+#define JC_HORI_INPUT_RPT_CMD 0x9A
+#define JC_HORI_INPUT_RPT 0x00
+
+#define JC_WIRED_CMD_GET_INFO 0x01
+#define JC_WIRED_CMD_SET_CHARGER 0x02
+#define JC_WIRED_CMD_GET_CHARGER 0x03
+#define JC_WIRED_CMD_BATT_VOLT 0x06
+#define JC_WIRED_CMD_WAKE_REASON 0x07
+#define JC_WIRED_CMD_HID_CONN 0x10
+#define JC_WIRED_CMD_HID_DISC 0x11
+#define JC_WIRED_CMD_SET_HIDRATE 0x12 // Output report rate.
+#define JC_WIRED_CMD_SET_BRATE 0x20
#define JC_HID_OUTPUT_RPT 0x01
#define JC_HID_RUMBLE_RPT 0x10
@@ -58,47 +67,124 @@
#define JC_HID_SUBCMD_RUMBLE_CTL 0x48
#define JC_HID_SUBCMD_SND_RUMBLE 0xFF
+#define JC_SIO_OUTPUT_RPT 0x91
+#define JC_SIO_INPUT_RPT 0x92
+#define JC_SIO_CMD_ACK 0x80
+
+#define JC_SIO_CMD_INIT 0x01
+#define JC_SIO_CMD_UNK02 0x02
+#define JC_SIO_CMD_VER_RPT 0x03
+#define JC_SIO_CMD_UNK20 0x20 // JC_WIRED_CMD_SET_BRATE
+#define JC_SIO_CMD_UNK21 0x21
+#define JC_SIO_CMD_UNK22 0x22
+#define JC_SIO_CMD_UNK40 0x40
+#define JC_SIO_CMD_STATUS 0x41
+#define JC_SIO_CMD_IAP_VER 0x42
+
+
#define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status.
#define JC_BTN_MASK_R 0x0056FF
-#define JC_ID_L 1
-#define JC_ID_R 2
+#define JC_ID_L 0x01 // Joycon (L). Mask for Hori (L).
+#define JC_ID_R 0x02 // Joycon (R). Mask for Hori (R).
+#define JC_ID_HORI 0x20 // Mask for Hori. Actual ids: 0x21, 0x22.
+
+#define JC_CRC8_POLY 0x8D
+
+enum
+{
+ JC_STATE_START = 0,
+ JC_STATE_HANDSHAKED = 1,
+ JC_STATE_BRATE_CHANGED = 2,
+ JC_STATE_BRATE_OK = 3,
+ JC_STATE_INIT_DONE = 4
+};
enum
{
JC_BATT_EMTPY = 0,
- JC_BATT_CRIT = 2,
- JC_BATT_LOW = 4,
- JC_BATT_MID = 6,
- JC_BATT_FULL = 8
+ JC_BATT_CRIT = 1,
+ JC_BATT_LOW = 2,
+ JC_BATT_MID = 3,
+ JC_BATT_FULL = 4
};
-static const u8 init_jc[] = {
+static const u8 sio_init[] = {
+ JC_SIO_OUTPUT_RPT, JC_SIO_CMD_INIT,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x95
+};
+
+static const u8 sio_set_rpt_version[] = {
+ JC_SIO_OUTPUT_RPT, JC_SIO_CMD_VER_RPT,
+ // old fw: 0x00, 0x0D (0.13). New 3.4.
+ // force_update_en: 0x01
+ 0x00, 0x00, 0x03, 0x04, 0x00, 0xDA
+};
+
+// Every 8ms.
+static const u8 sio_pad_status[] = {
+ JC_SIO_OUTPUT_RPT, JC_SIO_CMD_STATUS,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0
+};
+
+static const u8 init_wake[] = {
0xA1, 0xA2, 0xA3, 0xA4
};
static const u8 init_handshake[] = {
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
JC_INIT_HANDSHAKE, 0x02, // Wired cmd and wired subcmd.
- 0x01, 0x7E, 0x00, 0x00, 0x00 // Wired subcmd data.
+ 0x01, 0x7E, 0x00, 0x00, 0x00 // Wired subcmd data and crc.
};
static const u8 init_get_info[] = {
- 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
- JC_WIRED_CMD, JC_WIRED_CMD_MAC, // Wired cmd and subcmd.
- 0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data.
+ 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
+ JC_WIRED_CMD, JC_WIRED_CMD_GET_INFO, // Wired cmd and subcmd.
+ 0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data and crc.
};
-static const u8 init_finilize[] = {
- 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
- JC_WIRED_CMD, JC_WIRED_CMD_10, // Wired cmd and subcmd.
- 0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data.
+static const u8 init_switch_brate[] = {
+ 0x19, 0x01, 0x03, 0x0F, 0x00, // Uart header.
+ JC_WIRED_CMD, JC_WIRED_CMD_SET_BRATE, // Wired cmd and subcmd.
+ 0x08, 0x00, 0x00, 0xBD, 0xB1, // Wired subcmd data, data crc and crc.
+ // Baudrate 3 megabaud.
+ 0xC0, 0xC6, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 init_hid_disconnect[] = {
+ 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
+ JC_WIRED_CMD, JC_WIRED_CMD_HID_DISC, // Wired cmd and subcmd.
+ 0x00, 0x00, 0x00, 0x00, 0x0E // Wired subcmd data and crc.
+};
+
+static const u8 init_set_hid_rate[] = {
+ 0x19, 0x01, 0x03, 0x0B, 0x00, // Uart header.
+ JC_WIRED_CMD, JC_WIRED_CMD_SET_HIDRATE, // Wired cmd and subcmd.
+ 0x04, 0x00, 0x00, 0x12, 0xA6, // Wired subcmd data, data crc and crc.
+ // Output report rate 15 ms.
+ 0x0F, 0x00, 0x00, 0x00
+
+ // 5 ms.
+ // 0x04, 0x00, 0x00, 0x0E, 0xD5,
+ // 0x05, 0x00, 0x00, 0x00
+};
+
+static const u8 init_hid_connect[] = {
+ 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
+ JC_WIRED_CMD, JC_WIRED_CMD_HID_CONN, // Wired cmd and subcmd.
+ 0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data and crc.
};
static const u8 nx_pad_status[] = {
0x19, 0x01, 0x03, 0x08, 0x00, // Uart header.
JC_WIRED_HID, 0x00, // Wired cmd and hid cmd.
- 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data.
+ 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data, data crc and crc.
+};
+
+static const u8 hori_pad_status[] = {
+ 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
+ JC_HORI_INPUT_RPT_CMD, 0x01, // Hori cmd and hori subcmd.
+ 0x00, 0x00, 0x00, 0x00, 0x48 // Hori cmd data and crc.
};
typedef struct _jc_uart_hdr_t
@@ -136,8 +222,8 @@ typedef struct _jc_hid_in_rpt_t
{
u8 cmd;
u8 pkt_id;
- u8 conn_info:4;
- u8 batt_info:4;
+ u8 conn_info:4; // Connection detect.
+ u8 batt_info:4; // Power info.
u8 btn_right;
u8 btn_shared;
u8 btn_left;
@@ -147,7 +233,7 @@ typedef struct _jc_hid_in_rpt_t
u8 stick_h_right;
u8 stick_m_right;
u8 stick_v_right;
- u8 vib_decider;
+ u8 vib_decider; // right:4, left:4 (bit3 en, bit2-0 buffer avail).
u8 submcd_ack;
u8 subcmd;
u8 subcmd_data[];
@@ -172,36 +258,232 @@ typedef struct _jc_hid_in_pair_data_t
u8 pad1;
} jc_hid_in_pair_data_t;
+typedef struct _jc_sio_out_rpt_t
+{
+ u8 cmd;
+ u8 subcmd;
+ u16 payload_size;
+ u8 data[2];
+ u8 crc_payload;
+ u8 crc_hdr;
+ u8 payload[];
+} jc_sio_out_rpt_t;
+
+typedef struct _jc_sio_in_rpt_t
+{
+ u8 cmd;
+ u8 ack;
+ u16 payload_size;
+ u8 status;
+ u8 unk;
+ u8 crc_payload;
+ u8 crc_hdr;
+ u8 payload[];
+} jc_sio_in_rpt_t;
+
+typedef struct _jc_hid_in_sixaxis_rpt_t
+{
+ s16 acc_x;
+ s16 acc_y;
+ s16 acc_z;
+ s16 gyr_x;
+ s16 gyr_y;
+ s16 gyr_z;
+} __attribute__((packed)) jc_hid_in_sixaxis_rpt_t;
+
+typedef struct _jc_sio_hid_in_rpt_t
+{
+ u8 type;
+ u8 pkt_id;
+ u8 unk;
+ u8 btn_right;
+ u8 btn_shared;
+ u8 btn_left;
+ u8 stick_h_left;
+ u8 stick_m_left;
+ u8 stick_v_left;
+ u8 stick_h_right;
+ u8 stick_m_right;
+ u8 stick_v_right;
+ u8 siaxis_rpt; // bit0-3: report num. bit4-7: imu type.
+ // Each report is 800 us?
+ jc_hid_in_sixaxis_rpt_t sixaxis[15];
+} jc_sio_hid_in_rpt_t;
+
typedef struct _joycon_ctxt_t
{
- u8 buf[0x100]; //FIXME: If heap is used, dumping breaks.
- u8 uart;
- u8 type;
- u8 mac[6];
- u32 hw_init_done;
+ u8 buf[0x100]; //FIXME: If heap is used, dumping breaks.
+ u8 uart;
+ u8 type;
+ u8 state;
u32 last_received_time;
u32 last_status_req_time;
- u8 rumble_sent;
- u8 connected;
+ u8 mac[6];
+ u8 pkt_id;
+ u8 rumble_sent;
+ u8 connected;
+ u8 detected;
+ u8 sio_mode;
} joycon_ctxt_t;
-static joycon_ctxt_t jc_l;
-static joycon_ctxt_t jc_r;
+static joycon_ctxt_t jc_l = {0};
+static joycon_ctxt_t jc_r = {0};
static bool jc_init_done = false;
-static u32 hid_pkt_inc = 0;
static jc_gamepad_rpt_t jc_gamepad;
-void jc_power_supply(u8 uart, bool enable);
-
-void joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
+static u8 _jc_crc(const u8 *data, u16 len, u8 init)
{
- uart_send(uart_port, buf, size);
- uart_wait_idle(uart_port, UART_TX_IDLE);
+ u8 crc = init;
+ for (u16 i = 0; i < len; i++)
+ {
+ crc ^= data[i];
+ for (u16 j = 0; j < 8; j++)
+ {
+ if ((crc & 0x80) != 0)
+ crc = (u8)((crc << 1) ^ JC_CRC8_POLY);
+ else
+ crc <<= 1;
+ }
+ }
+ return crc;
}
-static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size)
+static void _jc_power_supply(u8 uart, bool enable)
+{
+ if (enable)
+ {
+ if (regulator_5v_get_dev_enabled(1 << uart))
+ return;
+
+ regulator_5v_enable(1 << uart);
+
+ if (jc_gamepad.sio_mode)
+ return;
+
+ if (jc_init_done)
+ {
+ if (uart == UART_C)
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
+ else
+ gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
+ return;
+ }
+
+ if (uart == UART_C)
+ {
+ // Joy-Con(L) Charge Enable.
+ PINMUX_AUX(PINMUX_AUX_SPDIF_IN) = PINMUX_PULL_DOWN | 1;
+ gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
+ }
+ else
+ {
+ // Joy-Con(R) Charge Enable.
+ PINMUX_AUX(PINMUX_AUX_GPIO_PK3) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN | 2;
+ gpio_direction_output(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
+ }
+ }
+ else
+ {
+ if (!regulator_5v_get_dev_enabled(1 << uart))
+ return;
+
+ regulator_5v_disable(1 << uart);
+
+ if (jc_gamepad.sio_mode)
+ return;
+
+ if (uart == UART_C)
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW);
+ else
+ gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_LOW);
+ }
+}
+
+static void _jc_detect()
+{
+ if (!jc_gamepad.sio_mode)
+ {
+ // Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled.
+ PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE;
+ PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE;
+ gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
+ gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
+ usleep(20);
+
+ //! HW BUG: Unlatch gpio buffer.
+ (void)gpio_read(GPIO_PORT_H, GPIO_PIN_6);
+ (void)gpio_read(GPIO_PORT_E, GPIO_PIN_6);
+
+ // Read H6/E6 which are shared with UART TX pins.
+ jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6);
+ jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6);
+
+ // Turn off Joy-Con detect. (UARTB/C TX).
+ PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
+ PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
+ gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
+ gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
+ usleep(20);
+ }
+ else
+ {
+ //! TODO: Is there a way to detect a broken Sio?
+ jc_l.detected = true;
+ }
+}
+
+static void _jc_conn_check()
+{
+ _jc_detect();
+
+ if (jc_gamepad.sio_mode)
+ return;
+
+ // Check if a Joy-Con was disconnected.
+ if (!jc_l.detected)
+ {
+ if (jc_l.connected)
+ _jc_power_supply(UART_C, false);
+
+ jc_l.pkt_id = 0;
+
+ jc_l.connected = false;
+ jc_l.rumble_sent = false;
+
+ jc_gamepad.conn_l = false;
+
+ jc_gamepad.batt_info_l = 0;
+ jc_gamepad.bt_conn_l.type = 0;
+ jc_gamepad.buttons &= ~JC_BTN_MASK_L;
+ }
+
+ if (!jc_r.detected)
+ {
+ if (jc_r.connected)
+ _jc_power_supply(UART_B, false);
+
+ jc_r.pkt_id = 0;
+
+ jc_r.connected = false;
+ jc_r.rumble_sent = false;
+
+ jc_gamepad.conn_r = false;
+
+ jc_gamepad.batt_info_r = 0;
+ jc_gamepad.bt_conn_r.type = 0;
+ jc_gamepad.buttons &= ~JC_BTN_MASK_R;
+ }
+}
+
+static void _joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
+{
+ uart_send(uart_port, buf, size);
+ uart_wait_xfer(uart_port, UART_TX_IDLE);
+}
+
+static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, const u8 *data, u16 size, bool crc)
{
out->uart_hdr.magic[0] = 0x19;
out->uart_hdr.magic[1] = 0x01;
@@ -214,14 +496,16 @@ static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u
if (data)
memcpy(out->data, data, size);
- out->crc = 0; // wired crc8ccit can be skipped.
+ out->crc = crc ? _jc_crc(&out->uart_hdr.total_size_msb,
+ sizeof(out->uart_hdr.total_size_msb) +
+ sizeof(out->cmd) + sizeof(out->data), 0) : 0;
return sizeof(jc_wired_hdr_t);
}
-static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size)
+static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, const u8 *payload, u16 size, bool crc)
{
- u16 pkt_size = jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0);
+ u16 pkt_size = _jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
pkt_size += size;
rpt->uart_hdr.total_size_lsb += size;
@@ -234,34 +518,25 @@ static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size)
return pkt_size;
}
-void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size)
+static void _jc_send_hid_output_rpt(joycon_ctxt_t *jc, jc_hid_out_rpt_t *hid_pkt, u16 size, bool crc)
{
u8 rpt[0x50];
memset(rpt, 0, sizeof(rpt));
- u32 rpt_size = jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size);
+ hid_pkt->pkt_id = (jc->pkt_id++ & 0xF);
+ u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, (u8 *)hid_pkt, size, crc);
- joycon_send_raw(uart, rpt, rpt_size);
+ _joycon_send_raw(jc->uart, rpt, rpt_size);
}
-static u8 jc_hid_pkt_id_incr()
+static void _jc_send_hid_cmd(joycon_ctxt_t *jc, u8 subcmd, const u8 *data, u16 size)
{
- u8 curr_id = hid_pkt_inc;
- hid_pkt_inc++;
+ static const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
+ static const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
- return (curr_id & 0xF);
-}
-
-void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
-{
- u8 temp[0x30];
- u8 rumble_neutral[8] = {0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40};
- u8 rumble_init[8] = {0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72};
-
- memset(temp, 0, sizeof(temp));
+ u8 temp[0x30] = {0};
jc_hid_out_rpt_t *hid_pkt = (jc_hid_out_rpt_t *)temp;
-
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
if (subcmd == JC_HID_SUBCMD_SND_RUMBLE)
@@ -270,70 +545,74 @@ void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
bool send_l_rumble = jc_l.connected && !jc_l.rumble_sent;
// Enable rumble.
- hid_pkt->cmd = JC_HID_OUTPUT_RPT;
- hid_pkt->pkt_id = jc_hid_pkt_id_incr();
+ hid_pkt->cmd = JC_HID_OUTPUT_RPT;
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
hid_pkt->subcmd_data[0] = 1;
if (send_r_rumble)
- jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10);
+ _jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
if (send_l_rumble)
- jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10);
+ _jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
// Send rumble.
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
- hid_pkt->pkt_id = jc_hid_pkt_id_incr();
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
if (send_r_rumble)
- jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10);
+ _jc_send_hid_output_rpt(&jc_r, hid_pkt, 10, false);
if (send_l_rumble)
- jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10);
+ _jc_send_hid_output_rpt(&jc_l, hid_pkt, 10, false);
msleep(15);
// Disable rumble.
- hid_pkt->cmd = JC_HID_OUTPUT_RPT;
- hid_pkt->pkt_id = jc_hid_pkt_id_incr();
+ hid_pkt->cmd = JC_HID_OUTPUT_RPT;
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
hid_pkt->subcmd_data[0] = 0;
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
if (send_r_rumble)
- jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10);
+ _jc_send_hid_output_rpt(&jc_r, hid_pkt, 0x10, false);
if (send_l_rumble)
- jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10);
+ _jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
}
else
{
- hid_pkt->cmd = JC_HID_OUTPUT_RPT;
- hid_pkt->pkt_id = jc_hid_pkt_id_incr();
+ bool crc_needed = jc->type & JC_ID_HORI;
+
+ hid_pkt->cmd = JC_HID_OUTPUT_RPT;
hid_pkt->subcmd = subcmd;
if (data)
memcpy(hid_pkt->subcmd_data, data, size);
- u8 pkt_size = sizeof(jc_hid_out_rpt_t) + size;
-
- jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, pkt_size);
+ _jc_send_hid_output_rpt(jc, hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
}
}
-static void jc_charging_decider(u8 batt, u8 uart)
+static void _jc_charging_decider(u8 batt, u8 uart)
{
u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000;
// Power supply control based on battery levels and charging.
- if ((batt >> 1 << 1) < JC_BATT_LOW) // Level without checking charging.
- jc_power_supply(uart, true);
- else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID)) // Addresses the charging bit.
- jc_power_supply(uart, false);
+ if ((batt >> 1) < JC_BATT_LOW) // Level without checking charging.
+ _jc_power_supply(uart, true);
+ else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID) << 1) // Addresses the charging bit.
+ _jc_power_supply(uart, false);
}
-static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
+static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8 *packet, int size)
{
u32 btn_tmp;
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
switch (hid_pkt->cmd)
{
+ case JC_HORI_INPUT_RPT:
+ if (!(jc->type & JC_ID_HORI))
+ return;
+
case JC_HID_INPUT_RPT:
+ // Discard incomplete hid packets.
+ if (size < 12)
+ break;
+
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
if (jc->type & JC_ID_L)
@@ -360,7 +639,8 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
jc_gamepad.conn_l = jc_l.connected;
jc_gamepad.conn_r = jc_r.connected;
- jc_charging_decider(hid_pkt->batt_info, jc->uart);
+ if (hid_pkt->cmd == JC_HID_INPUT_RPT)
+ _jc_charging_decider(hid_pkt->batt_info, jc->uart);
break;
case JC_HID_SUBMCD_RPT:
if (hid_pkt->subcmd == JC_HID_SUBCMD_SPI_READ)
@@ -372,10 +652,10 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
else
bt_conn = &jc_gamepad.bt_conn_r;
- jc_hid_in_spi_read_t *spi_info = (jc_hid_in_spi_read_t *)hid_pkt->subcmd_data;
+ jc_hid_in_spi_read_t *spi_info = (jc_hid_in_spi_read_t *)hid_pkt->subcmd_data;
jc_hid_in_pair_data_t *pair_data = (jc_hid_in_pair_data_t *)spi_info->data;
- // Check if we reply is pairing info.
+ // Check if the reply is pairing info.
if (spi_info->size == 0x1A && pair_data->magic == 0x95 && pair_data->size == 0x22)
{
bt_conn->type = jc->type;
@@ -390,116 +670,192 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
default:
break;
}
- jc->last_received_time = get_tmr_ms();
}
-static void jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
+static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8 *data, int size)
{
+ // Discard empty packets.
+ if (size <= 0)
+ return;
+
switch (data[0])
{
- case JC_WIRED_CMD_MAC:
+ case JC_WIRED_CMD_GET_INFO:
for (int i = 12; i > 6; i--)
jc->mac[12 - i] = data[i];
jc->type = data[6];
jc->connected = true;
+ break;
+ case JC_WIRED_CMD_SET_BRATE:
+ jc->state = JC_STATE_BRATE_CHANGED;
+ break;
+ case JC_WIRED_CMD_HID_DISC:
+ jc->state = JC_STATE_BRATE_OK;
+ break;
+ case JC_WIRED_CMD_HID_CONN:
+ case JC_WIRED_CMD_SET_HIDRATE:
+ // done.
default:
break;
}
}
-static void jc_uart_pkt_parse(joycon_ctxt_t *jc, const u8* packet, size_t size)
+static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, int size)
{
- jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)packet;
switch (pkt->cmd)
{
+ case JC_HORI_INPUT_RPT_CMD:
case JC_WIRED_HID:
- jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
+ _jc_parse_wired_hid(jc, pkt->payload, size - sizeof(jc_wired_hdr_t));
break;
case JC_WIRED_INIT_REPLY:
- jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
+ _jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
+ break;
+ case JC_INIT_HANDSHAKE:
+ jc->state = JC_STATE_HANDSHAKED;
+ break;
+ default:
+ break;
+ }
+
+ jc->last_received_time = get_tmr_ms();
+}
+
+static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8 *payload, int size)
+{
+ switch (cmd)
+ {
+ case JC_SIO_CMD_STATUS:
+ // Discard incomplete packets.
+ if (size < 12)
+ break;
+
+ jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
+ jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
+ jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
+
+ jc_gamepad.lstick_x = hid_pkt->stick_h_left | ((hid_pkt->stick_m_left & 0xF) << 8);
+ jc_gamepad.lstick_y = (hid_pkt->stick_m_left >> 4) | (hid_pkt->stick_v_left << 4);
+ jc_gamepad.rstick_x = hid_pkt->stick_h_right | ((hid_pkt->stick_m_right & 0xF) << 8);
+ jc_gamepad.rstick_y = (hid_pkt->stick_m_right >> 4) | (hid_pkt->stick_v_right << 4);
+
+ jc_gamepad.batt_info_l = jc_l.connected;
+ jc_gamepad.batt_info_r = gpio_read(GPIO_PORT_E, GPIO_PIN_7); // Set IRQ status.
+
+ jc_gamepad.conn_l = jc_l.connected;
+ jc_gamepad.conn_r = jc_l.connected;
break;
default:
break;
}
}
-static void jc_rcv_pkt(joycon_ctxt_t *jc)
+static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, int size)
{
- if (gpio_read(GPIO_PORT_E, GPIO_PIN_6) && jc->uart == UART_C)
- return;
- else if (gpio_read(GPIO_PORT_H, GPIO_PIN_6) && jc->uart == UART_B)
+ if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
return;
- // Check if device stopped sending data.
- u32 uart_irq = uart_get_IIR(jc->uart);
- if ((uart_irq & 0x8) != 0x8)
+ u8 cmd = pkt->ack & (~JC_SIO_CMD_ACK);
+ switch (cmd)
+ {
+ case JC_SIO_CMD_INIT:
+ jc->connected = pkt->status == 0;
+ break;
+ case JC_SIO_CMD_VER_RPT:
+ if (jc->connected)
+ jc->connected = pkt->status == 0;
+ break;
+ case JC_SIO_CMD_IAP_VER:
+ case JC_SIO_CMD_STATUS:
+ _jc_sio_parse_payload(jc, cmd, pkt->payload, size - sizeof(jc_sio_in_rpt_t));
+ break;
+ case JC_SIO_CMD_UNK02:
+ case JC_SIO_CMD_UNK20:
+ case JC_SIO_CMD_UNK21:
+ case JC_SIO_CMD_UNK22:
+ case JC_SIO_CMD_UNK40:
+ default:
+ break;
+ }
+
+ jc->last_received_time = get_tmr_ms();
+}
+
+static void _jc_rcv_pkt(joycon_ctxt_t *jc)
+{
+ if (!jc->detected)
return;
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
+ if (len < 8)
+ return;
- // Check valid size and uart reply magic.
- if (len > 7 && !memcmp(jc->buf, "\x19\x81\x03", 3))
+ // For Joycon, check uart reply magic.
+ jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
+ if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
{
- jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)(jc->buf);
+ _jc_uart_pkt_parse(jc, jc_pkt, len);
- jc_uart_pkt_parse(jc, jc->buf, pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t));
+ return;
+ }
+
+ // For Sio, check uart output report and command ack.
+ jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
+ if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
+ {
+ _jc_sio_uart_pkt_parse(jc, sio_pkt, len);
+
+ return;
}
}
-static bool jc_send_init_rumble(joycon_ctxt_t *jc)
+static bool _jc_send_init_rumble(joycon_ctxt_t *jc)
{
// Send init rumble or request nx pad status report.
if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent))
{
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
-
- jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
+ _jc_send_hid_cmd(jc, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
if (jc_l.connected)
jc_l.rumble_sent = true;
if (jc_r.connected)
jc_r.rumble_sent = true;
- if (jc->uart != UART_B)
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
- else
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
-
return 1;
}
return 0;
}
-static void jc_req_nx_pad_status(joycon_ctxt_t *jc)
+static void _jc_req_nx_pad_status(joycon_ctxt_t *jc)
{
- bool sent_rumble = jc_send_init_rumble(jc);
-
- if (sent_rumble)
+ if (!jc->detected)
return;
+ bool is_nxpad = !(jc->type & JC_ID_HORI) && !jc->sio_mode;
+
if (jc->last_status_req_time > get_tmr_ms() || !jc->connected)
return;
- // Turn off Joy-Con detect.
- if (jc->uart == UART_B)
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
+ if (is_nxpad)
+ {
+ bool sent_rumble = _jc_send_init_rumble(jc);
+
+ if (sent_rumble)
+ return;
+ }
+
+ if (is_nxpad)
+ _joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
+ else if (jc->sio_mode)
+ _joycon_send_raw(jc->uart, sio_pad_status, sizeof(sio_pad_status));
else
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
+ _joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
- joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
-
- // Turn Joy-Con detect on.
- if (jc->uart == UART_B)
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
- else
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
-
- jc->last_status_req_time = get_tmr_ms() + 15;
+ jc->last_status_req_time = get_tmr_ms() + (!jc->sio_mode ? 15 : 7);
}
-static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
+static bool _jc_validate_pairing_info(const u8 *buf, bool *is_hos)
{
u8 crc = 0;
for (u32 i = 0; i < 0x22; i++)
@@ -524,21 +880,23 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
u8 retries;
jc_bt_conn_t *bt_conn;
- if (!jc_init_done)
+ if (!jc_init_done || jc_gamepad.sio_mode)
return NULL;
bt_conn = &jc_gamepad.bt_conn_l;
memset(bt_conn->host_mac, 0, 6);
- memset(bt_conn->ltk, 0, 16);
+ memset(bt_conn->ltk, 0, 16);
bt_conn = &jc_gamepad.bt_conn_r;
memset(bt_conn->host_mac, 0, 6);
- memset(bt_conn->ltk, 0, 16);
+ memset(bt_conn->ltk, 0, 16);
+
+ _jc_conn_check();
while (jc_l.last_status_req_time > get_tmr_ms())
{
- jc_rcv_pkt(&jc_r);
- jc_rcv_pkt(&jc_l);
+ _jc_rcv_pkt(&jc_r);
+ _jc_rcv_pkt(&jc_l);
}
jc_hid_in_spi_read_t subcmd_data_l;
@@ -549,13 +907,13 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
subcmd_data_r.addr = 0x2000;
subcmd_data_r.size = 0x1A;
- // Turn off Joy-Con detect.
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
-
bool jc_r_found = jc_r.connected ? false : true;
bool jc_l_found = jc_l.connected ? false : true;
+ // Set mode to HW controlled RTS.
+ uart_set_mode(jc_l.uart, UART_AO_TX_HW_RX);
+ uart_set_mode(jc_r.uart, UART_AO_TX_HW_RX);
+
u32 total_retries = 10;
retry:
retries = 10;
@@ -566,23 +924,26 @@ retry:
{
if (!jc_l_found)
{
- jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
+ _jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
jc_l.last_status_req_time = get_tmr_ms() + 15;
}
if (!jc_r_found)
{
- jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
+ _jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
jc_r.last_status_req_time = get_tmr_ms() + 15;
}
retries--;
}
+ // Wait for the first 36 bytes to arrive.
+ msleep(5);
+
if (!jc_l_found)
{
memset(jc_l.buf, 0, 0x100);
- jc_rcv_pkt(&jc_l);
+ _jc_rcv_pkt(&jc_l);
bool is_hos = false;
if (_jc_validate_pairing_info(&jc_l.buf[SPI_READ_OFFSET], &is_hos))
@@ -602,7 +963,7 @@ retry:
if (!jc_r_found)
{
memset(jc_r.buf, 0, 0x100);
- jc_rcv_pkt(&jc_r);
+ _jc_rcv_pkt(&jc_r);
bool is_hos = false;
if (_jc_validate_pairing_info(&jc_r.buf[SPI_READ_OFFSET], &is_hos))
@@ -635,179 +996,156 @@ retry:
{
bt_conn = &jc_gamepad.bt_conn_l;
memset(bt_conn->host_mac, 0, 6);
- memset(bt_conn->ltk, 0, 16);
+ memset(bt_conn->ltk, 0, 16);
}
if (!jc_r_found)
{
bt_conn = &jc_gamepad.bt_conn_r;
memset(bt_conn->host_mac, 0, 6);
- memset(bt_conn->ltk, 0, 16);
+ memset(bt_conn->ltk, 0, 16);
}
}
- // Turn Joy-Con detect on.
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
+ // Restore mode to manual RTS.
+ uart_set_mode(jc_l.uart, UART_AO_TX_MN_RX);
+ uart_set_mode(jc_r.uart, UART_AO_TX_MN_RX);
return &jc_gamepad;
}
-void jc_deinit()
+static void _jc_init_conn(joycon_ctxt_t *jc)
{
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
+ if (!jc->detected)
+ return;
- u8 data = HCI_STATE_SLEEP;
-
- if (jc_r.connected)
- {
- jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1);
- jc_rcv_pkt(&jc_r);
- }
- if (jc_l.connected)
- {
- jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
- jc_rcv_pkt(&jc_l);
- }
-
- jc_power_supply(UART_B, false);
- jc_power_supply(UART_C, false);
-}
-
-static void jc_init_conn(joycon_ctxt_t *jc)
-{
if (((u32)get_tmr_ms() - jc->last_received_time) > 1000)
{
- jc_power_supply(jc->uart, true);
+ _jc_power_supply(jc->uart, true);
- // Turn off Joy-Con detect.
+ // Mask out buttons and set connected to false.
if (jc->uart == UART_B)
{
jc_gamepad.buttons &= ~JC_BTN_MASK_R;
jc_gamepad.conn_r = false;
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
}
else
{
jc_gamepad.buttons &= ~JC_BTN_MASK_L;
jc_gamepad.conn_l = false;
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
}
- uart_init(jc->uart, 1000000);
- uart_invert(jc->uart, true, UART_INVERT_TXD);
- uart_set_IIR(jc->uart);
+ // Initialize uart to 1 megabaud and manual RTS.
+ uart_init(jc->uart, 1000000, UART_AO_TX_MN_RX);
- joycon_send_raw(jc->uart, init_jc, 4);
- joycon_send_raw(jc->uart, init_handshake, sizeof(init_handshake));
+ if (!jc->sio_mode)
+ {
+ jc->state = JC_STATE_START;
- msleep(5);
- jc_rcv_pkt(jc);
+ // Set TX and RTS inversion for Joycon.
+ uart_invert(jc->uart, true, UART_INVERT_TXD | UART_INVERT_RTS);
- joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info));
- msleep(5);
- jc_rcv_pkt(jc);
+ // Wake up the controller.
+ _joycon_send_raw(jc->uart, init_wake, sizeof(init_wake));
+ _jc_rcv_pkt(jc); // Clear RX FIFO.
- joycon_send_raw(jc->uart, init_finilize, sizeof(init_finilize));
- msleep(5);
- jc_rcv_pkt(jc);
+ // Do a handshake.
+ u32 retries = 10;
+ while (retries && jc->state != JC_STATE_HANDSHAKED)
+ {
+ _joycon_send_raw(jc->uart, init_handshake, sizeof(init_handshake));
+ msleep(5);
+ _jc_rcv_pkt(jc);
+ retries--;
+ }
- // Turn Joy-Con detect on.
- if (jc->uart == UART_B)
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
+ if (jc->state != JC_STATE_HANDSHAKED)
+ goto out;
+
+ // Get info about the controller.
+ _joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info));
+ msleep(2);
+ _jc_rcv_pkt(jc);
+
+ if (!(jc->type & JC_ID_HORI))
+ {
+ // Request 3 megabaud change.
+ _joycon_send_raw(jc->uart, init_switch_brate, sizeof(init_switch_brate));
+ msleep(2);
+ _jc_rcv_pkt(jc);
+
+ if (jc->state == JC_STATE_BRATE_CHANGED)
+ {
+ // Reinitialize uart to 3 megabaud and manual RTS.
+ uart_init(jc->uart, 3000000, UART_AO_TX_MN_RX);
+ uart_invert(jc->uart, true, UART_INVERT_TXD | UART_INVERT_RTS);
+
+ // Disconnect HID.
+ retries = 10;
+ while (retries && jc->state != JC_STATE_BRATE_OK)
+ {
+ _joycon_send_raw(jc->uart, init_hid_disconnect, sizeof(init_hid_disconnect));
+ msleep(5);
+ _jc_rcv_pkt(jc);
+ retries--;
+ }
+
+ if (jc->state != JC_STATE_BRATE_OK)
+ goto out;
+ }
+
+ // Create HID connection with the new rate.
+ _joycon_send_raw(jc->uart, init_hid_connect, sizeof(init_hid_connect));
+ msleep(2);
+ _jc_rcv_pkt(jc);
+
+ // Set hid packet rate.
+ _joycon_send_raw(jc->uart, init_set_hid_rate, sizeof(init_set_hid_rate));
+ msleep(2);
+ _jc_rcv_pkt(jc);
+ }
+ else // Hori. Unset RTS inversion.
+ uart_invert(jc->uart, false, UART_INVERT_RTS);
+ }
else
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
+ {
+ // Set Sio NPOR low to configure BOOT0 mode.
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW);
+ usleep(300);
+ gpio_write(GPIO_PORT_T, GPIO_PIN_0, GPIO_LOW);
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_HIGH);
+ msleep(100);
+ // Clear RX FIFO.
+ _jc_rcv_pkt(jc);
+
+ // Initialize the controller.
+ u32 retries = 10;
+ while (!jc->connected && retries)
+ {
+ _joycon_send_raw(jc->uart, sio_init, sizeof(sio_init));
+ msleep(5);
+ _jc_rcv_pkt(jc);
+ retries--;
+ }
+
+ if (!jc->connected)
+ goto out;
+
+ // Set output report version.
+ _joycon_send_raw(jc->uart, sio_set_rpt_version, sizeof(sio_set_rpt_version));
+ msleep(5);
+ _jc_rcv_pkt(jc);
+ }
+
+ // Initialization done.
+ jc->state = JC_STATE_INIT_DONE;
+
+out:
jc->last_received_time = get_tmr_ms();
- if (jc->connected)
- jc_power_supply(jc->uart, false);
- }
-}
-
-static void jc_conn_check()
-{
- // Check if a Joy-Con was disconnected.
- if (gpio_read(GPIO_PORT_E, GPIO_PIN_6))
- {
- jc_power_supply(UART_C, false);
-
- hid_pkt_inc = 0;
-
- jc_l.connected = false;
- jc_l.rumble_sent = false;
-
- jc_gamepad.buttons &= ~JC_BTN_MASK_L;
- jc_gamepad.conn_l = false;
-
- jc_gamepad.batt_info_l = 0;
- jc_gamepad.bt_conn_l.type = 0;
- }
-
- if (gpio_read(GPIO_PORT_H, GPIO_PIN_6))
- {
- jc_power_supply(UART_B, false);
-
- hid_pkt_inc = 0;
-
- jc_r.connected = false;
- jc_r.rumble_sent = false;
-
- jc_gamepad.buttons &= ~JC_BTN_MASK_R;
- jc_gamepad.conn_r = false;
-
- jc_gamepad.batt_info_r = 0;
- jc_gamepad.bt_conn_r.type = 0;
- }
-}
-
-void jc_power_supply(u8 uart, bool enable)
-{
- if (enable)
- {
- if (regulator_get_5v_dev_enabled(1 << uart))
- return;
-
- regulator_enable_5v(1 << uart);
-
- if (jc_init_done)
- {
- if (uart == UART_C)
- gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
- else
- gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
- return;
- }
-
- if (uart == UART_C)
- {
- // Joy-Con(L) Charge Detect.
- PINMUX_AUX(PINMUX_AUX_SPDIF_IN) = PINMUX_PULL_DOWN | 1;
- gpio_config(GPIO_PORT_CC, GPIO_PIN_3, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_3, GPIO_OUTPUT_ENABLE);
- gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
- }
- else
- {
- // Joy-Con(R) Charge Detect.
- PINMUX_AUX(PINMUX_AUX_GPIO_PK3) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN | 2;
- gpio_config(GPIO_PORT_K, GPIO_PIN_3, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_K, GPIO_PIN_3, GPIO_OUTPUT_ENABLE);
- gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
- }
- }
- else
- {
- if (!regulator_get_5v_dev_enabled(1 << uart))
- return;
-
- regulator_disable_5v(1 << uart);
-
- if (uart == UART_C)
- gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW);
- else
- gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_LOW);
+ if (!jc->sio_mode && jc->connected && !(jc->type & JC_ID_HORI))
+ _jc_power_supply(jc->uart, false);
}
}
@@ -816,64 +1154,121 @@ void jc_init_hw()
jc_l.uart = UART_C;
jc_r.uart = UART_B;
+ jc_l.sio_mode = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
+ jc_gamepad.sio_mode = jc_l.sio_mode;
+
#if !defined(DEBUG_UART_PORT) || !(DEBUG_UART_PORT)
- if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG)
- return;
+ _jc_power_supply(UART_C, true);
+ _jc_power_supply(UART_B, true);
- jc_power_supply(UART_C, true);
- jc_power_supply(UART_B, true);
+ // Sio Initialization.
+ if (jc_gamepad.sio_mode)
+ {
+ // Enable 4 MHz clock to Sio.
+ clock_enable_extperiph2();
+ PINMUX_AUX(PINMUX_AUX_TOUCH_CLK) = PINMUX_PULL_DOWN;
- // Joy-Con (R) IsAttached.
- PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
- gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
+ // Configure Sio HOME BUTTON.
+ PINMUX_AUX(PINMUX_AUX_LCD_GPIO1) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 1;
+ gpio_direction_input(GPIO_PORT_V, GPIO_PIN_3);
- // Joy-Con (L) IsAttached.
+ // Configure Sio IRQ
+ PINMUX_AUX(PINMUX_AUX_GPIO_PE7) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP;
+ gpio_direction_input(GPIO_PORT_E, GPIO_PIN_7);
+
+ // Configure Sio NRST and BOOT0.
+ PINMUX_AUX(PINMUX_AUX_CAM1_STROBE) = PINMUX_PULL_DOWN | 1;
+ PINMUX_AUX(PINMUX_AUX_CAM2_PWDN) = PINMUX_PULL_DOWN | 1;
+
+ // Set BOOT0 to flash mode. (output high is sram mode).
+ gpio_direction_output(GPIO_PORT_T, GPIO_PIN_0, GPIO_LOW);
+
+ // NRST to pull down.
+ gpio_direction_input(GPIO_PORT_T, GPIO_PIN_1);
+
+ // Configure Sio NPOR.
+ PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) = PINMUX_IO_HV | PINMUX_LPDR | 1;
+ gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW);
+ }
+
+#if 0 // Already set by hw init.
+ // Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+ PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+
+ // Set Joy-Con IsAttached mode. Shared with UARTB/UARTC TX.
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
+ gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
+#endif
// Configure pinmuxing for UART B and C.
- pinmux_config_uart(UART_B);
+ if (!jc_gamepad.sio_mode)
+ pinmux_config_uart(UART_B);
pinmux_config_uart(UART_C);
- // Ease the stress to APB.
- bpmp_clk_rate_set(BPMP_CLK_NORMAL);
-
// Enable UART B and C clocks.
- clock_enable_uart(UART_B);
+ if (!jc_gamepad.sio_mode)
+ clock_enable_uart(UART_B);
clock_enable_uart(UART_C);
- // Restore OC.
- bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
-
- // Turn Joy-Con detect on.
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
-
jc_init_done = true;
#endif
}
+void jc_deinit()
+{
+ if (!jc_init_done)
+ return;
+
+ // Disable power.
+ _jc_power_supply(UART_B, false);
+ _jc_power_supply(UART_C, false);
+
+ if (!jc_gamepad.sio_mode)
+ {
+ // Send sleep command.
+ u8 data = HCI_STATE_SLEEP;
+ if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
+ {
+ _jc_send_hid_cmd(&jc_r, JC_HID_SUBCMD_HCI_STATE, &data, 1);
+ _jc_rcv_pkt(&jc_r);
+ }
+ if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
+ {
+ _jc_send_hid_cmd(&jc_l, JC_HID_SUBCMD_HCI_STATE, &data, 1);
+ _jc_rcv_pkt(&jc_l);
+ }
+ }
+ else
+ {
+ // Disable Sio NPOR.
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW);
+
+ // Disable 4 MHz clock to Sio.
+ clock_disable_extperiph2();
+ }
+
+ // Disable UART B and C clocks.
+ if (!jc_gamepad.sio_mode)
+ clock_disable_uart(UART_B);
+ clock_disable_uart(UART_C);
+}
+
jc_gamepad_rpt_t *joycon_poll()
{
if (!jc_init_done)
return NULL;
- if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
- jc_init_conn(&jc_r);
- if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
- jc_init_conn(&jc_l);
+ _jc_conn_check();
- if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
- jc_req_nx_pad_status(&jc_r);
- if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
- jc_req_nx_pad_status(&jc_l);
+ _jc_init_conn(&jc_r);
+ _jc_init_conn(&jc_l);
- if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
- jc_rcv_pkt(&jc_r);
- if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
- jc_rcv_pkt(&jc_l);
+ _jc_req_nx_pad_status(&jc_r);
+ _jc_req_nx_pad_status(&jc_l);
- jc_conn_check();
+ _jc_rcv_pkt(&jc_r);
+ _jc_rcv_pkt(&jc_l);
return &jc_gamepad;
}
diff --git a/bdk/input/joycon.h b/bdk/input/joycon.h
index 932c836..fbb789f 100644
--- a/bdk/input/joycon.h
+++ b/bdk/input/joycon.h
@@ -43,34 +43,34 @@ typedef struct _jc_gamepad_rpt_t
struct
{
// Joy-Con (R).
- u32 y:1;
- u32 x:1;
- u32 b:1;
- u32 a:1;
- u32 sr_r:1;
- u32 sl_r:1;
- u32 r:1;
- u32 zr:1;
+/*00*/ u32 y:1;
+/*01*/ u32 x:1;
+/*02*/ u32 b:1;
+/*03*/ u32 a:1;
+/*04*/ u32 sr_r:1;
+/*05*/ u32 sl_r:1;
+/*06*/ u32 r:1;
+/*07*/ u32 zr:1;
// Shared
- u32 minus:1;
- u32 plus:1;
- u32 r3:1;
- u32 l3:1;
- u32 home:1;
- u32 cap:1;
- u32 pad:1;
- u32 wired:1;
+/*08*/ u32 minus:1;
+/*09*/ u32 plus:1;
+/*10*/ u32 r3:1;
+/*11*/ u32 l3:1;
+/*12*/ u32 home:1;
+/*13*/ u32 cap:1;
+/*14*/ u32 pad:1;
+/*15*/ u32 wired:1;
// Joy-Con (L).
- u32 down:1;
- u32 up:1;
- u32 right:1;
- u32 left:1;
- u32 sr_l:1;
- u32 sl_l:1;
- u32 l:1;
- u32 zl:1;
+/*16*/ u32 down:1;
+/*17*/ u32 up:1;
+/*18*/ u32 right:1;
+/*19*/ u32 left:1;
+/*20*/ u32 sr_l:1;
+/*21*/ u32 sl_l:1;
+/*22*/ u32 l:1;
+/*23*/ u32 zl:1;
};
u32 buttons;
};
@@ -83,16 +83,26 @@ typedef struct _jc_gamepad_rpt_t
bool center_stick_r;
bool conn_l;
bool conn_r;
- u8 batt_info_l;
- u8 batt_info_r;
+ bool sio_mode;
+ u8 batt_info_l; // Also Sio Connected status.
+ u8 batt_info_r; // Also Sio IRQ.
jc_bt_conn_t bt_conn_l;
jc_bt_conn_t bt_conn_r;
} jc_gamepad_rpt_t;
-void jc_power_supply(u8 uart, bool enable);
+typedef struct _jc_calib_t
+{
+ u16 x_max:12;
+ u16 y_max:12;
+ u16 x_center:12;
+ u16 y_center:12;
+ u16 x_min:12;
+ u16 y_min:12;
+} __attribute__((packed)) jc_calib_t;
+
void jc_init_hw();
void jc_deinit();
jc_gamepad_rpt_t *joycon_poll();
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos);
-#endif
\ No newline at end of file
+#endif
diff --git a/bdk/input/touch.c b/bdk/input/touch.c
index f24b53a..f5b5098 100644
--- a/bdk/input/touch.c
+++ b/bdk/input/touch.c
@@ -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-2023 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,17 +23,26 @@
#include
#include
#include
-#include
#include
+#include
#include
#include
-#include
#include "touch.h"
#include
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
+static touch_panel_info_t _panels[] =
+{
+ { 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0.
+ { 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
+ { 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
+ { 3, 1, 0, 0, "GiS 5.5\"" },// 4.
+ { 4, 0, 0, 1, "Samsung TSP" },// 5?
+ { -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
+};
+
static int touch_command(u8 cmd, u8 *buf, u8 size)
{
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
@@ -53,7 +62,7 @@ static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
return 0;
}
-static int touch_wait_event(u8 event, u8 status, u32 timeout)
+static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
{
u32 timer = get_tmr_ms() + timeout;
while (true)
@@ -61,7 +70,11 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout)
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 (buf)
+ memcpy(buf, &tmp[3], 5);
return 0;
+ }
if (get_tmr_ms() > timer)
return 1;
@@ -74,19 +87,19 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout)
static void _touch_compensate_limits(touch_event *event, bool touching)
{
- event->x = MAX(event->x, EDGE_OFFSET);
- event->x = MIN(event->x, X_REAL_MAX);
+ event->x = MAX(event->x, EDGE_OFFSET);
+ event->x = MIN(event->x, X_REAL_MAX);
event->x -= EDGE_OFFSET;
u32 x_adj = (1280 * 1000) / (X_REAL_MAX - EDGE_OFFSET);
- event->x = ((u32)event->x * x_adj) / 1000;
+ event->x = ((u32)event->x * x_adj) / 1000;
if (touching)
{
- event->y = MAX(event->y, EDGE_OFFSET);
- event->y = MIN(event->y, Y_REAL_MAX);
+ event->y = MAX(event->y, EDGE_OFFSET);
+ event->y = MIN(event->y, Y_REAL_MAX);
event->y -= EDGE_OFFSET;
u32 y_adj = (720 * 1000) / (Y_REAL_MAX - EDGE_OFFSET);
- event->y = ((u32)event->y * y_adj) / 1000;
+ event->y = ((u32)event->y * y_adj) / 1000;
}
}
@@ -102,6 +115,7 @@ static void _touch_process_contact_event(touch_event *event, bool touching)
event->z = event->raw[5] | (event->raw[6] << 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;
@@ -147,10 +161,10 @@ static void _touch_parse_event(touch_event *event)
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
}
- // gfx_con_setpos(&gfx_con, 0, 300);
+ // 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]);
+ // 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]);
}
void touch_poll(touch_event *event)
@@ -183,16 +197,45 @@ touch_info touch_get_info()
info.config_id = buf[4];
info.config_ver = buf[5];
- //DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02x, Cfg Ver: %d\n",
+ //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;
}
+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, ""};
+
+ if (touch_command(STMFTS_VENDOR, &cmd, 1))
+ return NULL;
+
+ if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
+ return NULL;
+
+ for (u32 i = 0; i < ARRAY_SIZE(_panels); i++)
+ {
+ touch_panel_info_t *panel = &_panels[i];
+ if (buf[0] == panel->gpio0 && buf[1] == panel->gpio1 && buf[2] == panel->gpio2)
+ return panel;
+ }
+
+ // Touch panel not found, return current gpios.
+ panel_info.gpio0 = buf[0];
+ panel_info.gpio1 = buf[1];
+ panel_info.gpio2 = buf[2];
+
+ return &panel_info;
+}
+
int touch_get_fw_info(touch_fw_info_t *fw)
{
u8 buf[8] = {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);
@@ -203,7 +246,7 @@ int touch_get_fw_info(touch_fw_info_t *fw)
res = touch_read_reg(cmd, 3, buf, 8);
if (!res)
{
- fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
+ fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
fw->ftb_ver = (buf[6] << 8) | buf[5];
}
@@ -227,7 +270,7 @@ int touch_sys_reset()
continue;
}
msleep(10);
- if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20))
+ if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL))
continue;
else
return 0;
@@ -284,7 +327,7 @@ int touch_get_fb_info(u8 *buf)
int res = 0;
- for (u32 i = 0; i < 0x10000; i+=4)
+ for (u32 i = 0; i < 0x10000; i += 4)
{
if (!res)
{
@@ -301,9 +344,9 @@ int touch_get_fb_info(u8 *buf)
int touch_sense_enable()
{
- // Enable auto tuning calibration and multi-touch sensing.
- u8 cmd = 1;
- if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1))
+ // Switch sense mode and enable multi-touch sensing.
+ u8 cmd = STMFTS_FINGER_MODE;
+ if (touch_command(STMFTS_SWITCH_SENSE_MODE, &cmd, 1))
return 0;
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
@@ -329,19 +372,19 @@ int touch_execute_autotune()
// 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))
+ if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000, NULL))
return 0;
// 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))
+ if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000, NULL))
return 0;
// 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))
+ if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, NULL))
return 0;
return touch_sense_enable();
@@ -358,34 +401,32 @@ static int touch_init()
int touch_power_on()
{
- // Enables LDO6 for touchscreen VDD/AVDD supply
- max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
- (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
-
- // Configure touchscreen GPIO.
- PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
- gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
- gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
-
- // IRQ and more.
- // PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3;
- // gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO);
- // gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW);
-
// 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;
- gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO);
+ 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);
+ usleep(20);
+
+ // Enable LDO6 for touchscreen AVDD and DVDD supply.
+ max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
+ max7762x_regulator_enable(REGULATOR_LDO6, true);
// Initialize I2C3.
pinmux_config_i2c(I2C_3);
clock_enable_i2c(I2C_3);
i2c_init(I2C_3);
+ usleep(1000);
+
+ // Set Touch Reset pin.
+ gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
+ usleep(10000);
// Wait for the touchscreen module to get ready.
- touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20);
+ touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
// Check for forced boot time calibration.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
@@ -414,9 +455,7 @@ void touch_power_off()
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
// Disables LDO6 for touchscreen VDD, AVDD supply
- max77620_regulator_enable(REGULATOR_LDO6, 0);
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
- MAX77620_LDO_CFG2_ADE_ENABLE | (2 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
+ max7762x_regulator_enable(REGULATOR_LDO6, false);
clock_disable_i2c(I2C_3);
}
\ No newline at end of file
diff --git a/bdk/input/touch.h b/bdk/input/touch.h
index 9245be3..871659e 100644
--- a/bdk/input/touch.h
+++ b/bdk/input/touch.h
@@ -47,19 +47,27 @@
#define STMFTS_ITO_CHECK 0xA7
#define STMFTS_RELEASEINFO 0xAA
#define STMFTS_WRITE_REG 0xB6
-#define STMFTS_AUTO_CALIBRATION 0xC3
+#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 STMFTS_UNK0 0xB8 //Request compensation
-#define STMFTS_UNK1 0xCF
-#define STMFTS_UNK2 0xF7
-#define STMFTS_UNK3 0xFA
-#define STMFTS_UNK4 0xF9
+#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
+/* 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
/* events */
#define STMFTS_EV_NO_EVENT 0x00
@@ -74,6 +82,7 @@
#define STMFTS_EV_ERROR 0x0f
#define STMFTS_EV_NOISE_READ 0x17
#define STMFTS_EV_NOISE_WRITE 0x18
+#define STMFTS_EV_VENDOR 0x20
#define STMFTS_EV_CONTROLLER_READY 0x10
#define STMFTS_EV_STATUS 0x16
@@ -131,6 +140,15 @@ typedef struct _touch_event {
bool touch;
} touch_event;
+typedef struct _touch_panel_info_t
+{
+ u8 idx;
+ u8 gpio0;
+ u8 gpio1;
+ u8 gpio2;
+ char *vendor;
+} touch_panel_info_t;
+
typedef struct _touch_info {
u16 chip_id;
u16 fw_ver;
@@ -146,6 +164,7 @@ typedef struct _touch_fw_info_t {
void touch_poll(touch_event *event);
touch_event touch_poll_wait();
+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_panel_ito_test(u8 *err);
diff --git a/bdk/libs/compr/blz.c b/bdk/libs/compr/blz.c
index 685ef4a..5bc9e49 100644
--- a/bdk/libs/compr/blz.c
+++ b/bdk/libs/compr/blz.c
@@ -20,33 +20,33 @@
#include "blz.h"
-const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)
+const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer)
{
- if (compDataLen < sizeof(blz_footer))
+ if (comp_data_size < sizeof(blz_footer))
return NULL;
- const blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];
- if (outFooter != NULL)
- memcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.
+ const blz_footer *src_footer = (const blz_footer *)&comp_data[comp_data_size - sizeof(blz_footer)];
+ if (out_footer)
+ memcpy(out_footer, src_footer, sizeof(blz_footer)); // Must be a memcpy because no unaligned accesses on ARMv4.
- return srcFooter;
+ return src_footer;
}
// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
-int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer)
+int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer)
{
u32 addl_size = footer->addl_size;
u32 header_size = footer->header_size;
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;
- unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
+ u8 *cmp_start = &data[comp_size] - cmp_and_hdr_size;
u32 cmp_ofs = cmp_and_hdr_size - header_size;
u32 out_ofs = cmp_and_hdr_size + addl_size;
while (out_ofs)
{
- unsigned char control = cmp_start[--cmp_ofs];
- for (unsigned int i=0; i<8; i++)
+ u8 control = cmp_start[--cmp_ofs];
+ for (u32 i = 0; i < 8; i++)
{
if (control & 0x80)
{
@@ -54,45 +54,48 @@ int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const
return 0; // Out of bounds.
cmp_ofs -= 2;
- u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
+ u16 seg_val = ((u32)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
- if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
+
+ // Kernel restricts segment copy to stay in bounds.
+ if (out_ofs < seg_size)
seg_size = out_ofs;
out_ofs -= seg_size;
- for (unsigned int j = 0; j < seg_size; j++)
+ for (u32 j = 0; j < seg_size; j++)
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
}
- else
+ else // Copy directly.
{
- // Copy directly.
if (cmp_ofs < 1)
- return 0; //out of bounds
+ return 0; // Out of bounds.
cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
}
+
control <<= 1;
- if (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.
+
+ if (!out_ofs) // Blz works backwards, so if it reaches byte 0, it's done.
return 1;
- }
}
+ }
return 1;
}
-int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)
+int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size)
{
blz_footer footer;
- const blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
- if (compFooterPtr == NULL)
+ const blz_footer *comp_footer = blz_get_footer(comp_data, comp_data_size, &footer);
+ if (!comp_footer)
return 0;
- // Decompression must be done in-place, so need to copy the relevant compressed data first.
- unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
- memcpy(dstData, compData, numCompBytes);
- memset(&dstData[numCompBytes], 0, dstSize - numCompBytes);
+ // Decompression happens in-place, so need to copy the relevant compressed data first.
+ u32 comp_bytes = (const u8 *)comp_footer - comp_data;
+ memcpy(dst_data, comp_data, comp_bytes);
+ memset(&dst_data[comp_bytes], 0, dst_size - comp_bytes);
- return blz_uncompress_inplace(dstData, compDataLen, &footer);
+ return blz_uncompress_inplace(dst_data, comp_data_size, &footer);
}
diff --git a/bdk/libs/compr/blz.h b/bdk/libs/compr/blz.h
index a1cce37..bb058d8 100644
--- a/bdk/libs/compr/blz.h
+++ b/bdk/libs/compr/blz.h
@@ -26,11 +26,11 @@ typedef struct _blz_footer
u32 addl_size;
} blz_footer;
-// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.
-const blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);
+// Returns pointer to footer in comp_data if present, additionally copies it to out_footer if not NULL.
+const blz_footer *blz_get_footer(const u8 *comp_data, u32 comp_data_size, blz_footer *out_footer);
// Returns 0 on failure.
-int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);
+int blz_uncompress_inplace(u8 *data, u32 comp_size, const blz_footer *footer);
// Returns 0 on failure.
-int blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);
+int blz_uncompress_srcdest(const u8 *comp_data, u32 comp_data_size, u8 *dst_data, u32 dst_size);
#endif
diff --git a/bdk/libs/compr/lz4.c b/bdk/libs/compr/lz4.c
index ddea3d8..d6c22c6 100644
--- a/bdk/libs/compr/lz4.c
+++ b/bdk/libs/compr/lz4.c
@@ -92,22 +92,12 @@
# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
#endif
-#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
-# define expect(expr,value) (__builtin_expect ((expr),(value)) )
-#else
-# define expect(expr,value) (expr)
-#endif
-
-#define likely(expr) expect((expr) != 0, 1)
-#define unlikely(expr) expect((expr) != 0, 0)
-
-
/*-************************************
* Memory routines
**************************************/
#include /* malloc, calloc, free */
#define ALLOC(s) malloc(s)
-#define ALLOC_AND_ZERO(s) calloc(1,s)
+#define ALLOC_AND_ZERO(s) zalloc(s)
#define FREEMEM free
#include /* memset, memcpy */
#define MEM_INIT memset
@@ -839,10 +829,12 @@ int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
{
int result;
- LZ4_stream_t ctx;
- LZ4_stream_t* const ctxPtr = &ctx;
+ LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
+ LZ4_stream_t* const ctxPtr = ctx;
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
+ FREEMEM(ctx);
+
return result;
}
@@ -857,13 +849,18 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO
/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
{
- LZ4_stream_t ctx;
- LZ4_resetStream(&ctx);
+ int result;
+ LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
+ LZ4_resetStream(ctx);
if (inputSize < LZ4_64Klimit)
- return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
+ result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
else
- return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
+ result = LZ4_compress_generic(&ctx->internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
+
+ FREEMEM(ctx);
+
+ return result;
}
@@ -1045,11 +1042,13 @@ static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src,
int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
{
- LZ4_stream_t ctxBody;
- LZ4_stream_t* ctx = &ctxBody;
+ LZ4_stream_t* ctxBody = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));;
+ LZ4_stream_t* ctx = ctxBody;
int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
+ FREEMEM(ctxBody);
+
return result;
}
diff --git a/bdk/libs/fatfs/diskio.h b/bdk/libs/fatfs/diskio.h
index 6959fb4..b5299c6 100644
--- a/bdk/libs/fatfs/diskio.h
+++ b/bdk/libs/fatfs/diskio.h
@@ -27,7 +27,8 @@ typedef enum {
DRIVE_SD = 0,
DRIVE_RAM = 1,
DRIVE_EMMC = 2,
- DRIVE_BIS = 3
+ DRIVE_BIS = 3,
+ DRIVE_EMU = 4
} DDRIVE;
@@ -59,6 +60,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
#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 */
diff --git a/bdk/libs/fatfs/ff.c b/bdk/libs/fatfs/ff.c
index 9035f35..109e87b 100644
--- a/bdk/libs/fatfs/ff.c
+++ b/bdk/libs/fatfs/ff.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2019 CTCaer
+ * Copyright (c) 2018-2022 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,
@@ -38,6 +38,7 @@
#include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of device I/O functions */
+#include
#include
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
@@ -3273,7 +3274,6 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
stat = disk_status(fs->pdrv);
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
- EFSPRINTF("WPEN1");
return FR_WRITE_PROTECTED;
}
return FR_OK; /* The filesystem object is valid */
@@ -3284,14 +3284,13 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */
fs->fs_type = 0; /* Clear the filesystem object */
+ fs->part_type = 0; /* Clear the Partition object */
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
- EFSPRINTF("MDNR");
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
}
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */
- EFSPRINTF("WPEN2");
return FR_WRITE_PROTECTED;
}
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
@@ -3318,6 +3317,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
EFSPRINTF("BRNL");
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
}
+#if FF_SIMPLE_GPT
+ if (fmt >= 2) {
+ /* If GPT Check the first partition */
+ 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 */
+ }
+ }
+#endif
if (fmt >= 2) {
EFSPRINTF("NOFAT");
return FR_NO_FILESYSTEM; /* No FAT volume is found */
@@ -4685,20 +4698,27 @@ 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 */
ff_memfree(fp->cltbl);
- fp->cltbl = NULL;
+ fp->cltbl = (void *)0;
EFSPRINTF("CLTBLSZ");
- return NULL;
+ return (void *)0;
}
f_lseek(fp, 0);
@@ -5866,7 +5886,7 @@ FRESULT f_mkfs (
stat = disk_initialize(pdrv);
if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
- if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */
+ if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 131072 || (sz_blk & (sz_blk - 1))) sz_blk = 2048; /* Erase block to align data area. 1MB minimum */
#if FF_MAX_SS != FF_MIN_SS /* Get sector size of the medium if variable sector size cfg. */
if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;
if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;
@@ -5902,7 +5922,7 @@ FRESULT f_mkfs (
} else {
/* Create a single-partition in this function */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
- b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */
+ b_vol = (opt & FM_SFD) ? 0 : sz_blk; /* Volume start sector */
if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);
sz_vol -= b_vol; /* Volume size */
}
@@ -6169,7 +6189,9 @@ FRESULT f_mkfs (
#endif
/* Create FAT VBR */
mem_set(buf, 0, ss);
- mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */
+ /* Boot jump code (x86), OEM name */
+ if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.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] */
st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */
@@ -6182,23 +6204,27 @@ FRESULT f_mkfs (
}
buf[BPB_Media] = 0xF8; /* Media descriptor byte */
st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */
- st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */
+ st_word(buf + BPB_NumHeads, (opt & FM_PRF2) ? 16 : 255); /* Number of heads (for int13) */
st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */
if (fmt == FS_FAT32) {
- st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */
+ st_dword(buf + BS_VolID32, (opt & FM_PRF2) ? 0 : GET_FATTIME()); /* VSN */
st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */
st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */
st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig32] = 0x29; /* Extended boot signature */
- mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */
+ /* Volume label, FAT signature */
+ if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab32, FF_MKFS_LABEL "FAT32 ", 19);
+ else mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19);
} else {
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig] = 0x29; /* Extended boot signature */
- mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */
+ /* Volume label, FAT signature */
+ if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab, FF_MKFS_LABEL "FAT ", 19);
+ else mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19);
}
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
@@ -6209,13 +6235,35 @@ FRESULT f_mkfs (
mem_set(buf, 0, ss);
st_dword(buf + FSI_LeadSig, 0x41615252);
st_dword(buf + FSI_StrucSig, 0x61417272);
- st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
- st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */
+ if (opt & FM_PRF2) {
+ st_dword(buf + FSI_Free_Count, 0xFFFFFFFF); /* Invalidate free count */
+ st_dword(buf + FSI_Nxt_Free, 0xFFFFFFFF); /* Invalidate last allocated cluster */
+ } else {
+ st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
+ st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */
+ }
st_word(buf + BS_55AA, 0xAA55);
disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
}
+ /* Create PRF2SAFE info */
+ 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) */
+ }
+
/* Initialize FAT area */
mem_set(buf, 0, (UINT)szb_buf);
sect = b_fat; /* FAT start sector */
@@ -6705,6 +6753,8 @@ int f_puts (
putbuff pb;
+ if (str == (void *)0) return EOF; /* String is NULL */
+
putc_init(&pb, fp);
while (*str) putc_bfd(&pb, *str++); /* Put the string */
return putc_flush(&pb);
@@ -6731,6 +6781,8 @@ int f_printf (
TCHAR c, d, str[32], *p;
+ if (fmt == (void *)0) return EOF; /* String is NULL */
+
putc_init(&pb, fp);
va_start(arp, fmt);
diff --git a/bdk/libs/fatfs/ff.h b/bdk/libs/fatfs/ff.h
index a83cf63..3a6c423 100644
--- a/bdk/libs/fatfs/ff.h
+++ b/bdk/libs/fatfs/ff.h
@@ -95,8 +95,8 @@ typedef DWORD FSIZE_t;
/* Filesystem object structure (FATFS) */
typedef struct {
- BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
BYTE fs_type; /* Filesystem type (0:not mounted) */
+ BYTE part_type; /* Partition type (0:MBR, 1:GPT) */
BYTE pdrv; /* Associated physical drive */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
@@ -138,6 +138,7 @@ typedef struct {
DWORD bitbase; /* Allocation bitmap base sector */
#endif
DWORD winsect; /* Current sector appearing in the win[] */
+ BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg). DMA aligned. */
} FATFS;
@@ -168,9 +169,6 @@ typedef struct {
/* File object structure (FIL) */
typedef struct {
-#if !FF_FS_TINY
- BYTE buf[FF_MAX_SS]; /* File private data read/write window */
-#endif
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
@@ -184,6 +182,9 @@ typedef struct {
#if FF_USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
+#if !FF_FS_TINY
+ BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window. DMA aligned. */
+#endif
} FIL;
@@ -365,6 +366,7 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
+#define FM_PRF2 0x10
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
diff --git a/nyx/nyx_gui/libs/fatfs/ffsystem.c b/bdk/libs/fatfs/ffsystem.c
similarity index 79%
rename from nyx/nyx_gui/libs/fatfs/ffsystem.c
rename to bdk/libs/fatfs/ffsystem.c
index cdd2a7a..b4af454 100644
--- a/nyx/nyx_gui/libs/fatfs/ffsystem.c
+++ b/bdk/libs/fatfs/ffsystem.c
@@ -1,16 +1,12 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
-/* (C) ChaN, 2018 */
-/* (C) CTCaer, 2018 */
+/* (C) ChaN, 2018 */
+/* (C) CTCaer, 2018-2024 */
/*------------------------------------------------------------------------*/
+#include
#include
-#include "../../config.h"
-#include
-#include
-
-extern nyx_config n_cfg;
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
@@ -22,7 +18,8 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if no
UINT msize /* Number of bytes to allocate */
)
{
- return malloc(msize); /* Allocate a new memory block with POSIX API */
+ // Ensure size is aligned to SDMMC block size.
+ return malloc(ALIGN(msize, SDMMC_DAT_BLOCKSIZE)); /* Allocate a new memory block with POSIX API */
}
@@ -51,12 +48,7 @@ DWORD get_fattime (
{
rtc_time_t time;
- max77620_rtc_get_time(&time);
- if (n_cfg.timeoff)
- {
- u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff);
- max77620_rtc_epoch_to_date(epoch, &time);
- }
+ max77620_rtc_get_time_adjusted(&time);
return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) |
((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1));
diff --git a/bdk/libs/lv_conf.h b/bdk/libs/lv_conf.h
index 7af36a4..89dc555 100644
--- a/bdk/libs/lv_conf.h
+++ b/bdk/libs/lv_conf.h
@@ -17,7 +17,7 @@
#ifndef LV_CONF_H
#define LV_CONF_H
-#include
+#include
#include
/*===================
Dynamic memory
@@ -147,10 +147,10 @@
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
/*HAL settings*/
-#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
+#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
#if LV_TICK_CUSTOM == 1
-#define LV_TICK_CUSTOM_INCLUDE /*Header for the sys time function*/
-#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
+#define LV_TICK_CUSTOM_INCLUDE /*Header for the sys time function*/
+#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((u32)get_tmr_ms()) /*Expression evaluating to current systime in ms*/
#endif /*LV_TICK_CUSTOM*/
@@ -296,6 +296,9 @@
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
#define USE_LV_MBOX 1
+#if USE_LV_MBOX != 0
+# define LV_MBOX_CLOSE_ANIM_TIME 200 /*ms*/
+#endif
/*Text area (dependencies: lv_label, lv_page)*/
#define USE_LV_TA 1
diff --git a/bdk/libs/lvgl/lv_core/lv_group.c b/bdk/libs/lvgl/lv_core/lv_group.c
index 3fd4120..cedef7f 100644
--- a/bdk/libs/lvgl/lv_core/lv_group.c
+++ b/bdk/libs/lvgl/lv_core/lv_group.c
@@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
/*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/
- lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
- lv_obj_invalidate(last_top);
+ if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
+ lv_obj_invalidate(last_top); /*Only invalidate if not top*/
}
}
diff --git a/bdk/libs/lvgl/lv_core/lv_indev.c b/bdk/libs/lvgl/lv_core/lv_indev.c
index 763abf7..d1dc582 100644
--- a/bdk/libs/lvgl/lv_core/lv_indev.c
+++ b/bdk/libs/lvgl/lv_core/lv_indev.c
@@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/
- lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
- lv_obj_invalidate(last_top);
+ if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
+ lv_obj_invalidate(last_top); /*Only invalidate if not top*/
}
/*Send a signal about the press*/
diff --git a/bdk/libs/lvgl/lv_misc/lv_color.h b/bdk/libs/lvgl/lv_misc/lv_color.h
index 3459b63..59f038f 100644
--- a/bdk/libs/lvgl/lv_misc/lv_color.h
+++ b/bdk/libs/lvgl/lv_misc/lv_color.h
@@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
#endif
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
-#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
+#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
#else
-#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
- ((uint32_t)((uint32_t)c >> 8) & 0xFF), \
- ((uint32_t) c & 0xFF))
+#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
+ ((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
+ ((uint32_t) (c) & 0xFF))
#endif
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
-#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
- ((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
- ((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
+#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
+ ((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
+ ((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
/**
diff --git a/bdk/libs/lvgl/lv_misc/lv_ll.c b/bdk/libs/lvgl/lv_misc/lv_ll.c
index 43d8847..5583311 100644
--- a/bdk/libs/lvgl/lv_misc/lv_ll.c
+++ b/bdk/libs/lvgl/lv_misc/lv_ll.c
@@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
* @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list
* @param node pointer to a node
+ * @return head changed
*/
-void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
+bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
{
+ bool changed = ll_new_p->head != node;
+
lv_ll_rem(ll_ori_p, node);
/*Set node as head*/
@@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
ll_new_p->tail = node;
}
+
+ return changed;
}
/**
diff --git a/bdk/libs/lvgl/lv_misc/lv_ll.h b/bdk/libs/lvgl/lv_misc/lv_ll.h
index 086ba40..5bde7e5 100644
--- a/bdk/libs/lvgl/lv_misc/lv_ll.h
+++ b/bdk/libs/lvgl/lv_misc/lv_ll.h
@@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
* @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list
* @param node pointer to a node
+ * @return head changed
*/
-void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
+bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
/**
* Return with head node of the linked list
diff --git a/bdk/libs/lvgl/lv_themes/lv_theme_hekate.c b/bdk/libs/lvgl/lv_themes/lv_theme_hekate.c
index d12732c..f151dbe 100644
--- a/bdk/libs/lvgl/lv_themes/lv_theme_hekate.c
+++ b/bdk/libs/lvgl/lv_themes/lv_theme_hekate.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 CTCaer
+ * Copyright (c) 2018-2022 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,13 +32,16 @@
#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_ORANGE LV_COLOR_HEX(0xFF5500)
-#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_LIGHT LV_COLOR_HEX(0x3D3D3D)
-#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
#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_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.
+
+
/**********************
* TYPEDEFS
**********************/
@@ -57,8 +60,9 @@ static lv_style_t def;
static lv_style_t sb;
/*Saved input parameters*/
-static uint16_t _hue;
+static uint16_t _hue;
static lv_font_t * _font;
+uint32_t theme_bg_color;
/**********************
* MACROS
@@ -80,18 +84,17 @@ static void basic_init(void)
//def.image.opa = LV_OPA_COVER;
lv_style_copy(&bg, &def);
- bg.body.main_color = COLOR_HOS_BG;
- //bg.body.main_color = LV_COLOR_BLACK;
+ bg.body.main_color = COLOR_BG;
bg.body.grad_color = bg.body.main_color;
bg.body.radius = 0;
bg.body.empty = 1;
lv_style_copy(&panel, &def);
panel.body.radius = DEF_RADIUS;
- panel.body.main_color = COLOR_HOS_BG;
- panel.body.grad_color = COLOR_HOS_BG;
+ panel.body.main_color = COLOR_BG;
+ panel.body.grad_color = COLOR_BG;
panel.body.border.width = 1;
- panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
+ panel.body.border.color = COLOR_LIGHT_BORDER;
panel.body.border.opa = LV_OPA_COVER;
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
panel.body.shadow.type = LV_SHADOW_BOTTOM;
@@ -129,7 +132,7 @@ static void btn_init(void)
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
lv_style_copy(&rel, &def);
- rel.body.main_color = COLOR_HOS_BG_LIGHT;
+ rel.body.main_color = COLOR_BG_LIGHT;
rel.body.grad_color = rel.body.main_color;
rel.body.radius = 6;
rel.body.padding.hor = LV_DPI / 3;
@@ -139,7 +142,7 @@ static void btn_init(void)
rel.body.shadow.type = LV_SHADOW_BOTTOM;
rel.body.shadow.width = 6;
rel.body.border.width = 0;
- rel.body.border.color = COLOR_HOS_BG_LIGHT;
+ rel.body.border.color = COLOR_BG_LIGHT;
rel.body.border.part = LV_BORDER_FULL;
//rel.text.color = COLOR_HOS_TXT_WHITE;
@@ -162,7 +165,7 @@ static void btn_init(void)
tgl_pr.body.shadow.width = 0;
lv_style_copy(&ina, &rel);
- ina.body.main_color = COLOR_HOS_BG_DARK;
+ ina.body.main_color = COLOR_BG_DARK;
ina.body.grad_color = ina.body.main_color;
//ina.body.shadow.width = 0;
ina.text.color = LV_COLOR_HEX(0x888888);
@@ -207,7 +210,7 @@ static void img_init(void)
img_light.image.intense = LV_OPA_80;
lv_style_copy(&img_dark, &def);
- img_dark.image.color = COLOR_HOS_BG_DARKER;
+ img_dark.image.color = COLOR_BG_DARKER;
img_dark.image.intense = LV_OPA_80;
@@ -250,7 +253,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_HOS_LIGHT_BORDER;
+ bar_bg.body.main_color = COLOR_LIGHT_BORDER;
bar_bg.body.grad_color = bar_bg.body.main_color;
bar_bg.body.radius = 3;
bar_bg.body.border.width = 0;
@@ -536,9 +539,9 @@ static void mbox_init(void)
static lv_style_t bg;
lv_style_copy(&bg, theme.panel);
- bg.body.main_color = LV_COLOR_HEX(0x464646);
+ bg.body.main_color = COLOR_BG_LIGHTER;
bg.body.grad_color = bg.body.main_color;
- bg.body.shadow.color = COLOR_HOS_BG;
+ bg.body.shadow.color = COLOR_BG;
bg.body.shadow.type = LV_SHADOW_FULL;
bg.body.shadow.width = 8;
@@ -628,7 +631,7 @@ static void list_init(void)
// pr.text.font = _font;
lv_style_copy(&tgl_rel, &pr);
- tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
+ tgl_rel.body.main_color = COLOR_BG_LIGHT;
tgl_rel.body.grad_color = tgl_rel.body.main_color;
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
@@ -639,7 +642,7 @@ static void list_init(void)
tgl_pr.body.border.width = 0;
lv_style_copy(&ina, &pr);
- ina.body.main_color = COLOR_HOS_BG_DARK;
+ ina.body.main_color = COLOR_BG_DARK;
ina.body.grad_color = ina.body.main_color;
theme.list.sb = &sb;
@@ -667,7 +670,7 @@ static void ddlist_init(void)
bg.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&sel, &bg);
- sel.body.main_color = COLOR_HOS_BG_LIGHT;
+ sel.body.main_color = COLOR_BG_LIGHT;
sel.body.grad_color = sel.body.main_color;
theme.ddlist.bg = &bg;
@@ -713,7 +716,7 @@ static void tabview_init(void)
indic.body.opa = LV_OPA_0;
lv_style_copy(&btn_bg, &def);
- btn_bg.body.main_color = COLOR_HOS_BG;
+ btn_bg.body.main_color = COLOR_BG;
btn_bg.body.grad_color = btn_bg.body.main_color;
btn_bg.body.radius = 0;
btn_bg.body.empty = 1;
@@ -734,7 +737,7 @@ static void tabview_init(void)
rel.text.font = _font;
lv_style_copy(&pr, &def);
- pr.body.main_color = COLOR_HOS_BG_LIGHT;
+ pr.body.main_color = COLOR_BG_LIGHT;
pr.body.grad_color = pr.body.main_color;
pr.body.border.width = 0;
pr.body.empty = 0;
@@ -750,7 +753,7 @@ static void tabview_init(void)
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&tgl_pr, &def);
- tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
+ tgl_pr.body.main_color = COLOR_BG_LIGHT;
tgl_pr.body.grad_color = tgl_pr.body.main_color;
tgl_pr.body.border.width = 0;
tgl_pr.body.empty = 0;
@@ -797,7 +800,7 @@ static void win_init(void)
static lv_style_t header, rel, pr;
lv_style_copy(&header, &def);
- header.body.main_color = COLOR_HOS_BG;
+ header.body.main_color = COLOR_BG;
header.body.grad_color = header.body.main_color;
header.body.radius = 0;
header.body.border.width = 0;
@@ -843,10 +846,11 @@ static void win_init(void)
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
-lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
+lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
{
if(font == NULL) font = LV_FONT_DEFAULT;
+ theme_bg_color = bg_color;
_hue = hue;
_font = font;
diff --git a/bdk/libs/lvgl/lv_themes/lv_theme_hekate.h b/bdk/libs/lvgl/lv_themes/lv_theme_hekate.h
index cc61d2d..45448b9 100644
--- a/bdk/libs/lvgl/lv_themes/lv_theme_hekate.h
+++ b/bdk/libs/lvgl/lv_themes/lv_theme_hekate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 CTCaer
+ * Copyright (c) 2018-2022 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,6 +35,14 @@ extern "C" {
/*********************
* DEFINES
*********************/
+#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
+#define COLOR_HOS_BG_BASE_BLACK 0x000000
+
+#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
/**********************
* TYPEDEFS
@@ -44,13 +52,15 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
+extern uint32_t theme_bg_color;
+
/**
* Initialize the material theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
-lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
+lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
/**
* Get a pointer to the theme
diff --git a/bdk/mem/emc.h b/bdk/mem/emc.h
index ea5420a..a1b4c3a 100644
--- a/bdk/mem/emc.h
+++ b/bdk/mem/emc.h
@@ -2,7 +2,7 @@
* arch/arm/mach-tegra/tegra21_emc.h
*
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
- * Copyright (c) 2019-2020, CTCaer.
+ * 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
@@ -23,6 +23,7 @@
#ifndef _EMC_H_
#define _EMC_H_
+#define EMC_INTSTATUS 0x0
#define EMC_DBG 0x8
#define EMC_CFG 0xC
#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
@@ -698,6 +699,8 @@
typedef enum _emc_mr_t
{
+ MR0_FEAT = 0,
+ MR4_TEMP = 4,
MR5_MAN_ID = 5,
MR6_REV_ID1 = 6,
MR7_REV_ID2 = 7,
@@ -710,7 +713,7 @@ enum
EMC_CHAN1 = 1
};
-typedef struct _emc_mr_data_t
+typedef struct _emc_mr_chip_data_t
{
// Device 0.
u8 rank0_ch0;
@@ -719,6 +722,12 @@ typedef struct _emc_mr_data_t
// 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
diff --git a/bdk/mem/heap.c b/bdk/mem/heap.c
index d249140..ad70729 100644
--- a/bdk/mem/heap.c
+++ b/bdk/mem/heap.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 CTCaer
+ * Copyright (c) 2018-2024 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,33 +19,44 @@
#include "heap.h"
#include
-static void _heap_create(heap_t *heap, u32 start)
+heap_t _heap;
+
+static void _heap_create(void *start)
{
- heap->start = start;
- heap->first = NULL;
+ _heap.start = start;
+ _heap.first = NULL;
+ _heap.last = NULL;
}
// Node info is before node address.
-static u32 _heap_alloc(heap_t *heap, u32 size)
+static void *_heap_alloc(u32 size)
{
hnode_t *node, *new_node;
// Align to cache line size.
size = ALIGN(size, sizeof(hnode_t));
- if (!heap->first)
+ // First allocation.
+ if (!_heap.first)
{
- node = (hnode_t *)heap->start;
+ node = (hnode_t *)_heap.start;
node->used = 1;
node->size = size;
node->prev = NULL;
node->next = NULL;
- heap->first = node;
- return (u32)node + sizeof(hnode_t);
+ _heap.first = node;
+ _heap.last = node;
+
+ return (void *)node + sizeof(hnode_t);
}
- node = heap->first;
+#ifdef BDK_MALLOC_NO_DEFRAG
+ // Get the last allocated block.
+ node = _heap.last;
+#else
+ // Get first block and find the first available one.
+ node = _heap.first;
while (true)
{
// Check if there's available unused node.
@@ -53,7 +64,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
{
// Size and offset of the new unused node.
u32 new_size = node->size - size;
- new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
+ new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + size);
// If there's aligned unused space from the old node,
// create a new one and set the leftover size.
@@ -76,7 +87,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
node->size = size;
node->used = 1;
- return (u32)node + sizeof(hnode_t);
+ return (void *)node + sizeof(hnode_t);
}
// No unused node found, try the next one.
@@ -85,23 +96,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
else
break;
}
+#endif
// No unused node found, create a new one.
- new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
+ new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
new_node->used = 1;
new_node->size = size;
new_node->prev = node;
new_node->next = NULL;
- node->next = new_node;
- return (u32)new_node + sizeof(hnode_t);
+ node->next = new_node;
+ _heap.last = new_node;
+
+ return (void *)new_node + sizeof(hnode_t);
}
-static void _heap_free(heap_t *heap, u32 addr)
+static void _heap_free(void *addr)
{
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
node->used = 0;
- node = heap->first;
+ node = _heap.first;
+
+#ifndef BDK_MALLOC_NO_DEFRAG
+ // Do simple defragmentation on next blocks.
while (node)
{
if (!node->used)
@@ -117,36 +134,42 @@ static void _heap_free(heap_t *heap, u32 addr)
}
node = node->next;
}
+#endif
}
-heap_t _heap;
-
-void heap_init(u32 base)
+void heap_init(void *base)
{
- _heap_create(&_heap, base);
+ _heap_create(base);
}
-void heap_copy(heap_t *heap)
+void heap_set(heap_t *heap)
{
memcpy(&_heap, heap, sizeof(heap_t));
}
void *malloc(u32 size)
{
- return (void *)_heap_alloc(&_heap, size);
+ return _heap_alloc(size);
}
void *calloc(u32 num, u32 size)
{
- void *res = (void *)_heap_alloc(&_heap, num * 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 free(void *buf)
{
- if ((u32)buf >= _heap.start)
- _heap_free(&_heap, (u32)buf);
+ if (buf >= _heap.start)
+ _heap_free(buf);
}
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
@@ -158,7 +181,10 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
while (true)
{
if (node->used)
+ {
+ mon->nodes_used++;
mon->used += node->size + sizeof(hnode_t);
+ }
else
mon->total += node->size + sizeof(hnode_t);
@@ -174,4 +200,5 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
break;
}
mon->total += mon->used;
+ mon->nodes_total = count;
}
diff --git a/bdk/mem/heap.h b/bdk/mem/heap.h
index 811f13d..c898ee0 100644
--- a/bdk/mem/heap.h
+++ b/bdk/mem/heap.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 CTCaer
+ * Copyright (c) 2018-2024 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,
@@ -31,20 +31,24 @@ typedef struct _hnode
typedef struct _heap
{
- u32 start;
+ void *start;
hnode_t *first;
+ hnode_t *last;
} heap_t;
typedef struct
{
- u32 total;
- u32 used;
+ u32 total;
+ u32 used;
+ u32 nodes_total;
+ u32 nodes_used;
} heap_monitor_t;
-void heap_init(u32 base);
-void heap_copy(heap_t *heap);
+void heap_init(void *base);
+void heap_set(heap_t *heap);
void *malloc(u32 size);
void *calloc(u32 num, u32 size);
+void *zalloc(u32 size);
void free(void *buf);
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
diff --git a/bdk/mem/mc.c b/bdk/mem/mc.c
index cc136dc..4e6ede6 100644
--- a/bdk/mem/mc.c
+++ b/bdk/mem/mc.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018-2024 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,12 +15,13 @@
* along with this program. If not, see .
*/
+#include
#include
+#include
#include
#include
-#include
-void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
+void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
{
MC(MC_SEC_CARVEOUT_BOM) = bom;
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
@@ -30,105 +31,56 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
void mc_config_carveout()
{
+ // Enable ACR GSR3.
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MC(MC_VIDEO_PROTECT_BOM) = 0;
- MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
- MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
+ MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
- // Configure TSEC carveout @ 0x90000000, 1MB.
- //mc_config_tsec_carveout(0x90000000, 1, false);
- mc_config_tsec_carveout(0, 0, true);
+ // Configure TZDRAM carveout @ 0x90000000, 1MB.
+ //mc_config_tzdram_carveout(0x90000000, 1, false);
+ mc_config_tzdram_carveout(0, 0, true);
MC(MC_MTS_CARVEOUT_BOM) = 0;
- MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
- MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
- MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
- MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
+ 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;
- MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
- MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
+ MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
- MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
- MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
- MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
-
- MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
- MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
+ 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;
- MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
- MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
- MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
- MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
+ MC(MC_SECURITY_CARVEOUT5_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;
}
void mc_enable_ahb_redirect()
{
// Enable ARC_CLK_OVR_ON.
- CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000;
- //MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
- MC(MC_IRAM_BOM) = 0x40000000;
- MC(MC_IRAM_TOM) = 0x4003F000;
+ 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.
}
void mc_disable_ahb_redirect()
@@ -136,24 +88,36 @@ void mc_disable_ahb_redirect()
MC(MC_IRAM_BOM) = 0xFFFFF000;
MC(MC_IRAM_TOM) = 0;
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
- //MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
+ //MC(MC_IRAM_REG_CTRL) |= BIT(0);
// Disable ARC_CLK_OVR_ON.
- CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF;
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
+}
+
+bool mc_client_has_access(void *address)
+{
+ // Check if address is in DRAM or if arbitration for IRAM is enabled.
+ if ((u32)address >= DRAM_START)
+ return true; // Access by default.
+ else if ((u32)address >= IRAM_BASE && MC(MC_IRAM_BOM) == IRAM_BASE)
+ return true; // Access by AHB arbitration.
+
+ // No access to address space.
+ return false;
}
void mc_enable()
{
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
- // Enable memory clocks.
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_EMC)) | BIT(CLK_H_EMC);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_MEM)) | BIT(CLK_H_MEM);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & ~BIT(CLK_X_EMC_DLL)) | BIT(CLK_X_EMC_DLL);
- // Clear clock resets for memory.
+ // 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 CONFIG_ENABLE_AHB_REDIRECT
+#ifdef BDK_MC_ENABLE_AHB_REDIRECT
+ mc_enable_ahb_redirect();
+#else
mc_disable_ahb_redirect();
- //mc_enable_ahb_redirect();
- //#endif
+#endif
}
diff --git a/bdk/mem/mc.h b/bdk/mem/mc.h
index 1a9bc83..300bbfd 100644
--- a/bdk/mem/mc.h
+++ b/bdk/mem/mc.h
@@ -25,6 +25,7 @@ void mc_config_carveout();
void mc_config_carveout_finalize();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
+bool mc_client_has_access(void *address);
void mc_enable();
#endif
diff --git a/bdk/mem/mc_t210.h b/bdk/mem/mc_t210.h
index a7a9877..ff96b9d 100644
--- a/bdk/mem/mc_t210.h
+++ b/bdk/mem/mc_t210.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2014, NVIDIA Corporation.
+ * Copyright (c) 2018-2023, CTCaer
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -14,6 +15,22 @@
#ifndef _MC_T210_H_
#define _MC_T210_H_
+/*! MC SMMU registers */
+#define MC_SMMU_CONFIG 0x10
+#define MC_SMMU_TLB_CONFIG 0x14
+#define MC_SMMU_PTC_CONFIG 0x18
+#define MC_SMMU_PTB_ASID 0x1c
+#define MC_SMMU_PTB_DATA 0x20
+#define MC_SMMU_TLB_FLUSH 0x30
+#define MC_SMMU_PTC_FLUSH 0x34
+#define MC_SMMU_ASID_SECURITY 0x38
+#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
+#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
+#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
+#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
+#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
+
+/*! MC General registers */
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
@@ -464,11 +481,111 @@
#define MC_UNTRANSLATED_REGION_CHECK 0x948
#define MC_DA_CONFIG0 0x9dc
+/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */
+#define SEC_CARVEOUT_CA0_R_PTCR BIT(0)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0B BIT(3)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0BB BIT(4)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0C BIT(5)
+#define SEC_CARVEOUT_CA0_R_DISPLAY0CB BIT(6)
+#define SEC_CARVEOUT_CA0_R_AFI BIT(14)
+#define SEC_CARVEOUT_CA0_R_BPMP_C BIT(15)
+#define SEC_CARVEOUT_CA0_R_DISPLAYHC BIT(16)
+#define SEC_CARVEOUT_CA0_R_DISPLAYHCB BIT(17)
+#define SEC_CARVEOUT_CA0_R_HDA BIT(21)
+#define SEC_CARVEOUT_CA0_R_HOST1XDMA BIT(22)
+#define SEC_CARVEOUT_CA0_R_HOST1X BIT(23)
+#define SEC_CARVEOUT_CA0_R_NVENC BIT(28)
+#define SEC_CARVEOUT_CA0_R_PPCSAHBDMA BIT(29)
+#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30)
+#define SEC_CARVEOUT_CA0_R_SATAR BIT(31)
+
+/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */
+#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2)
+#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3)
+#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4)
+#define SEC_CARVEOUT_CA1_R_VDETPE BIT(5)
+#define SEC_CARVEOUT_CA1_R_CCPLEXLP_C BIT(6)
+#define SEC_CARVEOUT_CA1_R_CCPLEX_C BIT(7)
+#define SEC_CARVEOUT_CA1_W_NVENC BIT(11)
+#define SEC_CARVEOUT_CA1_W_AFI BIT(17)
+#define SEC_CARVEOUT_CA1_W_BPMP_C BIT(18)
+#define SEC_CARVEOUT_CA1_W_HDA BIT(21)
+#define SEC_CARVEOUT_CA1_W_HOST1X BIT(22)
+#define SEC_CARVEOUT_CA1_W_CCPLEXLP_C BIT(24)
+#define SEC_CARVEOUT_CA1_W_CCPLEX_C BIT(25)
+#define SEC_CARVEOUT_CA1_W_PPCSAHBDMA BIT(27)
+#define SEC_CARVEOUT_CA1_W_PPCSAHBSLV BIT(28)
+#define SEC_CARVEOUT_CA1_W_SATA BIT(29)
+#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30)
+#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31)
+
+/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */
+#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0)
+#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1)
+#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
+#define SEC_CARVEOUT_CA2_W_ISPWA BIT(6)
+#define SEC_CARVEOUT_CA2_W_ISPWB BIT(7)
+#define SEC_CARVEOUT_CA2_R_XUSB_HOST BIT(10)
+#define SEC_CARVEOUT_CA2_W_XUSB_HOST BIT(11)
+#define SEC_CARVEOUT_CA2_R_XUSB_DEV BIT(12)
+#define SEC_CARVEOUT_CA2_W_XUSB_DEV BIT(13)
+#define SEC_CARVEOUT_CA2_R_SE2 BIT(14)
+#define SEC_CARVEOUT_CA2_W_SE2 BIT(16)
+#define SEC_CARVEOUT_CA2_R_TSEC BIT(20)
+#define SEC_CARVEOUT_CA2_W_TSEC BIT(21)
+#define SEC_CARVEOUT_CA2_R_ADSP_SC BIT(22)
+#define SEC_CARVEOUT_CA2_W_ADSP_SC BIT(23)
+#define SEC_CARVEOUT_CA2_R_GPU BIT(24)
+#define SEC_CARVEOUT_CA2_W_GPU BIT(25)
+#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26)
+
+/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */
+#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0)
+#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1)
+#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
+#define SEC_CARVEOUT_CA3_R_SDMMCAB BIT(3)
+#define SEC_CARVEOUT_CA3_W_SDMMCA BIT(4)
+#define SEC_CARVEOUT_CA3_W_SDMMCAA BIT(5)
+#define SEC_CARVEOUT_CA3_W_SDMMC BIT(6)
+#define SEC_CARVEOUT_CA3_W_SDMMCAB BIT(7)
+#define SEC_CARVEOUT_CA3_R_VIC BIT(12)
+#define SEC_CARVEOUT_CA3_W_VIC BIT(13)
+#define SEC_CARVEOUT_CA3_W_VIW BIT(18)
+#define SEC_CARVEOUT_CA3_R_DISPLAYD BIT(19)
+#define SEC_CARVEOUT_CA3_R_NVDEC BIT(24)
+#define SEC_CARVEOUT_CA3_W_NVDEC BIT(25)
+#define SEC_CARVEOUT_CA3_R_APE BIT(26)
+#define SEC_CARVEOUT_CA3_W_APE BIT(27)
+#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
+#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31)
+
+/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */
+#define SEC_CARVEOUT_CA4_R_SE BIT(0)
+#define SEC_CARVEOUT_CA4_W_SE BIT(1)
+#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)
+#define SEC_CARVEOUT_CA4_W_AXIAP BIT(3)
+#define SEC_CARVEOUT_CA4_R_ETR BIT(4)
+#define SEC_CARVEOUT_CA4_W_ETR BIT(5)
+#define SEC_CARVEOUT_CA4_R_TSECB BIT(6)
+#define SEC_CARVEOUT_CA4_W_TSECB BIT(7)
+#define SEC_CARVEOUT_CA4_R_GPU2 BIT(8)
+#define SEC_CARVEOUT_CA4_W_GPU2 BIT(9)
+
+// MC_VIDEO_PROTECT_REG_CTRL
+#define VPR_LOCK_MODE_SHIFT 0
+#define VPR_CTRL_UNLOCKED (0 << VPR_LOCK_MODE_SHIFT)
+#define VPR_CTRL_LOCKED (1 << VPR_LOCK_MODE_SHIFT)
+#define VPR_PROTECT_MODE_SHIFT 1
+#define SEC_CTRL_SECURE (0 << VPR_PROTECT_MODE_SHIFT)
+#define VPR_CTRL_TZ_SECURE (1 << VPR_PROTECT_MODE_SHIFT)
+
// MC_SECURITY_CARVEOUTX_CFG0
// Mode of LOCK_MODE.
#define PROTECT_MODE_SHIFT 0
-#define SEC_CARVEOUT_CFG_SECURE (0 << PROTECT_MODE_SHIFT0)
-#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT0)
+#define SEC_CARVEOUT_CFG_ALL_SECURE (0 << PROTECT_MODE_SHIFT)
+#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT)
// Enables PROTECT_MODE.
#define LOCK_MODE_SHIFT 1
#define SEC_CARVEOUT_CFG_UNLOCKED (0 << LOCK_MODE_SHIFT)
@@ -479,30 +596,31 @@
#define SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY (1 << ADDRESS_TYPE_SHIFT)
#define READ_ACCESS_LEVEL_SHIFT 3
-#define SEC_CARVEOUT_CFG_RD_ALL (1 << READ_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_RD_UNK (2 << READ_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_RD_NS (1 << READ_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_RD_SEC (2 << READ_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_RD_FALCON_LS (4 << READ_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_RD_FALCON_HS (8 << READ_ACCESS_LEVEL_SHIFT)
#define WRITE_ACCESS_LEVEL_SHIFT 7
-#define SEC_CARVEOUT_CFG_WR_ALL (1 << WRITE_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_WR_UNK (2 << WRITE_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_WR_NS (1 << WRITE_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_WR_SEC (2 << WRITE_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_WR_FALCON_LS (4 << WRITE_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_WR_FALCON_HS (8 << WRITE_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_APERTURE_ID_MASK (3 << 11)
+#define SEC_CARVEOUT_CFG_APERTURE_ID(id) ((id) << 11)
#define DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT 14
-#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L0 (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L1 (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L2 (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L3 (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_NS (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_SEC (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_LS (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_HS (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
#define DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT 18
-#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L0 (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L1 (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L2 (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
-#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L3 (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_NS (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_SEC (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_LS (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
+#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_HS (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU BIT(22)
diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c
index 183b633..3fd05e4 100644
--- a/bdk/mem/minerva.c
+++ b/bdk/mem/minerva.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2024 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,21 +19,26 @@
#include "minerva.h"
-#include
#include
+#include
#include
#include
#include
#include
#include
+#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;
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init()
{
- u32 curr_ram_idx = 0;
+ u32 tbl_idx = 0;
minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
@@ -42,7 +47,7 @@ u32 minerva_init()
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
return 0;
-#ifdef NYX
+#ifdef BDK_MINERVA_CFG_FROM_RAM
// Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
@@ -60,7 +65,7 @@ u32 minerva_init()
mtc_config_t mtc_tmp;
mtc_tmp.mtc_table = mtc_cfg->mtc_table;
- mtc_tmp.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
+ mtc_tmp.sdram_id = fuse_read_dramid(false);
mtc_tmp.init_done = MTC_NEW_MAGIC;
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp);
@@ -81,7 +86,7 @@ u32 minerva_init()
// Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
- mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
+ mtc_cfg->sdram_id = fuse_read_dramid(false);
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
@@ -97,28 +102,29 @@ u32 minerva_init()
return 1;
// Get current frequency
- for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
+ 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 (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
+ if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
break;
}
- mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
- mtc_cfg->rate_to = 204000;
+ mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
+ mtc_cfg->rate_to = FREQ_204;
mtc_cfg->train_mode = OP_TRAIN;
minerva_cfg(mtc_cfg, NULL);
- mtc_cfg->rate_to = 800000;
+ mtc_cfg->rate_to = FREQ_800;
minerva_cfg(mtc_cfg, NULL);
- mtc_cfg->rate_to = 1600000;
+ mtc_cfg->rate_to = FREQ_1600;
minerva_cfg(mtc_cfg, NULL);
// FSP WAR.
mtc_cfg->train_mode = OP_SWITCH;
- mtc_cfg->rate_to = 800000;
+ mtc_cfg->rate_to = FREQ_800;
minerva_cfg(mtc_cfg, NULL);
// Switch to max.
- mtc_cfg->rate_to = 1600000;
+ mtc_cfg->rate_to = FREQ_1600;
minerva_cfg(mtc_cfg, NULL);
return 0;
@@ -129,6 +135,7 @@ void minerva_change_freq(minerva_freq_t freq)
if (!minerva_cfg)
return;
+ // 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)
{
@@ -138,6 +145,110 @@ void minerva_change_freq(minerva_freq_t freq)
}
}
+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));
+
+ // Adjust SDMMC1 latency allowance.
+ switch (freq)
+ {
+ case 204000:
+ la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
+ break;
+ case 408000:
+ la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
+ break;
+ default:
+ la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
+ break;
+ }
+}
+
+void minerva_prep_boot_freq()
+{
+ if (!minerva_cfg)
+ return;
+
+ mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
+
+ // Check if there's RAM OC. If not exit.
+ if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
+ return;
+
+ // FSP WAR.
+ minerva_change_freq(FREQ_204);
+ // Scale down to 800 MHz boot freq.
+ minerva_change_freq(FREQ_800);
+}
+
+void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
+{
+ if (!minerva_cfg)
+ 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);
+
+ // Add OC frequency.
+ if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
+ {
+ memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
+ &mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
+ sizeof(emc_table_t));
+
+ mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
+ mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
+ mtc_cfg->table_entries++;
+ }
+
+ // Trim table.
+ int entries = 0;
+ for (u32 i = 0; i < mtc_cfg->table_entries; i++)
+ {
+ // Copy frequencies from 204/408/800 MHz and 1333+ MHz.
+ int rate = mtc_cfg->mtc_table[i].rate_khz;
+ if (rate == FREQ_204 ||
+ rate == FREQ_408 ||
+ rate == FREQ_800 ||
+ rate >= FREQ_1333)
+ {
+ memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
+ entries++;
+ }
+ }
+ mtc_cfg->table_entries = entries;
+
+ // Set init frequency.
+ minerva_change_freq(FREQ_204);
+
+ // Train the rest of the frequencies.
+ mtc_cfg->train_mode = OP_TRAIN;
+ for (u32 i = 0; i < mtc_cfg->table_entries; i++)
+ {
+ // Skip already trained frequencies and OC freq (Arachne handles it).
+ if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
+ continue;
+
+ // Train frequency.
+ mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
+ minerva_cfg(mtc_cfg, NULL);
+ }
+
+ // Do FSP WAR and scale to 800 MHz as boot freq.
+ bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
+ if (fsp_opwr_disabled)
+ minerva_change_freq(FREQ_1333);
+ minerva_change_freq(FREQ_800);
+
+ // Do not let other mtc ops.
+ mtc_cfg->init_done = 0;
+}
+
void minerva_periodic_training()
{
if (!minerva_cfg)
@@ -149,4 +260,22 @@ void minerva_periodic_training()
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
minerva_cfg(mtc_cfg, NULL);
}
-}
\ No newline at end of file
+}
+
+emc_table_t *minerva_get_mtc_table()
+{
+ if (!minerva_cfg)
+ 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)
+ return 0;
+
+ mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
+ return mtc_cfg->table_entries;
+}
diff --git a/bdk/mem/minerva.h b/bdk/mem/minerva.h
index ed80b95..e78bb41 100644
--- a/bdk/mem/minerva.h
+++ b/bdk/mem/minerva.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2022 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,
@@ -27,8 +27,8 @@
typedef struct
{
- s32 rate_to;
- s32 rate_from;
+ u32 rate_to;
+ u32 rate_from;
emc_table_t *mtc_table;
u32 table_entries;
emc_table_t *current_emc_table;
@@ -38,7 +38,7 @@ typedef struct
bool emc_2X_clk_src_is_pllmb;
bool fsp_for_src_freq;
bool train_ram_patterns;
- bool init_done;
+ u32 init_done;
} mtc_config_t;
enum train_mode_t
@@ -53,13 +53,20 @@ enum train_mode_t
typedef enum
{
FREQ_204 = 204000,
+ FREQ_408 = 408000,
FREQ_800 = 800000,
+ FREQ_1333 = 1331200,
FREQ_1600 = 1600000
} minerva_freq_t;
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init();
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_periodic_training();
+emc_table_t *minerva_get_mtc_table();
+int minerva_get_mtc_table_entries();
#endif
diff --git a/bdk/mem/mtc_table.h b/bdk/mem/mtc_table.h
index e24fa81..7802280 100644
--- a/bdk/mem/mtc_table.h
+++ b/bdk/mem/mtc_table.h
@@ -481,7 +481,8 @@ typedef struct
u32 rate_khz;
u32 min_volt;
u32 gpu_min_volt;
- char clock_src[32];
+ char clock_src[28];
+ u32 opt_custom;
u32 clk_src_emc;
u32 needs_training;
u32 training_pattern;
diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c
index aad98db..4aa98fa 100644
--- a/bdk/mem/sdram.c
+++ b/bdk/mem/sdram.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011
- * Copyright (c) 2019-2020 CTCaer
+ * Copyright (c) 2019-2023 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,
@@ -31,34 +31,60 @@
#include
#include
#include
+#include
#include
-#include
-#define CONFIG_SDRAM_KEEP_ALIVE
-
-//#define CONFIG_SDRAM_COMPRESS_CFG
+#define DRAM_ID(x) BIT(x)
+#define DRAM_CC(x) BIT(x)
typedef struct _sdram_vendor_patch_t
{
u32 val;
- u32 addr:10;
- u32 dramid:22;
+ u32 dramcf:16;
+ u32 offset:16;
} sdram_vendor_patch_t;
-#ifdef CONFIG_SDRAM_COMPRESS_CFG
- #include
- #include "sdram_config_lz.inl"
-#else
- #include "sdram_config.inl"
-#endif
+static const u8 dram_encoding_t210b01[] = {
+/* 00 */ LPDDR4X_UNUSED,
+/* 01 */ LPDDR4X_UNUSED,
+/* 02 */ LPDDR4X_UNUSED,
+/* 03 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE,
+/* 04 */ LPDDR4X_UNUSED,
+/* 05 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE,
+/* 06 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE,
+/* 07 */ LPDDR4X_UNUSED,
+/* 08 */ LPDDR4X_NO_PATCH,
+/* 09 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ,
+/* 10 */ LPDDR4X_NO_PATCH,
+/* 11 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE,
+/* 12 */ LPDDR4X_NO_PATCH,
+/* 13 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ,
+/* 14 */ LPDDR4X_NO_PATCH,
+/* 15 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE,
+/* 16 */ LPDDR4X_UNUSED,
+/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
+/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
+/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
+/* 20 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
+/* 21 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
+/* 22 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
+/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
+/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
+/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
+/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
+/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
+/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
+/* 29 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
+/* 30 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
+/* 31 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
+/* 32 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
+/* 33 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
+/* 34 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
+};
+#include "sdram_config.inl"
#include "sdram_config_t210b01.inl"
-static u32 _sdram_get_id()
-{
- return ((fuse_read_odm(4) & 0xF8) >> 3);
-}
-
static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)
{
bool err = true;
@@ -99,6 +125,18 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel)
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
{
emc_mr_data_t data;
+ u32 mrr;
+ bool dual_rank = EMC(EMC_ADR_CFG) & 1;
+ bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; // Each EMC channel is a RAM chip module.
+
+ // Clear left overs.
+ for (u32 i = 0; i < 16; i++)
+ {
+ (void)EMC(EMC_MRR);
+ usleep(1);
+ }
+
+ memset(&data, 0xFF, sizeof(emc_mr_data_t));
/*
* When a dram chip has only one rank, then the info from the 2 ranks differs.
@@ -106,28 +144,106 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
*/
// Get Device 0 (Rank 0) info from both dram chips (channels).
- _sdram_req_mrr_data(BIT(31) | (mrx << 16), EMC_CHAN0);
- data.rank0_ch0 = EMC(EMC_MRR) & 0xFF;
- data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
+ _sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel);
- // Get Device 1 (Rank 1) info from both dram chips (channels).
- _sdram_req_mrr_data(BIT(30) | (mrx << 16), EMC_CHAN1);
- data.rank1_ch0 = EMC(EMC_MRR) & 0xFF;
- data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
+ // Ram module 0 info.
+ mrr = EMC_CH0(EMC_MRR);
+ data.chip0.rank0_ch0 = mrr & 0xFF;
+ data.chip0.rank0_ch1 = (mrr & 0xFF00 >> 8);
+
+ // Ram module 1 info.
+ if (dual_channel)
+ {
+ mrr = EMC_CH1(EMC_MRR);
+ data.chip1.rank0_ch0 = mrr & 0xFF;
+ data.chip1.rank0_ch1 = (mrr & 0xFF00 >> 8);
+ }
+
+ // If Rank 1 exists, get info.
+ if (dual_rank)
+ {
+ // Get Device 1 (Rank 1) info from both dram chips (channels).
+ _sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel);
+
+ // Ram module 0 info.
+ mrr = EMC_CH0(EMC_MRR);
+ data.chip0.rank1_ch0 = mrr & 0xFF;
+ data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
+
+ // Ram module 1 info.
+ if (dual_channel)
+ {
+ mrr = EMC_CH1(EMC_MRR);
+ data.chip1.rank1_ch0 = mrr & 0xFF;
+ data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
+ }
+ }
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.
+ PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
+ usleep(params->pmc_vddp_sel_wait);
+
+ // Set DDR pad voltage.
+ PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); // Normally params->pmc_ddr_pwr.
+
+ // Turn on MEM IO Power.
+ PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
+ PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
+
+ PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
+
+ // Patch 1 using BCT spare variables
+ if (params->emc_bct_spare0)
+ *(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
+
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
- u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
+ u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | PMC_IO_DPD_REQ_DPD_ON;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
- dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
+ dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | PMC_IO_DPD_REQ_DPD_ON;
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
usleep(params->pmc_io_dpd4_req_wait);
@@ -138,45 +254,42 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
usleep(1);
- // Start clocks.
+ // Start PLLM.
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
-#ifdef CONFIG_SDRAM_KEEP_ALIVE
- CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) =
- (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20) | PLLCX_BASE_ENABLE;
-#else
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;
-#endif
u32 wait_end = get_tmr_us() + 300;
- while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & 0x8000000))
+ while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & BIT(27)))
{
if (get_tmr_us() >= wait_end)
- goto break_nosleep;
+ goto lock_timeout;
}
usleep(10);
-break_nosleep:
+lock_timeout:
+ // Set clock sources.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
if (params->emc_clock_source_dll)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1)
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_MC1); // Clear Reset to MC1.
// 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);
- // Set pad macros.
+ // Set pad vtt levels.
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
usleep(10); // Ensure the regulators settle.
// Select EMC write mux.
@@ -188,7 +301,7 @@ break_nosleep:
// Program CMD mapping. Required before brick mapping, else
// we can't guarantee CK will be differential at all times.
- EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
+ EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
@@ -201,7 +314,7 @@ break_nosleep:
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
- EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
+ EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
// Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
@@ -213,6 +326,7 @@ break_nosleep:
// This is required to do any reads from the pad macros.
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
+ // Set data pipes mode.
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
// Set swizzle for Rank 0.
@@ -230,12 +344,12 @@ break_nosleep:
if (params->emc_bct_spare6)
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
- // Set pad controls.
- EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
+ // Program calibration impedance.
+ EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
- // Program Autocal controls with shadowed register fields.
+ // Program Autocal controls.
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
@@ -244,71 +358,79 @@ break_nosleep:
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
- EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
- EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
- EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
- EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
+ // Program termination and drive strength
+ EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
+ EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
+ EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
+ EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
- EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
- EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
+ EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
+ EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
- EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
- EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
+ // Program dll config.
+ EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
+ EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
+ // Program barrelshift.
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
- EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
- EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
- EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
- EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
- EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
- EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
+ EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
+ EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
+ EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
+ EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
+ EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
+ EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
EMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
+ // Program pad macros controls and termination.
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
- EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
+ EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
- EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
- EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
+ EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
+ EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
- EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;
- EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
- EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
- EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
- EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
- EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
- EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
+ EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;
+ EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
+ EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
+ EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
+ EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
+ EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
+ EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
- EMC(EMC_CFG_3) = params->emc_cfg3;
- EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
- EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
- EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
- EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
- EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
- EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
+ // Program pad macro pins/bytes.
+ EMC(EMC_CFG_3) = params->emc_cfg3;
+ EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
+ EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
+ EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
+ EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
+ EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
+ EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
- EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
- EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
- EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
- EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
- EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
- EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
- EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
- EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
- EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
- EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
- EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
- EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
+ EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
+ EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
+ EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
+ EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
+ EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
+ EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
+ EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
+ // Program inbound vref setting.
+ EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
+ EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
+ EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
+ EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
+ EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
+
+ // Program quse trimmers.
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
@@ -321,8 +443,9 @@ break_nosleep:
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
- EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
+ EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
+ // Program outbound trimmers.
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
@@ -357,11 +480,12 @@ break_nosleep:
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
+ // Program clock trimmers.
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
@@ -373,21 +497,22 @@ break_nosleep:
if (params->emc_bct_spare4)
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
// Initialize MC VPR settings.
- MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
- MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
- MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
- MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
- MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
+ MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
+ MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
+ MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
+ MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
+ MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
// Program SDRAM geometry parameters.
- MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
- MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
- MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
+ MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
+ MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
+ MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
// Program bank swizzling.
@@ -399,46 +524,47 @@ break_nosleep:
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
// Program SEC carveout (base and size).
- MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
- MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
+ MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
+ MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
// Program MTS carveout (base and size).
- MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
- MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
+ MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
+ MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
// Program the memory arbiter.
- MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
+ MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
- MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
+ MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
MC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;
- MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
- MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
- MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
- MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
- MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
- MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
- MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
- MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
- MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
- MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
- MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
- MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
- MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
- MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
- MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
- MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
- MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
- MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
- MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
- MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
- MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
- MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
- MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
- MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
+ MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
+ MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
+ MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
+ MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
+ MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
+ MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
+ MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
+ MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
+ MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
+ MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
+ MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
+ MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
+ MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
+ MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
+ MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
+ MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
+ MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
+ MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
+ MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
+ MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
+ MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
+ MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
+ MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
+ MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
- MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
+ // Trigger MC timing update.
+ MC(MC_TIMING_CONTROL) = 1;
// Program second-level clock enable overrides.
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
@@ -460,8 +586,9 @@ break_nosleep:
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
+ // Program/Start auto calibration.
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
- EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
+ EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
usleep(params->emc_auto_cal_wait);
// Patch 5 using BCT spare variables.
@@ -469,96 +596,100 @@ break_nosleep:
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
// Program EMC timing configuration.
- EMC(EMC_CFG_2) = params->emc_cfg2;
- EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
- EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
- EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
- EMC(EMC_CMDQ) = params->emc_cmd_q;
- EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;
- EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
- EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
- EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
- EMC(EMC_RC) = params->emc_rc;
- EMC(EMC_RFC) = params->emc_rfc;
- EMC(EMC_RFCPB) = params->emc_rfc_pb;
- EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;
- EMC(EMC_RFC_SLR) = params->emc_rfc_slr;
- EMC(EMC_RAS) = params->emc_ras;
- EMC(EMC_RP) = params->emc_rp;
- EMC(EMC_TPPD) = params->emc_tppd;
- EMC(EMC_R2R) = params->emc_r2r;
- EMC(EMC_W2W) = params->emc_w2w;
- EMC(EMC_R2W) = params->emc_r2w;
- EMC(EMC_W2R) = params->emc_w2r;
- EMC(EMC_R2P) = params->emc_r2p;
- EMC(EMC_W2P) = params->emc_w2p;
- EMC(EMC_CCDMW) = params->emc_ccdmw;
- EMC(EMC_RD_RCD) = params->emc_rd_rcd;
- EMC(EMC_WR_RCD) = params->emc_wr_rcd;
- EMC(EMC_RRD) = params->emc_rrd;
- EMC(EMC_REXT) = params->emc_rext;
- EMC(EMC_WEXT) = params->emc_wext;
- EMC(EMC_WDV) = params->emc_wdv;
- EMC(EMC_WDV_CHK) = params->emc_wdv_chk;
- EMC(EMC_WSV) = params->emc_wsv;
- EMC(EMC_WEV) = params->emc_wev;
- EMC(EMC_WDV_MASK) = params->emc_wdv_mask;
- EMC(EMC_WS_DURATION) = params->emc_ws_duration;
- EMC(EMC_WE_DURATION) = params->emc_we_duration;
- EMC(EMC_QUSE) = params->emc_quse;
- EMC(EMC_QUSE_WIDTH) = params->emc_quse_width;
- EMC(EMC_IBDLY) = params->emc_ibdly;
- EMC(EMC_OBDLY) = params->emc_obdly;
- EMC(EMC_EINPUT) = params->emc_einput;
+ EMC(EMC_CFG_2) = params->emc_cfg2;
+ EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
+ EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
+ EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
+ EMC(EMC_CMDQ) = params->emc_cmd_q;
+ EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;
+ EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
+ EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
+ EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
+ EMC(EMC_RC) = params->emc_rc;
+ EMC(EMC_RFC) = params->emc_rfc;
+ EMC(EMC_RFCPB) = params->emc_rfc_pb;
+ EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;
+ EMC(EMC_RFC_SLR) = params->emc_rfc_slr;
+ EMC(EMC_RAS) = params->emc_ras;
+ EMC(EMC_RP) = params->emc_rp;
+ EMC(EMC_TPPD) = params->emc_tppd;
+ EMC(EMC_R2R) = params->emc_r2r;
+ EMC(EMC_W2W) = params->emc_w2w;
+ EMC(EMC_R2W) = params->emc_r2w;
+ EMC(EMC_W2R) = params->emc_w2r;
+ EMC(EMC_R2P) = params->emc_r2p;
+ EMC(EMC_W2P) = params->emc_w2p;
+ EMC(EMC_CCDMW) = params->emc_ccdmw;
+ EMC(EMC_RD_RCD) = params->emc_rd_rcd;
+ EMC(EMC_WR_RCD) = params->emc_wr_rcd;
+ EMC(EMC_RRD) = params->emc_rrd;
+ EMC(EMC_REXT) = params->emc_rext;
+ EMC(EMC_WEXT) = params->emc_wext;
+ EMC(EMC_WDV) = params->emc_wdv;
+ EMC(EMC_WDV_CHK) = params->emc_wdv_chk;
+ EMC(EMC_WSV) = params->emc_wsv;
+ EMC(EMC_WEV) = params->emc_wev;
+ EMC(EMC_WDV_MASK) = params->emc_wdv_mask;
+ EMC(EMC_WS_DURATION) = params->emc_ws_duration;
+ EMC(EMC_WE_DURATION) = params->emc_we_duration;
+ EMC(EMC_QUSE) = params->emc_quse;
+ EMC(EMC_QUSE_WIDTH) = params->emc_quse_width;
+ EMC(EMC_IBDLY) = params->emc_ibdly;
+ EMC(EMC_OBDLY) = params->emc_obdly;
+ EMC(EMC_EINPUT) = params->emc_einput;
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
- EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
- EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
+ EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
+ EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
- EMC(EMC_DBG) = params->emc_dbg;
- EMC(EMC_QRST) = params->emc_qrst;
- EMC(EMC_ISSUE_QRST) = 1;
- EMC(EMC_ISSUE_QRST) = 0;
- EMC(EMC_QSAFE) = params->emc_qsafe;
- EMC(EMC_RDV) = params->emc_rdv;
- EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
- EMC(EMC_RDV_EARLY) = params->emc_rdv_early;
- EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
- EMC(EMC_QPOP) = params->emc_qpop;
- EMC(EMC_REFRESH) = params->emc_refresh;
- EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
+ EMC(EMC_DBG) = params->emc_dbg;
+
+ // Clear read fifo.
+ EMC(EMC_QRST) = params->emc_qrst;
+ EMC(EMC_ISSUE_QRST) = 1;
+ EMC(EMC_ISSUE_QRST) = 0;
+
+ // Program the rest of EMC timing configuration.
+ EMC(EMC_QSAFE) = params->emc_qsafe;
+ EMC(EMC_RDV) = params->emc_rdv;
+ EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
+ EMC(EMC_RDV_EARLY) = params->emc_rdv_early;
+ EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
+ EMC(EMC_QPOP) = params->emc_qpop;
+ EMC(EMC_REFRESH) = params->emc_refresh;
+ EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
EMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;
- EMC(EMC_PDEX2WR) = params->emc_pdex2wr;
- EMC(EMC_PDEX2RD) = params->emc_pdex2rd;
- EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;
- EMC(EMC_ACT2PDEN) = params->emc_act2pden;
- EMC(EMC_AR2PDEN) = params->emc_ar2pden;
- EMC(EMC_RW2PDEN) = params->emc_rw2pden;
- EMC(EMC_CKE2PDEN) = params->emc_cke2pden;
- EMC(EMC_PDEX2CKE) = params->emc_pdex2che;
- EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;
- EMC(EMC_TXSR) = params->emc_txsr;
- EMC(EMC_TXSRDLL) = params->emc_txsr_dll;
- EMC(EMC_TCKE) = params->emc_tcke;
- EMC(EMC_TCKESR) = params->emc_tckesr;
- EMC(EMC_TPD) = params->emc_tpd;
- EMC(EMC_TFAW) = params->emc_tfaw;
- EMC(EMC_TRPAB) = params->emc_trpab;
- EMC(EMC_TCLKSTABLE) = params->emc_tclkstable;
- EMC(EMC_TCLKSTOP) = params->emc_tclkstop;
- EMC(EMC_TREFBW) = params->emc_trefbw;
- EMC(EMC_ODT_WRITE) = params->emc_odt_write;
- EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
- EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
+ EMC(EMC_PDEX2WR) = params->emc_pdex2wr;
+ EMC(EMC_PDEX2RD) = params->emc_pdex2rd;
+ EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;
+ EMC(EMC_ACT2PDEN) = params->emc_act2pden;
+ EMC(EMC_AR2PDEN) = params->emc_ar2pden;
+ EMC(EMC_RW2PDEN) = params->emc_rw2pden;
+ EMC(EMC_CKE2PDEN) = params->emc_cke2pden;
+ EMC(EMC_PDEX2CKE) = params->emc_pdex2che;
+ EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;
+ EMC(EMC_TXSR) = params->emc_txsr;
+ EMC(EMC_TXSRDLL) = params->emc_txsr_dll;
+ EMC(EMC_TCKE) = params->emc_tcke;
+ EMC(EMC_TCKESR) = params->emc_tckesr;
+ EMC(EMC_TPD) = params->emc_tpd;
+ EMC(EMC_TFAW) = params->emc_tfaw;
+ EMC(EMC_TRPAB) = params->emc_trpab;
+ EMC(EMC_TCLKSTABLE) = params->emc_tclkstable;
+ EMC(EMC_TCLKSTOP) = params->emc_tclkstop;
+ EMC(EMC_TREFBW) = params->emc_trefbw;
+ EMC(EMC_ODT_WRITE) = params->emc_odt_write;
+ EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
+ EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
// Don't write CFG_ADR_EN (bit 1) here - lock bit written later.
- EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
- EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
+ EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
+ EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
EMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
- EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
+ EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
// Set pipe bypass enable bits before sending any DRAM commands.
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
@@ -567,14 +698,16 @@ break_nosleep:
if (params->boot_rom_patch_control & BIT(31))
{
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
- MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
+
+ // Trigger MC timing update.
+ MC(MC_TIMING_CONTROL) = 1;
}
// Release SEL_DPD_CMD.
- PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
+ PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | PMC_IO_DPD_REQ_DPD_OFF;
usleep(params->pmc_io_dpd3_req_wait);
- // Set autocal interval if not configured.
+ // Stall auto call measurements if periodic calibration is disabled.
if (!params->emc_auto_cal_interval)
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
@@ -583,16 +716,12 @@ break_nosleep:
// ZQ CAL setup (not actually issuing ZQ CAL now).
if (params->emc_zcal_warm_cold_boot_enables & 1)
{
- if (params->memory_type == MEMORY_TYPE_DDR3L)
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3;
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
- EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
- }
+ EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
}
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
usleep(params->emc_timing_control_wait);
// Deassert HOLD_CKE_LOW.
@@ -601,68 +730,51 @@ break_nosleep:
// Set clock enable signal.
u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
- if (params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_PIN) = pin_gpio_cfg;
- (void)EMC(EMC_PIN);
- usleep(params->emc_pin_extra_wait + 200);
- EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
- (void)EMC(EMC_PIN);
- }
+ EMC(EMC_PIN) = pin_gpio_cfg;
+ (void)EMC(EMC_PIN);
+ usleep(params->emc_pin_extra_wait + 200);
+ EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
+ (void)EMC(EMC_PIN);
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
- usleep(params->emc_pin_extra_wait + 2000);
- else if (params->memory_type == MEMORY_TYPE_DDR3L)
- usleep(params->emc_pin_extra_wait + 500);
+ usleep(params->emc_pin_extra_wait + 2000);
// Enable clock enable signal.
EMC(EMC_PIN) = pin_gpio_cfg | 0x101;
(void)EMC(EMC_PIN);
usleep(params->emc_pin_program_wait);
- // Send NOP (trigger just needs to be non-zero).
- if (params->memory_type != MEMORY_TYPE_LPDDR4)
- EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
-
- // On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high.
- if (params->memory_type == MEMORY_TYPE_LPDDR2)
- usleep(params->emc_pin_extra_wait + 200);
-
// Init zq calibration,
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
+ // Patch 6 using BCT spare variables.
+ if (params->emc_bct_spare10)
+ *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
+
+ // Write mode registers.
+ EMC(EMC_MRW2) = params->emc_mrw2;
+ EMC(EMC_MRW) = params->emc_mrw1;
+ EMC(EMC_MRW3) = params->emc_mrw3;
+ EMC(EMC_MRW4) = params->emc_mrw4;
+ EMC(EMC_MRW6) = params->emc_mrw6;
+ EMC(EMC_MRW14) = params->emc_mrw14;
+
+ EMC(EMC_MRW8) = params->emc_mrw8;
+ EMC(EMC_MRW12) = params->emc_mrw12;
+ EMC(EMC_MRW9) = params->emc_mrw9;
+ EMC(EMC_MRW13) = params->emc_mrw13;
+
+ if (params->emc_zcal_warm_cold_boot_enables & 1)
{
- // Patch 6 using BCT spare variables.
- if (params->emc_bct_spare10)
- *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
+ // Issue ZQCAL start, device 0.
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
+ usleep(params->emc_zcal_init_wait);
- // Write mode registers.
- EMC(EMC_MRW2) = params->emc_mrw2;
- EMC(EMC_MRW) = params->emc_mrw1;
- EMC(EMC_MRW3) = params->emc_mrw3;
- EMC(EMC_MRW4) = params->emc_mrw4;
- EMC(EMC_MRW6) = params->emc_mrw6;
- EMC(EMC_MRW14) = params->emc_mrw14;
-
- EMC(EMC_MRW8) = params->emc_mrw8;
- EMC(EMC_MRW12) = params->emc_mrw12;
- EMC(EMC_MRW9) = params->emc_mrw9;
- EMC(EMC_MRW13) = params->emc_mrw13;
-
- if (params->emc_zcal_warm_cold_boot_enables & 1)
+ // Issue ZQCAL latch.
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
+ // Same for device 1.
+ if (!(params->emc_dev_select & 2))
{
- // Issue ZQCAL start, device 0.
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
usleep(params->emc_zcal_init_wait);
-
- // Issue ZQCAL latch.
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
- // Same for device 1.
- if (!(params->emc_dev_select & 2))
- {
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
- usleep(params->emc_zcal_init_wait);
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;
- }
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;
}
}
@@ -670,36 +782,35 @@ break_nosleep:
PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;
// Start periodic ZQ calibration (LPDDRx only).
- if (params->memory_type && params->memory_type <= MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
- EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
- }
+ EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
+ EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
// Patch 7 using BCT spare variables.
if (params->emc_bct_spare12)
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
if (params->emc_extra_refresh_num)
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
// Enable refresh.
- EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
+ EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
- EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
- EMC(EMC_CFG) = params->emc_cfg;
- EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
+ EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
+ EMC(EMC_CFG) = params->emc_cfg;
+ EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
- EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
+ EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
- EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
+ EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
- EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
+ // Re-trigger timing to latch power saving functions.
+ EMC(EMC_TIMING_CONTROL) = 1;
// Enable EMC pipe clock gating.
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
@@ -712,8 +823,8 @@ break_nosleep:
// Lock carveouts per BCT cfg.
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
- MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
- MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
+ MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
+ MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
// Disable write access to a bunch of EMC registers.
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
@@ -721,8 +832,19 @@ break_nosleep:
static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
{
- u32 pmc_scratch1 = ~params->emc_pmc_scratch1;
- u32 pmc_scratch2 = ~params->emc_pmc_scratch2;
+ // VDDP Select.
+ PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
+ usleep(params->pmc_vddp_sel_wait);
+
+ // Turn on MEM IO Power.
+ PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
+ PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
+
+ PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
+
+ // Patch 1 using BCT spare variables
+ if (params->emc_bct_spare0)
+ *(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
// Override HW FSM if needed.
if (params->clk_rst_pllm_misc20_override_enable)
@@ -730,21 +852,23 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
- PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
- PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000;
+ u32 pmc_scratch1 = ~params->emc_pmc_scratch1;
+ PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
+ PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) | PMC_IO_DPD_REQ_DPD_ON;
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
- PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | 0x80000000;
+ u32 pmc_scratch2 = ~params->emc_pmc_scratch2;
+ PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | PMC_IO_DPD_REQ_DPD_ON;
usleep(params->pmc_io_dpd4_req_wait);
// Disable e_dpd_bg.
- PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | 0x80000000;
+ PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | PMC_IO_DPD_REQ_DPD_ON;
usleep(1);
// Program CMD mapping. Required before brick mapping, else
// we can't guarantee CK will be differential at all times.
- EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
+ EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
@@ -757,7 +881,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
- EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
+ EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
// Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
@@ -780,11 +904,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
if (params->emc_bct_spare_secure4)
*(vu32 *)params->emc_bct_spare_secure4 = params->emc_bct_spare_secure5;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
usleep(params->pmc_vddp_sel_wait + 2); // Ensure the regulators settle.
// Set clock sources.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = params->emc_clock_source;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = params->emc_clock_source;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
// Select EMC write mux.
@@ -797,6 +922,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// This is required to do any reads from the pad macros.
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
+ // Set data pipes mode.
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
// Set swizzle for Rank 0.
@@ -814,12 +940,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
if (params->emc_bct_spare6)
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
- // Set pad controls.
- EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
+ // Program calibration impedance.
+ EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
- // Program Autocal controls with shadowed register fields.
+ // Program Autocal controls.
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
@@ -828,51 +954,56 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
- EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
- EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
- EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
- EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
+ // Program termination and drive strength
+ EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
+ EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
+ EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
+ EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
- EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
- EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
+ EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
+ EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
- EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
- EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
+ // Program dll config.
+ EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
+ EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
+ // Program barrelshift.
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
- EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
- EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
- EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
- EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
- EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
- EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
+ EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
+ EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
+ EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
+ EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
+ EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
+ EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
EMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
+ // Program pad macros controls and termination.
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
- EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
+ EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
- EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
- EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
+ EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
+ EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
- EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
- EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
- EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
- EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
- EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
- EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF;
+ EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
+ EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
+ EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
+ EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
+ EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
+ EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF;
- EMC(EMC_CFG_3) = params->emc_cfg3;
- EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
- EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
- EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
- EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
- EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
- EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
+ // Program pad macro pins/bytes.
+ EMC(EMC_CFG_3) = params->emc_cfg3;
+ EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
+ EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
+ EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
+ EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
+ EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
+ EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;
@@ -887,34 +1018,37 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
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_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_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl;
+ EMC(EMC_PMACRO_CMD_PI_CTRL) = 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;
- EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
- EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
- EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
- EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
- EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
- EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
- EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
+ EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
+ EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
+ EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
+ EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
+ EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
+ EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
+ EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
+
+ // Program inbound vref setting.
+ EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
+ EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
- EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
+ EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
+ // Program quse trimmers.
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
@@ -928,6 +1062,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
+ // Program outbound trimmers.
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
@@ -962,11 +1097,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
- EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
+ // Program clock trimmers.
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
+ EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
@@ -980,27 +1116,28 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Patch 4 to 6 using BCT spare secure variables.
if (params->emc_bct_spare_secure6)
- *(vu32 *)params->emc_bct_spare_secure6 = params->emc_bct_spare_secure7;
+ *(vu32 *)params->emc_bct_spare_secure6 = params->emc_bct_spare_secure7;
if (params->emc_bct_spare_secure8)
- *(vu32 *)params->emc_bct_spare_secure8 = params->emc_bct_spare_secure9;
+ *(vu32 *)params->emc_bct_spare_secure8 = params->emc_bct_spare_secure9;
if (params->emc_bct_spare_secure10)
*(vu32 *)params->emc_bct_spare_secure10 = params->emc_bct_spare_secure11;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
// Initialize MC VPR settings.
- MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
- MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
- MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
- MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
- MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
+ MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
+ MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
+ MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
+ MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
+ MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
// Program SDRAM geometry parameters.
- MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
- MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
- MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
+ MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
+ MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
+ MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
// Program bank swizzling.
@@ -1012,46 +1149,47 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
// Program SEC carveout (base and size).
- MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
- MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
+ MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
+ MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
// Program MTS carveout (base and size).
- MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
- MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
+ MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
+ MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
// Program the memory arbiter.
- MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
+ MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
- MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
+ MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
MC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;
- MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
- MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
- MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
- MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
- MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
- MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
- MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
- MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
- MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
- MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
- MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
- MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
- MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
- MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
- MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
- MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
- MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
- MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
- MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
- MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
- MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
- MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
- MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
- MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
+ MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
+ MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
+ MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
+ MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
+ MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
+ MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
+ MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
+ MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
+ MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
+ MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
+ MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
+ MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
+ MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
+ MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
+ MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
+ MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
+ MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
+ MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
+ MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
+ MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
+ MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
+ MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
+ MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
+ MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
- MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
+ // Trigger MC timing update.
+ MC(MC_TIMING_CONTROL) = 1;
// Program second-level clock enable overrides.
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
@@ -1073,8 +1211,9 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
+ // Program/Start auto calibration.
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
- EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
+ EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
usleep(params->emc_auto_cal_wait);
// Patch 5 using BCT spare variables.
@@ -1084,99 +1223,104 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_AUTO_CAL_CONFIG9) = params->emc_auto_cal_config9;
// Program EMC timing configuration.
- EMC(EMC_CFG_2) = params->emc_cfg2;
- EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
- EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
- EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
- EMC(EMC_CMDQ) = params->emc_cmd_q;
- EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;
- EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
- EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
- EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
- EMC(EMC_RC) = params->emc_rc;
- EMC(EMC_RFC) = params->emc_rfc;
- EMC(EMC_RFCPB) = params->emc_rfc_pb;
- EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;
- EMC(EMC_RFC_SLR) = params->emc_rfc_slr;
- 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_R2R) = params->emc_r2r;
- EMC(EMC_W2W) = params->emc_w2w;
- EMC(EMC_R2W) = params->emc_r2w;
- EMC(EMC_W2R) = params->emc_w2r;
- EMC(EMC_R2P) = params->emc_r2p;
- EMC(EMC_W2P) = params->emc_w2p;
- EMC(EMC_CCDMW) = params->emc_ccdmw;
- EMC(EMC_RD_RCD) = params->emc_rd_rcd;
- EMC(EMC_WR_RCD) = params->emc_wr_rcd;
- EMC(EMC_RRD) = params->emc_rrd;
- EMC(EMC_REXT) = params->emc_rext;
- EMC(EMC_WEXT) = params->emc_wext;
- EMC(EMC_WDV) = params->emc_wdv;
- EMC(EMC_WDV_CHK) = params->emc_wdv_chk;
- EMC(EMC_WSV) = params->emc_wsv;
- EMC(EMC_WEV) = params->emc_wev;
- EMC(EMC_WDV_MASK) = params->emc_wdv_mask;
- EMC(EMC_WS_DURATION) = params->emc_ws_duration;
- EMC(EMC_WE_DURATION) = params->emc_we_duration;
- EMC(EMC_QUSE) = params->emc_quse;
- EMC(EMC_QUSE_WIDTH) = params->emc_quse_width;
- EMC(EMC_IBDLY) = params->emc_ibdly;
- EMC(EMC_OBDLY) = params->emc_obdly;
- EMC(EMC_EINPUT) = params->emc_einput;
+ EMC(EMC_CFG_2) = params->emc_cfg2;
+ EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
+ EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
+ EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
+ EMC(EMC_CMDQ) = params->emc_cmd_q;
+ EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;
+ EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
+ EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
+ EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
+ EMC(EMC_RC) = params->emc_rc;
+ EMC(EMC_RFC) = params->emc_rfc;
+ EMC(EMC_RFCPB) = params->emc_rfc_pb;
+ EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;
+ EMC(EMC_RFC_SLR) = params->emc_rfc_slr;
+ 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_R2R) = params->emc_r2r;
+ EMC(EMC_W2W) = params->emc_w2w;
+ EMC(EMC_R2W) = params->emc_r2w;
+ EMC(EMC_W2R) = params->emc_w2r;
+ EMC(EMC_R2P) = params->emc_r2p;
+ EMC(EMC_W2P) = params->emc_w2p;
+ EMC(EMC_CCDMW) = params->emc_ccdmw;
+ EMC(EMC_RD_RCD) = params->emc_rd_rcd;
+ EMC(EMC_WR_RCD) = params->emc_wr_rcd;
+ EMC(EMC_RRD) = params->emc_rrd;
+ EMC(EMC_REXT) = params->emc_rext;
+ EMC(EMC_WEXT) = params->emc_wext;
+ EMC(EMC_WDV) = params->emc_wdv;
+ EMC(EMC_WDV_CHK) = params->emc_wdv_chk;
+ EMC(EMC_WSV) = params->emc_wsv;
+ EMC(EMC_WEV) = params->emc_wev;
+ EMC(EMC_WDV_MASK) = params->emc_wdv_mask;
+ EMC(EMC_WS_DURATION) = params->emc_ws_duration;
+ EMC(EMC_WE_DURATION) = params->emc_we_duration;
+ EMC(EMC_QUSE) = params->emc_quse;
+ EMC(EMC_QUSE_WIDTH) = params->emc_quse_width;
+ EMC(EMC_IBDLY) = params->emc_ibdly;
+ EMC(EMC_OBDLY) = params->emc_obdly;
+ EMC(EMC_EINPUT) = params->emc_einput;
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
- EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
- EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
- EMC(EMC_DBG) = params->emc_dbg;
- EMC(EMC_QRST) = params->emc_qrst;
- EMC(EMC_ISSUE_QRST) = 1;
- EMC(EMC_ISSUE_QRST) = 0;
- EMC(EMC_QSAFE) = params->emc_qsafe;
- EMC(EMC_RDV) = params->emc_rdv;
- EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
- EMC(EMC_RDV_EARLY) = params->emc_rdv_early;
- EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
- EMC(EMC_QPOP) = params->emc_qpop;
- EMC(EMC_REFRESH) = params->emc_refresh;
- EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
+ EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
+ EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
+
+ EMC(EMC_DBG) = params->emc_dbg;
+
+ // Clear read fifo.
+ EMC(EMC_QRST) = params->emc_qrst;
+ EMC(EMC_ISSUE_QRST) = 1;
+ EMC(EMC_ISSUE_QRST) = 0;
+
+ // Program the rest of EMC timing configuration.
+ EMC(EMC_QSAFE) = params->emc_qsafe;
+ EMC(EMC_RDV) = params->emc_rdv;
+ EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
+ EMC(EMC_RDV_EARLY) = params->emc_rdv_early;
+ EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
+ EMC(EMC_QPOP) = params->emc_qpop;
+ EMC(EMC_REFRESH) = params->emc_refresh;
+ EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
EMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;
- EMC(EMC_PDEX2WR) = params->emc_pdex2wr;
- EMC(EMC_PDEX2RD) = params->emc_pdex2rd;
- EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;
- EMC(EMC_ACT2PDEN) = params->emc_act2pden;
- EMC(EMC_AR2PDEN) = params->emc_ar2pden;
- EMC(EMC_RW2PDEN) = params->emc_rw2pden;
- EMC(EMC_CKE2PDEN) = params->emc_cke2pden;
- EMC(EMC_PDEX2CKE) = params->emc_pdex2che;
- EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;
- EMC(EMC_TXSR) = params->emc_txsr;
- EMC(EMC_TXSRDLL) = params->emc_txsr_dll;
- EMC(EMC_TCKE) = params->emc_tcke;
- EMC(EMC_TCKESR) = params->emc_tckesr;
- EMC(EMC_TPD) = params->emc_tpd;
- EMC(EMC_TFAW) = params->emc_tfaw;
- EMC(EMC_TRPAB) = params->emc_trpab;
- EMC(EMC_TCLKSTABLE) = params->emc_tclkstable;
- EMC(EMC_TCLKSTOP) = params->emc_tclkstop;
- EMC(EMC_TREFBW) = params->emc_trefbw;
- EMC(EMC_ODT_WRITE) = params->emc_odt_write;
- EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
- EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
+ EMC(EMC_PDEX2WR) = params->emc_pdex2wr;
+ EMC(EMC_PDEX2RD) = params->emc_pdex2rd;
+ EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;
+ EMC(EMC_ACT2PDEN) = params->emc_act2pden;
+ EMC(EMC_AR2PDEN) = params->emc_ar2pden;
+ EMC(EMC_RW2PDEN) = params->emc_rw2pden;
+ EMC(EMC_CKE2PDEN) = params->emc_cke2pden;
+ EMC(EMC_PDEX2CKE) = params->emc_pdex2che;
+ EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;
+ EMC(EMC_TXSR) = params->emc_txsr;
+ EMC(EMC_TXSRDLL) = params->emc_txsr_dll;
+ EMC(EMC_TCKE) = params->emc_tcke;
+ EMC(EMC_TCKESR) = params->emc_tckesr;
+ EMC(EMC_TPD) = params->emc_tpd;
+ EMC(EMC_TFAW) = params->emc_tfaw;
+ EMC(EMC_TRPAB) = params->emc_trpab;
+ EMC(EMC_TCLKSTABLE) = params->emc_tclkstable;
+ EMC(EMC_TCLKSTOP) = params->emc_tclkstop;
+ EMC(EMC_TREFBW) = params->emc_trefbw;
+ EMC(EMC_ODT_WRITE) = params->emc_odt_write;
+ EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
+ EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
// Don't write CFG_ADR_EN (bit 1) here - lock bit written later.
- EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
- EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
+ EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
+ EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
EMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
- EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
+ EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0;
// Set pipe bypass enable bits before sending any DRAM commands.
@@ -1186,7 +1330,9 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
if (params->boot_rom_patch_control)
{
*(vu32 *)params->boot_rom_patch_control = params->boot_rom_patch_data;
- MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
+
+ // Trigger MC timing update.
+ MC(MC_TIMING_CONTROL) = 1;
}
// Patch 7 to 9 using BCT spare secure variables.
@@ -1198,7 +1344,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
// Release SEL_DPD_CMD.
- PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
+ PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | PMC_IO_DPD_REQ_DPD_OFF;
usleep(params->pmc_io_dpd3_req_wait);
// Set transmission pad control parameters.
@@ -1207,16 +1353,12 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// ZQ CAL setup (not actually issuing ZQ CAL now).
if (params->emc_zcal_warm_cold_boot_enables & 1)
{
- if (params->memory_type == MEMORY_TYPE_DDR3L)
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3;
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
- EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
- }
+ EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
}
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
usleep(params->emc_timing_control_wait);
// Deassert HOLD_CKE_LOW.
@@ -1225,68 +1367,51 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Set clock enable signal.
u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
- if (params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_PIN) = pin_gpio_cfg;
- (void)EMC(EMC_PIN);
- usleep(params->emc_pin_extra_wait + 200);
- EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
- (void)EMC(EMC_PIN);
- }
+ EMC(EMC_PIN) = pin_gpio_cfg;
+ (void)EMC(EMC_PIN);
+ usleep(params->emc_pin_extra_wait + 200);
+ EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
+ (void)EMC(EMC_PIN);
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
- usleep(params->emc_pin_extra_wait + 2000);
- else if (params->memory_type == MEMORY_TYPE_DDR3L)
- usleep(params->emc_pin_extra_wait + 500);
+ usleep(params->emc_pin_extra_wait + 2000);
// Enable clock enable signal.
EMC(EMC_PIN) = pin_gpio_cfg | 0x101;
(void)EMC(EMC_PIN);
usleep(params->emc_pin_program_wait);
- // Send NOP (trigger just needs to be non-zero).
- if (params->memory_type != MEMORY_TYPE_LPDDR4)
- EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
-
- // On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high.
- if (params->memory_type == MEMORY_TYPE_LPDDR2)
- usleep(params->emc_pin_extra_wait + 200);
-
// Init zq calibration,
- if (params->memory_type == MEMORY_TYPE_LPDDR4)
+ // Patch 6 using BCT spare variables.
+ if (params->emc_bct_spare10)
+ *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
+
+ // Write mode registers.
+ EMC(EMC_MRW2) = params->emc_mrw2;
+ EMC(EMC_MRW) = params->emc_mrw1;
+ EMC(EMC_MRW3) = params->emc_mrw3;
+ EMC(EMC_MRW4) = params->emc_mrw4;
+ EMC(EMC_MRW6) = params->emc_mrw6;
+ EMC(EMC_MRW14) = params->emc_mrw14;
+
+ EMC(EMC_MRW8) = params->emc_mrw8;
+ EMC(EMC_MRW12) = params->emc_mrw12;
+ EMC(EMC_MRW9) = params->emc_mrw9;
+ EMC(EMC_MRW13) = params->emc_mrw13;
+
+ if (params->emc_zcal_warm_cold_boot_enables & 1)
{
- // Patch 6 using BCT spare variables.
- if (params->emc_bct_spare10)
- *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
+ // Issue ZQCAL start, device 0.
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
+ usleep(params->emc_zcal_init_wait);
- // Write mode registers.
- EMC(EMC_MRW2) = params->emc_mrw2;
- EMC(EMC_MRW) = params->emc_mrw1;
- EMC(EMC_MRW3) = params->emc_mrw3;
- EMC(EMC_MRW4) = params->emc_mrw4;
- EMC(EMC_MRW6) = params->emc_mrw6;
- EMC(EMC_MRW14) = params->emc_mrw14;
-
- EMC(EMC_MRW8) = params->emc_mrw8;
- EMC(EMC_MRW12) = params->emc_mrw12;
- EMC(EMC_MRW9) = params->emc_mrw9;
- EMC(EMC_MRW13) = params->emc_mrw13;
-
- if (params->emc_zcal_warm_cold_boot_enables & 1)
+ // Issue ZQCAL latch.
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
+ // Same for device 1.
+ if (!(params->emc_dev_select & 2))
{
- // Issue ZQCAL start, device 0.
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
usleep(params->emc_zcal_init_wait);
-
- // Issue ZQCAL latch.
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
- // Same for device 1.
- if (!(params->emc_dev_select & 2))
- {
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
- usleep(params->emc_zcal_init_wait);
- EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;
- }
+ EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;
}
}
@@ -1302,35 +1427,34 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;
// Start periodic ZQ calibration (LPDDRx only).
- if (params->memory_type == MEMORY_TYPE_LPDDR2 || params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4)
- {
- EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
- EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
- EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
- }
+ EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
+ EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
// Patch 7 using BCT spare variables.
if (params->emc_bct_spare12)
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
- EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
+ // Trigger timing update so above writes take place.
+ EMC(EMC_TIMING_CONTROL) = 1;
if (params->emc_extra_refresh_num)
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
// Enable refresh.
- EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
+ EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
- EMC(EMC_CFG) = params->emc_cfg;
- EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
+ EMC(EMC_CFG) = params->emc_cfg;
+ EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
- EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
+ EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
- EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
+ EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
- EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
+ // Re-trigger timing to latch power saving functions.
+ EMC(EMC_TIMING_CONTROL) = 1;
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
@@ -1345,8 +1469,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Lock carveouts per BCT cfg.
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
- MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
- MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
+ MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
+ MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
// Disable write access to a bunch of EMC registers.
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
@@ -1355,100 +1479,42 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | (params->ahb_arbitration_xbar_ctrl_meminit_done << 16);
}
-#ifndef CONFIG_SDRAM_COMPRESS_CFG
-static void _sdram_patch_model_params_t210(u32 dramid, u32 *params)
-{
- for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210); i++)
- if (sdram_cfg_vendor_patches_t210[i].dramid & DRAM_ID(dramid))
- params[sdram_cfg_vendor_patches_t210[i].addr] = sdram_cfg_vendor_patches_t210[i].val;
-}
-#endif
-
-static void _sdram_patch_model_params_t210b01(u32 dramid, u32 *params)
-{
- for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++)
- if (sdram_cfg_vendor_patches_t210b01[i].dramid & DRAM_ID2(dramid))
- params[sdram_cfg_vendor_patches_t210b01[i].addr] = sdram_cfg_vendor_patches_t210b01[i].val;
-}
-
static void *_sdram_get_params_t210()
{
// Check if id is proper.
- u32 dramid = _sdram_get_id();
- if (dramid > 6)
- dramid = 0;
+ u32 dramid = fuse_read_dramid(false);
-#ifdef CONFIG_SDRAM_COMPRESS_CFG
+ // Copy base parameters.
+ u32 *params = (u32 *)SDRAM_PARAMS_ADDR;
+ memcpy(params, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t210_t));
- u8 *buf = (u8 *)SDRAM_PARAMS_ADDR;
- LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
- return (void *)&buf[sizeof(sdram_params_t210_t) * dramid];
+ // Patch parameters if needed.
+ for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210); i++)
+ if (sdram_cfg_vendor_patches_t210[i].dramcf & DRAM_ID(dramid))
+ params[sdram_cfg_vendor_patches_t210[i].offset] = sdram_cfg_vendor_patches_t210[i].val;
-#else
-
- u32 *buf = (u32 *)SDRAM_PARAMS_ADDR;
- memcpy(buf, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t210_t));
-
- switch (dramid)
- {
- case LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH:
- case LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT:
- break;
-
- case LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE:
- case LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH:
-#ifdef CONFIG_SDRAM_COPPER_SUPPORT
- case LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH:
- case LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE:
- case LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT:
-#endif
- _sdram_patch_model_params_t210(dramid, (u32 *)buf);
- break;
- }
- return (void *)buf;
-
-#endif
+ return (void *)params;
}
void *sdram_get_params_t210b01()
{
// Check if id is proper.
- u32 dramid = _sdram_get_id();
- if (dramid > 27)
- dramid = 8;
+ u32 dramid = fuse_read_dramid(false);
- u32 *buf = (u32 *)SDRAM_PARAMS_ADDR;
- memcpy(buf, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t));
+ // Copy base parameters.
+ u32 *params = (u32 *)SDRAM_PARAMS_ADDR;
+ memcpy(params, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t));
- switch (dramid)
- {
- case LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ:
- case LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME:
- case LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ:
- case LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME:
- break;
+ // Patch parameters if needed.
+ u8 dram_code = dram_encoding_t210b01[dramid];
+ if (!dram_code)
+ return (void *)params;
- case LPDDR4X_IOWA_4GB_SAMSUNG_X1X2:
- case LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ:
- case LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT:
- case LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ:
- case LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT:
- case LPDDR4X_IOWA_4GB_SAMSUNG_Y:
- case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X:
- case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X:
- case LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X:
- case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y:
- case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y:
- case LPDDR4X_SDS_4GB_SAMSUNG_1Y_A:
- case LPDDR4X_SDS_8GB_SAMSUNG_1Y_X:
- case LPDDR4X_SDS_4GB_SAMSUNG_1Y_X:
- case LPDDR4X_IOWA_4GB_MICRON_1Y_A:
- case LPDDR4X_HOAG_4GB_MICRON_1Y_A:
- case LPDDR4X_SDS_4GB_MICRON_1Y_A:
- _sdram_patch_model_params_t210b01(dramid, (u32 *)buf);
- break;
- }
- return (void *)buf;
+ for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++)
+ if (sdram_cfg_vendor_patches_t210b01[i].dramcf & DRAM_CC(dram_code))
+ params[sdram_cfg_vendor_patches_t210b01[i].offset] = sdram_cfg_vendor_patches_t210b01[i].val;
+
+ return (void *)params;
}
/*
@@ -1489,61 +1555,28 @@ void *sdram_get_params_patched()
return (void *)sdram_params;
}
-static void _sdram_init_t210()
-{
- const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210();
-
- // Set DRAM voltage.
- max77620_regulator_set_voltage(REGULATOR_SD1, 1100000);
-
- // VDDP Select.
- PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
- usleep(params->pmc_vddp_sel_wait);
-
- // Set DDR pad voltage.
- PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);
-
- // Turn on MEM IO Power.
- PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
- PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
-
- PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
-
- // Patch 1 using BCT spare variables
- if (params->emc_bct_spare0)
- *(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
-
- _sdram_config_t210(params);
-}
-
-static void _sdram_init_t210b01()
-{
- const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01();
-
- // VDDP Select.
- PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
- usleep(params->pmc_vddp_sel_wait);
-
- // Turn on MEM IO Power.
- PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
- PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
-
- PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
-
- // Patch 1 using BCT spare variables
- if (params->emc_bct_spare0)
- *(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
-
- _sdram_config_t210b01(params);
-}
-
void sdram_init()
{
- // Configure SD regulator for DRAM.
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
+ // Disable remote sense for SD1.
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0 | MAX77620_SD_CNF2_RSVD);
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
- _sdram_init_t210();
+ {
+ const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210();
+ if (params->memory_type != MEMORY_TYPE_LPDDR4)
+ return;
+
+ // Set DRAM voltage.
+ max7762x_regulator_set_voltage(REGULATOR_SD1, 1125000); // HOS: 1.125V. Bootloader: 1.1V.
+
+ _sdram_config_t210(params);
+ }
else
- _sdram_init_t210b01();
+ {
+ const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01();
+ if (params->memory_type != MEMORY_TYPE_LPDDR4)
+ return;
+
+ _sdram_config_t210b01(params);
+ }
}
diff --git a/bdk/mem/sdram.h b/bdk/mem/sdram.h
index 77db819..10fb705 100644
--- a/bdk/mem/sdram.h
+++ b/bdk/mem/sdram.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2020 CTCaer
+ * Copyright (c) 2020-2024 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,73 +23,119 @@
/*
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
*
- * 40.8 MHz: 0.61 GiB/s
- * 68.0 MHz: 1.01 GiB/s
- * 102.0 MHz: 1.52 GiB/s
- * 204.0 MHz: 3.04 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
- * 408.0 MHz: 6.08 GiB/s
- * 665.6 MHz: 9.92 GiB/s
- * 800.0 MHz: 11.92 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
- * 1065.6 MHz: 15.89 GiB/s
- * 1331.2 MHz: 19.84 GiB/s
- * 1600.0 MHz: 23.84 GiB/s <-- Tegra X1 Official Max Frequency
- * 1862.4 MHz: 27.75 GiB/s <-- Tegra X1+ Official Max Frequency
- * 2131.2 MHz: 31.76 GiB/s
+ * Note: Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
+ * Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
+ * Configurations supported: 1x32, 2x32, 1x64.
+ * x64 ram modules can be used by combining the 2 32-bit channels into one.
*
- * Note: BWbits = Hz x bus width x channels = Hz x 64 x 2.
+ * 204.0 MHz: 3.04 <-- Tegra X1/X1+ Init/SC7 Frequency
+ * 408.0 MHz: 6.08
+ * 665.6 MHz: 9.92
+ * 800.0 MHz: 11.92 <-- Tegra X1/X1+ Nvidia OS Boot Frequency
+ * 1065.6 MHz: 15.89
+ * 1331.2 MHz: 19.84
+ * 1600.0 MHz: 23.84
+ * 1862.4 MHz: 27.75 <-- Tegra X1 Official Max Frequency
+ * 2131.2 MHz: 31.76 <-- Tegra X1+ Official Max Frequency. Not all regs have support for > 2046 MHz.
*/
enum sdram_ids_erista
{
// LPDDR4 3200Mbps.
- LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
- LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
- LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2,
- LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3,
- LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
- LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5,
- LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6,
+ LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
+ LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
+ LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
+
+ LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, // Die-C. (2y-01).
+
+ /*
+ * Custom hekate/L4T supported 8GB. 7 dram id can be easily applied in fuses.
+ *
+ * 4GB modules:
+ * Samsung K4FBE3D4HM-MGCH/CJ/CL. MG/TF/GF/TH/GH: Package + Temperature.
+ * Hynix H9HCNNNCPUMLXR-NME/NEE/NEI. E/I: Temperature.
+ * Hynix H54G56BYYVX046/QX046/PX046. V/Q/P: Package + Temperature.
+ */
+ LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // XX: CH/CJ/CL.
};
enum sdram_ids_mariko
{
+ /*
+ * Nintendo Switch LPDRR4X generations:
+ * - 1x nm are 1st-gen
+ * - 1y nm are 2nd-gen
+ * - 1z/a nm are 3rd-gen
+ */
+
+ // LPDDR4X 4266Mbps.
+ LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
+ LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
+ LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
+
// LPDDR4X 3733Mbps.
- LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7,
+ LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
+ LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
+ LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
+ LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
- LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8,
- LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9,
- LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10,
- LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps.
+ LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
+ LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
+ LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
+ LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
- LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12,
- LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13,
- LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14,
- LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps.
+ // LPDDR4X 4266Mbps.
+ LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03).
+ LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
+ LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03).
- // LPDDR4X 4266Mbps?
- LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16,
+ LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. (1z-01). 40% lp.
+ LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
+ LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. (1z-01). 40% lp.
- LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X = 17,
- LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X = 18,
- LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X = 19,
+ LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
+ LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
- LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20,
- LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21,
+ LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
+ LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
+ LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
- LPDDR4X_SDS_4GB_SAMSUNG_1Y_A = 22,
+ LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
- LPDDR4X_SDS_8GB_SAMSUNG_1Y_X = 23,
- LPDDR4X_SDS_4GB_SAMSUNG_1Y_X = 24,
+ // Old naming scheme: H9HCNNNBKMCLXR-NEE
+ LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
+ LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
+ LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
- LPDDR4X_IOWA_4GB_MICRON_1Y_A = 25,
- LPDDR4X_HOAG_4GB_MICRON_1Y_A = 26,
- LPDDR4X_SDS_4GB_MICRON_1Y_A = 27
+ LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
+ LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
+ LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
+};
+
+enum sdram_codes_mariko
+{
+ LPDDR4X_NO_PATCH = 0,
+ LPDDR4X_UNUSED = 0,
+
+ // LPDDR4X_4GB_SAMSUNG_K4U6E3S4AM_MGCJ DRAM IDs: 08, 12.
+ // LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLHR_NME DRAM IDs: 10, 14.
+
+ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 1, // DRAM IDs: 09, 13.
+ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
+ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
+ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
+ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 5, // DRAM IDs: 20, 21, 22.
+ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
+ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
+ LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
+ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
};
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
diff --git a/bdk/mem/sdram_config.inl b/bdk/mem/sdram_config.inl
index 727ec60..e6d6f0b 100644
--- a/bdk/mem/sdram_config.inl
+++ b/bdk/mem/sdram_config.inl
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2020 CTCaer
+ * Copyright (c) 2020-2024 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,8 +17,6 @@
#define DRAM_CFG_T210_SIZE 1896
-#define DRAM_ID(x) BIT(x)
-
static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
/* Specifies the type of memory device */
.memory_type = MEMORY_TYPE_LPDDR4,
@@ -97,7 +95,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
- .emc_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
+ .emc_adr_cfg = 0x00000001, // 2 Ranks.
/*
* Specifies the time to wait after asserting pin
@@ -243,7 +241,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_cfg_dig_dll = 0x002C00A0,
.emc_cfg_dig_dll_1 = 0x00003701,
.emc_cfg_dig_dll_period = 0x00008000,
- .emc_dev_select = 0x00000000, // Both devices.
+ .emc_dev_select = 0x00000000, // Both Ranks.
.emc_sel_dpd_ctrl = 0x00040008,
/* Pads trimmer delays */
@@ -406,7 +404,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.pmc_ddr_ctrl = 0x0007FF8B,
.emc_acpd_control = 0x00000000,
- .emc_swizzle_rank0_byte0 = 0x76543201,
+ .emc_swizzle_rank0_byte0 = 0x76543201, // Overridden to 0x76543201 by spare6/7.
.emc_swizzle_rank0_byte1 = 0x65324710,
.emc_swizzle_rank0_byte2 = 0x25763410,
.emc_swizzle_rank0_byte3 = 0x25673401,
@@ -436,9 +434,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_dll_cfg0 = 0x1F13412F,
.emc_dll_cfg1 = 0x00010014,
- .emc_pmc_scratch1 = 0x4FAFFFFF,
+ .emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
.emc_pmc_scratch2 = 0x7FFFFFFF,
- .emc_pmc_scratch3 = 0x4006D70B,
+ .emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
@@ -454,7 +452,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_pmacro_data_rx_term_mode = 0x00000010,
.emc_pmacro_cmd_rx_term_mode = 0x00003000,
.emc_pmacro_data_pad_tx_ctrl = 0x02000111,
- .emc_pmacro_common_pad_tx_ctrl = 0x00000008,
+ .emc_pmacro_common_pad_tx_ctrl = 0x00000008, // Overridden to 0x0000000A by spare4/5.
.emc_pmacro_cmd_pad_tx_ctrl = 0x0A000000,
.emc_cfg3 = 0x00000040,
@@ -490,9 +488,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_pmacro_cmd_ctrl2 = 0x0A0A0A0A,
/* DRAM size information */
- .mc_emem_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
- .mc_emem_adr_cfg_dev0 = 0x00070302, // Density 512MB.
- .mc_emem_adr_cfg_dev1 = 0x00070302, // Density 512MB.
+ .mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
+ .mc_emem_adr_cfg_dev0 = 0x00070302, // Chip 0 Density 512MB.
+ .mc_emem_adr_cfg_dev1 = 0x00070302, // Chip 1 Density 512MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -501,7 +499,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
- .mc_emem_cfg = 0x00001000, // 4GB total density.
+ .mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@@ -543,13 +541,19 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_video_protect_bom = 0xFFF00000,
.mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 0x00000000,
- .mc_video_protect_vpr_override = 0xE4BAC343,
- .mc_video_protect_vpr_override1 = 0x00001ED3,
- .mc_video_protect_gpu_override0 = 0x00000000,
- .mc_video_protect_gpu_override1 = 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.
+
+ .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.
+
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
+
.mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000,
@@ -644,48 +648,27 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_mts_carveout_reg_ctrl = 0x00000000
};
+#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
// Hynix timing config.
- { 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w.
- { 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra.
- { 0x80000000, 92, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_width.
- { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
- { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
+ { 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
+ { 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
+ { 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
+ { 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
+ { 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
// Samsung 6GB density config.
- { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
- { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
- { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
+ { 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
+ { 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
+ { 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
-#ifdef CONFIG_SDRAM_COPPER_SUPPORT
- // Copper prototype Samsung/Hynix/Micron timing configs.
- { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
- { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
- { 0x00000012, 108, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
- { 0x0000003B, 112, DRAM_ID(6) }, // emc_txsr.
- { 0x0000003B, 113, DRAM_ID(6) }, // emc_txsr_dll.
- { 0x00000003, 119, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
- { 0x00120015, 205, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x00160012, 206, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
- { 0x00120015, 211, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00160012, 212, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
- { 0x002F0032, 213, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00310032, 214, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00360034, 215, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0033002F, 216, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
- { 0x00000006, 217, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x002F0032, 219, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00310032, 220, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00360034, 221, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0033002F, 222, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
- { 0x00000006, 223, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00150015, 233, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x00120012, 235, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
- { 0x00160016, 236, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
- { 0x00000015, 237, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x00000012, 295, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
- { 0x00000012, 296, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
- { 0x00000007, 370, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
- { 0x72A30504, 373, DRAM_ID(6) }, // mc_emem_arb_misc0.
-#endif
+ // Samsung 8GB density config.
+ { 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
+ { 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
+ { 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
+ { 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
+ { 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.
};
+#undef DCFG_OFFSET_OF
diff --git a/bdk/mem/sdram_config_lz.inl b/bdk/mem/sdram_config_lz.inl
deleted file mode 100644
index 832b5b4..0000000
--- a/bdk/mem/sdram_config_lz.inl
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2018 naehrwert
- *
- * 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 .
- */
-
-static const u8 _dram_cfg_lz[1262] = {
- 0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
- 0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,
- 0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,
- 0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,
- 0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,
- 0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,
- 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,
- 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,
- 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,
- 0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,
- 0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,
- 0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,
- 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,
- 0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,
- 0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,
- 0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,
- 0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,
- 0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,
- 0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,
- 0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,
- 0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,
- 0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,
- 0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,
- 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,
- 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
- 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,
- 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
- 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
- 0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,
- 0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,
- 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,
- 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,
- 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,
- 0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,
- 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,
- 0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,
- 0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,
- 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,
- 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,
- 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,
- 0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,
- 0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,
- 0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,
- 0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,
- 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,
- 0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,
- 0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,
- 0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,
- 0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,
- 0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,
- 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,
- 0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,
- 0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,
- 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,
- 0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,
- 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,
- 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,
- 0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,
- 0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,
- 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,
- 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,
- 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,
- 0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,
- 0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,
- 0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,
- 0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,
- 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,
- 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,
- 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,
- 0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,
- 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,
- 0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,
- 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,
- 0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,
- 0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,
- 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,
- 0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,
- 0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,
- 0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,
- 0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,
- 0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,
- 0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,
- 0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,
- 0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,
- 0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,
- 0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x17, 0x0D, 0x16,
- 0x17, 0x0E, 0x82, 0x3C, 0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24,
- 0x17, 0x5C, 0x8E, 0x68, 0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01,
- 0x8E, 0x68, 0x02, 0x17, 0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78,
- 0x17, 0x85, 0x28, 0x8E, 0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81,
- 0x24, 0x8E, 0x68, 0x17, 0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04,
- 0x30, 0x17, 0x85, 0x3C, 0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17,
- 0x88, 0x74, 0x8E, 0x68, 0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04,
- 0x04, 0x17, 0x12, 0x8E, 0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17,
- 0x83, 0x04, 0x9D, 0x50, 0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B,
- 0x49, 0x17, 0x0B, 0x18, 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00,
- 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17,
- 0x18, 0x18, 0x17, 0x20, 0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06,
- 0x5E, 0x16, 0x00, 0x15, 0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F,
- 0xBB, 0x20, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38,
- 0x3B, 0x17, 0x04, 0x04, 0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53,
- 0xAC, 0x38, 0x07, 0x17, 0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10,
- 0x8E, 0x68
-};
diff --git a/bdk/mem/sdram_config_t210b01.inl b/bdk/mem/sdram_config_t210b01.inl
index 983c93a..3879e0c 100644
--- a/bdk/mem/sdram_config_t210b01.inl
+++ b/bdk/mem/sdram_config_t210b01.inl
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 CTCaer
+ * Copyright (c) 2020-2024 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,8 +16,6 @@
#define DRAM_CFG_T210B01_SIZE 2104
-#define DRAM_ID2(x) BIT((x) - 7)
-
static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
/* Specifies the type of memory device */
.memory_type = MEMORY_TYPE_LPDDR4,
@@ -109,7 +107,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.emc_pmacro_ca_tx_drive = 0x3F3F3F3F,
.emc_pmacro_cmd_tx_drive = 0x00001220,
.emc_pmacro_auto_cal_common = 0x00000804,
- .emc_pmacro_zcrtl = 0x505050,
+ .emc_pmacro_zcrtl = 0x00505050,
/* Specifies the time for the calibration to stabilize (in microseconds) */
.emc_auto_cal_wait = 0x000001A1,
@@ -122,7 +120,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
- .emc_adr_cfg = 0x00000000, // 1 populated DRAM Device.
+ .emc_adr_cfg = 0x00000000, // 1 Rank.
/*
* Specifies the time to wait after asserting pin
@@ -273,7 +271,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.emc_cfg_dig_dll = 0x002C00A0,
.emc_cfg_dig_dll_1 = 0x000F3701,
.emc_cfg_dig_dll_period = 0x00008000,
- .emc_dev_select = 0x00000002, // Dev0 only.
+ .emc_dev_select = 0x00000002, // Rank 0 only.
.emc_sel_dpd_ctrl = 0x0004000C,
/* Pads trimmer delays */
@@ -543,9 +541,9 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.emc_pmacro_cmd_ctrl2 = 0x00000000,
/* DRAM size information */
- .mc_emem_adr_cfg = 0x00000000, // 1 populated DRAM Device.
- .mc_emem_adr_cfg_dev0 = 0x00080302, // Density 1024MB.
- .mc_emem_adr_cfg_dev1 = 0x00080302, // Density 1024MB.
+ .mc_emem_adr_cfg = 0x00000000, // 1 Rank.
+ .mc_emem_adr_cfg_dev0 = 0x00080302, // Chip 0 Density 1024MB.
+ .mc_emem_adr_cfg_dev1 = 0x00080302, // Chip 1 Density 1024MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -554,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
- .mc_emem_cfg = 0x00001000, // 4GB total density.
+ .mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@@ -596,13 +594,19 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.mc_video_protect_bom = 0xFFF00000,
.mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 0x00000000,
- .mc_video_protect_vpr_override = 0xE4BAC343,
- .mc_video_protect_vpr_override1 = 0x06001ED3, // Add SE2, SE2B.
- .mc_video_protect_gpu_override0 = 0x00000000,
- .mc_video_protect_gpu_override1 = 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.
+
+ .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.
+
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
+
.mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000,
@@ -703,300 +707,106 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.bct_na = 0x00000000,
};
-//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
+#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
+#define DRAM_CC_LPDDR4X_PUPD_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
+
+#define DRAM_CC_LPDDR4X_DSR (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
+
+#define DRAM_CC_LPDDR4X_QUSE (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
+
+#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
+
+#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
+ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
+ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
+ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
+
+#define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
+ DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
+
+#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
- // Samsung LPDDR4X 4GB X1X2 for prototype Iowa.
- { 0x000E0022, 0x3AC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x001B0010, 0x3B0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
- { 0x000E0022, 0x3C4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x001B0010, 0x3C8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
- { 0x00490043, 0x3CC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00420045, 0x3D0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00490047, 0x3D4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x00460047, 0x3D8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
- { 0x00000016, 0x3DC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00100000, 0x3E0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
- { 0x00490043, 0x3E4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00420045, 0x3E8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00490047, 0x3EC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x00460047, 0x3F0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
- { 0x00000016, 0x3F4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00100000, 0x3F8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
- { 0x00220022, 0x41C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000E000E, 0x420 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00100010, 0x424 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_2.
- { 0x001B001B, 0x428 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_3.
- { 0x00000022, 0x42C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_4.
+ // Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
+ { 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
+ { 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_0) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_1) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_2) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_3) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_0) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_1) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
+ { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
- // Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ for SDEV Iowa and Hoag.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_adr_cfg. 2 populated DRAM Devices.
- { 0x00000006, 0x1CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput_duration.
- { 0x08010004, 0x2B8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_dev_select. Both devices.
- { 0x35353535, 0x350 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_0.
- { 0x35353535, 0x354 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_1.
- { 0x00100010, 0x3FC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
- { 0x00100010, 0x400 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
- { 0x00100010, 0x404 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
- { 0x00100010, 0x408 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
- { 0x00100010, 0x40C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
- { 0x00100010, 0x410 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
- { 0x00100010, 0x414 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
- { 0x00100010, 0x418 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
- { 0x0051004F, 0x450 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
- { 0x00002000, 0x64C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_cfg. 8GB total density.
- { 0x00000002, 0x680 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override1.
+ /*! Shared patched between DRAM Codes. */
+ { 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
+ { 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_vref_sel0) },
- // Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT for Iowa and Hoag.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_vref_sel0.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_dyn_self_ref_control.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override1.
+ // Moved to default config.
+ // { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
+ // { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
- // Samsung LPDDR4X 4GB Die-Y for Iowa.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(16) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(16) }, // emc_auto_cal_vref_sel0.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(16) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(16) }, // emc_dyn_self_ref_control.
- { 0x32323232, 0x350 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_0.
- { 0x32323232, 0x354 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_1.
- { 0x000F0018, 0x3AC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00780078, 0x3FC / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
- { 0x00780078, 0x400 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
- { 0x00780078, 0x404 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
- { 0x00780078, 0x408 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
- { 0x00780078, 0x40C / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
- { 0x00780078, 0x410 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
- { 0x00780078, 0x414 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
- { 0x00780078, 0x418 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
- { 0x00180018, 0x41C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override1.
+ { 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
+ { 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
- // Samsung LPDDR4X 4GB 10nm-class (1y) Die-X for Iowa, Hoag and SDS.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_vref_sel0.
- { 0x00000006, 0x1CC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput_duration.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_dyn_self_ref_control.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override1.
+ { 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
+ { 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
+ { 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
+ { 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
- // Samsung LPDDR4X 8GB 10nm-class (1y) Die-X for SDEV Iowa and SDS.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_adr_cfg. 2 populated DRAM Devices.
- { 0x00000006, 0x1CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput_duration.
- { 0x00000008, 0x24C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_tfaw.
- { 0x08010004, 0x2B8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_dev_select. Both devices.
- { 0x0051004F, 0x450 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
- { 0x00002000, 0x64C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_cfg. 8GB total density.
- { 0x00000001, 0x670 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_faw.
- { 0x00000002, 0x680 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override1.
+ { 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
+ { 0x00000001, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(mc_emem_arb_timing_faw) },
- // Samsung LPDDR4X 4GB 10nm-class (1y) Die-Y for Iowa.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(20) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(20) }, // emc_auto_cal_vref_sel0.
- { 0x00000008, 0x24C / 4, DRAM_ID2(20) }, // emc_tfaw.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(20) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(20) }, // emc_dyn_self_ref_control.
- { 0x000F0018, 0x3AC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00180018, 0x41C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x00000001, 0x670 / 4, DRAM_ID2(20) }, // mc_emem_arb_timing_faw.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override1.
+ // Moved to default config.
+ // { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
+ // { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
- // Samsung LPDDR4X 8GB 10nm-class (1y) Die-Y for SDEV Iowa.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(21) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(21) }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, DRAM_ID2(21) }, // emc_adr_cfg. 2 populated DRAM Devices.
- { 0x00000008, 0x24C / 4, DRAM_ID2(21) }, // emc_tfaw.
- { 0x08010004, 0x2B8 / 4, DRAM_ID2(21) }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, DRAM_ID2(21) }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, DRAM_ID2(21) }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, DRAM_ID2(21) }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, DRAM_ID2(21) }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(21) }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(21) }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(21) }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(21) }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, DRAM_ID2(21) }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, DRAM_ID2(21) }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, DRAM_ID2(21) }, // emc_dev_select. Both devices.
- { 0x32323232, 0x350 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_0.
- { 0x32323232, 0x354 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_1.
- { 0x000F0018, 0x3AC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00180018, 0x41C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x0051004F, 0x450 / 4, DRAM_ID2(21) }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, DRAM_ID2(21) }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, DRAM_ID2(21) }, // mc_emem_adr_cfg. 2 populated DRAM Devices.
- { 0x00002000, 0x64C / 4, DRAM_ID2(21) }, // mc_emem_cfg. 8GB total density.
- { 0x00000001, 0x670 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_faw.
- { 0x00000002, 0x680 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, DRAM_ID2(21) }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override1.
-
- // Samsung LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown SDS.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(22) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(22) }, // emc_auto_cal_vref_sel0.
- { 0x00000008, 0x24C / 4, DRAM_ID2(22) }, // emc_tfaw.
- { 0x1C041B06, 0x26C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_0.
- { 0x02050307, 0x270 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_1.
- { 0x03252500, 0x274 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_2.
- { 0x081D1E00, 0x278 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_0.
- { 0x090C0A0D, 0x27C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_1.
- { 0x0526260B, 0x280 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_2.
- { 0x05030402, 0x284 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_0.
- { 0x1B1C0600, 0x288 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_1.
- { 0x07252507, 0x28C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_2.
- { 0x0C1D0B0A, 0x290 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_0.
- { 0x0800090D, 0x294 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_1.
- { 0x0926261E, 0x298 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_2.
- { 0x2A080624, 0x29C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_byte.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(22) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(22) }, // emc_dyn_self_ref_control.
- { 0x00140010, 0x3AC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x0013000B, 0x3B0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
- { 0x00140010, 0x3C4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x0013000B, 0x3C8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
- { 0x00450047, 0x3CC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x004D004F, 0x3D0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00460046, 0x3D4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x00480048, 0x3D8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
- { 0x000C0008, 0x3DC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x000B000C, 0x3E0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
- { 0x00450047, 0x3E4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x004D004F, 0x3E8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00460046, 0x3EC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x00480048, 0x3F0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
- { 0x000C0008, 0x3F4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x000B000C, 0x3F8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
- { 0x00100010, 0x41C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x00140014, 0x420 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00130013, 0x428 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_3.
- { 0x00000010, 0x42C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x40280100, 0x4B4 / 4, DRAM_ID2(22) }, // pmc_ddr_cfg.
- { 0x4F9F9FFF, 0x4B8 / 4, DRAM_ID2(22) }, // pmc_io_dpd3_req.
- { 0x64032157, 0x4D8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte0.
- { 0x51320467, 0x4DC / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte1.
- { 0x04735621, 0x4E0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte2.
- { 0x47356012, 0x4E4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte3.
- { 0x12045673, 0x4E8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte0.
- { 0x43657210, 0x4EC / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte1.
- { 0x65402137, 0x4F0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte2.
- { 0x57302164, 0x4F4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte3.
- { 0x4F9F9FFF, 0x534 / 4, DRAM_ID2(22) }, // emc_pmc_scratch1.
- { 0x4033CF1F, 0x53C / 4, DRAM_ID2(22) }, // emc_pmc_scratch3.
- { 0x10000000, 0x590 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd3.
- { 0x00030108, 0x594 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd4.
- { 0x01400050, 0x598 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd5.
- { 0x29081081, 0x5A0 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping0.
- { 0x54A59332, 0x5A4 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping1.
- { 0x87766B4A, 0x5A8 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping2.
- { 0x00000001, 0x670 / 4, DRAM_ID2(22) }, // mc_emem_arb_timing_faw.
- { 0xE4FACB43, 0x6D4 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override. + TSEC, NVENC.
- { 0x0600FED3, 0x6D8 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override1.
- { 0x0000009C, 0x814 / 4, DRAM_ID2(22) }, // swizzle_rank_byte_encode.
-
- // Micron LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown Iowa/Hoag/SDS.
- { 0x05500000, 0x0D4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_vref_sel0.
- { 0x00000006, 0x1CC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput_duration.
- { 0x00000008, 0x24C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_tfaw.
- { 0x88161414, 0x2E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_dyn_self_ref_control.
- { 0x00000001, 0x670 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_emem_arb_timing_faw.
- { 0x2A800000, 0x6DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override1.
+ { 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
+ { 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
+ { 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
+ { 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
+ { 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
+ { 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
+ { 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
+ { 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
+ { 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
+ { 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
+ { 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
+ { 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
+ { 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
+ { 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
+ { 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
+ { 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
+ { 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
+ { 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
+ { 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
+ { 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
+ { 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
};
+#undef DCFG_OFFSET_OF
diff --git a/bdk/mem/sdram_lp0.c b/bdk/mem/sdram_lp0.c
deleted file mode 100644
index 7d2836e..0000000
--- a/bdk/mem/sdram_lp0.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- * Copyright 2014 Google Inc.
- * Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 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.
- */
-
-#include
-#include
-#include
-#include
-
-#define pack(src, src_bits, dst, dst_bits) { \
- u32 mask = 0xffffffff >> (31 - ((1 ? src_bits) - (0 ? src_bits))); \
- dst &= ~(mask << (0 ? dst_bits)); \
- dst |= ((src >> (0 ? src_bits)) & mask) << (0 ? dst_bits); \
-}
-
-#define s(param, src_bits, pmcreg, dst_bits) \
- pack(sdram->param, src_bits, pmc->pmcreg, dst_bits)
-
-#define c(value, pmcreg, dst_bits) \
- pack(value, (1 ? dst_bits) - (0 ? dst_bits) : 0, pmc->pmcreg, dst_bits)
-
-/* 32 bits version of s macro */
-#define s32(param, pmcreg) pmc->pmcreg = sdram->param
-
-/* 32 bits version c macro */
-#define c32(value, pmcreg) pmc->pmcreg = value
-
-/*
- * This function reads SDRAM parameters from the common BCT format and
- * writes them into PMC scratch registers (where the BootROM expects them
- * on LP0 resume).
- */
-static void _sdram_lp0_save_params_t210(const void *params)
-{
- struct sdram_params_t210 *sdram = (struct sdram_params_t210 *)params;
- struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE;
-
- //TODO: pkg1.1 (1.X - 3.X) reads them from MC.
- // Patch carveout parameters.
- /*sdram->McGeneralizedCarveout1Bom = 0;
- sdram->McGeneralizedCarveout1BomHi = 0;
- sdram->McGeneralizedCarveout1Size128kb = 0;
- sdram->McGeneralizedCarveout1Access0 = 0;
- sdram->McGeneralizedCarveout1Access1 = 0;
- sdram->McGeneralizedCarveout1Access2 = 0;
- sdram->McGeneralizedCarveout1Access3 = 0;
- sdram->McGeneralizedCarveout1Access4 = 0;
- sdram->McGeneralizedCarveout1ForceInternalAccess0 = 0;
- sdram->McGeneralizedCarveout1ForceInternalAccess1 = 0;
- sdram->McGeneralizedCarveout1ForceInternalAccess2 = 0;
- sdram->McGeneralizedCarveout1ForceInternalAccess3 = 0;
- sdram->McGeneralizedCarveout1ForceInternalAccess4 = 0;
- sdram->McGeneralizedCarveout1Cfg0 = 0;
- sdram->McGeneralizedCarveout2Bom = 0x80020000;
- sdram->McGeneralizedCarveout2BomHi = 0;
- sdram->McGeneralizedCarveout2Size128kb = 2;
- sdram->McGeneralizedCarveout2Access0 = 0;
- sdram->McGeneralizedCarveout2Access1 = 0;
- sdram->McGeneralizedCarveout2Access2 = 0x3000000;
- sdram->McGeneralizedCarveout2Access3 = 0;
- sdram->McGeneralizedCarveout2Access4 = 0x300;
- sdram->McGeneralizedCarveout2ForceInternalAccess0 = 0;
- sdram->McGeneralizedCarveout2ForceInternalAccess1 = 0;
- sdram->McGeneralizedCarveout2ForceInternalAccess2 = 0;
- sdram->McGeneralizedCarveout2ForceInternalAccess3 = 0;
- sdram->McGeneralizedCarveout2ForceInternalAccess4 = 0;
- sdram->McGeneralizedCarveout2Cfg0 = 0x440167E;
- sdram->McGeneralizedCarveout3Bom = 0;
- sdram->McGeneralizedCarveout3BomHi = 0;
- sdram->McGeneralizedCarveout3Size128kb = 0;
- sdram->McGeneralizedCarveout3Access0 = 0;
- sdram->McGeneralizedCarveout3Access1 = 0;
- sdram->McGeneralizedCarveout3Access2 = 0x3000000;
- sdram->McGeneralizedCarveout3Access3 = 0;
- sdram->McGeneralizedCarveout3Access4 = 0x300;
- sdram->McGeneralizedCarveout3ForceInternalAccess0 = 0;
- sdram->McGeneralizedCarveout3ForceInternalAccess1 = 0;
- sdram->McGeneralizedCarveout3ForceInternalAccess2 = 0;
- sdram->McGeneralizedCarveout3ForceInternalAccess3 = 0;
- sdram->McGeneralizedCarveout3ForceInternalAccess4 = 0;
- sdram->McGeneralizedCarveout3Cfg0 = 0x4401E7E;
- sdram->McGeneralizedCarveout4Bom = 0;
- sdram->McGeneralizedCarveout4BomHi = 0;
- sdram->McGeneralizedCarveout4Size128kb = 0;
- sdram->McGeneralizedCarveout4Access0 = 0;
- sdram->McGeneralizedCarveout4Access1 = 0;
- sdram->McGeneralizedCarveout4Access2 = 0;
- sdram->McGeneralizedCarveout4Access3 = 0;
- sdram->McGeneralizedCarveout4Access4 = 0;
- sdram->McGeneralizedCarveout4ForceInternalAccess0 = 0;
- sdram->McGeneralizedCarveout4ForceInternalAccess1 = 0;
- sdram->McGeneralizedCarveout4ForceInternalAccess2 = 0;
- sdram->McGeneralizedCarveout4ForceInternalAccess3 = 0;
- sdram->McGeneralizedCarveout4ForceInternalAccess4 = 0;
- sdram->McGeneralizedCarveout4Cfg0 = 0x8F;
- sdram->McGeneralizedCarveout5Bom = 0;
- sdram->McGeneralizedCarveout5BomHi = 0;
- sdram->McGeneralizedCarveout5Size128kb = 0;
- sdram->McGeneralizedCarveout5Access0 = 0;
- sdram->McGeneralizedCarveout5Access1 = 0;
- sdram->McGeneralizedCarveout5Access2 = 0;
- sdram->McGeneralizedCarveout5Access3 = 0;
- sdram->McGeneralizedCarveout5Access4 = 0;
- sdram->McGeneralizedCarveout5ForceInternalAccess0 = 0;
- sdram->McGeneralizedCarveout5ForceInternalAccess1 = 0;
- sdram->McGeneralizedCarveout5ForceInternalAccess2 = 0;
- sdram->McGeneralizedCarveout5ForceInternalAccess3 = 0;
- sdram->McGeneralizedCarveout5ForceInternalAccess4 = 0;
- sdram->McGeneralizedCarveout5Cfg0 = 0x8F;*/
-
- //TODO: this is 4.X+ behaviour which seems to work fine for < 4.X.
- // Patch carveout parameters.
- sdram->McGeneralizedCarveout1Cfg0 = 0;
- sdram->McGeneralizedCarveout2Cfg0 = 0;
- sdram->McGeneralizedCarveout3Cfg0 = 0;
- sdram->McGeneralizedCarveout4Cfg0 = 0;
- sdram->McGeneralizedCarveout5Cfg0 = 0;
-
- // Patch SDRAM parameters.
- u32 t0 = sdram->EmcSwizzleRank0Byte0 << 5 >> 29 > sdram->EmcSwizzleRank0Byte0 << 1 >> 29;
- u32 t1 = (t0 & 0xFFFFFFEF) | ((sdram->EmcSwizzleRank1Byte0 << 5 >> 29 > sdram->EmcSwizzleRank1Byte0 << 1 >> 29) << 4);
- u32 t2 = (t1 & 0xFFFFFFFD) | ((sdram->EmcSwizzleRank0Byte1 << 5 >> 29 > sdram->EmcSwizzleRank0Byte1 << 1 >> 29) << 1);
- u32 t3 = (t2 & 0xFFFFFFDF) | ((sdram->EmcSwizzleRank1Byte1 << 5 >> 29 > sdram->EmcSwizzleRank1Byte1 << 1 >> 29) << 5);
- u32 t4 = (t3 & 0xFFFFFFFB) | ((sdram->EmcSwizzleRank0Byte2 << 5 >> 29 > sdram->EmcSwizzleRank0Byte2 << 1 >> 29) << 2);
- u32 t5 = (t4 & 0xFFFFFFBF) | ((sdram->EmcSwizzleRank1Byte2 << 5 >> 29 > sdram->EmcSwizzleRank1Byte2 << 1 >> 29) << 6);
- u32 t6 = (t5 & 0xFFFFFFF7) | ((sdram->EmcSwizzleRank0Byte3 << 5 >> 29 > sdram->EmcSwizzleRank0Byte3 << 1 >> 29) << 3);
- u32 t7 = (t6 & 0xFFFFFF7F) | ((sdram->EmcSwizzleRank1Byte3 << 5 >> 29 > sdram->EmcSwizzleRank1Byte3 << 1 >> 29) << 7);
- sdram->SwizzleRankByteEncode = t7;
- sdram->EmcBctSpare2 = 0x40000DD8;
- sdram->EmcBctSpare3 = t7;
-
- s(EmcClockSource, 7:0, scratch6, 15:8);
- s(EmcClockSourceDll, 7:0, scratch6, 23:16);
- s(EmcClockSource, 31:29, scratch6, 26:24);
- s(EmcClockSourceDll, 31:29, scratch6, 29:27);
- s(EmcClockSourceDll, 11:10, scratch6, 31:30);
- s(ClkRstControllerPllmMisc2Override, 9:8, scratch7, 1:0);
- s(ClkRstControllerPllmMisc2Override, 2:1, scratch7, 3:2);
- s(EmcZqCalLpDdr4WarmBoot, 31:30, scratch7, 5:4);
- s(EmcClockSource, 15:15, scratch7, 6:6);
- s(EmcClockSource, 26:26, scratch7, 7:7);
- s(EmcClockSource, 20:20, scratch7, 8:8);
- s(EmcClockSource, 19:19, scratch7, 9:9);
- s(ClkRstControllerPllmMisc2Override, 13:13, scratch7, 10:10);
- s(ClkRstControllerPllmMisc2Override, 12:12, scratch7, 11:11);
- s(ClkRstControllerPllmMisc2Override, 11:11, scratch7, 12:12);
- s(ClkRstControllerPllmMisc2Override, 10:10, scratch7, 13:13);
- s(ClkRstControllerPllmMisc2Override, 5:5, scratch7, 14:14);
- s(ClkRstControllerPllmMisc2Override, 4:4, scratch7, 15:15);
- s(ClkRstControllerPllmMisc2Override, 3:3, scratch7, 16:16);
- s(ClkRstControllerPllmMisc2Override, 0:0, scratch7, 17:17);
- s(EmcZqCalLpDdr4WarmBoot, 1:0, scratch7, 19:18);
- s(EmcZqCalLpDdr4WarmBoot, 4:4, scratch7, 20:20);
- s(EmcOdtWrite, 5:0, scratch7, 26:21);
- s(EmcOdtWrite, 11:8, scratch7, 30:27);
- s(EmcOdtWrite, 31:31, scratch7, 31:31);
- s(EmcFdpdCtrlCmdNoRamp, 0:0, scratch13, 30:30);
- s(EmcCfgPipeClk, 0:0, scratch13, 31:31);
- s(McEmemArbMisc2, 0:0, scratch14, 30:30);
- s(McDaCfg0, 0:0, scratch14, 31:31);
- s(EmcQRst, 6:0, scratch15, 26:20);
- s(EmcQRst, 20:16, scratch15, 31:27);
- s(EmcPmacroCmdTxDrv, 5:0, scratch16, 25:20);
- s(EmcPmacroCmdTxDrv, 13:8, scratch16, 31:26);
- s(EmcPmacroAutocalCfg0, 2:0, scratch17, 22:20);
- s(EmcPmacroAutocalCfg0, 10:8, scratch17, 25:23);
- s(EmcPmacroAutocalCfg0, 18:16, scratch17, 28:26);
- s(EmcPmacroAutocalCfg0, 26:24, scratch17, 31:29);
- s(EmcPmacroAutocalCfg1, 2:0, scratch18, 22:20);
- s(EmcPmacroAutocalCfg1, 10:8, scratch18, 25:23);
- s(EmcPmacroAutocalCfg1, 18:16, scratch18, 28:26);
- s(EmcPmacroAutocalCfg1, 26:24, scratch18, 31:29);
- s(EmcPmacroAutocalCfg2, 2:0, scratch19, 22:20);
- s(EmcPmacroAutocalCfg2, 10:8, scratch19, 25:23);
- s(EmcPmacroAutocalCfg2, 18:16, scratch19, 28:26);
- s(EmcPmacroAutocalCfg2, 26:24, scratch19, 31:29);
- s32(EmcCfgRsv,scratch22);
- s32(EmcAutoCalConfig, scratch23);
- s32(EmcAutoCalVrefSel0, scratch24);
- s32(EmcPmacroBrickCtrlRfu1, scratch25);
- s32(EmcPmacroBrickCtrlRfu2, scratch26);
- s32(EmcPmcScratch1, scratch27);
- s32(EmcPmcScratch2, scratch28);
- s32(EmcPmcScratch3, scratch29);
- s32(McEmemArbDaTurns, scratch30);
- s(EmcFbioSpare, 31:24, scratch58, 7:0);
- s(EmcFbioSpare, 23:16, scratch58, 15:8);
- s(EmcFbioSpare, 15:8, scratch58, 23:16);
- s(EmcFbioSpare, 7:2, scratch58, 29:24);
- s(EmcFbioSpare, 0:0, scratch58, 30:30);
- s(EmcDllCfg0, 29:0, scratch59, 29:0);
- s(EmcPmacroDdllBypass, 11:0, scratch60, 11:0);
- s(EmcPmacroDdllBypass, 27:13, scratch60, 26:12);
- s(EmcPmacroDdllBypass, 31:29, scratch60, 29:27);
- s(McEmemArbMisc0, 14:0, scratch61, 14:0);
- s(McEmemArbMisc0, 30:16, scratch61, 29:15);
- s(EmcFdpdCtrlCmd, 16:0, scratch62, 16:0);
- s(EmcFdpdCtrlCmd, 31:20, scratch62, 28:17);
- s(EmcAutoCalConfig2, 27:0, scratch63, 27:0);
- s(EmcBurstRefreshNum, 3:0, scratch63, 31:28);
- s(EmcPmacroZctrl, 27:0, scratch64, 27:0);
- s(EmcTppd, 3:0, scratch64, 31:28);
- s(EmcCfgDigDll, 10:0, scratch65, 10:0);
- s(EmcCfgDigDll, 25:12, scratch65, 24:11);
- s(EmcCfgDigDll, 27:27, scratch65, 25:25);
- s(EmcCfgDigDll, 31:30, scratch65, 27:26);
- s(EmcR2r, 3:0, scratch65, 31:28);
- s(EmcFdpdCtrlDq, 16:0, scratch66, 16:0);
- s(EmcFdpdCtrlDq, 28:20, scratch66, 25:17);
- s(EmcFdpdCtrlDq, 31:30, scratch66, 27:26);
- s(EmcW2w, 3:0, scratch66, 31:28);
- s(EmcPmacroTxPwrd4, 13:0, scratch67, 13:0);
- s(EmcPmacroTxPwrd4, 29:16, scratch67, 27:14);
- s(EmcPmacroCommonPadTxCtrl, 3:0, scratch67, 31:28);
- s(EmcPmacroTxPwrd5, 13:0, scratch68, 13:0);
- s(EmcPmacroTxPwrd5, 29:16, scratch68, 27:14);
- s(EmcPmacroDdllPwrd0, 4:0, scratch69, 4:0);
- s(EmcPmacroDdllPwrd0, 12:6, scratch69, 11:5);
- s(EmcPmacroDdllPwrd0, 20:14, scratch69, 18:12);
- s(EmcPmacroDdllPwrd0, 28:22, scratch69, 25:19);
- s(EmcPmacroDdllPwrd0, 31:30, scratch69, 27:26);
- s(EmcCfg, 4:4, scratch69, 31:31);
- s(EmcPmacroDdllPwrd1, 4:0, scratch70, 4:0);
- s(EmcPmacroDdllPwrd1, 12:6, scratch70, 11:5);
- s(EmcPmacroDdllPwrd1, 20:14, scratch70, 18:12);
- s(EmcPmacroDdllPwrd1, 28:22, scratch70, 25:19);
- s(EmcPmacroDdllPwrd1, 31:30, scratch70, 27:26);
- s(EmcCfg, 5:5, scratch70, 31:31);
- s(EmcPmacroDdllPwrd2, 4:0, scratch71, 4:0);
- s(EmcPmacroDdllPwrd2, 12:6, scratch71, 11:5);
- s(EmcPmacroDdllPwrd2, 20:14, scratch71, 18:12);
- s(EmcPmacroDdllPwrd2, 28:22, scratch71, 25:19);
- s(EmcPmacroDdllPwrd2, 31:30, scratch71, 27:26);
- s(EmcFbioCfg5, 23:20, scratch71, 31:28);
- s(EmcPmacroIbVrefDq_0, 6:0, scratch72, 6:0);
- s(EmcPmacroIbVrefDq_0, 14:8, scratch72, 13:7);
- s(EmcPmacroIbVrefDq_0, 22:16, scratch72, 20:14);
- s(EmcPmacroIbVrefDq_0, 30:24, scratch72, 27:21);
- s(EmcFbioCfg5, 15:13, scratch72, 30:28);
- s(EmcCfg, 6:6, scratch72, 31:31);
- s(EmcPmacroIbVrefDq_1, 6:0, scratch73, 6:0);
- s(EmcPmacroIbVrefDq_1, 14:8, scratch73, 13:7);
- s(EmcPmacroIbVrefDq_1, 22:16, scratch73, 20:14);
- s(EmcPmacroIbVrefDq_1, 30:24, scratch73, 27:21);
- s(EmcCfg2, 5:3, scratch73, 30:28);
- s(EmcCfg, 7:7, scratch73, 31:31);
- s(EmcPmacroIbVrefDqs_0, 6:0, scratch74, 6:0);
- s(EmcPmacroIbVrefDqs_0, 14:8, scratch74, 13:7);
- s(EmcPmacroIbVrefDqs_0, 22:16, scratch74, 20:14);
- s(EmcPmacroIbVrefDqs_0, 30:24, scratch74, 27:21);
- s(EmcCfg, 17:16, scratch74, 29:28);
- s(EmcFbioCfg5, 1:0, scratch74, 31:30);
- s(EmcPmacroIbVrefDqs_1, 6:0, scratch75, 6:0);
- s(EmcPmacroIbVrefDqs_1, 14:8, scratch75, 13:7);
- s(EmcPmacroIbVrefDqs_1, 22:16, scratch75, 20:14);
- s(EmcPmacroIbVrefDqs_1, 30:24, scratch75, 27:21);
- s(EmcFbioCfg5, 3:2, scratch75, 29:28);
- s(EmcCfg2, 27:26, scratch75, 31:30);
- s(EmcPmacroDdllShortCmd_0, 6:0, scratch76, 6:0);
- s(EmcPmacroDdllShortCmd_0, 14:8, scratch76, 13:7);
- s(EmcPmacroDdllShortCmd_0, 22:16, scratch76, 20:14);
- s(EmcPmacroDdllShortCmd_0, 30:24, scratch76, 27:21);
- s(EmcPmacroCmdPadTxCtrl, 3:2, scratch76, 29:28);
- s(EmcPmacroCmdPadTxCtrl, 7:6, scratch76, 31:30);
- s(EmcPmacroDdllShortCmd_1, 6:0, scratch77, 6:0);
- s(EmcPmacroDdllShortCmd_1, 14:8, scratch77, 13:7);
- s(EmcPmacroDdllShortCmd_1, 22:16, scratch77, 20:14);
- s(EmcPmacroDdllShortCmd_1, 30:24, scratch77, 27:21);
- s(EmcPmacroCmdPadTxCtrl, 11:10, scratch77, 29:28);
- s(EmcPmacroCmdPadTxCtrl, 15:14, scratch77, 31:30);
- s(EmcAutoCalChannel, 5:0, scratch78, 5:0);
- s(EmcAutoCalChannel, 11:8, scratch78, 9:6);
- s(EmcAutoCalChannel, 27:16, scratch78, 21:10);
- s(EmcAutoCalChannel, 31:29, scratch78, 24:22);
- s(EmcConfigSampleDelay, 6:0, scratch78, 31:25);
- s(EmcPmacroRxTerm, 5:0, scratch79, 5:0);
- s(EmcPmacroRxTerm, 13:8, scratch79, 11:6);
- s(EmcPmacroRxTerm, 21:16, scratch79, 17:12);
- s(EmcPmacroRxTerm, 29:24, scratch79, 23:18);
- s(EmcRc, 7:0, scratch79, 31:24);
- s(EmcPmacroDqTxDrv, 5:0, scratch80, 5:0);
- s(EmcPmacroDqTxDrv, 13:8, scratch80, 11:6);
- s(EmcPmacroDqTxDrv, 21:16, scratch80, 17:12);
- s(EmcPmacroDqTxDrv, 29:24, scratch80, 23:18);
- s(EmcSelDpdCtrl, 5:2, scratch80, 27:24);
- s(EmcSelDpdCtrl, 8:8, scratch80, 28:28);
- s(EmcSelDpdCtrl, 18:16, scratch80, 31:29);
- s(EmcPmacroCaTxDrv, 5:0, scratch81, 5:0);
- s(EmcPmacroCaTxDrv, 13:8, scratch81, 11:6);
- s(EmcPmacroCaTxDrv, 21:16, scratch81, 17:12);
- s(EmcPmacroCaTxDrv, 29:24, scratch81, 23:18);
- s(EmcObdly, 5:0, scratch81, 29:24);
- s(EmcObdly, 29:28, scratch81, 31:30);
- s(EmcZcalInterval, 23:10, scratch82, 13:0);
- s(EmcZcalInterval, 9:0, scratch82, 23:14);
- s(EmcPmacroCmdRxTermMode, 1:0, scratch82, 25:24);
- s(EmcPmacroCmdRxTermMode, 5:4, scratch82, 27:26);
- s(EmcPmacroCmdRxTermMode, 9:8, scratch82, 29:28);
- s(EmcPmacroCmdRxTermMode, 13:12, scratch82, 31:30);
- s(EmcDataBrlshft0, 23:0, scratch83, 23:0);
- s(EmcPmacroDataRxTermMode, 1:0, scratch83, 25:24);
- s(EmcPmacroDataRxTermMode, 5:4, scratch83, 27:26);
- s(EmcPmacroDataRxTermMode, 9:8, scratch83, 29:28);
- s(EmcPmacroDataRxTermMode, 13:12, scratch83, 31:30);
- s(EmcDataBrlshft1, 23:0, scratch84, 23:0);
- s(McEmemArbTimingRc, 7:0, scratch84, 31:24);
- s(EmcDqsBrlshft0, 23:0, scratch85, 23:0);
- s(McEmemArbRsv, 7:0, scratch85, 31:24);
- s(EmcDqsBrlshft1, 23:0, scratch86, 23:0);
- s(EmcCfgPipe2, 11:0, scratch87, 11:0);
- s(EmcCfgPipe2, 27:16, scratch87, 23:12);
- s(EmcCfgPipe1, 11:0, scratch88, 11:0);
- s(EmcCfgPipe1, 27:16, scratch88, 23:12);
- s(EmcPmacroCmdCtrl0, 5:0, scratch89, 5:0);
- s(EmcPmacroCmdCtrl0, 13:8, scratch89, 11:6);
- s(EmcPmacroCmdCtrl0, 21:16, scratch89, 17:12);
- s(EmcPmacroCmdCtrl0, 29:24, scratch89, 23:18);
- s(EmcPmacroCmdCtrl1, 5:0, scratch90, 5:0);
- s(EmcPmacroCmdCtrl1, 13:8, scratch90, 11:6);
- s(EmcPmacroCmdCtrl1, 21:16, scratch90, 17:12);
- s(EmcPmacroCmdCtrl1, 29:24, scratch90, 23:18);
- s(EmcRas, 6:0, scratch90, 30:24);
- s(EmcCfg, 8:8, scratch90, 31:31);
- s(EmcPmacroVttgenCtrl2, 23:0, scratch91, 23:0);
- s(EmcW2p, 6:0, scratch91, 30:24);
- s(EmcCfg, 9:9, scratch91, 31:31);
- s(EmcPmacroCmdPadRxCtrl, 2:0, scratch92, 2:0);
- s(EmcPmacroCmdPadRxCtrl, 5:4, scratch92, 4:3);
- s(EmcPmacroCmdPadRxCtrl, 10:8, scratch92, 7:5);
- s(EmcPmacroCmdPadRxCtrl, 22:12, scratch92, 18:8);
- s(EmcPmacroCmdPadRxCtrl, 28:24, scratch92, 23:19);
- s(EmcQSafe, 6:0, scratch92, 30:24);
- s(EmcCfg, 18:18, scratch92, 31:31);
- s(EmcPmacroDataPadRxCtrl, 2:0, scratch93, 2:0);
- s(EmcPmacroDataPadRxCtrl, 5:4, scratch93, 4:3);
- s(EmcPmacroDataPadRxCtrl, 10:8, scratch93, 7:5);
- s(EmcPmacroDataPadRxCtrl, 22:12, scratch93, 18:8);
- s(EmcPmacroDataPadRxCtrl, 28:24, scratch93, 23:19);
- s(EmcRdv, 6:0, scratch93, 30:24);
- s(EmcCfg, 21:21, scratch93, 31:31);
- s(McEmemArbDaCovers, 23:0, scratch94, 23:0);
- s(EmcRw2Pden, 6:0, scratch94, 30:24);
- s(EmcCfg, 22:22, scratch94, 31:31);
- s(EmcPmacroCmdCtrl2, 5:0, scratch95, 5:0);
- s(EmcPmacroCmdCtrl2, 13:9, scratch95, 10:6);
- s(EmcPmacroCmdCtrl2, 21:16, scratch95, 16:11);
- s(EmcPmacroCmdCtrl2, 29:24, scratch95, 22:17);
- s(EmcRfcPb, 8:0, scratch95, 31:23);
- s(EmcPmacroQuseDdllRank0_0, 10:0, scratch96, 10:0);
- s(EmcPmacroQuseDdllRank0_0, 26:16, scratch96, 21:11);
- s(EmcCfgUpdate, 2:0, scratch96, 24:22);
- s(EmcCfgUpdate, 10:8, scratch96, 27:25);
- s(EmcCfgUpdate, 31:28, scratch96, 31:28);
- s(EmcPmacroQuseDdllRank0_1, 10:0, scratch97, 10:0);
- s(EmcPmacroQuseDdllRank0_1, 26:16, scratch97, 21:11);
- s(EmcRfc, 9:0, scratch97, 31:22);
- s(EmcPmacroQuseDdllRank0_2, 10:0, scratch98, 10:0);
- s(EmcPmacroQuseDdllRank0_2, 26:16, scratch98, 21:11);
- s(EmcTxsr, 9:0, scratch98, 31:22);
- s(EmcPmacroQuseDdllRank0_3, 10:0, scratch99, 10:0);
- s(EmcPmacroQuseDdllRank0_3, 26:16, scratch99, 21:11);
- s(EmcMc2EmcQ, 2:0, scratch99, 24:22);
- s(EmcMc2EmcQ, 10:8, scratch99, 27:25);
- s(EmcMc2EmcQ, 27:24, scratch99, 31:28);
- s(EmcPmacroQuseDdllRank0_4, 10:0, scratch100, 10:0);
- s(EmcPmacroQuseDdllRank0_4, 26:16, scratch100, 21:11);
- s(McEmemArbRing1Throttle, 4:0, scratch100, 26:22);
- s(McEmemArbRing1Throttle, 20:16, scratch100, 31:27);
- s(EmcPmacroQuseDdllRank0_5, 10:0, scratch101, 10:0);
- s(EmcPmacroQuseDdllRank0_5, 26:16, scratch101, 21:11);
- s(EmcPmacroQuseDdllRank1_0, 10:0, scratch102, 10:0);
- s(EmcPmacroQuseDdllRank1_0, 26:16, scratch102, 21:11);
- s(EmcAr2Pden, 8:0, scratch102, 30:22);
- s(EmcCfg, 23:23, scratch102, 31:31);
- s(EmcPmacroQuseDdllRank1_1, 10:0, scratch103, 10:0);
- s(EmcPmacroQuseDdllRank1_1, 26:16, scratch103, 21:11);
- s(EmcRfcSlr, 8:0, scratch103, 30:22);
- s(EmcCfg, 24:24, scratch103, 31:31);
- s(EmcPmacroQuseDdllRank1_2, 10:0, scratch104, 10:0);
- s(EmcPmacroQuseDdllRank1_2, 26:16, scratch104, 21:11);
- s(EmcIbdly, 6:0, scratch104, 28:22);
- s(EmcIbdly, 29:28, scratch104, 30:29);
- s(EmcCfg, 25:25, scratch104, 31:31);
- s(EmcPmacroQuseDdllRank1_3, 10:0, scratch105, 10:0);
- s(EmcPmacroQuseDdllRank1_3, 26:16, scratch105, 21:11);
- s(McEmemArbTimingRFCPB, 8:0, scratch105, 30:22);
- s(EmcCfg, 26:26, scratch105, 31:31);
- s(EmcPmacroQuseDdllRank1_4, 10:0, scratch106, 10:0);
- s(EmcPmacroQuseDdllRank1_4, 26:16, scratch106, 21:11);
- s(EmcTfaw, 6:0, scratch106, 28:22);
- s(EmcPmacroDataPadTxCtrl, 3:2, scratch106, 30:29);
- s(EmcCfg, 28:28, scratch106, 31:31);
- s(EmcPmacroQuseDdllRank1_5, 10:0, scratch107, 10:0);
- s(EmcPmacroQuseDdllRank1_5, 26:16, scratch107, 21:11);
- s(EmcTClkStable, 6:0, scratch107, 28:22);
- s(EmcPmacroDataPadTxCtrl, 7:6, scratch107, 30:29);
- s(EmcCfg, 29:29, scratch107, 31:31);
- s(EmcPmacroObDdllLongDqRank0_0, 10:0, scratch108, 10:0);
- s(EmcPmacroObDdllLongDqRank0_0, 26:16, scratch108, 21:11);
- s(EmcPdex2Mrr, 6:0, scratch108, 28:22);
- s(EmcPmacroDataPadTxCtrl, 11:10, scratch108, 30:29);
- s(EmcCfg, 30:30, scratch108, 31:31);
- s(EmcPmacroObDdllLongDqRank0_1, 10:0, scratch109, 10:0);
- s(EmcPmacroObDdllLongDqRank0_1, 26:16, scratch109, 21:11);
- s(EmcRdvMask, 6:0, scratch109, 28:22);
- s(EmcPmacroDataPadTxCtrl, 15:14, scratch109, 30:29);
- s(EmcCfg, 31:31, scratch109, 31:31);
- s(EmcPmacroObDdllLongDqRank0_2, 10:0, scratch110, 10:0);
- s(EmcPmacroObDdllLongDqRank0_2, 26:16, scratch110, 21:11);
- s(EmcRdvEarlyMask, 6:0, scratch110, 28:22);
- s(EmcFbioCfg5, 4:4, scratch110, 29:29);
- s(EmcFbioCfg5, 8:8, scratch110, 30:30);
- s(EmcFbioCfg5, 10:10, scratch110, 31:31);
- s(EmcPmacroObDdllLongDqRank0_3, 10:0, scratch111, 10:0);
- s(EmcPmacroObDdllLongDqRank0_3, 26:16, scratch111, 21:11);
- s(EmcRdvEarly, 6:0, scratch111, 28:22);
- s(EmcFbioCfg5, 12:12, scratch111, 29:29);
- s(EmcFbioCfg5, 25:24, scratch111, 31:30);
- s(EmcPmacroObDdllLongDqRank0_4, 10:0, scratch112, 10:0);
- s(EmcPmacroObDdllLongDqRank0_4, 26:16, scratch112, 21:11);
- s(EmcPmacroDdllShortCmd_2, 6:0, scratch112, 28:22);
- s(EmcFbioCfg5, 28:26, scratch112, 31:29);
- s(EmcPmacroObDdllLongDqRank0_5, 10:0, scratch113, 10:0);
- s(EmcPmacroObDdllLongDqRank0_5, 26:16, scratch113, 21:11);
- s(McEmemArbTimingRp, 6:0, scratch113, 28:22);
- s(EmcFbioCfg5, 31:30, scratch113, 30:29);
- s(EmcCfg2, 0:0, scratch113, 31:31);
- s(EmcPmacroObDdllLongDqRank1_0, 10:0, scratch114, 10:0);
- s(EmcPmacroObDdllLongDqRank1_0, 26:16, scratch114, 21:11);
- s(McEmemArbTimingRas, 6:0, scratch114, 28:22);
- s(EmcCfg2, 2:1, scratch114, 30:29);
- s(EmcCfg2, 7:7, scratch114, 31:31);
- s(EmcPmacroObDdllLongDqRank1_1, 10:0, scratch115, 10:0);
- s(EmcPmacroObDdllLongDqRank1_1, 26:16, scratch115, 21:11);
- s(McEmemArbTimingFaw, 6:0, scratch115, 28:22);
- s(EmcCfg2, 11:10, scratch115, 30:29);
- s(EmcCfg2, 14:14, scratch115, 31:31);
- s(EmcPmacroObDdllLongDqRank1_2, 10:0, scratch123, 10:0);
- s(EmcPmacroObDdllLongDqRank1_2, 26:16, scratch123, 21:11);
- s(McEmemArbTimingRap2Pre, 6:0, scratch123, 28:22);
- s(EmcCfg2, 16:15, scratch123, 30:29);
- s(EmcCfg2, 20:20, scratch123, 31:31);
- s(EmcPmacroObDdllLongDqRank1_3, 10:0, scratch124, 10:0);
- s(EmcPmacroObDdllLongDqRank1_3, 26:16, scratch124, 21:11);
- s(McEmemArbTimingWap2Pre, 6:0, scratch124, 28:22);
- s(EmcCfg2, 24:22, scratch124, 31:29);
- s(EmcPmacroObDdllLongDqRank1_4, 10:0, scratch125, 10:0);
- s(EmcPmacroObDdllLongDqRank1_4, 26:16, scratch125, 21:11);
- s(McEmemArbTimingR2W, 6:0, scratch125, 28:22);
- s(EmcCfg2, 25:25, scratch125, 29:29);
- s(EmcCfg2, 29:28, scratch125, 31:30);
- s(EmcPmacroObDdllLongDqRank1_5, 10:0, scratch126, 10:0);
- s(EmcPmacroObDdllLongDqRank1_5, 26:16, scratch126, 21:11);
- s(McEmemArbTimingW2R, 6:0, scratch126, 28:22);
- s(EmcCfg2, 31:30, scratch126, 30:29);
- s(EmcCfgPipe, 0:0, scratch126, 31:31);
- s(EmcPmacroObDdllLongDqsRank0_0, 10:0, scratch127, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_0, 26:16, scratch127, 21:11);
- s(EmcRp, 5:0, scratch127, 27:22);
- s(EmcCfgPipe, 4:1, scratch127, 31:28);
- s(EmcPmacroObDdllLongDqsRank0_1, 10:0, scratch128, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_1, 26:16, scratch128, 21:11);
- s(EmcR2w, 5:0, scratch128, 27:22);
- s(EmcCfgPipe, 8:5, scratch128, 31:28);
- s(EmcPmacroObDdllLongDqsRank0_2, 10:0, scratch129, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_2, 26:16, scratch129, 21:11);
- s(EmcW2r, 5:0, scratch129, 27:22);
- s(EmcCfgPipe, 11:9, scratch129, 30:28);
- s(EmcCfgPipe, 16:16, scratch129, 31:31);
- s(EmcPmacroObDdllLongDqsRank0_3, 10:0, scratch130, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_3, 26:16, scratch130, 21:11);
- s(EmcR2p, 5:0, scratch130, 27:22);
- s(EmcCfgPipe, 20:17, scratch130, 31:28);
- s(EmcPmacroObDdllLongDqsRank0_4, 10:0, scratch131, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_4, 26:16, scratch131, 21:11);
- s(EmcCcdmw, 5:0, scratch131, 27:22);
- s(EmcCfgPipe, 24:21, scratch131, 31:28);
- s(EmcPmacroObDdllLongDqsRank0_5, 10:0, scratch132, 10:0);
- s(EmcPmacroObDdllLongDqsRank0_5, 26:16, scratch132, 21:11);
- s(EmcRdRcd, 5:0, scratch132, 27:22);
- s(EmcCfgPipe, 27:25, scratch132, 30:28);
- s(EmcPmacroTxPwrd0, 0:0, scratch132, 31:31);
- s(EmcPmacroObDdllLongDqsRank1_0, 10:0, scratch133, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_0, 26:16, scratch133, 21:11);
- s(EmcWrRcd, 5:0, scratch133, 27:22);
- s(EmcPmacroTxPwrd0, 4:1, scratch133, 31:28);
- s(EmcPmacroObDdllLongDqsRank1_1, 10:0, scratch134, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_1, 26:16, scratch134, 21:11);
- s(EmcWdv, 5:0, scratch134, 27:22);
- s(EmcPmacroTxPwrd0, 8:5, scratch134, 31:28);
- s(EmcPmacroObDdllLongDqsRank1_2, 10:0, scratch135, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_2, 26:16, scratch135, 21:11);
- s(EmcQUse, 5:0, scratch135, 27:22);
- s(EmcPmacroTxPwrd0, 12:9, scratch135, 31:28);
- s(EmcPmacroObDdllLongDqsRank1_3, 10:0, scratch136, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_3, 26:16, scratch136, 21:11);
- s(EmcPdEx2Wr, 5:0, scratch136, 27:22);
- s(EmcPmacroTxPwrd0, 13:13, scratch136, 28:28);
- s(EmcPmacroTxPwrd0, 18:16, scratch136, 31:29);
- s(EmcPmacroObDdllLongDqsRank1_4, 10:0, scratch137, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_4, 26:16, scratch137, 21:11);
- s(EmcPdEx2Rd, 5:0, scratch137, 27:22);
- s(EmcPmacroTxPwrd0, 22:19, scratch137, 31:28);
- s(EmcPmacroObDdllLongDqsRank1_5, 10:0, scratch138, 10:0);
- s(EmcPmacroObDdllLongDqsRank1_5, 26:16, scratch138, 21:11);
- s(EmcPdex2Cke, 5:0, scratch138, 27:22);
- s(EmcPmacroTxPwrd0, 26:23, scratch138, 31:28);
- s(EmcPmacroIbDdllLongDqsRank0_0, 10:0, scratch139, 10:0);
- s(EmcPmacroIbDdllLongDqsRank0_0, 26:16, scratch139, 21:11);
- s(EmcPChg2Pden, 5:0, scratch139, 27:22);
- s(EmcPmacroTxPwrd0, 29:27, scratch139, 30:28);
- s(EmcPmacroTxPwrd1, 0:0, scratch139, 31:31);
- s(EmcPmacroIbDdllLongDqsRank0_1, 10:0, scratch140, 10:0);
- s(EmcPmacroIbDdllLongDqsRank0_1, 26:16, scratch140, 21:11);
- s(EmcAct2Pden, 5:0, scratch140, 27:22);
- s(EmcPmacroTxPwrd1, 4:1, scratch140, 31:28);
- s(EmcPmacroIbDdllLongDqsRank0_2, 10:0, scratch141, 10:0);
- s(EmcPmacroIbDdllLongDqsRank0_2, 26:16, scratch141, 21:11);
- s(EmcCke2Pden, 5:0, scratch141, 27:22);
- s(EmcPmacroTxPwrd1, 8:5, scratch141, 31:28);
- s(EmcPmacroIbDdllLongDqsRank0_3, 10:0, scratch142, 10:0);
- s(EmcPmacroIbDdllLongDqsRank0_3, 26:16, scratch142, 21:11);
- s(EmcTcke, 5:0, scratch142, 27:22);
- s(EmcPmacroTxPwrd1, 12:9, scratch142, 31:28);
- s(EmcPmacroIbDdllLongDqsRank1_0, 10:0, scratch143, 10:0);
- s(EmcPmacroIbDdllLongDqsRank1_0, 26:16, scratch143, 21:11);
- s(EmcTrpab, 5:0, scratch143, 27:22);
- s(EmcPmacroTxPwrd1, 13:13, scratch143, 28:28);
- s(EmcPmacroTxPwrd1, 18:16, scratch143, 31:29);
- s(EmcPmacroIbDdllLongDqsRank1_1, 10:0, scratch144, 10:0);
- s(EmcPmacroIbDdllLongDqsRank1_1, 26:16, scratch144, 21:11);
- s(EmcClkenOverride, 3:1, scratch144, 24:22);
- s(EmcClkenOverride, 8:6, scratch144, 27:25);
- s(EmcPmacroTxPwrd1, 22:19, scratch144, 31:28);
- s(EmcPmacroIbDdllLongDqsRank1_2, 10:0, scratch145, 10:0);
- s(EmcPmacroIbDdllLongDqsRank1_2, 26:16, scratch145, 21:11);
- s(EmcEInput, 5:0, scratch145, 27:22);
- s(EmcPmacroTxPwrd1, 26:23, scratch145, 31:28);
- s(EmcPmacroIbDdllLongDqsRank1_3, 10:0, scratch146, 10:0);
- s(EmcPmacroIbDdllLongDqsRank1_3, 26:16, scratch146, 21:11);
- s(EmcEInputDuration, 5:0, scratch146, 27:22);
- s(EmcPmacroTxPwrd1, 29:27, scratch146, 30:28);
- s(EmcPmacroTxPwrd2, 0:0, scratch146, 31:31);
- s(EmcPmacroDdllLongCmd_0, 10:0, scratch147, 10:0);
- s(EmcPmacroDdllLongCmd_0, 26:16, scratch147, 21:11);
- s(EmcPutermExtra, 5:0, scratch147, 27:22);
- s(EmcPmacroTxPwrd2, 4:1, scratch147, 31:28);
- s(EmcPmacroDdllLongCmd_1, 10:0, scratch148, 10:0);
- s(EmcPmacroDdllLongCmd_1, 26:16, scratch148, 21:11);
- s(EmcTckesr, 5:0, scratch148, 27:22);
- s(EmcPmacroTxPwrd2, 8:5, scratch148, 31:28);
- s(EmcPmacroDdllLongCmd_2, 10:0, scratch149, 10:0);
- s(EmcPmacroDdllLongCmd_2, 26:16, scratch149, 21:11);
- s(EmcTpd, 5:0, scratch149, 27:22);
- s(EmcPmacroTxPwrd2, 12:9, scratch149, 31:28);
- s(EmcPmacroDdllLongCmd_3, 10:0, scratch150, 10:0);
- s(EmcPmacroDdllLongCmd_3, 26:16, scratch150, 21:11);
- s(EmcWdvMask, 5:0, scratch150, 27:22);
- s(EmcPmacroTxPwrd2, 13:13, scratch150, 28:28);
- s(EmcPmacroTxPwrd2, 18:16, scratch150, 31:29);
- s(McEmemArbCfg, 8:0, scratch151, 8:0);
- s(McEmemArbCfg, 20:16, scratch151, 13:9);
- s(McEmemArbCfg, 31:24, scratch151, 21:14);
- s(EmcWdvChk, 5:0, scratch151, 27:22);
- s(EmcPmacroTxPwrd2, 22:19, scratch151, 31:28);
- s(McEmemArbMisc1, 12:0, scratch152, 12:0);
- s(McEmemArbMisc1, 25:21, scratch152, 17:13);
- s(McEmemArbMisc1, 31:28, scratch152, 21:18);
- s(EmcCmdBrlshft0, 5:0, scratch152, 27:22);
- s(EmcPmacroTxPwrd2, 26:23, scratch152, 31:28);
- s(EmcMrsWaitCnt2, 9:0, scratch153, 9:0);
- s(EmcMrsWaitCnt2, 26:16, scratch153, 20:10);
- s(EmcPmacroIbRxrt, 10:0, scratch153, 31:21);
- s(EmcMrsWaitCnt, 9:0, scratch154, 9:0);
- s(EmcMrsWaitCnt, 26:16, scratch154, 20:10);
- s(EmcPmacroDdllLongCmd_4, 10:0, scratch154, 31:21);
- s(EmcAutoCalInterval, 20:0, scratch155, 20:0);
- s(McEmemArbOutstandingReq, 8:0, scratch155, 29:21);
- s(McEmemArbOutstandingReq, 31:30, scratch155, 31:30);
- s(McEmemArbRefpbHpCtrl, 6:0, scratch156, 6:0);
- s(McEmemArbRefpbHpCtrl, 14:8, scratch156, 13:7);
- s(McEmemArbRefpbHpCtrl, 22:16, scratch156, 20:14);
- s(EmcCmdBrlshft1, 5:0, scratch156, 26:21);
- s(EmcRrd, 4:0, scratch156, 31:27);
- s(EmcQuseBrlshft0, 19:0, scratch157, 19:0);
- s(EmcFbioCfg8, 27:16, scratch157, 31:20);
- s(EmcQuseBrlshft1, 19:0, scratch158, 19:0);
- s(EmcTxsrDll, 11:0, scratch158, 31:20);
- s(EmcQuseBrlshft2, 19:0, scratch159, 19:0);
- s(EmcTxdsrvttgen, 11:0, scratch159, 31:20);
- s(EmcQuseBrlshft3, 19:0, scratch160, 19:0);
- s(EmcPmacroVttgenCtrl0, 3:0, scratch160, 23:20);
- s(EmcPmacroVttgenCtrl0, 11:8, scratch160, 27:24);
- s(EmcPmacroVttgenCtrl0, 19:16, scratch160, 31:28);
- s(EmcPmacroVttgenCtrl1, 19:0, scratch161, 19:0);
- s(EmcCmdBrlshft2, 5:0, scratch161, 25:20);
- s(EmcCmdBrlshft3, 5:0, scratch161, 31:26);
- s(EmcAutoCalConfig3, 5:0, scratch162, 5:0);
- s(EmcAutoCalConfig3, 13:8, scratch162, 11:6);
- s(EmcAutoCalConfig3, 18:16, scratch162, 14:12);
- s(EmcAutoCalConfig3, 22:20, scratch162, 17:15);
- s(EmcTRefBw, 13:0, scratch162, 31:18);
- s(EmcAutoCalConfig4, 5:0, scratch163, 5:0);
- s(EmcAutoCalConfig4, 13:8, scratch163, 11:6);
- s(EmcAutoCalConfig4, 18:16, scratch163, 14:12);
- s(EmcAutoCalConfig4, 22:20, scratch163, 17:15);
- s(EmcQpop, 6:0, scratch163, 24:18);
- s(EmcQpop, 22:16, scratch163, 31:25);
- s(EmcAutoCalConfig5, 5:0, scratch164, 5:0);
- s(EmcAutoCalConfig5, 13:8, scratch164, 11:6);
- s(EmcAutoCalConfig5, 18:16, scratch164, 14:12);
- s(EmcAutoCalConfig5, 22:20, scratch164, 17:15);
- s(EmcPmacroAutocalCfgCommon, 5:0, scratch164, 23:18);
- s(EmcPmacroAutocalCfgCommon, 13:8, scratch164, 29:24);
- s(EmcPmacroAutocalCfgCommon, 16:16, scratch164, 30:30);
- s(EmcPmacroTxPwrd2, 27:27, scratch164, 31:31);
- s(EmcAutoCalConfig6, 5:0, scratch165, 5:0);
- s(EmcAutoCalConfig6, 13:8, scratch165, 11:6);
- s(EmcAutoCalConfig6, 18:16, scratch165, 14:12);
- s(EmcAutoCalConfig6, 22:20, scratch165, 17:15);
- s(EmcWev, 5:0, scratch165, 23:18);
- s(EmcWsv, 5:0, scratch165, 29:24);
- s(EmcPmacroTxPwrd2, 29:28, scratch165, 31:30);
- s(EmcAutoCalConfig7, 5:0, scratch166, 5:0);
- s(EmcAutoCalConfig7, 13:8, scratch166, 11:6);
- s(EmcAutoCalConfig7, 18:16, scratch166, 14:12);
- s(EmcAutoCalConfig7, 22:20, scratch166, 17:15);
- s(EmcCfg3, 2:0, scratch166, 20:18);
- s(EmcCfg3, 6:4, scratch166, 23:21);
- s(EmcQuseWidth, 3:0, scratch166, 27:24);
- s(EmcQuseWidth, 29:28, scratch166, 29:28);
- s(EmcPmacroTxPwrd3, 1:0, scratch166, 31:30);
- s(EmcAutoCalConfig8, 5:0, scratch167, 5:0);
- s(EmcAutoCalConfig8, 13:8, scratch167, 11:6);
- s(EmcAutoCalConfig8, 18:16, scratch167, 14:12);
- s(EmcAutoCalConfig8, 22:20, scratch167, 17:15);
- s(EmcPmacroBgBiasCtrl0, 2:0, scratch167, 20:18);
- s(EmcPmacroBgBiasCtrl0, 6:4, scratch167, 23:21);
- s(McEmemArbTimingRcd, 5:0, scratch167, 29:24);
- s(EmcPmacroTxPwrd3, 3:2, scratch167, 31:30);
- s(EmcXm2CompPadCtrl2, 17:0, scratch168, 17:0);
- s(McEmemArbTimingCcdmw, 5:0, scratch168, 23:18);
- s(McEmemArbOverride, 27:27, scratch168, 24:24);
- s(McEmemArbOverride, 26:26, scratch168, 25:25);
- s(McEmemArbOverride, 16:16, scratch168, 26:26);
- s(McEmemArbOverride, 10:10, scratch168, 27:27);
- s(McEmemArbOverride, 4:4, scratch168, 28:28);
- s(McEmemArbOverride, 3:3, scratch168, 29:29);
- s(EmcPmacroTxPwrd3, 5:4, scratch168, 31:30);
- s(EmcXm2CompPadCtrl3, 17:0, scratch169, 17:0);
- s(EmcRext, 4:0, scratch169, 22:18);
- s(EmcTClkStop, 4:0, scratch169, 27:23);
- s(EmcPmacroTxPwrd3, 9:6, scratch169, 31:28);
- s(EmcZcalWaitCnt, 10:0, scratch170, 10:0);
- s(EmcZcalWaitCnt, 21:16, scratch170, 16:11);
- s(EmcZcalWaitCnt, 31:31, scratch170, 17:17);
- s(EmcWext, 4:0, scratch170, 22:18);
- s(EmcRefctrl2, 0:0, scratch170, 23:23);
- s(EmcRefctrl2, 26:24, scratch170, 26:24);
- s(EmcRefctrl2, 31:31, scratch170, 27:27);
- s(EmcPmacroTxPwrd3, 13:10, scratch170, 31:28);
- s(EmcZcalMrwCmd, 7:0, scratch171, 7:0);
- s(EmcZcalMrwCmd, 23:16, scratch171, 15:8);
- s(EmcZcalMrwCmd, 31:30, scratch171, 17:16);
- s(EmcWeDuration, 4:0, scratch171, 22:18);
- s(EmcWsDuration, 4:0, scratch171, 27:23);
- s(EmcPmacroTxPwrd3, 19:16, scratch171, 31:28);
- s(EmcSwizzleRank0Byte0, 2:0, scratch172, 2:0);
- s(EmcSwizzleRank0Byte0, 6:4, scratch172, 5:3);
- s(EmcSwizzleRank0Byte0, 10:8, scratch172, 8:6);
- s(EmcSwizzleRank0Byte0, 14:12, scratch172, 11:9);
- s(EmcSwizzleRank0Byte0, 18:16, scratch172, 14:12);
- s(EmcSwizzleRank0Byte0, 22:20, scratch172, 17:15);
- s(EmcPutermWidth, 31:31, scratch172, 18:18);
- s(EmcPutermWidth, 3:0, scratch172, 22:19);
- s(McEmemArbTimingRrd, 4:0, scratch172, 27:23);
- s(EmcPmacroTxPwrd3, 23:20, scratch172, 31:28);
- s(EmcSwizzleRank0Byte1, 2:0, scratch173, 2:0);
- s(EmcSwizzleRank0Byte1, 6:4, scratch173, 5:3);
- s(EmcSwizzleRank0Byte1, 10:8, scratch173, 8:6);
- s(EmcSwizzleRank0Byte1, 14:12, scratch173, 11:9);
- s(EmcSwizzleRank0Byte1, 18:16, scratch173, 14:12);
- s(EmcSwizzleRank0Byte1, 22:20, scratch173, 17:15);
- s(McEmemArbTimingR2R, 4:0, scratch173, 22:18);
- s(McEmemArbTimingW2W, 4:0, scratch173, 27:23);
- s(EmcPmacroTxPwrd3, 27:24, scratch173, 31:28);
- s(EmcSwizzleRank0Byte2, 2:0, scratch174, 2:0);
- s(EmcSwizzleRank0Byte2, 6:4, scratch174, 5:3);
- s(EmcSwizzleRank0Byte2, 10:8, scratch174, 8:6);
- s(EmcSwizzleRank0Byte2, 14:12, scratch174, 11:9);
- s(EmcSwizzleRank0Byte2, 18:16, scratch174, 14:12);
- s(EmcSwizzleRank0Byte2, 22:20, scratch174, 17:15);
- s(EmcPmacroTxPwrd3, 29:28, scratch174, 19:18);
- s(EmcPmacroTxSelClkSrc0, 11:0, scratch174, 31:20);
- s(EmcSwizzleRank0Byte3, 2:0, scratch175, 2:0);
- s(EmcSwizzleRank0Byte3, 6:4, scratch175, 5:3);
- s(EmcSwizzleRank0Byte3, 10:8, scratch175, 8:6);
- s(EmcSwizzleRank0Byte3, 14:12, scratch175, 11:9);
- s(EmcSwizzleRank0Byte3, 18:16, scratch175, 14:12);
- s(EmcSwizzleRank0Byte3, 22:20, scratch175, 17:15);
- s(EmcPmacroTxSelClkSrc0, 27:16, scratch175, 29:18);
- s(EmcPmacroTxSelClkSrc1, 1:0, scratch175, 31:30);
- s(EmcSwizzleRank1Byte0, 2:0, scratch176, 2:0);
- s(EmcSwizzleRank1Byte0, 6:4, scratch176, 5:3);
- s(EmcSwizzleRank1Byte0, 10:8, scratch176, 8:6);
- s(EmcSwizzleRank1Byte0, 14:12, scratch176, 11:9);
- s(EmcSwizzleRank1Byte0, 18:16, scratch176, 14:12);
- s(EmcSwizzleRank1Byte0, 22:20, scratch176, 17:15);
- s(EmcPmacroTxSelClkSrc1, 11:2, scratch176, 27:18);
- s(EmcPmacroTxSelClkSrc1, 19:16, scratch176, 31:28);
- s(EmcSwizzleRank1Byte1, 2:0, scratch177, 2:0);
- s(EmcSwizzleRank1Byte1, 6:4, scratch177, 5:3);
- s(EmcSwizzleRank1Byte1, 10:8, scratch177, 8:6);
- s(EmcSwizzleRank1Byte1, 14:12, scratch177, 11:9);
- s(EmcSwizzleRank1Byte1, 18:16, scratch177, 14:12);
- s(EmcSwizzleRank1Byte1, 22:20, scratch177, 17:15);
- s(EmcPmacroTxSelClkSrc1, 27:20, scratch177, 25:18);
- s(EmcPmacroTxSelClkSrc3, 5:0, scratch177, 31:26);
- s(EmcSwizzleRank1Byte2, 2:0, scratch178, 2:0);
- s(EmcSwizzleRank1Byte2, 6:4, scratch178, 5:3);
- s(EmcSwizzleRank1Byte2, 10:8, scratch178, 8:6);
- s(EmcSwizzleRank1Byte2, 14:12, scratch178, 11:9);
- s(EmcSwizzleRank1Byte2, 18:16, scratch178, 14:12);
- s(EmcSwizzleRank1Byte2, 22:20, scratch178, 17:15);
- s(EmcPmacroTxSelClkSrc3, 11:6, scratch178, 23:18);
- s(EmcPmacroTxSelClkSrc3, 23:16, scratch178, 31:24);
- s(EmcSwizzleRank1Byte3, 2:0, scratch179, 2:0);
- s(EmcSwizzleRank1Byte3, 6:4, scratch179, 5:3);
- s(EmcSwizzleRank1Byte3, 10:8, scratch179, 8:6);
- s(EmcSwizzleRank1Byte3, 14:12, scratch179, 11:9);
- s(EmcSwizzleRank1Byte3, 18:16, scratch179, 14:12);
- s(EmcSwizzleRank1Byte3, 22:20, scratch179, 17:15);
- s(EmcPmacroTxSelClkSrc3, 27:24, scratch179, 21:18);
- s(EmcPmacroTxSelClkSrc2, 9:0, scratch179, 31:22);
- s(EmcPmacroCmdBrickCtrlFdpd, 17:0, scratch180, 17:0);
- s(EmcPmacroTxSelClkSrc2, 11:10, scratch180, 19:18);
- s(EmcPmacroTxSelClkSrc2, 27:16, scratch180, 31:20);
- s(EmcPmacroDataBrickCtrlFdpd, 17:0, scratch181, 17:0);
- s(EmcPmacroTxSelClkSrc4, 11:0, scratch181, 29:18);
- s(EmcPmacroTxSelClkSrc4, 17:16, scratch181, 31:30);
- s(EmcFbioCfg7, 16:0, scratch182, 16:0);
- s(McEmemArbRefpbBankCtrl, 6:0, scratch182, 23:17);
- s(McEmemArbRefpbBankCtrl, 14:8, scratch182, 30:24);
- s(McEmemArbRefpbBankCtrl, 31:31, scratch182, 31:31);
- s(EmcDynSelfRefControl, 15:0, scratch183, 15:0);
- s(EmcDynSelfRefControl, 31:31, scratch183, 16:16);
- s(EmcPmacroTxSelClkSrc4, 27:18, scratch183, 26:17);
- s(EmcPmacroTxSelClkSrc5, 4:0, scratch183, 31:27);
- s(EmcDllCfg1, 16:0, scratch184, 16:0);
- s(EmcPmacroTxSelClkSrc5, 11:5, scratch184, 23:17);
- s(EmcPmacroTxSelClkSrc5, 23:16, scratch184, 31:24);
- s(EmcPmacroPadCfgCtrl, 1:0, scratch185, 1:0);
- s(EmcPmacroPadCfgCtrl, 6:5, scratch185, 3:2);
- s(EmcPmacroPadCfgCtrl, 11:9, scratch185, 6:4);
- s(EmcPmacroPadCfgCtrl, 13:13, scratch185, 7:7);
- s(EmcPmacroPadCfgCtrl, 17:16, scratch185, 9:8);
- s(EmcPmacroPadCfgCtrl, 21:20, scratch185, 11:10);
- s(EmcPmacroPadCfgCtrl, 25:24, scratch185, 13:12);
- s(EmcPmacroPadCfgCtrl, 30:28, scratch185, 16:14);
- s(EmcPmacroTxSelClkSrc5, 27:24, scratch185, 20:17);
- s(EmcPmacroCmdPadTxCtrl, 1:0, scratch185, 22:21);
- s(EmcPmacroCmdPadTxCtrl, 5:4, scratch185, 24:23);
- s(EmcPmacroCmdPadTxCtrl, 9:8, scratch185, 26:25);
- s(EmcPmacroCmdPadTxCtrl, 13:12, scratch185, 28:27);
- s(EmcPmacroCmdPadTxCtrl, 16:16, scratch185, 29:29);
- s(EmcPmacroCmdPadTxCtrl, 21:20, scratch185, 31:30);
- s(EmcRefresh, 15:0, scratch186, 15:0);
- s(EmcCmdQ, 4:0, scratch186, 20:16);
- s(EmcCmdQ, 10:8, scratch186, 23:21);
- s(EmcCmdQ, 14:12, scratch186, 26:24);
- s(EmcCmdQ, 28:24, scratch186, 31:27);
- s(EmcAcpdControl, 15:0, scratch187, 15:0);
- s(EmcAutoCalVrefSel1, 15:0, scratch187, 31:16);
- s(EmcXm2CompPadCtrl, 1:0, scratch188, 1:0);
- s(EmcXm2CompPadCtrl, 6:3, scratch188, 5:2);
- s(EmcXm2CompPadCtrl, 9:9, scratch188, 6:6);
- s(EmcXm2CompPadCtrl, 19:11, scratch188, 15:7);
- s(EmcCfgDigDllPeriod, 15:0, scratch188, 31:16);
- s(EmcCfgDigDll_1, 15:0, scratch189, 15:0);
- s(EmcPreRefreshReqCnt, 15:0, scratch189, 31:16);
- s(EmcPmacroCmdPadTxCtrl, 27:24, scratch190, 19:16);
- s(EmcPmacroDataPadTxCtrl, 1:0, scratch190, 21:20);
- s(EmcPmacroDataPadTxCtrl, 5:4, scratch190, 23:22);
- s(EmcPmacroDataPadTxCtrl, 9:8, scratch190, 25:24);
- s(EmcPmacroDataPadTxCtrl, 13:12, scratch190, 27:26);
- s(EmcPmacroDataPadTxCtrl, 16:16, scratch190, 28:28);
- s(EmcPmacroDataPadTxCtrl, 21:20, scratch190, 30:29);
- s(EmcPmacroDataPadTxCtrl, 24:24, scratch190, 31:31);
- s(EmcPmacroDataPadTxCtrl, 27:25, scratch191, 2:0);
-
- s(EmcPinGpio, 1:0, scratch8, 31:30);
- s(EmcPinGpioEn, 1:0, scratch9, 31:30);
- s(EmcDevSelect, 1:0, scratch10, 31:30);
- s(EmcZcalWarmColdBootEnables, 1:0, scratch11, 31:30);
- s(EmcCfgDigDllPeriodWarmBoot, 1:0, scratch12, 31:30);
- s32(EmcBctSpare13, scratch31);
- s32(EmcBctSpare12, scratch32);
- s32(EmcBctSpare7, scratch33);
- s32(EmcBctSpare6, scratch40);
- s32(EmcBctSpare5, scratch42);
- s32(EmcBctSpare4, scratch44);
- s32(EmcBctSpare3, scratch45);
- s32(EmcBctSpare2, scratch46);
- s32(EmcBctSpare1, scratch47);
- s32(EmcBctSpare0, scratch48);
- s32(EmcBctSpare9, scratch50);
- s32(EmcBctSpare8, scratch51);
- s32(BootRomPatchData, scratch56);
- s32(BootRomPatchControl, scratch57);
- s(McClkenOverrideAllWarmBoot, 0:0, scratch58, 31:31);
- s(EmcClkenOverrideAllWarmBoot, 0:0, scratch59, 30:30);
- s(EmcMrsWarmBootEnable, 0:0, scratch59, 31:31);
- s(ClearClk2Mc1, 0:0, scratch60, 30:30);
- s(EmcWarmBootExtraModeRegWriteEnable, 0:0, scratch60, 31:31);
- s(ClkRstControllerPllmMisc2OverrideEnable, 0:0, scratch61, 30:30);
- s(EmcDbgWriteMux, 0:0, scratch61, 31:31);
- s(EmcExtraRefreshNum, 2:0, scratch62, 31:29);
- s(PmcIoDpd3ReqWait, 2:0, scratch68, 30:28);
- s(AhbArbitrationXbarCtrlMemInitDone, 0:0, scratch68, 31:31);
- s(MemoryType, 2:0, scratch69, 30:28);
- s(PmcIoDpd4ReqWait, 2:0, scratch70, 30:28);
- s(EmcTimingControlWait, 7:0, scratch86, 31:24);
- s(EmcZcalWarmBootWait, 7:0, scratch87, 31:24);
- s(WarmBootWait, 7:0, scratch88, 31:24);
- s(EmcPinProgramWait, 7:0, scratch89, 31:24);
- s(EmcAutoCalWait, 9:0, scratch101, 31:22);
- s(SwizzleRankByteEncode, 15:0, scratch190, 15:0);
-
- switch (sdram->MemoryType)
- {
- case NvBootMemoryType_LpDdr2:
- case NvBootMemoryType_LpDdr4:
- s(EmcMrwLpddr2ZcalWarmBoot, 23:16, scratch5, 7:0);
- s(EmcMrwLpddr2ZcalWarmBoot, 7:0, scratch5, 15:8);
- s(EmcWarmBootMrwExtra, 23:16, scratch5, 23:16);
- s(EmcWarmBootMrwExtra, 7:0, scratch5, 31:24);
- s(EmcMrwLpddr2ZcalWarmBoot, 31:30, scratch6, 1:0);
- s(EmcWarmBootMrwExtra, 31:30, scratch6, 3:2);
- s(EmcMrwLpddr2ZcalWarmBoot, 27:26, scratch6, 5:4);
- s(EmcWarmBootMrwExtra, 27:26, scratch6, 7:6);
- s(EmcMrw6, 27:0, scratch8, 27:0);
- s(EmcMrw6, 31:30, scratch8, 29:28);
- s(EmcMrw8, 27:0, scratch9, 27:0);
- s(EmcMrw8, 31:30, scratch9, 29:28);
- s(EmcMrw9, 27:0, scratch10, 27:0);
- s(EmcMrw9, 31:30, scratch10, 29:28);
- s(EmcMrw10, 27:0, scratch11, 27:0);
- s(EmcMrw10, 31:30, scratch11, 29:28);
- s(EmcMrw12, 27:0, scratch12, 27:0);
- s(EmcMrw12, 31:30, scratch12, 29:28);
- s(EmcMrw13, 27:0, scratch13, 27:0);
- s(EmcMrw13, 31:30, scratch13, 29:28);
- s(EmcMrw14, 27:0, scratch14, 27:0);
- s(EmcMrw14, 31:30, scratch14, 29:28);
- s(EmcMrw1, 7:0, scratch15, 7:0);
- s(EmcMrw1, 23:16, scratch15, 15:8);
- s(EmcMrw1, 27:26, scratch15, 17:16);
- s(EmcMrw1, 31:30, scratch15, 19:18);
- s(EmcWarmBootMrwExtra, 7:0, scratch16, 7:0);
- s(EmcWarmBootMrwExtra, 23:16, scratch16, 15:8);
- s(EmcWarmBootMrwExtra, 27:26, scratch16, 17:16);
- s(EmcWarmBootMrwExtra, 31:30, scratch16, 19:18);
- s(EmcMrw2, 7:0, scratch17, 7:0);
- s(EmcMrw2, 23:16, scratch17, 15:8);
- s(EmcMrw2, 27:26, scratch17, 17:16);
- s(EmcMrw2, 31:30, scratch17, 19:18);
- s(EmcMrw3, 7:0, scratch18, 7:0);
- s(EmcMrw3, 23:16, scratch18, 15:8);
- s(EmcMrw3, 27:26, scratch18, 17:16);
- s(EmcMrw3, 31:30, scratch18, 19:18);
- s(EmcMrw4, 7:0, scratch19, 7:0);
- s(EmcMrw4, 23:16, scratch19, 15:8);
- s(EmcMrw4, 27:26, scratch19, 17:16);
- s(EmcMrw4, 31:30, scratch19, 19:18);
- break;
- case NvBootMemoryType_Ddr3:
- s(EmcMrs, 13:0, scratch5, 13:0);
- s(EmcEmrs, 13:0, scratch5, 27:14);
- s(EmcMrs, 21:20, scratch5, 29:28);
- s(EmcMrs, 31:30, scratch5, 31:30);
- s(EmcEmrs2, 13:0, scratch8, 13:0);
- s(EmcEmrs3, 13:0, scratch8, 27:14);
- s(EmcEmrs, 21:20, scratch8, 29:28);
- s(EmcWarmBootMrsExtra, 13:0, scratch9, 13:0);
- s(EmcEmrs, 31:30, scratch9, 15:14);
- s(EmcEmrs2, 21:20, scratch9, 17:16);
- s(EmcEmrs2, 31:30, scratch9, 19:18);
- s(EmcEmrs3, 21:20, scratch9, 21:20);
- s(EmcEmrs3, 31:30, scratch9, 23:22);
- s(EmcWarmBootMrsExtra, 31:30, scratch9, 25:24);
- s(EmcWarmBootMrsExtra, 21:20, scratch9, 27:26);
- s(EmcZqCalDdr3WarmBoot, 31:30, scratch9, 29:28);
- s(EmcMrs, 27:26, scratch10, 1:0);
- s(EmcEmrs, 27:26, scratch10, 3:2);
- s(EmcEmrs2, 27:26, scratch10, 5:4);
- s(EmcEmrs3, 27:26, scratch10, 7:6);
- s(EmcWarmBootMrsExtra, 27:27, scratch10, 8:8);
- s(EmcWarmBootMrsExtra, 26:26, scratch10, 9:9);
- s(EmcZqCalDdr3WarmBoot, 0:0, scratch10, 10:10);
- s(EmcZqCalDdr3WarmBoot, 4:4, scratch10, 11:11);
- break;
- }
-
- s32(EmcCmdMappingByte, secure_scratch8);
- s32(EmcPmacroBrickMapping0, secure_scratch9);
- s32(EmcPmacroBrickMapping1, secure_scratch10);
- s32(EmcPmacroBrickMapping2, secure_scratch11);
- s32(McVideoProtectGpuOverride0, secure_scratch12);
- s(EmcCmdMappingCmd0_0, 6:0, secure_scratch13, 6:0);
- s(EmcCmdMappingCmd0_0, 14:8, secure_scratch13, 13:7);
- s(EmcCmdMappingCmd0_0, 22:16, secure_scratch13, 20:14);
- s(EmcCmdMappingCmd0_0, 30:24, secure_scratch13, 27:21);
- s(McVideoProtectBomAdrHi, 1:0, secure_scratch13, 29:28);
- s(McVideoProtectWriteAccess, 1:0, secure_scratch13, 31:30);
- s(EmcCmdMappingCmd0_1, 6:0, secure_scratch14, 6:0);
- s(EmcCmdMappingCmd0_1, 14:8, secure_scratch14, 13:7);
- s(EmcCmdMappingCmd0_1, 22:16, secure_scratch14, 20:14);
- s(EmcCmdMappingCmd0_1, 30:24, secure_scratch14, 27:21);
- s(McSecCarveoutAdrHi, 1:0, secure_scratch14, 29:28);
- s(McMtsCarveoutAdrHi, 1:0, secure_scratch14, 31:30);
- s(EmcCmdMappingCmd1_0, 6:0, secure_scratch15, 6:0);
- s(EmcCmdMappingCmd1_0, 14:8, secure_scratch15, 13:7);
- s(EmcCmdMappingCmd1_0, 22:16, secure_scratch15, 20:14);
- s(EmcCmdMappingCmd1_0, 30:24, secure_scratch15, 27:21);
- s(McGeneralizedCarveout5BomHi, 1:0, secure_scratch15, 29:28);
- s(McGeneralizedCarveout3BomHi, 1:0, secure_scratch15, 31:30);
- s(EmcCmdMappingCmd1_1, 6:0, secure_scratch16, 6:0);
- s(EmcCmdMappingCmd1_1, 14:8, secure_scratch16, 13:7);
- s(EmcCmdMappingCmd1_1, 22:16, secure_scratch16, 20:14);
- s(EmcCmdMappingCmd1_1, 30:24, secure_scratch16, 27:21);
- s(McGeneralizedCarveout2BomHi, 1:0, secure_scratch16, 29:28);
- s(McGeneralizedCarveout4BomHi, 1:0, secure_scratch16, 31:30);
- s(EmcCmdMappingCmd2_0, 6:0, secure_scratch17, 6:0);
- s(EmcCmdMappingCmd2_0, 14:8, secure_scratch17, 13:7);
- s(EmcCmdMappingCmd2_0, 22:16, secure_scratch17, 20:14);
- s(EmcCmdMappingCmd2_0, 30:24, secure_scratch17, 27:21);
- s(McGeneralizedCarveout1BomHi, 1:0, secure_scratch17, 29:28);
- s(EmcAdrCfg, 0:0, secure_scratch17, 30:30);
- s(EmcFbioSpare, 1:1, secure_scratch17, 31:31);
- s(EmcCmdMappingCmd2_1, 6:0, secure_scratch18, 6:0);
- s(EmcCmdMappingCmd2_1, 14:8, secure_scratch18, 13:7);
- s(EmcCmdMappingCmd2_1, 22:16, secure_scratch18, 20:14);
- s(EmcCmdMappingCmd2_1, 30:24, secure_scratch18, 27:21);
- s(EmcFbioCfg8, 15:15, secure_scratch18, 28:28);
- s(McEmemAdrCfg, 0:0, secure_scratch18, 29:29);
- s(McSecCarveoutProtectWriteAccess, 0:0, secure_scratch18, 30:30);
- s(McMtsCarveoutRegCtrl, 0:0, secure_scratch18, 31:31);
- s(EmcCmdMappingCmd3_0, 6:0, secure_scratch19, 6:0);
- s(EmcCmdMappingCmd3_0, 14:8, secure_scratch19, 13:7);
- s(EmcCmdMappingCmd3_0, 22:16, secure_scratch19, 20:14);
- s(EmcCmdMappingCmd3_0, 30:24, secure_scratch19, 27:21);
- s(McGeneralizedCarveout2Cfg0, 6:3, secure_scratch19, 31:28);
- s(EmcCmdMappingCmd3_1, 6:0, secure_scratch20, 6:0);
- s(EmcCmdMappingCmd3_1, 14:8, secure_scratch20, 13:7);
- s(EmcCmdMappingCmd3_1, 22:16, secure_scratch20, 20:14);
- s(EmcCmdMappingCmd3_1, 30:24, secure_scratch20, 27:21);
- s(McGeneralizedCarveout2Cfg0, 10:7, secure_scratch20, 31:28);
- s(McGeneralizedCarveout4Cfg0, 26:0, secure_scratch39, 26:0);
- s(McGeneralizedCarveout2Cfg0, 17:14, secure_scratch39, 30:27);
- s(McVideoProtectVprOverride, 0:0, secure_scratch39, 31:31);
- s(McGeneralizedCarveout5Cfg0, 26:0, secure_scratch40, 26:0);
- s(McGeneralizedCarveout2Cfg0, 21:18, secure_scratch40, 30:27);
- s(McVideoProtectVprOverride, 1:1, secure_scratch40, 31:31);
- s(EmcCmdMappingCmd0_2, 6:0, secure_scratch41, 6:0);
- s(EmcCmdMappingCmd0_2, 14:8, secure_scratch41, 13:7);
- s(EmcCmdMappingCmd0_2, 22:16, secure_scratch41, 20:14);
- s(EmcCmdMappingCmd0_2, 27:24, secure_scratch41, 24:21);
- s(McGeneralizedCarveout1Cfg0, 6:3, secure_scratch41, 28:25);
- s(McGeneralizedCarveout2Cfg0, 13:11, secure_scratch41, 31:29);
- s(EmcCmdMappingCmd1_2, 6:0, secure_scratch42, 6:0);
- s(EmcCmdMappingCmd1_2, 14:8, secure_scratch42, 13:7);
- s(EmcCmdMappingCmd1_2, 22:16, secure_scratch42, 20:14);
- s(EmcCmdMappingCmd1_2, 27:24, secure_scratch42, 24:21);
- s(McGeneralizedCarveout1Cfg0, 13:7, secure_scratch42, 31:25);
- s(EmcCmdMappingCmd2_2, 6:0, secure_scratch43, 6:0);
- s(EmcCmdMappingCmd2_2, 14:8, secure_scratch43, 13:7);
- s(EmcCmdMappingCmd2_2, 22:16, secure_scratch43, 20:14);
- s(EmcCmdMappingCmd2_2, 27:24, secure_scratch43, 24:21);
- s(McGeneralizedCarveout1Cfg0, 17:14, secure_scratch43, 28:25);
- s(McGeneralizedCarveout3Cfg0, 13:11, secure_scratch43, 31:29);
- s(EmcCmdMappingCmd3_2, 6:0, secure_scratch44, 6:0);
- s(EmcCmdMappingCmd3_2, 14:8, secure_scratch44, 13:7);
- s(EmcCmdMappingCmd3_2, 22:16, secure_scratch44, 20:14);
- s(EmcCmdMappingCmd3_2, 27:24, secure_scratch44, 24:21);
- s(McGeneralizedCarveout1Cfg0, 21:18, secure_scratch44, 28:25);
- s(McVideoProtectVprOverride, 3:2, secure_scratch44, 30:29);
- s(McVideoProtectVprOverride, 6:6, secure_scratch44, 31:31);
- s(McEmemAdrCfgChannelMask, 31:9, secure_scratch45, 22:0);
- s(McEmemAdrCfgDev0, 2:0, secure_scratch45, 25:23);
- s(McEmemAdrCfgDev0, 9:8, secure_scratch45, 27:26);
- s(McEmemAdrCfgDev0, 19:16, secure_scratch45, 31:28);
- s(McEmemAdrCfgBankMask0, 31:10, secure_scratch46, 21:0);
- s(McEmemAdrCfgDev1, 2:0, secure_scratch46, 24:22);
- s(McEmemAdrCfgDev1, 9:8, secure_scratch46, 26:25);
- s(McEmemAdrCfgDev1, 19:16, secure_scratch46, 30:27);
- s(McVideoProtectVprOverride, 7:7, secure_scratch46, 31:31);
- s(McEmemAdrCfgBankMask1, 31:10, secure_scratch47, 21:0);
- s(McGeneralizedCarveout3Cfg0, 10:3, secure_scratch47, 29:22);
- s(McVideoProtectVprOverride, 9:8, secure_scratch47, 31:30);
- s(McEmemAdrCfgBankMask2, 31:10, secure_scratch48, 21:0);
- s(McGeneralizedCarveout3Cfg0, 21:14, secure_scratch48, 29:22);
- s(McVideoProtectVprOverride, 11:11, secure_scratch48, 30:30);
- s(McVideoProtectVprOverride, 14:14, secure_scratch48, 31:31);
- s(McVideoProtectGpuOverride1, 15:0, secure_scratch49, 15:0);
- s(McEmemCfg, 13:0, secure_scratch49, 29:16);
- s(McEmemCfg, 31:31, secure_scratch49, 30:30);
- s(McVideoProtectVprOverride, 15:15, secure_scratch49, 31:31);
- s(McGeneralizedCarveout3Bom, 31:17, secure_scratch50, 14:0);
- s(McGeneralizedCarveout1Bom, 31:17, secure_scratch50, 29:15);
- s(McVideoProtectVprOverride, 18:17, secure_scratch50, 31:30);
- s(McGeneralizedCarveout4Bom, 31:17, secure_scratch51, 14:0);
- s(McGeneralizedCarveout2Bom, 31:17, secure_scratch51, 29:15);
- s(McVideoProtectVprOverride, 20:19, secure_scratch51, 31:30);
- s(McGeneralizedCarveout5Bom, 31:17, secure_scratch52, 14:0);
- s(McVideoProtectBom, 31:20, secure_scratch52, 26:15);
- s(McVideoProtectVprOverride, 23:21, secure_scratch52, 29:27);
- s(McVideoProtectVprOverride, 26:26, secure_scratch52, 30:30);
- s(McVideoProtectVprOverride, 29:29, secure_scratch52, 31:31);
- s(McVideoProtectSizeMb, 11:0, secure_scratch53, 11:0);
- s(McSecCarveoutBom, 31:20, secure_scratch53, 23:12);
- s(McVideoProtectVprOverride, 31:30, secure_scratch53, 25:24);
- s(McVideoProtectVprOverride1, 1:0, secure_scratch53, 27:26);
- s(McVideoProtectVprOverride1, 7:4, secure_scratch53, 31:28);
- s(McSecCarveoutSizeMb, 11:0, secure_scratch54, 11:0);
- s(McMtsCarveoutBom, 31:20, secure_scratch54, 23:12);
- s(McVideoProtectVprOverride1, 15:8, secure_scratch54, 31:24);
- s(McMtsCarveoutSizeMb, 11:0, secure_scratch55, 11:0);
- s(McGeneralizedCarveout4Size128kb, 11:0, secure_scratch55, 23:12);
- s(McVideoProtectVprOverride1, 16:16, secure_scratch55, 24:24);
- s(McGeneralizedCarveout2Cfg0, 2:0, secure_scratch55, 27:25);
- s(McGeneralizedCarveout2Cfg0, 25:22, secure_scratch55, 31:28);
- s(McGeneralizedCarveout3Size128kb, 11:0, secure_scratch56, 11:0);
- s(McGeneralizedCarveout2Size128kb, 11:0, secure_scratch56, 23:12);
- s(McGeneralizedCarveout2Cfg0, 26:26, secure_scratch56, 24:24);
- s(McGeneralizedCarveout1Cfg0, 2:0, secure_scratch56, 27:25);
- s(McGeneralizedCarveout1Cfg0, 25:22, secure_scratch56, 31:28);
- s(McGeneralizedCarveout1Size128kb, 11:0, secure_scratch57, 11:0);
- s(McGeneralizedCarveout5Size128kb, 11:0, secure_scratch57, 23:12);
- s(McGeneralizedCarveout1Cfg0, 26:26, secure_scratch57, 24:24);
- s(McGeneralizedCarveout3Cfg0, 2:0, secure_scratch57, 27:25);
- s(McGeneralizedCarveout3Cfg0, 25:22, secure_scratch57, 31:28);
- s(McGeneralizedCarveout3Cfg0, 26:26, secure_scratch58, 0:0);
-
- s32(McGeneralizedCarveout1Access0, secure_scratch59);
- s32(McGeneralizedCarveout1Access1, secure_scratch60);
- s32(McGeneralizedCarveout1Access2, secure_scratch61);
- s32(McGeneralizedCarveout1Access3, secure_scratch62);
- s32(McGeneralizedCarveout1Access4, secure_scratch63);
- s32(McGeneralizedCarveout2Access0, secure_scratch64);
- s32(McGeneralizedCarveout2Access1, secure_scratch65);
- s32(McGeneralizedCarveout2Access2, secure_scratch66);
- s32(McGeneralizedCarveout2Access3, secure_scratch67);
- s32(McGeneralizedCarveout2Access4, secure_scratch68);
- s32(McGeneralizedCarveout3Access0, secure_scratch69);
- s32(McGeneralizedCarveout3Access1, secure_scratch70);
- s32(McGeneralizedCarveout3Access2, secure_scratch71);
- s32(McGeneralizedCarveout3Access3, secure_scratch72);
- s32(McGeneralizedCarveout3Access4, secure_scratch73);
- s32(McGeneralizedCarveout4Access0, secure_scratch74);
- s32(McGeneralizedCarveout4Access1, secure_scratch75);
- s32(McGeneralizedCarveout4Access2, secure_scratch76);
- s32(McGeneralizedCarveout4Access3, secure_scratch77);
- s32(McGeneralizedCarveout4Access4, secure_scratch78);
- s32(McGeneralizedCarveout5Access0, secure_scratch79);
- s32(McGeneralizedCarveout5Access1, secure_scratch80);
- s32(McGeneralizedCarveout5Access2, secure_scratch81);
- s32(McGeneralizedCarveout5Access3, secure_scratch82);
- s32(McGeneralizedCarveout1ForceInternalAccess0, secure_scratch84);
- s32(McGeneralizedCarveout1ForceInternalAccess1, secure_scratch85);
- s32(McGeneralizedCarveout1ForceInternalAccess2, secure_scratch86);
- s32(McGeneralizedCarveout1ForceInternalAccess3, secure_scratch87);
- s32(McGeneralizedCarveout1ForceInternalAccess4, secure_scratch88);
- s32(McGeneralizedCarveout2ForceInternalAccess0, secure_scratch89);
- s32(McGeneralizedCarveout2ForceInternalAccess1, secure_scratch90);
- s32(McGeneralizedCarveout2ForceInternalAccess2, secure_scratch91);
- s32(McGeneralizedCarveout2ForceInternalAccess3, secure_scratch92);
- s32(McGeneralizedCarveout2ForceInternalAccess4, secure_scratch93);
- s32(McGeneralizedCarveout3ForceInternalAccess0, secure_scratch94);
- s32(McGeneralizedCarveout3ForceInternalAccess1, secure_scratch95);
- s32(McGeneralizedCarveout3ForceInternalAccess2, secure_scratch96);
- s32(McGeneralizedCarveout3ForceInternalAccess3, secure_scratch97);
- s32(McGeneralizedCarveout3ForceInternalAccess4, secure_scratch98);
- s32(McGeneralizedCarveout4ForceInternalAccess0, secure_scratch99);
- s32(McGeneralizedCarveout4ForceInternalAccess1, secure_scratch100);
- s32(McGeneralizedCarveout4ForceInternalAccess2, secure_scratch101);
- s32(McGeneralizedCarveout4ForceInternalAccess3, secure_scratch102);
- s32(McGeneralizedCarveout4ForceInternalAccess4, secure_scratch103);
- s32(McGeneralizedCarveout5ForceInternalAccess0, secure_scratch104);
- s32(McGeneralizedCarveout5ForceInternalAccess1, secure_scratch105);
- s32(McGeneralizedCarveout5ForceInternalAccess2, secure_scratch106);
- s32(McGeneralizedCarveout5ForceInternalAccess3, secure_scratch107);
-
- c32(0, scratch2);
- s(PllMInputDivider, 7:0, scratch2, 7:0);
- s(PllMFeedbackDivider, 7:0, scratch2, 15:8);
- s(PllMPostDivider, 4:0, scratch2, 20:16);
- s(PllMKVCO, 0:0, scratch2, 21:21);
- s(PllMKCP, 1:0, scratch2, 23:22);
-
- c32(0, scratch35);
- s(PllMSetupControl, 15:0, scratch35, 15:0);
-
- c32(0, scratch3);
- s(PllMInputDivider, 7:0, scratch3, 7:0);
- c(0x3e, scratch3, 15:8);
- c(0, scratch3, 20:16);
- s(PllMKVCO, 0:0, scratch3, 21:21);
- s(PllMKCP, 1:0, scratch3, 23:22);
-
- c32(0, scratch36);
- s(PllMSetupControl, 23:0, scratch36, 23:0);
-
- c32(0, scratch4);
- s(PllMStableTime, 9:0, scratch4, 9:0);
-}
-
-#pragma GCC diagnostic ignored "-Wparentheses"
-
-static void _sdram_lp0_save_params_t210b01(const void *params)
-{
- struct sdram_params_t210b01 *sdram = (struct sdram_params_t210b01 *)params;
- struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE;
-
- u32 tmp = 0;
-
- sdram->mc_generalized_carveout1_cfg0 = 0;
- sdram->mc_generalized_carveout2_cfg0 = 0;
- sdram->mc_generalized_carveout3_cfg0 = 0;
- sdram->mc_generalized_carveout4_cfg0 = 0;
- sdram->mc_generalized_carveout5_cfg0 = 0;
-
- // Patch SDRAM parameters.
- u32 t0 = sdram->emc_swizzle_rank0_byte0 << 5 >> 29 > sdram->emc_swizzle_rank0_byte0 << 1 >> 29;
- u32 t1 = (t0 & 0xFFFFFFEF) | ((sdram->emc_swizzle_rank1_byte0 << 5 >> 29 > sdram->emc_swizzle_rank1_byte0 << 1 >> 29) << 4);
- u32 t2 = (t1 & 0xFFFFFFFD) | ((sdram->emc_swizzle_rank0_byte1 << 5 >> 29 > sdram->emc_swizzle_rank0_byte1 << 1 >> 29) << 1);
- u32 t3 = (t2 & 0xFFFFFFDF) | ((sdram->emc_swizzle_rank1_byte1 << 5 >> 29 > sdram->emc_swizzle_rank1_byte1 << 1 >> 29) << 5);
- u32 t4 = (t3 & 0xFFFFFFFB) | ((sdram->emc_swizzle_rank0_byte2 << 5 >> 29 > sdram->emc_swizzle_rank0_byte2 << 1 >> 29) << 2);
- u32 t5 = (t4 & 0xFFFFFFBF) | ((sdram->emc_swizzle_rank1_byte2 << 5 >> 29 > sdram->emc_swizzle_rank1_byte2 << 1 >> 29) << 6);
- u32 t6 = (t5 & 0xFFFFFFF7) | ((sdram->emc_swizzle_rank0_byte3 << 5 >> 29 > sdram->emc_swizzle_rank0_byte3 << 1 >> 29) << 3);
- u32 t7 = (t6 & 0xFFFFFF7F) | ((sdram->emc_swizzle_rank1_byte3 << 5 >> 29 > sdram->emc_swizzle_rank1_byte3 << 1 >> 29) << 7);
- sdram->swizzle_rank_byte_encode = t7;
- sdram->emc_bct_spare2 = 0x40000DD8;
- sdram->emc_bct_spare3 = t7;
-
- s(emc_clock_source, 7:0, scratch6, 15:8);
- s(emc_clock_source_dll, 7:0, scratch6, 23:16);
- s(emc_clock_source, 31:29, scratch6, 26:24);
- s(emc_clock_source_dll, 31:29, scratch6, 29:27);
- s(emc_clock_source_dll, 11:10, scratch6, 31:30);
- pmc->scratch7 = (sdram->emc_rc << 24) | ((sdram->emc_zqcal_lpddr4_warm_boot << 27 >> 31 << 23) | ((sdram->emc_zqcal_lpddr4_warm_boot << 30 >> 31 << 22) | ((sdram->emc_zqcal_lpddr4_warm_boot << 21) & 0x3FFFFF | ((sdram->clk_rst_pllm_misc20_override << 20) & 0x1FFFFF | ((sdram->clk_rst_pllm_misc20_override << 28 >> 31 << 19) | ((sdram->clk_rst_pllm_misc20_override << 27 >> 31 << 18) | ((sdram->clk_rst_pllm_misc20_override << 26 >> 31 << 17) | ((sdram->clk_rst_pllm_misc20_override << 21 >> 31 << 16) | ((sdram->clk_rst_pllm_misc20_override << 20 >> 31 << 15) | ((sdram->clk_rst_pllm_misc20_override << 19 >> 31 << 14) | ((sdram->clk_rst_pllm_misc20_override << 18 >> 31 << 13) | ((sdram->emc_clock_source << 15 >> 31 << 12) | ((sdram->emc_clock_source << 11 >> 31 << 11) | ((sdram->emc_clock_source << 12 >> 31 << 10) | ((sdram->emc_clock_source << 6 >> 31 << 9) | ((sdram->emc_clock_source << 16 >> 31 << 8) | ((32 * sdram->emc_clock_source >> 31 << 7) | ((16 * sdram->emc_clock_source >> 31 << 6) | (16 * (sdram->emc_zqcal_lpddr4_warm_boot >> 30) | (4 * (sdram->clk_rst_pllm_misc20_override << 29 >> 30) | ((sdram->clk_rst_pllm_misc20_override << 22 >> 30) | 4 * (pmc->scratch7 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFFFFFF;
- pmc->scratch8 = (sdram->emc_pmacro_bg_bias_ctrl0 << 18 >> 30 << 30) | ((4 * pmc->scratch8) >> 2);
- pmc->scratch14 = ((u8)(sdram->emc_cfg_pipe_clk) << 31) | (2 * (((u8)(sdram->emc_fdpd_ctrl_cmd_no_ramp) << 30) | pmc->scratch14 & 0xBFFFFFFF) >> 1);
- s(emc_qrst, 6:0, scratch15, 26:20);
- s(emc_qrst, 20:16, scratch15, 31:27);
- s(emc_pmacro_cmd_tx_drive, 5:0, scratch16, 25:20);
- s(emc_pmacro_cmd_tx_drive, 13:8, scratch16, 31:26);
- pmc->scratch17 = (16 * sdram->emc_fbio_cfg8 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg8 >> 31 << 30) | ((sdram->emc_fbio_cfg8 << 6 >> 31 << 29) | ((sdram->emc_fbio_cfg8 << 7 >> 31 << 28) | ((sdram->emc_fbio_cfg8 << 8 >> 31 << 27) | ((sdram->emc_fbio_cfg8 << 9 >> 31 << 26) | ((sdram->emc_fbio_cfg8 << 10 >> 31 << 25) | ((sdram->emc_fbio_cfg8 << 11 >> 31 << 24) | ((sdram->emc_fbio_cfg8 << 12 >> 31 << 23) | ((sdram->emc_fbio_cfg8 << 13 >> 31 << 22) | ((sdram->emc_fbio_cfg8 << 14 >> 31 << 21) | ((sdram->emc_fbio_cfg8 << 15 >> 31 << 20) | pmc->scratch17 & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch18 = ((u16)(sdram->emc_txsr_dll) << 20) | pmc->scratch18 & 0xFFFFF;
- pmc->scratch19 = (sdram->emc_txdsrvttgen << 20) | pmc->scratch19 & 0xFFFFF;
- s32(emc_cfg_rsv, scratch22);
- s32(emc_auto_cal_config, scratch23);
- s32(emc_auto_cal_vref_sel0, scratch24);
- s32(emc_pmacro_brick_ctrl_rfu1, scratch25);
- s32(emc_pmacro_brick_ctrl_rfu2, scratch26);
- s32(emc_pmc_scratch1, scratch27);
- s32(emc_pmc_scratch2, scratch28);
- s32(emc_pmc_scratch3, scratch29);
- pmc->scratch30 = (sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl0 & 3 | 4 * (pmc->scratch30 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch31 = (sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl1 & 3 | 4 * (pmc->scratch31 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch32 = (sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl2 & 3 | 4 * (pmc->scratch32 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch33 = (sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl3 & 3 | 4 * (pmc->scratch33 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch40 = (sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl4 & 3 | 4 * (pmc->scratch40 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch42 = (sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl5 & 3 | 4 * (pmc->scratch42 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch44 = (sdram->mc_emem_arb_da_turns >> 24 << 24) | ((sdram->mc_emem_arb_da_turns >> 16 << 16) | ((sdram->mc_emem_arb_da_turns << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_turns & 0xFF | (pmc->scratch44 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFFFFFF;
- pmc->scratch64 = ((u16)(sdram->mc_emem_arb_misc2) << 31) | (2 * ((sdram->emc_fbio_spare << 30) | ((sdram->emc_fbio_spare << 24 >> 26 << 24) | ((sdram->emc_fbio_spare << 16 >> 24 << 16) | ((sdram->emc_fbio_spare << 8 >> 24 << 8) | ((sdram->emc_fbio_spare >> 24) | (pmc->scratch64 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch65 = ((u16)(sdram->mc_da_cfg0) << 31 >> 1) | ((2 * sdram->mc_emem_arb_misc0 >> 29 << 27) | ((16 * sdram->mc_emem_arb_misc0 >> 31 << 26) | ((32 * sdram->mc_emem_arb_misc0 >> 26 << 20) | ((sdram->mc_emem_arb_misc0 << 11 >> 27 << 15) | ((sdram->mc_emem_arb_misc0 << 17 >> 25 << 8) | ((u8)sdram->mc_emem_arb_misc0 | (pmc->scratch65 >> 8 << 8)) & 0xFFFF80FF) & 0xFFF07FFF) & 0xFC0FFFFF) & 0xFBFFFFFF) & 0xC7FFFFFF) & 0xBFFFFFFF;
- pmc->scratch66 = (sdram->emc_fdpd_ctrl_cmd >> 30 << 27) | ((4 * sdram->emc_fdpd_ctrl_cmd >> 31 << 26) | ((8 * sdram->emc_fdpd_ctrl_cmd >> 27 << 21) | ((sdram->emc_fdpd_ctrl_cmd << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_cmd << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_cmd << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_cmd | (pmc->scratch66 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xFBFFFFFF) & 0xE7FFFFFF;
- pmc->scratch67 = ((u8)(sdram->emc_burst_refresh_num) << 28) | ((16 * sdram->emc_auto_cal_config2 >> 30 << 26) | ((sdram->emc_auto_cal_config2 << 6 >> 30 << 24) | ((sdram->emc_auto_cal_config2 << 8 >> 30 << 22) | ((sdram->emc_auto_cal_config2 << 10 >> 30 << 20) | ((sdram->emc_auto_cal_config2 << 12 >> 30 << 18) | ((sdram->emc_auto_cal_config2 << 14 >> 30 << 16) | ((sdram->emc_auto_cal_config2 << 16 >> 30 << 14) | ((sdram->emc_auto_cal_config2 << 18 >> 30 << 12) | ((sdram->emc_auto_cal_config2 << 20 >> 30 << 10) | ((sdram->emc_auto_cal_config2 << 22 >> 30 << 8) | ((sdram->emc_auto_cal_config2 << 24 >> 30 << 6) | (16 * (sdram->emc_auto_cal_config2 << 26 >> 30) | (4 * (sdram->emc_auto_cal_config2 << 28 >> 30) | (sdram->emc_auto_cal_config2 & 3 | 4 * (pmc->scratch67 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xFFFFFFF;
- pmc->scratch68 = ((u8)(sdram->emc_tppd) << 28) | ((sdram->emc_cfg_dig_dll >> 31 << 27) | ((2 * sdram->emc_cfg_dig_dll >> 31 << 26) | ((16 * sdram->emc_cfg_dig_dll >> 31 << 25) | ((sdram->emc_cfg_dig_dll << 6 >> 22 << 15) | ((sdram->emc_cfg_dig_dll << 16 >> 31 << 14) | ((sdram->emc_cfg_dig_dll << 17 >> 31 << 13) | ((sdram->emc_cfg_dig_dll << 18 >> 30 << 11) | ((sdram->emc_cfg_dig_dll << 21 >> 29 << 8) | ((sdram->emc_cfg_dig_dll << 24 >> 30 << 6) | (32 * (sdram->emc_cfg_dig_dll << 26 >> 31) | (16 * (sdram->emc_cfg_dig_dll << 27 >> 31) | (8 * (sdram->emc_cfg_dig_dll << 28 >> 31) | (4 * (sdram->emc_cfg_dig_dll << 29 >> 31) | (2 * (sdram->emc_cfg_dig_dll << 30 >> 31) | (sdram->emc_cfg_dig_dll & 1 | 2 * (pmc->scratch68 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFF3F) & 0xFFFFF8FF) & 0xFFFFE7FF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFE007FFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF;
- pmc->scratch69 = (sdram->emc_r2r << 28) | ((sdram->emc_fdpd_ctrl_dq >> 30 << 26) | ((8 * sdram->emc_fdpd_ctrl_dq >> 27 << 21) | ((sdram->emc_fdpd_ctrl_dq << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_dq << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_dq << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_dq | (pmc->scratch69 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xF3FFFFFF) & 0xFFFFFFF;
- pmc->scratch70 = (sdram->emc_w2w << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_0 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ib_vref_dq_0 & 0x7F | (pmc->scratch70 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF;
- pmc->scratch71 = (sdram->emc_pmacro_vttgen_ctrl0 << 12 >> 28 << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_1 << 17 >> 25 << 7) | ((pmc->scratch71 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dq_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF;
- pmc->scratch72 = (((sdram->emc_pmacro_ib_vref_dqs_0 << 17 >> 25 << 7) | ((pmc->scratch72 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_0 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF | (sdram->emc_pmacro_ib_vref_dqs_0 << 9 >> 25 << 14)) & 0xF01FFFFF | (2 * sdram->emc_pmacro_ib_vref_dqs_0 >> 25 << 21);
- pmc->scratch73 = (2 * sdram->emc_pmacro_ib_vref_dqs_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 17 >> 25 << 7) | ((pmc->scratch73 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF;
- pmc->scratch74 = (2 * sdram->emc_pmacro_ddll_short_cmd_0 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_0 & 0x7F | (pmc->scratch74 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF;
- pmc->scratch75 = (2 * sdram->emc_pmacro_ddll_short_cmd_1 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_1 & 0x7F | (pmc->scratch75 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF;
- pmc->scratch76 = (sdram->emc_rp << 26) | ((4 * sdram->emc_dll_cfg0 >> 31 << 25) | ((8 * sdram->emc_dll_cfg0 >> 31 << 24) | ((16 * sdram->emc_dll_cfg0 >> 28 << 20) | ((sdram->emc_dll_cfg0 << 8 >> 28 << 16) | ((sdram->emc_dll_cfg0 << 12 >> 28 << 12) | ((sdram->emc_dll_cfg0 << 16 >> 28 << 8) | ((sdram->emc_dll_cfg0 << 20 >> 24) | (pmc->scratch76 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFF0FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF;
- tmp = (sdram->emc_pmacro_tx_pwrd0 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd0 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd0 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd0 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd0 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd0 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd0 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd0 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd0 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd0 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd0 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd0 & 1 | 2 * (pmc->scratch77 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF;
- pmc->scratch77 = (sdram->emc_r2w << 26) | ((4 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd0 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd0 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd0 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd0 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd0 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd0 << 11 >> 31 << 17) | tmp & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF;
- tmp = ((8 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd1 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd1 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd1 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd1 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd1 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd1 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd1 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd1 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd1 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd1 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd1 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd1 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd1 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd1 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd1 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd1 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd1 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd1 & 1 | 2 * (pmc->scratch78 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF;
- pmc->scratch78 = (sdram->emc_w2r << 26) | ((4 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 25) | tmp) & 0x3FFFFFF;
- tmp = ((8 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd2 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd2 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd2 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd2 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd2 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd2 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd2 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd2 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd2 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd2 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd2 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd2 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd2 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd2 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd2 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd2 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd2 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd2 & 1 | 2 * (pmc->scratch79 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF;
- pmc->scratch79 = (sdram->emc_r2p << 26) | ((4 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 25) | tmp) & 0x3FFFFFF;
- tmp = (sdram->emc_pmacro_tx_pwrd3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd3 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd3 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd3 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd3 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd3 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd3 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd3 & 1 | 2 * (pmc->scratch80 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF;
- pmc->scratch80 = ((u8)(sdram->emc_ccdmw) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd3 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd3 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd3 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd3 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd3 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd3 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd3 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd3 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd3 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd3 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd3 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd3 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd3 << 22 >> 31 << 9) | tmp & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF;
- tmp = ((8 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd4 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd4 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd4 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd4 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd4 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd4 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd4 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd4 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd4 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd4 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd4 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd4 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd4 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd4 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd4 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd4 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd4 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd4 & 1 | 2 * (pmc->scratch81 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF;
- pmc->scratch81 = ((u8)(sdram->emc_rd_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 25) | tmp) & 0x3FFFFFF;
- tmp = ((8 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd5 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd5 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd5 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd5 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd5 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd5 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd5 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd5 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd5 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd5 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd5 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd5 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd5 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd5 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd5 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd5 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd5 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd5 & 1 | 2 * (pmc->scratch82 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF;
- pmc->scratch82 = ((u16)(sdram->emc_wr_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 25) | tmp) & 0x3FFFFFF;
- pmc->scratch83 = ((u8)(sdram->emc_config_sample_delay) << 25) | ((sdram->emc_auto_cal_channel >> 31 << 24) | ((2 * sdram->emc_auto_cal_channel >> 31 << 23) | ((4 * sdram->emc_auto_cal_channel >> 31 << 22) | ((16 * sdram->emc_auto_cal_channel >> 25 << 15) | ((sdram->emc_auto_cal_channel << 11 >> 27 << 10) | ((sdram->emc_auto_cal_channel << 20 >> 28 << 6) | (sdram->emc_auto_cal_channel & 0x3F | (pmc->scratch83 >> 6 << 6)) & 0xFFFFFC3F) & 0xFFFF83FF) & 0xFFC07FFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0x1FFFFFF;
- pmc->scratch84 = (sdram->emc_sel_dpd_ctrl << 13 >> 29 << 29) | ((sdram->emc_sel_dpd_ctrl << 23 >> 31 << 28) | ((sdram->emc_sel_dpd_ctrl << 26 >> 31 << 27) | ((sdram->emc_sel_dpd_ctrl << 27 >> 31 << 26) | ((sdram->emc_sel_dpd_ctrl << 28 >> 31 << 25) | ((sdram->emc_sel_dpd_ctrl << 29 >> 31 << 24) | ((4 * sdram->emc_pmacro_rx_term >> 26 << 18) | ((sdram->emc_pmacro_rx_term << 10 >> 26 << 12) | ((sdram->emc_pmacro_rx_term << 18 >> 26 << 6) | (sdram->emc_pmacro_rx_term & 0x3F | (pmc->scratch84 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF;
- pmc->scratch85 = (4 * sdram->emc_obdly >> 30 << 30) | (4 * ((sdram->emc_obdly << 24) | ((4 * sdram->emc_pmacro_dq_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_dq_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_dq_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_dq_tx_drive & 0x3F | (pmc->scratch85 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2);
- pmc->scratch86 = (sdram->emc_pmacro_vttgen_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_vttgen_ctrl1 << 16 >> 26 << 24) | ((4 * sdram->emc_pmacro_ca_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_ca_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_ca_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_ca_tx_drive & 0x3F | (pmc->scratch86 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2);
- pmc->scratch87 = (sdram->emc_pmacro_vttgen_ctrl2 >> 16 << 24) | ((16 * sdram->emc_pmacro_zcrtl >> 30 << 22) | ((sdram->emc_pmacro_zcrtl << 6 >> 30 << 20) | ((sdram->emc_pmacro_zcrtl << 8 >> 30 << 18) | ((sdram->emc_pmacro_zcrtl << 10 >> 30 << 16) | ((sdram->emc_pmacro_zcrtl << 12 >> 30 << 14) | ((sdram->emc_pmacro_zcrtl << 14 >> 30 << 12) | ((sdram->emc_pmacro_zcrtl << 16 >> 30 << 10) | ((sdram->emc_pmacro_zcrtl << 18 >> 30 << 8) | ((sdram->emc_pmacro_zcrtl << 20 >> 30 << 6) | (16 * (sdram->emc_pmacro_zcrtl << 22 >> 30) | (4 * (sdram->emc_pmacro_zcrtl << 24 >> 30) | ((sdram->emc_pmacro_zcrtl << 26 >> 30) | 4 * (pmc->scratch87 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFFFFFF;
- pmc->scratch88 = (sdram->mc_emem_arb_timing_rc << 24) | ((sdram->emc_zcal_interval << 14) | ((sdram->emc_zcal_interval << 8 >> 18) | (pmc->scratch88 >> 14 << 14)) & 0xFF003FFF) & 0xFFFFFF;
- pmc->scratch89 = ((u16)(sdram->mc_emem_arb_rsv) << 24) | ((sdram->emc_data_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft0 << 26 >> 29) | (sdram->emc_data_brlshft0 & 7 | 8 * (pmc->scratch89 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0xFFFFFF;
- pmc->scratch90 = (sdram->emc_data_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft1 << 26 >> 29) | (sdram->emc_data_brlshft1 & 7 | 8 * (pmc->scratch90 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF;
- pmc->scratch91 = (sdram->emc_dqs_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft0 << 26 >> 29) | (sdram->emc_dqs_brlshft0 & 7 | 8 * (pmc->scratch91 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF;
- pmc->scratch92 = (sdram->emc_dqs_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft1 << 26 >> 29) | (sdram->emc_dqs_brlshft1 & 7 | 8 * (pmc->scratch92 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF;
- pmc->scratch93 = (2 * sdram->emc_swizzle_rank0_byte0 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte0 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte0 & 7 | 8 * (pmc->scratch93 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF;
- pmc->scratch94 = ((u8)(sdram->emc_cfg) << 27 >> 31 << 31) | (2 * ((sdram->emc_ras << 24) | ((2 * sdram->emc_swizzle_rank0_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte1 & 7 | 8 * (pmc->scratch94 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch95 = ((u8)(sdram->emc_cfg) << 26 >> 31 << 31) | (2 * ((sdram->emc_w2p << 24) | ((2 * sdram->emc_swizzle_rank0_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte2 & 7 | 8 * (pmc->scratch95 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch96 = ((u8)(sdram->emc_cfg) << 25 >> 31 << 31) | (2 * ((sdram->emc_qsafe << 24) | ((2 * sdram->emc_swizzle_rank0_byte3 >> 29 << 21) | (((sdram->emc_swizzle_rank0_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte3 & 7 | 8 * (pmc->scratch96 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank0_byte3 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch97 = ((u8)(sdram->emc_cfg) << 24 >> 31 << 31) | (2 * ((sdram->emc_rdv << 24) | ((2 * sdram->emc_swizzle_rank1_byte0 >> 29 << 21) | (((sdram->emc_swizzle_rank1_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte0 & 7 | 8 * (pmc->scratch97 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank1_byte0 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch98 = ((u16)(sdram->emc_cfg) << 23 >> 31 << 31) | (2 * (((u16)(sdram->emc_rw2pden) << 24) | ((2 * sdram->emc_swizzle_rank1_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte1 & 7 | 8 * (pmc->scratch98 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch99 = ((u16)(sdram->emc_cfg) << 22 >> 31 << 31) | (2 * ((sdram->emc_tfaw << 24) | ((2 * sdram->emc_swizzle_rank1_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte2 & 7 | 8 * (pmc->scratch99 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch100 = (sdram->emc_cfg << 13 >> 31 << 31) | (2 * ((sdram->emc_tclkstable << 24) | ((2 * sdram->emc_swizzle_rank1_byte3 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte3 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte3 & 7 | 8 * (pmc->scratch100 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1);
- tmp = 2 * (((u8)(sdram->emc_trtm) << 24) | ((16 * sdram->emc_cfg_pipe2 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe2 >> 31 << 22) | ((sdram->emc_cfg_pipe2 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe2 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe2 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe2 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe2 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe2 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe2 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe2 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe2 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe2 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe2 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe2 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe2 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe2 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe2 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe2 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe2 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe2 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe2 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe2 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe2 << 30 >> 31) | (sdram->emc_cfg_pipe2 & 1 | 2 * (pmc->scratch101 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1;
- pmc->scratch101 = (sdram->emc_cfg << 10 >> 31 << 31) | tmp;
- tmp = (2 * (pmc->scratch102 >> 1) | sdram->emc_cfg_pipe1 & 1) & 0xFFFFFFFD;
- pmc->scratch102 = (sdram->emc_cfg << 9 >> 31 << 31) | (2 * (((u8)(sdram->emc_twtm) << 24) | ((16 * sdram->emc_cfg_pipe1 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe1 >> 31 << 22) | ((sdram->emc_cfg_pipe1 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe1 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe1 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe1 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe1 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe1 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe1 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe1 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe1 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe1 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe1 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe1 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe1 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe1 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe1 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe1 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe1 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe1 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe1 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe1 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe1 << 30 >> 31) | tmp) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1);
- tmp = 2 * (((u8)(sdram->emc_tratm) << 24) | ((sdram->emc_pmacro_ddll_pwrd0 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd0 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd0 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd0 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd0 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd0 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd0 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd0 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd0 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd0 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd0 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd0 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd0 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd0 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd0 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd0 << 30 >> 31) | 2 * (pmc->scratch103 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1;
- pmc->scratch103 = (sdram->emc_cfg << 8 >> 31 << 31) | tmp;
- tmp = 2 * (((u8)(sdram->emc_twatm) << 24) | ((sdram->emc_pmacro_ddll_pwrd1 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd1 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd1 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd1 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd1 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd1 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd1 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd1 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd1 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd1 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd1 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd1 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd1 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd1 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd1 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd1 << 30 >> 31) | 2 * (pmc->scratch104 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1;
- pmc->scratch104 = (sdram->emc_cfg << 7 >> 31 << 31) | tmp;
- tmp = (sdram->emc_pmacro_ddll_pwrd2 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd2 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd2 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd2 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd2 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd2 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd2 << 30 >> 31) | 2 * (pmc->scratch105 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF;
- pmc->scratch105 = (sdram->emc_cfg << 6 >> 31 << 31) | (2 * (((u8)(sdram->emc_tr2ref) << 24) | ((sdram->emc_pmacro_ddll_pwrd2 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd2 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd2 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd2 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd2 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd2 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd2 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd2 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd2 << 21 >> 31 << 7) | tmp & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch106 = (32 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_pdex2mrr) << 24) | ((8 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 23) | ((16 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 21) | ((sdram->emc_pmacro_ddll_periodic_offset << 6 >> 31 << 20) | ((sdram->emc_pmacro_ddll_periodic_offset << 7 >> 31 << 19) | ((sdram->emc_pmacro_ddll_periodic_offset << 8 >> 31 << 18) | ((sdram->emc_pmacro_ddll_periodic_offset << 9 >> 31 << 17) | ((sdram->emc_pmacro_ddll_periodic_offset << 10 >> 31 << 16) | ((sdram->emc_pmacro_ddll_periodic_offset << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_periodic_offset << 15 >> 31 << 14) | ((sdram->emc_pmacro_ddll_periodic_offset << 16 >> 31 << 13) | ((sdram->emc_pmacro_ddll_periodic_offset << 17 >> 31 << 12) | ((sdram->emc_pmacro_ddll_periodic_offset << 18 >> 31 << 11) | ((sdram->emc_pmacro_ddll_periodic_offset << 19 >> 31 << 10) | ((sdram->emc_pmacro_ddll_periodic_offset << 20 >> 31 << 9) | ((sdram->emc_pmacro_ddll_periodic_offset << 21 >> 31 << 8) | ((sdram->emc_pmacro_ddll_periodic_offset << 22 >> 31 << 7) | ((sdram->emc_pmacro_ddll_periodic_offset << 23 >> 31 << 6) | (sdram->emc_pmacro_ddll_periodic_offset & 0x3F | (pmc->scratch106 >> 6 << 6)) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch107 = (8 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_clken_override << 15 >> 31 << 30) | ((sdram->emc_clken_override << 23 >> 31 << 29) | ((sdram->emc_clken_override << 24 >> 31 << 28) | ((sdram->emc_clken_override << 25 >> 31 << 27) | ((sdram->emc_clken_override << 28 >> 31 << 26) | ((sdram->emc_clken_override << 29 >> 31 << 25) | ((sdram->emc_clken_override << 30 >> 31 << 24) | ((sdram->mc_emem_arb_da_covers << 8 >> 24 << 16) | ((sdram->mc_emem_arb_da_covers << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_covers & 0xFF | (pmc->scratch107 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch108 = (sdram->emc_rfc_pb << 23) | ((sdram->emc_xm2_comp_pad_ctrl >> 24 << 15) | ((sdram->emc_xm2_comp_pad_ctrl << 12 >> 24 << 7) | ((sdram->emc_xm2_comp_pad_ctrl << 20 >> 31 << 6) | (32 * (sdram->emc_xm2_comp_pad_ctrl << 22 >> 31) | (4 * (sdram->emc_xm2_comp_pad_ctrl << 25 >> 29) | (sdram->emc_xm2_comp_pad_ctrl & 3 | 4 * (pmc->scratch108 >> 2)) & 0xFFFFFFE3) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFF807F) & 0xFF807FFF) & 0x7FFFFF;
- pmc->scratch109 = (sdram->emc_cfg_update >> 31 << 31) | (2 * ((2 * sdram->emc_cfg_update >> 31 << 30) | ((4 * sdram->emc_cfg_update >> 31 << 29) | ((8 * sdram->emc_cfg_update >> 31 << 28) | ((sdram->emc_cfg_update << 21 >> 30 << 26) | ((sdram->emc_cfg_update << 23 >> 31 << 25) | ((sdram->emc_cfg_update << 29 >> 30 << 23) | ((sdram->emc_cfg_update << 22) & 0x7FFFFF | ((sdram->emc_auto_cal_config3 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config3 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config3 << 17 >> 25 << 7) | ((pmc->scratch109 >> 7 << 7) | sdram->emc_auto_cal_config3 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFE7FFFFF) & 0xFDFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch110 = (sdram->emc_rfc << 22) | ((sdram->emc_auto_cal_config4 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config4 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config4 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config4 & 0x7F | (pmc->scratch110 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF;
- pmc->scratch111 = ((u16)(sdram->emc_txsr) << 22) | ((sdram->emc_auto_cal_config5 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config5 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config5 << 17 >> 25 << 7) | ((pmc->scratch111 >> 7 << 7) | sdram->emc_auto_cal_config5 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF;
- pmc->scratch112 = (16 * sdram->emc_mc2emc_q >> 28 << 28) | ((sdram->emc_mc2emc_q << 21 >> 29 << 25) | ((sdram->emc_mc2emc_q << 22) & 0x1FFFFFF | ((sdram->emc_auto_cal_config6 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config6 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config6 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config6 & 0x7F | (pmc->scratch112 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xFFFFFFF;
- pmc->scratch113 = (sdram->mc_emem_arb_ring1_throttle << 11 >> 27 << 27) | ((sdram->mc_emem_arb_ring1_throttle << 22) | ((sdram->emc_auto_cal_config7 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config7 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config7 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config7 & 0x7F | (pmc->scratch113 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xF83FFFFF) & 0x7FFFFFF;
- pmc->scratch114 = (sdram->emc_auto_cal_config8 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config8 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config8 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config8 & 0x7F | (pmc->scratch114 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF;
- pmc->scratch115 = (4 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_ar2pden) << 22) | ((sdram->emc_fbio_cfg7 << 10 >> 30 << 20) | ((sdram->emc_fbio_cfg7 << 12 >> 31 << 19) | ((sdram->emc_fbio_cfg7 << 13 >> 31 << 18) | ((sdram->emc_fbio_cfg7 << 14 >> 31 << 17) | ((sdram->emc_fbio_cfg7 << 15 >> 31 << 16) | ((sdram->emc_fbio_cfg7 << 16 >> 31 << 15) | ((sdram->emc_fbio_cfg7 << 17 >> 31 << 14) | ((sdram->emc_fbio_cfg7 << 18 >> 31 << 13) | ((sdram->emc_fbio_cfg7 << 19 >> 31 << 12) | ((sdram->emc_fbio_cfg7 << 20 >> 31 << 11) | ((sdram->emc_fbio_cfg7 << 21 >> 31 << 10) | ((sdram->emc_fbio_cfg7 << 22 >> 31 << 9) | ((sdram->emc_fbio_cfg7 << 23 >> 31 << 8) | ((sdram->emc_fbio_cfg7 << 24 >> 31 << 7) | ((sdram->emc_fbio_cfg7 << 25 >> 31 << 6) | (32 * (sdram->emc_fbio_cfg7 << 26 >> 31) | (16 * (sdram->emc_fbio_cfg7 << 27 >> 31) | (8 * (sdram->emc_fbio_cfg7 << 28 >> 31) | (4 * (sdram->emc_fbio_cfg7 << 29 >> 31) | (2 * (sdram->emc_fbio_cfg7 << 30 >> 31) | (sdram->emc_fbio_cfg7 & 1 | 2 * (pmc->scratch115 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFCFFFFF) & 0x803FFFFF) >> 1);
- pmc->scratch123 = (2 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_rfc_slr << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_0 & 0x7FF | (pmc->scratch123 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1);
- pmc->scratch124 = (sdram->emc_cfg >> 31 << 31) | (2 * ((4 * sdram->emc_ibdly >> 30 << 29) | ((sdram->emc_ibdly << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_1 & 0x7FF | (pmc->scratch124 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1);
- pmc->scratch125 = (sdram->emc_fbio_cfg5 << 27 >> 31 << 31) | (2 * (((u16)(sdram->mc_emem_arb_timing_rfcpb) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_2 & 0x7FF | (pmc->scratch125 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1);
- pmc->scratch126 = (sdram->emc_fbio_cfg5 << 16 >> 29 << 29) | ((sdram->emc_auto_cal_config9 << 25 >> 31 << 28) | ((sdram->emc_auto_cal_config9 << 26 >> 31 << 27) | ((sdram->emc_auto_cal_config9 << 27 >> 31 << 26) | ((sdram->emc_auto_cal_config9 << 28 >> 31 << 25) | ((sdram->emc_auto_cal_config9 << 29 >> 31 << 24) | ((sdram->emc_auto_cal_config9 << 30 >> 31 << 23) | ((sdram->emc_auto_cal_config9 << 22) & 0x7FFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_3 & 0x7FF | (pmc->scratch126 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF;
- pmc->scratch127 = ((u8)(sdram->emc_cfg2) << 26 >> 29 << 29) | ((sdram->emc_rdv_mask << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_4 & 0x7FF | (pmc->scratch127 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch128 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 27 >> 29 << 29) | (((u8)(sdram->emc_rdv_early_mask) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_5 & 0x7FF | (pmc->scratch128 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch129 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_rdv_early << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_0 & 0x7FF | (pmc->scratch129 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch130 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 17 >> 29 << 29) | ((4 * sdram->emc_quse_width >> 31 << 28) | ((8 * sdram->emc_quse_width >> 31 << 27) | ((sdram->emc_quse_width << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_1 & 0x7FF | (pmc->scratch130 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF;
- pmc->scratch131 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 12 >> 29 << 29) | (((u16)(sdram->emc_pmacro_ddll_short_cmd_2) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_2 & 0x7FF | (pmc->scratch131 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch132 = (sdram->emc_pmacro_data_pad_tx_ctrl << 27 >> 29 << 29) | ((sdram->emc_pmacro_cmd_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_cmd_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_3 & 0x7FF | (pmc->scratch132 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF;
- pmc->scratch133 = (sdram->emc_pmacro_data_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_pmacro_data_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_data_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_data_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_data_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_4 & 0x7FF | (pmc->scratch133 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF;
- pmc->scratch134 = (sdram->emc_pmacro_data_pad_tx_ctrl << 17 >> 29 << 29) | ((sdram->mc_emem_arb_timing_rp << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_5 & 0x7FF | (pmc->scratch134 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch135 = (sdram->emc_pmacro_data_pad_tx_ctrl << 12 >> 29 << 29) | ((sdram->mc_emem_arb_timing_ras << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 & 0x7FF | (pmc->scratch135 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF;
- pmc->scratch136 = (sdram->emc_fbio_cfg5 << 23 >> 31 << 31) | (2 * ((sdram->emc_cfg << 14 >> 30 << 29) | ((sdram->mc_emem_arb_timing_faw << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 & 0x7FF | (pmc->scratch136 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1);
- pmc->scratch137 = (sdram->emc_fbio_cfg5 << 21 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 29) | ((sdram->mc_emem_arb_timing_rap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 & 0x7FF | (pmc->scratch137 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1);
- pmc->scratch138 = (sdram->emc_fbio_cfg5 << 19 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 28 >> 30 << 29) | ((sdram->mc_emem_arb_timing_wap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 & 0x7FF | (pmc->scratch138 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1);
- pmc->scratch139 = (sdram->emc_fbio_cfg5 << 7 >> 31 << 31) | (2 * ((16 * sdram->emc_cfg2 >> 30 << 29) | (((u8)(sdram->mc_emem_arb_timing_r2w) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 & 0x7FF | (pmc->scratch139 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1);
- pmc->scratch140 = (16 * sdram->emc_fbio_cfg5 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg5 >> 31 << 30) | ((sdram->emc_fbio_cfg5 << 6 >> 31 << 29) | (((u8)(sdram->mc_emem_arb_timing_w2r) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 & 0x7FF | (pmc->scratch140 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch141 = (sdram->emc_fbio_cfg5 << 8 >> 28 << 28) | (((u16)(sdram->emc_wdv) << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 & 0x7FF | (pmc->scratch141 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xFFFFFFF;
- pmc->scratch142 = ((u8)(sdram->emc_cfg2) << 31) | (2 * ((sdram->emc_fbio_cfg5 >> 31 << 30) | ((2 * sdram->emc_fbio_cfg5 >> 31 << 29) | ((8 * sdram->emc_fbio_cfg5 >> 31 << 28) | ((sdram->emc_quse << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 & 0x7FF | (pmc->scratch142 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch143 = (((u16)(sdram->emc_cfg2) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg2) << 24) >> 31 << 30) | ((((u16)(sdram->emc_cfg2) << 29) >> 31 << 29) | ((((u16)(sdram->emc_cfg2) << 30) >> 31 << 28) | (((u8)(sdram->emc_pdex2wr) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 & 0x7FF | (pmc->scratch143 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch144 = (sdram->emc_cfg2 << 15 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 16 >> 31 << 30) | ((sdram->emc_cfg2 << 17 >> 31 << 29) | ((sdram->emc_cfg2 << 20 >> 31 << 28) | (((u8)(sdram->emc_pdex2rd) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 & 0x7FF | (pmc->scratch144 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch145 = (sdram->emc_cfg2 << 7 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 8 >> 31 << 30) | ((sdram->emc_cfg2 << 9 >> 31 << 29) | ((sdram->emc_cfg2 << 11 >> 31 << 28) | (((u16)(sdram->emc_pdex2che) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 & 0x7FF | (pmc->scratch145 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch146 = (2 * sdram->emc_cfg2 >> 31 << 31) | (2 * ((4 * sdram->emc_cfg2 >> 31 << 30) | (((sdram->emc_cfg2 << 6 >> 31 << 28) | (((u8)(sdram->emc_pchg2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 & 0x7FF | (pmc->scratch146 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (8 * sdram->emc_cfg2 >> 31 << 29)) & 0xBFFFFFFF) >> 1);
- pmc->scratch147 = (((u8)(sdram->emc_cfg_pipe) << 29) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 30) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 31) >> 2) | ((sdram->emc_cfg2 >> 31 << 28) | (((u16)(sdram->emc_act2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch147 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch148 = (((u8)(sdram->emc_cfg_pipe) << 25) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 26) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 27) >> 31 << 29) | ((((u8)(sdram->emc_cfg_pipe) << 28) >> 31 << 28) | (((u16)(sdram->emc_cke2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch148 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch149 = (((u16)(sdram->emc_cfg_pipe) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg_pipe) << 22) >> 31 << 30) | ((((u16)(sdram->emc_cfg_pipe) << 23) >> 31 << 29) | ((((u16)(sdram->emc_cfg_pipe) << 24) >> 31 << 28) | ((sdram->emc_tcke << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch149 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch150 = (sdram->emc_cfg_pipe << 13 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 14 >> 31 << 30) | (((sdram->emc_cfg_pipe << 20 >> 31 << 28) | ((sdram->emc_trpab << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch150 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (sdram->emc_cfg_pipe << 15 >> 31 << 29)) & 0xBFFFFFFF) >> 1);
- pmc->scratch151 = (sdram->emc_cfg_pipe << 9 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 10 >> 31 << 30) | ((sdram->emc_cfg_pipe << 11 >> 31 << 29) | ((sdram->emc_cfg_pipe << 12 >> 31 << 28) | ((sdram->emc_einput << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 & 0x7FF | (pmc->scratch151 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch152 = (32 * sdram->emc_cfg_pipe >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 6 >> 31 << 30) | ((sdram->emc_cfg_pipe << 7 >> 31 << 29) | ((sdram->emc_cfg_pipe << 8 >> 31 << 28) | ((sdram->emc_einput_duration << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 & 0x7FF | (pmc->scratch152 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch153 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 31) >> 2) | ((16 * sdram->emc_cfg_pipe >> 31 << 28) | ((sdram->emc_puterm_extra << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch153 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch154 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 26) >> 31 << 30) | (((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 28) >> 31 << 28) | ((sdram->emc_tckesr << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch154 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 27) >> 31 << 29)) & 0xBFFFFFFF) >> 1);
- pmc->scratch155 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 24) >> 31 << 28) | ((sdram->emc_tpd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch155 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch156 = (sdram->emc_pmacro_tx_sel_clk_src0 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 15 >> 31 << 28) | ((sdram->emc_wdv_mask << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch156 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch157 = (sdram->emc_pmacro_tx_sel_clk_src0 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 11 >> 31 << 28) | (((u16)(sdram->emc_wdv_chk) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 & 0x7FF | (pmc->scratch157 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch158 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src0 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 7 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft0) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft0) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 & 0x7FF | (pmc->scratch158 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch159 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 27) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 28) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 29) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 30) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft1) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft1) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch159 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch160 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 23) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 24) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 25) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 26) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft2) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft2) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch160 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch161 = (sdram->emc_pmacro_tx_sel_clk_src1 << 14 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 15 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 21 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 22 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft3) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch161 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch162 = (sdram->emc_pmacro_tx_sel_clk_src1 << 10 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 11 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 12 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 13 >> 31 << 28) | (((u16)(sdram->emc_wev) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch162 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch163 = (sdram->emc_pmacro_tx_sel_clk_src1 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 7 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 8 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 9 >> 31 << 28) | (((u16)(sdram->emc_wsv) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch163 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch164 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 31) >> 2) | ((32 * sdram->emc_pmacro_tx_sel_clk_src1 >> 31 << 28) | (((u8)(sdram->emc_cfg3) << 25 >> 29 << 25) | (((u8)(sdram->emc_cfg3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch164 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch165 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 26) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 27) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 28) >> 31 << 28) | ((sdram->emc_puterm_width << 23) & 0xFFFFFFF | ((sdram->emc_puterm_width >> 31 << 22) | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch165 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xF07FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch166 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 24) >> 31 << 28) | ((sdram->mc_emem_arb_timing_rcd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch166 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch167 = (sdram->emc_pmacro_tx_sel_clk_src3 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 15 >> 31 << 28) | (((u16)(sdram->mc_emem_arb_timing_ccdmw) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ddll_long_cmd_0 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_0 & 0x7FF | (pmc->scratch167 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch168 = (sdram->emc_pmacro_tx_sel_clk_src3 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 11 >> 31 << 28) | ((sdram->mc_emem_arb_override << 28 >> 31 << 27) | (((sdram->mc_emem_arb_override << 21 >> 31 << 25) | ((sdram->mc_emem_arb_override << 15 >> 31 << 24) | ((32 * sdram->mc_emem_arb_override >> 31 << 23) | ((16 * sdram->mc_emem_arb_override >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_1 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_1 & 0x7FF | (pmc->scratch168 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF | (sdram->mc_emem_arb_override << 27 >> 31 << 26)) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch169 = ((u16)(sdram->emc_rext) << 27) | (((u16)(sdram->emc_rrd) << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_2 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_2 & 0x7FF | (pmc->scratch169 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF;
- pmc->scratch170 = ((u16)(sdram->emc_wext) << 27) | ((sdram->emc_tclkstop << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_3 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_3 & 0x7FF | (pmc->scratch170 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF;
- tmp = (32 * sdram->emc_pmacro_perbit_fgcg_ctrl0 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl0 & 1 | 2 * (pmc->scratch171 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF;
- pmc->scratch171 = (sdram->emc_we_duration << 27) | ((sdram->emc_ref_ctrl2 >> 31 << 26) | ((32 * sdram->emc_ref_ctrl2 >> 29 << 23) | ((sdram->emc_ref_ctrl2 << 22) & 0x7FFFFF | tmp & 0xFFBFFFFF) & 0xFC7FFFFF) & 0xFBFFFFFF) & 0x7FFFFFF;
- tmp = (sdram->emc_pmacro_pad_cfg_ctrl << 22 >> 31 << 28) | ((sdram->emc_pmacro_pad_cfg_ctrl << 27) & 0xFFFFFFF | ((sdram->emc_ws_duration << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl1 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl1 & 1 | 2 * (pmc->scratch172 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF;
- pmc->scratch172 = (sdram->emc_pmacro_pad_cfg_ctrl << 14 >> 30 << 30) | (4 * ((sdram->emc_pmacro_pad_cfg_ctrl << 18 >> 31 << 29) | tmp & 0xDFFFFFFF) >> 2);
- pmc->scratch173 = ((u8)(sdram->mc_emem_arb_timing_r2r) << 27) | ((sdram->mc_emem_arb_timing_rrd << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl2 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl2 & 1 | 2 * (pmc->scratch173 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0x7FFFFFF;
- tmp = 32 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl3 & 1 | 2 * (pmc->scratch174 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF;
- pmc->scratch174 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30 >> 31 << 31) | (2 * (((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30) | ((32 * sdram->emc_pmacro_tx_sel_clk_src3 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 6 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 7 >> 31 << 27) | (((u8)(sdram->mc_emem_arb_timing_w2w) << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl3 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 25 >> 31 << 6) | tmp & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 28 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 29 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl4 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl4 & 1 | 2 * (pmc->scratch175 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF;
- pmc->scratch175 = (sdram->emc_pmacro_tx_sel_clk_src2 << 15 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 21 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 22 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 23 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 24 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 25 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 26 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 27 >> 31 << 24) | tmp & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 12 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 13 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 14 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl5 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl5 & 1 | 2 * (pmc->scratch176 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF;
- pmc->scratch176 = (32 * sdram->emc_pmacro_tx_sel_clk_src2 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 6 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 8 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 9 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 10 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 11 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch177 = (sdram->emc_pmacro_tx_sel_clk_src4 << 22 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 23 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 24 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 25 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 26 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 27 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 28 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 29 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 30 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 22) & 0x7FFFFF | ((sdram->mc_emem_arb_cfg >> 28 << 18) | ((16 * sdram->mc_emem_arb_cfg >> 28 << 14) | ((sdram->mc_emem_arb_cfg << 11 >> 27 << 9) | (sdram->mc_emem_arb_cfg & 0x1FF | (pmc->scratch177 >> 9 << 9)) & 0xFFFFC1FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch178 = (sdram->emc_pmacro_tx_sel_clk_src4 << 7 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 8 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 9 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 10 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 11 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 12 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 13 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 14 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 15 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 21 >> 31 << 22) | ((sdram->mc_emem_arb_misc1 >> 28 << 18) | ((sdram->mc_emem_arb_misc1 << 6 >> 30 << 16) | ((sdram->mc_emem_arb_misc1 << 8 >> 29 << 13) | (16 * (sdram->mc_emem_arb_misc1 << 19 >> 23) | (8 * (sdram->mc_emem_arb_misc1 << 28 >> 31) | (4 * (sdram->mc_emem_arb_misc1 << 29 >> 31) | (2 * (sdram->mc_emem_arb_misc1 << 30 >> 31) | (sdram->mc_emem_arb_misc1 & 1 | 2 * (pmc->scratch178 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFE00F) & 0xFFFF1FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch179 = (sdram->emc_odt_write >> 31 << 31) | (2 * ((sdram->emc_odt_write << 20 >> 28 << 27) | ((sdram->emc_odt_write << 26 >> 31 << 26) | ((sdram->emc_odt_write << 27 >> 31 << 25) | ((sdram->emc_odt_write << 21) & 0x1FFFFFF | ((32 * sdram->emc_mrs_wait_cnt2 >> 21 << 10) | (sdram->emc_mrs_wait_cnt2 & 0x3FF | (pmc->scratch179 >> 10 << 10)) & 0xFFE003FF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1);
- pmc->scratch180 = (sdram->emc_pmacro_ib_rxrt << 21) | ((32 * sdram->emc_mrs_wait_cnt >> 21 << 10) | (sdram->emc_mrs_wait_cnt & 0x3FF | (pmc->scratch180 >> 10 << 10)) & 0xFFE003FF) & 0x1FFFFF;
- pmc->scratch181 = ((u16)(sdram->emc_pmacro_ddll_long_cmd_4) << 21) | sdram->emc_auto_cal_interval & 0x1FFFFF;
- pmc->scratch182 = (sdram->mc_emem_arb_outstanding_req >> 31 << 31) | (2 * ((2 * sdram->mc_emem_arb_outstanding_req >> 31 << 30) | ((sdram->mc_emem_arb_outstanding_req << 23 >> 2) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 9 >> 25 << 14) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 17 >> 25 << 7) | (sdram->emc_emem_arb_refpb_hp_ctrl & 0x7F | (pmc->scratch182 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xC01FFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch183 = (4 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl0 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl0 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl0 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl0 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl0 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl0 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl0 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl0 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl0 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl0 << 20) & 0x1FFFFF | ((4 * sdram->emc_xm2_comp_pad_ctrl2 >> 26 << 14) | ((sdram->emc_xm2_comp_pad_ctrl2 << 10 >> 30 << 12) | ((sdram->emc_xm2_comp_pad_ctrl2 << 14 >> 31 << 11) | ((sdram->emc_xm2_comp_pad_ctrl2 << 15 >> 31 << 10) | ((sdram->emc_xm2_comp_pad_ctrl2 << 16 >> 30 << 8) | ((sdram->emc_xm2_comp_pad_ctrl2 << 18 >> 30 << 6) | (4 * (sdram->emc_xm2_comp_pad_ctrl2 << 26 >> 28) | (sdram->emc_xm2_comp_pad_ctrl2 & 3 | 4 * (pmc->scratch183 >> 2)) & 0xFFFFFFC3) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFF03FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch184 = (4 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl1 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl1 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl1 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl1 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl1 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl1 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl1 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl1 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl1 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl1 << 20) & 0x1FFFFF | ((sdram->emc_cfg_dig_dll_1 << 12 >> 28 << 16) | ((sdram->emc_cfg_dig_dll_1 << 16 >> 28 << 12) | ((sdram->emc_cfg_dig_dll_1 << 20 >> 26 << 6) | (2 * (sdram->emc_cfg_dig_dll_1 << 26 >> 27) | (sdram->emc_cfg_dig_dll_1 & 1 | 2 * (pmc->scratch184 >> 1)) & 0xFFFFFFC1) & 0xFFFFF03F) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch185 = (4 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl2 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl2 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl2 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl2 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl2 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl2 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl2 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl2 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl2 << 20) & 0x1FFFFF | ((sdram->emc_quse_brlshft0 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft0 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft0 << 22 >> 27) | (sdram->emc_quse_brlshft0 & 0x1F | 32 * (pmc->scratch185 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch186 = (sdram->emc_pmacro_dsr_vttgen_ctrl0 >> 8 << 24) | ((sdram->emc_pmacro_dsr_vttgen_ctrl0 << 20) | ((sdram->emc_quse_brlshft1 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft1 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft1 << 22 >> 27) | (sdram->emc_quse_brlshft1 & 0x1F | 32 * (pmc->scratch186 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFF0FFFFF) & 0xFFFFFF;
- pmc->scratch187 = (sdram->emc_pmacro_perbit_rfu1_ctrl0 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft2 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft2 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft2 << 22 >> 27) | (sdram->emc_quse_brlshft2 & 0x1F | 32 * (pmc->scratch187 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch188 = (sdram->emc_pmacro_perbit_rfu1_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft3 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft3 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft3 << 22 >> 27) | (sdram->emc_quse_brlshft3 & 0x1F | 32 * (pmc->scratch188 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2);
- pmc->scratch189 = (sdram->emc_trefbw << 18) | ((sdram->emc_dbg >> 31 << 17) | ((2 * sdram->emc_dbg >> 31 << 16) | ((4 * sdram->emc_dbg >> 31 << 15) | ((8 * sdram->emc_dbg >> 31 << 14) | ((16 * sdram->emc_dbg >> 30 << 12) | ((sdram->emc_dbg << 6 >> 31 << 11) | ((sdram->emc_dbg << 7 >> 31 << 10) | ((sdram->emc_dbg << 18 >> 31 << 9) | ((sdram->emc_dbg << 19 >> 31 << 8) | ((sdram->emc_dbg << 20 >> 31 << 7) | ((sdram->emc_dbg << 21 >> 31 << 6) | (32 * (sdram->emc_dbg << 22 >> 31) | (16 * (sdram->emc_dbg << 27 >> 31) | (8 * (sdram->emc_dbg << 28 >> 31) | (4 * (sdram->emc_dbg << 29 >> 31) | (2 * (sdram->emc_dbg << 30 >> 31) | (sdram->emc_dbg & 1 | 2 * (pmc->scratch189 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0x3FFFF;
- pmc->scratch191 = (sdram->emc_qpop << 9 >> 25 << 25) | ((sdram->emc_qpop << 18) | ((sdram->emc_zcal_wait_cnt >> 31 << 17) | ((sdram->emc_zcal_wait_cnt << 10 >> 26 << 11) | (sdram->emc_zcal_wait_cnt & 0x7FF | (pmc->scratch191 >> 11 << 11)) & 0xFFFE07FF) & 0xFFFDFFFF) & 0xFE03FFFF) & 0x1FFFFFF;
- pmc->scratch192 = (sdram->emc_pmacro_tx_sel_clk_src4 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_auto_cal_common << 15 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_common << 18 >> 26 << 24) | ((sdram->emc_pmacro_auto_cal_common << 18) & 0xFFFFFF | ((sdram->emc_zcal_mrw_cmd >> 30 << 16) | ((sdram->emc_zcal_mrw_cmd << 8 >> 24 << 8) | (sdram->emc_zcal_mrw_cmd & 0xFF | (pmc->scratch192 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFCFFFF) & 0xFF03FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1);
- tmp = (sdram->emc_dll_cfg1 << 7 >> 31 << 17) | ((sdram->emc_dll_cfg1 << 10 >> 31 << 16) | ((sdram->emc_dll_cfg1 << 11 >> 31 << 15) | ((sdram->emc_dll_cfg1 << 14 >> 30 << 13) | ((sdram->emc_dll_cfg1 << 18 >> 31 << 12) | ((sdram->emc_dll_cfg1 << 19 >> 31 << 11) | ((pmc->scratch193 >> 11 << 11) | sdram->emc_dll_cfg1 & 0x7FF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFF9FFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF;
- pmc->scratch193 = (sdram->emc_pmacro_tx_sel_clk_src5 << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src4 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 18) & 0xFFFFF | tmp & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl2 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch194 = (sdram->emc_pmacro_tx_sel_clk_src5 << 29 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 30 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 14 >> 30 << 24) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 18) & 0xFFFFF | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_cmd_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch194 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 26 >> 30 << 22)) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch195 = (sdram->emc_pmacro_tx_sel_clk_src5 << 27 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 28 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 18) & 0xFFFFF | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_data_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch195 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl4 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch196 = (sdram->emc_emem_arb_refpb_bank_ctrl >> 31 << 31) | (2 * ((sdram->emc_emem_arb_refpb_bank_ctrl << 17 >> 25 << 24) | ((sdram->emc_emem_arb_refpb_bank_ctrl << 17) & 0xFFFFFF | ((sdram->emc_dyn_self_ref_control >> 31 << 16) | (sdram->emc_dyn_self_ref_control & 0xFFFF | (pmc->scratch196 >> 16 << 16)) & 0xFFFEFFFF) & 0xFF01FFFF) & 0x80FFFFFF) >> 1);
- pmc->scratch197 = (sdram->emc_pmacro_tx_sel_clk_src5 << 24 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 25 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 26 >> 31 << 29) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 10 >> 30 << 27) | (((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 14 >> 30 << 23) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 26 >> 30 << 21) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 28 >> 30 << 19) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 17) & 0x7FFFF | ((16 * sdram->emc_pmacro_cmd_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_cmd_pad_rx_ctrl & 3 | 4 * (pmc->scratch197 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFF9FFFF) & 0xFFE7FFFF) & 0xFF9FFFFF) & 0xFE7FFFFF) & 0xF9FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl5 << 12 >> 30 << 25)) & 0xE7FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch198 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src5 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 7 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 8 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 9 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 10 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 11 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 12 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 13 >> 31 << 22) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 14 >> 31 << 21) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 15 >> 31 << 20) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 21 >> 31 << 19) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 22 >> 31 << 18) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 23 >> 31 << 17) | ((16 * sdram->emc_pmacro_data_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_data_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_data_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_data_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_data_pad_rx_ctrl & 3 | 4 * (pmc->scratch198 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch199 = (8 * sdram->emc_cmd_q >> 27 << 27) | ((sdram->emc_cmd_q << 17 >> 29 << 24) | ((sdram->emc_cmd_q << 21 >> 29 << 21) | ((sdram->emc_cmd_q << 16) & 0x1FFFFF | (((u16)(sdram->emc_refresh) << 16 >> 22 << 6) | (sdram->emc_refresh & 0x3F | (pmc->scratch199 >> 6 << 6)) & 0xFFFF003F) & 0xFFE0FFFF) & 0xFF1FFFFF) & 0xF8FFFFFF) & 0x7FFFFFF;
- pmc->scratch210 = (sdram->emc_auto_cal_vref_sel1 << 16 >> 31 << 31) | (2 * ((sdram->emc_auto_cal_vref_sel1 << 17 >> 25 << 24) | ((sdram->emc_auto_cal_vref_sel1 << 24 >> 31 << 23) | ((sdram->emc_auto_cal_vref_sel1 << 16) & 0x7FFFFF | (sdram->emc_acpd_control & 0xFFFF | (pmc->scratch210 >> 16 << 16)) & 0xFF80FFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1);
- tmp = 8 * (sdram->emc_pmacro_auto_cal_cfg0 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg0 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg0 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg0 & 1 | 2 * (pmc->scratch211 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7;
- tmp = (sdram->emc_pmacro_auto_cal_cfg1 << 7 >> 31 << 28) | ((sdram->emc_pmacro_auto_cal_cfg1 << 12 >> 31 << 27) | ((sdram->emc_pmacro_auto_cal_cfg1 << 13 >> 31 << 26) | ((sdram->emc_pmacro_auto_cal_cfg1 << 14 >> 31 << 25) | ((sdram->emc_pmacro_auto_cal_cfg1 << 15 >> 31 << 24) | ((sdram->emc_pmacro_auto_cal_cfg1 << 20 >> 31 << 23) | ((sdram->emc_pmacro_auto_cal_cfg1 << 21 >> 31 << 22) | ((sdram->emc_pmacro_auto_cal_cfg1 << 22 >> 31 << 21) | ((sdram->emc_pmacro_auto_cal_cfg1 << 23 >> 31 << 20) | ((sdram->emc_pmacro_auto_cal_cfg1 << 28 >> 31 << 19) | ((sdram->emc_pmacro_auto_cal_cfg1 << 29 >> 31 << 18) | ((sdram->emc_pmacro_auto_cal_cfg1 << 30 >> 31 << 17) | ((sdram->emc_pmacro_auto_cal_cfg1 << 16) & 0x1FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg0 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg0 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg0 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg0 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg0 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg0 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg0 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg0 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg0 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg0 << 23 >> 31) | tmp & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF;
- pmc->scratch211 = (16 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 31) | (2 * ((32 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_cfg1 << 6 >> 31 << 29) | tmp & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->scratch212 = (sdram->emc_xm2_comp_pad_ctrl3 << 8 >> 28 << 28) | ((sdram->emc_xm2_comp_pad_ctrl3 << 14 >> 31 << 27) | ((sdram->emc_xm2_comp_pad_ctrl3 << 15 >> 31 << 26) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16 >> 30 << 24) | ((sdram->emc_xm2_comp_pad_ctrl3 << 18 >> 30 << 22) | ((sdram->emc_xm2_comp_pad_ctrl3 << 26 >> 28 << 18) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16) & 0x3FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg2 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg2 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg2 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg2 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg2 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg2 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg2 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg2 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg2 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg2 << 23 >> 31) | (8 * (sdram->emc_pmacro_auto_cal_cfg2 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg2 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg2 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg2 & 1 | 2 * (pmc->scratch212 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF;
- pmc->scratch213 = ((u16)(sdram->emc_prerefresh_req_cnt) << 16) | (u16)(sdram->emc_cfg_dig_dll_period);
- pmc->scratch214 = (sdram->emc_pmacro_data_pi_ctrl << 10 >> 26 << 26) | ((sdram->emc_pmacro_data_pi_ctrl << 19 >> 31 << 25) | ((sdram->emc_pmacro_data_pi_ctrl << 20 >> 28 << 21) | ((sdram->emc_pmacro_data_pi_ctrl << 27 >> 31 << 20) | ((sdram->emc_pmacro_data_pi_ctrl << 16) & 0xFFFFF | ((sdram->emc_pmacro_ddll_bypass >> 31 << 15) | ((2 * sdram->emc_pmacro_ddll_bypass >> 31 << 14) | ((4 * sdram->emc_pmacro_ddll_bypass >> 31 << 13) | ((16 * sdram->emc_pmacro_ddll_bypass >> 31 << 12) | ((32 * sdram->emc_pmacro_ddll_bypass >> 31 << 11) | ((sdram->emc_pmacro_ddll_bypass << 6 >> 31 << 10) | ((sdram->emc_pmacro_ddll_bypass << 7 >> 31 << 9) | ((sdram->emc_pmacro_ddll_bypass << 15 >> 31 << 8) | ((sdram->emc_pmacro_ddll_bypass << 16 >> 31 << 7) | ((sdram->emc_pmacro_ddll_bypass << 17 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_bypass << 18 >> 31) | (16 * (sdram->emc_pmacro_ddll_bypass << 20 >> 31) | (8 * (sdram->emc_pmacro_ddll_bypass << 21 >> 31) | (4 * (sdram->emc_pmacro_ddll_bypass << 22 >> 31) | (2 * (sdram->emc_pmacro_ddll_bypass << 23 >> 31) | (sdram->emc_pmacro_ddll_bypass & 1 | 2 * (pmc->scratch214 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0x3FFFFFF;
- pmc->scratch215 = (sdram->emc_pmacro_cmd_pi_ctrl << 10 >> 26 << 10) | ((sdram->emc_pmacro_cmd_pi_ctrl << 19 >> 31 << 9) | (32 * (sdram->emc_pmacro_cmd_pi_ctrl << 20 >> 28) | (16 * (sdram->emc_pmacro_cmd_pi_ctrl << 27 >> 31) | (sdram->emc_pmacro_cmd_pi_ctrl & 0xF | 16 * (pmc->scratch215 >> 4)) & 0xFFFFFFEF) & 0xFFFFFE1F) & 0xFFFFFDFF) & 0xFFFF03FF;
- tmp = (sdram->emc_pmacro_data_pad_tx_ctrl << 7 >> 31 << 24) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 8 >> 31 << 23) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 9 >> 31 << 22) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 10 >> 31 << 21) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15 >> 31 << 20) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 16 >> 31 << 19) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 21 >> 31 << 18) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 25 >> 31 << 17) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 26 >> 31 << 16) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15) & 0xFFFF | ((2 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 14) | ((4 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 13) | ((8 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 12) | ((16 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 11) | ((32 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 6 >> 31 << 9) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 7 >> 31 << 8) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 8 >> 31 << 7) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 9 >> 31 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 10 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 15 >> 31) | (8 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 16 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 21 >> 31) | (2 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 25 >> 31) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 26 >> 31) | 2 * (pmc->scratch216 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF;
-
- s(emc_pin_gpio, 1:0, scratch9, 31:30);
- s(emc_pin_gpio_enable, 1:0, scratch10, 31:30);
- s(emc_dev_select, 1:0, scratch11, 31:30);
- s(emc_zcal_warm_cold_boot_enables, 1:0, scratch12, 31:30);
- s(emc_cfg_dig_dll_period_warm_boot, 1:0, scratch13, 31:30);
- s32(emc_bct_spare13, scratch45);
- s32(emc_bct_spare12, scratch46);
- s32(emc_bct_spare7, scratch47);
- s32(emc_bct_spare6, scratch48);
- s32(emc_bct_spare5, scratch50);
- s32(emc_bct_spare4, scratch51);
- s32(emc_bct_spare3, scratch56);
- s32(emc_bct_spare2, scratch57);
- s32(emc_bct_spare1, scratch58);
- s32(emc_bct_spare0, scratch59);
- s32(emc_bct_spare9, scratch60);
- s32(emc_bct_spare8, scratch61);
- s32(boot_rom_patch_data, scratch62);
- s32(boot_rom_patch_control, scratch63);
- s(mc_clken_override_allwarm_boot, 0:0, scratch65, 31:31);
- pmc->scratch66 = pmc->scratch66 & 0x1FFFFFFF | ((u8)(sdram->emc_extra_refresh_num) << 29);
- pmc->scratch72 = pmc->scratch72 & 0x8FFFFFFF | ((u16)(sdram->pmc_io_dpd3_req_wait) << 28) & 0x70000000;
- pmc->scratch72 = ((2 * pmc->scratch72) >> 1) | ((u16)(sdram->emc_clken_override_allwarm_boot) << 31);
- pmc->scratch73 = pmc->scratch73 & 0x8FFFFFFF | ((u8)(sdram->memory_type) << 28) & 0x70000000;
- pmc->scratch73 = ((2 * pmc->scratch73) >> 1) | (sdram->emc_mrs_warm_boot_enable << 31);
- pmc->scratch74 = pmc->scratch74 & 0x8FFFFFFF | (sdram->pmc_io_dpd4_req_wait << 28) & 0x70000000;
- pmc->scratch74 = ((2 * pmc->scratch74) >> 1) | (sdram->clear_clock2_mc1 << 31);
- pmc->scratch75 = pmc->scratch75 & 0xEFFFFFFF | (sdram->emc_warm_boot_extramode_reg_write_enable << 28) & 0x10000000;
- pmc->scratch75 = pmc->scratch75 & 0xDFFFFFFF | (sdram->clk_rst_pllm_misc20_override_enable << 29) & 0x20000000;
- pmc->scratch75 = pmc->scratch75 & 0xBFFFFFFF | ((u16)(sdram->emc_dbg_write_mux) << 30) & 0x40000000;
- pmc->scratch75 = ((2 * pmc->scratch75) >> 1) | ((u16)(sdram->ahb_arbitration_xbar_ctrl_meminit_done) << 31);
- pmc->scratch90 = pmc->scratch90 & 0xFFFFFF | (sdram->emc_timing_control_wait << 24);
- pmc->scratch91 = pmc->scratch91 & 0xFFFFFF | (sdram->emc_zcal_warm_boot_wait << 24);
- pmc->scratch92 = pmc->scratch92 & 0xFFFFFF | (sdram->warm_boot_wait << 24);
- pmc->scratch93 = pmc->scratch93 & 0xFFFFFF | ((u16)(sdram->emc_pin_program_wait) << 24);
- pmc->scratch114 = pmc->scratch114 & 0x3FFFFF | ((u16)(sdram->emc_auto_cal_wait) << 22);
- pmc->scratch215 = (u16)pmc->scratch215 | ((u16)(sdram->swizzle_rank_byte_encode) << 16);
- pmc->scratch216 = (2 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 30) | ((4 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 29) | ((8 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 28) | ((16 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 27) | ((32 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 26) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 6 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF;
- s(emc_mrw_lpddr2zcal_warm_boot, 23:16, scratch5, 7:0);
- s(emc_mrw_lpddr2zcal_warm_boot, 7:0, scratch5, 15:8);
- s(emc_warm_boot_mrw_extra, 23:16, scratch5, 23:16);
- s(emc_warm_boot_mrw_extra, 7:0, scratch5, 31:24);
- s(emc_mrw_lpddr2zcal_warm_boot, 31:30, scratch6, 1:0);
- s(emc_warm_boot_mrw_extra, 31:30, scratch6, 3:2);
- s(emc_mrw_lpddr2zcal_warm_boot, 27:26, scratch6, 5:4);
- s(emc_warm_boot_mrw_extra, 27:26, scratch6, 7:6);
- s(EmcMrw6, 27:0, scratch8, 27:0);
- s(EmcMrw6, 31:30, scratch8, 29:28);
- s(EmcMrw8, 27:0, scratch9, 27:0);
- s(EmcMrw8, 31:30, scratch9, 29:28);
- s(EmcMrw9, 27:0, scratch10, 27:0);
- s(EmcMrw9, 31:30, scratch10, 29:28);
- s(EmcMrw10, 27:0, scratch11, 27:0);
- s(EmcMrw10, 31:30, scratch11, 29:28);
- s(EmcMrw12, 27:0, scratch12, 27:0);
- s(EmcMrw12, 31:30, scratch12, 29:28);
- s(EmcMrw13, 27:0, scratch13, 27:0);
- s(EmcMrw13, 31:30, scratch13, 29:28);
- s(EmcMrw14, 27:0, scratch14, 27:0);
- s(EmcMrw14, 31:30, scratch14, 29:28);
- s(EmcMrw1, 7:0, scratch15, 7:0);
- s(EmcMrw1, 23:16, scratch15, 15:8);
- s(EmcMrw1, 27:26, scratch15, 17:16);
- s(EmcMrw1, 31:30, scratch15, 19:18);
- s(emc_warm_boot_mrw_extra, 7:0, scratch16, 7:0);
- s(emc_warm_boot_mrw_extra, 23:16, scratch16, 15:8);
- s(emc_warm_boot_mrw_extra, 27:26, scratch16, 17:16);
- s(emc_warm_boot_mrw_extra, 31:30, scratch16, 19:18);
- s(emc_mrw2, 7:0, scratch17, 7:0);
- s(emc_mrw2, 23:16, scratch17, 15:8);
- s(emc_mrw2, 27:26, scratch17, 17:16);
- s(emc_mrw2, 31:30, scratch17, 19:18);
- pmc->scratch18 = (sdram->emc_mrw3 >> 30 << 18) | ((16 * sdram->emc_mrw3 >> 31 << 17) | ((32 * sdram->emc_mrw3 >> 31 << 16) | ((sdram->emc_mrw3 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw3 | (pmc->scratch18 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF;
- pmc->scratch19 = (sdram->emc_mrw4 >> 30 << 18) | ((16 * sdram->emc_mrw4 >> 31 << 17) | ((32 * sdram->emc_mrw4 >> 31 << 16) | ((sdram->emc_mrw4 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw4 | (pmc->scratch19 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF;
- s32(emc_cmd_mapping_byte, secure_scratch8);
- s32(emc_pmacro_brick_mapping0, secure_scratch9);
- s32(emc_pmacro_brick_mapping1, secure_scratch10);
- s32(emc_pmacro_brick_mapping2, secure_scratch11);
- s32(mc_video_protect_gpu_override0, secure_scratch12);
- pmc->secure_scratch13 = ((u16)(sdram->emc_adr_cfg) << 31) | (2 * ((((u16)(sdram->mc_untranslated_region_check) << 22) >> 31 << 30) | ((((u16)(sdram->mc_untranslated_region_check) << 23) >> 31 << 29) | (((u16)(sdram->mc_untranslated_region_check) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd0_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_0 & 0x7F | (pmc->secure_scratch13 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch14 = (sdram->mc_video_protect_write_access << 30 >> 31 << 31) | (2 * ((sdram->mc_video_protect_write_access << 30) | ((sdram->mc_video_protect_bom_adr_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd0_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_1 & 0x7F | (pmc->secure_scratch14 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch15 = ((u16)(sdram->mc_mts_carveout_adr_hi) << 30) | (4 * ((sdram->mc_sec_carveout_adr_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_0 & 0x7F | (pmc->secure_scratch15 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2);
- pmc->secure_scratch16 = (sdram->mc_generalized_carveout3_bom_hi << 30) | (4 * ((sdram->mc_generalized_carveout5_bom_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_1 & 0x7F | (pmc->secure_scratch16 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2);
- pmc->secure_scratch17 = ((u16)(sdram->mc_generalized_carveout4_bom_hi) << 30) | (4 * (((u16)(sdram->mc_generalized_carveout2_bom_hi) << 28) | ((2 * sdram->emc_cmd_mapping_cmd2_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_0 & 0x7F | (pmc->secure_scratch17 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2);
- pmc->secure_scratch18 = (sdram->emc_fbio_cfg8 << 16 >> 31 << 31) | (2 * (((u16)(sdram->emc_fbio_spare) << 30 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd2_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_1 & 0x7F | (pmc->secure_scratch18 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch19 = (sdram->mc_video_protect_vpr_override << 31) | (2 * (((u16)(sdram->mc_mts_carveout_reg_ctrl) << 30) | ((sdram->mc_sec_carveout_protect_write_access << 31 >> 2) | (((u16)(sdram->mc_emem_adr_cfg) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd3_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_0 & 0x7F | (pmc->secure_scratch19 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch20 = (sdram->mc_generalized_carveout2_cfg0 << 25 >> 28 << 28) | ((2 * sdram->emc_cmd_mapping_cmd3_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_1 & 0x7F | (pmc->secure_scratch20 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF;
- pmc->secure_scratch39 = (sdram->mc_video_protect_vpr_override << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 21 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout4_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout4_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout4_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout4_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout4_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout4_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout4_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout4_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout4_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout4_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout4_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout4_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout4_cfg0 & 1 | 2 * (pmc->secure_scratch39 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1);
- pmc->secure_scratch40 = (sdram->mc_video_protect_vpr_override << 29 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 14 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout5_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout5_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout5_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout5_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout5_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout5_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout5_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout5_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout5_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout5_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout5_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout5_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout5_cfg0 & 1 | 2 * (pmc->secure_scratch40 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1);
- pmc->secure_scratch41 = (sdram->mc_generalized_carveout2_cfg0 << 18 >> 29 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 10 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd0_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd0_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_2 & 0x7F | (pmc->secure_scratch41 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF;
- pmc->secure_scratch42 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 25 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd1_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd1_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_2 & 0x7F | (pmc->secure_scratch42 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF;
- pmc->secure_scratch43 = ((u16)(sdram->mc_generalized_carveout3_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 21 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd2_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd2_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_2 & 0x7F | (pmc->secure_scratch43 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF;
- pmc->secure_scratch44 = (sdram->mc_video_protect_vpr_override << 24 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 25 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override << 28 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 14 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd3_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd3_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_2 & 0x7F | (pmc->secure_scratch44 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- s(mc_emem_adr_cfg_channel_mask, 31:9, secure_scratch45, 22:0);
- s(mc_emem_adr_cfg_dev0, 2:0, secure_scratch45, 25:23);
- s(mc_emem_adr_cfg_dev0, 9:8, secure_scratch45, 27:26);
- s(mc_emem_adr_cfg_dev0, 19:16, secure_scratch45, 31:28);
- pmc->secure_scratch46 = (sdram->mc_video_protect_vpr_override << 23 >> 31 << 31) | (2 * ((sdram->mc_emem_adr_cfg_dev1 << 12 >> 28 << 27) | ((sdram->mc_emem_adr_cfg_dev1 << 22 >> 30 << 25) | ((sdram->mc_emem_adr_cfg_dev1 << 22) & 0x1FFFFFF | ((sdram->mc_emem_adr_cfg_bank_mask0 >> 10) | (pmc->secure_scratch46 >> 22 << 22)) & 0xFE3FFFFF) & 0xF9FFFFFF) & 0x87FFFFFF) >> 1);
- pmc->secure_scratch47 = (sdram->mc_video_protect_vpr_override << 20 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 22 >> 31 << 30) | (((u8)(sdram->mc_generalized_carveout3_cfg0) << 25 >> 28 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 10 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask1 >> 10) | (pmc->secure_scratch47 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch48 = (sdram->mc_video_protect_vpr_override << 16 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 17 >> 31 << 30) | ((sdram->mc_generalized_carveout3_cfg0 << 14 >> 28 << 26) | ((sdram->mc_generalized_carveout3_cfg0 << 21 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask2 >> 10) | (pmc->secure_scratch48 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch49 = (sdram->mc_video_protect_vpr_override << 14 >> 31 << 31) | (2 * ((sdram->mc_emem_cfg >> 31 << 30) | ((sdram->mc_emem_cfg << 18 >> 2) | (sdram->mc_video_protect_gpu_override1 & 0xFFFF | (pmc->secure_scratch49 >> 16 << 16)) & 0xC000FFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch50 = (sdram->mc_video_protect_vpr_override << 12 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 13 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom >> 17 << 15) | ((sdram->mc_generalized_carveout3_bom >> 17) | (pmc->secure_scratch50 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch51 = (sdram->mc_video_protect_vpr_override << 10 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 11 >> 31 << 30) | ((sdram->mc_generalized_carveout2_bom >> 17 << 15) | ((sdram->mc_generalized_carveout4_bom >> 17) | (pmc->secure_scratch51 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch52 = (sdram->mc_video_protect_vpr_override << 9 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout3_cfg0 << 10 >> 28 << 27) | ((sdram->mc_video_protect_bom >> 20 << 15) | ((sdram->mc_generalized_carveout5_bom >> 17) | (pmc->secure_scratch52 >> 15 << 15)) & 0xF8007FFF) & 0x87FFFFFF) >> 1);
- pmc->secure_scratch53 = (sdram->mc_video_protect_vpr_override1 << 27 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 30 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 31 >> 2) | ((sdram->mc_video_protect_vpr_override >> 31 << 28) | ((2 * sdram->mc_video_protect_vpr_override >> 31 << 27) | ((4 * sdram->mc_video_protect_vpr_override >> 31 << 26) | ((32 * sdram->mc_video_protect_vpr_override >> 31 << 25) | ((sdram->mc_video_protect_vpr_override << 8 >> 31 << 24) | ((sdram->mc_sec_carveout_bom >> 20 << 12) | (sdram->mc_video_protect_size_mb & 0xFFF | (pmc->secure_scratch53 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch54 = (sdram->mc_video_protect_vpr_override1 << 19 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 20 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 21 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 22 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 23 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 24 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 25 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 26 >> 31 << 24) | ((sdram->mc_mts_carveout_bom >> 20 << 12) | (sdram->mc_sec_carveout_size_mb & 0xFFF | (pmc->secure_scratch54 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch55 = (sdram->mc_generalized_carveout2_cfg0 << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 30) | ((32 * sdram->mc_video_protect_vpr_override1 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 6 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 15 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 16 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 17 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 18 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout4_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_mts_carveout_size_mb & 0xFFF | (pmc->secure_scratch55 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch56 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 30 >> 31 << 31) | (2 * (((u16)(sdram->mc_generalized_carveout1_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout2_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout2_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout2_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout2_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout2_cfg0 << 29 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout2_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout3_size_128kb & 0xFFF | (pmc->secure_scratch56 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
- pmc->secure_scratch57 = ((u8)(sdram->mc_generalized_carveout3_cfg0) << 30 >> 31 << 31) | (2 * (((u8)(sdram->mc_generalized_carveout3_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout1_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout1_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout1_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout1_cfg0 << 29 >> 31 << 24) | ((sdram->mc_generalized_carveout5_size_128kb << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout1_size_128kb & 0xFFF | (pmc->secure_scratch57 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1);
-
- s32(mc_generalized_carveout1_access0, secure_scratch59);
- s32(mc_generalized_carveout1_access1, secure_scratch60);
- s32(mc_generalized_carveout1_access2, secure_scratch61);
- s32(mc_generalized_carveout1_access3, secure_scratch62);
- s32(mc_generalized_carveout1_access4, secure_scratch63);
- s32(mc_generalized_carveout2_access0, secure_scratch64);
- s32(mc_generalized_carveout2_access1, secure_scratch65);
- s32(mc_generalized_carveout2_access2, secure_scratch66);
- s32(mc_generalized_carveout2_access3, secure_scratch67);
- s32(mc_generalized_carveout2_access4, secure_scratch68);
- s32(mc_generalized_carveout3_access0, secure_scratch69);
- s32(mc_generalized_carveout3_access1, secure_scratch70);
- s32(mc_generalized_carveout3_access2, secure_scratch71);
- s32(mc_generalized_carveout3_access3, secure_scratch72);
- s32(mc_generalized_carveout3_access4, secure_scratch73);
- s32(mc_generalized_carveout4_access0, secure_scratch74);
- s32(mc_generalized_carveout4_access1, secure_scratch75);
- s32(mc_generalized_carveout4_access2, secure_scratch76);
- s32(mc_generalized_carveout4_access3, secure_scratch77);
- s32(mc_generalized_carveout4_access4, secure_scratch78);
- s32(mc_generalized_carveout5_access0, secure_scratch79);
- s32(mc_generalized_carveout5_access1, secure_scratch80);
- s32(mc_generalized_carveout5_access2, secure_scratch81);
- s32(mc_generalized_carveout5_access3, secure_scratch82);
- s32(mc_generalized_carveout1_force_internal_access0, secure_scratch84);
- s32(mc_generalized_carveout1_force_internal_access1, secure_scratch85);
- s32(mc_generalized_carveout1_force_internal_access2, secure_scratch86);
- s32(mc_generalized_carveout1_force_internal_access3, secure_scratch87);
- s32(mc_generalized_carveout1_force_internal_access4, secure_scratch88);
- s32(mc_generalized_carveout2_force_internal_access0, secure_scratch89);
- s32(mc_generalized_carveout2_force_internal_access1, secure_scratch90);
- s32(mc_generalized_carveout2_force_internal_access2, secure_scratch91);
- s32(mc_generalized_carveout2_force_internal_access3, secure_scratch92);
- s32(mc_generalized_carveout2_force_internal_access4, secure_scratch93);
- s32(mc_generalized_carveout3_force_internal_access0, secure_scratch94);
- s32(mc_generalized_carveout3_force_internal_access1, secure_scratch95);
- s32(mc_generalized_carveout3_force_internal_access2, secure_scratch96);
- s32(mc_generalized_carveout3_force_internal_access3, secure_scratch97);
- s32(mc_generalized_carveout3_force_internal_access4, secure_scratch98);
- s32(mc_generalized_carveout4_force_internal_access0, secure_scratch99);
- s32(mc_generalized_carveout4_force_internal_access1, secure_scratch100);
- s32(mc_generalized_carveout4_force_internal_access2, secure_scratch101);
- s32(mc_generalized_carveout4_force_internal_access3, secure_scratch102);
- s32(mc_generalized_carveout4_force_internal_access4, secure_scratch103);
- s32(mc_generalized_carveout5_force_internal_access0, secure_scratch104);
- s32(mc_generalized_carveout5_force_internal_access1, secure_scratch105);
- s32(mc_generalized_carveout5_force_internal_access2, secure_scratch106);
- s32(mc_generalized_carveout5_force_internal_access3, secure_scratch107);
-
- pmc->secure_scratch58 = 32 * (32 * sdram->mc_generalized_carveout3_cfg0 >> 31) | (16 * (sdram->mc_generalized_carveout3_cfg0 << 6 >> 31) | (8 * (sdram->mc_generalized_carveout3_cfg0 << 7 >> 31) | (4 * (sdram->mc_generalized_carveout3_cfg0 << 8 >> 31) | (2 * (sdram->mc_generalized_carveout3_cfg0 << 9 >> 31) | ((sdram->mc_generalized_carveout3_cfg0 << 29 >> 31) | 2 * (pmc->secure_scratch58 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF;
-
- c32(0, scratch2);
- s(pllm_input_divider, 7:0, scratch2, 7:0);
- s(pllm_feedback_divider, 7:0, scratch2, 15:8);
- s(pllm_post_divider, 4:0, scratch2, 20:16);
- s(pllm_kvco, 0:0, scratch2, 17:17);
- s(pllm_kcp, 1:0, scratch2, 19:18);
-
- c32(0, scratch35);
- s(pllm_setup_control, 15:0, scratch35, 15:0);
-
- c32(0, scratch3);
- s(pllm_input_divider, 7:0, scratch3, 7:0);
- c(0x3e, scratch3, 15:8);
- c(0, scratch3, 20:16);
- s(pllm_kvco, 0:0, scratch3, 21:21);
- s(pllm_kcp, 1:0, scratch3, 23:22);
-
- c32(0, scratch36);
- s(PllMSetupControl, 23:0, scratch36, 23:0);
-
- c32(0, scratch4);
- s(pllm_stable_time, 9:0, scratch4, 9:0); // s32(pllm_stable_time, scratch4);, s(pllm_stable_time, 31:0, scratch4, 31:10);
- s(pllm_stable_time, 31:0, scratch4, 31:10);
-}
-
-#pragma GCC diagnostic pop
-
-void sdram_lp0_save_params(const void *params)
-{
- u32 chip_id = (APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF;
-
- if (chip_id != GP_HIDREV_MAJOR_T210B01)
- _sdram_lp0_save_params_t210(params);
- else
- _sdram_lp0_save_params_t210b01(params);
-}
diff --git a/bdk/mem/sdram_lp0_param_t210.h b/bdk/mem/sdram_lp0_param_t210.h
deleted file mode 100644
index 09e960e..0000000
--- a/bdk/mem/sdram_lp0_param_t210.h
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
- * Copyright 2014 Google Inc.
- * Copyright (c) 2018 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.
- */
-
-/**
- * Defines the SDRAM parameter structure.
- *
- * Note that PLLM is used by EMC. The field names are in camel case to ease
- * directly converting BCT config files (*.cfg) into C structure.
- */
-
-#ifndef __TEGRA210_SDRAM_PARAM_H__
-#define __TEGRA210_SDRAM_PARAM_H__
-
-#include
-
-enum
-{
- /* Specifies the memory type to be undefined */
- NvBootMemoryType_None = 0,
-
- /* Specifies the memory type to be DDR SDRAM */
- NvBootMemoryType_Ddr = 0,
-
- /* Specifies the memory type to be LPDDR SDRAM */
- NvBootMemoryType_LpDdr = 0,
-
- /* Specifies the memory type to be DDR2 SDRAM */
- NvBootMemoryType_Ddr2 = 0,
-
- /* Specifies the memory type to be LPDDR2 SDRAM */
- NvBootMemoryType_LpDdr2,
-
- /* Specifies the memory type to be DDR3 SDRAM */
- NvBootMemoryType_Ddr3,
-
- /* Specifies the memory type to be LPDDR4 SDRAM */
- NvBootMemoryType_LpDdr4,
-
- NvBootMemoryType_Num,
-
- /* Specifies an entry in the ram_code table that's not in use */
- NvBootMemoryType_Unused = 0X7FFFFFF,
-};
-
-/**
- * Defines the SDRAM parameter structure
- */
-struct sdram_params_t210
-{
-
- /* Specifies the type of memory device */
- u32 MemoryType;
-
- /* MC/EMC clock source configuration */
-
- /* Specifies the M value for PllM */
- u32 PllMInputDivider;
- /* Specifies the N value for PllM */
- u32 PllMFeedbackDivider;
- /* Specifies the time to wait for PLLM to lock (in microseconds) */
- u32 PllMStableTime;
- /* Specifies misc. control bits */
- u32 PllMSetupControl;
- /* Specifies the P value for PLLM */
- u32 PllMPostDivider;
- /* Specifies value for Charge Pump Gain Control */
- u32 PllMKCP;
- /* Specifies VCO gain */
- u32 PllMKVCO;
- /* Spare BCT param */
- u32 EmcBctSpare0;
- /* Spare BCT param */
- u32 EmcBctSpare1;
- /* Spare BCT param */
- u32 EmcBctSpare2;
- /* Spare BCT param */
- u32 EmcBctSpare3;
- /* Spare BCT param */
- u32 EmcBctSpare4;
- /* Spare BCT param */
- u32 EmcBctSpare5;
- /* Spare BCT param */
- u32 EmcBctSpare6;
- /* Spare BCT param */
- u32 EmcBctSpare7;
- /* Spare BCT param */
- u32 EmcBctSpare8;
- /* Spare BCT param */
- u32 EmcBctSpare9;
- /* Spare BCT param */
- u32 EmcBctSpare10;
- /* Spare BCT param */
- u32 EmcBctSpare11;
- /* Spare BCT param */
- u32 EmcBctSpare12;
- /* Spare BCT param */
- u32 EmcBctSpare13;
-
- /* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
- u32 EmcClockSource;
- u32 EmcClockSourceDll;
-
- /* Defines possible override for PLLLM_MISC2 */
- u32 ClkRstControllerPllmMisc2Override;
- /* enables override for PLLLM_MISC2 */
- u32 ClkRstControllerPllmMisc2OverrideEnable;
- /* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
- u32 ClearClk2Mc1;
-
- /* Auto-calibration of EMC pads */
-
- /* Specifies the value for EMC_AUTO_CAL_INTERVAL */
- u32 EmcAutoCalInterval;
- /*
- * Specifies the value for EMC_AUTO_CAL_CONFIG
- * Note: Trigger bits are set by the SDRAM code.
- */
- u32 EmcAutoCalConfig;
-
- /* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
- u32 EmcAutoCalConfig2;
-
- /* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
- u32 EmcAutoCalConfig3;
-
- /* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
- u32 EmcAutoCalConfig4;
- u32 EmcAutoCalConfig5;
- u32 EmcAutoCalConfig6;
- u32 EmcAutoCalConfig7;
- u32 EmcAutoCalConfig8;
-
- /* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
- u32 EmcAutoCalVrefSel0;
- u32 EmcAutoCalVrefSel1;
-
- /* Specifies the value for EMC_AUTO_CAL_CHANNEL */
- u32 EmcAutoCalChannel;
-
- /* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
- u32 EmcPmacroAutocalCfg0;
- u32 EmcPmacroAutocalCfg1;
- u32 EmcPmacroAutocalCfg2;
- u32 EmcPmacroRxTerm;
- u32 EmcPmacroDqTxDrv;
- u32 EmcPmacroCaTxDrv;
- u32 EmcPmacroCmdTxDrv;
- u32 EmcPmacroAutocalCfgCommon;
- u32 EmcPmacroZctrl;
-
- /*
- * Specifies the time for the calibration
- * to stabilize (in microseconds)
- */
- u32 EmcAutoCalWait;
-
- u32 EmcXm2CompPadCtrl;
- u32 EmcXm2CompPadCtrl2;
- u32 EmcXm2CompPadCtrl3;
-
- /*
- * DRAM size information
- * Specifies the value for EMC_ADR_CFG
- */
- u32 EmcAdrCfg;
-
- /*
- * Specifies the time to wait after asserting pin
- * CKE (in microseconds)
- */
- u32 EmcPinProgramWait;
- /* Specifies the extra delay before/after pin RESET/CKE command */
- u32 EmcPinExtraWait;
-
- u32 EmcPinGpioEn;
- u32 EmcPinGpio;
-
- /*
- * Specifies the extra delay after the first writing
- * of EMC_TIMING_CONTROL
- */
- u32 EmcTimingControlWait;
-
- /* Timing parameters required for the SDRAM */
-
- /* Specifies the value for EMC_RC */
- u32 EmcRc;
- /* Specifies the value for EMC_RFC */
- u32 EmcRfc;
- /* Specifies the value for EMC_RFC_PB */
- u32 EmcRfcPb;
- /* Specifies the value for EMC_RFC_CTRL2 */
- u32 EmcRefctrl2;
- /* Specifies the value for EMC_RFC_SLR */
- u32 EmcRfcSlr;
- /* Specifies the value for EMC_RAS */
- u32 EmcRas;
- /* Specifies the value for EMC_RP */
- u32 EmcRp;
- /* Specifies the value for EMC_R2R */
- u32 EmcR2r;
- /* Specifies the value for EMC_W2W */
- u32 EmcW2w;
- /* Specifies the value for EMC_R2W */
- u32 EmcR2w;
- /* Specifies the value for EMC_W2R */
- u32 EmcW2r;
- /* Specifies the value for EMC_R2P */
- u32 EmcR2p;
- /* Specifies the value for EMC_W2P */
- u32 EmcW2p;
-
- u32 EmcTppd;
- u32 EmcCcdmw;
-
- /* Specifies the value for EMC_RD_RCD */
- u32 EmcRdRcd;
- /* Specifies the value for EMC_WR_RCD */
- u32 EmcWrRcd;
- /* Specifies the value for EMC_RRD */
- u32 EmcRrd;
- /* Specifies the value for EMC_REXT */
- u32 EmcRext;
- /* Specifies the value for EMC_WEXT */
- u32 EmcWext;
- /* Specifies the value for EMC_WDV */
- u32 EmcWdv;
-
- u32 EmcWdvChk;
- u32 EmcWsv;
- u32 EmcWev;
-
- /* Specifies the value for EMC_WDV_MASK */
- u32 EmcWdvMask;
-
- u32 EmcWsDuration;
- u32 EmcWeDuration;
-
- /* Specifies the value for EMC_QUSE */
- u32 EmcQUse;
- /* Specifies the value for EMC_QUSE_WIDTH */
- u32 EmcQuseWidth;
- /* Specifies the value for EMC_IBDLY */
- u32 EmcIbdly;
- /* Specifies the value for EMC_OBDLY */
- u32 EmcObdly;
- /* Specifies the value for EMC_EINPUT */
- u32 EmcEInput;
- /* Specifies the value for EMC_EINPUT_DURATION */
- u32 EmcEInputDuration;
- /* Specifies the value for EMC_PUTERM_EXTRA */
- u32 EmcPutermExtra;
- /* Specifies the value for EMC_PUTERM_WIDTH */
- u32 EmcPutermWidth;
- /* Specifies the value for EMC_PUTERM_ADJ */
- ////u32 EmcPutermAdj;
-
- /* Specifies the value for EMC_QRST */
- u32 EmcQRst;
- /* Specifies the value for EMC_QSAFE */
- u32 EmcQSafe;
- /* Specifies the value for EMC_RDV */
- u32 EmcRdv;
- /* Specifies the value for EMC_RDV_MASK */
- u32 EmcRdvMask;
- /* Specifies the value for EMC_RDV_EARLY */
- u32 EmcRdvEarly;
- /* Specifies the value for EMC_RDV_EARLY_MASK */
- u32 EmcRdvEarlyMask;
- /* Specifies the value for EMC_QPOP */
- u32 EmcQpop;
-
- /* Specifies the value for EMC_REFRESH */
- u32 EmcRefresh;
- /* Specifies the value for EMC_BURST_REFRESH_NUM */
- u32 EmcBurstRefreshNum;
- /* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
- u32 EmcPreRefreshReqCnt;
- /* Specifies the value for EMC_PDEX2WR */
- u32 EmcPdEx2Wr;
- /* Specifies the value for EMC_PDEX2RD */
- u32 EmcPdEx2Rd;
- /* Specifies the value for EMC_PCHG2PDEN */
- u32 EmcPChg2Pden;
- /* Specifies the value for EMC_ACT2PDEN */
- u32 EmcAct2Pden;
- /* Specifies the value for EMC_AR2PDEN */
- u32 EmcAr2Pden;
- /* Specifies the value for EMC_RW2PDEN */
- u32 EmcRw2Pden;
- /* Specifies the value for EMC_CKE2PDEN */
- u32 EmcCke2Pden;
- /* Specifies the value for EMC_PDEX2CKE */
- u32 EmcPdex2Cke;
- /* Specifies the value for EMC_PDEX2MRR */
- u32 EmcPdex2Mrr;
- /* Specifies the value for EMC_TXSR */
- u32 EmcTxsr;
- /* Specifies the value for EMC_TXSRDLL */
- u32 EmcTxsrDll;
- /* Specifies the value for EMC_TCKE */
- u32 EmcTcke;
- /* Specifies the value for EMC_TCKESR */
- u32 EmcTckesr;
- /* Specifies the value for EMC_TPD */
- u32 EmcTpd;
- /* Specifies the value for EMC_TFAW */
- u32 EmcTfaw;
- /* Specifies the value for EMC_TRPAB */
- u32 EmcTrpab;
- /* Specifies the value for EMC_TCLKSTABLE */
- u32 EmcTClkStable;
- /* Specifies the value for EMC_TCLKSTOP */
- u32 EmcTClkStop;
- /* Specifies the value for EMC_TREFBW */
- u32 EmcTRefBw;
-
- /* FBIO configuration values */
-
- /* Specifies the value for EMC_FBIO_CFG5 */
- u32 EmcFbioCfg5;
- /* Specifies the value for EMC_FBIO_CFG7 */
- u32 EmcFbioCfg7;
- /* Specifies the value for EMC_FBIO_CFG8 */
- u32 EmcFbioCfg8;
-
- /* Command mapping for CMD brick 0 */
- u32 EmcCmdMappingCmd0_0;
- u32 EmcCmdMappingCmd0_1;
- u32 EmcCmdMappingCmd0_2;
- u32 EmcCmdMappingCmd1_0;
- u32 EmcCmdMappingCmd1_1;
- u32 EmcCmdMappingCmd1_2;
- u32 EmcCmdMappingCmd2_0;
- u32 EmcCmdMappingCmd2_1;
- u32 EmcCmdMappingCmd2_2;
- u32 EmcCmdMappingCmd3_0;
- u32 EmcCmdMappingCmd3_1;
- u32 EmcCmdMappingCmd3_2;
- u32 EmcCmdMappingByte;
-
- /* Specifies the value for EMC_FBIO_SPARE */
- u32 EmcFbioSpare;
-
- /* Specifies the value for EMC_CFG_RSV */
- u32 EmcCfgRsv;
-
- /* MRS command values */
-
- /* Specifies the value for EMC_MRS */
- u32 EmcMrs;
- /* Specifies the MP0 command to initialize mode registers */
- u32 EmcEmrs;
- /* Specifies the MP2 command to initialize mode registers */
- u32 EmcEmrs2;
- /* Specifies the MP3 command to initialize mode registers */
- u32 EmcEmrs3;
- /* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
- u32 EmcMrw1;
- /* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
- u32 EmcMrw2;
- /* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
- u32 EmcMrw3;
- /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
- u32 EmcMrw4;
- /* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
- u32 EmcMrw6;
- /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
- u32 EmcMrw8;
- /* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
- u32 EmcMrw9;
- /* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
- u32 EmcMrw10;
- /* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
- u32 EmcMrw12;
- /* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
- u32 EmcMrw13;
- /* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
- u32 EmcMrw14;
- /*
- * Specifies the programming to extra LPDDR2 Mode Register
- * at cold boot
- */
- u32 EmcMrwExtra;
- /*
- * Specifies the programming to extra LPDDR2 Mode Register
- * at warm boot
- */
- u32 EmcWarmBootMrwExtra;
- /*
- * Specify the enable of extra Mode Register programming at
- * warm boot
- */
- u32 EmcWarmBootExtraModeRegWriteEnable;
- /*
- * Specify the enable of extra Mode Register programming at
- * cold boot
- */
- u32 EmcExtraModeRegWriteEnable;
-
- /* Specifies the EMC_MRW reset command value */
- u32 EmcMrwResetCommand;
- /* Specifies the EMC Reset wait time (in microseconds) */
- u32 EmcMrwResetNInitWait;
- /* Specifies the value for EMC_MRS_WAIT_CNT */
- u32 EmcMrsWaitCnt;
- /* Specifies the value for EMC_MRS_WAIT_CNT2 */
- u32 EmcMrsWaitCnt2;
-
- /* EMC miscellaneous configurations */
-
- /* Specifies the value for EMC_CFG */
- u32 EmcCfg;
- /* Specifies the value for EMC_CFG_2 */
- u32 EmcCfg2;
- /* Specifies the pipe bypass controls */
- u32 EmcCfgPipe;
- u32 EmcCfgPipeClk;
- u32 EmcFdpdCtrlCmdNoRamp;
- u32 EmcCfgUpdate;
-
- /* Specifies the value for EMC_DBG */
- u32 EmcDbg;
- u32 EmcDbgWriteMux;
-
- /* Specifies the value for EMC_CMDQ */
- u32 EmcCmdQ;
- /* Specifies the value for EMC_MC2EMCQ */
- u32 EmcMc2EmcQ;
- /* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
- u32 EmcDynSelfRefControl;
-
- /* Specifies the value for MEM_INIT_DONE */
- u32 AhbArbitrationXbarCtrlMemInitDone;
-
- /* Specifies the value for EMC_CFG_DIG_DLL */
- u32 EmcCfgDigDll;
- u32 EmcCfgDigDll_1;
- /* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
- u32 EmcCfgDigDllPeriod;
- /* Specifies the value of *DEV_SELECTN of various EMC registers */
- u32 EmcDevSelect;
-
- /* Specifies the value for EMC_SEL_DPD_CTRL */
- u32 EmcSelDpdCtrl;
-
- /* Pads trimmer delays */
- u32 EmcFdpdCtrlDq;
- u32 EmcFdpdCtrlCmd;
- u32 EmcPmacroIbVrefDq_0;
- u32 EmcPmacroIbVrefDq_1;
- u32 EmcPmacroIbVrefDqs_0;
- u32 EmcPmacroIbVrefDqs_1;
- u32 EmcPmacroIbRxrt;
- u32 EmcCfgPipe1;
- u32 EmcCfgPipe2;
-
- /* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
- u32 EmcPmacroQuseDdllRank0_0;
- u32 EmcPmacroQuseDdllRank0_1;
- u32 EmcPmacroQuseDdllRank0_2;
- u32 EmcPmacroQuseDdllRank0_3;
- u32 EmcPmacroQuseDdllRank0_4;
- u32 EmcPmacroQuseDdllRank0_5;
- u32 EmcPmacroQuseDdllRank1_0;
- u32 EmcPmacroQuseDdllRank1_1;
- u32 EmcPmacroQuseDdllRank1_2;
- u32 EmcPmacroQuseDdllRank1_3;
- u32 EmcPmacroQuseDdllRank1_4;
- u32 EmcPmacroQuseDdllRank1_5;
-
- u32 EmcPmacroObDdllLongDqRank0_0;
- u32 EmcPmacroObDdllLongDqRank0_1;
- u32 EmcPmacroObDdllLongDqRank0_2;
- u32 EmcPmacroObDdllLongDqRank0_3;
- u32 EmcPmacroObDdllLongDqRank0_4;
- u32 EmcPmacroObDdllLongDqRank0_5;
- u32 EmcPmacroObDdllLongDqRank1_0;
- u32 EmcPmacroObDdllLongDqRank1_1;
- u32 EmcPmacroObDdllLongDqRank1_2;
- u32 EmcPmacroObDdllLongDqRank1_3;
- u32 EmcPmacroObDdllLongDqRank1_4;
- u32 EmcPmacroObDdllLongDqRank1_5;
-
- u32 EmcPmacroObDdllLongDqsRank0_0;
- u32 EmcPmacroObDdllLongDqsRank0_1;
- u32 EmcPmacroObDdllLongDqsRank0_2;
- u32 EmcPmacroObDdllLongDqsRank0_3;
- u32 EmcPmacroObDdllLongDqsRank0_4;
- u32 EmcPmacroObDdllLongDqsRank0_5;
- u32 EmcPmacroObDdllLongDqsRank1_0;
- u32 EmcPmacroObDdllLongDqsRank1_1;
- u32 EmcPmacroObDdllLongDqsRank1_2;
- u32 EmcPmacroObDdllLongDqsRank1_3;
- u32 EmcPmacroObDdllLongDqsRank1_4;
- u32 EmcPmacroObDdllLongDqsRank1_5;
-
- u32 EmcPmacroIbDdllLongDqsRank0_0;
- u32 EmcPmacroIbDdllLongDqsRank0_1;
- u32 EmcPmacroIbDdllLongDqsRank0_2;
- u32 EmcPmacroIbDdllLongDqsRank0_3;
- u32 EmcPmacroIbDdllLongDqsRank1_0;
- u32 EmcPmacroIbDdllLongDqsRank1_1;
- u32 EmcPmacroIbDdllLongDqsRank1_2;
- u32 EmcPmacroIbDdllLongDqsRank1_3;
-
- u32 EmcPmacroDdllLongCmd_0;
- u32 EmcPmacroDdllLongCmd_1;
- u32 EmcPmacroDdllLongCmd_2;
- u32 EmcPmacroDdllLongCmd_3;
- u32 EmcPmacroDdllLongCmd_4;
- u32 EmcPmacroDdllShortCmd_0;
- u32 EmcPmacroDdllShortCmd_1;
- u32 EmcPmacroDdllShortCmd_2;
-
- /*
- * Specifies the delay after asserting CKE pin during a WarmBoot0
- * sequence (in microseconds)
- */
- u32 WarmBootWait;
-
- /* Specifies the value for EMC_ODT_WRITE */
- u32 EmcOdtWrite;
-
- /* Periodic ZQ calibration */
-
- /*
- * Specifies the value for EMC_ZCAL_INTERVAL
- * Value 0 disables ZQ calibration
- */
- u32 EmcZcalInterval;
- /* Specifies the value for EMC_ZCAL_WAIT_CNT */
- u32 EmcZcalWaitCnt;
- /* Specifies the value for EMC_ZCAL_MRW_CMD */
- u32 EmcZcalMrwCmd;
-
- /* DRAM initialization sequence flow control */
-
- /* Specifies the MRS command value for resetting DLL */
- u32 EmcMrsResetDll;
- /* Specifies the command for ZQ initialization of device 0 */
- u32 EmcZcalInitDev0;
- /* Specifies the command for ZQ initialization of device 1 */
- u32 EmcZcalInitDev1;
- /*
- * Specifies the wait time after programming a ZQ initialization
- * command (in microseconds)
- */
- u32 EmcZcalInitWait;
- /*
- * Specifies the enable for ZQ calibration at cold boot [bit 0]
- * and warm boot [bit 1]
- */
- u32 EmcZcalWarmColdBootEnables;
-
- /*
- * Specifies the MRW command to LPDDR2 for ZQ calibration
- * on warmboot
- */
- /* Is issued to both devices separately */
- u32 EmcMrwLpddr2ZcalWarmBoot;
- /*
- * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
- * Is issued to both devices separately
- */
- u32 EmcZqCalDdr3WarmBoot;
- u32 EmcZqCalLpDdr4WarmBoot;
- /*
- * Specifies the wait time for ZQ calibration on warmboot
- * (in microseconds)
- */
- u32 EmcZcalWarmBootWait;
- /*
- * Specifies the enable for DRAM Mode Register programming
- * at warm boot
- */
- u32 EmcMrsWarmBootEnable;
- /*
- * Specifies the wait time after sending an MRS DLL reset command
- * in microseconds)
- */
- u32 EmcMrsResetDllWait;
- /* Specifies the extra MRS command to initialize mode registers */
- u32 EmcMrsExtra;
- /* Specifies the extra MRS command at warm boot */
- u32 EmcWarmBootMrsExtra;
- /* Specifies the EMRS command to enable the DDR2 DLL */
- u32 EmcEmrsDdr2DllEnable;
- /* Specifies the MRS command to reset the DDR2 DLL */
- u32 EmcMrsDdr2DllReset;
- /* Specifies the EMRS command to set OCD calibration */
- u32 EmcEmrsDdr2OcdCalib;
- /*
- * Specifies the wait between initializing DDR and setting OCD
- * calibration (in microseconds)
- */
- u32 EmcDdr2Wait;
- /* Specifies the value for EMC_CLKEN_OVERRIDE */
- u32 EmcClkenOverride;
-
- /*
- * Specifies LOG2 of the extra refresh numbers after booting
- * Program 0 to disable
- */
- u32 EmcExtraRefreshNum;
- /* Specifies the master override for all EMC clocks */
- u32 EmcClkenOverrideAllWarmBoot;
- /* Specifies the master override for all MC clocks */
- u32 McClkenOverrideAllWarmBoot;
- /* Specifies digital dll period, choosing between 4 to 64 ms */
- u32 EmcCfgDigDllPeriodWarmBoot;
-
- /* Pad controls */
-
- /* Specifies the value for PMC_VDDP_SEL */
- u32 PmcVddpSel;
- /* Specifies the wait time after programming PMC_VDDP_SEL */
- u32 PmcVddpSelWait;
- /* Specifies the value for PMC_DDR_PWR */
- u32 PmcDdrPwr;
- /* Specifies the value for PMC_DDR_CFG */
- u32 PmcDdrCfg;
- /* Specifies the value for PMC_IO_DPD3_REQ */
- u32 PmcIoDpd3Req;
- /* Specifies the wait time after programming PMC_IO_DPD3_REQ */
- u32 PmcIoDpd3ReqWait;
- u32 PmcIoDpd4ReqWait;
-
- /* Specifies the value for PMC_REG_SHORT */
- u32 PmcRegShort;
- /* Specifies the value for PMC_NO_IOPOWER */
- u32 PmcNoIoPower;
-
- u32 PmcDdrCntrlWait;
- u32 PmcDdrCntrl;
-
- /* Specifies the value for EMC_ACPD_CONTROL */
- u32 EmcAcpdControl;
-
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
- ////u32 EmcSwizzleRank0ByteCfg;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
- u32 EmcSwizzleRank0Byte0;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
- u32 EmcSwizzleRank0Byte1;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
- u32 EmcSwizzleRank0Byte2;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
- u32 EmcSwizzleRank0Byte3;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
- ////u32 EmcSwizzleRank1ByteCfg;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
- u32 EmcSwizzleRank1Byte0;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
- u32 EmcSwizzleRank1Byte1;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
- u32 EmcSwizzleRank1Byte2;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
- u32 EmcSwizzleRank1Byte3;
-
- /* Specifies the value for EMC_TXDSRVTTGEN */
- u32 EmcTxdsrvttgen;
-
- /* Specifies the value for EMC_DATA_BRLSHFT_0 */
- u32 EmcDataBrlshft0;
- u32 EmcDataBrlshft1;
-
- u32 EmcDqsBrlshft0;
- u32 EmcDqsBrlshft1;
-
- u32 EmcCmdBrlshft0;
- u32 EmcCmdBrlshft1;
- u32 EmcCmdBrlshft2;
- u32 EmcCmdBrlshft3;
-
- u32 EmcQuseBrlshft0;
- u32 EmcQuseBrlshft1;
- u32 EmcQuseBrlshft2;
- u32 EmcQuseBrlshft3;
-
- u32 EmcDllCfg0;
- u32 EmcDllCfg1;
-
- u32 EmcPmcScratch1;
- u32 EmcPmcScratch2;
- u32 EmcPmcScratch3;
-
- u32 EmcPmacroPadCfgCtrl;
-
- u32 EmcPmacroVttgenCtrl0;
- u32 EmcPmacroVttgenCtrl1;
- u32 EmcPmacroVttgenCtrl2;
-
- u32 EmcPmacroBrickCtrlRfu1;
- u32 EmcPmacroCmdBrickCtrlFdpd;
- u32 EmcPmacroBrickCtrlRfu2;
- u32 EmcPmacroDataBrickCtrlFdpd;
- u32 EmcPmacroBgBiasCtrl0;
- u32 EmcPmacroDataPadRxCtrl;
- u32 EmcPmacroCmdPadRxCtrl;
- u32 EmcPmacroDataRxTermMode;
- u32 EmcPmacroCmdRxTermMode;
- u32 EmcPmacroDataPadTxCtrl;
- u32 EmcPmacroCommonPadTxCtrl;
- u32 EmcPmacroCmdPadTxCtrl;
- u32 EmcCfg3;
-
- u32 EmcPmacroTxPwrd0;
- u32 EmcPmacroTxPwrd1;
- u32 EmcPmacroTxPwrd2;
- u32 EmcPmacroTxPwrd3;
- u32 EmcPmacroTxPwrd4;
- u32 EmcPmacroTxPwrd5;
-
- u32 EmcConfigSampleDelay;
-
- u32 EmcPmacroBrickMapping0;
- u32 EmcPmacroBrickMapping1;
- u32 EmcPmacroBrickMapping2;
-
- u32 EmcPmacroTxSelClkSrc0;
- u32 EmcPmacroTxSelClkSrc1;
- u32 EmcPmacroTxSelClkSrc2;
- u32 EmcPmacroTxSelClkSrc3;
- u32 EmcPmacroTxSelClkSrc4;
- u32 EmcPmacroTxSelClkSrc5;
-
- u32 EmcPmacroDdllBypass;
-
- u32 EmcPmacroDdllPwrd0;
- u32 EmcPmacroDdllPwrd1;
- u32 EmcPmacroDdllPwrd2;
-
- u32 EmcPmacroCmdCtrl0;
- u32 EmcPmacroCmdCtrl1;
- u32 EmcPmacroCmdCtrl2;
-
- /* DRAM size information */
-
- /* Specifies the value for MC_EMEM_ADR_CFG */
- u32 McEmemAdrCfg;
- /* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
- u32 McEmemAdrCfgDev0;
- /* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
- u32 McEmemAdrCfgDev1;
- u32 McEmemAdrCfgChannelMask;
-
- /* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
- u32 McEmemAdrCfgBankMask0;
- /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
- u32 McEmemAdrCfgBankMask1;
- /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
- u32 McEmemAdrCfgBankMask2;
-
- /*
- * Specifies the value for MC_EMEM_CFG which holds the external memory
- * size (in KBytes)
- */
- u32 McEmemCfg;
-
- /* MC arbitration configuration */
-
- /* Specifies the value for MC_EMEM_ARB_CFG */
- u32 McEmemArbCfg;
- /* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
- u32 McEmemArbOutstandingReq;
-
- u32 McEmemArbRefpbHpCtrl;
- u32 McEmemArbRefpbBankCtrl;
-
- /* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
- u32 McEmemArbTimingRcd;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RP */
- u32 McEmemArbTimingRp;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RC */
- u32 McEmemArbTimingRc;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
- u32 McEmemArbTimingRas;
- /* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
- u32 McEmemArbTimingFaw;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
- u32 McEmemArbTimingRrd;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
- u32 McEmemArbTimingRap2Pre;
- /* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
- u32 McEmemArbTimingWap2Pre;
- /* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
- u32 McEmemArbTimingR2R;
- /* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
- u32 McEmemArbTimingW2W;
- /* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
- u32 McEmemArbTimingR2W;
- /* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
- u32 McEmemArbTimingW2R;
-
- u32 McEmemArbTimingRFCPB;
-
- /* Specifies the value for MC_EMEM_ARB_DA_TURNS */
- u32 McEmemArbDaTurns;
- /* Specifies the value for MC_EMEM_ARB_DA_COVERS */
- u32 McEmemArbDaCovers;
- /* Specifies the value for MC_EMEM_ARB_MISC0 */
- u32 McEmemArbMisc0;
- /* Specifies the value for MC_EMEM_ARB_MISC1 */
- u32 McEmemArbMisc1;
- u32 McEmemArbMisc2;
-
- /* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
- u32 McEmemArbRing1Throttle;
- /* Specifies the value for MC_EMEM_ARB_OVERRIDE */
- u32 McEmemArbOverride;
- /* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
- u32 McEmemArbOverride1;
- /* Specifies the value for MC_EMEM_ARB_RSV */
- u32 McEmemArbRsv;
-
- u32 McDaCfg0;
- u32 McEmemArbTimingCcdmw;
-
- /* Specifies the value for MC_CLKEN_OVERRIDE */
- u32 McClkenOverride;
-
- /* Specifies the value for MC_STAT_CONTROL */
- u32 McStatControl;
-
- /* Specifies the value for MC_VIDEO_PROTECT_BOM */
- u32 McVideoProtectBom;
- /* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
- u32 McVideoProtectBomAdrHi;
- /* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
- u32 McVideoProtectSizeMb;
- /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
- u32 McVideoProtectVprOverride;
- /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
- u32 McVideoProtectVprOverride1;
- /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
- u32 McVideoProtectGpuOverride0;
- /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
- u32 McVideoProtectGpuOverride1;
- /* Specifies the value for MC_SEC_CARVEOUT_BOM */
- u32 McSecCarveoutBom;
- /* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
- u32 McSecCarveoutAdrHi;
- /* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
- u32 McSecCarveoutSizeMb;
- /* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
- VIDEO_PROTECT_WRITEAccess */
- u32 McVideoProtectWriteAccess;
- /* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
- SEC_CARVEOUT_WRITEAccess */
- u32 McSecCarveoutProtectWriteAccess;
-
- /* Write-Protect Regions (WPR) */
- u32 McGeneralizedCarveout1Bom;
- u32 McGeneralizedCarveout1BomHi;
- u32 McGeneralizedCarveout1Size128kb;
- u32 McGeneralizedCarveout1Access0;
- u32 McGeneralizedCarveout1Access1;
- u32 McGeneralizedCarveout1Access2;
- u32 McGeneralizedCarveout1Access3;
- u32 McGeneralizedCarveout1Access4;
- u32 McGeneralizedCarveout1ForceInternalAccess0;
- u32 McGeneralizedCarveout1ForceInternalAccess1;
- u32 McGeneralizedCarveout1ForceInternalAccess2;
- u32 McGeneralizedCarveout1ForceInternalAccess3;
- u32 McGeneralizedCarveout1ForceInternalAccess4;
- u32 McGeneralizedCarveout1Cfg0;
-
- u32 McGeneralizedCarveout2Bom;
- u32 McGeneralizedCarveout2BomHi;
- u32 McGeneralizedCarveout2Size128kb;
- u32 McGeneralizedCarveout2Access0;
- u32 McGeneralizedCarveout2Access1;
- u32 McGeneralizedCarveout2Access2;
- u32 McGeneralizedCarveout2Access3;
- u32 McGeneralizedCarveout2Access4;
- u32 McGeneralizedCarveout2ForceInternalAccess0;
- u32 McGeneralizedCarveout2ForceInternalAccess1;
- u32 McGeneralizedCarveout2ForceInternalAccess2;
- u32 McGeneralizedCarveout2ForceInternalAccess3;
- u32 McGeneralizedCarveout2ForceInternalAccess4;
- u32 McGeneralizedCarveout2Cfg0;
-
- u32 McGeneralizedCarveout3Bom;
- u32 McGeneralizedCarveout3BomHi;
- u32 McGeneralizedCarveout3Size128kb;
- u32 McGeneralizedCarveout3Access0;
- u32 McGeneralizedCarveout3Access1;
- u32 McGeneralizedCarveout3Access2;
- u32 McGeneralizedCarveout3Access3;
- u32 McGeneralizedCarveout3Access4;
- u32 McGeneralizedCarveout3ForceInternalAccess0;
- u32 McGeneralizedCarveout3ForceInternalAccess1;
- u32 McGeneralizedCarveout3ForceInternalAccess2;
- u32 McGeneralizedCarveout3ForceInternalAccess3;
- u32 McGeneralizedCarveout3ForceInternalAccess4;
- u32 McGeneralizedCarveout3Cfg0;
-
- u32 McGeneralizedCarveout4Bom;
- u32 McGeneralizedCarveout4BomHi;
- u32 McGeneralizedCarveout4Size128kb;
- u32 McGeneralizedCarveout4Access0;
- u32 McGeneralizedCarveout4Access1;
- u32 McGeneralizedCarveout4Access2;
- u32 McGeneralizedCarveout4Access3;
- u32 McGeneralizedCarveout4Access4;
- u32 McGeneralizedCarveout4ForceInternalAccess0;
- u32 McGeneralizedCarveout4ForceInternalAccess1;
- u32 McGeneralizedCarveout4ForceInternalAccess2;
- u32 McGeneralizedCarveout4ForceInternalAccess3;
- u32 McGeneralizedCarveout4ForceInternalAccess4;
- u32 McGeneralizedCarveout4Cfg0;
-
- u32 McGeneralizedCarveout5Bom;
- u32 McGeneralizedCarveout5BomHi;
- u32 McGeneralizedCarveout5Size128kb;
- u32 McGeneralizedCarveout5Access0;
- u32 McGeneralizedCarveout5Access1;
- u32 McGeneralizedCarveout5Access2;
- u32 McGeneralizedCarveout5Access3;
- u32 McGeneralizedCarveout5Access4;
- u32 McGeneralizedCarveout5ForceInternalAccess0;
- u32 McGeneralizedCarveout5ForceInternalAccess1;
- u32 McGeneralizedCarveout5ForceInternalAccess2;
- u32 McGeneralizedCarveout5ForceInternalAccess3;
- u32 McGeneralizedCarveout5ForceInternalAccess4;
- u32 McGeneralizedCarveout5Cfg0;
-
- /* Specifies enable for CA training */
- u32 EmcCaTrainingEnable;
-
- /* Set if bit 6 select is greater than bit 7 select; uses aremc.
- spec packet SWIZZLE_BIT6_GT_BIT7 */
- u32 SwizzleRankByteEncode;
- /* Specifies enable and offset for patched boot ROM write */
- u32 BootRomPatchControl;
- /* Specifies data for patched boot ROM write */
- u32 BootRomPatchData;
-
- /* Specifies the value for MC_MTS_CARVEOUT_BOM */
- u32 McMtsCarveoutBom;
- /* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
- u32 McMtsCarveoutAdrHi;
- /* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
- u32 McMtsCarveoutSizeMb;
- /* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
- u32 McMtsCarveoutRegCtrl;
-
- /* End */
-};
-
-#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */
diff --git a/bdk/mem/sdram_lp0_param_t210b01.h b/bdk/mem/sdram_lp0_param_t210b01.h
deleted file mode 100644
index f987a1e..0000000
--- a/bdk/mem/sdram_lp0_param_t210b01.h
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- * Copyright (c) 2020 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.
- */
-
-#ifndef __TEGRA210B01_SDRAM_PARAM_H__
-#define __TEGRA210B01_SDRAM_PARAM_H__
-
-#include
-
-struct sdram_params_t210b01
-{
- /* Specifies the type of memory device */
- u32 memory_type;
-
- /* MC/EMC clock source configuration */
-
- /* Specifies the M value for PllM */
- u32 pllm_input_divider;
- /* Specifies the N value for PllM */
- u32 pllm_feedback_divider;
- /* Specifies the time to wait for PLLM to lock (in microseconds) */
- u32 pllm_stable_time;
- /* Specifies misc. control bits */
- u32 pllm_setup_control;
- /* Specifies the P value for PLLM */
- u32 pllm_post_divider;
- /* Specifies value for Charge Pump Gain Control */
- u32 pllm_kcp;
- /* Specifies VCO gain */
- u32 pllm_kvco;
- /* Spare BCT param */
- u32 emc_bct_spare0;
- /* Spare BCT param */
- u32 emc_bct_spare1;
- /* Spare BCT param */
- u32 emc_bct_spare2;
- /* Spare BCT param */
- u32 emc_bct_spare3;
- /* Spare BCT param */
- u32 emc_bct_spare4;
- /* Spare BCT param */
- u32 emc_bct_spare5;
- /* Spare BCT param */
- u32 emc_bct_spare6;
- /* Spare BCT param */
- u32 emc_bct_spare7;
- /* Spare BCT param */
- u32 emc_bct_spare8;
- /* Spare BCT param */
- u32 emc_bct_spare9;
- /* Spare BCT param */
- u32 emc_bct_spare10;
- /* Spare BCT param */
- u32 emc_bct_spare11;
- /* Spare BCT param */
- u32 emc_bct_spare12;
- /* Spare BCT param */
- u32 emc_bct_spare13;
- /* Spare BCT param */
- u32 emc_bct_spare_secure0;
- /* Spare BCT param */
- u32 emc_bct_spare_secure1;
- /* Spare BCT param */
- u32 emc_bct_spare_secure2;
- /* Spare BCT param */
- u32 emc_bct_spare_secure3;
- /* Spare BCT param */
- u32 emc_bct_spare_secure4;
- /* Spare BCT param */
- u32 emc_bct_spare_secure5;
- /* Spare BCT param */
- u32 emc_bct_spare_secure6;
- /* Spare BCT param */
- u32 emc_bct_spare_secure7;
- /* Spare BCT param */
- u32 emc_bct_spare_secure8;
- /* Spare BCT param */
- u32 emc_bct_spare_secure9;
- /* Spare BCT param */
- u32 emc_bct_spare_secure10;
- /* Spare BCT param */
- u32 emc_bct_spare_secure11;
- /* Spare BCT param */
- u32 emc_bct_spare_secure12;
- /* Spare BCT param */
- u32 emc_bct_spare_secure13;
- /* Spare BCT param */
- u32 emc_bct_spare_secure14;
- /* Spare BCT param */
- u32 emc_bct_spare_secure15;
- /* Spare BCT param */
- u32 emc_bct_spare_secure16;
- /* Spare BCT param */
- u32 emc_bct_spare_secure17;
- /* Spare BCT param */
- u32 emc_bct_spare_secure18;
- /* Spare BCT param */
- u32 emc_bct_spare_secure19;
- /* Spare BCT param */
- u32 emc_bct_spare_secure20;
- /* Spare BCT param */
- u32 emc_bct_spare_secure21;
- /* Spare BCT param */
- u32 emc_bct_spare_secure22;
- /* Spare BCT param */
- u32 emc_bct_spare_secure23;
-
- /* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
- u32 emc_clock_source;
- u32 emc_clock_source_dll;
-
- /* Defines possible override for PLLLM_MISC2 */
- u32 clk_rst_pllm_misc20_override;
- /* enables override for PLLLM_MISC2 */
- u32 clk_rst_pllm_misc20_override_enable;
- /* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
- u32 clear_clock2_mc1;
-
- /* Auto-calibration of EMC pads */
-
- /* Specifies the value for EMC_AUTO_CAL_INTERVAL */
- u32 emc_auto_cal_interval;
- /*
- * Specifies the value for EMC_AUTO_CAL_CONFIG
- * Note: Trigger bits are set by the SDRAM code.
- */
- u32 emc_auto_cal_config;
-
- /* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
- u32 emc_auto_cal_config2;
-
- /* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
- u32 emc_auto_cal_config3;
- u32 emc_auto_cal_config4;
- u32 emc_auto_cal_config5;
- u32 emc_auto_cal_config6;
- u32 emc_auto_cal_config7;
- u32 emc_auto_cal_config8;
- u32 emc_auto_cal_config9;
-
- /* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
- u32 emc_auto_cal_vref_sel0;
- u32 emc_auto_cal_vref_sel1;
-
- /* Specifies the value for EMC_AUTO_CAL_CHANNEL */
- u32 emc_auto_cal_channel;
-
- /* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
- u32 emc_pmacro_auto_cal_cfg0;
- u32 emc_pmacro_auto_cal_cfg1;
- u32 emc_pmacro_auto_cal_cfg2;
-
- u32 emc_pmacro_rx_term;
- u32 emc_pmacro_dq_tx_drive;
- u32 emc_pmacro_ca_tx_drive;
- u32 emc_pmacro_cmd_tx_drive;
- u32 emc_pmacro_auto_cal_common;
- u32 emc_pmacro_zcrtl;
-
- /*
- * Specifies the time for the calibration
- * to stabilize (in microseconds)
- */
- u32 emc_auto_cal_wait;
-
- u32 emc_xm2_comp_pad_ctrl;
- u32 emc_xm2_comp_pad_ctrl2;
- u32 emc_xm2_comp_pad_ctrl3;
-
- /*
- * DRAM size information
- * Specifies the value for EMC_ADR_CFG
- */
- u32 emc_adr_cfg;
-
- /*
- * Specifies the time to wait after asserting pin
- * CKE (in microseconds)
- */
- u32 emc_pin_program_wait;
- /* Specifies the extra delay before/after pin RESET/CKE command */
- u32 emc_pin_extra_wait;
-
- u32 emc_pin_gpio_enable;
- u32 emc_pin_gpio;
-
- /*
- * Specifies the extra delay after the first writing
- * of EMC_TIMING_CONTROL
- */
- u32 emc_timing_control_wait;
-
- /* Timing parameters required for the SDRAM */
-
- /* Specifies the value for EMC_RC */
- u32 emc_rc;
- /* Specifies the value for EMC_RFC */
- u32 emc_rfc;
-
- u32 emc_rfc_pb;
- u32 emc_ref_ctrl2;
-
- /* Specifies the value for EMC_RFC_SLR */
- u32 emc_rfc_slr;
- /* Specifies the value for EMC_RAS */
- u32 emc_ras;
- /* Specifies the value for EMC_RP */
- u32 emc_rp;
- /* Specifies the value for EMC_R2R */
- u32 emc_r2r;
- /* Specifies the value for EMC_W2W */
- u32 emc_w2w;
- /* Specifies the value for EMC_R2W */
- u32 emc_r2w;
- /* Specifies the value for EMC_W2R */
- u32 emc_w2r;
- /* Specifies the value for EMC_R2P */
- u32 emc_r2p;
- /* Specifies the value for EMC_W2P */
- u32 emc_w2p;
- /* Specifies the value for EMC_RD_RCD */
-
- u32 emc_tppd;
- u32 emc_trtm;
- u32 emc_twtm;
- u32 emc_tratm;
- u32 emc_twatm;
- u32 emc_tr2ref;
- u32 emc_ccdmw;
-
- u32 emc_rd_rcd;
- /* Specifies the value for EMC_WR_RCD */
- u32 emc_wr_rcd;
- /* Specifies the value for EMC_RRD */
- u32 emc_rrd;
- /* Specifies the value for EMC_REXT */
- u32 emc_rext;
- /* Specifies the value for EMC_WEXT */
- u32 emc_wext;
- /* Specifies the value for EMC_WDV */
- u32 emc_wdv;
-
- u32 emc_wdv_chk;
- u32 emc_wsv;
- u32 emc_wev;
-
- /* Specifies the value for EMC_WDV_MASK */
- u32 emc_wdv_mask;
-
- u32 emc_ws_duration;
- u32 emc_we_duration;
-
- /* Specifies the value for EMC_QUSE */
- u32 emc_quse;
- /* Specifies the value for EMC_QUSE_WIDTH */
- u32 emc_quse_width;
- /* Specifies the value for EMC_IBDLY */
- u32 emc_ibdly;
-
- u32 emc_obdly;
-
- /* Specifies the value for EMC_EINPUT */
- u32 emc_einput;
- /* Specifies the value for EMC_EINPUT_DURATION */
- u32 emc_einput_duration;
- /* Specifies the value for EMC_PUTERM_EXTRA */
- u32 emc_puterm_extra;
- /* Specifies the value for EMC_PUTERM_WIDTH */
- u32 emc_puterm_width;
-
- u32 emc_qrst;
- u32 emc_qsafe;
- u32 emc_rdv;
- u32 emc_rdv_mask;
-
- u32 emc_rdv_early;
- u32 emc_rdv_early_mask;
-
- /* Specifies the value for EMC_QPOP */
- u32 emc_qpop;
-
- /* Specifies the value for EMC_REFRESH */
- u32 emc_refresh;
- /* Specifies the value for EMC_BURST_REFRESH_NUM */
- u32 emc_burst_refresh_num;
- /* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
- u32 emc_prerefresh_req_cnt;
- /* Specifies the value for EMC_PDEX2WR */
- u32 emc_pdex2wr;
- /* Specifies the value for EMC_PDEX2RD */
- u32 emc_pdex2rd;
- /* Specifies the value for EMC_PCHG2PDEN */
- u32 emc_pchg2pden;
- /* Specifies the value for EMC_ACT2PDEN */
- u32 emc_act2pden;
- /* Specifies the value for EMC_AR2PDEN */
- u32 emc_ar2pden;
- /* Specifies the value for EMC_RW2PDEN */
- u32 emc_rw2pden;
-
- u32 emc_cke2pden;
- u32 emc_pdex2che;
- u32 emc_pdex2mrr;
-
- /* Specifies the value for EMC_TXSR */
- u32 emc_txsr;
- /* Specifies the value for EMC_TXSRDLL */
- u32 emc_txsr_dll;
- /* Specifies the value for EMC_TCKE */
- u32 emc_tcke;
- /* Specifies the value for EMC_TCKESR */
- u32 emc_tckesr;
- /* Specifies the value for EMC_TPD */
- u32 emc_tpd;
- /* Specifies the value for EMC_TFAW */
- u32 emc_tfaw;
- /* Specifies the value for EMC_TRPAB */
- u32 emc_trpab;
- /* Specifies the value for EMC_TCLKSTABLE */
- u32 emc_tclkstable;
- /* Specifies the value for EMC_TCLKSTOP */
- u32 emc_tclkstop;
- /* Specifies the value for EMC_TREFBW */
- u32 emc_trefbw;
-
- /* FBIO configuration values */
-
- /* Specifies the value for EMC_FBIO_CFG5 */
- u32 emc_fbio_cfg5;
- /* Specifies the value for EMC_FBIO_CFG7 */
- u32 emc_fbio_cfg7;
- u32 emc_fbio_cfg8;
-
- /* Command mapping for CMD brick 0 */
- u32 emc_cmd_mapping_cmd0_0;
- u32 emc_cmd_mapping_cmd0_1;
- u32 emc_cmd_mapping_cmd0_2;
- u32 emc_cmd_mapping_cmd1_0;
- u32 emc_cmd_mapping_cmd1_1;
- u32 emc_cmd_mapping_cmd1_2;
- u32 emc_cmd_mapping_cmd2_0;
- u32 emc_cmd_mapping_cmd2_1;
- u32 emc_cmd_mapping_cmd2_2;
- u32 emc_cmd_mapping_cmd3_0;
- u32 emc_cmd_mapping_cmd3_1;
- u32 emc_cmd_mapping_cmd3_2;
- u32 emc_cmd_mapping_byte;
-
- /* Specifies the value for EMC_FBIO_SPARE */
- u32 emc_fbio_spare;
-
- /* Specifies the value for EMC_CFG_RSV */
- u32 emc_cfg_rsv;
-
- /* MRS command values */
-
- /* Specifies the value for EMC_MRS */
- u32 emc_mrs;
- /* Specifies the MP0 command to initialize mode registers */
- u32 emc_emrs;
- /* Specifies the MP2 command to initialize mode registers */
- u32 emc_emrs2;
- /* Specifies the MP3 command to initialize mode registers */
- u32 emc_emrs3;
- /* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
- u32 emc_mrw1;
- /* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
- u32 emc_mrw2;
- /* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
- u32 emc_mrw3;
- /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
- u32 emc_mrw4;
-
- /* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
- u32 emc_mrw6;
- /* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
- u32 emc_mrw8;
- /* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
- u32 emc_mrw9;
- /* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
- u32 emc_mrw10;
- /* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
- u32 emc_mrw12;
- /* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
- u32 emc_mrw13;
- /* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
- u32 emc_mrw14;
-
- /*
- * Specifies the programming to extra LPDDR2 Mode Register
- * at cold boot
- */
- u32 emc_mrw_extra;
- /*
- * Specifies the programming to extra LPDDR2 Mode Register
- * at warm boot
- */
- u32 emc_warm_boot_mrw_extra;
- /*
- * Specify the enable of extra Mode Register programming at
- * warm boot
- */
- u32 emc_warm_boot_extramode_reg_write_enable;
- /*
- * Specify the enable of extra Mode Register programming at
- * cold boot
- */
- u32 emc_extramode_reg_write_enable;
-
- /* Specifies the EMC_MRW reset command value */
- u32 emc_mrw_reset_command;
- /* Specifies the EMC Reset wait time (in microseconds) */
- u32 emc_mrw_reset_ninit_wait;
- /* Specifies the value for EMC_MRS_WAIT_CNT */
- u32 emc_mrs_wait_cnt;
- /* Specifies the value for EMC_MRS_WAIT_CNT2 */
- u32 emc_mrs_wait_cnt2;
-
- /* EMC miscellaneous configurations */
-
- /* Specifies the value for EMC_CFG */
- u32 emc_cfg;
- /* Specifies the value for EMC_CFG_2 */
- u32 emc_cfg2;
- /* Specifies the pipe bypass controls */
- u32 emc_cfg_pipe;
-
- u32 emc_cfg_pipe_clk;
- u32 emc_fdpd_ctrl_cmd_no_ramp;
- u32 emc_cfg_update;
-
- /* Specifies the value for EMC_DBG */
- u32 emc_dbg;
-
- u32 emc_dbg_write_mux;
-
- /* Specifies the value for EMC_CMDQ */
- u32 emc_cmd_q;
- /* Specifies the value for EMC_MC2EMCQ */
- u32 emc_mc2emc_q;
- /* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
- u32 emc_dyn_self_ref_control;
-
- /* Specifies the value for MEM_INIT_DONE */
- u32 ahb_arbitration_xbar_ctrl_meminit_done;
-
- /* Specifies the value for EMC_CFG_DIG_DLL */
- u32 emc_cfg_dig_dll;
- u32 emc_cfg_dig_dll_1;
-
- /* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
- u32 emc_cfg_dig_dll_period;
- /* Specifies the value of *DEV_SELECTN of various EMC registers */
- u32 emc_dev_select;
-
- /* Specifies the value for EMC_SEL_DPD_CTRL */
- u32 emc_sel_dpd_ctrl;
-
- /* Pads trimmer delays */
- u32 emc_fdpd_ctrl_dq;
- u32 emc_fdpd_ctrl_cmd;
- u32 emc_pmacro_ib_vref_dq_0;
- u32 emc_pmacro_ib_vref_dq_1;
- u32 emc_pmacro_ib_vref_dqs_0;
- u32 emc_pmacro_ib_vref_dqs_1;
- u32 emc_pmacro_ib_rxrt;
- u32 emc_cfg_pipe1;
- u32 emc_cfg_pipe2;
-
- /* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
- u32 emc_pmacro_quse_ddll_rank0_0;
- u32 emc_pmacro_quse_ddll_rank0_1;
- u32 emc_pmacro_quse_ddll_rank0_2;
- u32 emc_pmacro_quse_ddll_rank0_3;
- u32 emc_pmacro_quse_ddll_rank0_4;
- u32 emc_pmacro_quse_ddll_rank0_5;
- u32 emc_pmacro_quse_ddll_rank1_0;
- u32 emc_pmacro_quse_ddll_rank1_1;
- u32 emc_pmacro_quse_ddll_rank1_2;
- u32 emc_pmacro_quse_ddll_rank1_3;
- u32 emc_pmacro_quse_ddll_rank1_4;
- u32 emc_pmacro_quse_ddll_rank1_5;
-
- u32 emc_pmacro_ob_ddll_long_dq_rank0_0;
- u32 emc_pmacro_ob_ddll_long_dq_rank0_1;
- u32 emc_pmacro_ob_ddll_long_dq_rank0_2;
- u32 emc_pmacro_ob_ddll_long_dq_rank0_3;
- u32 emc_pmacro_ob_ddll_long_dq_rank0_4;
- u32 emc_pmacro_ob_ddll_long_dq_rank0_5;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_0;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_1;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_2;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_3;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_4;
- u32 emc_pmacro_ob_ddll_long_dq_rank1_5;
-
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_0;
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_1;
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_2;
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_3;
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_4;
- u32 emc_pmacro_ob_ddll_long_dqs_rank0_5;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_0;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_1;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_2;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_3;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_4;
- u32 emc_pmacro_ob_ddll_long_dqs_rank1_5;
-
- u32 emc_pmacro_ib_ddll_long_dqs_rank0_0;
- u32 emc_pmacro_ib_ddll_long_dqs_rank0_1;
- u32 emc_pmacro_ib_ddll_long_dqs_rank0_2;
- u32 emc_pmacro_ib_ddll_long_dqs_rank0_3;
- u32 emc_pmacro_ib_ddll_long_dqs_rank1_0;
- u32 emc_pmacro_ib_ddll_long_dqs_rank1_1;
- u32 emc_pmacro_ib_ddll_long_dqs_rank1_2;
- u32 emc_pmacro_ib_ddll_long_dqs_rank1_3;
-
- u32 emc_pmacro_ddll_long_cmd_0;
- u32 emc_pmacro_ddll_long_cmd_1;
- u32 emc_pmacro_ddll_long_cmd_2;
- u32 emc_pmacro_ddll_long_cmd_3;
- u32 emc_pmacro_ddll_long_cmd_4;
- u32 emc_pmacro_ddll_short_cmd_0;
- u32 emc_pmacro_ddll_short_cmd_1;
- u32 emc_pmacro_ddll_short_cmd_2;
-
- u32 emc_pmacro_ddll_periodic_offset;
-
- /*
- * Specifies the delay after asserting CKE pin during a WarmBoot0
- * sequence (in microseconds)
- */
- u32 warm_boot_wait;
-
- /* Specifies the value for EMC_ODT_WRITE */
- u32 emc_odt_write;
-
- /* Periodic ZQ calibration */
-
- /*
- * Specifies the value for EMC_ZCAL_INTERVAL
- * Value 0 disables ZQ calibration
- */
- u32 emc_zcal_interval;
- /* Specifies the value for EMC_ZCAL_WAIT_CNT */
- u32 emc_zcal_wait_cnt;
- /* Specifies the value for EMC_ZCAL_MRW_CMD */
- u32 emc_zcal_mrw_cmd;
-
- /* DRAM initialization sequence flow control */
-
- /* Specifies the MRS command value for resetting DLL */
- u32 emc_mrs_reset_dll;
- /* Specifies the command for ZQ initialization of device 0 */
- u32 emc_zcal_init_dev0;
- /* Specifies the command for ZQ initialization of device 1 */
- u32 emc_zcal_init_dev1;
- /*
- * Specifies the wait time after programming a ZQ initialization
- * command (in microseconds)
- */
- u32 emc_zcal_init_wait;
- /*
- * Specifies the enable for ZQ calibration at cold boot [bit 0]
- * and warm boot [bit 1]
- */
- u32 emc_zcal_warm_cold_boot_enables;
-
- /*
- * Specifies the MRW command to LPDDR2 for ZQ calibration
- * on warmboot
- */
- /* Is issued to both devices separately */
- u32 emc_mrw_lpddr2zcal_warm_boot;
- /*
- * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
- * Is issued to both devices separately
- */
- u32 emc_zqcal_ddr3_warm_boot;
-
- u32 emc_zqcal_lpddr4_warm_boot;
-
- /*
- * Specifies the wait time for ZQ calibration on warmboot
- * (in microseconds)
- */
- u32 emc_zcal_warm_boot_wait;
- /*
- * Specifies the enable for DRAM Mode Register programming
- * at warm boot
- */
- u32 emc_mrs_warm_boot_enable;
- /*
- * Specifies the wait time after sending an MRS DLL reset command
- * in microseconds)
- */
- u32 emc_mrs_reset_dll_wait;
- /* Specifies the extra MRS command to initialize mode registers */
- u32 emc_mrs_extra;
- /* Specifies the extra MRS command at warm boot */
- u32 emc_warm_boot_mrs_extra;
- /* Specifies the EMRS command to enable the DDR2 DLL */
- u32 emc_emrs_ddr2_dll_enable;
- /* Specifies the MRS command to reset the DDR2 DLL */
- u32 emc_mrs_ddr2_dll_reset;
- /* Specifies the EMRS command to set OCD calibration */
- u32 emc_emrs_ddr2_ocd_calib;
- /*
- * Specifies the wait between initializing DDR and setting OCD
- * calibration (in microseconds)
- */
- u32 emc_ddr2_wait;
- /* Specifies the value for EMC_CLKEN_OVERRIDE */
- u32 emc_clken_override;
- /*
- * Specifies LOG2 of the extra refresh numbers after booting
- * Program 0 to disable
- */
- u32 emc_extra_refresh_num;
- /* Specifies the master override for all EMC clocks */
- u32 emc_clken_override_allwarm_boot;
- /* Specifies the master override for all MC clocks */
- u32 mc_clken_override_allwarm_boot;
- /* Specifies digital dll period, choosing between 4 to 64 ms */
- u32 emc_cfg_dig_dll_period_warm_boot;
-
- /* Pad controls */
-
- /* Specifies the value for PMC_VDDP_SEL */
- u32 pmc_vddp_sel;
- /* Specifies the wait time after programming PMC_VDDP_SEL */
- u32 pmc_vddp_sel_wait;
- /* Specifies the value for PMC_DDR_CFG */
- u32 pmc_ddr_cfg;
- /* Specifies the value for PMC_IO_DPD3_REQ */
- u32 pmc_io_dpd3_req;
- /* Specifies the wait time after programming PMC_IO_DPD3_REQ */
- u32 pmc_io_dpd3_req_wait;
-
- u32 pmc_io_dpd4_req_wait;
-
- /* Specifies the value for PMC_REG_SHORT */
- u32 pmc_reg_short;
- /* Specifies the value for PMC_NO_IOPOWER */
- u32 pmc_no_io_power;
-
- u32 pmc_ddr_ctrl_wait;
- u32 pmc_ddr_ctrl;
-
- /* Specifies the value for EMC_ACPD_CONTROL */
- u32 emc_acpd_control;
-
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
- u32 emc_swizzle_rank0_byte0;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
- u32 emc_swizzle_rank0_byte1;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
- u32 emc_swizzle_rank0_byte2;
- /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
- u32 emc_swizzle_rank0_byte3;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
- u32 emc_swizzle_rank1_byte0;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
- u32 emc_swizzle_rank1_byte1;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
- u32 emc_swizzle_rank1_byte2;
- /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
- u32 emc_swizzle_rank1_byte3;
-
- /* Specifies the value for EMC_TXDSRVTTGEN */
- u32 emc_txdsrvttgen;
-
- /* Specifies the value for EMC_DATA_BRLSHFT_0 */
- u32 emc_data_brlshft0;
- u32 emc_data_brlshft1;
-
- u32 emc_dqs_brlshft0;
- u32 emc_dqs_brlshft1;
-
- u32 emc_cmd_brlshft0;
- u32 emc_cmd_brlshft1;
- u32 emc_cmd_brlshft2;
- u32 emc_cmd_brlshft3;
-
- u32 emc_quse_brlshft0;
- u32 emc_quse_brlshft1;
- u32 emc_quse_brlshft2;
- u32 emc_quse_brlshft3;
-
- u32 emc_dll_cfg0;
- u32 emc_dll_cfg1;
-
- u32 emc_pmc_scratch1;
- u32 emc_pmc_scratch2;
- u32 emc_pmc_scratch3;
-
- u32 emc_pmacro_pad_cfg_ctrl;
-
- u32 emc_pmacro_vttgen_ctrl0;
- u32 emc_pmacro_vttgen_ctrl1;
- u32 emc_pmacro_vttgen_ctrl2;
- u32 emc_pmacro_dsr_vttgen_ctrl0;
- u32 emc_pmacro_brick_ctrl_rfu1;
- u32 emc_pmacro_cmd_brick_ctrl_fdpd;
- u32 emc_pmacro_brick_ctrl_rfu2;
- u32 emc_pmacro_data_brick_ctrl_fdpd;
- u32 emc_pmacro_bg_bias_ctrl0;
- u32 emc_pmacro_data_pad_rx_ctrl;
- u32 emc_pmacro_cmd_pad_rx_ctrl;
- u32 emc_pmacro_data_rx_term_mode;
- u32 emc_pmacro_cmd_rx_term_mode;
- u32 emc_pmacro_data_pad_tx_ctrl;
- u32 emc_pmacro_cmd_pad_tx_ctrl;
- u32 emc_cfg3;
-
- u32 emc_pmacro_tx_pwrd0;
- u32 emc_pmacro_tx_pwrd1;
- u32 emc_pmacro_tx_pwrd2;
- u32 emc_pmacro_tx_pwrd3;
- u32 emc_pmacro_tx_pwrd4;
- u32 emc_pmacro_tx_pwrd5;
-
- u32 emc_config_sample_delay;
-
- u32 emc_pmacro_brick_mapping0;
- u32 emc_pmacro_brick_mapping1;
- u32 emc_pmacro_brick_mapping2;
-
- u32 emc_pmacro_tx_sel_clk_src0;
- u32 emc_pmacro_tx_sel_clk_src1;
- u32 emc_pmacro_tx_sel_clk_src2;
- u32 emc_pmacro_tx_sel_clk_src3;
- u32 emc_pmacro_tx_sel_clk_src4;
- u32 emc_pmacro_tx_sel_clk_src5;
-
- u32 emc_pmacro_perbit_fgcg_ctrl0;
- u32 emc_pmacro_perbit_fgcg_ctrl1;
- u32 emc_pmacro_perbit_fgcg_ctrl2;
- u32 emc_pmacro_perbit_fgcg_ctrl3;
- u32 emc_pmacro_perbit_fgcg_ctrl4;
- u32 emc_pmacro_perbit_fgcg_ctrl5;
- u32 emc_pmacro_perbit_rfu_ctrl0;
- u32 emc_pmacro_perbit_rfu_ctrl1;
- u32 emc_pmacro_perbit_rfu_ctrl2;
- u32 emc_pmacro_perbit_rfu_ctrl3;
- u32 emc_pmacro_perbit_rfu_ctrl4;
- u32 emc_pmacro_perbit_rfu_ctrl5;
- u32 emc_pmacro_perbit_rfu1_ctrl0;
- u32 emc_pmacro_perbit_rfu1_ctrl1;
- u32 emc_pmacro_perbit_rfu1_ctrl2;
- u32 emc_pmacro_perbit_rfu1_ctrl3;
- u32 emc_pmacro_perbit_rfu1_ctrl4;
- u32 emc_pmacro_perbit_rfu1_ctrl5;
-
- u32 emc_pmacro_data_pi_ctrl;
- u32 emc_pmacro_cmd_pi_ctrl;
-
- u32 emc_pmacro_ddll_bypass;
-
- u32 emc_pmacro_ddll_pwrd0;
- u32 emc_pmacro_ddll_pwrd1;
- u32 emc_pmacro_ddll_pwrd2;
-
- u32 emc_pmacro_cmd_ctrl0;
- u32 emc_pmacro_cmd_ctrl1;
- u32 emc_pmacro_cmd_ctrl2;
-
- /* DRAM size information */
-
- /* Specifies the value for MC_EMEM_ADR_CFG */
- u32 mc_emem_adr_cfg;
- /* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
- u32 mc_emem_adr_cfg_dev0;
- /* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
- u32 mc_emem_adr_cfg_dev1;
-
- u32 mc_emem_adr_cfg_channel_mask;
-
- /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
- u32 mc_emem_adr_cfg_bank_mask0;
- /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
- u32 mc_emem_adr_cfg_bank_mask1;
- /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
- u32 mc_emem_adr_cfg_bank_mask2;
-
- /*
- * Specifies the value for MC_EMEM_CFG which holds the external memory
- * size (in KBytes)
- */
- u32 mc_emem_cfg;
-
- /* MC arbitration configuration */
-
- /* Specifies the value for MC_EMEM_ARB_CFG */
- u32 mc_emem_arb_cfg;
- /* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
- u32 mc_emem_arb_outstanding_req;
-
- u32 emc_emem_arb_refpb_hp_ctrl;
- u32 emc_emem_arb_refpb_bank_ctrl;
-
- /* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
- u32 mc_emem_arb_timing_rcd;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RP */
- u32 mc_emem_arb_timing_rp;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RC */
- u32 mc_emem_arb_timing_rc;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
- u32 mc_emem_arb_timing_ras;
- /* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
- u32 mc_emem_arb_timing_faw;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
- u32 mc_emem_arb_timing_rrd;
- /* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
- u32 mc_emem_arb_timing_rap2pre;
- /* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
- u32 mc_emem_arb_timing_wap2pre;
- /* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
- u32 mc_emem_arb_timing_r2r;
- /* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
- u32 mc_emem_arb_timing_w2w;
- /* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
- u32 mc_emem_arb_timing_r2w;
- /* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
- u32 mc_emem_arb_timing_w2r;
-
- u32 mc_emem_arb_timing_rfcpb;
-
- /* Specifies the value for MC_EMEM_ARB_DA_TURNS */
- u32 mc_emem_arb_da_turns;
- /* Specifies the value for MC_EMEM_ARB_DA_COVERS */
- u32 mc_emem_arb_da_covers;
- /* Specifies the value for MC_EMEM_ARB_MISC0 */
- u32 mc_emem_arb_misc0;
- /* Specifies the value for MC_EMEM_ARB_MISC1 */
- u32 mc_emem_arb_misc1;
- u32 mc_emem_arb_misc2;
-
- /* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
- u32 mc_emem_arb_ring1_throttle;
- /* Specifies the value for MC_EMEM_ARB_OVERRIDE */
- u32 mc_emem_arb_override;
- /* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
- u32 mc_emem_arb_override1;
- /* Specifies the value for MC_EMEM_ARB_RSV */
- u32 mc_emem_arb_rsv;
-
- u32 mc_da_cfg0;
- u32 mc_emem_arb_timing_ccdmw;
-
- /* Specifies the value for MC_CLKEN_OVERRIDE */
- u32 mc_clken_override;
-
- /* Specifies the value for MC_STAT_CONTROL */
- u32 mc_stat_control;
- /* Specifies the value for MC_VIDEO_PROTECT_BOM */
- u32 mc_video_protect_bom;
- /* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
- u32 mc_video_protect_bom_adr_hi;
- /* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
- u32 mc_video_protect_size_mb;
- /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
- u32 mc_video_protect_vpr_override;
- /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
- u32 mc_video_protect_vpr_override1;
- /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
- u32 mc_video_protect_gpu_override0;
- /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
- u32 mc_video_protect_gpu_override1;
- /* Specifies the value for MC_SEC_CARVEOUT_BOM */
- u32 mc_sec_carveout_bom;
- /* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
- u32 mc_sec_carveout_adr_hi;
- /* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
- u32 mc_sec_carveout_size_mb;
- /* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
- u32 mc_video_protect_write_access;
- /* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
- u32 mc_sec_carveout_protect_write_access;
-
- u32 mc_generalized_carveout1_bom;
- u32 mc_generalized_carveout1_bom_hi;
- u32 mc_generalized_carveout1_size_128kb;
- u32 mc_generalized_carveout1_access0;
- u32 mc_generalized_carveout1_access1;
- u32 mc_generalized_carveout1_access2;
- u32 mc_generalized_carveout1_access3;
- u32 mc_generalized_carveout1_access4;
- u32 mc_generalized_carveout1_force_internal_access0;
- u32 mc_generalized_carveout1_force_internal_access1;
- u32 mc_generalized_carveout1_force_internal_access2;
- u32 mc_generalized_carveout1_force_internal_access3;
- u32 mc_generalized_carveout1_force_internal_access4;
- u32 mc_generalized_carveout1_cfg0;
-
- u32 mc_generalized_carveout2_bom;
- u32 mc_generalized_carveout2_bom_hi;
- u32 mc_generalized_carveout2_size_128kb;
- u32 mc_generalized_carveout2_access0;
- u32 mc_generalized_carveout2_access1;
- u32 mc_generalized_carveout2_access2;
- u32 mc_generalized_carveout2_access3;
- u32 mc_generalized_carveout2_access4;
- u32 mc_generalized_carveout2_force_internal_access0;
- u32 mc_generalized_carveout2_force_internal_access1;
- u32 mc_generalized_carveout2_force_internal_access2;
- u32 mc_generalized_carveout2_force_internal_access3;
- u32 mc_generalized_carveout2_force_internal_access4;
- u32 mc_generalized_carveout2_cfg0;
-
- u32 mc_generalized_carveout3_bom;
- u32 mc_generalized_carveout3_bom_hi;
- u32 mc_generalized_carveout3_size_128kb;
- u32 mc_generalized_carveout3_access0;
- u32 mc_generalized_carveout3_access1;
- u32 mc_generalized_carveout3_access2;
- u32 mc_generalized_carveout3_access3;
- u32 mc_generalized_carveout3_access4;
- u32 mc_generalized_carveout3_force_internal_access0;
- u32 mc_generalized_carveout3_force_internal_access1;
- u32 mc_generalized_carveout3_force_internal_access2;
- u32 mc_generalized_carveout3_force_internal_access3;
- u32 mc_generalized_carveout3_force_internal_access4;
- u32 mc_generalized_carveout3_cfg0;
-
- u32 mc_generalized_carveout4_bom;
- u32 mc_generalized_carveout4_bom_hi;
- u32 mc_generalized_carveout4_size_128kb;
- u32 mc_generalized_carveout4_access0;
- u32 mc_generalized_carveout4_access1;
- u32 mc_generalized_carveout4_access2;
- u32 mc_generalized_carveout4_access3;
- u32 mc_generalized_carveout4_access4;
- u32 mc_generalized_carveout4_force_internal_access0;
- u32 mc_generalized_carveout4_force_internal_access1;
- u32 mc_generalized_carveout4_force_internal_access2;
- u32 mc_generalized_carveout4_force_internal_access3;
- u32 mc_generalized_carveout4_force_internal_access4;
- u32 mc_generalized_carveout4_cfg0;
-
- u32 mc_generalized_carveout5_bom;
- u32 mc_generalized_carveout5_bom_hi;
- u32 mc_generalized_carveout5_size_128kb;
- u32 mc_generalized_carveout5_access0;
- u32 mc_generalized_carveout5_access1;
- u32 mc_generalized_carveout5_access2;
- u32 mc_generalized_carveout5_access3;
- u32 mc_generalized_carveout5_access4;
- u32 mc_generalized_carveout5_force_internal_access0;
- u32 mc_generalized_carveout5_force_internal_access1;
- u32 mc_generalized_carveout5_force_internal_access2;
- u32 mc_generalized_carveout5_force_internal_access3;
- u32 mc_generalized_carveout5_force_internal_access4;
- u32 mc_generalized_carveout5_cfg0;
-
- /* Specifies enable for CA training */
- u32 emc_ca_training_enable;
- /* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
- u32 swizzle_rank_byte_encode;
- /* Specifies enable and offset for patched boot rom write */
- u32 boot_rom_patch_control;
- /* Specifies data for patched boot rom write */
- u32 boot_rom_patch_data;
-
- /* Specifies the value for MC_MTS_CARVEOUT_BOM */
- u32 mc_mts_carveout_bom;
- /* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
- u32 mc_mts_carveout_adr_hi;
- /* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
- u32 mc_mts_carveout_size_mb;
- /* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
- u32 mc_mts_carveout_reg_ctrl;
-
- u32 mc_untranslated_region_check;
-
- /* Just a place holder for special usage when there is no BCT for certain registers */
- u32 bct_na;
-};
-
-#endif
diff --git a/bdk/mem/sdram_param_t210b01.h b/bdk/mem/sdram_param_t210b01.h
index 8bcbed3..f7b956c 100644
--- a/bdk/mem/sdram_param_t210b01.h
+++ b/bdk/mem/sdram_param_t210b01.h
@@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
- /* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_trtm;
@@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
u32 emc_tr2ref;
u32 emc_ccdmw;
+ /* Specifies the value for EMC_RD_RCD */
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;
diff --git a/bdk/mem/smmu.c b/bdk/mem/smmu.c
index 6ee99b9..65b85aa 100644
--- a/bdk/mem/smmu.c
+++ b/bdk/mem/smmu.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011
+ * Copyright (c) 2018-2024 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,155 +18,228 @@
#include
+#include
#include
+#include
#include
#include
#include
-#include
-#include
+#include
-bool smmu_used = false;
-u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;
+/*! SMMU register defines */
+#define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
+#define SMMU_ENABLE BIT(31)
+#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
+#define SMMU_TLB_RR_ARBITRATION BIT(28)
+#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
+#define SMMU_TLB_STATS_ENABLE BIT(31)
+#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
+#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
+#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
+#define SMUU_PTC_CACHE_ENABLE BIT(29)
+#define SMUU_PTC_STATS_ENABLE BIT(31)
-//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;
-u8 smmu_payload[] __attribute__((aligned(16))) = {
- 0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010
+/*! Page table defines */
+#define SMMU_4MB_REGION 0
+#define SMMU_PAGE_TABLE 1
+#define SMMU_PDIR_COUNT 1024
+#define SMMU_PTBL_COUNT 1024
+#define SMMU_PAGE_SHIFT 12u
+#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
+#define SMMU_PDN_SHIFT 22u
+#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
+#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
+#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
+#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
+#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;
+
+// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
+static const 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]
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
- 0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0
- 0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
- 0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
- 0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
- 0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
- 0x00, 0x00, 0x00, 0x00, // 0x2C:
- 0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
- 0x00, 0x00, 0x00, 0x00 // 0x34:
+ 0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
};
-void *page_alloc(u32 num)
+void *smmu_page_zalloc(u32 num)
{
- u8 *res = _pageheap;
- _pageheap += 0x1000 * num;
- memset(res, 0, 0x1000 * num);
- return res;
+ void *page = smmu_heap;
+ memset(page, 0, SZ_PAGE * num);
+
+ smmu_heap += SZ_PAGE * num;
+
+ return page;
}
-u32 *smmu_alloc_pdir()
+static pde_t *_smmu_pdir_alloc()
{
- u32 *pdir = (u32 *)page_alloc(1);
- for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
- pdir[pdn] = _PDE_VACANT(pdn);
+ pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
+
+ // Initialize pdes with no permissions.
+ for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
+ pdir[pdn].huge.page = pdn;
+
return pdir;
}
-void smmu_flush_regs()
+static void _smmu_flush_regs()
{
(void)MC(MC_SMMU_PTB_DATA);
}
void smmu_flush_all()
{
+
+ // Flush the entire page table cache.
MC(MC_SMMU_PTC_FLUSH) = 0;
- smmu_flush_regs();
+ _smmu_flush_regs();
+
+ // Flush the entire table.
MC(MC_SMMU_TLB_FLUSH) = 0;
- smmu_flush_regs();
+ _smmu_flush_regs();
}
-void smmu_init(u32 secmon_base)
+void smmu_init()
{
- MC(MC_SMMU_PTB_ASID) = 0;
- MC(MC_SMMU_PTB_DATA) = 0;
- MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
- MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
- MC(MC_SMMU_PTC_FLUSH) = 0;
- MC(MC_SMMU_TLB_FLUSH) = 0;
-
- // Set the secmon address
- *(u32 *)(smmu_payload + 0x30) = secmon_base;
+ MC(MC_SMMU_PTB_ASID) = 0;
+ MC(MC_SMMU_PTB_DATA) = 0;
+ MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
+ MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
+ MC(MC_SMMU_PTC_FLUSH) = 0;
+ MC(MC_SMMU_TLB_FLUSH) = 0;
}
void smmu_enable()
{
- if (smmu_used)
+ static bool enabled = false;
+
+ if (enabled)
return;
- ccplex_boot_cpu0((u32)smmu_payload);
- smmu_used = true;
- msleep(150);
+ // 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();
+
+ enabled = true;
}
-bool smmu_is_used()
+void smmu_reset_heap()
{
- return smmu_used;
+ smmu_heap = (void *)SMMU_HEAP_ADDR;
}
-void smmu_exit()
+void *smmu_init_domain(u32 dev_base, u32 asid)
{
- *(u32 *)(smmu_payload + 0x14) = _NOP();
-}
-
-u32 *smmu_init_domain4(u32 dev_base, u32 asid)
-{
- u32 *pdir = smmu_alloc_pdir();
+ void *ptb = _smmu_pdir_alloc();
MC(MC_SMMU_PTB_ASID) = asid;
- MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);
- smmu_flush_regs();
+ MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
+ _smmu_flush_regs();
- MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);
- smmu_flush_regs();
+ // Use the same macro for both quad and single domains. Reserved bits are not set anyway.
+ MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
+ _smmu_flush_regs();
- return pdir;
+ return ptb;
}
-u32 *smmu_get_pte(u32 *pdir, u32 iova)
+void smmu_deinit_domain(u32 dev_base, u32 asid)
{
- u32 ptn = SMMU_ADDR_TO_PFN(iova);
- u32 pdn = SMMU_ADDR_TO_PDN(iova);
- u32 *ptbl;
+ MC(MC_SMMU_PTB_ASID) = asid;
+ MC(MC_SMMU_PTB_DATA) = 0;
+ MC(dev_base) = 0;
+ _smmu_flush_regs();
+}
- if (pdir[pdn] != _PDE_VACANT(pdn))
- ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);
+void smmu_domain_bypass(u32 dev_base, bool bypass)
+{
+ if (bypass)
+ {
+ smmu_flush_all();
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
+ MC(dev_base) &= ~SMMU_ENABLE;
+ }
else
{
- ptbl = (u32 *)page_alloc(1);
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
+ MC(dev_base) |= SMMU_ENABLE;
+ smmu_flush_all();
+ }
+ _smmu_flush_regs();
+}
+
+static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
+{
+ u32 pdn = SMMU_ADDR_TO_PDN(iova);
+ pte_t *ptbl;
+
+ // Get 4MB page table or initialize one.
+ if (pdir[pdn].tbl.attr)
+ ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
+ else
+ {
+ // Allocate page table.
+ ptbl = (pte_t *)smmu_page_zalloc(1);
+
+ // Get address.
u32 addr = SMMU_PDN_TO_ADDR(pdn);
- for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
- ptbl[pn] = _PTE_VACANT(addr);
- pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);
+
+ // Initialize page table with no permissions.
+ for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
+ ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
+
+ // Set page table to the page directory.
+ pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
+ pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
+ pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
+
smmu_flush_all();
}
- return &ptbl[ptn % SMMU_PTBL_COUNT];
+ return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
}
-void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)
+void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
{
- for (int i = 0; i < cnt; i++)
+ // Map pages to page table entries. VA/PA should be aligned to 4KB.
+ for (u32 i = 0; i < pages; i++)
{
- u32 *pte = smmu_get_pte(pdir, addr);
- *pte = SMMU_ADDR_TO_PFN(page) | attr;
- addr += 0x1000;
- page += 0x1000;
+ pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
+
+ pte->page = SMMU_ADDR_TO_PFN(iopa);
+ pte->attr = attr;
+
+ iova += SZ_PAGE;
+ iopa += SZ_PAGE;
}
+
smmu_flush_all();
}
-u32 *smmu_init_for_tsec()
+void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
{
- return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);
-}
+ pde_t *pdir = (pde_t *)ptb;
-void smmu_deinit_for_tsec()
-{
- MC(MC_SMMU_PTB_ASID) = 1;
- MC(MC_SMMU_PTB_DATA) = 0;
- MC(MC_SMMU_TSEC_ASID) = 0;
- smmu_flush_regs();
-}
+ // Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
+ for (u32 i = 0; i < regions; i++)
+ {
+ u32 pdn = SMMU_ADDR_TO_PDN(iova);
+ pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
+ pdir[pdn].huge.next = SMMU_4MB_REGION;
+ pdir[pdn].huge.attr = attr;
+ iova += SZ_4M;
+ iopa += SZ_4M;
+ }
+
+ smmu_flush_all();
+}
diff --git a/bdk/mem/smmu.h b/bdk/mem/smmu.h
index 7846253..e45a672 100644
--- a/bdk/mem/smmu.h
+++ b/bdk/mem/smmu.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018-2024 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,
@@ -14,69 +15,57 @@
* along with this program. If not, see .
*/
+#include
+
#include
-#define SMMU_HEAP_ADDR 0xA0000000
-
-#define MC_INTSTATUS 0x0
-#define MC_INTMASK 0x4
-#define MC_ERR_STATUS 0x8
-#define MC_ERR_ADR 0xc
-#define MC_SMMU_CONFIG 0x10
-#define MC_SMMU_TLB_CONFIG 0x14
-#define MC_SMMU_PTC_CONFIG 0x18
-#define MC_SMMU_PTB_ASID 0x1c
-#define MC_SMMU_PTB_DATA 0x20
-#define MC_SMMU_TLB_FLUSH 0x30
-#define MC_SMMU_PTC_FLUSH 0x34
-#define MC_SMMU_ASID_SECURITY 0x38
+#define MC_SMMU_AVPC_ASID 0x23C
#define MC_SMMU_TSEC_ASID 0x294
-#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
-#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
-#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
-#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
-#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
-#define SMMU_PDE_NEXT_SHIFT 28
-#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
-#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
-#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
-#define SMMU_PAGE_SHIFT 12
-#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
-#define SMMU_PDIR_COUNT 1024
-#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
-#define SMMU_PTBL_COUNT 1024
-#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
-#define SMMU_PDIR_SHIFT 12
-#define SMMU_PDE_SHIFT 12
-#define SMMU_PTE_SHIFT 12
-#define SMMU_PFN_MASK 0x000FFFFF
-#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
-#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
-#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
-#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
-#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
-#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
-#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
-#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
-#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
-#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
-#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
-#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
-#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
-#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
-#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
+#define SMMU_NS BIT(0)
+#define SMMU_WRITE BIT(1)
+#define SMMU_READ BIT(2)
+#define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
-void *page_alloc(u32 num);
-u32 *smmu_alloc_pdir();
-void smmu_flush_regs();
-void smmu_flush_all();
-void smmu_init(u32 secmon_base);
-void smmu_enable();
-bool smmu_is_used();
-void smmu_exit();
-u32 *smmu_init_domain4(u32 dev_base, u32 asid);
-u32 *smmu_get_pte(u32 *pdir, u32 iova);
-void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);
-u32 *smmu_init_for_tsec();
-void smmu_deinit_for_tsec();
+typedef struct _pde_t {
+ union {
+ union {
+ struct {
+ u32 table:22;
+ u32 rsvd:6;
+ u32 next:1;
+ u32 attr:3;
+ } tbl;
+
+ struct {
+ u32 rsvd_:10;
+ u32 page:12;
+ u32 rsvd:6;
+ u32 next:1;
+ u32 attr:3;
+ } huge;
+ };
+
+ u32 pde;
+ };
+} pde_t;
+
+typedef struct _pte_t {
+ u32 page:22;
+ u32 rsvd:7;
+ u32 attr:3;
+} pte_t;
+
+static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
+static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
+
+void *smmu_page_zalloc(u32 num);
+void smmu_flush_all();
+void smmu_init();
+void smmu_enable();
+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_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);
diff --git a/bdk/memory_map.h b/bdk/memory_map.h
index 385723b..c687f2c 100644
--- a/bdk/memory_map.h
+++ b/bdk/memory_map.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2021 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,61 +17,76 @@
#ifndef _MEMORY_MAP_H_
#define _MEMORY_MAP_H_
-//#define IPL_STACK_TOP 0x4003FF00
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
/* --- IPL: 0x40008000 - 0x40028000 --- */
#define LDR_LOAD_ADDR 0x40007000
#define IPL_LOAD_ADDR 0x40008000
-#define IPL_SZ_MAX 0x20000 // 128KB.
+#define IPL_SZ_MAX SZ_128K
-/* --- XUSB EP context and TRB ring buffers --- */
-#define XUSB_RING_ADDR 0x40020000
+#define XUSB_RING_ADDR 0x40020000 // XUSB EP context and TRB ring buffers.
-#define SECMON_MIN_START 0x4002B000
+#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
-#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
+
+/* start.S / exception_handlers.S */
+#define SYS_STACK_TOP_INIT 0x4003FF00
+#define FIQ_STACK_TOP 0x40040000
+#define IRQ_STACK_TOP 0x40040000
+#define IPL_RELOC_ADDR 0x4003FF00
+#define IPL_RELOC_SZ 0x10
+#define EXCP_STORAGE_ADDR 0x4003FFF0
+#define EXCP_STORAGE_SZ 0x10
/* --- DRAM START --- */
#define DRAM_START 0x80000000
-#define HOS_RSVD 0x1000000 // Do not write anything in this area.
+#define HOS_RSVD SZ_16M // Do not write anything in this area.
#define NYX_LOAD_ADDR 0x81000000
-#define NYX_SZ_MAX 0x1000000 // 16MB
+#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 0x20000000 // 512MB.
+#define IPL_HEAP_SZ (SZ_512M - SZ_64M)
+
+#define SMMU_HEAP_ADDR 0xA0000000
/* --- Gap: 1040MB 0xA4000000 - 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.
// L4T Kernel Panic Storage (PSTORE).
#define PSTORE_ADDR 0xB0000000
-#define PSTORE_SZ 0x200000 // 2MB.
+#define PSTORE_SZ SZ_2M
//#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 0x8000000 // 128MB.
+#define SDMMC_UP_BUF_SZ SZ_128M
// Nyx buffers.
#define NYX_STORAGE_ADDR 0xED000000
#define NYX_RES_ADDR 0xEE000000
-#define NYX_RES_SZ 0x1000000 // 16MB.
+#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
-#define SDMMC_DMA_BUF_SZ 0x1000000 // 16MB (4MB currently used).
+#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
// Nyx LvGL buffers.
#define NYX_LV_VDB_ADR 0xF1000000
@@ -88,22 +103,19 @@
#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
-// NX BIS driver sector cache.
-#define NX_BIS_CACHE_ADDR 0xFEE00000
-#define NX_BIS_CACHE_SZ 0x100000
-
// USB buffers.
#define USBD_ADDR 0xFEF00000
#define USB_DESCRIPTOR_ADDR 0xFEF40000
#define USB_EP_CONTROL_BUF_ADDR 0xFEF80000
#define USB_EP_BULK_IN_BUF_ADDR 0xFF000000
#define USB_EP_BULK_OUT_BUF_ADDR 0xFF800000
-#define USB_EP_BULK_OUT_MAX_XFER 0x800000
+#define USB_EP_BULK_OUT_MAX_XFER SZ_8M
// #define EXT_PAYLOAD_ADDR 0xC0000000
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
diff --git a/bdk/module.h b/bdk/module.h
index 6ec303f..acc048c 100644
--- a/bdk/module.h
+++ b/bdk/module.h
@@ -21,10 +21,13 @@
#include
#include
+#define IANOS_EXT0 0x304E4149
+
// Module Callback
typedef void (*cbMainModule_t)(const char *s);
typedef void (*memcpy_t)(void *, void *, size_t);
typedef void (*memset_t)(void *, int, size_t);
+typedef int (*reg_voltage_set_t)(u32, u32);
typedef struct _bdkParams_t
{
@@ -33,6 +36,8 @@ typedef struct _bdkParams_t
heap_t *sharedHeap;
memcpy_t memcpy;
memset_t memset;
+ u32 extension_magic;
+ reg_voltage_set_t reg_voltage_set;
} *bdkParams_t;
// Module Entrypoint
diff --git a/bdk/power/bm92t36.c b/bdk/power/bm92t36.c
index d1496f7..371ed04 100644
--- a/bdk/power/bm92t36.c
+++ b/bdk/power/bm92t36.c
@@ -1,7 +1,7 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
- * Copyright (c) 2020 CTCaer
+ * Copyright (c) 2020-2023 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,
@@ -73,18 +73,23 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
if (inserted)
{
+ memset(buf, 0, sizeof(buf));
_bm92t36_read_reg(buf, 2, STATUS1_REG);
- *inserted = buf[0] & STATUS1_INSERT ? true : false;
+ *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);
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
+ if (usb_pd->pdo_no > 7)
+ usb_pd->pdo_no = 7;
+
for (u32 i = 0; i < usb_pd->pdo_no; i++)
{
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
diff --git a/bdk/power/bq24193.c b/bdk/power/bq24193.c
index 2b2e744..5194279 100644
--- a/bdk/power/bq24193.c
+++ b/bdk/power/bq24193.c
@@ -29,127 +29,128 @@ 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;
}
diff --git a/bdk/power/bq24193.h b/bdk/power/bq24193.h
index 1b6e717..399e225 100644
--- a/bdk/power/bq24193.h
+++ b/bdk/power/bq24193.h
@@ -28,7 +28,7 @@
// REG 1 masks.
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
-#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
+#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) // 3000uV HOS default.
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
#define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1<<4)
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
diff --git a/bdk/power/max17050.c b/bdk/power/max17050.c
index a561724..8c4f658 100644
--- a/bdk/power/max17050.c
+++ b/bdk/power/max17050.c
@@ -24,7 +24,7 @@
#include "max17050.h"
#include
-#include
+#include
#define BASE_SNS_UOHM 5000
@@ -279,3 +279,26 @@ int max17050_fix_configuration()
return 0;
}
+
+void max17050_dump_regs(void *buf)
+{
+ u16 *buff = (u16 *)buf;
+
+ // Unlock model table.
+ u16 unlock = 0x59;
+ i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
+ unlock = 0xC4;
+ i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
+
+ // Dump all battery fuel gauge registers.
+ for (u32 i = 0; i < 0x100; i++)
+ {
+ buff[i] = max17050_get_reg(i);
+ msleep(1);
+ }
+
+ // Lock model table.
+ unlock = 0;
+ i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
+ i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
+}
diff --git a/bdk/power/max17050.h b/bdk/power/max17050.h
index a9b3d37..438f55a 100644
--- a/bdk/power/max17050.h
+++ b/bdk/power/max17050.h
@@ -130,8 +130,9 @@ enum MAX17050_reg {
MAX17050_VFSOC = 0xFF,
};
-int max17050_get_property(enum MAX17050_reg reg, int *value);
-int max17050_fix_configuration();
-u32 max17050_get_cached_batt_volt();
+int max17050_get_property(enum MAX17050_reg reg, int *value);
+int max17050_fix_configuration();
+void max17050_dump_regs(void *buf);
+u32 max17050_get_cached_batt_volt();
#endif /* __MAX17050_H_ */
diff --git a/bdk/power/max77620.h b/bdk/power/max77620.h
index 23ee299..3d41459 100644
--- a/bdk/power/max77620.h
+++ b/bdk/power/max77620.h
@@ -1,8 +1,7 @@
/*
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
- * Copyright (c) 2016 NVIDIA CORPORATION. All rights reserved.
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2020 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,24 +29,33 @@
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
-#define MAX77620_CNFGGLBL1_LBHYST (BIT(5) | BIT(4))
#define MAX77620_CNFGGLBL1_MPPLD BIT(6)
#define MAX77620_CNFGGLBL1_LBDAC_EN BIT(7)
#define MAX77620_REG_CNFGGLBL2 0x01
-#define MAX77620_REG_CNFGGLBL3 0x02
-#define MAX77620_WDTC_MASK 0x3
-#define MAX77620_WDTEN BIT(2)
-#define MAX77620_WDTSLPC BIT(3)
-#define MAX77620_WDTOFFC BIT(4)
#define MAX77620_TWD_MASK 0x3
#define MAX77620_TWD_2s 0x0
#define MAX77620_TWD_16s 0x1
#define MAX77620_TWD_64s 0x2
#define MAX77620_TWD_128s 0x3
+#define MAX77620_WDTEN BIT(2)
+#define MAX77620_WDTSLPC BIT(3)
+#define MAX77620_WDTOFFC BIT(4)
+#define MAX77620_GLBL_LPM BIT(5)
+#define MAX77620_I2CTWD_MASK 0xC0
+#define MAX77620_I2CTWD_DISABLED 0x00
+#define MAX77620_I2CTWD_1_33ms 0x40
+#define MAX77620_I2CTWD_35_7ms 0x80
+#define MAX77620_I2CTWD_41_7ms 0xC0
+
+#define MAX77620_REG_CNFGGLBL3 0x02
+#define MAX77620_WDTC_MASK 0x3
#define MAX77620_REG_CNFG1_32K 0x03
+#define MAX77620_CNFG1_PWR_MD_32K_MASK 0x3
#define MAX77620_CNFG1_32K_OUT0_EN BIT(2)
+#define MAX77620_CNFG1_32KLOAD_MASK 0x30
+#define MAX77620_CNFG1_32K_OK BIT(7)
#define MAX77620_REG_CNFGBBC 0x04
#define MAX77620_CNFGBBC_ENABLE BIT(0)
@@ -64,6 +72,7 @@
#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
#define MAX77620_REG_IRQTOP 0x05
+#define MAX77620_REG_IRQTOPM 0x0D
#define MAX77620_IRQ_TOP_ONOFF_MASK BIT(1)
#define MAX77620_IRQ_TOP_32K_MASK BIT(2)
#define MAX77620_IRQ_TOP_RTC_MASK BIT(3)
@@ -73,28 +82,53 @@
#define MAX77620_IRQ_TOP_GLBL_MASK BIT(7)
#define MAX77620_REG_INTLBT 0x06
-#define MAX77620_REG_IRQTOPM 0x0D
+#define MAX77620_REG_INTENLBT 0x0E
+#define MAX77620_IRQ_GLBLM_MASK BIT(0)
#define MAX77620_IRQ_TJALRM2_MASK BIT(1)
#define MAX77620_IRQ_TJALRM1_MASK BIT(2)
#define MAX77620_IRQ_LBM_MASK BIT(3)
#define MAX77620_REG_IRQSD 0x07
-#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
-#define MAX77620_REG_IRQ_LVL2_L8 0x09
-#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
-#define MAX77620_REG_ONOFFIRQ 0x0B
-#define MAX77620_REG_NVERC 0x0C
-
-#define MAX77620_REG_INTENLBT 0x0E
-#define MAX77620_GLBLM_MASK BIT(0)
-
#define MAX77620_REG_IRQMASKSD 0x0F
+#define MAX77620_IRQSD_PFI_SD3 BIT(4)
+#define MAX77620_IRQSD_PFI_SD2 BIT(5)
+#define MAX77620_IRQSD_PFI_SD1 BIT(6)
+#define MAX77620_IRQSD_PFI_SD0 BIT(7)
+
+#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 // LDO number that irq occurred.
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
+#define MAX77620_REG_IRQ_LVL2_L8 0x09 // LDO number that irq occurred. Only bit0: LDO8 is valid.
#define MAX77620_REG_IRQ_MSK_L8 0x11
+#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A // Edge detection interrupt.
+
+#define MAX77620_REG_ONOFFIRQ 0x0B
#define MAX77620_REG_ONOFFIRQM 0x12
+#define MAX77620_ONOFFIRQ_MRWRN BIT(0)
+#define MAX77620_ONOFFIRQ_EN0_1SEC BIT(1)
+#define MAX77620_ONOFFIRQ_EN0_F BIT(2)
+#define MAX77620_ONOFFIRQ_EN0_R BIT(3)
+#define MAX77620_ONOFFIRQ_LID_F BIT(4)
+#define MAX77620_ONOFFIRQ_LID_R BIT(5)
+#define MAX77620_ONOFFIRQ_ACOK_F BIT(6)
+#define MAX77620_ONOFFIRQ_ACOK_R BIT(7)
+
+#define MAX77620_REG_NVERC 0x0C // Shutdown reason (non-volatile).
+#define MAX77620_NVERC_SHDN BIT(0)
+#define MAX77620_NVERC_WTCHDG BIT(1)
+#define MAX77620_NVERC_HDRST BIT(2)
+#define MAX77620_NVERC_TOVLD BIT(3)
+#define MAX77620_NVERC_MBLSD BIT(4)
+#define MAX77620_NVERC_MBO BIT(5)
+#define MAX77620_NVERC_MBU BIT(6)
+#define MAX77620_NVERC_RSTIN BIT(7)
+
#define MAX77620_REG_STATLBT 0x13
#define MAX77620_REG_STATSD 0x14
+
#define MAX77620_REG_ONOFFSTAT 0x15
+#define MAX77620_ONOFFSTAT_LID BIT(0)
+#define MAX77620_ONOFFSTAT_ACOK BIT(1)
+#define MAX77620_ONOFFSTAT_EN0 BIT(2)
/* SD and LDO Registers */
#define MAX77620_REG_SD0 0x16
@@ -102,18 +136,42 @@
#define MAX77620_REG_SD2 0x18
#define MAX77620_REG_SD3 0x19
#define MAX77620_REG_SD4 0x1A
-#define MAX77620_SDX_VOLT_MASK 0xFF
-#define MAX77620_SD0_VOLT_MASK 0x3F
-#define MAX77620_SD1_VOLT_MASK 0x7F
-#define MAX77620_LDO_VOLT_MASK 0x3F
#define MAX77620_REG_DVSSD0 0x1B
#define MAX77620_REG_DVSSD1 0x1C
-#define MAX77620_REG_SD0_CFG 0x1D // SD CNFG1.
-#define MAX77620_REG_SD1_CFG 0x1E // SD CNFG1.
-#define MAX77620_REG_SD2_CFG 0x1F // SD CNFG1.
-#define MAX77620_REG_SD3_CFG 0x20 // SD CNFG1.
-#define MAX77620_REG_SD4_CFG 0x21 // SD CNFG1.
+#define MAX77620_SDX_VOLT_MASK 0xFF
+#define MAX77620_SD0_VOLT_MASK 0x7F // Max is 0x40.
+#define MAX77620_SD1_VOLT_MASK 0x7F // Max is 0x4C.
+#define MAX77620_LDO_VOLT_MASK 0x3F
+
+#define MAX77620_REG_SD0_CFG 0x1D
+#define MAX77620_REG_SD1_CFG 0x1E
+#define MAX77620_REG_SD2_CFG 0x1F
+#define MAX77620_REG_SD3_CFG 0x20
+#define MAX77620_REG_SD4_CFG 0x21
+#define MAX77620_SD_SR_MASK 0xC0
+#define MAX77620_SD_SR_SHIFT 6
+#define MAX77620_SD_POWER_MODE_MASK 0x30
+#define MAX77620_SD_POWER_MODE_SHIFT 4
+#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
+#define MAX77620_SD_CFG1_ADE_DISABLE 0
+#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
+#define MAX77620_SD_FPWM_MASK 0x04
+#define MAX77620_SD_FPWM_SHIFT 2
+#define MAX77620_SD_FSRADE_MASK 0x01
+#define MAX77620_SD_FSRADE_SHIFT 0
+#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
+#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
+#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
+#define MAX77620_SD_CFG1_MPOK_MASK BIT(1)
+#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
+#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
+#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
+
#define MAX77620_REG_SD_CFG2 0x22
+#define MAX77620_SD_CNF2_RSVD BIT(0)
+#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
+#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
+
#define MAX77620_REG_LDO0_CFG 0x23
#define MAX77620_REG_LDO0_CFG2 0x24
#define MAX77620_REG_LDO1_CFG 0x25
@@ -132,26 +190,36 @@
#define MAX77620_REG_LDO7_CFG2 0x32
#define MAX77620_REG_LDO8_CFG 0x33
#define MAX77620_REG_LDO8_CFG2 0x34
-#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
-#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
-#define MAX77620_LDO_CFG2_SS_SLOW 0
-#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
-#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
-#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
-#define MAX20024_LDO_CFG2_MPOK_MASK BIT(2)
-#define MAX77620_LDO_POWER_MODE_MASK 0xC0
+/*! LDO CFG */
#define MAX77620_LDO_POWER_MODE_SHIFT 6
+#define MAX77620_LDO_POWER_MODE_MASK (3 << MAX77620_LDO_POWER_MODE_SHIFT)
#define MAX77620_POWER_MODE_NORMAL 3
#define MAX77620_POWER_MODE_LPM 2
#define MAX77620_POWER_MODE_GLPM 1
#define MAX77620_POWER_MODE_DISABLE 0
+/*! LDO CFG2 */
+#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
+#define MAX77620_LDO_CFG2_SS_FAST (0 << 0)
+#define MAX77620_LDO_CFG2_SS_SLOW (1 << 0)
+#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
+#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
+#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
+#define MAX77620_LDO_CFG2_MPOK_MASK BIT(2)
+#define MAX77620_LDO_CFG2_POK_MASK BIT(3)
+#define MAX77620_LDO_CFG2_COMP_SHIFT 4
+#define MAX77620_LDO_CFG2_COMP_MASK (3 << MAX77620_LDO_COMP_SHIFT)
+#define MAX77620_LDO_CFG2_COMP_SLOW 3
+#define MAX77620_LDO_CFG2_COMP_MID_SLOW 2
+#define MAX77620_LDO_CFG2_COMP_MID_FAST 1
+#define MAX77620_LDO_CFG2_COMP_FAST 0
+#define MAX77620_LDO_CFG2_ALPM_EN_MASK BIT(6)
+#define MAX77620_LDO_CFG2_OVCLMP_MASK BIT(7)
#define MAX77620_REG_LDO_CFG3 0x35
+#define MAX77620_LDO_BIAS_EN BIT(0)
#define MAX77620_TRACK4_SHIFT 5
#define MAX77620_TRACK4_MASK (1 << MAX77620_TRACK4_SHIFT)
-#define MAX77620_LDO_SLEW_RATE_MASK 0x1
-
#define MAX77620_REG_GPIO0 0x36
#define MAX77620_REG_GPIO1 0x37
#define MAX77620_REG_GPIO2 0x38
@@ -160,9 +228,6 @@
#define MAX77620_REG_GPIO5 0x3B
#define MAX77620_REG_GPIO6 0x3C
#define MAX77620_REG_GPIO7 0x3D
-#define MAX77620_REG_PUE_GPIO 0x3E
-#define MAX77620_REG_PDE_GPIO 0x3F
-#define MAX77620_REG_AME_GPIO 0x40
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN (0 << 0)
@@ -181,6 +246,13 @@
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
+#define MAX77620_GPIO_OUTPUT_DISABLE 0
+#define MAX77620_GPIO_OUTPUT_ENABLE 1
+
+#define MAX77620_REG_PUE_GPIO 0x3E // Gpio Pullup resistor enable.
+#define MAX77620_REG_PDE_GPIO 0x3F // Gpio Pulldown resistor enable.
+
+#define MAX77620_REG_AME_GPIO 0x40 // Gpio pinmuxing. Clear bits are Standard GPIO.
#define MAX77620_REG_ONOFFCNFG1 0x41
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
@@ -188,19 +260,30 @@
#define MAX77620_ONOFFCNFG1_SLPEN BIT(2)
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
+#define MAX77620_ONOFFCNFG1_RSVD BIT(6)
#define MAX77620_ONOFFCNFG1_SFT_RST BIT(7)
#define MAX77620_REG_ONOFFCNFG2 0x42
#define MAX77620_ONOFFCNFG2_WK_EN0 BIT(0)
+#define MAX77620_ONOFFCNFG2_WK_ALARM2 BIT(1)
#define MAX77620_ONOFFCNFG2_WK_ALARM1 BIT(2)
+#define MAX77620_ONOFFCNFG2_WK_MBATT BIT(3) // MBATT event generates a wakeup signal. use it in android/l4t?
+#define MAX77620_ONOFFCNFG2_WK_ACOK BIT(4)
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK BIT(5)
#define MAX77620_ONOFFCNFG2_WD_RST_WK BIT(6)
#define MAX77620_ONOFFCNFG2_SFT_RST_WK BIT(7)
/* FPS Registers */
-#define MAX77620_REG_FPS_CFG0 0x43
-#define MAX77620_REG_FPS_CFG1 0x44
-#define MAX77620_REG_FPS_CFG2 0x45
+#define MAX77620_REG_FPS_CFG0 0x43 // FPS0.
+#define MAX77620_REG_FPS_CFG1 0x44 // FPS1.
+#define MAX77620_REG_FPS_CFG2 0x45 // FPS2.
+#define MAX77620_FPS_ENFPS_SW_MASK 0x01
+#define MAX77620_FPS_ENFPS_SW 0x01
+#define MAX77620_FPS_EN_SRC_SHIFT 1
+#define MAX77620_FPS_EN_SRC_MASK 0x06
+#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
+#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
+
#define MAX77620_REG_FPS_LDO0 0x46
#define MAX77620_REG_FPS_LDO1 0x47
#define MAX77620_REG_FPS_LDO2 0x48
@@ -215,77 +298,39 @@
#define MAX77620_REG_FPS_SD2 0x51
#define MAX77620_REG_FPS_SD3 0x52
#define MAX77620_REG_FPS_SD4 0x53
-#define MAX77620_REG_FPS_NONE 0
-#define MAX77620_FPS_SRC_MASK 0xC0
-#define MAX77620_FPS_SRC_SHIFT 6
-#define MAX77620_FPS_PU_PERIOD_MASK 0x38
-#define MAX77620_FPS_PU_PERIOD_SHIFT 3
-#define MAX77620_FPS_PD_PERIOD_MASK 0x07
-#define MAX77620_FPS_PD_PERIOD_SHIFT 0
-
-/* Minimum and maximum FPS period time (in microseconds) are
- * different for MAX77620 and Max20024.
- */
-#define MAX77620_FPS_COUNT 3
-
-#define MAX77620_FPS_PERIOD_MIN_US 40
-#define MAX20024_FPS_PERIOD_MIN_US 20
-
-#define MAX77620_FPS_PERIOD_MAX_US 2560
-#define MAX20024_FPS_PERIOD_MAX_US 5120
-
#define MAX77620_REG_FPS_GPIO1 0x54
#define MAX77620_REG_FPS_GPIO2 0x55
#define MAX77620_REG_FPS_GPIO3 0x56
-#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
-#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
-#define MAX77620_FPS_EN_SRC_MASK 0x06
-#define MAX77620_FPS_EN_SRC_SHIFT 1
-#define MAX77620_FPS_ENFPS_SW_MASK 0x01
-#define MAX77620_FPS_ENFPS_SW 0x01
-
#define MAX77620_REG_FPS_RSO 0x57
+#define MAX77620_FPS_PD_PERIOD_SHIFT 0
+#define MAX77620_FPS_PD_PERIOD_MASK 0x07
+#define MAX77620_FPS_PU_PERIOD_SHIFT 3
+#define MAX77620_FPS_PU_PERIOD_MASK 0x38
+#define MAX77620_FPS_SRC_SHIFT 6
+#define MAX77620_FPS_SRC_MASK 0xC0
+
+#define MAX77620_FPS_COUNT 3
+#define MAX77620_FPS_PERIOD_MIN_US 40
+#define MAX77620_FPS_PERIOD_MAX_US 2560
+
#define MAX77620_REG_CID0 0x58
#define MAX77620_REG_CID1 0x59
#define MAX77620_REG_CID2 0x5A
#define MAX77620_REG_CID3 0x5B
-#define MAX77620_REG_CID4 0x5C
-#define MAX77620_REG_CID5 0x5D
-
-#define MAX77620_REG_DVSSD4 0x5E
-#define MAX20024_REG_MAX_ADD 0x70
-
-#define MAX77620_CID_DIDM_MASK 0xF0
-#define MAX77620_CID_DIDM_SHIFT 4
-
-/* CNCG2SD */
-#define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
-#define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
+#define MAX77620_REG_CID4 0x5C // OTP version.
+#define MAX77620_REG_CID5 0x5D // ES version.
+#define MAX77620_CID_DIDO_MASK 0xF
+#define MAX77620_CID_DIDO_SHIFT 0
+#define MAX77620_CID_DIDM_MASK 0xF0
+#define MAX77620_CID_DIDM_SHIFT 4
/* Device Identification Metal */
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
/* Device Indentification OTP */
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
-/* SD CNFG1 */
-#define MAX77620_SD_SR_MASK 0xC0
-#define MAX77620_SD_SR_SHIFT 6
-#define MAX77620_SD_POWER_MODE_MASK 0x30
-#define MAX77620_SD_POWER_MODE_SHIFT 4
-#define MAX77620_SD_CFG1_ADE_MASK BIT(3)
-#define MAX77620_SD_CFG1_ADE_DISABLE 0
-#define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
-#define MAX77620_SD_FPWM_MASK 0x04
-#define MAX77620_SD_FPWM_SHIFT 2
-#define MAX77620_SD_FSRADE_MASK 0x01
-#define MAX77620_SD_FSRADE_SHIFT 0
-#define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
-#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
-#define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
-#define MAX20024_SD_CFG1_MPOK_MASK BIT(1)
-#define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
-#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
-#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
+#define MAX77620_REG_DVSSD4 0x5E
+#define MAX20024_REG_MAX_ADD 0x70
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 BIT(0)
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 BIT(1)
@@ -332,9 +377,4 @@ enum max77620_fps_src {
MAX77620_FPS_SRC_DEF,
};
-enum max77620_chip_id {
- MAX77620,
- MAX20024,
-};
-
#endif /* _MFD_MAX77620_H_ */
diff --git a/bdk/power/max7762x.c b/bdk/power/max7762x.c
index 6102ee1..f0aefb5 100644
--- a/bdk/power/max7762x.c
+++ b/bdk/power/max7762x.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2020 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,163 +17,334 @@
#include
#include
+#include
+#include
#include
-#include
+#include
+#include
-#define REGULATOR_SD 0
+#define REGULATOR_SD 0
#define REGULATOR_LDO 1
+#define REGULATOR_BC0 2
+#define REGULATOR_BC1 3
-typedef struct _max77620_regulator_t
+typedef struct _max77620_fps_t
{
- u8 type;
- const char *name;
- u8 reg_sd;
-
- u32 mv_step;
- u32 mv_min;
- u32 mv_default;
- u32 mv_max;
-
- u8 volt_addr;
- u8 cfg_addr;
-
- u8 volt_mask;
- u8 enable_mask;
- u8 enable_shift;
- u8 status_mask;
-
u8 fps_addr;
u8 fps_src;
u8 pd_period;
u8 pu_period;
+} max77620_fps_t;
+
+typedef struct _max77621_ctrl_t
+{
+ u8 ctrl1_por;
+ u8 ctrl1_hos;
+ u8 ctrl2_por;
+ u8 ctrl2_hos;
+} max77621_ctrl_t;
+
+typedef struct _max77812_ctrl_t
+{
+ u8 mask;
+ u8 shift;
+ u8 rsvd0;
+ u8 rsvd1;
+} max77812_en_t;
+
+typedef struct _max77620_regulator_t
+{
+ const char *name;
+
+ u32 uv_step;
+ u32 uv_min;
+ u32 uv_default;
+ u32 uv_max;
+
+ u8 type;
+ u8 volt_addr;
+ u8 cfg_addr;
+ u8 volt_mask;
+
+ union {
+ max77620_fps_t fps;
+ max77621_ctrl_t ctrl;
+ max77812_en_t enable;
+ };
} max77620_regulator_t;
static const max77620_regulator_t _pmic_regulators[] = {
- { REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x80, MAX77620_REG_FPS_SD0, 1, 7, 1 },
- { REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x40, MAX77620_REG_FPS_SD1, 0, 1, 5 },
- { REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x20, MAX77620_REG_FPS_SD2, 1, 5, 2 },
- { REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x10, MAX77620_REG_FPS_SD3, 0, 3, 3 },
- { REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO0, 3, 7, 0 },
- { REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO1, 3, 7, 0 },
- { REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO2, 3, 7, 0 },
- { REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO3, 3, 7, 0 },
- { REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 1000000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO4, 0, 7, 1 },
- { REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 },
- { REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 },
- { REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 },
- { REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 2800000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
+ { "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 }} },
+ { "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 }} },
+ { "ldo1", 25000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO1, 3, 7, 0 }} },
+ { "ldo2", 50000, 800000, 1800000, 3300000, REGULATOR_LDO, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO2, 3, 7, 0 }} },
+ { "ldo3", 50000, 800000, 3100000, 3100000, REGULATOR_LDO, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO3, 3, 7, 0 }} },
+ { "ldo4", 12500, 800000, 850000, 1000000, REGULATOR_LDO, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO4, 0, 7, 1 }} },
+ { "ldo5", 50000, 800000, 1800000, 1800000, REGULATOR_LDO, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO5, 3, 7, 0 }} },
+ { "ldo6", 50000, 800000, 2900000, 2900000, REGULATOR_LDO, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO6, 3, 7, 0 }} },
+ { "ldo7", 50000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO7, 1, 4, 3 }} },
+ { "ldo8", 50000, 800000, 1050000, 2800000, REGULATOR_LDO, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO8, 3, 7, 0 }} },
+
+ { "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
+ { "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
+ { "max77812_CPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M4_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M4_MASK, MAX77812_EN_CTRL_EN_M4_SHIFT, 0, 0 }} },
+ { "max77812_RAM", 5000, 250000, 600000, 650000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration.
+ //{ "max77812_GPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M1_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M1_MASK, MAX77812_EN_CTRL_EN_M1_SHIFT, 0, 0 }} },
};
-static void _max77620_set_reg(u8 reg, u8 val)
+static u8 _max77812_get_address()
+{
+ static u8 max77812_i2c_addr = 0;
+
+ if (max77812_i2c_addr)
+ return max77812_i2c_addr;
+
+ max77812_i2c_addr =
+ !(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
+
+ return max77812_i2c_addr;
+}
+
+static u8 _max7762x_get_i2c_address(u32 id)
+{
+ const max77620_regulator_t *reg = &_pmic_regulators[id];
+
+ // Choose the correct i2c address.
+ switch (reg->type)
+ {
+ case REGULATOR_SD:
+ case REGULATOR_LDO:
+ return MAX77620_I2C_ADDR;
+ case REGULATOR_BC0:
+ return (id == REGULATOR_CPU0 ? MAX77621_CPU_I2C_ADDR : MAX77621_GPU_I2C_ADDR);
+ case REGULATOR_BC1:
+ {
+ u8 reg_addr = _max77812_get_address();
+ if (id == REGULATOR_RAM0 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
+ reg_addr = 0;
+ return reg_addr;
+ }
+ default:
+ return 0;
+ }
+}
+
+static void _max7762x_set_reg(u8 addr, u8 reg, u8 val)
{
u32 retries = 100;
while (retries)
{
- if (i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val))
+ if (i2c_send_byte(I2C_5, addr, reg, val))
break;
- usleep(100);
+
+ usleep(50);
retries--;
}
}
int max77620_regulator_get_status(u32 id)
{
- if (id > REGULATOR_MAX)
+ if (id > REGULATOR_LDO8)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
+ // SD power OK status.
if (reg->type == REGULATOR_SD)
- return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;
- return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & 8) ? 1 : 0;
+ {
+ u8 mask = 1u << (7 - id);
+ return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & mask) ? 0 : 1;
+ }
+
+ // LDO power OK status.
+ return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & MAX77620_LDO_CFG2_POK_MASK) ? 1 : 0;
}
int max77620_regulator_config_fps(u32 id)
{
- if (id > REGULATOR_MAX)
+ if (id > REGULATOR_LDO8)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
- _max77620_set_reg(reg->fps_addr,
- (reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
+ // Set FPS configuration.
+ _max7762x_set_reg(MAX77620_I2C_ADDR,
+ reg->fps.fps_addr,
+ (reg->fps.fps_src << MAX77620_FPS_SRC_SHIFT) |
+ (reg->fps.pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) |
+ (reg->fps.pd_period << MAX77620_FPS_PD_PERIOD_SHIFT));
return 1;
}
-int max77620_regulator_set_voltage(u32 id, u32 mv)
+int max7762x_regulator_set_voltage(u32 id, u32 uv)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
- if (mv < reg->mv_min || mv > reg->mv_max)
+ if (uv < reg->uv_min || uv > reg->uv_max)
return 0;
- u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
- u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
+ u8 addr = _max7762x_get_i2c_address(id);
+ if (!addr)
+ return 0;
+
+ // Calculate voltage multiplier.
+ u32 mult = (uv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
+ u8 val = i2c_recv_byte(I2C_5, addr, reg->volt_addr);
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
- _max77620_set_reg(reg->volt_addr, val);
+
+ // Set voltage.
+ _max7762x_set_reg(addr, reg->volt_addr, val);
+
+ // If max77621 set DVS voltage also.
+ if (reg->type == REGULATOR_BC0)
+ _max7762x_set_reg(addr, reg->cfg_addr, MAX77621_VOUT_ENABLE_MASK | val);
+
+ // Wait for ramp up/down delay.
usleep(1000);
return 1;
}
-int max77620_regulator_enable(u32 id, int enable)
+int max7762x_regulator_enable(u32 id, bool enable)
{
+ u8 reg_addr;
+ u8 enable_val;
+ u8 enable_mask;
+ u8 enable_shift;
+
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
- u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
- u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);
+ // Choose the correct i2c and register addresses and mask/shift for each type.
+ switch (reg->type)
+ {
+ case REGULATOR_SD:
+ reg_addr = reg->cfg_addr;
+ enable_val = MAX77620_POWER_MODE_NORMAL;
+ enable_mask = MAX77620_SD_POWER_MODE_MASK;
+ enable_shift = MAX77620_SD_POWER_MODE_SHIFT;
+ break;
+ case REGULATOR_LDO:
+ reg_addr = reg->volt_addr;
+ enable_val = MAX77620_POWER_MODE_NORMAL;
+ enable_mask = MAX77620_LDO_POWER_MODE_MASK;
+ enable_shift = MAX77620_LDO_POWER_MODE_SHIFT;
+ break;
+ case REGULATOR_BC0:
+ reg_addr = reg->volt_addr;
+ enable_val = MAX77621_VOUT_ENABLE;
+ enable_mask = MAX77621_DVC_DVS_ENABLE_MASK;
+ enable_shift = MAX77621_DVC_DVS_ENABLE_SHIFT;
+ break;
+ case REGULATOR_BC1:
+ reg_addr = reg->cfg_addr;
+ enable_val = MAX77812_EN_CTRL_ENABLE;
+ enable_mask = reg->enable.mask;
+ enable_shift = reg->enable.shift;
+ break;
+ default:
+ return 0;
+ }
+
+ u8 addr = _max7762x_get_i2c_address(id);
+ if (!addr)
+ return 0;
+
+ // Read and enable/disable.
+ u8 val = i2c_recv_byte(I2C_5, addr, reg_addr);
+ val &= ~enable_mask;
+
if (enable)
- val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
- else
- val &= ~reg->enable_mask;
- _max77620_set_reg(addr, val);
+ val |= (enable_val << enable_shift);
+
+ // Set enable.
+ _max7762x_set_reg(addr, reg_addr, val);
+
+ // Wait for enable/disable ramp delay.
usleep(1000);
return 1;
}
-// LDO only.
-int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
+void max77620_config_gpio(u32 gpio_id, bool enable)
{
- if (id > REGULATOR_MAX)
- return 0;
+ if (gpio_id > 7)
+ return;
+ // Configure as standard GPIO.
+ u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, val & ~BIT(gpio_id));
+
+ // Set GPIO configuration.
+ if (enable)
+ val = MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DIR_OUTPUT | MAX77620_CNFG_GPIO_DRV_PUSHPULL;
+ else
+ val = MAX77620_CNFG_GPIO_DIR_INPUT | MAX77620_CNFG_GPIO_DRV_OPENDRAIN;
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO0 + gpio_id, val);
+}
+
+void max77621_config_default(u32 id, bool por)
+{
const max77620_regulator_t *reg = &_pmic_regulators[id];
- if (mv < reg->mv_min || mv > reg->mv_max)
- return 0;
+ if (reg->type != REGULATOR_BC0)
+ return;
- u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
- u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
- _max77620_set_reg(reg->volt_addr, val);
- usleep(1000);
+ u8 addr = _max7762x_get_i2c_address(id);
+ if (!addr)
+ return;
- return 1;
+ if (por)
+ {
+ // Set voltage and disable power before changing the inductor.
+ max7762x_regulator_set_voltage(id, 1000000);
+ max7762x_regulator_enable(id, false);
+
+ // Configure to default.
+ i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_por);
+ i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_por);
+ }
+ else
+ {
+ i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_hos);
+ i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_hos);
+ }
}
void max77620_config_default()
{
- for (u32 i = 1; i <= REGULATOR_MAX; i++)
+ // Check if Erista OTP.
+ if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4) != 0x35)
+ return;
+
+ // Set default voltages and enable regulators.
+ for (u32 i = REGULATOR_SD1; i <= REGULATOR_LDO8; i++)
{
- i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
max77620_regulator_config_fps(i);
- max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
- if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
- max77620_regulator_enable(i, 1);
+ max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
+ if (_pmic_regulators[i].fps.fps_src != MAX77620_FPS_SRC_NONE)
+ max7762x_regulator_enable(i, true);
}
- _max77620_set_reg(MAX77620_REG_SD_CFG2, 4);
+
+ // Enable SD0 output voltage sense and disable for SD1. Additionally disable the reserved bit.
+ _max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, MAX77620_SD_CNF2_ROVS_EN_SD0);
}
+// Stock HOS: disabled.
void max77620_low_battery_monitor_config(bool enable)
{
- _max77620_set_reg(MAX77620_REG_CNFGGLBL1,
- MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
- MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
+ _max7762x_set_reg(MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
+ MAX77620_CNFGGLBL1_LBDAC_EN |
+ (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
+ MAX77620_CNFGGLBL1_LBHYST_200 |
+ MAX77620_CNFGGLBL1_LBDAC_2800);
}
diff --git a/bdk/power/max7762x.h b/bdk/power/max7762x.h
index dd06bf7..342f40b 100644
--- a/bdk/power/max7762x.h
+++ b/bdk/power/max7762x.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2020 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,6 +20,14 @@
#include
+/*
+ * SDx actual min is 625 mV. Multipliers 0/1 reserved.
+ * SD0 max is 1400 mV
+ * SD1 max is 1550 mV
+ * SD2 max is 3787.5 mV
+ * SD3 max is 3787.5 mV
+ */
+
/*
* Switch Power domains (max77620):
* Name | Usage | uV step | uV min | uV default | uV max | Init
@@ -32,23 +40,44 @@
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
-* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
+* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | 0.85V (AO, pcv)
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
-* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
-* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
-* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
+* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv)
+* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
+* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
*/
+
+// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
+
+/*
+ * OTP: T210 - T210B01:
+ * SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
+ * SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
+ * SD2: 1.35V 1.35V
+ * SD3: 1.8V 1.8V
+ * All powered off?
+ * LDO0: -- -- - Display
+ * LDO1: 1.05V 1.05V
+ * LDO2: -- -- - SD
+ * LDO3: 3.1V 3.1V - GC ASIC
+ * LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
+ * LDO5: 3.1V 3.1V
+ * LDO6: 2.8V 2.9V - Touch.
+ * LDO7: 1.05V 1.0V
+ * LDO8: 1.05V 1.0V
+ */
+
/*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable
*/
/*! MAX77620 partitions. */
-#define REGULATOR_SD0 0
-#define REGULATOR_SD1 1
-#define REGULATOR_SD2 2
-#define REGULATOR_SD3 3
+#define REGULATOR_SD0 0
+#define REGULATOR_SD1 1
+#define REGULATOR_SD2 2
+#define REGULATOR_SD3 3
#define REGULATOR_LDO0 4
#define REGULATOR_LDO1 5
#define REGULATOR_LDO2 6
@@ -58,26 +87,40 @@
#define REGULATOR_LDO6 10
#define REGULATOR_LDO7 11
#define REGULATOR_LDO8 12
-#define REGULATOR_MAX 12
+#define REGULATOR_CPU0 13 // T210 CPU.
+#define REGULATOR_GPU0 14 // T210 CPU.
+#define REGULATOR_CPU1 15 // T210B01 CPU.
+#define REGULATOR_RAM0 16 // T210B01 RAM for PHASE211.
+//#define REGULATOR_GPU1 17 // T210B01 CPU.
+#define REGULATOR_MAX REGULATOR_RAM0
#define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C
-#define MAX77621_VOUT_REG 0
-#define MAX77621_VOUT_DVS_REG 1
-#define MAX77621_CONTROL1_REG 2
-#define MAX77621_CONTROL2_REG 3
-
-/* MAX77621_VOUT */
-#define MAX77621_VOUT_ENABLE BIT(7)
-#define MAX77621_VOUT_MASK 0x7F
-#define MAX77621_VOUT_0_95V 0x37
-#define MAX77621_VOUT_1_09V 0x4F
+#define MAX77621_REG_VOUT 0x00
+#define MAX77621_REG_VOUT_DVS 0x01
+#define MAX77621_REG_CONTROL1 0x02
+#define MAX77621_REG_CONTROL2 0x03
+#define MAX77621_REG_CHIPID1 0x04
+#define MAX77621_REG_CHIPID2 0x05
/* MAX77621_VOUT_DVC_DVS */
-#define MAX77621_DVS_VOUT_MASK 0x7F
+#define MAX77621_DVC_DVS_VOLT_MASK 0x7F
+#define MAX77621_DVC_DVS_ENABLE_SHIFT 7
+#define MAX77621_DVC_DVS_ENABLE_MASK (1 << MAX77621_DVC_DVS_ENABLE_SHIFT)
+
+/* MAX77621_VOUT */
+#define MAX77621_VOUT_DISABLE 0
+#define MAX77621_VOUT_ENABLE 1
+#define MAX77621_VOUT_ENABLE_MASK (MAX77621_VOUT_ENABLE << MAX77621_DVC_DVS_ENABLE_SHIFT)
/* MAX77621_CONTROL1 */
+#define MAX77621_RAMP_12mV_PER_US 0x0
+#define MAX77621_RAMP_25mV_PER_US 0x1
+#define MAX77621_RAMP_50mV_PER_US 0x2
+#define MAX77621_RAMP_200mV_PER_US 0x3
+#define MAX77621_RAMP_MASK 0x3
+
#define MAX77621_FREQSHIFT_9PER BIT(2)
#define MAX77621_BIAS_ENABLE BIT(3)
#define MAX77621_AD_ENABLE BIT(4)
@@ -85,34 +128,48 @@
#define MAX77621_FPWM_EN_M BIT(6)
#define MAX77621_SNS_ENABLE BIT(7)
-#define MAX77621_RAMP_12mV_PER_US 0x0
-#define MAX77621_RAMP_25mV_PER_US 0x1
-#define MAX77621_RAMP_50mV_PER_US 0x2
-#define MAX77621_RAMP_200mV_PER_US 0x3
-#define MAX77621_RAMP_MASK 0x3
-
/* MAX77621_CONTROL2 */
-#define MAX77621_FT_ENABLE BIT(4)
-#define MAX77621_DISCH_ENBABLE BIT(5)
+#define MAX77621_INDUCTOR_MIN_30_PER 0
+#define MAX77621_INDUCTOR_NOMINAL 1
+#define MAX77621_INDUCTOR_PLUS_30_PER 2
+#define MAX77621_INDUCTOR_PLUS_60_PER 3
+#define MAX77621_INDUCTOR_MASK 3
+
+#define MAX77621_CKKADV_TRIP_75mV_PER_US (0 << 2)
+#define MAX77621_CKKADV_TRIP_150mV_PER_US (1u << 2)
+#define MAX77621_CKKADV_TRIP_DISABLE (3u << 2)
+#define MAX77621_CKKADV_TRIP_MASK (3u << 2)
+
+#define MAX77621_FT_ENABLE BIT(4)
+#define MAX77621_DISCH_ENABLE BIT(5)
#define MAX77621_WDTMR_ENABLE BIT(6)
-#define MAX77621_T_JUNCTION_120 BIT(7)
+#define MAX77621_T_JUNCTION_120 BIT(7)
-#define MAX77621_CKKADV_TRIP_DISABLE 0xC
-#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
-#define MAX77621_CKKADV_TRIP_150mV_PER_US 0x4
-#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
+#define MAX77621_CPU_CTRL1_POR_DEFAULT (MAX77621_RAMP_50mV_PER_US)
+#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \
+ MAX77621_NFSR_ENABLE | \
+ MAX77621_SNS_ENABLE | \
+ MAX77621_RAMP_12mV_PER_US)
+#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \
+ MAX77621_FT_ENABLE | \
+ MAX77621_CKKADV_TRIP_DISABLE | \
+ MAX77621_INDUCTOR_NOMINAL)
+#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \
+ MAX77621_WDTMR_ENABLE | \
+ MAX77621_CKKADV_TRIP_75mV_PER_US | \
+ MAX77621_INDUCTOR_NOMINAL)
-#define MAX77621_INDUCTOR_MIN_30_PER 0x0
-#define MAX77621_INDUCTOR_NOMINAL 0x1
-#define MAX77621_INDUCTOR_PLUS_30_PER 0x2
-#define MAX77621_INDUCTOR_PLUS_60_PER 0x3
+#define MAX77621_CTRL_HOS_CFG 0
+#define MAX77621_CTRL_POR_CFG 1
-int max77620_regulator_get_status(u32 id);
-int max77620_regulator_config_fps(u32 id);
-int max77620_regulator_set_voltage(u32 id, u32 mv);
-int max77620_regulator_enable(u32 id, int enable);
-int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
+int max77620_regulator_get_status(u32 id);
+int max77620_regulator_config_fps(u32 id);
+int max7762x_regulator_set_voltage(u32 id, u32 uv);
+int max7762x_regulator_enable(u32 id, bool enable);
+void max77620_config_gpio(u32 id, bool enable);
void max77620_config_default();
void max77620_low_battery_monitor_config(bool enable);
+void max77621_config_default(u32 id, bool por);
+
#endif
diff --git a/bdk/power/max77812.h b/bdk/power/max77812.h
index f8ac3fb..b58e3ae 100644
--- a/bdk/power/max77812.h
+++ b/bdk/power/max77812.h
@@ -17,8 +17,8 @@
#ifndef _MAX77812_H_
#define _MAX77812_H_
-#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31
-#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33
+#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31 // High power GPU. 2 Outputs: 3-phase M1 + 1-phase M4.
+#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33 // Low power GPU. 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4.
#define MAX77812_REG_RSET 0x00
#define MAX77812_REG_INT_SRC 0x01
@@ -27,7 +27,15 @@
#define MAX77812_REG_TOPSYS_INT_M 0x04
#define MAX77812_REG_TOPSYS_STAT 0x05
#define MAX77812_REG_EN_CTRL 0x06
-#define MAX77812_EN_CTRL_EN_M4 BIT(6)
+#define MAX77812_EN_CTRL_ENABLE 1
+#define MAX77812_EN_CTRL_EN_M1_SHIFT 0
+#define MAX77812_EN_CTRL_EN_M1_MASK (1 << MAX77812_EN_CTRL_EN_M1_SHIFT)
+#define MAX77812_EN_CTRL_EN_M2_SHIFT 2
+#define MAX77812_EN_CTRL_EN_M2_MASK (1 << MAX77812_EN_CTRL_EN_M2_SHIFT)
+#define MAX77812_EN_CTRL_EN_M3_SHIFT 4
+#define MAX77812_EN_CTRL_EN_M3_MASK (1 << MAX77812_EN_CTRL_EN_M3_SHIFT)
+#define MAX77812_EN_CTRL_EN_M4_SHIFT 6
+#define MAX77812_EN_CTRL_EN_M4_MASK (1 << MAX77812_EN_CTRL_EN_M4_SHIFT)
#define MAX77812_REG_STUP_DLY2 0x07
#define MAX77812_REG_STUP_DLY3 0x08
#define MAX77812_REG_STUP_DLY4 0x09
@@ -46,11 +54,10 @@
#define MAX77812_REG_BUCK_INT 0x20
#define MAX77812_REG_BUCK_INT_M 0x21
#define MAX77812_REG_BUCK_STAT 0x22
-#define MAX77812_REG_M1_VOUT 0x23
+#define MAX77812_REG_M1_VOUT 0x23 // GPU.
#define MAX77812_REG_M2_VOUT 0x24
-#define MAX77812_REG_M3_VOUT 0x25
-#define MAX77812_REG_M4_VOUT 0x26
-#define MAX77812_M4_VOUT_0_80V 0x6E
+#define MAX77812_REG_M3_VOUT 0x25 // DRAM on PHASE211.
+#define MAX77812_REG_M4_VOUT 0x26 // CPU.
#define MAX77812_REG_M1_VOUT_D 0x27
#define MAX77812_REG_M2_VOUT_D 0x28
#define MAX77812_REG_M3_VOUT_D 0x29
@@ -59,20 +66,23 @@
#define MAX77812_REG_M2_VOUT_S 0x2C
#define MAX77812_REG_M3_VOUT_S 0x2D
#define MAX77812_REG_M4_VOUT_S 0x2E
-#define MAX77812_REG_M1_CFG 0x2F
-#define MAX77812_REG_M2_CFG 0x30
-#define MAX77812_REG_M3_CFG 0x31
-#define MAX77812_REG_M4_CFG 0x32
-#define MAX77812_REG_GLB_CFG1 0x33
-#define MAX77812_REG_GLB_CFG2 0x34
+#define MAX77812_REG_M1_CFG 0x2F // HOS: M1_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M2_CFG 0x30 // HOS: M2_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M3_CFG 0x31 // HOS: M3_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_M4_CFG 0x32 // HOS: M4_ILIM - 7.2A/4.8A.
+#define MAX77812_REG_GLB_CFG1 0x33 // HOS: B_SD_SR/B_SS_SR - 5mV/us.
+#define MAX77812_REG_GLB_CFG2 0x34 // HOS: B_RD_SR/B_RU_SR - 5mV/us
#define MAX77812_REG_GLB_CFG3 0x35
-#define MAX77812_REG_GLB_CFG4 0x36
-#define MAX77812_REG_GLB_CFG5 0x37
-#define MAX77812_REG_GLB_CFG6 0x38
-#define MAX77812_REG_GLB_CFG7 0x39
-#define MAX77812_REG_GLB_CFG8 0x3A
-#define MAX77812_REG_PROT_ACCESS 0xFD
-#define MAX77812_REG_MAX 0xFE
+
+/*! Protected area and settings only for MAX77812_ES2_VERSION */
+#define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
+#define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
+#define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
+#define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
+#define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
+
+#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
+#define MAX77812_REG_UNKNOWN 0xFE
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
#define MAX77812_START_SLEW_RATE_MASK 0x07
@@ -91,10 +101,6 @@
#define MAX77812_ES2_VERSION 0x04
#define MAX77812_QS_VERSION 0x05
-#define MAX77812_VOUT_MASK 0xFF
-#define MAX77812_VOUT_N_VOLTAGE 0xFF
-#define MAX77812_VOUT_VMIN 250000
-#define MAX77812_VOUT_VMAX 1525000
-#define MAX77812_VOUT_STEP 5000
+#define MAX77812_BUCK_VOLT_MASK 0xFF
#endif
diff --git a/bdk/power/regulator_5v.c b/bdk/power/regulator_5v.c
index c61db64..55f81f7 100644
--- a/bdk/power/regulator_5v.c
+++ b/bdk/power/regulator_5v.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 CTCaer
+ * Copyright (c) 2019-2023 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,
@@ -14,63 +14,90 @@
* along with this program. If not, see .
*/
+#include
#include
+#include
#include
#include
#include
#include
static u8 reg_5v_dev = 0;
+static bool usb_src = false;
-void regulator_enable_5v(u8 dev)
+void regulator_5v_enable(u8 dev)
{
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+
// The power supply selection from battery or USB is automatic.
if (!reg_5v_dev)
{
- // Fan and Rail power from internal 5V regulator (battery).
+ // Fan and Rail power from battery 5V regulator EN.
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
- gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
- gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
+ gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
- // Fan and Rail power from USB 5V VDD.
- PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
- gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
- gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
+ // Only Icosa has USB 5V VBUS rails.
+ if (tegra_t210)
+ {
+ // Fan and Rail power from USB 5V VBUS EN.
+ PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
+ gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
+ }
- // Make sure GPIO power is enabled.
- PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
- // Override power detect for GPIO AO IO rails.
- PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN;
+ // Make sure GPIO IO power is enabled.
+ PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO;
+ (void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
+
+ // Inform GPIO IO pads that we switched to 1.8V.
+ PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_GPIO;
+ (void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
+
+ usb_src = false;
}
reg_5v_dev |= dev;
}
-void regulator_disable_5v(u8 dev)
+void regulator_5v_disable(u8 dev)
{
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+
reg_5v_dev &= ~dev;
if (!reg_5v_dev)
{
- // Rail power from internal 5V regulator (battery).
+ // Rail power from battery 5V regulator.
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
- gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE);
- gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO);
- PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE;
- // Rail power from USB 5V VDD.
- gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
- gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
- gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO);
- PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE;
+ // Only Icosa has USB 5V VBUS rails.
+ if (tegra_t210)
+ {
+ // Rail power from USB 5V VBUS.
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
+ usb_src = false;
- // GPIO AO IO rails.
- PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN;
+ }
}
}
-bool regulator_get_5v_dev_enabled(u8 dev)
+bool regulator_5v_get_dev_enabled(u8 dev)
{
return (reg_5v_dev & dev);
}
+
+void regulator_5v_usb_src_enable(bool enable)
+{
+ // Only for Icosa.
+ if (hw_get_chip_id() != GP_HIDREV_MAJOR_T210)
+ return;
+
+ if (enable && !usb_src)
+ {
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
+ usb_src = true;
+ }
+ else if (!enable && usb_src)
+ {
+ gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
+ usb_src = false;
+ }
+}
diff --git a/bdk/power/regulator_5v.h b/bdk/power/regulator_5v.h
index 6bb837a..527c18a 100644
--- a/bdk/power/regulator_5v.h
+++ b/bdk/power/regulator_5v.h
@@ -27,8 +27,9 @@ enum
REGULATOR_5V_ALL = 0xFF
};
-void regulator_enable_5v(u8 dev);
-void regulator_disable_5v(u8 dev);
-bool regulator_get_5v_dev_enabled(u8 dev);
+void regulator_5v_enable(u8 dev);
+void regulator_5v_disable(u8 dev);
+bool regulator_5v_get_dev_enabled(u8 dev);
+void regulator_5v_usb_src_enable(bool enable);
#endif
\ No newline at end of file
diff --git a/bdk/rtc/max77620-rtc.c b/bdk/rtc/max77620-rtc.c
index 164df75..6f813c0 100644
--- a/bdk/rtc/max77620-rtc.c
+++ b/bdk/rtc/max77620-rtc.c
@@ -1,7 +1,7 @@
/*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
*
- * Copyright (c) 2018-2019 CTCaer
+ * Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2019 shchmue
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,7 +19,16 @@
#include
#include
-#include
+#include
+#include
+#include
+
+int epoch_offset = 0;
+
+void max77620_rtc_prep_read()
+{
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
+}
void max77620_rtc_get_time(rtc_time_t *time)
{
@@ -35,7 +44,7 @@ void max77620_rtc_get_time(rtc_time_t *time)
// 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);
+ u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
time->hour = hour & 0x1F;
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
@@ -53,7 +62,7 @@ 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_DATE_REG) & 0x1f;
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
}
@@ -64,6 +73,7 @@ void max77620_rtc_stop_alarm()
// Update RTC regs from RTC clock.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
+ msleep(16);
// Stop alarm for both ALARM1 and ALARM2. Horizon uses ALARM2.
for (int i = 0; i < (MAX77620_RTC_NR_TIME_REGS * 2); i++)
@@ -82,9 +92,9 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
u32 tmp, edays, year, month, day;
// Set time.
- time->sec = epoch % 60;
+ time->sec = epoch % 60;
epoch /= 60;
- time->min = epoch % 60;
+ time->min = epoch % 60;
epoch /= 60;
time->hour = epoch % 24;
epoch /= 24;
@@ -99,14 +109,14 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
day = edays - month * 30 - month * 601 / 1000;
// Month/Year offset.
- if(month < 14)
+ if (month < 14)
{
year -= 4716;
month--;
}
else
{
- year -= 4715;
+ year -= 4715;
month -= 13;
}
@@ -129,13 +139,13 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
month = time->month;
// Month/Year offset.
- if(month < 3)
+ if (month < 3)
{
month += 12;
year--;
}
- epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
+ epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
epoch -= 719561; // Epoch time is 1/1/1970.
@@ -145,3 +155,60 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
return epoch;
}
+
+void max77620_rtc_get_time_adjusted(rtc_time_t *time)
+{
+ max77620_rtc_get_time(time);
+ if (epoch_offset)
+ {
+ u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
+ max77620_rtc_epoch_to_date(epoch, time);
+ }
+}
+
+void max77620_rtc_set_epoch_offset(int offset)
+{
+ epoch_offset = offset;
+}
+
+void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
+{
+ max77620_rtc_stop_alarm();
+
+ // Set reboot reason.
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG, rr->enc.val1);
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG, rr->enc.val2);
+
+ // Set reboot reason magic.
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
+
+ // Update RTC clock from RTC regs.
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
+ msleep(16);
+}
+
+bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr)
+{
+ u8 magic[2];
+
+ // Get reboot reason magic.
+ magic[0] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG);
+ magic[1] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG);
+
+ // Magic must be correct and match on both registers.
+ if (magic[0] != RTC_REBOOT_REASON_MAGIC || magic[0] != magic[1])
+ return false;
+
+ // Reboot reason setter is expected to have updated the actual regs already.
+ rr->enc.val1 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG);
+ rr->enc.val2 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG);
+
+ // Clear magic and update actual regs.
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, 0);
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, 0);
+ i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
+
+ // Return reboot reason. False if [config] was selected.
+ return true;
+}
diff --git a/bdk/rtc/max77620-rtc.h b/bdk/rtc/max77620-rtc.h
index 93b24c4..b82c3e6 100644
--- a/bdk/rtc/max77620-rtc.h
+++ b/bdk/rtc/max77620-rtc.h
@@ -1,7 +1,7 @@
/*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
*
- * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018-2022 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,6 +25,8 @@
#define MAX77620_RTC_NR_TIME_REGS 7
+#define MAX77620_RTC_RTCINT_REG 0x00
+#define MAX77620_RTC_RTCINTM_REG 0x01
#define MAX77620_RTC_CONTROLM_REG 0x02
#define MAX77620_RTC_CONTROL_REG 0x03
#define MAX77620_RTC_BIN_FORMAT BIT(0)
@@ -34,6 +36,9 @@
#define MAX77620_RTC_WRITE_UPDATE BIT(0)
#define MAX77620_RTC_READ_UPDATE BIT(4)
+#define MAX77620_RTC_UPDATE1_REG 0x05
+#define MAX77620_RTC_RTCSMPL_REG 0x06
+
#define MAX77620_RTC_SEC_REG 0x07
#define MAX77620_RTC_MIN_REG 0x08
#define MAX77620_RTC_HOUR_REG 0x09
@@ -69,9 +74,47 @@ typedef struct _rtc_time_t {
u16 year;
} rtc_time_t;
+#define RTC_REBOOT_REASON_MAGIC 0x77 // 7-bit reg.
+
+enum {
+ REBOOT_REASON_NOP = 0, // Use [config].
+ REBOOT_REASON_SELF = 1, // Use autoboot_idx/autoboot_list.
+ REBOOT_REASON_MENU = 2, // Force menu.
+ REBOOT_REASON_UMS = 3, // Force selected UMS partition.
+ REBOOT_REASON_REC = 4, // Set PMC_SCRATCH0_MODE_RECOVERY and reboot to self.
+ REBOOT_REASON_PANIC = 5 // Inform bootloader that panic occured if T210B01.
+};
+
+typedef struct _rtc_rr_decoded_t
+{
+ u16 reason:4;
+ u16 autoboot_idx:4;
+ u16 autoboot_list:1;
+ u16 ums_idx:3;
+} rtc_rr_decoded_t;
+
+typedef struct _rtc_rr_encoded_t
+{
+ u16 val1:6; // 6-bit reg.
+ u16 val2:6; // 6-bit reg.
+} rtc_rr_encoded_t;
+
+typedef struct _rtc_reboot_reason_t
+{
+ union {
+ rtc_rr_decoded_t dec;
+ rtc_rr_encoded_t enc;
+ };
+} rtc_reboot_reason_t;
+
+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_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);
+u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
+void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr);
+bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr);
#endif /* _MFD_MAX77620_RTC_H_ */
diff --git a/bdk/sec/se.c b/bdk/sec/se.c
index 3a97ddd..4ed04ec 100644
--- a/bdk/sec/se.c
+++ b/bdk/sec/se.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 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,
@@ -18,12 +18,12 @@
#include
#include "se.h"
-#include "se_t210.h"
-#include
+#include
#include
+#include
#include
+#include
#include
-#include
typedef struct _se_ll_t
{
@@ -32,6 +32,9 @@ typedef struct _se_ll_t
vu32 size;
} se_ll_t;
+se_ll_t ll_src, ll_dst;
+se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
+
static void _gf256_mul_x(void *block)
{
u8 *pdata = (u8 *)block;
@@ -48,69 +51,75 @@ static void _gf256_mul_x(void *block)
pdata[0xF] ^= 0x87;
}
+static void _gf256_mul_x_le(void *block)
+{
+ u32 *pdata = (u32 *)block;
+ u32 carry = 0;
+
+ for (u32 i = 0; i < 4; i++)
+ {
+ u32 b = pdata[i];
+ pdata[i] = (b << 1) | carry;
+ carry = b >> 31;
+ }
+
+ if (carry)
+ pdata[0x0] ^= 0x87;
+}
+
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
{
- ll->num = 0;
+ ll->num = 0;
ll->addr = addr;
ll->size = size;
}
-static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
+static void _se_ll_set(se_ll_t *src, se_ll_t *dst)
{
- SE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;
- SE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;
+ SE(SE_IN_LL_ADDR_REG) = (u32)src;
+ SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
}
static int _se_wait()
{
- while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+
+ // Wait for operation to be done.
+ while (!(SE(SE_INT_STATUS_REG) & SE_INT_OP_DONE))
;
- if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
- SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN ||
- SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR)
+
+ // Check for errors.
+ if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
+ (SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
+ (SE(SE_ERR_STATUS_REG) != 0)
+ )
+ {
return 0;
- return 1;
-}
-
-se_ll_t *ll_dst, *ll_src;
-static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
-{
- ll_dst = NULL;
- ll_src = NULL;
-
- if (dst)
- {
- ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
- _se_ll_init(ll_dst, (u32)dst, dst_size);
}
- if (src)
+ // T210B01: IRAM/TZRAM/DRAM AHB coherency WAR.
+ if (!tegra_t210 && ll_dst_ptr)
{
- ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
- _se_ll_init(ll_src, (u32)src, src_size);
- }
+ u32 timeout = get_tmr_us() + 1000000;
+ // Ensure data is out from SE.
+ while (SE(SE_STATUS_REG) & SE_STATUS_MEM_IF_BUSY)
+ {
+ if (get_tmr_us() > timeout)
+ return 0;
+ usleep(1);
+ }
- _se_ll_set(ll_dst, ll_src);
-
- SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
- SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
-
- bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
-
- SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
-
- if (is_oneshot)
- {
- int res = _se_wait();
-
- bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
-
- if (src)
- free(ll_src);
- if (dst)
- free(ll_dst);
-
- return res;
+ // Ensure data is out from AHB.
+ if (ll_dst_ptr->addr >= DRAM_START)
+ {
+ 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);
+ }
+ }
}
return 1;
@@ -120,22 +129,48 @@ static int _se_execute_finalize()
{
int res = _se_wait();
- bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
+ // Invalidate data after OP is done.
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
- if (ll_src)
- {
- free(ll_src);
- ll_src = NULL;
- }
- if (ll_dst)
- {
- free(ll_dst);
- ll_dst = NULL;
- }
+ 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)
+{
+ 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);
+ }
+
+ if (dst)
+ {
+ ll_dst_ptr = &ll_dst;
+ _se_ll_init(ll_dst_ptr, (u32)dst, dst_size);
+ }
+
+ _se_ll_set(ll_src_ptr, ll_dst_ptr);
+
+ SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
+ SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
+
+ // Flush data before starting OP.
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
+
+ SE(SE_OPERATION_REG) = op;
+
+ if (is_oneshot)
+ return _se_execute_finalize();
+
+ return 1;
+}
+
static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
{
return _se_execute(op, dst, dst_size, src, src_size, true);
@@ -146,83 +181,81 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
if (!src || !dst)
return 0;
- u8 *block = (u8 *)malloc(0x10);
- memset(block, 0, 0x10);
+ u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
- SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
+ SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
memcpy(block, src, src_size);
- int res = _se_execute_oneshot(op, block, 0x10, block, 0x10);
+ int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
memcpy(dst, block, dst_size);
- free(block);
return res;
}
-static void _se_aes_ctr_set(void *ctr)
+static void _se_aes_ctr_set(const void *ctr)
{
- u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
- memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE);
+ u32 data[SE_AES_IV_SIZE / 4];
+ memcpy(data, ctr, SE_AES_IV_SIZE);
- for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
- SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i];
+ for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++)
+ SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i];
}
void se_rsa_acc_ctrl(u32 rs, u32 flags)
{
- if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG)
- SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) =
- ((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
- ((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
- if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
- SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs);
+ if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
+ SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * 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)
+ SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
}
void se_key_acc_ctrl(u32 ks, u32 flags)
{
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
- SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
- if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
- SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks);
+ SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * 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_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks);
+ return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
}
-void se_aes_key_set(u32 ks, void *key, u32 size)
+void se_aes_key_set(u32 ks, const void *key, u32 size)
{
- u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
+ u32 data[SE_AES_MAX_KEY_SIZE / 4];
memcpy(data, key, size);
for (u32 i = 0; i < (size / 4); i++)
{
- SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
- SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
+ SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
+ SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
}
}
-void se_aes_iv_set(u32 ks, void *iv)
+void se_aes_iv_set(u32 ks, const void *iv)
{
- u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
- memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE);
+ u32 data[SE_AES_IV_SIZE / 4];
+ memcpy(data, iv, SE_AES_IV_SIZE);
- for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
+ for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
{
- SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
- SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
+ 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];
}
}
void se_aes_key_get(u32 ks, void *key, u32 size)
{
- u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
+ u32 data[SE_AES_MAX_KEY_SIZE / 4];
for (u32 i = 0; i < (size / 4); i++)
{
- SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
- data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
+ SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
+ data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG);
}
memcpy(key, data, size);
@@ -230,78 +263,107 @@ void se_aes_key_get(u32 ks, void *key, u32 size)
void se_aes_key_clear(u32 ks)
{
- for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++)
+ for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++)
{
- SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
- SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
+ SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
+ SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
}
}
void se_aes_iv_clear(u32 ks)
{
- for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
+ for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
{
- SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
- SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
+ 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)
+{
+ 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_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
- SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
- SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
+ 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_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
- return _se_execute_oneshot(OP_START, NULL, 0, input, 0x10);
+ return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
+}
+
+int se_aes_crypt_hash(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_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);
+ }
+ 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_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_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
+ 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_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
+ 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_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
+ 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_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
- SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
+ 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);
}
else
{
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
- SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
+ 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(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
+ 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_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
{
- return se_aes_crypt_ecb(ks, enc, dst, 0x10, src, 0x10);
+ return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE);
}
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)
{
- SE(SE_SPARE_0_REG_OFFSET) = 1;
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = 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_VAL(1);
+ 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_CRYPTO_CTR_CNTN(1);
_se_aes_ctr_set(ctr);
u32 src_size_aligned = src_size & 0xFFFFFFF0;
@@ -309,128 +371,196 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
if (src_size_aligned)
{
- SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- if (!_se_execute_oneshot(OP_START, dst, dst_size, src, 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(OP_START, dst + src_size_aligned,
+ 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;
}
-int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
+int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
{
int res = 0;
- u8 *tweak = (u8 *)malloc(0x10);
+ u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
+ u8 *tweak = (u8 *)tmp;
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
- //Generate tweak.
+ // Generate tweak.
for (int i = 0xF; i >= 0; i--)
{
tweak[i] = sec & 0xFF;
sec >>= 8;
}
- if (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak))
+ if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
goto out;
- //We are assuming a 0x10-aligned sector size in this implementation.
- for (u32 i = 0; i < secsize / 0x10; i++)
+ // 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 < 0x10; j++)
+ for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
pdst[j] = psrc[j] ^ tweak[j];
- if (!se_aes_crypt_block_ecb(ks2, enc, pdst, pdst))
+ if (!se_aes_crypt_block_ecb(crypt_ks, enc, pdst, pdst))
goto out;
- for (u32 j = 0; j < 0x10; j++)
+ for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
pdst[j] = pdst[j] ^ tweak[j];
_gf256_mul_x(tweak);
- psrc += 0x10;
- pdst += 0x10;
+ psrc += SE_AES_BLOCK_SIZE;
+ pdst += SE_AES_BLOCK_SIZE;
}
res = 1;
-out:;
- free(tweak);
+out:
return res;
}
-int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
+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)
+{
+ u32 *pdst = (u32 *)dst;
+ u32 *psrc = (u32 *)src;
+ u32 *ptweak = (u32 *)tweak;
+
+ if (regen_tweak)
+ {
+ for (int i = 0xF; i >= 0; i--)
+ {
+ tweak[i] = sec & 0xFF;
+ sec >>= 8;
+ }
+ if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
+ return 0;
+ }
+
+ // tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls.
+ for (u32 i = 0; i < (tweak_exp << 5); i++)
+ _gf256_mul_x_le(tweak);
+
+ u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4)));
+ memcpy(orig_tweak, tweak, SE_KEY_128_SIZE);
+
+ // 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++)
+ pdst[j] = psrc[j] ^ ptweak[j];
+
+ _gf256_mul_x_le(tweak);
+ psrc += 4;
+ pdst += 4;
+ }
+
+ if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size))
+ return 0;
+
+ pdst = (u32 *)dst;
+ ptweak = (u32 *)orig_tweak;
+ for (u32 i = 0; i < (sec_size >> 4); i++)
+ {
+ for (u32 j = 0; j < 4; j++)
+ pdst[j] = pdst[j] ^ ptweak[j];
+
+ _gf256_mul_x_le(orig_tweak);
+ pdst += 4;
+ }
+
+ return 1;
+}
+
+int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 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(ks1, ks2, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
+ if (!se_aes_xts_crypt_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))
return 0;
return 1;
}
+static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
+{
+ 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)));
+ 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)
{
int res;
- u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
+ 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;
+ }
+
// Setup config for SHA256.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
- SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg;
- SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
+ 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.
- SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3);
- SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29);
- SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
- SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
+ 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_OFFSET) = (u32)(total_size << 3);
- SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29);
- SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
- SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
+ SE(SE_SHA_MSG_LEFT_0_REG) = (u32)(total_size << 3);
+ SE(SE_SHA_MSG_LEFT_1_REG) = (u32)(total_size >> 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_OFFSET) = msg_left[0];
- SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
+ SE(SE_SHA_MSG_LEFT_0_REG) = msg_left[0];
+ SE(SE_SHA_MSG_LEFT_1_REG) = msg_left[1];
// Restore hash reg.
- memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE);
- for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
- SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
+ 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.
- res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot);
+ res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
if (is_oneshot)
- {
- // Backup message left.
- if (msg_left)
- {
- msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
- msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
- }
-
- // Copy output hash.
- for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
- hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
- memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
- }
+ se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@@ -442,20 +572,9 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{
- u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize();
- // Backup message left.
- if (msg_left)
- {
- msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
- msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
- }
-
- // Copy output hash.
- for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
- hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
- memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
+ se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@@ -463,18 +582,17 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
int se_gen_prng128(void *dst)
{
// Setup config for X931 PRNG.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
+ 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;
- SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL);
- //SE(SE_RNG_SRC_CONFIG_REG_OFFSET) =
- // SE_RNG_SRC_CONFIG_ENT_SRC(RNG_SRC_RO_ENT_ENABLE) | SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE);
- SE(SE_RNG_RESEED_INTERVAL_REG_OFFSET) = 1;
-
- SE(SE_BLOCK_COUNT_REG_OFFSET) = (16 >> 4) - 1;
+ SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1;
// Trigger the operation.
- return _se_execute_oneshot(OP_START, dst, 16, NULL, 0);
+ return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0);
}
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
@@ -482,43 +600,43 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
// Set Secure Random Key.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
- SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
- SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
+ SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
+ SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
+ SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute_oneshot(OP_START, NULL, 0, NULL, 0);
+ _se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0);
// Save AES keys.
- SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | 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);
- for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++)
+ for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++)
{
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
- (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
+ SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
+ SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
- memcpy(keys + i * keysize, aligned_buf, 0x10);
+ _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
+ memcpy(keys + i * keysize, aligned_buf, SE_AES_BLOCK_SIZE);
- if (keysize > 0x10)
+ if (keysize > SE_KEY_128_SIZE)
{
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
- (i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
+ SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
+ SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
- memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
+ _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
+ memcpy(keys + i * keysize + SE_AES_BLOCK_SIZE, aligned_buf, SE_AES_BLOCK_SIZE);
}
}
// Save SRK to PMC secure scratches.
- SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
- SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(SRK);
+ SE(SE_CRYPTO_LAST_BLOCK) = 0;
+ _se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
// End context save.
- SE(SE_CONFIG_REG_OFFSET) = 0;
- _se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ SE(SE_CONFIG_REG) = 0;
+ _se_execute_oneshot(SE_OP_CTX_SAVE, NULL, 0, NULL, 0);
// Get SRK.
u32 srk[4];
@@ -529,7 +647,67 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Decrypt context.
se_aes_key_clear(3);
- se_aes_key_set(3, srk, 0x10);
- se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize);
+ 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_key_clear(3);
}
+
+int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
+{
+ int res = 0;
+
+ u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0};
+ u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
+ u8 *key = (u8 *)tmp1;
+ u8 *last_block = (u8 *)tmp2;
+
+ se_aes_iv_clear(ks);
+ se_aes_iv_updated_clear(ks);
+
+ // Generate sub key
+ if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
+ goto out;
+
+ _gf256_mul_x(key);
+ if (src_size & 0xF)
+ _gf256_mul_x(key);
+
+ 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;
+ 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_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
+ }
+
+ if (src_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);
+ }
+
+ for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
+ last_block[i] ^= key[i];
+
+ SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
+ res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
+
+ u32 *dst32 = (u32 *)dst;
+ for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
+ dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
+
+out:
+ return res;
+}
diff --git a/bdk/sec/se.h b/bdk/sec/se.h
index 4d3a92c..36b057b 100644
--- a/bdk/sec/se.h
+++ b/bdk/sec/se.h
@@ -1,41 +1,49 @@
/*
-* Copyright (c) 2018 naehrwert
-*
-* 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 .
-*/
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2019-2022 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 .
+ */
#ifndef _SE_H_
#define _SE_H_
+#include "se_t210.h"
#include
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);
-void se_aes_key_set(u32 ks, void *key, u32 size);
-void se_aes_iv_set(u32 ks, void *iv);
+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_key_get(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks);
void se_aes_iv_clear(u32 ks);
-int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
-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_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);
+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);
#endif
diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h
index 6fbf1b0..317c4fa 100644
--- a/bdk/sec/se_t210.h
+++ b/bdk/sec/se_t210.h
@@ -1,400 +1,328 @@
/*
-* Driver for Tegra Security Engine
-*
-* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.
-*
-* 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.
-*/
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018-2021 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 .
+ */
-#ifndef _CRYPTO_TEGRA_SE_H
-#define _CRYPTO_TEGRA_SE_H
+#ifndef _SE_T210_H
+#define _SE_T210_H
#include
-#define TEGRA_SE_CRA_PRIORITY 300
-#define TEGRA_SE_COMPOSITE_PRIORITY 400
-#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50
-#define SE_MAX_SRC_SG_COUNT 50
-#define SE_MAX_DST_SG_COUNT 50
+#define SE_CRYPTO_QUEUE_LENGTH 50
+#define SE_MAX_SRC_SG_COUNT 50
+#define SE_MAX_DST_SG_COUNT 50
-#define TEGRA_SE_KEYSLOT_COUNT 16
-#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
+#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
+#define SE_AES_MIN_KEY_SIZE 16
+#define SE_AES_MAX_KEY_SIZE 32
+#define SE_KEY_128_SIZE 16
+#define SE_KEY_192_SIZE 24
+#define SE_KEY_256_SIZE 32
+#define SE_SHA_192_SIZE 24
+#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_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE)
+
+#define SE_AES_CMAC_DIGEST_SIZE 16
+#define SE_RSA512_DIGEST_SIZE 64
+#define SE_RSA1024_DIGEST_SIZE 128
+#define SE_RSA1536_DIGEST_SIZE 192
+#define SE_RSA2048_DIGEST_SIZE 256
+
+#define DECRYPT 0
+#define ENCRYPT 1
/* SE register definitions */
-#define SE_SECURITY_0 0x000
-#define SE_KEY_SCHED_READ_SHIFT 3
+#define SE_SE_SECURITY_REG 0x000
+#define SE_HARD_SETTING BIT(0)
+#define SE_ENG_DIS BIT(1)
+#define SE_PERKEY_SETTING BIT(2)
+#define SE_SOFT_SETTING BIT(16)
-#define SE_TZRAM_SECURITY_0 0x004
+#define SE_TZRAM_SECURITY_REG 0x004
+#define SE_TZRAM_HARD_SETTING BIT(0)
+#define SE_TZRAM_ENG_DIS BIT(1)
-#define SE_CONFIG_REG_OFFSET 0x014
-#define SE_CONFIG_ENC_ALG_SHIFT 12
-#define SE_CONFIG_DEC_ALG_SHIFT 8
-#define ALG_AES_ENC 1
-#define ALG_RNG 2
-#define ALG_SHA 3
-#define ALG_RSA 4
-#define ALG_NOP 0
-#define ALG_AES_DEC 1
-#define SE_CONFIG_ENC_ALG(x) ((x) << SE_CONFIG_ENC_ALG_SHIFT)
-#define SE_CONFIG_DEC_ALG(x) ((x) << SE_CONFIG_DEC_ALG_SHIFT)
-#define SE_CONFIG_DST_SHIFT 2
-#define DST_MEMORY 0
-#define DST_HASHREG 1
-#define DST_KEYTAB 2
-#define DST_SRK 3
-#define DST_RSAREG 4
-#define SE_CONFIG_DST(x) ((x) << SE_CONFIG_DST_SHIFT)
-#define SE_CONFIG_ENC_MODE_SHIFT 24
-#define SE_CONFIG_DEC_MODE_SHIFT 16
-#define MODE_KEY128 0
-#define MODE_KEY192 1
-#define MODE_KEY256 2
-#define MODE_SHA1 0
-#define MODE_SHA224 4
-#define MODE_SHA256 5
-#define MODE_SHA384 6
-#define MODE_SHA512 7
-#define SE_CONFIG_ENC_MODE(x) ((x) << SE_CONFIG_ENC_MODE_SHIFT)
-#define SE_CONFIG_DEC_MODE(x) ((x) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_OPERATION_REG 0x008
+#define SE_OP_ABORT 0
+#define SE_OP_START 1
+#define SE_OP_RESTART_OUT 2
+#define SE_OP_CTX_SAVE 3
+#define SE_OP_RESTART_IN 4
-#define SE_RNG_CONFIG_REG_OFFSET 0x340
-#define RNG_MODE_SHIFT 0
-#define RNG_MODE_NORMAL 0
-#define RNG_MODE_FORCE_INSTANTION 1
-#define RNG_MODE_FORCE_RESEED 2
-#define SE_RNG_CONFIG_MODE(x) ((x) << RNG_MODE_SHIFT)
-#define RNG_SRC_SHIFT 2
-#define RNG_SRC_NONE 0
-#define RNG_SRC_ENTROPY 1
-#define RNG_SRC_LFSR 2
-#define SE_RNG_CONFIG_SRC(x) ((x) << RNG_SRC_SHIFT)
+#define SE_INT_ENABLE_REG 0x00C
+#define SE_INT_STATUS_REG 0x010
+#define SE_INT_IN_LL_BUF_RD BIT(0)
+#define SE_INT_IN_DONE BIT(1)
+#define SE_INT_OUT_LL_BUF_WR BIT(2)
+#define SE_INT_OUT_DONE BIT(3)
+#define SE_INT_OP_DONE BIT(4)
+#define SE_INT_RESEED_NEEDED BIT(5)
+#define SE_INT_ERR_STAT BIT(16)
-#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344
-#define RNG_SRC_RO_ENT_SHIFT 1
-#define RNG_SRC_RO_ENT_ENABLE 1
-#define RNG_SRC_RO_ENT_DISABLE 0
-#define SE_RNG_SRC_CONFIG_ENT_SRC(x) ((x) << RNG_SRC_RO_ENT_SHIFT)
-#define RNG_SRC_RO_ENT_LOCK_SHIFT 0
-#define RNG_SRC_RO_ENT_LOCK_ENABLE 1
-#define RNG_SRC_RO_ENT_LOCK_DISABLE 0
-#define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) ((x) << RNG_SRC_RO_ENT_LOCK_SHIFT)
+#define SE_CONFIG_REG 0x014
+#define DST_MEMORY 0
+#define DST_HASHREG 1
+#define DST_KEYTABLE 2
+#define DST_SRK 3
+#define DST_RSAREG 4
+#define SE_CONFIG_DST(x) ((x) << 2)
+#define ALG_NOP 0
+#define ALG_AES_DEC 1
+#define SE_CONFIG_DEC_ALG(x) ((x) << 8)
+#define ALG_NOP 0
+#define ALG_AES_ENC 1
+#define ALG_RNG 2
+#define ALG_SHA 3
+#define ALG_RSA 4
+#define SE_CONFIG_ENC_ALG(x) ((x) << 12)
+#define MODE_KEY128 0
+#define MODE_KEY192 1
+#define MODE_KEY256 2
+#define MODE_SHA1 0
+#define MODE_SHA224 4
+#define MODE_SHA256 5
+#define MODE_SHA384 6
+#define MODE_SHA512 7
+#define SE_CONFIG_DEC_MODE(x) ((x) << 16)
+#define SE_CONFIG_ENC_MODE(x) ((x) << 24)
-#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348
+#define SE_IN_LL_ADDR_REG 0x018
+#define SE_IN_CUR_BYTE_ADDR_REG 0x01C
+#define SE_IN_CUR_LL_ID_REG 0x020
+#define SE_OUT_LL_ADDR_REG 0x024
+#define SE_OUT_CUR_BYTE_ADDR_REG 0x028
+#define SE_OUT_CUR_LL_ID_REG 0x02C
-#define SE_KEYTABLE_REG_OFFSET 0x31c
-#define SE_KEYTABLE_SLOT_SHIFT 4
-#define SE_KEYTABLE_SLOT(x) ((x) << SE_KEYTABLE_SLOT_SHIFT)
-#define SE_KEYTABLE_QUAD_SHIFT 2
-#define QUAD_KEYS_128 0
-#define QUAD_KEYS_192 1
-#define QUAD_KEYS_256 1
-#define QUAD_ORG_IV 2
-#define QUAD_UPDTD_IV 3
-#define SE_KEYTABLE_QUAD(x) ((x) << SE_KEYTABLE_QUAD_SHIFT)
-#define SE_KEYTABLE_OP_TYPE_SHIFT 9
-#define OP_READ 0
-#define OP_WRITE 1
-#define SE_KEYTABLE_OP_TYPE(x) ((x) << SE_KEYTABLE_OP_TYPE_SHIFT)
-#define SE_KEYTABLE_TABLE_SEL_SHIFT 8
-#define TABLE_KEYIV 0
-#define TABLE_SCHEDULE 1
-#define SE_KEYTABLE_TABLE_SEL(x) ((x) << SE_KEYTABLE_TABLE_SEL_SHIFT)
-#define SE_KEYTABLE_PKT_SHIFT 0
-#define SE_KEYTABLE_PKT(x) ((x) << SE_KEYTABLE_PKT_SHIFT)
+#define SE_HASH_RESULT_REG 0x030
+#define SE_HASH_RESULT_REG_COUNT 16
-#define SE_OP_DONE_SHIFT 4
-#define OP_DONE 1
-#define SE_OP_DONE(x, y) ((x) && ((y) << SE_OP_DONE_SHIFT))
+#define SE_CONTEXT_SAVE_CONFIG_REG 0x070
+#define KEYS_0_3 0
+#define KEYS_4_7 1
+#define ORIGINAL_IV 2
+#define UPDATED_IV 3
+#define SE_CONTEXT_AES_WORD_QUAD(x) ((x) << 0)
+#define SE_CONTEXT_AES_KEY_INDEX(x) ((x) << 8)
+#define KEYS_0_3 0
+#define KEYS_4_7 1
+#define KEYS_8_11 2
+#define KEYS_12_15 3
+#define SE_CONTEXT_RSA_WORD_QUAD(x) ((x) << 12)
+#define SLOT0_EXPONENT 0
+#define SLOT0_MODULUS 1
+#define SLOT1_EXPONENT 2
+#define SLOT1_MODULUS 3
+#define SE_CONTEXT_RSA_KEY_INDEX(x) ((x) << 16)
+#define STICKY_0_3 0
+#define STICKY_4_7 1
+#define SE_CONTEXT_STICKY_WORD_QUAD(x) ((x) << 24)
+#define STICKY_BITS 0
+#define RSA_KEYTABLE 1
+#define AES_KEYTABLE 2
+#define MEM 4
+#define SRK 6
+#define SE_CONTEXT_SRC(x) ((x) << 29)
-#define SE_CRYPTO_LAST_BLOCK 0x080
+#define SE_CTX_SAVE_AUTO_T210B01_REG 0x074
+#define SE_CTX_SAVE_AUTO_ENABLE BIT(0)
+#define SE_CTX_SAVE_AUTO_LOCK BIT(8)
+#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16)
-#define SE_CRYPTO_REG_OFFSET 0x304
-#define SE_CRYPTO_HASH_SHIFT 0
-#define HASH_DISABLE 0
-#define HASH_ENABLE 1
-#define SE_CRYPTO_HASH(x) ((x) << SE_CRYPTO_HASH_SHIFT)
-#define SE_CRYPTO_XOR_POS_SHIFT 1
-#define XOR_BYPASS 0
-#define XOR_TOP 2
-#define XOR_BOTTOM 3
-#define SE_CRYPTO_XOR_POS(x) ((x) << SE_CRYPTO_XOR_POS_SHIFT)
-#define SE_CRYPTO_INPUT_SEL_SHIFT 3
-#define INPUT_AHB 0
-#define INPUT_RANDOM 1
-#define INPUT_AESOUT 2
-#define INPUT_LNR_CTR 3
-#define SE_CRYPTO_INPUT_SEL(x) ((x) << SE_CRYPTO_INPUT_SEL_SHIFT)
-#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5
-#define VCTRAM_AHB 0
-#define VCTRAM_AESOUT 2
-#define VCTRAM_PREVAHB 3
-#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
-#define SE_CRYPTO_IV_SEL_SHIFT 7
-#define IV_ORIGINAL 0
-#define IV_UPDATED 1
-#define SE_CRYPTO_IV_SEL(x) ((x) << SE_CRYPTO_IV_SEL_SHIFT)
-#define SE_CRYPTO_CORE_SEL_SHIFT 8
-#define CORE_DECRYPT 0
-#define CORE_ENCRYPT 1
-#define SE_CRYPTO_CORE_SEL(x) ((x) << SE_CRYPTO_CORE_SEL_SHIFT)
-#define SE_CRYPTO_CTR_VAL_SHIFT 11
-#define SE_CRYPTO_CTR_VAL(x) ((x) << SE_CRYPTO_CTR_VAL_SHIFT)
-#define SE_CRYPTO_KEY_INDEX_SHIFT 24
-#define SE_CRYPTO_KEY_INDEX(x) ((x) << SE_CRYPTO_KEY_INDEX_SHIFT)
-#define SE_CRYPTO_CTR_CNTN_SHIFT 11
-#define SE_CRYPTO_CTR_CNTN(x) ((x) << SE_CRYPTO_CTR_CNTN_SHIFT)
+#define SE_CRYPTO_LAST_BLOCK 0x080
-#define SE_CRYPTO_CTR_REG_COUNT 4
-#define SE_CRYPTO_CTR_REG_OFFSET 0x308
-
-#define SE_OPERATION_REG_OFFSET 0x008
-#define SE_OPERATION_SHIFT 0
-#define OP_ABORT 0
-#define OP_START 1
-#define OP_RESTART 2
-#define OP_CTX_SAVE 3
-#define OP_RESTART_IN 4
-#define SE_OPERATION(x) ((x) << SE_OPERATION_SHIFT)
-
-#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070
-#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0
-#define KEYS_0_3 0
-#define KEYS_4_7 1
-#define ORIG_IV 2
-#define UPD_IV 3
-#define SE_CONTEXT_SAVE_WORD_QUAD(x) ((x) << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)
-
-#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8
-#define SE_CONTEXT_SAVE_KEY_INDEX(x) ((x) << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)
-
-#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT 24
-#define STICKY_0_3 0
-#define STICKY_4_7 1
-#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \
- ((x) << SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT)
-
-#define SE_CONTEXT_SAVE_SRC_SHIFT 29
-#define STICKY_BITS 0
-#define KEYTABLE 2
-#define MEM 4
-#define SRK 6
-
-#define RSA_KEYTABLE 1
-#define AES_KEYTABLE 2
-#define SE_CONTEXT_SAVE_SRC(x) ((x) << SE_CONTEXT_SAVE_SRC_SHIFT)
-
-#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16
-#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \
- ((x) << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)
-
-#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12
-#define SE_CONTEXT_RSA_WORD_QUAD(x) \
- ((x) << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)
-
-#define SE_CTX_SAVE_AUTO 0x074
-#define CTX_SAVE_AUTO_ENABLE BIT(0)
-#define CTX_SAVE_AUTO_LOCK BIT(8)
-#define CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16)
-
-#define SE_INT_ENABLE_REG_OFFSET 0x00c
-#define SE_INT_STATUS_REG_OFFSET 0x010
-#define INT_DISABLE 0
-#define INT_ENABLE 1
-#define INT_UNSET 0
-#define INT_SET 1
-#define SE_INT_OP_DONE_SHIFT 4
-#define SE_INT_OP_DONE(x) ((x) << SE_INT_OP_DONE_SHIFT)
-#define SE_INT_ERROR_SHIFT 16
-#define SE_INT_ERROR(x) ((x) << SE_INT_ERROR_SHIFT)
-
-#define SE_STATUS_0 0x800
-#define SE_STATUS_0_STATE_WAIT_IN 3
-
-#define SE_ERR_STATUS_0 0x804
-#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0
-
-#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
-#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
-#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \
- ((x) << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
-
-#define SE_KEY_INDEX_SHIFT 8
-#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) ((x) << SE_KEY_INDEX_SHIFT)
-
-#define SE_IN_LL_ADDR_REG_OFFSET 0x018
-#define SE_OUT_LL_ADDR_REG_OFFSET 0x024
-
-#define SE_KEYTABLE_DATA0_REG_OFFSET 0x320
-#define SE_KEYTABLE_REG_MAX_DATA 16
-
-#define SE_BLOCK_COUNT_REG_OFFSET 0x318
-
-#define SE_SPARE_0_REG_OFFSET 0x80c
-
-#define SE_SHA_CONFIG_REG_OFFSET 0x200
+#define SE_SHA_CONFIG_REG 0x200
#define SHA_CONTINUE 0
#define SHA_INIT_HASH 1
-#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204
-#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208
-#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C
-#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210
-#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214
-#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218
-#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C
-#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220
+#define SE_SHA_MSG_LENGTH_0_REG 0x204
+#define SE_SHA_MSG_LENGTH_1_REG 0x208
+#define SE_SHA_MSG_LENGTH_2_REG 0x20C
+#define SE_SHA_MSG_LENGTH_3_REG 0x210
+#define SE_SHA_MSG_LEFT_0_REG 0x214
+#define SE_SHA_MSG_LEFT_1_REG 0x218
+#define SE_SHA_MSG_LEFT_2_REG 0x21C
+#define SE_SHA_MSG_LEFT_3_REG 0x220
-#define SE_HASH_RESULT_REG_COUNT 16
-#define SE_HASH_RESULT_REG_OFFSET 0x030
-#define TEGRA_SE_KEY_256_SIZE 32
-#define TEGRA_SE_KEY_192_SIZE 24
-#define TEGRA_SE_KEY_128_SIZE 16
-#define TEGRA_SE_AES_BLOCK_SIZE 16
-#define TEGRA_SE_AES_MIN_KEY_SIZE 16
-#define TEGRA_SE_AES_MAX_KEY_SIZE 32
-#define TEGRA_SE_AES_IV_SIZE 16
-#define TEGRA_SE_SHA_512_SIZE 64
-#define TEGRA_SE_SHA_384_SIZE 48
-#define TEGRA_SE_SHA_256_SIZE 32
-#define TEGRA_SE_SHA_192_SIZE 24
-#define TEGRA_SE_RNG_IV_SIZE 16
-#define TEGRA_SE_RNG_DT_SIZE 16
-#define TEGRA_SE_RNG_KEY_SIZE 16
-#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \
- TEGRA_SE_RNG_KEY_SIZE + \
- TEGRA_SE_RNG_DT_SIZE)
+#define SE_CRYPTO_SECURITY_PERKEY_REG 0x280
+#define SE_KEY_LOCK_FLAG 0x80
+#define SE_CRYPTO_KEYTABLE_ACCESS_REG 0x284
+#define SE_CRYPTO_KEYTABLE_ACCESS_REG_COUNT 16
+#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
+#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
+#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
+#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
+#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
+#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
+#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
+#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
-#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
-#define TEGRA_SE_RSA512_DIGEST_SIZE 64
-#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
-#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
-#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
+#define SE_CRYPTO_CONFIG_REG 0x304
+#define HASH_DISABLE 0
+#define HASH_ENABLE 1
+#define SE_CRYPTO_HASH(x) ((x) << 0)
+#define XOR_BYPASS 0
+#define XOR_TOP 2
+#define XOR_BOTTOM 3
+#define SE_CRYPTO_XOR_POS(x) ((x) << 1)
+#define INPUT_MEMORY 0
+#define INPUT_RANDOM 1
+#define INPUT_AESOUT 2
+#define INPUT_LNR_CTR 3
+#define SE_CRYPTO_INPUT_SEL(x) ((x) << 3)
+#define VCTRAM_MEM 0
+#define VCTRAM_AESOUT 2
+#define VCTRAM_PREVMEM 3
+#define SE_CRYPTO_VCTRAM_SEL(x) ((x) << 5)
+#define IV_ORIGINAL 0
+#define IV_UPDATED 1
+#define SE_CRYPTO_IV_SEL(x) ((x) << 7)
+#define CORE_DECRYPT 0
+#define CORE_ENCRYPT 1
+#define SE_CRYPTO_CORE_SEL(x) ((x) << 8)
+#define SE_CRYPTO_KEYSCH_BYPASS BIT(10)
+#define SE_CRYPTO_CTR_CNTN(x) ((x) << 11)
+#define SE_CRYPTO_KEY_INDEX(x) ((x) << 24)
+#define MEMIF_AHB 0
+#define MEMIF_MCCIF 1
+#define SE_CRYPTO_MEMIF(x) ((x) << 31)
-#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
-#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
+#define SE_CRYPTO_LINEAR_CTR_REG 0x308
+#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4
-#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
-#define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
-#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
-#define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
-#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
-#define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
-#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
-#define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
-#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
+#define SE_CRYPTO_BLOCK_COUNT_REG 0x318
-#define SE_KEY_READ_DISABLE_SHIFT 0
-#define SE_KEY_UPDATE_DISABLE_SHIFT 1
+#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C
+#define SE_KEYTABLE_PKT(x) ((x) << 0)
+#define KEYS_0_3 0
+#define KEYS_4_7 1
+#define ORIGINAL_IV 2
+#define UPDATED_IV 3
+#define SE_KEYTABLE_QUAD(x) ((x) << 2)
+#define SE_KEYTABLE_SLOT(x) ((x) << 4)
-#define SE_CONTEXT_BUFER_SIZE 1072
-#define SE_CONTEXT_DRBG_BUFER_SIZE 2112
+#define SE_CRYPTO_KEYTABLE_DATA_REG 0x320
-#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET 0
-#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE 16
-#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET \
- (SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)
-#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE 16
+#define SE_CRYPTO_KEYTABLE_DST_REG 0x330
+#define KEYS_0_3 0
+#define KEYS_4_7 1
+#define ORIGINAL_IV 2
+#define UPDATED_IV 3
+#define SE_KEYTABLE_DST_WORD_QUAD(x) ((x) << 0)
+#define SE_KEYTABLE_DST_KEY_INDEX(x) ((x) << 8)
-#define SE_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
- SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
-#define SE11_CONTEXT_SAVE_KEYS_OFFSET (SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \
- SE_CONTEXT_SAVE_STICKY_BITS_SIZE + \
- SE_CONTEXT_SAVE_STICKY_BITS_SIZE)
+#define SE_RNG_CONFIG_REG 0x340
+#define MODE_NORMAL 0
+#define MODE_FORCE_INSTANTION 1
+#define MODE_FORCE_RESEED 2
+#define SE_RNG_CONFIG_MODE(x) ((x) << 0)
+#define SRC_NONE 0
+#define SRC_ENTROPY 1
+#define SRC_LFSR 2
+#define SE_RNG_CONFIG_SRC(x) ((x) << 2)
-#define SE_CONTEXT_SAVE_KEY_LENGTH 512
-#define SE_CONTEXT_ORIGINAL_IV_OFFSET (SE_CONTEXT_SAVE_KEYS_OFFSET + \
- SE_CONTEXT_SAVE_KEY_LENGTH)
-#define SE11_CONTEXT_ORIGINAL_IV_OFFSET (SE11_CONTEXT_SAVE_KEYS_OFFSET + \
- SE_CONTEXT_SAVE_KEY_LENGTH)
+#define SE_RNG_SRC_CONFIG_REG 0x344
+#define RO_ENTR_LOCK_DISABLE 0
+#define RO_ENTR_LOCK_ENABLE 1
+#define SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(x) ((x) << 0)
+#define RO_ENTR_DISABLE 0
+#define RO_ENTR_ENABLE 1
+#define SE_RNG_SRC_CONFIG_ENTR_SRC(x) ((x) << 1)
+#define RO_HW_DIS_CYA_DISABLE 0
+#define RO_HW_DIS_CYA_ENABLE 1
+#define SE_RNG_SRC_CONFIG_HW_DIS_CYA(x) ((x) << 2)
+#define SE_RNG_SRC_CONFIG_ENTR_SUBSMPL(x) ((x) << 4)
+#define SE_RNG_SRC_CONFIG_ENTR_DATA_FLUSH BIT(8)
-#define SE_CONTEXT_ORIGINAL_IV_LENGTH 256
+#define SE_RNG_RESEED_INTERVAL_REG 0x348
-#define SE_CONTEXT_UPDATED_IV_OFFSET (SE_CONTEXT_ORIGINAL_IV_OFFSET + \
- SE_CONTEXT_ORIGINAL_IV_LENGTH)
-#define SE11_CONTEXT_UPDATED_IV_OFFSET (SE11_CONTEXT_ORIGINAL_IV_OFFSET + \
- SE_CONTEXT_ORIGINAL_IV_LENGTH)
+#define SE_RSA_CONFIG 0x400
+#define RSA_KEY_SLOT_ONE 0
+#define RSA_KEY_SLOT_TW0 1
+#define RSA_KEY_SLOT(x) ((x) << 24)
-#define SE_CONTEXT_UPDATED_IV_LENGTH 256
+#define SE_RSA_KEY_SIZE_REG 0x404
+#define RSA_KEY_WIDTH_512 0
+#define RSA_KEY_WIDTH_1024 1
+#define RSA_KEY_WIDTH_1536 2
+#define RSA_KEY_WIDTH_2048 3
-#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \
- SE_CONTEXT_UPDATED_IV_LENGTH)
-#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \
- (SE11_CONTEXT_UPDATED_IV_OFFSET + \
- SE_CONTEXT_UPDATED_IV_LENGTH)
+#define SE_RSA_EXP_SIZE_REG 0x408
-#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET
+#define SE_RSA_SECURITY_PERKEY_REG 0x40C
+#define SE_RSA_KEY_LOCK_FLAG 0x80
+#define SE_RSA_KEYTABLE_ACCESS_REG 0x410
+#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
+#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
+#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2)
+#define SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
+#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
+#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG | SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG)
-#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH 1024
+#define SE_RSA_KEYTABLE_ADDR_REG 0x420
+#define SE_RSA_KEYTABLE_PKT(x) ((x) << 0)
+#define RSA_KEY_TYPE_EXP 0
+#define RSA_KEY_TYPE_MOD 1
+#define SE_RSA_KEYTABLE_TYPE(x) ((x) << 6)
+#define RSA_KEY_NUM(x) ((x) << 7)
+#define RSA_KEY_INPUT_MODE_REG 0
+#define RSA_KEY_INPUT_MODE_DMA 1
+#define SE_RSA_KEYTABLE_INPUT_MODE(x) ((x) << 8)
+#define RSA_KEY_READ 0
+#define RSA_KEY_WRITE 1
+#define SE_RSA_KEY_OP(x) ((x) << 10)
-#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET \
- (SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)
+#define SE_RSA_KEYTABLE_DATA_REG 0x424
-#define SE_CONTEXT_KNOWN_PATTERN_SIZE 16
+#define SE_RSA_OUTPUT_REG 0x428
+#define SE_RSA_OUTPUT_REG_COUNT 64
-#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
+#define SE_STATUS_REG 0x800
+#define SE_STATUS_STATE_IDLE 0
+#define SE_STATUS_STATE_BUSY 1
+#define SE_STATUS_STATE_WAIT_OUT 2
+#define SE_STATUS_STATE_WAIT_IN 3
+#define SE_STATUS_STATE_MASK 3
+#define SE_STATUS_MEM_IF_IDLE (0 << 2)
+#define SE_STATUS_MEM_IF_BUSY BIT(2)
-#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
-#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
+#define SE_ERR_STATUS_REG 0x804
+#define SE_ERR_STATUS_SE_NS_ACCESS BIT(0)
+#define SE_ERR_STATUS_BUSY_REG_WR BIT(1)
+#define SE_ERR_STATUS_DST BIT(2)
+#define SE_ERR_STATUS_SRK_USAGE_LIMIT BIT(3)
+#define SE_ERR_STATUS_TZRAM_NS_ACCESS BIT(24)
+#define SE_ERR_STATUS_TZRAM_ADDRESS BIT(25)
-#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
-#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
-#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
-#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
-#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2)
-#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT BIT(2)
-#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7
-#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F
+#define SE_MISC_REG 0x808
+#define SE_ENTROPY_NEXT_192BIT BIT(0)
+#define SE_ENTROPY_VN_BYPASS BIT(1)
+#define SE_CLK_OVR_ON BIT(2)
-#define SE_RSA_KEYTABLE_ADDR 0x420
-#define SE_RSA_KEYTABLE_DATA 0x424
-#define SE_RSA_OUTPUT 0x428
+#define SE_SPARE_REG 0x80C
+#define SE_ERRATA_FIX_DISABLE 0
+#define SE_ERRATA_FIX_ENABLE 1
+#define SE_ECO(x) ((x) << 0)
-#define RSA_KEY_READ 0
-#define RSA_KEY_WRITE 1
-#define SE_RSA_KEY_OP_SHIFT 10
-#define SE_RSA_KEY_OP(x) ((x) << SE_RSA_KEY_OP_SHIFT)
-
-#define RSA_KEY_INPUT_MODE_REG 0
-#define RSA_KEY_INPUT_MODE_DMA 1
-#define RSA_KEY_INPUT_MODE_SHIFT 8
-#define RSA_KEY_INPUT_MODE(x) ((x) << RSA_KEY_INPUT_MODE_SHIFT)
-
-#define RSA_KEY_SLOT_ONE 0
-#define RSA_KEY_SLOT_TW0 1
-#define RSA_KEY_NUM_SHIFT 7
-#define RSA_KEY_NUM(x) ((x) << RSA_KEY_NUM_SHIFT)
-
-#define RSA_KEY_TYPE_EXP 0
-#define RSA_KEY_TYPE_MOD 1
-#define RSA_KEY_TYPE_SHIFT 6
-#define RSA_KEY_TYPE(x) ((x) << RSA_KEY_TYPE_SHIFT)
-
-#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404
-#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408
-
-#define RSA_KEY_SLOT_SHIFT 24
-#define RSA_KEY_SLOT(x) ((x) << RSA_KEY_SLOT_SHIFT)
-#define SE_RSA_CONFIG 0x400
-
-#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0
-#define RSA_KEY_PKT_WORD_ADDR(x) ((x) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
-
-#define RSA_KEY_WORD_ADDR_SHIFT 0
-#define RSA_KEY_WORD_ADDR(x) ((x) << RSA_KEY_WORD_ADDR_SHIFT)
-
-#define SE_RSA_KEYTABLE_PKT_SHIFT 0
-#define SE_RSA_KEYTABLE_PKT(x) ((x) << SE_RSA_KEYTABLE_PKT_SHIFT)
-
-#endif /* _CRYPTO_TEGRA_SE_H */
+#endif
diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c
index b4485b1..de2dbbb 100644
--- a/bdk/sec/tsec.c
+++ b/bdk/sec/tsec.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2019 CTCaer
+ * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,20 +20,23 @@
#include "tsec.h"
#include "tsec_t210.h"
+#include
+#include
+#include
+#include
#include
#include
#include
#include
+#include
#include
-#include
-#include
-#include
-#include
+#include
// #include
#define PKG11_MAGIC 0x31314B50
-#define KB_TSEC_FW_EMU_COMPAT 6 // KB ID for HOS 6.2.0.
+
+#define TSEC_HOS_KB_620 6
static int _tsec_dma_wait_idle()
{
@@ -55,48 +58,62 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse
else
cmd = TSEC_DMATRFCMD_IMEM; // DMA IMEM (Instruction memmory)
- TSEC(TSEC_DMATRFMOFFS) = i_offset;
+ TSEC(TSEC_DMATRFMOFFS) = i_offset;
TSEC(TSEC_DMATRFFBOFFS) = pa_offset;
- TSEC(TSEC_DMATRFCMD) = cmd;
+ TSEC(TSEC_DMATRFCMD) = cmd;
return _tsec_dma_wait_idle();
}
-int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
+int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
{
int res = 0;
u8 *fwbuf = NULL;
- u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
+ u32 type = tsec_ctxt->type;
+ u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *pkg11_magic_off;
+ void *ptb;
bpmp_mmu_disable();
- bpmp_clk_rate_set(BPMP_CLK_NORMAL);
+ bpmp_clk_rate_relaxed(true);
// Enable clocks.
- clock_enable_host1x();
- usleep(2);
clock_enable_tsec();
clock_enable_sor_safe();
clock_enable_sor0();
clock_enable_sor1();
clock_enable_kfuse();
-
kfuse_wait_ready();
+ // Disable AHB aperture.
+ mc_disable_ahb_redirect();
+
+ 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);
+
+ // Enable AHB aperture and set it to full mmio.
+ mc_enable_ahb_redirect();
+ }
+
// Configure Falcon.
TSEC(TSEC_DMACTL) = 0;
TSEC(TSEC_IRQMSET) =
TSEC_IRQMSET_EXT(0xFF) |
- TSEC_IRQMSET_WDTMR |
- TSEC_IRQMSET_HALT |
- TSEC_IRQMSET_EXTERR |
- TSEC_IRQMSET_SWGEN0 |
+ TSEC_IRQMSET_WDTMR |
+ TSEC_IRQMSET_HALT |
+ TSEC_IRQMSET_EXTERR |
+ TSEC_IRQMSET_SWGEN0 |
TSEC_IRQMSET_SWGEN1;
TSEC(TSEC_IRQDEST) =
TSEC_IRQDEST_EXT(0xFF) |
- TSEC_IRQDEST_HALT |
- TSEC_IRQDEST_EXTERR |
- TSEC_IRQDEST_SWGEN0 |
+ TSEC_IRQDEST_HALT |
+ TSEC_IRQDEST_EXTERR |
+ TSEC_IRQDEST_SWGEN0 |
TSEC_IRQDEST_SWGEN1;
TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN;
if (!_tsec_dma_wait_idle())
@@ -106,13 +123,14 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
}
// Load firmware or emulate memio environment for newer TSEC fw.
- if (kb == KB_TSEC_FW_EMU_COMPAT)
+ if (type == TSEC_FW_TYPE_EMU)
TSEC(TSEC_DMATRFBASE) = (u32)tsec_ctxt->fw >> 8;
else
{
- fwbuf = (u8 *)malloc(0x4000);
+ fwbuf = (u8 *)malloc(SZ_16K);
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100);
memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size);
+
TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8;
}
@@ -125,72 +143,72 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
}
}
- if (kb == KB_TSEC_FW_EMU_COMPAT)
+ if (type == TSEC_FW_TYPE_EMU)
{
// Init SMMU translation for TSEC.
- pdir = smmu_init_for_tsec();
- smmu_init(tsec_ctxt->secmon_base);
- // Enable SMMU
- if (!smmu_is_used())
- smmu_enable();
+ ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
+ smmu_init();
+
+ // Enable SMMU.
+ smmu_enable();
// Clock reset controller.
- car = page_alloc(1);
- memcpy(car, (void *)CLOCK_BASE, 0x1000);
- car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2;
- smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE);
+ car = smmu_page_zalloc(1);
+ memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
+ car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
+ smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
// Fuse driver.
- fuse = page_alloc(1);
- memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, 0x400);
+ fuse = smmu_page_zalloc(1);
+ memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
fuse[0x82C / 4] = 0;
- fuse[0x9E0 / 4] = (1 << (kb + 2)) - 1;
- fuse[0x9E4 / 4] = (1 << (kb + 2)) - 1;
- smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE);
+ fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
+ fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
+ smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
// Power management controller.
- pmc = page_alloc(1);
- smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE);
+ pmc = smmu_page_zalloc(1);
+ smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
// Flow control.
- flowctrl = page_alloc(1);
- smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE);
+ flowctrl = smmu_page_zalloc(1);
+ smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
// Security engine.
- se = page_alloc(1);
- memcpy(se, (void *)SE_BASE, 0x1000);
- smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE);
+ se = smmu_page_zalloc(1);
+ memcpy(se, (void *)SE_BASE, SZ_PAGE);
+ smmu_map(ptb, SE_BASE, (u32)se, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Memory controller.
- mc = page_alloc(1);
- memcpy(mc, (void *)MC_BASE, 0x1000);
+ mc = smmu_page_zalloc(1);
+ memcpy(mc, (void *)MC_BASE, SZ_PAGE);
mc[MC_IRAM_BOM / 4] = 0;
- mc[MC_IRAM_TOM / 4] = 0x80000000;
- smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE);
+ mc[MC_IRAM_TOM / 4] = DRAM_START;
+ smmu_map(ptb, MC_BASE, (u32)mc, 1, SMMU_READ | SMMU_NS);
// IRAM
- iram = page_alloc(0x30);
+ iram = smmu_page_zalloc(0x30);
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
// PKG1.1 magic offset.
- pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4));
- smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE);
+ pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
+ smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Exception vectors
- evec = page_alloc(1);
- smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE);
+ evec = smmu_page_zalloc(1);
+ smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
}
// Execute firmware.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
- TSEC(TSEC_STATUS) = 0;
- TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
- TSEC(TSEC_BOOTVEC) = 0;
- TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
+ TSEC(TSEC_MAILBOX1) = 0;
+ TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
+ TSEC(TSEC_BOOTVEC) = 0;
+ TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
- if (kb == KB_TSEC_FW_EMU_COMPAT)
+ if (type == TSEC_FW_TYPE_EMU)
{
- u32 start = get_tmr_us();
- u32 k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
+ u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
+ u32 timeout = get_tmr_us() + 125000;
u32 key[16] = {0};
u32 kidx = 0;
@@ -198,21 +216,21 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
{
smmu_flush_all();
- if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4])
+ if (k != se[SE_CRYPTO_KEYTABLE_DATA_REG / 4])
{
- k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
+ k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
key[kidx++] = k;
}
// Failsafe.
- if ((u32)get_tmr_us() - start > 125000)
+ if ((u32)get_tmr_us() > timeout)
break;
}
if (kidx != 8)
{
res = -6;
- smmu_deinit_for_tsec();
+ smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
goto out_free;
}
@@ -223,12 +241,12 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
memcpy(tsec_keys, &key, 0x20);
memcpy(tsec_ctxt->pkg1, iram, 0x30000);
- smmu_deinit_for_tsec();
+ smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
// for (int i = 0; i < kidx; i++)
// gfx_printf("key %08X\n", key[i]);
- // gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
+ // gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
// u32 errst = MC(MC_ERR_STATUS);
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
@@ -244,14 +262,18 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
res = -3;
goto out_free;
}
+
u32 timeout = get_tmr_ms() + 2000;
- while (!TSEC(TSEC_STATUS))
+ while (!TSEC(TSEC_MAILBOX1))
+ {
if (get_tmr_ms() > timeout)
{
res = -4;
goto out_free;
}
- if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
+ }
+
+ if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
{
res = -5;
goto out_free;
@@ -260,23 +282,22 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
// Fetch result.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
u32 buf[4];
- buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
- buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
- buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
- buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
- SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
- SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
- SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
- SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
+ buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
+ buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
+ buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
+ buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
+ SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
+ SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
+ SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
+ SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
- memcpy(tsec_keys, &buf, 0x10);
+ memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
}
-out_free:;
+out_free:
free(fwbuf);
-out:;
-
+out:
// Disable clocks.
clock_disable_kfuse();
clock_disable_sor1();
@@ -284,7 +305,12 @@ out:;
clock_disable_sor_safe();
clock_disable_tsec();
bpmp_mmu_enable();
- bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
+ bpmp_clk_rate_relaxed(false);
+
+#ifdef BDK_MC_ENABLE_AHB_REDIRECT
+ // Re-enable AHB aperture.
+ mc_enable_ahb_redirect();
+#endif
return res;
}
diff --git a/bdk/sec/tsec.h b/bdk/sec/tsec.h
index 6206034..16aa4b7 100644
--- a/bdk/sec/tsec.h
+++ b/bdk/sec/tsec.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
-* Copyright (c) 2018 CTCaer
+* Copyright (c) 2018-2024 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,15 +20,23 @@
#include
+enum tsec_fw_type
+{
+ // Retail Hovi Keygen.
+ TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
+ TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
+ TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
+};
+
typedef struct _tsec_ctxt_t
{
void *fw;
u32 size;
+ u32 type;
void *pkg1;
u32 pkg11_off;
- u32 secmon_base;
} tsec_ctxt_t;
-int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt);
+int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
#endif
diff --git a/bdk/sec/tsec_t210.h b/bdk/sec/tsec_t210.h
index 889d0d4..96624e2 100644
--- a/bdk/sec/tsec_t210.h
+++ b/bdk/sec/tsec_t210.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018 CTCaer
+* Copyright (c) 2018-2023 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,8 +17,8 @@
#ifndef _TSEC_T210_H_
#define _TSEC_T210_H_
-#define TSEC_BOOTKEYVER 0x1040
-#define TSEC_STATUS 0x1044
+#define TSEC_MAILBOX0 0x1040
+#define TSEC_MAILBOX1 0x1044
#define TSEC_ITFEN 0x1048
#define TSEC_ITFEN_CTXEN BIT(0)
#define TSEC_ITFEN_MTHDEN BIT(1)
diff --git a/bdk/soc/actmon.c b/bdk/soc/actmon.c
new file mode 100644
index 0000000..568f82e
--- /dev/null
+++ b/bdk/soc/actmon.c
@@ -0,0 +1,172 @@
+/*
+ * Activity Monitor driver for Tegra X1
+ *
+ * Copyright (c) 2021 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 .
+ */
+
+#include "actmon.h"
+#include "clock.h"
+#include "t210.h"
+
+/* Global registers */
+#define ACTMON_GLB_STATUS 0x0
+#define ACTMON_MCCPU_MON_ACT BIT(8)
+#define ACTMON_MCALL_MON_ACT BIT(9)
+#define ACTMON_CPU_FREQ_MON_ACT BIT(10)
+#define ACTMON_APB_MON_ACT BIT(12)
+#define ACTMON_AHB_MON_ACT BIT(13)
+#define ACTMON_BPMP_MON_ACT BIT(14)
+#define ACTMON_CPU_MON_ACT BIT(15)
+#define ACTMON_MCCPU_INTR BIT(25)
+#define ACTMON_MCALL_INTR BIT(26)
+#define ACTMON_CPU_FREQ_INTR BIT(27)
+#define ACTMON_APB_INTR BIT(28)
+#define ACTMON_AHB_INTR BIT(29)
+#define ACTMON_BPMP_INTR BIT(30)
+#define ACTMON_CPU_INTR BIT(31)
+#define ACTMON_GLB_PERIOD_CTRL 0x4
+#define ACTMON_GLB_PERIOD_USEC BIT(8)
+#define ACTMON_GLB_PERIOD_SAMPLE(n) (((n) - 1) & 0xFF)
+
+/* Device Registers */
+#define ACTMON_DEV_BASE ACTMON_BASE + 0x80
+#define ACTMON_DEV_SIZE 0x40
+/* CTRL */
+#define ACTMON_DEV_CTRL_K_VAL(k) (((k) & 7) << 10)
+#define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18)
+#define ACTMON_DEV_CTRL_AT_END_EN BIT(19)
+#define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20)
+#define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21)
+#define ACTMON_DEV_CTRL_WHEN_OVERFLOW_EN BIT(22)
+#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM(n) (((n) & 7) << 23)
+#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM(n) (((n) & 7) << 26)
+#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29)
+#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30)
+#define ACTMON_DEV_CTRL_ENB BIT(31)
+/* INTR_STATUS */
+#define ACTMON_DEV_ISTS_AVG_ABOVE_WMARK BIT(24)
+#define ACTMON_DEV_ISTS_AVG_BELOW_WMARK BIT(25)
+#define ACTMON_DEV_ISTS_WHEN_OVERFLOW BIT(26)
+#define ACTMON_DEV_ISTS_AT_END BIT(29)
+#define ACTMON_DEV_ISTS_CONSECUTIVE_LOWER BIT(30)
+#define ACTMON_DEV_ISTS_CONSECUTIVE_UPPER BIT(31)
+
+/* Histogram Registers */
+#define ACTMON_HISTOGRAM_CONFIG 0x300
+#define ACTMON_HIST_CFG_ACTIVE BIT(0)
+#define ACTMON_HIST_CFG_LINEAR_MODE BIT(1)
+#define ACTMON_HIST_CFG_NO_UNDERFLOW_BUCKET BIT(2)
+#define ACTMON_HIST_CFG_STALL_ON_SINGLE_SATURATE BIT(3)
+#define ACTMON_HIST_CFG_SHIFT(s) (((s) & 0x1F) << 4)
+#define ACTMON_HIST_CFG_SOURCE(s) (((s) & 0xF) << 12)
+#define ACTMON_HISTOGRAM_CTRL 0x304
+#define ACTMON_HIST_CTRL_CLEAR_ALL BIT(0)
+#define ACTMON_HISTOGRAM_DATA_BASE 0x380
+#define ACTMON_HISTOGRAM_DATA_NUM 32
+
+#define ACTMON_FREQ 19200000
+#define ACTMON_PERIOD_MS 20
+#define DEV_COUNT_WEIGHT 5
+
+typedef struct _actmon_dev_reg_t
+{
+ vu32 ctrl;
+ vu32 upper_wnark;
+ vu32 lower_wmark;
+ vu32 init_avg;
+ vu32 avg_upper_wmark;
+ vu32 avg_lower_wmark;
+ vu32 count_weight;
+ vu32 count;
+ vu32 avg_count;
+ vu32 intr_status;
+ vu32 ctrl2;
+ vu32 rsvd[5];
+} actmon_dev_reg_t;
+
+void actmon_hist_enable(actmon_hist_src_t src)
+{
+ ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
+ ACTMON(ACTMON_HISTOGRAM_CTRL) = ACTMON_HIST_CTRL_CLEAR_ALL;
+}
+
+void actmon_hist_disable()
+{
+ ACTMON(ACTMON_HISTOGRAM_CONFIG) = 0;
+}
+
+void actmon_hist_get(u32 *histogram)
+{
+ if (histogram)
+ {
+ for (u32 i = 0; i < ACTMON_HISTOGRAM_DATA_NUM; i++)
+ histogram[i] = ACTMON(ACTMON_HISTOGRAM_DATA_BASE + i * sizeof(u32));
+ }
+}
+
+void actmon_dev_enable(actmon_dev_t dev)
+{
+ actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
+
+ regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
+ regs->count_weight = DEV_COUNT_WEIGHT;
+
+ regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
+}
+
+void actmon_dev_disable(actmon_dev_t dev)
+{
+ actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
+
+ regs->ctrl = 0;
+}
+
+u32 actmon_dev_get_load(actmon_dev_t dev)
+{
+ actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
+
+ // Get load-based sampling. 1 decimal point precision.
+ u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
+
+ return load;
+}
+
+u32 actmon_dev_get_load_avg(actmon_dev_t dev)
+{
+ actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
+
+ // Get load-based sampling. 1 decimal point precision.
+ u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
+
+ return avg_load;
+}
+
+void atmon_dev_all_disable()
+{
+ // TODO: do a global reset?
+}
+
+void actmon_init()
+{
+ clock_enable_actmon();
+
+ // Set period.
+ ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
+}
+
+void actmon_end()
+{
+ clock_disable_actmon();
+}
\ No newline at end of file
diff --git a/bdk/soc/actmon.h b/bdk/soc/actmon.h
new file mode 100644
index 0000000..dc9d0c5
--- /dev/null
+++ b/bdk/soc/actmon.h
@@ -0,0 +1,62 @@
+/*
+ * Activity Monitor driver for Tegra X1
+ *
+ * Copyright (c) 2021 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 .
+ */
+
+#ifndef __ACTMON_H_
+#define __ACTMON_H_
+
+#include
+
+typedef enum _actmon_dev_t
+{
+ ACTMON_DEV_CPU,
+ ACTMON_DEV_BPMP,
+ ACTMON_DEV_AHB,
+ ACTMON_DEV_APB,
+ ACTMON_DEV_CPU_FREQ,
+ ACTMON_DEV_MC_ALL,
+ ACTMON_DEV_MC_CPU,
+
+ ACTMON_DEV_NUM,
+} actmon_dev_t;
+
+typedef enum _actmon_hist_src_t
+{
+ ACTMON_HIST_SRC_NONE = 0,
+ ACTMON_HIST_SRC_AHB = 1,
+ ACTMON_HIST_SRC_APB = 2,
+ ACTMON_HIST_SRC_BPMP = 3,
+ ACTMON_HIST_SRC_CPU = 4,
+ ACTMON_HIST_SRC_MC_ALL = 5,
+ ACTMON_HIST_SRC_MC_CPU = 6,
+ ACTMON_HIST_SRC_CPU_FREQ = 7,
+ ACTMON_HIST_SRC_NA = 8,
+ ACTMON_HIST_SRC_APB_MMIO = 9,
+} actmon_hist_src_t;
+
+void actmon_hist_enable(actmon_hist_src_t src);
+void actmon_hist_disable();
+void actmon_hist_get(u32 *histogram);
+void actmon_dev_enable(actmon_dev_t dev);
+void actmon_dev_disable(actmon_dev_t dev);
+u32 actmon_dev_get_load(actmon_dev_t dev);
+u32 actmon_dev_get_load_avg(actmon_dev_t dev);
+void atmon_dev_all_disable();
+void actmon_init();
+void actmon_end();
+
+#endif
\ No newline at end of file
diff --git a/bdk/soc/bpmp.c b/bdk/soc/bpmp.c
index 2e1819d..3979c2a 100644
--- a/bdk/soc/bpmp.c
+++ b/bdk/soc/bpmp.c
@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
- * Copyright (c) 2019-2020 CTCaer
+ * Copyright (c) 2019-2024 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,
@@ -18,9 +18,9 @@
#include
#include
+#include
#include
#include
-#include
#define BPMP_MMU_CACHE_LINE_SIZE 0x20
@@ -118,7 +118,7 @@
#define MMU_EN_READ BIT(2)
#define MMU_EN_WRITE BIT(3)
-bpmp_mmu_entry_t mmu_entries[] =
+static const bpmp_mmu_entry_t mmu_entries[] =
{
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
@@ -134,13 +134,13 @@ void bpmp_mmu_maintenance(u32 op, bool force)
// This is a blocking operation.
BPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;
- while(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
+ while (!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
;
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
}
-void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
+void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply)
{
if (idx > 31)
return;
@@ -150,8 +150,8 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
if (entry->enable)
{
mmu_entry->start_addr = ALIGN(entry->start_addr, BPMP_MMU_CACHE_LINE_SIZE);
- mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
- mmu_entry->attr = entry->attr;
+ mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
+ mmu_entry->attr = entry->attr;
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx);
@@ -166,9 +166,9 @@ void bpmp_mmu_enable()
return;
// Init BPMP MMU.
- BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
+ BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.
- BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
+ BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
// Init BPMP MMU entries.
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;
@@ -200,36 +200,70 @@ void bpmp_mmu_disable()
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
}
+
+/*
+ * CLK_RST_CONTROLLER_SCLK_BURST_POLICY:
+ * 0 = CLKM
+ * 1 = PLLC_OUT1
+ * 2 = PLLC4_OUT3
+ * 3 = PLLP_OUT0
+ * 4 = PLLP_OUT2
+ * 5 = PLLC4_OUT1
+ * 6 = CLK_S
+ * 7 = PLLC4_OUT2
+ */
+
+bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
+
+void bpmp_clk_rate_relaxed(bool enable)
+{
+ // This is a glitch-free way to reduce the SCLK timings.
+ if (enable)
+ {
+ // Restore to PLLP source during PLLC configuration.
+ CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT.
+ usleep(100); // Wait a bit for clock source change.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
+ }
+ 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_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 and CLKM for idle.
+ usleep(100); // Wait a bit for clock source change.
+ }
+}
+
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
// I2C host, DC/DSI/DISP. UART gives extra stress.
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
-const u8 pll_divn[] = {
+// APB clock max is supposed to be 204 MHz though.
+static const u8 pll_divn[] = {
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
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.
// Do not use for public releases!
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
};
-bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
-
void bpmp_clk_rate_get()
{
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
if (clk_src_is_pllp)
- bpmp_clock_set = BPMP_CLK_NORMAL;
+ bpmp_fid_current = BPMP_CLK_NORMAL;
else
{
- bpmp_clock_set = BPMP_CLK_HIGH_BOOST;
+ bpmp_fid_current = BPMP_CLK_HIGH_BOOST;
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
for (u32 i = 1; i < sizeof(pll_divn); i++)
{
if (pll_divn[i] == pll_divn_curr)
{
- bpmp_clock_set = i;
+ bpmp_fid_current = i;
break;
}
}
@@ -241,35 +275,37 @@ void bpmp_clk_rate_set(bpmp_freq_t fid)
if (fid > (BPMP_CLK_MAX - 1))
fid = BPMP_CLK_MAX - 1;
- if (bpmp_clock_set == fid)
+ if (bpmp_fid_current == fid)
return;
+ bpmp_fid_current = fid;
+
if (fid)
{
- if (bpmp_clock_set)
- {
- // Restore to PLLP source during PLLC4 configuration.
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
- msleep(1); // Wait a bit for clock source change.
- }
+ // Use default SCLK / HCLK / PCLK clocks.
+ bpmp_clk_rate_relaxed(true);
// Configure and enable PLLC.
clock_enable_pllc(pll_divn[fid]);
- // Set SCLK / HCLK / PCLK.
- CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 for active and CLKM for idle.
+ // Set new source and SCLK / HCLK / PCLK dividers.
+ bpmp_clk_rate_relaxed(false);
}
else
{
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT for active and CLKM for idle.
- msleep(1); // Wait a bit for clock source change.
- CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
+ // Use default SCLK / HCLK / PCLK clocks.
+ bpmp_clk_rate_relaxed(true);
// Disable PLLC to save power.
clock_disable_pllc();
}
- bpmp_clock_set = fid;
+}
+
+// State is reset to RUN on any clock or source set via SW.
+void bpmp_state_set(bpmp_state_t state)
+{
+ u32 cfg = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & ~0xF0000000u;
+ CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = cfg | (state << 28u);
}
// The following functions halt BPMP to reduce power while sleeping.
@@ -281,10 +317,10 @@ void bpmp_usleep(u32 us)
// Each iteration takes 1us.
while (us)
{
- delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us;
+ delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
us -= delay;
- FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay;
+ FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
}
}
@@ -295,14 +331,14 @@ void bpmp_msleep(u32 ms)
// Iteration time is variable. ~200 - 1000us.
while (ms)
{
- delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms;
+ delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
ms -= delay;
- FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay;
+ FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
}
}
void bpmp_halt()
{
- FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG;
+ FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
}
diff --git a/bdk/soc/bpmp.h b/bdk/soc/bpmp.h
index 81f000b..ace1290 100644
--- a/bdk/soc/bpmp.h
+++ b/bdk/soc/bpmp.h
@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
- * Copyright (c) 2019-2020 CTCaer
+ * Copyright (c) 2019-2024 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,20 +47,35 @@ typedef enum
{
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
+ BPMP_CLK_HIGH2_BOOST, // 563MHz 38% - 141MHz APB.
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_freq_t;
+typedef enum
+{
+ BPMP_STATE_STANDBY = 0, // 32KHz.
+ BPMP_STATE_IDLE = 1,
+ BPMP_STATE_RUN = 2,
+
+ BPMP_STATE_IRQ = BIT(2),
+ 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
void bpmp_mmu_maintenance(u32 op, bool force);
-void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
+void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply);
void bpmp_mmu_enable();
void bpmp_mmu_disable();
+void bpmp_clk_rate_relaxed(bool enable);
void bpmp_clk_rate_get();
void bpmp_clk_rate_set(bpmp_freq_t fid);
+void bpmp_state_set(bpmp_state_t state);
void bpmp_usleep(u32 us);
void bpmp_msleep(u32 ms);
void bpmp_halt();
diff --git a/bdk/soc/ccplex.c b/bdk/soc/ccplex.c
index a8d782d..c01a892 100644
--- a/bdk/soc/ccplex.c
+++ b/bdk/soc/ccplex.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 CTCaer
+ * Copyright (c) 2018-2024 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,8 +15,8 @@
* along with this program. If not, see .
*/
+#include
#include
-#include
#include
#include
#include
@@ -27,96 +27,139 @@
#include
#include
-void _ccplex_enable_power_t210()
-{
- u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO); // Get current pinmuxing
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & ~BIT(5)); // Disable GPIO5 pinmuxing.
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
+#define CCPLEX_FLOWCTRL_POWERGATING 0
- // Enable cores power.
+static void _ccplex_enable_power_t210()
+{
+ // Configure GPIO5 and enable output in order to power CPU pmic.
+ max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
+
+ // Configure CPU pmic.
// 1-3.x: MAX77621_NFSR_ENABLE.
- i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,
- MAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE | MAX77621_RAMP_12mV_PER_US);
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
- i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
- MAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL);
- i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
- i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
+ max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
+
+ // Set voltage and enable cluster power.
+ max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
+ max7762x_regulator_enable(REGULATOR_CPU0, true);
}
-void _ccplex_enable_power_t210b01()
+static void _ccplex_enable_power_t210b01()
{
- u8 pmic_cpu_addr = !(FUSE(FUSE_RESERVED_ODM28) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
- u8 tmp = i2c_recv_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL);
- i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL, tmp | MAX77812_EN_CTRL_EN_M4);
- i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_M4_VOUT, MAX77812_M4_VOUT_0_80V);
+ // Set voltage and enable cluster power.
+ max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
+ max7762x_regulator_enable(REGULATOR_CPU1, true);
}
-void ccplex_boot_cpu0(u32 entry)
+static void _ccplex_disable_power()
+{
+ // Disable cluster power.
+ if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
+ {
+ max7762x_regulator_enable(REGULATOR_CPU0, false);
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
+ }
+ else
+ max7762x_regulator_enable(REGULATOR_CPU1, false);
+}
+
+void ccplex_boot_cpu0(u32 entry, bool lock)
{
// Set ACTIVE_CLUSER to FAST.
- FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
+ FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
_ccplex_enable_power_t210();
else
_ccplex_enable_power_t210b01();
- if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE.
- {
- CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7; // Disable IDDQ.
- usleep(2);
- CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
- CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
- CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000;
- CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;
- }
- while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))
- ;
+ clock_enable_pllx();
- // Configure MSELECT source and enable clock.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
- CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & ~BIT(CLK_V_MSELECT)) | BIT(CLK_V_MSELECT);
+ // Configure MSELECT source and enable clock to 102MHz.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
// Configure initial CPU clock frequency and enable clock.
- CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
- CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
+ CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
+ CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
+ CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
clock_enable_coresight();
// CAR2PMC_CPU_ACK_WIDTH should be set to 0.
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
- // Enable CPU rail.
- pmc_enable_partition(0, 1);
+ // Enable CPU main rail.
+ pmc_enable_partition(POWER_RAIL_CRAIL, ENABLE);
// Enable cluster 0 non-CPU rail.
- pmc_enable_partition(15, 1);
- // Enable CE0 rail.
- pmc_enable_partition(14, 1);
+ pmc_enable_partition(POWER_RAIL_C0NC, ENABLE);
+ // Enable CPU0 rail.
+ pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
- // Request and wait for RAM repair.
- FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
- while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
+ // Request and wait for RAM repair. Needed for the Fast cluster.
+ FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
+ while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & RAM_REPAIR_STS))
;
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
// Set reset vector.
- SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
+ SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
SB(SB_AA64_RESET_HIGH) = 0;
+
// Non-secure reset vector write disable.
- SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
- (void)SB(SB_CSR);
+ if (lock)
+ {
+ SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
+ (void)SB(SB_CSR);
+ }
// Tighten up the security aperture.
// MC(MC_TZ_SECURITY_CTRL) = 1;
// Clear MSELECT reset.
- CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= ~BIT(CLK_V_MSELECT);
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
// Clear NONCPU reset.
- CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
+ CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
// Clear CPU0 reset.
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
- CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;
+ CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
+}
+
+void ccplex_powergate_cpu0()
+{
+#if CCPLEX_FLOWCTRL_POWERGATING
+ // Halt CPU0.
+ FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
+
+ // Powergate cluster via flow control without waiting for WFI.
+ FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
+
+ // Wait for the rail power off to finish.
+ while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
+
+ // Set CPU0 to waitevent.
+ FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
+#endif
+
+ // Set CPU0 POR and CORE, CX0, L2, and DBG reset.
+ 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);
+ // Disable cluster 0 non-CPU.
+ pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
+ // Disable CPU rail.
+ pmc_enable_partition(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);
+
+ _ccplex_disable_power();
}
diff --git a/bdk/soc/ccplex.h b/bdk/soc/ccplex.h
index fb5be92..496da43 100644
--- a/bdk/soc/ccplex.h
+++ b/bdk/soc/ccplex.h
@@ -19,6 +19,7 @@
#include
-void ccplex_boot_cpu0(u32 entry);
+void ccplex_boot_cpu0(u32 entry, bool lock);
+void ccplex_powergate_cpu0();
#endif
diff --git a/bdk/soc/clock.c b/bdk/soc/clock.c
index cf0007e..b3a48fa 100644
--- a/bdk/soc/clock.c
+++ b/bdk/soc/clock.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 CTCaer
+ * Copyright (c) 2018-2024 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,75 +15,113 @@
* along with this program. If not, see .
*/
+#include
#include
#include