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 b26a3f8..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 \
+ hos.o hos_config.o pkg1.o pkg2.o pkg3.o pkg2_ini_kippatch.o secmon_exo.o \
)
# Libraries.
@@ -63,21 +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
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
-WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
+WARNINGS := -Wall -Wsign-compare -Wtype-limits -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
+#-fno-delete-null-pointer-checks
+#-Wstack-usage=byte-size -fstack-usage
-ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
-CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
+ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork $(WARNINGS)
+CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
MODULEDIRS := $(wildcard modules/*)
@@ -94,15 +101,14 @@ 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 "--------------------------------------"
@@ -119,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
@@ -132,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 761d0ef..6101ca1 100644
--- a/README.md
+++ b/README.md
@@ -50,13 +50,14 @@ Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many m
| \|__ background.bmp | Nyx - Custom background. User provided. |
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
-| bootloader/sys/ | hekate and Nyx system modules folder. |
-| \|__ emummc.kipm | emuMMC KIP1 module. !Important! |
-| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
-| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. !Important! |
-| \|__ nyx.bin | Nyx - hekate's GUI. !Important! |
-| \|__ res.pak | Nyx resources package. !Important! |
-| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. !Important! |
+| bootloader/sys/ | hekate and Nyx system modules folder. !Important! |
+| \|__ emummc.kipm | emuMMC KIP1 module. |
+| \|__ libsys_lp0.bso | LP0 (sleep mode) module. |
+| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. |
+| \|__ nyx.bin | Nyx - hekate's GUI. |
+| \|__ res.pak | Nyx resources package. |
+| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. |
+| \|__ /l4t/ | Folder with firmware relevant to L4T (Linux/Android). |
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
| bootloader/payloads/ | For the `Payloads` menu. All CFW bootloaders, tools, Linux payloads are supported. Autoboot only supported by including them into an ini. |
| bootloader/libtools/ | Reserved |
@@ -76,16 +77,17 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
### 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. Max: 20s. |
+| noticker=0 | 0: Animated line is drawn during custom bootlogo, signifying time left to skip to menu. 1: Disable. |
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
-| backlight=100 | Screen backlight level. 0-255. |
+| backlight=100 | Screen backlight level. 0-255. |
### Boot entry key/value combinations:
@@ -97,21 +99,33 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
| kernel={FILE path} | Replaces the kernel binary |
| kip1={FILE path} | Replaces/Adds kernel initial process. Multiple can be set. |
| kip1={FOLDER path}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
-| fss0={FILE path} | Takes an Atmosphere `package3` binary (formerly fusee-secondary.bin) and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere if enabled. |
-| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
+| pkg3={FILE path} | Takes an Atmosphere `package3` binary and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere. |
+| fss0={FILE path} | Same as above. !Deprecated! |
+| pkg3ex=1 | Enables loading of experimental content from a PKG3/FSS0 storage |
+| pkg3kip1skip={KIP name} | Skips loading a kip from `pkg3`/`fss0`. Allows multiple and `,` as separator. The name must exactly match the name in `PKG3`. |
| exofatal={FILE path} | Replaces the exosphere fatal binary for Mariko |
| ---------------------- | ---------------------------------------------------------- |
-| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or in one line with `,` as separator. If actual patch is not found, a warning will show up |
+| kip1patch=patchname | Enables a kip1 patch. Allows multiple and `,` as separator. If actual patch is not found, a warning will show up. |
| emupath={FOLDER path} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
-| stock=1 | Disables unneeded kernel patching and CFW kips 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`. |
+| stock=1 | OFW via hekate bootloader. Disables unneeded kernel patching and CFW kips when running stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
| fullsvcperm=1 | Disables SVC verification (full services permission). Doesn't work with Mesosphere as kernel. |
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
-| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
+| kernelprocid=1 | Enables stock kernel process id send/recv patching. Not needed when `pkg3`/`fss0` is used. |
| ---------------------- | ---------------------------------------------------------- |
| payload={FILE path} | Payload launching. Tools, Android/Linux, CFW bootloaders, etc. Any key above when used with that, doesn't get into account. |
| ---------------------- | ---------------------------------------------------------- |
+| 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. |
@@ -119,11 +133,11 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
-**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
+**Note2**: When using PKG3/FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `pkg3`/`fss0`.
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
-**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
-This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be under `fss0` line.
+**Warning**: Careful when you override *pkg3/fss core* kips with `kip1`.
+That's in case the kips are incompatible between them. If compatible, you can override `pkg3`/`fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be **after** `pkg3`/`fss0` line.
### Boot entry key/value combinations for Exosphère:
@@ -145,7 +159,7 @@ This is in case the kips are incompatible between them. If compatible, you can o
### 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 |
| ----------------------- | ----------------------------------------------------------------- |
@@ -159,38 +173,45 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
| '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 and only has the `[config]` entry.
-
-
### 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. |
-| bpmpclock=1 | 0: Auto, 1: Faster, 2: Fast. Use 2 if Nyx hangs or some functions like UMS/Backup Verification fail. |
+| 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-2021, CTCaer.
+ (c) 2018-2025, CTCaer.
-Nyx GUI (c) 2019-2021, 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 accfe03..0a2b2bc 100644
--- a/README_BOOTLOGO.md
+++ b/README_BOOTLOGO.md
@@ -4,14 +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 a boot entry specifies a custom logo path (`logopath=`), this is one will be loaded.
+If a boot entry specifies a custom logo path (`logopath=`), this one will be loaded.
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 6033c27..c2278c1 100644
--- a/Versions.inc
+++ b/Versions.inc
@@ -1,11 +1,11 @@
# IPL Version.
-BLVERSION_MAJOR := 5
-BLVERSION_MINOR := 6
-BLVERSION_HOTFX := 2
-BLVERSION_RSVD := 0
+BLVERSION_MAJOR := 6
+BLVERSION_MINOR := 3
+BLVERSION_HOTFX := 1
+BLVERSION_REL := 0
# Nyx Version.
NYXVERSION_MAJOR := 1
-NYXVERSION_MINOR := 0
-NYXVERSION_HOTFX := 7
-NYXVERSION_RSVD := 0
+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
index ee4b45d..3eaf922 100644
--- a/bdk/display/di.c
+++ b/bdk/display/di.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 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,
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
@@ -35,11 +36,32 @@
extern volatile nyx_storage_t *nyx_str;
-static u32 _display_id = 0;
-static bool nx_aula = false;
+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;
@@ -57,9 +79,47 @@ static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 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.
@@ -70,44 +130,26 @@ static void _display_dsi_read_rx_fifo(u32 *data)
}
}
-int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
+int display_dsi_read(u8 cmd, u32 len, void *data)
{
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);
+ _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(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
+ _display_dsi_wait(250000, _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;
+ 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.
@@ -146,47 +188,100 @@ int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
else
res = 1;
- // Disable host cmd packets during video and restore host control.
- if (video_enabled)
+ 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)
{
- // 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))
- ;
+ // 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;
- // Reset all states of syncpt block.
- DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
- usleep(300); // Stabilization delay.
+ case GEN_1_BYTE_SHORT_RD_RES:
+ case DCS_1_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 1);
+ break;
- // Clear syncpt block reset.
- DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
- usleep(300); // Stabilization delay.
+ case GEN_2_BYTE_SHORT_RD_RES:
+ case DCS_2_BYTE_SHORT_RD_RES:
+ memcpy(data, &fifo[2], 2);
+ break;
- // 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;
+ 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, bool video_enabled)
+void display_dsi_write(u8 cmd, u32 len, void *data)
{
- u8 *fifo8;
- u32 *fifo32;
u32 host_control;
+ u32 fifo32[DSI_STATUS_TX_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;
+ // 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_HOST;
+ DSI(_DSIREG(DSI_HOST_CONTROL)) = (host_control & ~(DSI_HOST_CONTROL_TX_TRIG_MASK)) | DSI_HOST_CONTROL_TX_TRIG_HOST;
switch (len)
{
@@ -199,43 +294,36 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
break;
default:
- fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4);
- fifo8 = (u8 *)fifo32;
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++)
+ 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;
- free(fifo32);
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;
+ // Restore host control.
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
}
void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
{
- u8 *fifo8;
- u32 *fifo32;
+ u32 fifo32[DSI_STATUS_TX_FIFO_SIZE] = {0};
+ u8 *fifo8 = (u8 *)fifo32;
- // Enable vblank interrupt.
- DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
+ // 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.
+ }
- // 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))
- ;
+ _display_dsi_wait_vblank(true);
switch (len)
{
@@ -248,43 +336,21 @@ void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
break;
default:
- fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4);
- fifo8 = (u8 *)fifo32;
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++)
+ 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];
- free(fifo32);
break;
}
- // 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;
-
- // 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;
+ _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;
+ _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))
@@ -293,77 +359,52 @@ void display_init()
// 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.
- max7762x_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);
- max7762x_regulator_enable(REGULATOR_SD2, true);
-
- }
-
- // Enable power to display panel controller.
+ // Enable DSI AVDD.
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
max7762x_regulator_enable(REGULATOR_LDO0, true);
- if (tegra_t210)
- max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // 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_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) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
+ 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) = 10; // Set PLLP_OUT and div 6 (68MHz).
+ 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 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
-
- if (nx_aula)
+ // Configure LCD/BL pins.
+ if (!_nx_aula)
{
- // Configure LCD RST pin.
- gpio_config(GPIO_PORT_V, GPIO_PIN_2, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_V, GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
- }
- else
- {
- // 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);
+ // Configure LCD pins.
+ PINMUX_AUX(PINMUX_AUX_NFC_EN) = PINMUX_PULL_DOWN;
+ PINMUX_AUX(PINMUX_AUX_NFC_INT) = PINMUX_PULL_DOWN;
- // 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 pins.
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_PULL_DOWN;
+ PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) = PINMUX_PULL_DOWN;
- // 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 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;
@@ -373,39 +414,25 @@ void display_init()
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): 97.5 MHz (offset).
- 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.
- }
+ // 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.
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, ARRAY_SIZE(_di_dc_setup_win_config));
- // 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);
+ // 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)
- 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);
+ 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.
@@ -413,13 +440,13 @@ void display_init()
usleep(60000);
// Setup DSI device takeover timeout.
- DSI(_DSIREG(DSI_BTA_TIMING)) = nx_aula ? 0x40103 : 0x50204;
+ 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, DSI_VIDEO_DISABLED))
+ if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id))
break;
usleep(10000);
@@ -435,24 +462,47 @@ void display_init()
_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_70_UNK;
+ if (_nx_aula && _display_id == 0xCCCC)
+ _display_id = PANEL_SAM_AMS699VC01;
// Initialize display panel.
switch (_display_id)
{
- case PANEL_SAM_70_UNK:
+ case PANEL_SAM_AMS699VC01:
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xA0, 0); // Write 0 to 0xA0.
- _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_SET_CONTROL_DISPLAY | (DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL << 8), 0); // Enable brightness control.
+ // 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:
- exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
+ 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;
@@ -479,7 +529,7 @@ void display_init()
case PANEL_INL_2J055IA_27A:
case PANEL_AUO_A055TAN01:
- case PANEL_V40_55_UNK:
+ 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;
@@ -488,29 +538,29 @@ void display_init()
// 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): 234 MHz (offset, it's ddr btw, so normally div2).
- CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
+ // 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);
- 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 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));
- // 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: 234 / 3 / 1 = 78 MHz (offset) for 60 Hz.
+ // 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.
- exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
+
+ // 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.
- 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++)
+ /*
+ * 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;
@@ -519,57 +569,77 @@ void display_init()
// 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);
+ 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
{
- 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);
+ 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));
}
- // Set the rest of MIPI cal offsets and apply calibration.
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
+ // 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.
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113);
+ 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_70_UNK)
+ if (_display_id == PANEL_SAM_AMS699VC01)
return;
+ // Enable PWM clock.
clock_enable_pwm();
- PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
+ // 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)
{
- gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
+ // Backlight PWM GPIO.
+ gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW);
}
-void display_dsi_backlight_brightness(u32 brightness)
+static void _display_dsi_backlight_brightness(u32 duty)
{
- u16 bl_ctrl = byte_swap_16((u16)(brightness * 8));
- display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
-}
-
-void display_pwm_backlight_brightness(u32 brightness, u32 step_delay)
-{
- u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
- if (brightness == old_value)
+ if (_dsi_bl == duty)
return;
- if (old_value < brightness)
+ // 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 < brightness + 1; i++)
+ for (u32 i = old_value; i < duty + 1; i++)
{
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
usleep(step_delay);
@@ -577,13 +647,13 @@ void display_pwm_backlight_brightness(u32 brightness, u32 step_delay)
}
else
{
- for (u32 i = old_value; i > brightness; i--)
+ for (u32 i = old_value; i > duty; i--)
{
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
usleep(step_delay);
}
}
- if (!brightness)
+ if (!duty)
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
}
@@ -592,15 +662,18 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
if (brightness > 255)
brightness = 255;
- if (_display_id != PANEL_SAM_70_UNK)
- display_pwm_backlight_brightness(brightness, step_delay);
+ if (_display_id != PANEL_SAM_AMS699VC01)
+ _display_pwm_backlight_brightness(brightness, step_delay);
else
- display_dsi_backlight_brightness(brightness);
+ _display_dsi_backlight_brightness(brightness);
}
u32 display_get_backlight_brightness()
{
- return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
+ 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)
@@ -616,31 +689,43 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
// 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 | WRITE_MUX;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX_ACTIVE | WRITE_MUX_ACTIVE;
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);
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, ARRAY_SIZE(_di_dc_video_disable_config));
- if (_display_id != PANEL_SAM_70_UNK)
+ // 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:
- exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
+ 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:
- exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
+ 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_V40_55_UNK:
+ 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).
@@ -653,7 +738,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
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.
+ 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)
{
@@ -661,7 +746,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
}
- else // PANEL_V40_55_UNK.
+ 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;
@@ -672,46 +757,44 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
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_70_UNK) ? 120000 : 50000);
+ (_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.
+ if (!_nx_aula) // HOS uses panel id.
{
- 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);
+ 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.
}
- else
- usleep(30000); // Aula Panel.
+ 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);
+ 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_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.
- if (!nx_aula)
- {
- 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.
- }
+ // Disable DSI AVDD.
+ max7762x_regulator_enable(REGULATOR_LDO0, false);
}
void display_end() { _display_panel_and_hw_end(false); };
@@ -724,7 +807,7 @@ u16 display_get_decoded_panel_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;
+ _nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA;
// Decode Display ID.
_display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
@@ -733,131 +816,218 @@ void display_set_decoded_panel_id(u32 id)
_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_70_UNK;
+ if (_nx_aula && _display_id == 0xCCCC)
+ _display_id = PANEL_SAM_AMS699VC01;
}
void display_color_screen(u32 color)
{
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
+ // 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_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); // No need to wait on Aula.
- if (_display_id != PANEL_SAM_70_UNK)
+ // 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(255, 0);
+ display_backlight_brightness(150, 0);
}
-u32 *display_init_framebuffer_pitch()
+u32 *display_init_window_a_pitch()
{
// Sanitize framebuffer area.
- memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
+ memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ);
- // 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); // No need to wait on Aula.
+ // 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 *)IPL_FB_ADDRESS;
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
-u32 *display_init_framebuffer_pitch_inv()
+u32 *display_init_window_a_pitch_vic()
{
- // 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); // No need to wait on Aula.
+ // 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 *)NYX_FB_ADDRESS;
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
-u32 *display_init_framebuffer_block()
+u32 *display_init_window_a_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_block, 34);
- usleep(35000); // No need to wait on Aula.
+ // 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 *)NYX_FB_ADDRESS;
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
-u32 *display_init_framebuffer_log()
+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).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
+ reg_write_array((u32 *)DISPLAY_A_BASE, _di_winD_log, ARRAY_SIZE(_di_winD_log));
- return (u32 *)LOG_FB_ADDRESS;
+ return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
-void display_activate_console()
+void display_window_disable(u32 window)
{
- 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;
+ // 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;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+
+ // 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;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+
+ // 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_deactivate_console()
+void display_window_d_console_disable()
{
- DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
+ // 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;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+
+ // 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);
}
- 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;
+ // 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_init_cursor(void *crs_fb, u32 size)
+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;
+ 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_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)
+void display_cursor_set_pos(u32 x, u32 y)
{
+ // Set cursor position.
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ // 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_deinit_cursor()
+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_UPDATE | CURSOR_UPDATE;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
}
diff --git a/bdk/display/di.h b/bdk/display/di.h
index 9229a22..9a35d4f 100644
--- a/bdk/display/di.h
+++ b/bdk/display/di.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 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
@@ -593,6 +704,7 @@
#define MIPI_DCS_GET_SCANLINE 0x45
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
+#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.
@@ -606,7 +718,9 @@
#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 // Enable extended commands.
#define MIPI_DCS_PRIV_UNK_BD 0xBD
@@ -614,6 +728,9 @@
#define MIPI_DCS_PRIV_UNK_D6 0xD6
#define MIPI_DCS_PRIV_UNK_D8 0xD8
#define MIPI_DCS_PRIV_UNK_D9 0xD9
+#define MIPI_DCS_PRIV_SM_DISPLAY_ID 0xDD
+ // LVL1 LVL2 LVL3 UNK0 UNK1
+#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
#define MIPI_DCS_PRIV_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.
@@ -648,30 +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 (Rev B1)
- * [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV]
- * [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
+ * [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] 93 [10]: AUO A055TAN01 (59.05A30.001)
- * [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
*
- * 7.0" OLED panels for Aula skus:
- * [50] XX [20]: Samsung AMS700XXXX [UNCONFIRMED ID and MODEL]
+ * 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:
@@ -684,7 +830,7 @@
* 10h: Japan Display Inc.
* 20h: InnoLux Corporation
* 30h: AU Optronics
- * 40h: Unknown0
+ * 40h: Sharp
* 50h: Samsung
*
* Boards, Panel Size:
@@ -702,18 +848,36 @@ enum
PANEL_AUO_A062TAN01 = 0x0F30,
PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030,
- PANEL_V40_55_UNK = 0x1040,
- PANEL_SAM_70_UNK = 0x2050
+ 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);
@@ -722,18 +886,22 @@ 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/display/di.inl b/bdk/display/di.inl
index c1e5d84..d74130e 100644
--- a/bdk/display/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,51 +99,59 @@ 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 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},
@@ -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/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 8deca45..99a996d 100644
--- a/bdk/ianos/ianos.c
+++ b/bdk/ianos/ianos.c
@@ -22,7 +22,7 @@
#include
#include
#include
-#include
+#include
#include
#include
@@ -74,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)
@@ -100,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;
@@ -116,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 be55426..277f0d5 100644
--- a/bdk/input/als.c
+++ b/bdk/input/als.c
@@ -45,7 +45,7 @@ typedef struct _opt_win_cal_t
} opt_win_cal_t;
// Nintendo Switch Icosa/Iowa Optical Window calibration.
-const opt_win_cal_t opt_win_cal_default[] = {
+static const opt_win_cal_t opt_win_cal_default[] = {
{ 500, 5002, 7502 },
{ 754, 2250, 2000 },
{ 1029, 1999, 1667 },
@@ -54,14 +54,14 @@ const opt_win_cal_t opt_win_cal_default[] = {
};
// Nintendo Switch Aula Optical Window calibration.
-const opt_win_cal_t opt_win_cal_aula[] = {
+static const opt_win_cal_t opt_win_cal_aula[] = {
{ 231, 9697, 30300 },
{ 993, 3333, 2778 },
{ 1478, 1621, 1053 },
{ 7500, 81, 10 }
};
-const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
+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)
{
@@ -70,10 +70,8 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
if (!cycle)
cycle = 1;
- else if (cycle > 255)
- cycle = 255;
- i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
+ i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
als_ctxt->gain = gain;
@@ -83,25 +81,25 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
void get_als_lux(als_ctxt_t *als_ctxt)
{
u32 data[2];
- u32 visible_light;
+ u32 vi_light;
u32 ir_light;
u64 lux = 0;
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
// 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);
- visible_light = data[0];
+ vi_light = data[0];
ir_light = data[1];
- als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
- als_ctxt->vi_light = visible_light;
+ als_ctxt->vi_light = vi_light;
als_ctxt->ir_light = ir_light;
+ als_ctxt->over_limit = vi_light > 65534 || ir_light > 65534;
- if (!visible_light)
+ if (!vi_light)
{
als_ctxt->lux = 0;
@@ -116,7 +114,7 @@ void get_als_lux(als_ctxt_t *als_ctxt)
// Apply optical window calibration coefficients.
for (u32 i = 0; i < opt_win_cal_count; i++)
{
- if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
+ 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;
diff --git a/bdk/input/joycon.c b/bdk/input/joycon.c
index 825e347..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-2021 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
@@ -42,8 +41,15 @@
#define JC_HORI_INPUT_RPT_CMD 0x9A
#define JC_HORI_INPUT_RPT 0x00
-#define JC_WIRED_CMD_MAC 0x01
-#define JC_WIRED_CMD_10 0x10
+#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
@@ -61,26 +67,67 @@
#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 0x01
-#define JC_ID_R 0x02
-#define JC_ID_HORI 0x20
+#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_INIT 0x00
-#define JC_CRC8_POLY 0x8D
+#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
};
@@ -91,21 +138,47 @@ static const u8 init_handshake[] = {
};
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 and crc.
+ 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_finalize[] = {
- 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 and crc.
+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 and crc.
+ 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data, data crc and crc.
};
static const u8 hori_pad_status[] = {
@@ -149,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;
@@ -160,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[];
@@ -185,36 +258,89 @@ 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 = {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);
-
-static u8 jc_crc(u8 *data, u16 len)
+static u8 _jc_crc(const u8 *data, u16 len, u8 init)
{
- u8 crc = JC_CRC8_INIT;
- u16 i, j;
- for (i = 0; i < len; i++) {
+ u8 crc = init;
+ for (u16 i = 0; i < len; i++)
+ {
crc ^= data[i];
- for (j = 0; j < 8; j++) {
+ for (u16 j = 0; j < 8; j++)
+ {
if ((crc & 0x80) != 0)
crc = (u8)((crc << 1) ^ JC_CRC8_POLY);
else
@@ -224,13 +350,140 @@ static u8 jc_crc(u8 *data, u16 len)
return crc;
}
-void joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
+static void _jc_power_supply(u8 uart, bool enable)
{
- uart_send(uart_port, buf, size);
- uart_wait_idle(uart_port, UART_TX_IDLE);
+ 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 u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc)
+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;
@@ -243,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 = crc ? jc_crc(&out->uart_hdr.total_size_msb, sizeof(out->uart_hdr.total_size_msb) + sizeof(out->cmd) + sizeof(out->data)) : 0;
+ 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, bool crc)
+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, crc);
+ 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;
@@ -263,34 +518,25 @@ static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, b
return pkt_size;
}
-void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc)
+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, crc);
+ 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)
@@ -299,63 +545,59 @@ 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, false);
+ _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, false);
+ _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, false);
+ _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, false);
+ _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, false);
+ _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, false);
+ _jc_send_hid_output_rpt(&jc_l, hid_pkt, 0x10, false);
}
else
{
- bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI);
+ bool crc_needed = jc->type & JC_ID_HORI;
- 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 = subcmd;
if (data)
memcpy(hid_pkt->subcmd_data, data, size);
- jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
+ _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;
@@ -363,7 +605,14 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
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)
@@ -390,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)
@@ -402,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;
@@ -420,125 +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 != UART_IIR_REDI)
+ 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 is_nxpad = !(jc->type & JC_ID_HORI);
+ 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;
if (is_nxpad)
{
- bool sent_rumble = jc_send_init_rumble(jc);
+ bool sent_rumble = _jc_send_init_rumble(jc);
if (sent_rumble)
return;
}
- 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);
- else
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
-
if (is_nxpad)
- joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
+ _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
- joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
+ _joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_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++)
@@ -563,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;
@@ -588,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;
@@ -605,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))
@@ -641,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))
@@ -674,189 +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)
{
- // Disable power.
- jc_power_supply(UART_B, false);
- jc_power_supply(UART_C, false);
+ if (!jc->detected)
+ return;
- // 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);
-
- // Send sleep command.
- u8 data = HCI_STATE_SLEEP;
-
- if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
- {
- jc_send_hid_cmd(UART_B, 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(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
- jc_rcv_pkt(&jc_l);
- }
-
- // Disable UART B and C clocks.
- clock_disable_uart(UART_B);
- clock_disable_uart(UART_C);
-}
-
-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));
-
- msleep(5);
- jc_rcv_pkt(jc);
-
- joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info));
- msleep(5);
- jc_rcv_pkt(jc);
-
- if (!(jc->type & JC_ID_HORI))
+ if (!jc->sio_mode)
{
- joycon_send_raw(jc->uart, init_finalize, sizeof(init_finalize));
+ jc->state = JC_STATE_START;
+
+ // Set TX and RTS inversion for Joycon.
+ uart_invert(jc->uart, true, UART_INVERT_TXD | UART_INVERT_RTS);
+
+ // Wake up the controller.
+ _joycon_send_raw(jc->uart, init_wake, sizeof(init_wake));
+ _jc_rcv_pkt(jc); // Clear RX FIFO.
+
+ // 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--;
+ }
+
+ 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
+ {
+ // 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);
+ _jc_rcv_pkt(jc);
}
- // 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);
+ // 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_5v_get_dev_enabled(1 << uart))
- return;
-
- regulator_5v_enable(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_5v_get_dev_enabled(1 << uart))
- return;
-
- regulator_5v_disable(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);
}
}
@@ -865,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_freq_t prev_fid = 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(prev_fid);
-
- // 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 2aba0e4..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,
@@ -24,9 +24,9 @@
#include
#include
#include
+#include
#include
#include
-#include
#include "touch.h"
@@ -35,12 +35,12 @@
static touch_panel_info_t _panels[] =
{
- { 0, 1, 1, 1, "NISSHA NFT-K12D" },
- { 1, 0, 1, 1, "GiS GGM6 B2X" },
- { 2, 0, 0, 0, "NISSHA NBF-K9A" },
- { 3, 1, 0, 0, "GiS 5.5\"" },
- { 4, 0, 0, 1, "Unknown_001" },
- { -1, 1, 0, 1, "GiS VA 6.2\"" }
+ { 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)
@@ -87,19 +87,19 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
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;
}
}
@@ -115,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;
@@ -245,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];
}
@@ -400,30 +401,29 @@ static int touch_init()
int touch_power_on()
{
- // Enable LDO6 for touchscreen AVDD supply.
- max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
- max7762x_regulator_enable(REGULATOR_LDO6, true);
-
- // Configure touchscreen VDD 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;
+ 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, NULL);
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 4f6f425..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
diff --git a/bdk/libs/fatfs/ff.c b/bdk/libs/fatfs/ff.c
index 75e0271..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-2021 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,
@@ -3274,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 */
@@ -3289,11 +3288,9 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
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) */
@@ -4701,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);
@@ -5882,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;
@@ -5918,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 */
}
@@ -6231,8 +6235,13 @@ 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) */
@@ -6241,11 +6250,18 @@ FRESULT f_mkfs (
/* Create PRF2SAFE info */
if (fmt == FS_FAT32 && opt & FM_PRF2) {
mem_set(buf, 0, ss);
- buf[16] = 0x64; /* Record type */
- st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
- st_dword(buf + 36, 25); /* Entries. SYSTEM: 22. USER: 25.Static? */
- st_dword(buf + 508, 0x517BBFE0); /* Custom CRC32. SYSTEM: 0x6B673904. USER: 0x517BBFE0. */
- disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
+ 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 */
@@ -6737,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);
@@ -6763,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/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 d577bd7..4e6ede6 100644
--- a/bdk/mem/mc.c
+++ b/bdk/mem/mc.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 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,
@@ -17,13 +17,11 @@
#include
#include
+#include
#include
#include
-#include
-//#define CONFIG_ENABLE_AHB_REDIRECT
-
-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;
@@ -33,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(bool full_aperture)
+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) = full_aperture ? DRAM_START : 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()
@@ -139,24 +88,34 @@ 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()
{
// Reset EMC source to PLLP.
- 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) = BIT(CLK_H_EMC);
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
+ 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);
- // Clear clock resets for memory.
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();
diff --git a/bdk/mem/mc.h b/bdk/mem/mc.h
index d873c7d..300bbfd 100644
--- a/bdk/mem/mc.h
+++ b/bdk/mem/mc.h
@@ -23,8 +23,9 @@
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
void mc_config_carveout();
void mc_config_carveout_finalize();
-void mc_enable_ahb_redirect(bool full_aperture);
+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 2560dfe..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;
@@ -97,13 +102,14 @@ 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_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);
@@ -139,6 +145,27 @@ 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)
@@ -156,6 +183,72 @@ void minerva_prep_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)
@@ -167,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 51cb215..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,14 +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 0f2ce3e..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-2021 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,48 +31,55 @@
#include
#include
#include
+#include
#include
-#include
-#define CONFIG_SDRAM_KEEP_ALIVE
+#define DRAM_ID(x) BIT(x)
+#define DRAM_CC(x) BIT(x)
typedef struct _sdram_vendor_patch_t
{
u32 val;
- u32 offset:16;
u32 dramcf:16;
+ u32 offset:16;
} sdram_vendor_patch_t;
static const u8 dram_encoding_t210b01[] = {
- LPDDR4X_UNUSED,
- LPDDR4X_UNUSED,
- LPDDR4X_UNUSED,
- LPDDR4X_4GB_HYNIX_1Y_A,
- LPDDR4X_UNUSED,
- LPDDR4X_4GB_HYNIX_1Y_A,
- LPDDR4X_4GB_HYNIX_1Y_A,
- LPDDR4X_4GB_SAMSUNG_X1X2,
- LPDDR4X_NO_PATCH,
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ,
- LPDDR4X_NO_PATCH,
- LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046,
- LPDDR4X_NO_PATCH,
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ,
- LPDDR4X_NO_PATCH,
- LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046,
- LPDDR4X_4GB_SAMSUNG_Y,
- LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
- LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
- LPDDR4X_4GB_SAMSUNG_1Y_Y,
- LPDDR4X_8GB_SAMSUNG_1Y_Y,
- LPDDR4X_UNUSED, // Removed.
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
- LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
- LPDDR4X_4GB_MICRON_1Y_A,
- LPDDR4X_4GB_MICRON_1Y_A,
- LPDDR4X_4GB_MICRON_1Y_A,
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
+/* 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"
@@ -118,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.
@@ -125,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);
@@ -157,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.
@@ -207,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;
@@ -220,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;
@@ -232,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.
@@ -249,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;
@@ -263,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;
@@ -340,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;
@@ -376,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;
@@ -392,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.
@@ -418,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;
@@ -479,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.
@@ -488,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;
@@ -586,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;
@@ -602,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.
@@ -620,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;
}
}
@@ -689,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;
@@ -731,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;
@@ -740,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)
@@ -749,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;
@@ -776,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;
@@ -799,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.
@@ -816,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.
@@ -833,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;
@@ -847,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;
@@ -906,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;
@@ -947,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;
@@ -981,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;
@@ -999,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.
@@ -1031,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;
@@ -1092,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.
@@ -1103,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.
@@ -1205,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.
@@ -1217,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.
@@ -1226,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.
@@ -1244,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;
}
}
@@ -1321,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;
@@ -1364,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;
@@ -1406,7 +1511,7 @@ void *sdram_get_params_t210b01()
return (void *)params;
for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++)
- if (sdram_cfg_vendor_patches_t210b01[i].dramcf == dram_code)
+ 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;
@@ -1450,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.
- max7762x_regulator_set_voltage(REGULATOR_SD1, 1100000); // HOS uses 1.125V
-
- // 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()
{
// 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 3caac47..10fb705 100644
--- a/bdk/mem/sdram.h
+++ b/bdk/mem/sdram.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2020-2021 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,107 +23,119 @@
/*
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
*
- * Note: BWbits T210 = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
- * BWbits T210B01 = Hz x ddr x bus width x channels = Hz x 2 x 64 x 2.
- * Both assume that both sub-partitions are used and thus reaching max
- * bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit).
- * Retail Mariko use one sub-partition, in order to meet Erista perf.
- *
- * T210 T210B01
- * 40.8 MHz: 0.61 1.22 GiB/s
- * 68.0 MHz: 1.01 2.02 GiB/s
- * 102.0 MHz: 1.52 3.04 GiB/s
- * 204.0 MHz: 3.04 6.08 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
- * 408.0 MHz: 6.08 12.16 GiB/s
- * 665.6 MHz: 9.92 19.84 GiB/s
- * 800.0 MHz: 11.92 23.84 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
- * 1065.6 MHz: 15.89 31.78 GiB/s
- * 1331.2 MHz: 19.84 39.68 GiB/s
- * 1600.0 MHz: 23.84 47.68 GiB/s <-- Tegra X1/X1+ HOS Max Frequency
- * 1862.4 MHz: 27.75 55.50 GiB/s <-- Tegra X1 Official Max Frequency
- * 2131.2 MHz: 31.76 63.52 GiB/s <-- Tegra X1+ Official Max Frequency
+ * 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.
*
+ * 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, // Changed to Iowa Hynix 4GB 1Y-A.
- LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
- LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5, // Changed to Hoag Hynix 4GB 1Y-A.
- LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6, // Changed to Aula Hynix 4GB 1Y-A.
+ 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_IOWA_4GB_HYNIX_1Y_A = 3, // Replaced from Copper.
- LPDDR4X_HOAG_4GB_HYNIX_1Y_A = 5, // Replaced from Copper.
- LPDDR4X_AULA_4GB_HYNIX_1Y_A = 6, // Replaced from Copper.
+ 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, // Die-M.
- LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M.
- LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M.
- LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps. WT:E. Die-E.
-
- LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M.
- LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M.
- LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M.
- LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps. WT:E. Die-E.
+ 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 4266Mbps.
- LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16,
+ 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_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A.
- LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A.
- LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A.
+ 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_Y = 20,
- LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21,
+ LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
+ LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
- // LPDDR4X_AULA_8GB_SAMSUNG_1Y_A = 22, // Unused.
+ 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_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A.
- LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A.
+ LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
- LPDDR4X_IOWA_4GB_MICRON_1Y_A = 25,
- LPDDR4X_HOAG_4GB_MICRON_1Y_A = 26,
- LPDDR4X_AULA_4GB_MICRON_1Y_A = 27,
+ // 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_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A.
+ 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_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_4GB_SAMSUNG_X1X2 = 1, // DRAM IDs: 07.
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 2, // DRAM IDs: 09, 13.
- LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 = 3, // DRAM IDs: 11, 15.
- LPDDR4X_4GB_SAMSUNG_Y = 4, // DRAM IDs: 16.
- LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 5, // DRAM IDs: 17, 19, 24.
- LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 6, // DRAM IDs: 18, 23, 28.
- LPDDR4X_4GB_SAMSUNG_1Y_Y = 7, // DRAM IDs: 20.
- LPDDR4X_8GB_SAMSUNG_1Y_Y = 8, // DRAM IDs: 21.
- //LPDDR4X_8GB_SAMSUNG_1Y_A = 9, // DRAM IDs: 22. Unused.
- LPDDR4X_4GB_MICRON_1Y_A = 10, // DRAM IDs: 25, 26, 27.
- LPDDR4X_4GB_HYNIX_1Y_A = 11, // DRAM IDs: 03, 05, 06.
+ 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 4548981..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-2021 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,
@@ -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,
@@ -491,8 +489,8 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
/* DRAM size information */
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
- .mc_emem_adr_cfg_dev0 = 0x00070302, // Rank 0 Density 512MB.
- .mc_emem_adr_cfg_dev1 = 0x00070302, // Rank 1 Density 512MB.
+ .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,53 +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, 0x10C / 4, DRAM_ID(1) }, // emc_r2w.
- { 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra.
- { 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width.
- { 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode.
- { 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // 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, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density.
- { 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density.
- { 0x00001800, 0x584 / 4, 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, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh.
- { 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
- { 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w.
- { 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra.
- { 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width.
- { 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
- { 0x0000003B, 0x1C0 / 4, DRAM_ID(6) }, // emc_txsr.
- { 0x0000003B, 0x1C4 / 4, DRAM_ID(6) }, // emc_txsr_dll.
- { 0x00000003, 0x1DC / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
- { 0x00120015, 0x334 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x00160012, 0x338 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
- { 0x00120015, 0x34C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00160012, 0x350 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
- { 0x002F0032, 0x354 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00310032, 0x358 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00360034, 0x35C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0033002F, 0x360 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
- { 0x00000006, 0x364 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x002F0032, 0x36C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00310032, 0x370 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00360034, 0x374 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0033002F, 0x378 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
- { 0x00000006, 0x37C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00150015, 0x3A4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
- { 0x00120012, 0x3AC / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
- { 0x00160016, 0x3B0 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
- { 0x00000015, 0x3B4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
- { 0x00000012, 0x49C / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
- { 0x00000012, 0x4A0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
- { 0x00000210, 0x4F4 / 4, DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
- { 0x00000005, 0x5C0 / 4, DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
- { 0x00000007, 0x5C8 / 4, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
- { 0x72A30504, 0x5D4 / 4, 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_t210b01.inl b/bdk/mem/sdram_config_t210b01.inl
index 0d1d617..3879e0c 100644
--- a/bdk/mem/sdram_config_t210b01.inl
+++ b/bdk/mem/sdram_config_t210b01.inl
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 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,
@@ -542,8 +542,8 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
/* DRAM size information */
.mc_emem_adr_cfg = 0x00000000, // 1 Rank.
- .mc_emem_adr_cfg_dev0 = 0x00080302, // Rank 0 Density 1024MB.
- .mc_emem_adr_cfg_dev1 = 0x00080302, // Rank 1 Density 1024MB.
+ .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,
@@ -552,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,
@@ -594,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,
@@ -701,291 +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, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x001B0010, 0x3B0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
- { 0x000E0022, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x001B0010, 0x3C8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
- { 0x00490043, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00420045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00490047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x00460047, 0x3D8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
- { 0x00000016, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00100000, 0x3E0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
- { 0x00490043, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00420045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00490047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x00460047, 0x3F0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
- { 0x00000016, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00100000, 0x3F8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
- { 0x00220022, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000E000E, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00100010, 0x424 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_2.
- { 0x001B001B, 0x428 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_3.
- { 0x00000022, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_4.
-
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_adr_cfg. 2 Ranks.
- { 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput_duration.
- { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_dev_select. Both devices.
- { 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_0.
- { 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_1.
- { 0x00100010, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
- { 0x00100010, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
- { 0x00100010, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
- { 0x00100010, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
- { 0x00100010, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
- { 0x00100010, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
- { 0x00100010, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
- { 0x00100010, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
- { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_adr_cfg. 2 Ranks.
- { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_cfg. 8GB total density.
- { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override1.
+ { 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) },
- // Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT Die-E for retail Iowa and Hoag.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_auto_cal_vref_sel0.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_dyn_self_ref_control.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // 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) },
- // Samsung LPDDR4X 4GB (Y01) Die-? for Iowa.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_vref_sel0.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_dyn_self_ref_control.
- { 0x32323232, 0x350 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_0.
- { 0x32323232, 0x354 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_1.
- { 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00780078, 0x3FC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
- { 0x00780078, 0x400 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
- { 0x00780078, 0x404 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
- { 0x00780078, 0x408 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
- { 0x00780078, 0x40C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
- { 0x00780078, 0x410 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
- { 0x00780078, 0x414 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
- { 0x00780078, 0x418 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
- { 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_4.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // 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 K4U6E3S4AA-MGCL 10nm-class (1y-X03) Die-A for retail Iowa, Hoag and Aula.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_vref_sel0.
- { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput_duration.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_dyn_self_ref_control.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // 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 8GB K4UBE3D4AA-MGCL 10nm-class (1y-X03) Die-A for SDEV Iowa, Hoag and Aula.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_adr_cfg. 2 Ranks.
- { 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput_duration.
- { 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_tfaw.
- { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_dev_select. Both devices.
- { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_adr_cfg. 2 Ranks.
- { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_cfg. 8GB total density.
- { 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_faw.
- { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // 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 4GB 10nm-class (1y-Y01) Die-? for Iowa.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0.
- { 0x00000008, 0x24C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_tfaw.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_dyn_self_ref_control.
- { 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4.
- { 0x00000001, 0x670 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // 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 8GB 10nm-class (1y-Y01) Die-? for SDEV Iowa.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0.
- { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_adr_cfg. 2 Ranks.
- { 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_tfaw.
- { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_dev_select. Both devices.
- { 0x32323232, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_0.
- { 0x32323232, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_1.
- { 0x000F0018, 0x3AC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
- { 0x000F0018, 0x3C4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
- { 0x00440048, 0x3CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
- { 0x00440045, 0x3D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
- { 0x00470047, 0x3D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
- { 0x0005000D, 0x3DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
- { 0x00440048, 0x3E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
- { 0x00440045, 0x3E8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
- { 0x00470047, 0x3EC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
- { 0x0005000D, 0x3F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
- { 0x00180018, 0x41C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0.
- { 0x000F000F, 0x420 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1.
- { 0x00000018, 0x42C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4.
- { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_init_dev1.
- { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd4.
- { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_adr_cfg. 2 Ranks.
- { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_cfg. 8GB total density.
- { 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw.
- { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_da_turns.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // 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-A01) Die-? for SDEV Aula?
- { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_adr_cfg. 2 Ranks.
- { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw1.
- { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw2.
- { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw3.
- { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw6.
- { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw8.
- { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw9.
- { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw10.
- { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw12.
- { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw13.
- { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw14.
- { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw_extra.
- { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_dev_select. Both devices.
- { 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_0.
- { 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_1.
- { 0x35353535, 0x358 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_0.
- { 0x35353535, 0x35C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_1.
- { 0x00480048, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
- { 0x00480048, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
- { 0x00480048, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
- { 0x00480048, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
- { 0x00480048, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
- { 0x00480048, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
- { 0x00480048, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
- { 0x00480048, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
- { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_mrw_cmd.
- { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_init_dev1.
- { 0x00010100, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd4.
- { 0x00400010, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd5.
- { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_adr_cfg. 2 Ranks.
- { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_cfg. 8GB total density.
- { 0x00000002, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_faw.
- { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_r2r.
- { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_da_turns.
-*/
- // Micron LPDDR4X 4GB 10nm-class (1y-01) Die-A for Unknown Iowa/Hoag/Aula.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_auto_cal_vref_sel0.
- { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_einput_duration.
- { 0x00000008, 0x24C / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_tfaw.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_dyn_self_ref_control.
- { 0x00000001, 0x670 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_emem_arb_timing_faw.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_video_protect_gpu_override1.
-
- // Hynix LPDDR4X 4GB 10nm-class (1y-01) Die-A for Unknown Iowa/Hoag/Aula.
- { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_config2.
- { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_vref_sel0.
- { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse.
- { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse_width.
- { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput.
- { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput_duration.
- { 0x00000008, 0x24C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_tfaw.
- { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_mrw14.
- { 0x80000713, 0x32C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_dyn_self_ref_control.
- { 0x00000001, 0x670 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_emem_arb_timing_faw.
- { 0xE4FACB43, 0x6D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override. + TSEC, NVENC.
- { 0x0600FED3, 0x6D8 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
- { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override0.
- { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override1.
-
- //!TODO: Too many duplicates.
+ { 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 1e50103..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(emc_mrw6, 27:0, scratch8, 27:0);
- s(emc_mrw6, 31:30, scratch8, 29:28);
- s(emc_mrw8, 27:0, scratch9, 27:0);
- s(emc_mrw8, 31:30, scratch9, 29:28);
- s(emc_mrw9, 27:0, scratch10, 27:0);
- s(emc_mrw9, 31:30, scratch10, 29:28);
- s(emc_mrw10, 27:0, scratch11, 27:0);
- s(emc_mrw10, 31:30, scratch11, 29:28);
- s(emc_mrw12, 27:0, scratch12, 27:0);
- s(emc_mrw12, 31:30, scratch12, 29:28);
- s(emc_mrw13, 27:0, scratch13, 27:0);
- s(emc_mrw13, 31:30, scratch13, 29:28);
- s(emc_mrw14, 27:0, scratch14, 27:0);
- s(emc_mrw14, 31:30, scratch14, 29:28);
- s(emc_mrw1, 7:0, scratch15, 7:0);
- s(emc_mrw1, 23:16, scratch15, 15:8);
- s(emc_mrw1, 27:26, scratch15, 17:16);
- s(emc_mrw1, 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(pllm_setup_control, 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 848fc1c..c687f2c 100644
--- a/bdk/memory_map.h
+++ b/bdk/memory_map.h
@@ -17,34 +17,42 @@
#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.
@@ -60,25 +68,25 @@
// 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
@@ -95,6 +103,7 @@
#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 --- */
@@ -106,7 +115,7 @@
#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/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 d54909f..3d41459 100644
--- a/bdk/power/max77620.h
+++ b/bdk/power/max77620.h
@@ -95,9 +95,9 @@
#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 occured.
+#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 occured. Only bit0: LDO8 is valid.
+#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.
@@ -139,8 +139,8 @@
#define MAX77620_REG_DVSSD0 0x1B
#define MAX77620_REG_DVSSD1 0x1C
#define MAX77620_SDX_VOLT_MASK 0xFF
-#define MAX77620_SD0_VOLT_MASK 0x3F
-#define MAX77620_SD1_VOLT_MASK 0x7F
+#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
@@ -318,7 +318,7 @@
#define MAX77620_REG_CID2 0x5A
#define MAX77620_REG_CID3 0x5B
#define MAX77620_REG_CID4 0x5C // OTP version.
-#define MAX77620_REG_CID5 0x5D
+#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
diff --git a/bdk/power/max7762x.c b/bdk/power/max7762x.c
index a7d30ce..f0aefb5 100644
--- a/bdk/power/max7762x.c
+++ b/bdk/power/max7762x.c
@@ -20,8 +20,8 @@
#include
#include
#include
+#include
#include
-#include
#define REGULATOR_SD 0
#define REGULATOR_LDO 1
@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
static const max77620_regulator_t _pmic_regulators[] = {
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
- { "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
+ { "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 }} },
@@ -88,11 +88,11 @@ static const max77620_regulator_t _pmic_regulators[] = {
{ "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_VOUT_REG, MAX77621_VOUT_DVS_REG, 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_VOUT_REG, MAX77621_VOUT_DVS_REG, 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_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 }} },
- //{ "max77812_RAM", 5000, 250000, 600000, 1525000, 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.
};
static u8 _max77812_get_address()
@@ -103,7 +103,7 @@ static u8 _max77812_get_address()
return max77812_i2c_addr;
max77812_i2c_addr =
- !(FUSE(FUSE_RESERVED_ODM28_T210B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
+ !(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
return max77812_i2c_addr;
}
@@ -121,7 +121,12 @@ static u8 _max7762x_get_i2c_address(u32 id)
case REGULATOR_BC0:
return (id == REGULATOR_CPU0 ? MAX77621_CPU_I2C_ADDR : MAX77621_GPU_I2C_ADDR);
case REGULATOR_BC1:
- return _max77812_get_address();
+ {
+ 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;
}
@@ -175,20 +180,22 @@ int max77620_regulator_config_fps(u32 id)
return 1;
}
-int max7762x_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->uv_min || mv > reg->uv_max)
+ if (uv < reg->uv_min || uv > reg->uv_max)
return 0;
u8 addr = _max7762x_get_i2c_address(id);
+ if (!addr)
+ return 0;
// Calculate voltage multiplier.
- u32 mult = (mv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
+ 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);
@@ -249,6 +256,8 @@ int max7762x_regulator_enable(u32 id, bool enable)
}
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);
@@ -291,6 +300,8 @@ void max77621_config_default(u32 id, bool por)
return;
u8 addr = _max7762x_get_i2c_address(id);
+ if (!addr)
+ return;
if (por)
{
@@ -299,13 +310,13 @@ void max77621_config_default(u32 id, bool por)
max7762x_regulator_enable(id, false);
// Configure to default.
- i2c_send_byte(I2C_5, addr, MAX77621_CONTROL1_REG, reg->ctrl.ctrl1_por);
- i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_por);
+ 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_CONTROL1_REG, reg->ctrl.ctrl1_hos);
- i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_hos);
+ 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);
}
}
@@ -316,7 +327,7 @@ void max77620_config_default()
return;
// Set default voltages and enable regulators.
- for (u32 i = 1; i <= REGULATOR_LDO8; i++)
+ for (u32 i = REGULATOR_SD1; i <= REGULATOR_LDO8; i++)
{
max77620_regulator_config_fps(i);
max7762x_regulator_set_voltage(i, _pmic_regulators[i].uv_default);
diff --git a/bdk/power/max7762x.h b/bdk/power/max7762x.h
index 3478530..342f40b 100644
--- a/bdk/power/max7762x.h
+++ b/bdk/power/max7762x.h
@@ -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
@@ -39,6 +47,27 @@
* 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
@@ -58,22 +87,22 @@
#define REGULATOR_LDO6 10
#define REGULATOR_LDO7 11
#define REGULATOR_LDO8 12
-#define REGULATOR_CPU0 13
-#define REGULATOR_GPU0 14
-#define REGULATOR_CPU1 15
-//#define REGULATOR_GPU1 16
-//#define REGULATOR_GPU1 17
-#define REGULATOR_MAX 15
+#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 0x00
-#define MAX77621_VOUT_DVS_REG 0x01
-#define MAX77621_CONTROL1_REG 0x02
-#define MAX77621_CONTROL2_REG 0x03
-#define MAX77621_CHIPID1_REG 0x04
-#define MAX77621_CHIPID2_REG 0x05
+#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_DVC_DVS_VOLT_MASK 0x7F
@@ -106,11 +135,10 @@
#define MAX77621_INDUCTOR_PLUS_60_PER 3
#define MAX77621_INDUCTOR_MASK 3
-#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
-#define MAX77621_CKKADV_TRIP_150mV_PER_US BIT(2)
-#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS BIT(3)
-#define MAX77621_CKKADV_TRIP_DISABLE (BIT(2) | BIT(3))
-#define MAX77621_CKKADV_TRIP_MASK (BIT(2) | BIT(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)
@@ -118,18 +146,17 @@
#define MAX77621_T_JUNCTION_120 BIT(7)
#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 | \
+#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_75mV_PER_US_HIST_DIS | \
- MAX77621_CKKADV_TRIP_150mV_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 | \
+#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \
+ MAX77621_WDTMR_ENABLE | \
+ MAX77621_CKKADV_TRIP_75mV_PER_US | \
MAX77621_INDUCTOR_NOMINAL)
#define MAX77621_CTRL_HOS_CFG 0
@@ -137,7 +164,7 @@
int max77620_regulator_get_status(u32 id);
int max77620_regulator_config_fps(u32 id);
-int max7762x_regulator_set_voltage(u32 id, u32 mv);
+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();
diff --git a/bdk/power/max77812.h b/bdk/power/max77812.h
index 89c3baf..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 // 2 Outputs: 3-phase M1 + 1-phase M4.
-#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33 // 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4.
+#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
@@ -66,22 +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
-/*! Protected area and settings only for MAX77812_REG_VERSION 4 */
-#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
diff --git a/bdk/power/regulator_5v.c b/bdk/power/regulator_5v.c
index 7b8924b..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,7 +14,9 @@
* along with this program. If not, see .
*/
+#include
#include
+#include
#include
#include
#include
@@ -25,51 +27,55 @@ static bool usb_src = false;
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 battery 5V regulator.
+ // 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);
+
+ // 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 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.
- // Fan and Rail power from USB 5V VBUS.
- 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_LOW);
usb_src = false;
-
- // 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;
}
reg_5v_dev |= 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 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 VBUS.
- 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;
- usb_src = false;
+ // 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;
+ }
}
}
@@ -80,6 +86,10 @@ bool regulator_5v_get_dev_enabled(u8 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);
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 fa20b0a..4ed04ec 100644
--- a/bdk/sec/se.c
+++ b/bdk/sec/se.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 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,14 +51,30 @@ 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) = (u32)src;
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
@@ -63,54 +82,44 @@ static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
static int _se_wait()
{
+ 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) & SE_INT_ERR_STAT ||
- (SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
- SE(SE_ERR_STATUS_REG) != 0)
+
+ // 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_REG) = SE(SE_ERR_STATUS_REG);
- SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
-
- bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
-
- SE(SE_OPERATION_REG) = 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,8 +181,7 @@ 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(SE_AES_BLOCK_SIZE);
- memset(block, 0, SE_AES_BLOCK_SIZE);
+ u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
@@ -155,11 +189,10 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
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[SE_AES_IV_SIZE / 4];
memcpy(data, ctr, SE_AES_IV_SIZE);
@@ -172,7 +205,7 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
{
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
- (((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
+ (((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);
@@ -191,7 +224,7 @@ u32 se_key_acc_ctrl_get(u32 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[SE_AES_MAX_KEY_SIZE / 4];
memcpy(data, key, size);
@@ -203,7 +236,7 @@ void se_aes_key_set(u32 ks, void *key, u32 size)
}
}
-void se_aes_iv_set(u32 ks, void *iv)
+void se_aes_iv_set(u32 ks, const void *iv)
{
u32 data[SE_AES_IV_SIZE / 4];
memcpy(data, iv, SE_AES_IV_SIZE);
@@ -246,17 +279,45 @@ void se_aes_iv_clear(u32 ks)
}
}
+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) = 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_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(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)
@@ -278,14 +339,14 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
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(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
+ SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
- SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
- SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
+ SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
+ SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
@@ -300,8 +361,9 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
{
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(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;
@@ -322,10 +384,11 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
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(SE_AES_BLOCK_SIZE);
+ u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
+ u8 *tweak = (u8 *)tmp;
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
@@ -335,7 +398,7 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *sr
tweak[i] = sec & 0xFF;
sec >>= 8;
}
- if (!se_aes_crypt_block_ecb(ks1, ENCRYPT, 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.
@@ -343,7 +406,7 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *sr
{
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 < SE_AES_BLOCK_SIZE; j++)
pdst[j] = pdst[j] ^ tweak[j];
@@ -354,23 +417,91 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *sr
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;
@@ -380,6 +511,17 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
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) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG) = sha_cfg;
@@ -418,19 +560,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
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);
- 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);
- }
+ 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[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);
- 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);
+ se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@@ -463,9 +582,9 @@ 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) = 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_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;
@@ -481,9 +600,9 @@ 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) = 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_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(SE_OP_START, NULL, 0, NULL, 0);
@@ -493,7 +612,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++)
{
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_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
@@ -502,7 +621,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
if (keysize > SE_KEY_128_SIZE)
{
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_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
@@ -532,3 +651,63 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
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 3dd8df3..36b057b 100644
--- a/bdk/sec/se.h
+++ b/bdk/sec/se.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2019-2021 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,
@@ -18,25 +18,32 @@
#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);
+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 350bc15..317c4fa 100644
--- a/bdk/sec/se_t210.h
+++ b/bdk/sec/se_t210.h
@@ -304,6 +304,8 @@
#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_ERR_STATUS_REG 0x804
#define SE_ERR_STATUS_SE_NS_ACCESS BIT(0)
diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c
index 1e9d01f..de2dbbb 100644
--- a/bdk/sec/tsec.c
+++ b/bdk/sec/tsec.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 CTCaer
+ * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,16 +20,17 @@
#include "tsec.h"
#include "tsec_t210.h"
+#include
+#include
+#include
+#include
#include
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include
+#include
// #include
@@ -57,9 +58,9 @@ 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();
}
@@ -69,23 +70,24 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
int res = 0;
u8 *fwbuf = NULL;
u32 type = tsec_ctxt->type;
- u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
+ u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *pkg11_magic_off;
+ void *ptb;
bpmp_mmu_disable();
- bpmp_freq_t prev_fid = 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.
@@ -95,23 +97,23 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
// Enable AHB aperture and set it to full mmio.
- mc_enable_ahb_redirect(true);
+ 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())
@@ -125,9 +127,10 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
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;
}
@@ -143,69 +146,69 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
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 << (TSEC_HOS_KB_620 + 2)) - 1;
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
- smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE);
+ 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 (type == TSEC_FW_TYPE_EMU)
{
- u32 start = get_tmr_us();
u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
+ u32 timeout = get_tmr_us() + 125000;
u32 key[16] = {0};
u32 kidx = 0;
@@ -220,14 +223,14 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
}
// 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;
}
@@ -238,12 +241,12 @@ int tsec_query(void *tsec_keys, 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));
@@ -259,14 +262,18 @@ int tsec_query(void *tsec_keys, 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;
@@ -275,23 +282,22 @@ int tsec_query(void *tsec_keys, 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, SE_KEY_128_SIZE);
}
-out_free:;
+out_free:
free(fwbuf);
-out:;
-
+out:
// Disable clocks.
clock_disable_kfuse();
clock_disable_sor1();
@@ -299,11 +305,12 @@ out:;
clock_disable_sor_safe();
clock_disable_tsec();
bpmp_mmu_enable();
- bpmp_clk_rate_set(prev_fid);
+ bpmp_clk_rate_relaxed(false);
- // Disable AHB aperture.
- if (type == TSEC_FW_TYPE_NEW)
- mc_disable_ahb_redirect();
+#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 7456e44..16aa4b7 100644
--- a/bdk/sec/tsec.h
+++ b/bdk/sec/tsec.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
-* Copyright (c) 2018-2021 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,
@@ -24,7 +24,7 @@ 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 enviroment.
+ TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
};
@@ -35,7 +35,6 @@ typedef struct _tsec_ctxt_t
u32 type;
void *pkg1;
u32 pkg11_off;
- u32 secmon_base;
} tsec_ctxt_t;
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
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 fc0e412..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-2021 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,20 +200,54 @@ 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_fid_current = BPMP_CLK_NORMAL;
-
void bpmp_clk_rate_get()
{
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
@@ -236,45 +270,42 @@ void bpmp_clk_rate_get()
}
}
-bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid)
+void bpmp_clk_rate_set(bpmp_freq_t fid)
{
- bpmp_freq_t prev_fid = bpmp_fid_current;
-
if (fid > (BPMP_CLK_MAX - 1))
fid = BPMP_CLK_MAX - 1;
- if (prev_fid == fid)
- return prev_fid;
+ if (bpmp_fid_current == fid)
+ return;
+
+ bpmp_fid_current = fid;
if (fid)
{
- if (prev_fid)
- {
- // Restore to PLLP source during PLLC 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_fid_current = fid;
+}
- // Return old fid in case of temporary swap.
- return prev_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.
@@ -286,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;
}
}
@@ -300,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 0f80150..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-2021 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,21 +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();
-bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid);
+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 7d2f4b6..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,6 +15,7 @@
* along with this program. If not, see .
*/
+#include
#include
#include
#include
@@ -26,7 +27,9 @@
#include
#include
-void _ccplex_enable_power_t210()
+#define CCPLEX_FLOWCTRL_POWERGATING 0
+
+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);
@@ -36,22 +39,34 @@ void _ccplex_enable_power_t210()
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
- // Set voltage and enable cores power.
+ // 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()
{
- // Set voltage and enable cores power.
+ // 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();
@@ -61,13 +76,13 @@ void ccplex_boot_cpu0(u32 entry)
clock_enable_pllx();
// Configure MSELECT source and enable clock to 102MHz.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
+ 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; // PLLX_OUT0_LJ.
- CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
+ 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();
@@ -81,28 +96,70 @@ void ccplex_boot_cpu0(u32 entry)
// 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_DEV_V_CLR) = 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 f4d9e92..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,11 +15,13 @@
* along with this program. If not, see .
*/
+#include
#include
#include
+#include
+#include
#include
#include
-#include
typedef struct _clock_osc_t
{
@@ -38,69 +40,88 @@ static const clock_osc_t _clock_osc_cnt[] = {
{ 48000, 2836, 3023 }
};
-/* clock_t: reset, enable, source, index, clk_src, clk_div */
+/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
-static const clock_t _clock_uart[] = {
- { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
- { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
- { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
- { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
- { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
+static const clk_rst_t _clock_uart[] = {
+ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
+ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
+ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
+ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
+ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
};
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
-static const clock_t _clock_i2c[] = {
- { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
- { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
- { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
- { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
- { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
- { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
+static const clk_rst_t _clock_i2c[] = {
+ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
+ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
+ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
+ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
+ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
+ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
};
-static clock_t _clock_se = {
- CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz.
+static clk_rst_t _clock_se = {
+ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408MHz. Default: 408MHz. Max: 627.2 MHz.
+};
+static clk_rst_t _clock_tzram = {
+ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_host1x = {
+ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408MHz.
+};
+static clk_rst_t _clock_tsec = {
+ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204MHz. Max: 408MHz.
+};
+static clk_rst_t _clock_nvdec = {
+ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2MHz.
+};
+static clk_rst_t _clock_nvjpg = {
+ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
+};
+static clk_rst_t _clock_vic = {
+ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
+};
+static clk_rst_t _clock_sor_safe = {
+ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_sor0 = {
+ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_sor1 = {
+ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204MHz.
+};
+static clk_rst_t _clock_kfuse = {
+ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_cl_dvfs = {
+ CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_coresight = {
+ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136MHz.
+};
+static clk_rst_t _clock_pwm = {
+ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
+};
+static clk_rst_t _clock_sdmmc_legacy_tm = {
+ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
+};
+static clk_rst_t _clock_apbdma = {
+ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204MHz.
+};
+static clk_rst_t _clock_ahbdma = {
+ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_actmon = {
+ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2MHz.
+};
+static clk_rst_t _clock_extperiph1 = {
+ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
+};
+static clk_rst_t _clock_extperiph2 = {
+ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0MHz
};
-static clock_t _clock_tzram = {
- CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
-};
-
-static clock_t _clock_host1x = {
- CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz.
-};
-static clock_t _clock_tsec = {
- CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz.
-};
-static clock_t _clock_sor_safe = {
- CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
-};
-static clock_t _clock_sor0 = {
- CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0
-};
-static clock_t _clock_sor1 = {
- CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 //204MHz.
-};
-static clock_t _clock_kfuse = {
- CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
-};
-
-static clock_t _clock_cl_dvfs = {
- CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
-};
-static clock_t _clock_coresight = {
- CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz.
-};
-
-static clock_t _clock_pwm = {
- CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
-};
-
-static clock_t _clock_sdmmc_legacy_tm = {
- CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66
-};
-
-void clock_enable(const clock_t *clk)
+void clock_enable(const clk_rst_t *clk)
{
// Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
@@ -108,7 +129,7 @@ void clock_enable(const clock_t *clk)
CLOCK(clk->enable) &= ~BIT(clk->index);
// Configure clock source if required.
if (clk->source)
- CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
+ CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
// Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
usleep(2);
@@ -117,7 +138,7 @@ void clock_enable(const clock_t *clk)
CLOCK(clk->reset) &= ~BIT(clk->index);
}
-void clock_disable(const clock_t *clk)
+void clock_disable(const clk_rst_t *clk)
{
// Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
@@ -133,7 +154,13 @@ void clock_enable_fuse(bool enable)
void clock_enable_uart(u32 idx)
{
+ // Ease the stress to APB.
+ bpmp_clk_rate_relaxed(true);
+
clock_enable(&_clock_uart[idx]);
+
+ // Restore OC.
+ bpmp_clk_rate_relaxed(false);
}
void clock_disable_uart(u32 idx)
@@ -147,11 +174,13 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
{
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
- if (baud == 1000000)
- CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
+ if (baud == 3000000)
+ CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
+ else if (baud == 1000000)
+ CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
else
{
- CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
+ CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
return 1;
}
@@ -203,6 +232,42 @@ void clock_disable_tsec()
clock_disable(&_clock_tsec);
}
+void clock_enable_nvdec()
+{
+ clock_enable(&_clock_nvdec);
+}
+
+void clock_disable_nvdec()
+{
+ clock_disable(&_clock_nvdec);
+}
+
+void clock_enable_nvjpg()
+{
+ clock_enable(&_clock_nvjpg);
+}
+
+void clock_disable_nvjpg()
+{
+ clock_disable(&_clock_nvjpg);
+}
+
+void clock_enable_vic()
+{
+ // Ease the stress to APB.
+ bpmp_clk_rate_relaxed(true);
+
+ clock_enable(&_clock_vic);
+
+ // Restore sys clock.
+ bpmp_clk_rate_relaxed(false);
+}
+
+void clock_disable_vic()
+{
+ clock_disable(&_clock_vic);
+}
+
void clock_enable_sor_safe()
{
clock_enable(&_clock_sor_safe);
@@ -271,7 +336,13 @@ void clock_disable_coresight()
void clock_enable_pwm()
{
+ // Ease the stress to APB.
+ bpmp_clk_rate_relaxed(true);
+
clock_enable(&_clock_pwm);
+
+ // Restore OC.
+ bpmp_clk_rate_relaxed(false);
}
void clock_disable_pwm()
@@ -279,6 +350,84 @@ void clock_disable_pwm()
clock_disable(&_clock_pwm);
}
+void clock_enable_apbdma()
+{
+ clock_enable(&_clock_apbdma);
+}
+
+void clock_disable_apbdma()
+{
+ clock_disable(&_clock_apbdma);
+}
+
+void clock_enable_ahbdma()
+{
+ clock_enable(&_clock_ahbdma);
+}
+
+void clock_disable_ahbdma()
+{
+ clock_disable(&_clock_ahbdma);
+}
+
+void clock_enable_actmon()
+{
+ clock_enable(&_clock_actmon);
+}
+
+void clock_disable_actmon()
+{
+ clock_disable(&_clock_actmon);
+}
+
+void clock_enable_extperiph1()
+{
+ clock_enable(&_clock_extperiph1);
+
+ PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN;
+ usleep(5);
+}
+
+void clock_disable_extperiph1()
+{
+ PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN);
+ clock_disable(&_clock_extperiph1);
+}
+
+void clock_enable_extperiph2()
+{
+ clock_enable(&_clock_extperiph2);
+
+ PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN;
+ usleep(5);
+}
+
+void clock_disable_extperiph2()
+{
+ PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN);
+ clock_disable(&_clock_extperiph2);
+}
+
+void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
+{
+ u32 plld_div = (divp << 20) | (divn << 11) | 1;
+
+ // N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
+ u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
+ if (lowpower && tegra_t210)
+ misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
+
+ // Set DISP1 clock source.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
+
+ // Set dividers and enable PLLD.
+ CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
+ CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
+
+ // Set PLLD_SDM_DIN and enable PLLD to DSI pads.
+ CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
+}
+
void clock_enable_pllx()
{
// Configure and enable PLLX if disabled.
@@ -315,7 +464,7 @@ void clock_enable_pllc(u32 divn)
// Take PLLC out of reset and set basic misc parameters.
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
- ((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
+ ((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU.
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
// Disable PLL and IDDQ in case they are on.
@@ -332,21 +481,21 @@ void clock_enable_pllc(u32 divn)
;
// Disable PLLC_OUT1, enable reset and set div to 1.5.
- CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = BIT(8);
+ CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 1 << 8;
// Enable PLLC_OUT1 and bring it out of reset.
- CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
+ CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR;
msleep(1); // Wait a bit for PLL to stabilize.
}
void clock_disable_pllc()
{
// Disable PLLC and PLLC_OUT1.
- CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~(PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
+ CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
+ CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
- CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_REF_DIS;
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
- CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) |= PLLC_MISC_RESET;
+ CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
usleep(10);
}
@@ -371,7 +520,7 @@ static void _clock_enable_pllc4(u32 mask)
usleep(10);
// Set PLLC4 dividers.
- CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
// Enable PLLC4 and wait for Phase and Frequency lock.
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
@@ -409,9 +558,9 @@ void clock_enable_pllu()
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
// Wait for PLL to stabilize.
- u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
+ u32 timeout = get_tmr_us() + 1300;
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
- if ((u32)TMR(TIMERUS_CNTR_1US) > timeout)
+ if (get_tmr_us() > timeout)
break;
usleep(10);
@@ -421,9 +570,9 @@ void clock_enable_pllu()
void clock_disable_pllu()
{
- CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
- CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU.
- CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock.
+ CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
+ CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~BIT(30); // Disable PLLU.
+ CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~BIT(29); // Enable reference clock.
}
void clock_enable_utmipll()
@@ -552,7 +701,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
static void _clock_sdmmc_config_legacy_tm()
{
- clock_t *clk = &_clock_sdmmc_legacy_tm;
+ const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
if (!(CLOCK(clk->enable) & BIT(clk->index)))
clock_enable(clk);
}
@@ -567,6 +716,7 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
+#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
@@ -582,81 +732,90 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
{
case 25000:
*pclock = 24728;
- divisor = 31; // 16.5 div.
+ divisor = CLK_SRC_DIV(16.5);
break;
+
case 26000:
*pclock = 25500;
- divisor = 30; // 16 div.
- break;
- case 40800:
- *pclock = 40800;
- divisor = 18; // 10 div.
+ divisor = CLK_SRC_DIV(16);
break;
+
case 50000:
*pclock = 48000;
- divisor = 15; // 8.5 div.
+ divisor = CLK_SRC_DIV(8.5);
break;
+
case 52000:
*pclock = 51000;
- divisor = 14; // 8 div.
+ divisor = CLK_SRC_DIV(8);
break;
+
+ case 82000:
+ *pclock = 81600;
+ divisor = CLK_SRC_DIV(5);
+ break;
+
case 100000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
*pclock = 99840;
- divisor = 2; // 2 div.
+ divisor = CLK_SRC_DIV(2);
break;
+
case 164000:
*pclock = 163200;
- divisor = 3; // 2.5 div.
+ divisor = CLK_SRC_DIV(2.5);
break;
- case 200000: // 240MHz evo+.
+
+ case 200000:
switch (id)
{
case SDMMC_1:
- source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
- break;
- case SDMMC_2:
- source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
- break;
case SDMMC_3:
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
break;
+ case SDMMC_2:
case SDMMC_4:
- source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
+ source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
break;
}
*pclock = 199680;
- divisor = 0; // 1 div.
+ divisor = CLK_SRC_DIV(1);
break;
- default:
- *pclock = 24728;
- divisor = 31; // 16.5 div.
+
+#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
+ case 400000:
+ source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
+ *pclock = 399360;
+ divisor = CLK_SRC_DIV(2.5);
+ break;
+#endif
}
_clock_sdmmc_table[id].clock = val;
_clock_sdmmc_table[id].real_clock = *pclock;
// Enable PLLC4 if in use by any SDMMC.
- if (source)
+ if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
_clock_enable_pllc4(BIT(id));
// Set SDMMC legacy timeout clock.
_clock_sdmmc_config_legacy_tm();
// Set SDMMC clock.
+ u32 src_div = (source << 29u) | divisor;
switch (id)
{
case SDMMC_1:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
break;
case SDMMC_2:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
break;
case SDMMC_3:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
break;
case SDMMC_4:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
break;
}
@@ -686,54 +845,71 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
// Get Card clock divisor.
switch (type)
{
- case SDHCI_TIMING_MMC_ID: // Actual IO Freq: 380.59 KHz.
+ case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
*pclock = 26000;
*pdivisor = 66;
break;
+
case SDHCI_TIMING_MMC_LS26:
*pclock = 26000;
*pdivisor = 1;
break;
+
case SDHCI_TIMING_MMC_HS52:
*pclock = 52000;
*pdivisor = 1;
break;
+
case SDHCI_TIMING_MMC_HS200:
case SDHCI_TIMING_MMC_HS400:
case SDHCI_TIMING_UHS_SDR104:
*pclock = 200000;
*pdivisor = 1;
break;
- case SDHCI_TIMING_SD_ID: // Actual IO Freq: 380.43 KHz.
+
+ case SDHCI_TIMING_SD_ID: // Actual card clock: 386.38 KHz.
*pclock = 25000;
*pdivisor = 64;
break;
+
case SDHCI_TIMING_SD_DS12:
case SDHCI_TIMING_UHS_SDR12:
*pclock = 25000;
*pdivisor = 1;
break;
+
case SDHCI_TIMING_SD_HS25:
case SDHCI_TIMING_UHS_SDR25:
*pclock = 50000;
*pdivisor = 1;
break;
+
case SDHCI_TIMING_UHS_SDR50:
*pclock = 100000;
*pdivisor = 1;
break;
+
case SDHCI_TIMING_UHS_SDR82:
*pclock = 164000;
*pdivisor = 1;
break;
- case SDHCI_TIMING_UHS_DDR50:
- *pclock = 40800;
- *pdivisor = 1;
+
+ case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
+ *pclock = 82000;
+ *pdivisor = 2;
break;
- case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
+
+ case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
*pclock = 200000;
*pdivisor = 2;
break;
+
+#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
+ case SDHCI_TIMING_UHS_DDR200: // Actual card clock: 199.68 KHz.
+ *pclock = 400000;
+ *pdivisor = 2;
+ break;
+#endif
}
}
@@ -752,7 +928,8 @@ void clock_sdmmc_enable(u32 id, u32 val)
_clock_sdmmc_config_clock_host(&clock, id, val);
_clock_sdmmc_set_enable(id);
_clock_sdmmc_is_reset(id);
- usleep((100000 + clock - 1) / clock);
+ // Wait 100 cycles for reset and for clocks to stabilize.
+ usleep((100 * 1000 + clock - 1) / clock);
_clock_sdmmc_clear_reset(id);
_clock_sdmmc_is_reset(id);
}
diff --git a/bdk/soc/clock.h b/bdk/soc/clock.h
index 32afe8d..14d1df7 100644
--- a/bdk/soc/clock.h
+++ b/bdk/soc/clock.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,
@@ -47,6 +47,7 @@
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
+#define CLK_RST_CONTROLLER_PLLP_OUTB 0xA8
#define CLK_RST_CONTROLLER_PLLA_BASE 0xB0
#define CLK_RST_CONTROLLER_PLLA_OUT 0xB4
#define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8
@@ -117,7 +118,10 @@
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4
+#define CLK_RST_CONTROLLER_CLK_SOURCE_AHUB 0x3D0
+#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC
+#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
@@ -146,6 +150,7 @@
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
+#define CLK_RST_CONTROLLER_PLLMB_MISC1 0x5EC
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
@@ -153,8 +158,12 @@
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
+#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
+#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
+#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
+#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0
#define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE 0x710
@@ -191,6 +200,9 @@
#define UTMIPLL_LOCK BIT(31)
+/*! Clock source */
+#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
+
/*! PTO_CLK_CNT */
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
#define PTO_REF_CLK_WIN_CFG_16P 0xF
@@ -220,138 +232,232 @@
/*! PTO IDs. */
typedef enum _clock_pto_id_t
{
- CLK_PTO_PCLK_SYS = 0x06,
- CLK_PTO_HCLK_SYS = 0x07,
+ CLK_PTO_PCLK_SYS = 0x06,
+ CLK_PTO_HCLK_SYS = 0x07,
+ CLK_PTO_DMIC1 = 0x08,
+ CLK_PTO_DMIC2 = 0x09,
+ CLK_PTO_HDMI_SLOWCLK_DIV2 = 0x0A,
+ CLK_PTO_JTAG_REG = 0x0B,
+ CLK_PTO_UTMIP_240_A = 0x0C,
+ CLK_PTO_UTMIP_240_B = 0x0D,
- CLK_PTO_UTMIP_240 = 0x0C,
+ CLK_PTO_CCLK_G = 0x12,
+ CLK_PTO_CCLK_G_DIV2 = 0x13,
+ CLK_PTO_MIPIBIF = 0x14,
- CLK_PTO_CCLK_G = 0x12,
- CLK_PTO_CCLK_G_DIV2 = 0x13,
+ CLK_PTO_SPI1 = 0x17,
+ CLK_PTO_SPI2 = 0x18,
+ CLK_PTO_SPI3 = 0x19,
+ CLK_PTO_SPI4 = 0x1A,
+ CLK_PTO_MAUD = 0x1B,
+ CLK_PTO_SCLK = 0x1C,
- CLK_PTO_SPI1 = 0x17,
- CLK_PTO_SPI2 = 0x18,
- CLK_PTO_SPI3 = 0x19,
- CLK_PTO_SPI4 = 0x1A,
- CLK_PTO_MAUD = 0x1B,
- CLK_PTO_SCLK = 0x1C,
+ CLK_PTO_SDMMC1 = 0x20,
+ CLK_PTO_SDMMC2 = 0x21,
+ CLK_PTO_SDMMC3 = 0x22,
+ CLK_PTO_SDMMC4 = 0x23,
+ CLK_PTO_EMC = 0x24,
- CLK_PTO_SDMMC1 = 0x20,
- CLK_PTO_SDMMC2 = 0x21,
- CLK_PTO_SDMMC3 = 0x22,
- CLK_PTO_SDMMC4 = 0x23,
- CLK_PTO_EMC = 0x24,
+ CLK_PTO_DMIC3 = 0x2A,
+ CLK_PTO_CCLK_LP = 0x2B,
+ CLK_PTO_CCLK_LP_DIV2 = 0x2C,
- CLK_PTO_CCLK_LP = 0x2B,
- CLK_PTO_CCLK_LP_DIV2 = 0x2C,
+ CLK_PTO_MSELECT = 0x2F,
- CLK_PTO_MSELECT = 0x2F,
+ CLK_PTO_VI_SENSOR2 = 0x33,
+ CLK_PTO_VI_SENSOR = 0x34,
+ CLK_PTO_VIC = 0x35,
+ CLK_PTO_VIC_SKIP = 0x36,
+ CLK_PTO_ISP_SKIP = 0x37,
+ CLK_PTO_ISPB_SE2_SKIP = 0x38,
+ CLK_PTO_NVDEC_SKIP = 0x39,
+ CLK_PTO_NVENC_SKIP = 0x3A,
+ CLK_PTO_NVJPG_SKIP = 0x3B,
+ CLK_PTO_TSEC_SKIP = 0x3C,
+ CLK_PTO_TSECB_SKIP = 0x3D,
+ CLK_PTO_SE_SKIP = 0x3E,
+ CLK_PTO_VI_SKIP = 0x3F,
- CLK_PTO_VIC = 0x36,
+ CLK_PTO_PLLX_OBS = 0x40,
+ CLK_PTO_PLLC_OBS = 0x41,
+ CLK_PTO_PLLM_OBS = 0x42,
+ CLK_PTO_PLLP_OBS = 0x43,
+ CLK_PTO_PLLA_OBS = 0x44,
+ CLK_PTO_PLLMB_OBS = 0x45,
+ CLK_PTO_SATA_OOB = 0x46,
- CLK_PTO_NVDEC = 0x39,
+ CLK_PTO_FCPU_DVFS_DIV12_CPU = 0x48,
- CLK_PTO_NVENC = 0x3A,
- CLK_PTO_NVJPG = 0x3B,
- CLK_PTO_TSEC = 0x3C,
- CLK_PTO_TSECB = 0x3D,
- CLK_PTO_SE = 0x3E,
+ CLK_PTO_EQOS_AXI = 0x4C,
+ CLK_PTO_EQOS_PTP_REF = 0x4D,
+ CLK_PTO_EQOS_TX = 0x4E,
+ CLK_PTO_EQOS_RX = 0x4F,
- CLK_PTO_DSIA_LP = 0x62,
+ CLK_PTO_CILAB = 0x52,
+ CLK_PTO_CILCD = 0x53,
- CLK_PTO_ISP = 0x64,
- CLK_PTO_MC = 0x6A,
+ CLK_PTO_CILEF = 0x55,
+ CLK_PTO_PLLA1_PTO_OBS = 0x56,
+ CLK_PTO_PLLC4_PTO_OBS = 0x57,
- CLK_PTO_ACTMON = 0x6B,
- CLK_PTO_CSITE = 0x6C,
+ CLK_PTO_PLLC2_PTO_OBS = 0x59,
+ CLK_PTO_PLLC3_PTO_OBS = 0x5B,
- CLK_PTO_HOST1X = 0x6F,
+ CLK_PTO_DSIA_LP = 0x62,
+ CLK_PTO_DSIB_LP = 0x63,
+ CLK_PTO_ISP = 0x64,
+ CLK_PTO_PEX_PAD = 0x65,
- CLK_PTO_SE_2 = 0x74, // Same as CLK_PTO_SE.
- CLK_PTO_SOC_THERM = 0x75,
+ CLK_PTO_MC = 0x6A,
- CLK_PTO_TSEC_2 = 0x77, // Same as CLK_PTO_TSEC.
+ CLK_PTO_ACTMON = 0x6B,
+ CLK_PTO_CSITE = 0x6C,
+ CLK_PTO_VI_I2C = 0x6D,
- CLK_PTO_ACLK = 0x7C,
- CLK_PTO_QSPI = 0x7D,
+ CLK_PTO_HOST1X = 0x6F,
- CLK_PTO_I2S1 = 0x80,
- CLK_PTO_I2S2 = 0x81,
- CLK_PTO_I2S3 = 0x82,
- CLK_PTO_I2S4 = 0x83,
- CLK_PTO_I2S5 = 0x84,
- CLK_PTO_AHUB = 0x85,
- CLK_PTO_APE = 0x86,
+ CLK_PTO_QSPI_2X = 0x71,
+ CLK_PTO_NVDEC = 0x72,
+ CLK_PTO_NVJPG = 0x73,
+ CLK_PTO_SE = 0x74,
+ CLK_PTO_SOC_THERM = 0x75,
- CLK_PTO_DVFS_SOC = 0x88,
- CLK_PTO_DVFS_REF = 0x89,
+ CLK_PTO_TSEC = 0x77,
+ CLK_PTO_TSECB = 0x78,
+ CLK_PTO_VI = 0x79,
+ CLK_PTO_LA = 0x7A,
+ CLK_PTO_SCLK_SKIP = 0x7B,
- CLK_PTO_SPDIF = 0x8F,
- CLK_PTO_SPDIF_IN = 0x90,
+ CLK_PTO_ADSP_SKIP = 0x7C,
+ CLK_PTO_QSPI = 0x7D,
+
+ CLK_PTO_SDMMC2_SHAPER = 0x7E,
+ CLK_PTO_SDMMC4_SHAPER = 0x7F,
+ CLK_PTO_I2S1 = 0x80,
+ CLK_PTO_I2S2 = 0x81,
+ CLK_PTO_I2S3 = 0x82,
+ CLK_PTO_I2S4 = 0x83,
+ CLK_PTO_I2S5 = 0x84,
+ CLK_PTO_AHUB = 0x85,
+ CLK_PTO_APE = 0x86,
+
+ CLK_PTO_DVFS_SOC = 0x88,
+ CLK_PTO_DVFS_REF = 0x89,
+ CLK_PTO_ADSP_CLK = 0x8A,
+ CLK_PTO_ADSP_DIV2_CLK = 0x8B,
+
+ CLK_PTO_SPDIF_OUT = 0x8F,
+ CLK_PTO_SPDIF_IN = 0x90,
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
+ CLK_PTO_SYS2HSIO_SATA_CLK = 0x92,
+ CLK_PTO_PWM = 0x93,
+ CLK_PTO_I2C1 = 0x94,
+ CLK_PTO_I2C2 = 0x95,
+ CLK_PTO_I2C3 = 0x96,
+ CLK_PTO_I2C4 = 0x97,
+ CLK_PTO_I2C5 = 0x98,
+ CLK_PTO_I2C6 = 0x99,
+ CLK_PTO_I2C_SLOW = 0x9A,
+ CLK_PTO_UARTAPE = 0x9B,
- CLK_PTO_PWM = 0x93,
- CLK_PTO_I2C1 = 0x94,
- CLK_PTO_I2C2 = 0x95,
- CLK_PTO_I2C3 = 0x96,
- CLK_PTO_I2C4 = 0x97,
- CLK_PTO_I2C5 = 0x98,
- CLK_PTO_I2C6 = 0x99,
- CLK_PTO_I2C_SLOW = 0x9A,
- CLK_PTO_UARTAPE = 0x9B,
+ CLK_PTO_EXTPERIPH1 = 0x9D,
+ CLK_PTO_EXTPERIPH2 = 0x9E,
+ CLK_PTO_EXTPERIPH3 = 0x9F,
+ CLK_PTO_ENTROPY = 0xA0,
+ CLK_PTO_UARTA = 0xA1,
+ CLK_PTO_UARTB = 0xA2,
+ CLK_PTO_UARTC = 0xA3,
+ CLK_PTO_UARTD = 0xA4,
+ CLK_PTO_OWR = 0xA5,
+ CLK_PTO_TSENSOR = 0xA6,
+ CLK_PTO_HDA2CODEC_2X = 0xA7,
+ CLK_PTO_HDA = 0xA8,
+ CLK_PTO_EMC_LATENCY = 0xA9,
+ CLK_PTO_EMC_DLL = 0xAA,
+ CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
+ CLK_PTO_DBGAPB = 0xAC,
- CLK_PTO_EXTPERIPH1 = 0x9D,
- CLK_PTO_EXTPERIPH2 = 0x9E,
+ CLK_PTO_SOR0 = 0xC0,
+ CLK_PTO_SOR1 = 0xC1,
+ CLK_PTO_HDMI = 0xC2,
- CLK_PTO_ENTROPY = 0xA0,
- CLK_PTO_UARTA = 0xA1,
- CLK_PTO_UARTB = 0xA2,
- CLK_PTO_UARTC = 0xA3,
- CLK_PTO_UARTD = 0xA4,
- CLK_PTO_OWR = 0xA5,
+ CLK_PTO_DISP2 = 0xC4,
+ CLK_PTO_DISP1 = 0xC5,
- CLK_PTO_HDA2CODEC_2X = 0xA7,
- CLK_PTO_HDA = 0xA8,
+ CLK_PTO_PLLD_OBS = 0xCA,
+ CLK_PTO_PLLD2_PTO_OBS = 0xCC,
+ CLK_PTO_PLLDP_OBS = 0xCE,
+ CLK_PTO_PLLE_OBS = 0x10A,
+ CLK_PTO_PLLU_OBS = 0x10C,
+ CLK_PTO_PLLREFE_OBS = 0x10E,
- CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
+ CLK_PTO_XUSB_FALCON = 0x110,
+ CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
+ CLK_PTO_USB_L0_RX = 0x112,
+ CLK_PTO_USB_L3_RX = 0x113,
+ CLK_PTO_USB_RX = 0x114,
+ CLK_PTO_USB3_L0_TXCLKREF = 0x115,
+ CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
+ CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
+ CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
+ CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
+ CLK_PTO_PEX_L4_RX = 0x11A,
+ CLK_PTO_PEX_TXCLKREF = 0x11B,
+ CLK_PTO_PEX_TXCLKREF_DIV2 = 0x11C,
+ CLK_PTO_PEX_TXCLKREF2 = 0x11D,
+ CLK_PTO_PEX_L0_RX = 0x11E,
+ CLK_PTO_PEX_L1_RX = 0x11F,
+ CLK_PTO_PEX_L2_RX = 0x120,
+ CLK_PTO_PEX_L3_RX = 0x121,
+ CLK_PTO_SATA_TXCLKREF = 0x122,
+ CLK_PTO_SATA_TXCLKREF_DIV2 = 0x123,
+ CLK_PTO_USB_L5_RX = 0x124,
+ CLK_PTO_SATA_TX = 0x125,
+ CLK_PTO_SATA_L0_RX = 0x126,
- CLK_PTO_SOR0 = 0xC0,
- CLK_PTO_SOR1 = 0xC1,
+ CLK_PTO_USB3_L1_TXCLKREF = 0x129,
+ CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
+ CLK_PTO_USB3_L7_RX = 0x12B,
+ CLK_PTO_USB3_TX = 0x12C,
+ CLK_PTO_UTMIP_PLL_PAD = 0x12D,
- CLK_PTO_DISP2 = 0xC4,
- CLK_PTO_DISP1 = 0xC5,
+ CLK_PTO_XUSB_FS = 0x136,
+ CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
+ CLK_PTO_XUSB_CORE_HOST = 0x138,
+ CLK_PTO_XUSB_CORE_DEV = 0x139,
- CLK_PTO_XUSB_FALCON = 0x110,
-
- CLK_PTO_XUSB_FS = 0x136,
- CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
- CLK_PTO_XUSB_CORE_HOST = 0x138,
- CLK_PTO_XUSB_CORE_DEV = 0x139,
+ CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
+ CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
+ CLK_PTO_USB_L4_RX = 0x13E,
+ CLK_PTO_USB_L6_RX = 0x13F,
/*
* PLL need PTO enabled in MISC registers.
* Normal div is 2 so result is multiplied with it.
*/
- CLK_PTO_PLLC_DIV2 = 0x01,
- CLK_PTO_PLLM_DIV2 = 0x02,
- CLK_PTO_PLLP_DIV2 = 0x03,
- CLK_PTO_PLLA_DIV2 = 0x04,
- CLK_PTO_PLLX_DIV2 = 0x05,
+ CLK_PTO_PLLC_DIV2 = 0x01,
+ CLK_PTO_PLLM_DIV2 = 0x02,
+ CLK_PTO_PLLP_DIV2 = 0x03,
+ CLK_PTO_PLLA_DIV2 = 0x04,
+ CLK_PTO_PLLX_DIV2 = 0x05,
- CLK_PTO_PLLMB_DIV2 = 0x25,
+ CLK_PTO_PLLMB_DIV2 = 0x25,
- CLK_PTO_PLLC4_DIV2 = 0x51,
+ CLK_PTO_PLLC4_DIV2 = 0x51,
- CLK_PTO_PLLA1_DIV2 = 0x55,
- CLK_PTO_PLLC2_DIV2 = 0x58,
- CLK_PTO_PLLC3_DIV2 = 0x5A,
+ CLK_PTO_PLLA1_DIV2 = 0x55,
+ CLK_PTO_PLLC2_DIV2 = 0x58,
+ CLK_PTO_PLLC3_DIV2 = 0x5A,
- CLK_PTO_PLLD_DIV2 = 0xCB,
- CLK_PTO_PLLD2_DIV2 = 0xCD,
- CLK_PTO_PLLDP_DIV2 = 0xCF,
+ CLK_PTO_PLLD_DIV2 = 0xCB,
+ CLK_PTO_PLLD2_DIV2 = 0xCD,
+ CLK_PTO_PLLDP_DIV2 = 0xCF,
- CLK_PTO_PLLU_DIV2 = 0x10D,
+ CLK_PTO_PLLE_DIV2 = 0x10B,
- CLK_PTO_PLLREFE_DIV2 = 0x10F,
+ CLK_PTO_PLLU_DIV2 = 0x10D,
+
+ CLK_PTO_PLLREFE_DIV2 = 0x10F,
} clock_pto_id_t;
/*
@@ -618,7 +724,7 @@ enum CLK_Y_DEV
};
/*! Generic clock descriptor. */
-typedef struct _clock_t
+typedef struct _clk_rst_t
{
u16 reset;
u16 enable;
@@ -626,11 +732,11 @@ typedef struct _clock_t
u8 index;
u8 clk_src;
u8 clk_div;
-} clock_t;
+} clk_rst_t;
/*! Generic clock enable/disable. */
-void clock_enable(const clock_t *clk);
-void clock_disable(const clock_t *clk);
+void clock_enable(const clk_rst_t *clk);
+void clock_disable(const clk_rst_t *clk);
/*! Clock control for specific hardware portions. */
void clock_enable_fuse(bool enable);
@@ -645,6 +751,12 @@ void clock_enable_host1x();
void clock_disable_host1x();
void clock_enable_tsec();
void clock_disable_tsec();
+void clock_enable_nvdec();
+void clock_disable_nvdec();
+void clock_enable_nvjpg();
+void clock_disable_nvjpg();
+void clock_enable_vic();
+void clock_disable_vic();
void clock_enable_sor_safe();
void clock_disable_sor_safe();
void clock_enable_sor0();
@@ -659,12 +771,25 @@ void clock_enable_coresight();
void clock_disable_coresight();
void clock_enable_pwm();
void clock_disable_pwm();
+void clock_enable_apbdma();
+void clock_disable_apbdma();
+void clock_enable_ahbdma();
+void clock_disable_ahbdma();
+void clock_enable_actmon();
+void clock_disable_actmon();
+void clock_enable_extperiph1();
+void clock_disable_extperiph1();
+void clock_enable_extperiph2();
+void clock_disable_extperiph2();
+
+void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210);
void clock_enable_pllx();
void clock_enable_pllc(u32 divn);
void clock_disable_pllc();
void clock_enable_pllu();
void clock_disable_pllu();
void clock_enable_utmipll();
+
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
diff --git a/bdk/soc/fuse.c b/bdk/soc/fuse.c
index 63037e9..9668196 100644
--- a/bdk/soc/fuse.c
+++ b/bdk/soc/fuse.c
@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011
- * Copyright (c) 2019-2021 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,
@@ -19,11 +19,14 @@
#include
+#include
#include
#include
#include
#include
+#include
#include
+#include
#include
static const u32 evp_thunk_template[] = {
@@ -42,12 +45,19 @@ static const u32 evp_thunk_template[] = {
0xe3822001, // ORR R2, R2, #1
0xe8bd0003, // LDMFD SP!, {R0,R1}
0xe12fff12, // BX R2
+ // idx: 15:
0x001007b0, // off_1007EC DCD evp_thunk_template
0x001007f8, // off_1007F0 DCD thunk_end
0x40004c30, // off_1007F4 DCD iram_evp_thunks
// thunk_end is here
};
-static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
+
+static const u32 evp_thunk_func_offsets_t210b01[] = {
+ 0x0010022c, // off_100268 DCD evp_thunk_template
+ 0x00100174, // off_10026C DCD thunk_end
+ 0x40004164, // off_100270 DCD iram_evp_thunks
+ // thunk_end is here
+};
// treated as 12bit values
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
@@ -80,19 +90,26 @@ u32 fuse_read_odm_keygen_rev()
u32 fuse_read_dramid(bool raw_id)
{
- u32 dramid = (fuse_read_odm(4) & 0xF8) >> 3;
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+ u32 odm4 = fuse_read_odm(4);
+
+ u32 dramid = (odm4 & 0xF8) >> 3;
+
+ // Get extended dram id info.
+ if (!tegra_t210)
+ dramid |= (odm4 & 0x7000) >> 7;
if (raw_id)
return dramid;
- if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
+ if (tegra_t210)
{
- if (dramid > 6)
+ if (dramid > 7)
dramid = 0;
}
else
{
- if (dramid > 28)
+ if (dramid > 34)
dramid = 8;
}
@@ -152,11 +169,8 @@ int fuse_set_sbk()
void fuse_wait_idle()
{
- u32 ctrl;
- do
- {
- ctrl = FUSE(FUSE_CTRL);
- } while (((ctrl >> 16) & 0x1f) != 4);
+ while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
+ ;
}
u32 fuse_read(u32 addr)
@@ -170,19 +184,19 @@ u32 fuse_read(u32 addr)
void fuse_read_array(u32 *words)
{
- u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192;
+ u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
+ FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM;
for (u32 i = 0; i < array_size; i++)
words[i] = fuse_read(i);
}
-static u32 _parity32_even(u32 *words, u32 count)
+static u32 _parity32_even(const u32 *words, u32 count)
{
u32 acc = words[0];
for (u32 i = 1; i < count; i++)
- {
acc ^= words[i];
- }
+
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
u32 x = hi ^ lo;
@@ -198,26 +212,26 @@ static int _patch_hash_one(u32 *word)
u32 bits20_31 = *word & 0xfff00000;
u32 parity_bit = _parity32_even(&bits20_31, 1);
u32 hash = 0;
+
for (u32 i = 0; i < 12; i++)
{
if (*word & (1 << (20 + i)))
- {
hash ^= hash_vals[i];
- }
}
+
if (hash == 0)
{
if (parity_bit == 0)
- {
return 0;
- }
+
*word ^= 1 << 24;
+
return 1;
}
+
if (parity_bit == 0)
- {
return 3;
- }
+
for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++)
{
if (hash_vals[i] == hash)
@@ -226,6 +240,7 @@ static int _patch_hash_one(u32 *word)
return 1;
}
}
+
return 2;
}
@@ -246,9 +261,7 @@ static int _patch_hash_multi(u32 *words, u32 count)
for (u32 bitpos = 0; bitpos < 32; bitpos++)
{
if ((w >> bitpos) & 1)
- {
hash ^= 0x4000 + i * 32 + bitpos;
- }
}
}
}
@@ -260,16 +273,14 @@ static int _patch_hash_multi(u32 *words, u32 count)
if (hash == 0)
{
if (parity_bit == 0)
- {
return 0;
- }
+
words[0] ^= 0x8000;
return 1;
}
if (parity_bit == 0)
- {
return 3;
- }
+
u32 bitcount = hash - 0x4000;
if (bitcount < 16 || bitcount >= count * 32)
{
@@ -277,14 +288,11 @@ static int _patch_hash_multi(u32 *words, u32 count)
for (u32 bitpos = 0; bitpos < 15; bitpos++)
{
if ((hash >> bitpos) & 1)
- {
num_set++;
- }
}
if (num_set != 1)
- {
return 2;
- }
+
words[0] ^= hash;
return 1;
}
@@ -297,29 +305,35 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
u32 words[80];
u32 word_count;
u32 word_addr;
- u32 word0 = 0;
+ u32 word0;
u32 total_read = 0;
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
word_count &= 0x7F;
- word_addr = 191;
+ word_addr = FUSE_ARRAY_WORDS_NUM - 1;
while (word_count)
{
total_read += word_count;
if (total_read >= ARRAY_SIZE(words))
- {
break;
- }
for (u32 i = 0; i < word_count; i++)
+ {
words[i] = fuse_read(word_addr--);
+ // Parse extra T210B01 fuses when the difference is reached.
+ if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
+ word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
+ (FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
+ {
+ word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
+ }
+ }
word0 = words[0];
if (_patch_hash_multi(words, word_count) >= 2)
- {
return 1;
- }
+
u32 ipatch_count = (words[0] >> 16) & 0xF;
if (ipatch_count)
{
@@ -332,13 +346,14 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
ipatch(addr, data);
}
}
+
words[0] = word0;
if ((word0 >> 25) == 0)
break;
+
if (_patch_hash_one(&word0) >= 2)
- {
return 3;
- }
+
word_count = word0 >> 25;
}
@@ -350,33 +365,48 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
u32 words[80];
u32 word_count;
u32 word_addr;
- u32 word0 = 0;
+ u32 word0;
u32 total_read = 0;
int evp_thunk_written = 0;
void *evp_thunk_dst_addr = 0;
+ bool t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
+ u32 *evp_thunk_tmp = (u32 *)malloc(sizeof(evp_thunk_template));
+ memcpy(evp_thunk_tmp, evp_thunk_template, sizeof(evp_thunk_template));
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
+ if (t210b01)
+ memcpy(&evp_thunk_tmp[15], evp_thunk_func_offsets_t210b01, sizeof(evp_thunk_func_offsets_t210b01));
+
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
word_count &= 0x7F;
- word_addr = 191;
+ word_addr = FUSE_ARRAY_WORDS_NUM - 1;
while (word_count)
{
total_read += word_count;
if (total_read >= ARRAY_SIZE(words))
- {
break;
- }
for (u32 i = 0; i < word_count; i++)
+ {
words[i] = fuse_read(word_addr--);
+ // Parse extra T210B01 fuses when the difference is reached.
+ if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
+ word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
+ (FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
+ {
+ word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
+ }
+ }
word0 = words[0];
if (_patch_hash_multi(words, word_count) >= 2)
{
+ free(evp_thunk_tmp);
return 1;
}
+
u32 ipatch_count = (words[0] >> 16) & 0xF;
u32 insn_count = word_count - ipatch_count - 1;
if (insn_count)
@@ -385,10 +415,10 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
{
evp_thunk_dst_addr = (void *)iram_evp_thunks;
- memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
- evp_thunk_dst_addr += evp_thunk_template_len;
+ memcpy(evp_thunk_dst_addr, (void *)evp_thunk_tmp, sizeof(evp_thunk_template));
+ evp_thunk_dst_addr += sizeof(evp_thunk_template);
evp_thunk_written = 1;
- *iram_evp_thunks_len = evp_thunk_template_len;
+ *iram_evp_thunks_len = sizeof(evp_thunk_template);
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
}
@@ -398,16 +428,22 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
evp_thunk_dst_addr += thunk_patch_len;
*iram_evp_thunks_len += thunk_patch_len;
}
+
words[0] = word0;
if ((word0 >> 25) == 0)
break;
+
if (_patch_hash_one(&word0) >= 2)
{
+ free(evp_thunk_tmp);
return 3;
}
+
word_count = word0 >> 25;
}
+ free(evp_thunk_tmp);
+
return 0;
}
@@ -419,7 +455,7 @@ bool fuse_check_patched_rcm()
// Check if RCM is ipatched.
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
- u32 word_addr = 191;
+ u32 word_addr = FUSE_ARRAY_WORDS_NUM - 1;
while (word_count)
{
diff --git a/bdk/soc/fuse.h b/bdk/soc/fuse.h
index 62fa1ff..48a2c7f 100644
--- a/bdk/soc/fuse.h
+++ b/bdk/soc/fuse.h
@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011
- * Copyright (c) 2019-2021 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,
@@ -23,67 +23,276 @@
#include
/*! Fuse registers. */
-#define FUSE_CTRL 0x0
-#define FUSE_ADDR 0x4
-#define FUSE_RDATA 0x8
-#define FUSE_WDATA 0xC
-#define FUSE_TIME_RD1 0x10
-#define FUSE_TIME_RD2 0x14
-#define FUSE_TIME_PGM1 0x18
-#define FUSE_TIME_PGM2 0x1C
-#define FUSE_PRIV2INTFC 0x20
-#define FUSE_FUSEBYPASS 0x24
-#define FUSE_PRIVATEKEYDISABLE 0x28
-#define FUSE_DISABLEREGPROGRAM 0x2C
-#define FUSE_WRITE_ACCESS_SW 0x30
-#define FUSE_PWR_GOOD_SW 0x34
-#define FUSE_SKU_INFO 0x110
-#define FUSE_CPU_SPEEDO_0_CALIB 0x114
-#define FUSE_CPU_IDDQ_CALIB 0x118
-#define FUSE_OPT_FT_REV 0x128
-#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
-#define FUSE_CPU_SPEEDO_2_CALIB 0x130
-#define FUSE_SOC_SPEEDO_0_CALIB 0x134
-#define FUSE_SOC_SPEEDO_1_CALIB 0x138
-#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
-#define FUSE_SOC_IDDQ_CALIB 0x140
-#define FUSE_OPT_CP_REV 0x190
-#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c
-#define FUSE_PRIVATE_KEY0 0x1A4
-#define FUSE_PRIVATE_KEY1 0x1A8
-#define FUSE_PRIVATE_KEY2 0x1AC
-#define FUSE_PRIVATE_KEY3 0x1B0
-#define FUSE_PRIVATE_KEY4 0x1B4
-#define FUSE_RESERVED_SW 0x1C0
-#define FUSE_USB_CALIB 0x1F0
-#define FUSE_SKU_DIRECT_CONFIG 0x1F4
-#define FUSE_OPT_VENDOR_CODE 0x200
-#define FUSE_OPT_FAB_CODE 0x204
-#define FUSE_OPT_LOT_CODE_0 0x208
-#define FUSE_OPT_LOT_CODE_1 0x20C
-#define FUSE_OPT_WAFER_ID 0x210
-#define FUSE_OPT_X_COORDINATE 0x214
-#define FUSE_OPT_Y_COORDINATE 0x218
-#define FUSE_GPU_IDDQ_CALIB 0x228
-#define FUSE_USB_CALIB_EXT 0x350
+#define FUSE_CTRL 0x0
+#define FUSE_ADDR 0x4
+#define FUSE_RDATA 0x8
+#define FUSE_WDATA 0xC
+#define FUSE_TIME_RD1 0x10
+#define FUSE_TIME_RD2 0x14
+#define FUSE_TIME_PGM1 0x18
+#define FUSE_TIME_PGM2 0x1C
+#define FUSE_PRIV2INTFC 0x20
+#define FUSE_FUSEBYPASS 0x24
+#define FUSE_PRIVATEKEYDISABLE 0x28
+#define FUSE_DISABLEREGPROGRAM 0x2C
+#define FUSE_WRITE_ACCESS_SW 0x30
+#define FUSE_PWR_GOOD_SW 0x34
+#define FUSE_PRIV2RESHIFT 0x3C
+#define FUSE_FUSETIME_RD0 0x40
+#define FUSE_FUSETIME_RD1 0x44
+#define FUSE_FUSETIME_RD2 0x48
+#define FUSE_FUSETIME_RD3 0x4C
+#define FUSE_PRIVATE_KEY0_NONZERO 0x80
+#define FUSE_PRIVATE_KEY1_NONZERO 0x84
+#define FUSE_PRIVATE_KEY2_NONZERO 0x88
+#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
+#define FUSE_PRIVATE_KEY4_NONZERO 0x90
-#define FUSE_RESERVED_ODM28_T210B01 0x240
+/*! Fuse Cached registers */
+#define FUSE_RESERVED_ODM8_B01 0x98
+#define FUSE_RESERVED_ODM9_B01 0x9C
+#define FUSE_RESERVED_ODM10_B01 0xA0
+#define FUSE_RESERVED_ODM11_B01 0xA4
+#define FUSE_RESERVED_ODM12_B01 0xA8
+#define FUSE_RESERVED_ODM13_B01 0xAC
+#define FUSE_RESERVED_ODM14_B01 0xB0
+#define FUSE_RESERVED_ODM15_B01 0xB4
+#define FUSE_RESERVED_ODM16_B01 0xB8
+#define FUSE_RESERVED_ODM17_B01 0xBC
+#define FUSE_RESERVED_ODM18_B01 0xC0
+#define FUSE_RESERVED_ODM19_B01 0xC4
+#define FUSE_RESERVED_ODM20_B01 0xC8
+#define FUSE_RESERVED_ODM21_B01 0xCC
+#define FUSE_KEK00_B01 0xD0
+#define FUSE_KEK01_B01 0xD4
+#define FUSE_KEK02_B01 0xD8
+#define FUSE_KEK03_B01 0xDC
+#define FUSE_BEK00_B01 0xE0
+#define FUSE_BEK01_B01 0xE4
+#define FUSE_BEK02_B01 0xE8
+#define FUSE_BEK03_B01 0xEC
+#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
+#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
+#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
+#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
+
+#define FUSE_PRODUCTION_MODE 0x100
+#define FUSE_JTAG_SECUREID_VALID 0x104
+#define FUSE_ODM_LOCK 0x108
+#define FUSE_OPT_OPENGL_EN 0x10C
+#define FUSE_SKU_INFO 0x110
+#define FUSE_CPU_SPEEDO_0_CALIB 0x114
+#define FUSE_CPU_IDDQ_CALIB 0x118
+
+#define FUSE_RESERVED_ODM22_B01 0x11C
+#define FUSE_RESERVED_ODM23_B01 0x120
+#define FUSE_RESERVED_ODM24_B01 0x124
+
+#define FUSE_OPT_FT_REV 0x128
+#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
+#define FUSE_CPU_SPEEDO_2_CALIB 0x130
+#define FUSE_SOC_SPEEDO_0_CALIB 0x134
+#define FUSE_SOC_SPEEDO_1_CALIB 0x138
+#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
+#define FUSE_SOC_IDDQ_CALIB 0x140
+
+#define FUSE_RESERVED_ODM25_B01 0x144
+
+#define FUSE_FA 0x148
+#define FUSE_RESERVED_PRODUCTION 0x14C
+#define FUSE_HDMI_LANE0_CALIB 0x150
+#define FUSE_HDMI_LANE1_CALIB 0x154
+#define FUSE_HDMI_LANE2_CALIB 0x158
+#define FUSE_HDMI_LANE3_CALIB 0x15C
+#define FUSE_ENCRYPTION_RATE 0x160
+#define FUSE_PUBLIC_KEY0 0x164
+#define FUSE_PUBLIC_KEY1 0x168
+#define FUSE_PUBLIC_KEY2 0x16C
+#define FUSE_PUBLIC_KEY3 0x170
+#define FUSE_PUBLIC_KEY4 0x174
+#define FUSE_PUBLIC_KEY5 0x178
+#define FUSE_PUBLIC_KEY6 0x17C
+#define FUSE_PUBLIC_KEY7 0x180
+#define FUSE_TSENSOR1_CALIB 0x184
+#define FUSE_TSENSOR2_CALIB 0x188
+
+#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
+
+#define FUSE_OPT_CP_REV 0x190
+#define FUSE_OPT_PFG 0x194
+#define FUSE_TSENSOR0_CALIB 0x198
+#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
+#define FUSE_SECURITY_MODE 0x1A0
+#define FUSE_PRIVATE_KEY0 0x1A4
+#define FUSE_PRIVATE_KEY1 0x1A8
+#define FUSE_PRIVATE_KEY2 0x1AC
+#define FUSE_PRIVATE_KEY3 0x1B0
+#define FUSE_PRIVATE_KEY4 0x1B4
+#define FUSE_ARM_JTAG_DIS 0x1B8
+#define FUSE_BOOT_DEVICE_INFO 0x1BC
+#define FUSE_RESERVED_SW 0x1C0
+#define FUSE_OPT_VP9_DISABLE 0x1C4
+
+#define FUSE_RESERVED_ODM0 0x1C8
+#define FUSE_RESERVED_ODM1 0x1CC
+#define FUSE_RESERVED_ODM2 0x1D0
+#define FUSE_RESERVED_ODM3 0x1D4
+#define FUSE_RESERVED_ODM4 0x1D8
+#define FUSE_RESERVED_ODM5 0x1DC
+#define FUSE_RESERVED_ODM6 0x1E0
+#define FUSE_RESERVED_ODM7 0x1E4
+
+#define FUSE_OBS_DIS 0x1E8
+
+#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
+
+#define FUSE_USB_CALIB 0x1F0
+#define FUSE_SKU_DIRECT_CONFIG 0x1F4
+#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
+#define FUSE_PACKAGE_INFO 0x1FC
+#define FUSE_OPT_VENDOR_CODE 0x200
+#define FUSE_OPT_FAB_CODE 0x204
+#define FUSE_OPT_LOT_CODE_0 0x208
+#define FUSE_OPT_LOT_CODE_1 0x20C
+#define FUSE_OPT_WAFER_ID 0x210
+#define FUSE_OPT_X_COORDINATE 0x214
+#define FUSE_OPT_Y_COORDINATE 0x218
+#define FUSE_OPT_SEC_DEBUG_EN 0x21C
+#define FUSE_OPT_OPS_RESERVED 0x220
+#define FUSE_SATA_CALIB 0x224
+
+#define FUSE_SPARE_REGISTER_ODM_B01 0x224
+
+#define FUSE_GPU_IDDQ_CALIB 0x228
+#define FUSE_TSENSOR3_CALIB 0x22C
+#define FUSE_CLOCK_BONDOUT0 0x230
+#define FUSE_CLOCK_BONDOUT1 0x234
+
+#define FUSE_RESERVED_ODM26_B01 0x238
+#define FUSE_RESERVED_ODM27_B01 0x23C
+#define FUSE_RESERVED_ODM28_B01 0x240
+
+#define FUSE_OPT_SAMPLE_TYPE 0x244
+#define FUSE_OPT_SUBREVISION 0x248
+#define FUSE_OPT_SW_RESERVED_0 0x24C
+#define FUSE_OPT_SW_RESERVED_1 0x250
+#define FUSE_TSENSOR4_CALIB 0x254
+#define FUSE_TSENSOR5_CALIB 0x258
+#define FUSE_TSENSOR6_CALIB 0x25C
+#define FUSE_TSENSOR7_CALIB 0x260
+#define FUSE_OPT_PRIV_SEC_DIS 0x264
+#define FUSE_PKC_DISABLE 0x268
+
+#define FUSE_BOOT_SECURITY_INFO_B01 0x268
+#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
+#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
+#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
+#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
+
+#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
+#define FUSE_TSENSOR_COMMON 0x280
+#define FUSE_OPT_CP_BIN 0x284
+#define FUSE_OPT_GPU_DISABLE 0x288
+#define FUSE_OPT_FT_BIN 0x28C
+#define FUSE_OPT_DONE_MAP 0x290
+
+#define FUSE_RESERVED_ODM29_B01 0x294
+
+#define FUSE_APB2JTAG_DISABLE 0x298
+#define FUSE_ODM_INFO 0x29C
+#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
+
+#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
+#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
+#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
+#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
+
+#define FUSE_WOA_SKU_FLAG 0x2C0
+#define FUSE_ECO_RESERVE_1 0x2C4
+#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
+#define FUSE_PRODUCTION_MONTH 0x2CC
+#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
+#define FUSE_TSENSOR9_CALIB 0x2D4
+#define FUSE_VMIN_CALIBRATION 0x2DC
+#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
+#define FUSE_DEBUG_AUTHENTICATION 0x2E4
+#define FUSE_SECURE_PROVISION_INDEX 0x2E8
+#define FUSE_SECURE_PROVISION_INFO 0x2EC
+#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
+#define FUSE_SPARE_ENDIS 0x2F4
+#define FUSE_ECO_RESERVE_0 0x2F8
+#define FUSE_RESERVED_CALIB0 0x304
+#define FUSE_RESERVED_CALIB1 0x308
+#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
+#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
+#define FUSE_OPT_CPU_DISABLE 0x314
+#define FUSE_OPT_CPU_DISABLE_CP1 0x318
+#define FUSE_TSENSOR10_CALIB 0x31C
+#define FUSE_TSENSOR10_CALIB_AUX 0x320
+#define FUSE_OPT_RAM_SVOP_DP 0x324
+#define FUSE_OPT_RAM_SVOP_PDP 0x328
+#define FUSE_OPT_RAM_SVOP_REG 0x32C
+#define FUSE_OPT_RAM_SVOP_SP 0x330
+#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
+
+#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
+#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
+#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
+#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
+#define FUSE_OPT_ROM_SVOP_SP_B01 0x334
+
+#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
+#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
+#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
+#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
+#define FUSE_OPT_CPU_DISABLE_CP2 0x348
+#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
+#define FUSE_USB_CALIB_EXT 0x350
+#define FUSE_RESERVED_FIELD 0x354
+#define FUSE_SPARE_REALIGNMENT_REG 0x37C
+#define FUSE_SPARE_BIT_0 0x380
+//...
+#define FUSE_SPARE_BIT_31 0x3FC
/*! Fuse commands. */
-#define FUSE_READ 0x1
-#define FUSE_WRITE 0x2
-#define FUSE_SENSE 0x3
+#define FUSE_IDLE 0x0
+#define FUSE_READ 0x1
+#define FUSE_WRITE 0x2
+#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3
+/*! Fuse status. */
+#define FUSE_STATUS_RESET 0
+#define FUSE_STATUS_POST_RESET 1
+#define FUSE_STATUS_LOAD_ROW0 2
+#define FUSE_STATUS_LOAD_ROW1 3
+#define FUSE_STATUS_IDLE 4
+#define FUSE_STATUS_READ_SETUP 5
+#define FUSE_STATUS_READ_STROBE 6
+#define FUSE_STATUS_SAMPLE_FUSES 7
+#define FUSE_STATUS_READ_HOLD 8
+#define FUSE_STATUS_FUSE_SRC_SETUP 9
+#define FUSE_STATUS_WRITE_SETUP 10
+#define FUSE_STATUS_WRITE_ADDR_SETUP 11
+#define FUSE_STATUS_WRITE_PROGRAM 12
+#define FUSE_STATUS_WRITE_ADDR_HOLD 13
+#define FUSE_STATUS_FUSE_SRC_HOLD 14
+#define FUSE_STATUS_LOAD_RIR 15
+#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
+#define FUSE_STATUS_READ_DEASSERT_PD 17
+
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
+#define FUSE_ARRAY_WORDS_NUM 192
+#define FUSE_ARRAY_WORDS_NUM_B01 256
+
enum
{
FUSE_NX_HW_TYPE_ICOSA,
FUSE_NX_HW_TYPE_IOWA,
FUSE_NX_HW_TYPE_HOAG,
- FUSE_NX_HW_TYPE_AULA
+ FUSE_NX_HW_TYPE_AULA
};
enum
diff --git a/bdk/soc/gpio.c b/bdk/soc/gpio.c
index 5cd2ccd..8575333 100644
--- a/bdk/soc/gpio.c
+++ b/bdk/soc/gpio.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * 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,
@@ -18,23 +18,27 @@
#include
#include
-#define GPIO_BANK_IDX(port) ((port) >> 2)
+#define GPIO_BANK_IDX(port) ((port) >> 2)
+#define GPIO_PORT_OFFSET(port) ((GPIO_BANK_IDX(port) << 8) + (((port) % 4) << 2))
-#define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
+#define GPIO_CNF_OFFSET(port) (0x00 + GPIO_PORT_OFFSET(port))
+#define GPIO_OE_OFFSET(port) (0x10 + GPIO_PORT_OFFSET(port))
+#define GPIO_OUT_OFFSET(port) (0x20 + GPIO_PORT_OFFSET(port))
+#define GPIO_IN_OFFSET(port) (0x30 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_STA_OFFSET(port) (0x40 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_ENB_OFFSET(port) (0x50 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_LVL_OFFSET(port) (0x60 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_CLR_OFFSET(port) (0x70 + GPIO_PORT_OFFSET(port))
-#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
-#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
+#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + GPIO_PORT_OFFSET(port))
+#define GPIO_OE_MASKED_OFFSET(port) (0x90 + GPIO_PORT_OFFSET(port))
+#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + GPIO_PORT_OFFSET(port))
+#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + GPIO_PORT_OFFSET(port))
+
+#define GPIO_DB_CTRL_OFFSET(port) (0xB0 + GPIO_PORT_OFFSET(port))
+#define GPIO_DB_CNT_OFFSET(port) (0xF0 + GPIO_PORT_OFFSET(port))
#define GPIO_IRQ_BANK1 32
#define GPIO_IRQ_BANK2 33
@@ -52,7 +56,7 @@ static u8 gpio_bank_irq_ids[8] = {
void gpio_config(u32 port, u32 pins, int mode)
{
- u32 offset = GPIO_CNF_OFFSET(port);
+ const u32 offset = GPIO_CNF_OFFSET(port);
if (mode)
GPIO(offset) |= pins;
@@ -64,7 +68,7 @@ void gpio_config(u32 port, u32 pins, int mode)
void gpio_output_enable(u32 port, u32 pins, int enable)
{
- u32 port_offset = GPIO_OE_OFFSET(port);
+ const u32 port_offset = GPIO_OE_OFFSET(port);
if (enable)
GPIO(port_offset) |= pins;
@@ -76,7 +80,7 @@ void gpio_output_enable(u32 port, u32 pins, int enable)
void gpio_write(u32 port, u32 pins, int high)
{
- u32 port_offset = GPIO_OUT_OFFSET(port);
+ const u32 port_offset = GPIO_OUT_OFFSET(port);
if (high)
GPIO(port_offset) |= pins;
@@ -86,16 +90,49 @@ void gpio_write(u32 port, u32 pins, int high)
(void)GPIO(port_offset); // Commit the write.
}
+void gpio_direction_input(u32 port, u32 pins)
+{
+ gpio_config(port, pins, GPIO_MODE_GPIO);
+ gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
+}
+
+void gpio_direction_output(u32 port, u32 pins, int high)
+{
+ gpio_config(port, pins, GPIO_MODE_GPIO);
+ gpio_write(port, pins, high);
+ gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE);
+}
+
int gpio_read(u32 port, u32 pins)
{
- u32 port_offset = GPIO_IN_OFFSET(port);
+ const u32 port_offset = GPIO_IN_OFFSET(port);
return (GPIO(port_offset) & pins) ? 1 : 0;
}
+void gpio_set_debounce(u32 port, u32 pins, u32 ms)
+{
+ const u32 db_ctrl_offset = GPIO_DB_CTRL_OFFSET(port);
+ const u32 db_cnt_offset = GPIO_DB_CNT_OFFSET(port);
+
+ if (ms)
+ {
+ if (ms > 255)
+ ms = 255;
+
+ // Debounce time affects all pins of the same port.
+ GPIO(db_cnt_offset) = ms;
+ GPIO(db_ctrl_offset) = (pins << 8) | pins;
+ }
+ else
+ GPIO(db_ctrl_offset) = (pins << 8) | 0;
+
+ (void)GPIO(db_ctrl_offset); // Commit the write.
+}
+
static void _gpio_interrupt_clear(u32 port, u32 pins)
{
- u32 port_offset = GPIO_INT_CLR_OFFSET(port);
+ const u32 port_offset = GPIO_INT_CLR_OFFSET(port);
GPIO(port_offset) |= pins;
@@ -104,10 +141,10 @@ static void _gpio_interrupt_clear(u32 port, u32 pins)
int gpio_interrupt_status(u32 port, u32 pins)
{
- u32 port_offset = GPIO_INT_STA_OFFSET(port);
- u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
+ const u32 port_offset = GPIO_INT_STA_OFFSET(port);
+ const u32 enabled_mask = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
- int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
+ int status = ((GPIO(port_offset) & pins) && enabled_mask) ? 1 : 0;
// Clear the interrupt status.
if (status)
@@ -118,7 +155,7 @@ int gpio_interrupt_status(u32 port, u32 pins)
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
{
- u32 port_offset = GPIO_INT_ENB_OFFSET(port);
+ const u32 port_offset = GPIO_INT_ENB_OFFSET(port);
// Clear any possible stray interrupt.
_gpio_interrupt_clear(port, pins);
@@ -133,7 +170,7 @@ void gpio_interrupt_enable(u32 port, u32 pins, int enable)
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
{
- u32 port_offset = GPIO_INT_LVL_OFFSET(port);
+ const u32 port_offset = GPIO_INT_LVL_OFFSET(port);
u32 val = GPIO(port_offset);
@@ -162,7 +199,7 @@ void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
u32 gpio_get_bank_irq_id(u32 port)
{
- u32 bank_idx = GPIO_BANK_IDX(port);
+ const u32 bank_idx = GPIO_BANK_IDX(port);
return gpio_bank_irq_ids[bank_idx];
-}
\ No newline at end of file
+}
diff --git a/bdk/soc/gpio.h b/bdk/soc/gpio.h
index 0c92b14..7f94de5 100644
--- a/bdk/soc/gpio.h
+++ b/bdk/soc/gpio.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * 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,
@@ -85,8 +85,11 @@
void gpio_config(u32 port, u32 pins, int mode);
void gpio_output_enable(u32 port, u32 pins, int enable);
+void gpio_direction_input(u32 port, u32 pins);
+void gpio_direction_output(u32 port, u32 pins, int high);
void gpio_write(u32 port, u32 pins, int high);
int gpio_read(u32 port, u32 pins);
+void gpio_set_debounce(u32 port, u32 pins, u32 ms);
int gpio_interrupt_status(u32 port, u32 pins);
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
diff --git a/bdk/soc/hw_init.c b/bdk/soc/hw_init.c
index 5efe5df..7bfa599 100644
--- a/bdk/soc/hw_init.c
+++ b/bdk/soc/hw_init.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2021 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,6 +19,7 @@
#include
#include
+#include
#include
#include
#include
@@ -31,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -39,7 +41,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -48,6 +50,17 @@
extern boot_cfg_t b_cfg;
extern volatile nyx_storage_t *nyx_str;
+u32 hw_rst_status;
+u32 hw_rst_reason;
+
+u32 hw_get_chip_id()
+{
+ if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
+ return GP_HIDREV_MAJOR_T210B01;
+ else
+ return GP_HIDREV_MAJOR_T210;
+}
+
/*
* CLK_OSC - 38.4 MHz crystal.
* CLK_M - 19.2 MHz (osc/2).
@@ -57,35 +70,45 @@ extern volatile nyx_storage_t *nyx_str;
* PCLK - 68MHz init (-> 136MHz -> OC/4).
*/
-u32 hw_get_chip_id()
-{
- if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
- return GP_HIDREV_MAJOR_T210B01;
- else
- return GP_HIDREV_MAJOR_T210;
-}
-
static void _config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
- SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
- TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
- CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
+ SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
+ TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
+ CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
- PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
- PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | (4 << 23); // LP0 EMC2TMC_CFG_XM2COMP_PU_VREF_SEL_RANGE.
+ PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
+ PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
- CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
- CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
+ CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
- PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
+ PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
+ CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
- CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
+}
+
+void hw_config_arbiter(bool reset)
+{
+ if (reset)
+ {
+ ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x0040090;
+ ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x12024C2;
+ ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x2201209;
+ ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320365B;
+ }
+ else
+ {
+ ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
+ ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
+ ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
+ ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
+ }
}
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
@@ -96,53 +119,39 @@ static void _config_gpios(bool nx_hoag)
if (!nx_hoag)
{
+ // Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
-
- // Set pin mode for UARTB/C TX pins.
-#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
- gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
-#endif
-#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
- gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
-#endif
-
- // Enable input logic for UARTB/C TX pins.
- gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
- gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
+ gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
+ gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
}
- // Set Joy-Con IsAttached direction.
+ // 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.
- gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
- gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
-
- // Enable input logic for Joy-Con IsAttached pins.
- gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
- gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
+ // Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
+ gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
+ gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
pinmux_config_i2c(I2C_1);
pinmux_config_i2c(I2C_5);
pinmux_config_uart(UART_A);
// Configure volume up/down as inputs.
- gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
- gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
- gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
- gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
+ gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
- // Configure HOME as inputs.
- // PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
- // gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
+ // Configure HOME as input. (Shared with UARTB RTS).
+ PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+ gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
+
+ // Power button can be configured for hoag here. Only SKU where it's connected.
}
static void _config_pmc_scratch()
{
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
- PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
+ PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
}
@@ -175,8 +184,9 @@ static void _mbist_workaround()
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
+ // Set SLCG overrides.
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
- VIC(0x8C) = 0xFFFFFFFF;
+ VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
usleep(2);
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
@@ -243,9 +253,9 @@ static void _mbist_workaround()
// Set child clock sources.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
}
static void _config_se_brom()
@@ -260,17 +270,23 @@ static void _config_se_brom()
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
// This memset needs to happen here, else TZRAM will behave weirdly later on.
- memset((void *)TZRAM_BASE, 0, 0x10000);
+ memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
- SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts.
- // Clear the boot reason to avoid problems later
- PMC(APBDEV_PMC_SCRATCH200) = 0x0;
- PMC(APBDEV_PMC_RST_STATUS) = 0x0;
+ // Clear SE interrupts.
+ SE(SE_INT_STATUS_REG) = SE_INT_OP_DONE | SE_INT_OUT_DONE | SE_INT_OUT_LL_BUF_WR | SE_INT_IN_DONE | SE_INT_IN_LL_BUF_RD;
+
+ // Save reset reason.
+ hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
+ hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
+
+ // Clear the boot reason to avoid problems later.
+ PMC(APBDEV_PMC_SCRATCH200) = 0;
+ PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
}
-static void _config_regulators(bool tegra_t210)
+static void _config_regulators(bool tegra_t210, bool nx_hoag)
{
// Set RTC/AO domain to POR voltage.
if (tegra_t210)
@@ -279,19 +295,26 @@ static void _config_regulators(bool tegra_t210)
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
- // Disable SDMMC1 IO power.
- gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
+ // Power on all relevant rails in case we came out of warmboot. Only keep MEM/MEM_COMP and SDMMC1 states.
+ PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_MEM_COMP | PMC_NO_IOPOWER_SDMMC1 | PMC_NO_IOPOWER_MEM;
+
+ // Make sure SDMMC1 IO/Core are powered off.
max7762x_regulator_enable(REGULATOR_LDO2, false);
+ gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
+ PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
+ (void)PMC(APBDEV_PMC_NO_IOPOWER);
sd_power_cycle_time_start = get_tmr_ms();
+ // Disable backup battery charger.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
- MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
+
+ // Set PWR delay for forced shutdown off to 6s.
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT));
if (tegra_t210)
{
// Configure all Flexible Power Sequencers for MAX77620.
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (0 << MAX77620_FPS_EN_SRC_SHIFT));
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
max77620_regulator_config_fps(REGULATOR_LDO4);
@@ -300,13 +323,13 @@ static void _config_regulators(bool tegra_t210)
max77620_regulator_config_fps(REGULATOR_SD1);
max77620_regulator_config_fps(REGULATOR_SD3);
- i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
- (4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
+ // Set GPIO3 to FPS0 for SYS 3V3 EN. Enabled when FPS0 is enabled.
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, (4 << MAX77620_FPS_PU_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT));
// Set vdd_core voltage to 1.125V.
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
- // Fix CPU/GPU after L4T warmboot.
+ // Power down CPU/GPU regulators after L4T warmboot.
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
@@ -314,26 +337,49 @@ static void _config_regulators(bool tegra_t210)
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
}
- else // Tegra X1+ set vdd_core voltage to 1.05V.
+ else
+ {
+ // Tegra X1+ set vdd_core voltage to 1.05V.
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
+
+ // Power on SD2 regulator for supplying LDO0/1/8.
+ max7762x_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_POWER_MODE_NORMAL << MAX77620_SD_POWER_MODE_SHIFT) |
+ MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
+
+ // Enable LDO8 on HOAG as it also powers I2C1 IO pads.
+ if (nx_hoag)
+ {
+ max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
+ max7762x_regulator_enable(REGULATOR_LDO8, true);
+ }
+ }
}
void hw_init()
{
- // Get Chip ID.
+ // Get Chip ID and SKU.
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
// Bootrom stuff we skipped by going through rcm.
_config_se_brom();
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
- SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
- PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
+
+ // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
+ SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
+ PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
// Perform Memory Built-In Self Test WAR if T210.
if (tegra_t210)
_mbist_workaround();
+ // Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
+ CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
+
// Enable Security Engine clock.
clock_enable_se();
@@ -352,13 +398,7 @@ void hw_init()
// Initialize pin configuration.
_config_gpios(nx_hoag);
-#ifdef DEBUG_UART_PORT
- clock_enable_uart(DEBUG_UART_PORT);
- uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE);
- uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
-#endif
-
- // Enable Dynamic Voltage and Frequency Scaling device clock.
+ // Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
clock_enable_cl_dvfs();
// Enable clocks to I2C1 and I2CPWR.
@@ -371,63 +411,83 @@ void hw_init()
// Initialize I2C5, mandatory for PMIC.
i2c_init(I2C_5);
- //! TODO: Why? Device is NFC MCU on Lite.
- if (nx_hoag)
- {
- max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
- max7762x_regulator_enable(REGULATOR_LDO8, true);
- }
+ // Initialize various regulators based on Erista/Mariko platform.
+ _config_regulators(tegra_t210, nx_hoag);
// Initialize I2C1 for various power related devices.
i2c_init(I2C_1);
- // Initialize various regulators based on Erista/Mariko platform.
- _config_regulators(tegra_t210);
-
- // Enable charger in case it's disabled.
- bq24193_enable_charger();
-
_config_pmc_scratch(); // Missing from 4.x+
// Set BPMP/SCLK to PLLP_OUT (408MHz).
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
- // Disable TZRAM shutdown control and lock the regs.
+ // Power on T210B01 shadow TZRAM and lock the reg.
if (!tegra_t210)
{
- PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE;
- PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3;
- PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3;
+ PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
+ PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
+ PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
}
+ // Set arbiter.
+ hw_config_arbiter(false);
+
// Initialize External memory controller and configure DRAM parameters.
sdram_init();
bpmp_mmu_enable();
+
+ // Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
+ clock_enable_host1x();
+
+#ifdef DEBUG_UART_PORT
+ // Setup debug uart port.
+ #if (DEBUG_UART_PORT == UART_B)
+ gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
+ #elif (DEBUG_UART_PORT == UART_C)
+ gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
+ #endif
+ pinmux_config_uart(DEBUG_UART_PORT);
+ clock_enable_uart(DEBUG_UART_PORT);
+ uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
+ uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
+#endif
}
-void hw_reinit_workaround(bool coreboot, u32 bl_magic)
+void hw_deinit(bool coreboot, u32 bl_magic)
{
- // Disable BPMP max clock.
+ bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
+
+ // Scale down BPMP clock.
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
-#ifdef NYX
- // Disable temperature sensor, touchscreen, 5V regulators and Joy-Con.
+#ifdef BDK_HW_EXTRA_DEINIT
+ // Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
+ vic_end();
tmp451_end();
- set_fan_duty(0);
+ fan_set_duty(0);
touch_power_off();
jc_deinit();
regulator_5v_disable(REGULATOR_5V_ALL);
#endif
- // Flush/disable MMU cache and set DRAM clock to 204MHz.
- bpmp_mmu_disable();
+ // set DRAM clock to 204MHz.
minerva_change_freq(FREQ_204);
nyx_str->mtc_cfg.init_done = 0;
+ // Flush/disable MMU cache.
+ bpmp_mmu_disable();
+
+ // Reset arbiter.
+ hw_config_arbiter(true);
+
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
- CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
- CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
+ if (tegra_t210)
+ {
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
+ }
// Do coreboot mitigations.
if (coreboot)
@@ -436,14 +496,12 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
clock_disable_cl_dvfs();
- // Disable Joy-con GPIOs.
+ // Disable Joy-con detect in order to restore UART TX.
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
- gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);
- gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);
// Reinstate SD controller power.
- PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
+ PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
}
// Seamless display or display power off.
@@ -456,17 +514,11 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
display_backlight_brightness(brightness, 0);
break;
+ case BL_MAGIC_L4TLDR_SLD:
+ // Do not disable display or backlight at all.
+ break;
default:
display_end();
- }
-
- // Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
- if (bl_magic == BL_MAGIC_BROKEN_HWI)
- {
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
- sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
- clock_disable_cl_dvfs();
-
- msleep(200);
+ clock_disable_host1x();
}
}
diff --git a/bdk/soc/hw_init.h b/bdk/soc/hw_init.h
index a1b2dfc..fcd8d10 100644
--- a/bdk/soc/hw_init.h
+++ b/bdk/soc/hw_init.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,
@@ -21,10 +21,14 @@
#include
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
-#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit.
+#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1.
+
+extern u32 hw_rst_status;
+extern u32 hw_rst_reason;
void hw_init();
-void hw_reinit_workaround(bool coreboot, u32 magic);
+void hw_deinit(bool coreboot, u32 magic);
+void hw_config_arbiter(bool reset);
u32 hw_get_chip_id();
#endif
diff --git a/bdk/soc/i2c.c b/bdk/soc/i2c.c
index 0906adc..c38e952 100644
--- a/bdk/soc/i2c.c
+++ b/bdk/soc/i2c.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (c) 2018-2020 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,
@@ -18,7 +18,8 @@
#include
#include