Compare commits

...

630 commits

Author SHA1 Message Date
CTCaer
3250b2e32a Bump hekate to v6.2.2 and Nyx to v1.6.4 2024-10-12 17:51:00 +03:00
CTCaer
e3eee73318 nyx: do not spam log on partition restore 2024-10-12 17:50:54 +03:00
CTCaer
81fb318f6b hos: add 19.0.0 support 2024-10-11 13:04:16 +03:00
CTCaer
84f3f7d92a nyx: add 400us sleep in lv task loop
Tiny power save.
2024-10-10 18:28:29 +03:00
CTCaer
788ecb60a3 l4t: bump api to 7 2024-10-10 18:26:19 +03:00
CTCaer
14413ae6bd bdk: timer: restore rtc timer spinlock 2024-10-10 18:22:03 +03:00
CTCaer
1849ac6667 nyx: optimize battery info
- Remove input voltage limit
- Add an extra PD profile
2024-10-10 15:21:32 +03:00
CTCaer
1bec721baf hos: add missing deinit 2024-10-10 15:21:32 +03:00
CTCaer
6fa844b031 hekate/nyx: use updated dirlist 2024-10-09 15:22:16 +03:00
CTCaer
d2fc6379c6 bdk: utils: improve dirlist
Stop doing unnecessary copies during reordering and use pointers for that.
2024-10-09 15:14:44 +03:00
CTCaer
f15af01727 readme: explain what stock basically is even more 2024-10-09 15:10:23 +03:00
CTCaer
69acef4db3 nyx: part manager: change GPT partition colour
Since many confuse that on MBR
2024-10-04 22:19:01 +03:00
CTCaer
cdc1012f50 nyx: part manager: add version on android button
Check partition scheme for android and add the version on the flash button
2024-10-04 22:18:20 +03:00
CTCaer
63c4bdd7d9 nyx: no need to double check for errors 2024-10-04 22:16:36 +03:00
CTCaer
0e23d0e0fd nyx: name button list object appropriately 2024-10-04 22:14:51 +03:00
CTCaer
9463f8aa7d nyx: fix memleak when 10 launcher items are shown 2024-10-04 22:14:23 +03:00
CTCaer
34f8692f5c nyx: do not use global cal0 buf name 2024-10-04 22:12:53 +03:00
CTCaer
9da5149394 minerva: correct init done type 2024-10-04 22:11:41 +03:00
CTCaer
75676a78ff hos: secmon name ini lists properly 2024-10-04 22:10:50 +03:00
CTCaer
66454b934c hos: no need to double check allocated eks 2024-10-04 22:09:54 +03:00
CTCaer
7b60c3d162 hekate/nyx: constify more args 2024-10-04 22:09:06 +03:00
CTCaer
c422d63b64 hekate: tools: fix menu memleak 2024-10-04 22:04:56 +03:00
CTCaer
0acdefb32a hekate: info: remove input voltage limit
It's a useless metric and in HOS it's used incorrectly.
2024-10-04 22:02:34 +03:00
CTCaer
edf00d8e51 bdk: bpmp: add state set function
Some states are controlled via software. So add a function for that.
2024-10-04 21:54:58 +03:00
CTCaer
1a98e3a702 bdk: irq: disable irq if handler error 2024-10-04 21:53:17 +03:00
CTCaer
8bf3bee08b bdk: uart: fix fifo clear
- Do not clear fifo for everything if not needed
- Correct fifo clear checks
2024-10-04 21:52:24 +03:00
CTCaer
f2be59888b bdk: add irq header to bdk header 2024-10-04 21:48:44 +03:00
CTCaer
5c77601f7a bdk: ums: always allow finish reply
Parse scsi cmd failures are handled internally.
2024-10-04 21:47:26 +03:00
CTCaer
9e239df39e bdk: constify various args 2024-10-04 21:45:57 +03:00
CTCaer
b1bc6ebdd8 bdk: joycon: utilize packet id per joycon
Also fix a possible infinite loop
2024-10-04 21:39:35 +03:00
CTCaer
5c39d04ca2 Bump hekate to v6.2.1 and Nyx to v1.6.3 2024-07-02 19:02:46 +03:00
CTCaer
85cd26e305 l4t: update loader to v6
- Move TZ parameters to a static address inside TZDRAM
- Update fw rev for new ARC
- Refactor context and parameters into a single struct
2024-07-02 18:37:15 +03:00
CTCaer
6c601ccaa5 hekate: reinstate charger enable
Add back charger enable on boot, inside low battery check.

It will be kept as is since there's the following case that addresses:
OTG mode and shut off will not restore charger mode.
2024-07-02 18:32:16 +03:00
CTCaer
0aea402632 Add rel versioning and adjust accordingly 2024-07-02 18:29:39 +03:00
CTCaer
280ebcc1e6 nyx: refactor hw info to provide more SKU data 2024-07-02 18:06:32 +03:00
CTCaer
106a08f19c hos: rename function 2024-07-02 18:04:52 +03:00
CTCaer
aacae78420 nyx: partition manager error message improvement
Inform user that there's an issue with bootloader folder when a partial backup is done during partitioning.
2024-07-02 18:04:09 +03:00
CTCaer
716cfbfbaf bdk: sdram: refactor init 2024-07-02 18:02:05 +03:00
CTCaer
e47b6ec19b bdk: hwinit: display changes
Do not display ldo0 if enabled here as it's not needed.
Make sure PLLP_OUTB is properly reset in case of coming out of warmboot.
2024-07-02 17:59:14 +03:00
CTCaer
acb3997a7d bdk: hwinit: reorder no io power
And make sure sdmmc iopower is not enabled after vdd disable.
2024-07-02 17:56:20 +03:00
CTCaer
4c5cc6d567 bdk: display: small refactor 2024-07-02 17:52:12 +03:00
CTCaer
c321d3508c Bump hekate to v6.2.0 and Nyx to v1.6.2 2024-06-11 12:41:19 +03:00
CTCaer
66303d0d47 hos: reinstate host1x disable 2024-06-11 12:41:13 +03:00
CTCaer
80b3651d0a nyx: correct touch fw id display 2024-06-11 09:08:33 +03:00
CTCaer
242debfe3e modules: use echo -e for newline prints 2024-06-11 09:04:21 +03:00
CTCaer
68408bbb79 hos: add 18.1.0 support 2024-06-11 08:59:45 +03:00
CTCaer
cf954b451c hekate: refactor of main
- Remove unused function
- Rename some functions and make them static
- Reorder freeing of menu entries
2024-06-10 16:25:50 +03:00
CTCaer
75a4a8ba1d bdk: sdmmc: remove higher power limits
UHS-I Cards force a max of 1.44W even if higher modes are selected.
This does not change functionality, so remove them as unused.
2024-06-10 13:37:28 +03:00
CTCaer
a37b5c7841 bdk: sdmmc: no need to raise power limit for HS25 2024-06-10 13:24:07 +03:00
CTCaer
48334779a5 bdk: sdmmc: error reporting changes
- Correct transfer error message
- Add debug print for deinit
2024-06-08 17:41:11 +03:00
CTCaer
054c68f251 bdk: hwinit: power on all relevant rails
Since that doesn't happen via sdram init anymore, do it in hwinit.
It only matters if we came out of warmboot.
2024-06-08 12:21:15 +03:00
CTCaer
655209bedc bdk: sdram: keep sdmmc1 no iopower state 2024-06-08 12:19:24 +03:00
CTCaer
85eb5489fe bdk: pmc: rename io/det power defines 2024-06-08 12:16:07 +03:00
CTCaer
11262c2112 nyx: adhere to fan driver changes 2024-06-07 17:15:27 +03:00
CTCaer
8b4f776c9d bdk: fan: rename functions and add set from temp
- Rename functions to proper style (drivername_)
- Add fan_set_from_temp for managing the fan with passed SoC temperature.
2024-06-07 17:14:05 +03:00
CTCaer
a34206df5b bdk: sdmmc: small changes
- Log warning for comp pad calibration timeout
- Rename some func/defines
- Increase SDMMC1 power disable wait to 10ms
 No real perceived functionality change.
2024-06-07 17:09:30 +03:00
CTCaer
4a24fe0b35 bdk: display: add useful functions
- Window disable
- Window framebuffer address set
- Window framebuffer move to new address
2024-06-06 06:27:30 +03:00
CTCaer
14c482ddce bdk: display: remove max77620 gpio 7 enable
It is actually not used at all.
So do not configure it to save power.
2024-06-05 15:20:27 +03:00
CTCaer
8d49bc3c33 bdk: hwinit: move LDO8 init in regulators init
And also reorder it above I2C1 init (because of HOAG).
2024-06-05 01:35:05 +03:00
CTCaer
39c614a3ab bdk: hwinit: move sd2 to hw init
SD2 powers LDO0/1/8 on T210B01 so there's no need to be in display init.
Also there's not need to power it down first so configure it in one go.
2024-06-05 01:33:15 +03:00
CTCaer
7652d9cdb1 bdk: display: use mipi cal sw war on T210 also
As per Nvidia, the pad brick separates clock and data terminations.
This necessitates doing the calibration twice.

Nvidia/Nintendo probably never updated that part on T210 since it's from around
2015/2016. T210B01 is based on 2017 codebase so it has it.
HOS (nvservices, not boot) is probably updated to also do that.
If not, then they should fix it.

There are 0 known issue reports with that on T210, but well.
2024-06-05 01:11:04 +03:00
CTCaer
21d782587f hekate/nyx: adhere to display function renames 2024-06-05 01:03:46 +03:00
CTCaer
48ef1826e9 bdk: display: rename functions
display_init_framebuffer_pitch -> display_init_window_a_pitch
display_init_framebuffer_pitch_vic -> display_init_window_a_pitch_vic
display_init_framebuffer_pitch_inv -> display_init_window_a_pitch_inv
display_init_framebuffer_block -> display_init_window_a_block
display_init_framebuffer_log -> display_init_window_d_console
display_activate_console -> display_window_d_console_enable
display_deactivate_console -> display_window_d_console_disable
display_init_cursor -> display_cursor_init
display_set_pos_cursor -> display_cursor_set_pos
display_deinit_cursor -> display_cursor_deinit
2024-06-05 01:00:58 +03:00
CTCaer
4fef1890aa bdk: rename exec_cfg to reg_write_array
And cfg_op_t to reg_cfg_t.
2024-06-05 00:49:15 +03:00
CTCaer
320b91a767 bdk: display: return duty for oled panel properly
For display_get_backlight_brightness.
2024-06-02 08:23:58 +03:00
CTCaer
c5f6837c35 bdk: display: wait 1 frame after display off cmd 2024-06-02 08:23:13 +03:00
CTCaer
72f980d0f4 bdk: display: fully streamline dc/win setup
As explained before, Nvidia just grabbed the whole dynamic init and made arrays
of it, without actually optimizing it.
The second part of the streamline aims to fully de-duplicate that.
- Completely remove all already set registers for DC/DISP/WIN.
- Do not touch other windows when a specific window is setup.
- Init Window D also together with A/B/C since code is made for DISPA.
- Add missing increase for syncpt 1.
2024-06-02 08:22:20 +03:00
CTCaer
b3be7e7a41 bdk: display: use the same HS exit threshold
No need to use minimum on T210.
Use the same byte clocks as T210B01 to simplify init.
2024-06-02 08:11:22 +03:00
CTCaer
26c6c6372d bdk: display: rename window setup arrays
Add window number info and remove the fb naming
2024-06-02 08:05:50 +03:00
CTCaer
28eb3f4bcd bdk: display: deduplicate array size macro 2024-06-02 08:02:44 +03:00
CTCaer
bd55a3e756 bdk: clock: always set DISPA source
No need to distinguish between LP or HS.
Setting the same value doesn't glitch.
2024-06-02 08:00:42 +03:00
CTCaer
146ff53a31 hekate: set bpmp high clock earlier 2024-06-02 07:57:22 +03:00
CTCaer
a96cac5964 hekate: adjust payload sd wait
hekate always waits at init, so not need to do that 2 times.
2024-06-02 07:56:07 +03:00
CTCaer
b01cc2432f bdk: irq: remove ack source
HW interrupts can't be managed by FIR.
Only actual hw can clear the interrupt.
2024-06-02 07:46:18 +03:00
CTCaer
05db43a97c bdk: hwinit: move down debug uart init 2024-06-02 07:44:22 +03:00
CTCaer
859811a154 bdk: fatfs: update copyright
Last edit was in 2022.
2024-06-02 07:42:35 +03:00
CTCaer
0a6521ec26 Update "about" copyrights 2024-06-02 07:41:18 +03:00
CTCaer
6b54c4a477 bdk: usb: hid: don't send a packet if no new data
Reduce the interrupt caused at the host side
2024-06-02 07:40:11 +03:00
CTCaer
e46f54d4e6 hekate/nyx: use static/const where it should 2024-06-02 07:38:07 +03:00
CTCaer
9d79af231e bdk: use static where it should 2024-06-02 07:09:34 +03:00
CTCaer
d933aa80f7 hekate: use IRAM for stack 2024-06-02 07:04:17 +03:00
CTCaer
84c5439c70 bdk: usb: utilize apb relaxed clocks for init 2024-06-02 07:01:31 +03:00
CTCaer
ddd19661bd nyx: use bpmp relaxed func 2024-06-02 06:55:25 +03:00
CTCaer
78cdb5575d hos: use new func 2024-06-02 06:53:40 +03:00
CTCaer
8c44969afb bdk: blz: refactor style 2024-06-02 06:51:47 +03:00
CTCaer
7a74761da9 bdk: bpmp: add and use bpmp_clk_rate_relaxed 2024-06-02 06:51:06 +03:00
CTCaer
14706cef4e bdk: minerva: add emc src div disable 2024-06-02 06:46:28 +03:00
CTCaer
93296c2c38 bdk: joycon: add packet size checks
Pass the real received data size and do the proper checks for minimum info.
2024-05-19 17:42:10 +03:00
CTCaer
b744f82942 nyx: report right stick coordinates in debug
- Add right stick x/y
- Remove calibration x/y min/max
2024-05-19 12:19:26 +03:00
CTCaer
c4567ab2b5 nyx: set touch indev also and name them
Just keep it around for any reference.
2024-05-19 12:08:47 +03:00
CTCaer
0544f9143f nyx: tools: allow dynamic size for boot partitions
Let UMS driver set the size in case the partition is bigger.
That doesn't affect anything other than allowing the host to see the whole
physical partition.
2024-05-19 10:58:53 +03:00
CTCaer
a070d2e394 bdk: ums: allow real sizes for boot partitions
Since that's eMMC, do not clamp the size to 4MB.
That doesn't affect anything other than allowing the host to see the whole
physical partition .
2024-05-19 10:57:20 +03:00
CTCaer
927489d2da bdk: add missed defines 2024-05-19 10:50:25 +03:00
CTCaer
5453c593a3 hekate/nyx: adhere to hw_deinit change 2024-05-19 10:49:46 +03:00
CTCaer
ae29f359ee bdk: hwinit: rename reinit_workaround to deinit 2024-05-19 10:49:25 +03:00
CTCaer
7af343dd6c bdk: input: make joycon detection more robust
There's a hw bug on the gpio controller that can latch the last value on reads.
Mitigate that by reading once to unlatch the input value.

Also actually allow sio to be polled every 8ms.
2024-05-19 10:19:25 +03:00
CTCaer
547a3542ee bdk: display: add more defines 2024-05-19 10:16:52 +03:00
CTCaer
4bc0a0591c bdk: display: wait 2us for bl pwm config to take
Fixes the tiny blink showing up while pwm is still at max.
2024-05-19 10:15:52 +03:00
CTCaer
1214ab0e02 ldr/bl: manage arbiter 2024-05-19 10:12:18 +03:00
CTCaer
985c513770 bdk: hwinit: add arbiter config 2024-05-19 10:07:06 +03:00
CTCaer
16eb6a3c44 bdk: types: do not overflow on byte swaps
Addresses warning message.
2024-04-25 16:57:43 +03:00
CTCaer
ef1e328e11 bdk: info: revamp eMMC partition table info
Allow a max of 20 partitions to be shown
2024-04-25 04:57:31 +03:00
CTCaer
856994e4f4 bdk: sprintf: add right padding support 2024-04-25 04:56:38 +03:00
CTCaer
77782b974c nyx: info: report oem id for eMMC 2024-04-25 04:55:17 +03:00
CTCaer
38f4902e1d nyx: info: change touch fw version format 2024-04-25 04:54:58 +03:00
CTCaer
90b9f9f589 hos: add comments about autonogc 2024-04-25 04:53:06 +03:00
CTCaer
ec2e62236a bdk: pinmux: add i2s pin config 2024-04-25 04:52:13 +03:00
CTCaer
2648a2655c bdk: sdram: add info about custom 8GB T210 config
That's a suggestion on which 4GB modules are certainly fine to use.
2024-04-25 04:50:07 +03:00
CTCaer
62153fdfbb bdk: types: add likely/unlikely global macros 2024-04-25 04:48:09 +03:00
CTCaer
28960728f9 bdk: joycon: add bit numbers on the button struct 2024-04-25 04:46:27 +03:00
CTCaer
902ccede9a bdk: joycon: use proper bits for batt levels 2024-04-25 04:45:50 +03:00
CTCaer
96efa7a002 bdk: vic: add support for P8 and R5G5B5 2024-04-25 04:44:22 +03:00
CTCaer
d92906db5e bdk: display: correct some reg names and add more 2024-04-25 04:44:08 +03:00
CTCaer
e8d6516f43 bdk: display: use basic profile for OLED
That's the one with the accurate sRGB colors.
Anything else is over saturated.
2024-04-25 04:38:57 +03:00
CTCaer
a6727f6e32 bdk: display: update active regs on vsync for WinD
Doing that on hsync can cause issues on disable without actually syncing to it.
2024-04-25 04:38:04 +03:00
CTCaer
35ea35f6ad hos: pkg2: do not exit loop when non nogc 2024-03-29 15:12:53 +02:00
CTCaer
9e1b2ee573 Bump hekate to v6.1.1 and Nyx to v1.6.1 2024-03-29 16:34:08 +02:00
CTCaer
9cfe1d2162 nyx: add info about 6.2" oem panel clone 2024-03-29 16:34:08 +02:00
CTCaer
cfbbafe72f nyx: change imu cal warning message 2024-03-29 13:42:41 +02:00
CTCaer
5607fd18ea hos: 18.0.0 support 2024-03-29 13:21:53 +02:00
CTCaer
d71903abf2 hos: simplify nogc patch 2024-03-29 13:21:53 +02:00
CTCaer
547cfca0c9 hos: simplify emummc patch 2024-03-29 13:21:53 +02:00
CTCaer
dca350bfe9 hos: use strcmp for kip name
KIP1 names are NULL terminated, so use strcmp to reduce codesize.
2024-03-29 13:21:53 +02:00
CTCaer
06b7a38d47 nyx: retry to dump imu cal and skip it failed
On devices with mangled cal0 imu calibration can now be skipped (still mandatory on Lite).
2024-03-29 13:21:53 +02:00
CTCaer
9567ba19c8 l4t: bump loader/firmware revisions 2024-03-29 13:21:53 +02:00
CTCaer
c9ff5179f9 exo: use mixed version identification 2024-03-29 13:21:53 +02:00
CTCaer
f764bf04b1 hos: reboot to ofw if stock fails
If package1 fails to be read and conditions are valid, reboot to OFW automatically when stock mode is enabled.
2024-03-29 13:21:53 +02:00
CTCaer
8b1486c74b hekate: expose autorcm check 2024-03-29 13:21:53 +02:00
CTCaer
471b99366d hos: small refactor 2024-03-29 13:21:53 +02:00
CTCaer
368ca21316 hos: fix sys counters reset and always apply it 2024-03-29 13:21:53 +02:00
CTCaer
c021aef9b0 fss: save fss0 for being able to free it if error
Also do not free secmon/kernel in case it's from fss
2024-03-29 13:21:53 +02:00
CTCaer
622f7124ac fss: remove dynamic path
Atmosphere never implemented per sysMMC/emuMMC support for configs.
So remove path parsing to reduce codesize.
2024-03-29 13:21:53 +02:00
CTCaer
e846f4576e bdk: minerva: l4t: adjust sdmmc1 la and freq table
- LA is tightened up
- Copied frequencies are now 204/408/800/1333/1600/OC (from 204/666/800/1600/OC)
2024-03-29 13:21:53 +02:00
CTCaer
42c02e97e8 bdk: display: add 6.2" panel clone 2024-03-29 13:21:53 +02:00
CTCaer
4b3014bc18 hos: pkg2: simple refactor 2024-03-29 13:21:53 +02:00
CTCaer
4effaab241 hekate/nyx: use zalloc where appropriate 2024-03-27 09:16:06 +02:00
CTCaer
d687b53249 bdk: heap: add zalloc and utilize it 2024-03-27 09:00:53 +02:00
CTCaer
9e41aa7759 bdk: smmu: refactor and update driver
- Allow ASID to be configured
- Allow 34-bit PAs
- Use special type for setting PDE/PTE config
- Initialize all pages as non accessible
- Add function for mapping 4MB regions directly
- Add SMMU heap reset function
- Correct address load OP to 32-bit and remove alignment on SMMU enable payload
- Refactor all defines
2024-03-14 09:21:06 +02:00
CTCaer
0100c11757 nyx: info: show unknown for relevant eMMC vendors 2024-03-13 02:02:09 +02:00
CTCaer
9ba7c44b89 bdk: clock: use real source clock dividers
Use CLK_SRC_DIV macro in order to have the actual divider showing.
2024-03-13 02:01:01 +02:00
CTCaer
cdf0f30b17 hekate/nyx: smmu refactor 2024-03-13 01:56:31 +02:00
CTCaer
9a520d63a6 bdk: smmu: refactor driver and allow other asid 2024-03-13 01:54:46 +02:00
CTCaer
20e661fc01 bdk: refactor flow control defines 2024-03-13 01:50:45 +02:00
CTCaer
e341cf39f2 hekate/nyx: apply ccplex changes
HOS procedure can now launch secmon from coldboot again when HOS is 6.2.0.
And update L4T for the function signature change.
2024-03-13 01:49:31 +02:00
CTCaer
3a4fa12f42 bdk: smmu: powergate ccplex after enabling smmu 2024-03-13 01:44:58 +02:00
CTCaer
fb31cb2926 bdk: ccplex: add no rst vector lock & powergating
Allow not locking the reset vectors and launch a new payload after powergating ccplex.
2024-03-13 01:37:52 +02:00
CTCaer
82925845e3 hekate/nyx: utilize existing block size defines 2024-03-12 15:53:05 +02:00
CTCaer
f126486266 bdk: sdmmc: utilize block size defines 2024-03-12 15:47:14 +02:00
CTCaer
25b7ffecd1 bdk: fatfs: always align malloc to lba 2024-03-12 15:43:44 +02:00
CTCaer
7d1600b85c bdk: consolidate ffsystem into bdk 2024-03-12 15:16:18 +02:00
CTCaer
b1e6661a7a nyx: get rtc adjustments via driver 2024-03-12 15:11:32 +02:00
CTCaer
83ac40c4b9 bdk: rtc: handle offset adjustment in-place 2024-03-12 15:08:55 +02:00
CTCaer
29d1e4a809 Bump hekate to v6.1.0 and Nyx to v1.6.0 2024-02-22 11:45:19 +02:00
CTCaer
2ff2a5df2f nyx: add error code info on lite gamepad dumping 2024-02-22 11:44:43 +02:00
CTCaer
4131ff12d7 bdk: sdram: adjust sdmmc1 la for l4t 2024-02-21 10:50:15 +02:00
CTCaer
5f8814311e nyx: info: add panel clone info 2024-02-21 10:42:28 +02:00
CTCaer
9ea847578e bdk: display: add another oem clone 2024-02-21 10:40:46 +02:00
Thomas Makin
f37ae083ae nyx: add android dynamic partition support
Will be used in Android >=13 for larger capacity and future-proofing.
New full system size: 6 GiB.

Partitions:
- boot
- recovery
- dtb
- misc
- cache
- super
- userdata
2024-02-16 17:17:12 +02:00
CTCaer
feb5b11f66 minerva: do not reread mrr for channel b
Just in case the mrr fifo is not empty.
2024-02-16 16:34:30 +02:00
CTCaer
e96e74c72a nyx: finer control of fan when temp is high 2024-02-16 16:07:27 +02:00
CTCaer
6e6f5f8eed hekate: reduce binary size
By using the same message everywhere.
2024-02-16 16:05:42 +02:00
CTCaer
35c36908a1 hekate/nyx: change fs/clock year to 2024 2024-02-16 16:03:54 +02:00
CTCaer
6d69ef3cf6 bdk: sprintf: allow padding > 9 2024-02-16 16:01:54 +02:00
CTCaer
abeafb9a67 l4t: allow exFAT as boot drive
Allow exFAT support of boot partition.
For newer bl33 (U-Boot >= 2024-NX02).
Old ones will just fail to load the boot script in such cases.
2024-02-16 15:59:30 +02:00
CTCaer
be3297ae1f l4t: raise T210 vdd2 limit to 1237.5mV 2024-02-16 15:57:22 +02:00
CTCaer
f05563579e bdk: max77620: raise sd1 max voltage
For T210.
2024-02-16 15:55:40 +02:00
CTCaer
644747230c bdk: dram: add FPGA code for 3rd gen micron 2024-02-16 15:54:22 +02:00
CTCaer
05f4c42a2d l4t: add custom options
That's a special flag config that controls ARC.
2024-02-16 15:53:04 +02:00
CTCaer
1f30b8deb7 bdk: minerva: add custom option in table 2024-02-16 15:51:02 +02:00
CTCaer
6c518435ec nyx: add info about 3rd gen micron lpddr4x 2024-02-14 02:18:01 +02:00
CTCaer
25e48472c8 nyx: add info about oem 5.5" panel 2024-02-14 02:17:45 +02:00
CTCaer
bfc6069b2d bdk: display: add OEM panel id 2024-02-14 00:08:06 +02:00
CTCaer
38a792e564 nyx: add penel rev and change some labels 2024-02-12 04:14:14 +02:00
CTCaer
8c5fdf52d4 nyx: correct dram info
Parse per module info on channel A, rank 0.
It was channel info on chip 0, rank0 before.
2024-02-12 04:13:39 +02:00
CTCaer
4576ed81ef sdram: acquire per chip mrr info 2024-02-12 04:08:39 +02:00
CTCaer
e9d2bdb124 l4t: remove more redundant carveout cfg 2024-01-07 12:40:28 +02:00
CTCaer
b37430dc1d bdk: update copyright year 2024-01-07 12:38:10 +02:00
CTCaer
75543875e2 bdk: mc: remove some redundant carveout cfg 2024-01-07 12:33:29 +02:00
CTCaer
cc50ed2051 l4t: remove redundant wpr cfg
It's now done in dram cfg.
2024-01-06 22:09:18 +02:00
CTCaer
d1bae553ec nyx: info: use the updated define for micron wtc 2024-01-06 22:06:21 +02:00
CTCaer
30c320d6e7 bdk: sdram: update all ram info comments 2024-01-06 22:05:24 +02:00
CTCaer
eff27d92f2 bdk: sdram: update default wpr overrides
Since it's only used in L4T set them to the correct latest reg tool values.

HOS overrides them anyway.
2024-01-06 22:03:54 +02:00
CTCaer
3874840d77 bdk: sdram: update cfg for 8GB erista 2024-01-06 21:59:18 +02:00
CTCaer
74e252aaf2 bdk: sdram: update latest reg tool vpr overrides
Set them to default config and remove them from patching.
2024-01-06 21:58:51 +02:00
CTCaer
c7333e710c bdk: strtol: support unsigned 32bit hex
If base is 16 and input is not negative allow unsigned 32bit parsing.

This allows parsing numbers of up to 4294967295 in that case.
2024-01-06 21:55:21 +02:00
CTCaer
dab5eb9aa0 bdk: sprintf: do not accept null chars
Skip NULL chars on putc since they break the resulted string.
2024-01-06 21:52:48 +02:00
CTCaer
92093ff08e bdk: se: deduplicate sha hash extraction 2023-12-27 21:07:52 +02:00
CTCaer
2cc6cd45d9 bdk: dram: small refactor 2023-12-27 21:06:09 +02:00
CTCaer
a6ec41744b bdk: sdram: refactor patching offsets 2023-12-27 21:04:04 +02:00
CTCaer
bb6e4deb4c bdk: remove unused lp0 cfg from bdk 2023-12-27 21:02:33 +02:00
CTCaer
1522f1ee92 nyx: info: add max bus speed info for sd 2023-12-27 15:02:00 +02:00
CTCaer
41d3565353 bdk: sdmmc: deduplicate function modes get
And parse the whole info
2023-12-27 15:01:20 +02:00
CTCaer
e23d469f06 nyx: revamp jc/sio cal info dumping
Hoag:
- Add stick types
- Add imu type

All the rest:
- Add imu calibration info
- Add BT mac
2023-12-25 04:17:59 +02:00
CTCaer
bd1733c4fa minerva: use min 2 divm
Adhere to software based imposed limits for T210.
2023-12-25 04:11:55 +02:00
CTCaer
db214f2865 l4t: correct debug print 2023-12-25 04:09:46 +02:00
CTCaer
b584a3f53a bdk: add several defines 2023-12-25 04:08:34 +02:00
CTCaer
7f98fb736a bdk: hwinit: reorder sdmmc1 reg disable 2023-12-25 04:07:26 +02:00
CTCaer
87c50732c0 bdk: fuse: simplify idle wait 2023-12-25 03:47:26 +02:00
CTCaer
504659a39b bdk: actmon: switch to averaged sampling 2023-12-25 03:46:05 +02:00
CTCaer
e47a819948 bdk: se: add more useful functions
- aes cmac 128bit
- aes hashing
- option to clear updated aes iv
2023-12-25 03:44:52 +02:00
CTCaer
39abeb9a28 nyx: improve fuses info
Correct the Chip ID Revision and also add actual (derived) iddq values.
2023-12-25 03:33:37 +02:00
CTCaer
80a32304cb nyx: rename 3rd gen hynix ram chips 2023-12-25 03:21:17 +02:00
CTCaer
913cdee8e8 bdk: sdram: rename 3rd gen t210b01 hynix ram
Confirmed to be a Hynix H54G46CYRBX267 and not a H9HCNNNBKMMLXR-NEI
2023-12-25 03:02:11 +02:00
CTCaer
eff55ff378 bdk: touch: rename samsung touch panel
BH2109 is the board model and not the touch panel.
2023-12-25 02:41:42 +02:00
CTCaer
09dfcfc57d bdk: display: deduplicate interrupt code 2023-12-25 02:40:38 +02:00
CTCaer
239c48c790 bdk: usb: hid: improve stick calibration
Wait a bit before calibrating stick centers, in order to avoid bad values.
2023-12-25 02:37:40 +02:00
CTCaer
2e1a773a08 nyx: relax joycon calibration init
Wait a bit before actually doing stick calibration in order to avoid bad values.
2023-12-25 02:36:27 +02:00
CTCaer
d1ee0e35fd hos: pkg2: fix validation check for nogc 17.0.0 2023-10-13 07:58:56 +03:00
CTCaer
226b30b57c Bump hekate to v6.0.7 and Nyx to v1.5.6 2023-10-12 09:25:14 +03:00
CTCaer
7fab13b76d hos: correct meso version masking
And also use the version instead to decide for relative INI1 base setting.
That's because MSS0 and MSS1 come with prepopulated INI1 base.
2023-10-12 09:25:06 +03:00
CTCaer
d3d3768c8f hos: correct max KB 2023-10-12 08:07:46 +03:00
CTCaer
7040f1ada2 l4t: allow setting dram voltage even if no OC
Mostly for allowing undervolting.
2023-10-12 07:44:00 +03:00
CTCaer
697bde8667 hos: 17.0.0 support 2023-10-12 07:41:12 +03:00
CTCaer
03f11370c7 hos: allow reusage of embedded INI1 region 2023-10-12 07:36:00 +03:00
CTCaer
533fb08a1c nyx: info: K4U6E3S4AB-MGCL is now validated 2023-10-12 07:28:28 +03:00
CTCaer
c828539544 hos: pkg2: rename ini1 value offset
And simplify the logic a bit.
2023-10-12 07:26:55 +03:00
CTCaer
d1be18821d hos: reduce pkg1 id to 8 chars to save space 2023-10-12 07:16:23 +03:00
CTCaer
613fdf621d hos: rename KB defines
From KB_FIRMWARE_VERSION to HOS_KB_VERSION
2023-10-12 07:11:22 +03:00
CTCaer
5b13e81141 Adjust about-screens copyright year 2023-10-12 07:01:28 +03:00
CTCaer
ce137852b7 bdk: change some defines and comments 2023-10-12 06:59:15 +03:00
CTCaer
e84367e302 nyx: swap and fix config save text 2023-08-23 00:10:10 +03:00
CTCaer
e5a22230b1 Bump hekate to v6.0.6 and Nyx to v1.5.5 2023-08-22 16:56:59 +03:00
CTCaer
ce42e27f45 bdk: minerva: do not handle oc freq
Arachne already handles it.
2023-08-22 16:44:41 +03:00
CTCaer
01a8f30925 nyx: add contact me for unknown ram chips 2023-08-22 16:44:03 +03:00
CTCaer
d73a3fdd7c bdk: sdram: name 1a micron ram chips
Again, as with 3rd gen samsung and hynix, that's an educated guess.
2023-08-22 14:44:27 +03:00
CTCaer
fdf0dcc636 bdk: joycon: add info about sio imu report 2023-08-22 14:36:23 +03:00
CTCaer
976a02f8bc nyx: clock: fix year off-by-one 2023-08-07 21:12:18 +03:00
CTCaer
187b6d843e nyx: emummc: allow migrating emummc backup
Now if an eMMC backup is not found, emuMMC backup will be used.
2023-08-07 21:11:17 +03:00
CTCaer
6de29094fe nyx: gfx: add column control
gfx_getpos/setpos can now get/set column offset.
setpos column can be fully custom. Otherwise GFX_COL_KEEP or GFX_COL_AUTO (2 columns) can be used.

Additionally, always restore column when printing debug info in log screen.
2023-08-07 21:09:37 +03:00
CTCaer
f2bdc3f47c bdk: i2c: fix stack buffer overflow 2023-08-07 21:02:20 +03:00
CTCaer
09b1efe2a4 nyx: info: use updated defines 2023-07-31 17:09:04 +03:00
CTCaer
bb0a1fd0a2 minerva: add freqs up to 2366 MHz 2023-07-31 17:05:09 +03:00
CTCaer
1cc97ebc51 bdk: update various comments 2023-07-31 17:03:15 +03:00
CTCaer
1e28320e5a bdk: t210: add more mmio addresses
And simplify relevant drivers that hardcoded them.
2023-07-31 16:59:15 +03:00
CTCaer
0fe17cfb41 l4t: add latest api version info 2023-07-28 15:42:16 +03:00
CTCaer
91393700ff nyx: use restore/emummc folder for restoring
In order to avoid mistakes, emuMMC can now only be restored from `backup/{emmc_sn}/restore/emummc`.
2023-07-28 04:07:43 +03:00
CTCaer
cb964fe5d2 l4t: allow ram undervolting 2023-07-28 04:04:03 +03:00
CTCaer
010b08d4c7 l4t: t210b01: set real dram rate by default
Since Arachne Register Cell (ARC) is now final and stable,
automatically set rated DRAM frequency for T210B01 by default.
1866 MHz for old ones and 2133 MHz for newer ones.

Setting anything from 1600000 and lower will disable that.
2023-07-28 04:03:01 +03:00
CTCaer
b5fcdad33f nyx: info: improve ram channel/rank detection 2023-07-28 03:40:32 +03:00
CTCaer
6061bb5213 nyx: info: add public key info
And remove LOT Code 1 since it's not used.
2023-07-28 03:38:40 +03:00
CTCaer
221614212a nyx: info: add more cal0 info
Touch vendor, IMU type/mount and analog stick types.
2023-07-28 03:36:10 +03:00
CTCaer
5b94e8cf8a nyx: info: use fuel gauge reg dump function 2023-07-28 03:35:08 +03:00
CTCaer
f291a5cfa7 bdk: max17050: add reg dumping 2023-07-28 03:34:11 +03:00
CTCaer
7e397b3403 nyx: options: change autorcm icon 2023-07-28 03:33:09 +03:00
CTCaer
f35c5b0596 nyx: fix first time config save unmounting
SD card should not get unmounted on the first boot without hekate_ipl.ini.
Move sd card mounting management outside of it.
2023-07-28 03:32:33 +03:00
CTCaer
b142ca0f33 nyx: info: use new fuse names 2023-07-28 03:29:24 +03:00
CTCaer
21da947c02 nyx: hos: deduplicate cal0 dumping 2023-07-28 03:28:21 +03:00
CTCaer
317abb2f4e hekate: add bootwait for each entry
Allow overriding global bootwait with the one from boot entry.
2023-07-28 03:23:03 +03:00
CTCaer
d3567736c8 hos: allow overriding uCID 2023-07-28 03:06:20 +03:00
CTCaer
9187fa7a8c bdk: fuse: add all t210b01 fuses
And use B01 to distinguish the ones only on that SoC.
2023-07-22 07:10:12 +03:00
CTCaer
b9bc35a22e bdk: dram: correct old comments 2023-07-21 18:39:46 +03:00
CTCaer
6e954f5cdf nyx: provide the raw calib for Lite gamepad
Let L4T driver manage it.
2023-06-11 13:29:04 +03:00
CTCaer
d7ad9b874b bdk: use the typedefs on jc calib 2023-06-11 13:27:48 +03:00
CTCaer
820e6d5a6e bdk: update cal0 struct 2023-06-10 23:48:45 +03:00
CTCaer
0215d16405 Bump hekate to v6.0.4 and Nyx to v1.5.4 2023-06-09 11:08:13 +03:00
CTCaer
c0c0e34ef0 nyx: info: update dram info 2023-06-09 11:04:31 +03:00
CTCaer
581ac8ec33 nyx: info: always report errors for eMMC
Even if init fails.
2023-06-09 11:04:07 +03:00
CTCaer
26bf148188 nyx: add Lite gamepad calibration data dumping
Adds calibration data dumping via the Joycon BT pairing dumping function.

Calibration for everything about Sio is dumped. So Sticks and IMU.
2023-06-09 11:03:29 +03:00
CTCaer
dc8f6beb8d nyx: info: make cal0 dumping public 2023-06-09 11:01:08 +03:00
CTCaer
25b181bf36 nyx: add missing newlines
Change line since the text does not fit like that in these places, effectively breaking text color.
2023-06-09 10:59:03 +03:00
CTCaer
66e5e128f6 l4t: adjust revision amidst the new changes
Also add helpful message if files are missing.
2023-06-09 10:56:39 +03:00
CTCaer
84822726cb l4t: add fine tuned voltage support for DRAM
1000-1175mV for T210 VDDIO/Q via `ram_oc_vdd2`
1000-1175mV for T210B01 VDDIO and 600-650mV for VDDQ via `ram_oc_vdd2` and `ram_oc_vddq`.
2023-06-09 10:55:32 +03:00
CTCaer
b6e1e0d412 l4t: add bpmp-fw support for T210 2023-06-09 10:53:03 +03:00
CTCaer
496737248c l4t: there was never a need to normalize dram freq 2023-06-09 10:51:31 +03:00
CTCaer
4f52e1f24a l4t: refactor bpmp-fw defines for T210B01 2023-06-09 10:50:29 +03:00
CTCaer
3f9c7a7da6 hos: prep boot freq in minerva for cfw also 2023-06-09 10:41:53 +03:00
CTCaer
93ed4d0899 bdk: emc: add temp and feature reporting defines 2023-06-09 10:38:24 +03:00
CTCaer
01afd2de56 bdk: sdmmc: properly report comp pad status
The reporting of the resistor being shorted or open was swapped. Fix that so it's immediately known what's the issue.
2023-06-09 10:37:47 +03:00
CTCaer
d621d96af1 bdk: sdmmc: refactor comments 2023-06-09 10:36:29 +03:00
CTCaer
b674624ad0 bdk: timer: add instruction sleep
usage:
`isleep(ILOOP(instructions))`

Each loop is 3 cycles, or approximately 7.35ns on 408MHz CPU clock.
2023-06-09 10:33:11 +03:00
CTCaer
191a0533d9 bdk: clock: add more known pto ids 2023-06-09 10:29:47 +03:00
CTCaer
8502731fbd bdk: tsec: refactor some register names 2023-06-09 10:28:28 +03:00
CTCaer
18f3a1b70c bdk: max77620: reduce max DRAM VDDIO/Q
Reduce allowed VDDIO/VDDQfor T210B01 and VDDIO for T210B01.
2023-06-09 10:24:55 +03:00
CTCaer
418f029d11 lib: minerva: add 1966 and 2033 MHz in div table 2023-06-08 05:31:15 +03:00
CTCaer
066efda4cd lib: minerva: normalize output frequency
Allow frequencies that are not exact to receive proper dividers from the supported ones from table.
2023-06-08 04:56:14 +03:00
CTCaer
d8d15bde44 lib: minerva: add Samsung 8GB support
And remove frequencies smaller than deep sleep frequency from the tables.
2023-06-08 04:50:59 +03:00
CTCaer
9d8ebc7e38 lib: minerva: refactor table
Remove _idx used initially for RE at last.
2023-06-08 04:49:16 +03:00
CTCaer
c2ee6be2f5 bdk: sdram: add Samsung 8GB RAM support for T210
And remove Copper support completely.
2023-06-08 04:16:51 +03:00
CTCaer
73a133556d bdk: sdram: correct sku related info
Validated so rename accordingly.
2023-06-08 02:57:30 +03:00
CTCaer
7d3663616e bdk: sdram: name 2 of the new ram chips
Not actually validated, but educated guess, since all previous one were correct in the end.
New Micron still unknown, can be guessed but model doesn't exist in any public list.
2023-06-08 02:52:03 +03:00
CTCaer
e76aebabba bdk: mem: minerva: check table size in clock check
Don't hardcode table size to 10.
2023-06-08 02:45:34 +03:00
CTCaer
bc0eea11f3 bdk: joycon: add calibration struct 2023-06-08 02:44:35 +03:00
CTCaer
937ab52d14 Bump hekate to v6.0.4 2023-05-09 11:15:34 +03:00
CTCaer
e896d388ab hos: 16.0.3 support 2023-05-09 11:15:11 +03:00
CTCaer
ded959c449 Bump hekate to v6.0.3 and Nyx to v1.5.3 2023-04-06 17:38:36 +03:00
CTCaer
a7fd83c793 nyx: correct build flag 2023-04-06 17:36:22 +03:00
CTCaer
dd380d4d47 l4t: increase bw priority to SDMMC1 for L4T 2023-04-06 17:34:26 +03:00
CTCaer
795b4ad26e bdk: sdmmc: increase bw priority to SDMMC1 for L4T 2023-04-06 17:30:01 +03:00
CTCaer
bb10b8aea3 bdk: sdmmc: small refactor 2023-04-06 10:19:53 +03:00
CTCaer
811fa4c88b bdk: sdmmc: add SD registers debug printing
Can be enabled with `SDMMC_DEBUG_PRINT_SD_REGS`
2023-04-06 10:13:35 +03:00
CTCaer
22462e4bf3 nyx: info: optimize random benchmarking
Do not allow SD/eMMC to breath during random reads benchmarking. So only render progress at 15fps.
2023-03-31 09:24:55 +03:00
CTCaer
ca0263fa8c hekate: info: fully deinit/unmount sd card 2023-03-31 09:17:51 +03:00
CTCaer
b1112e0949 hos: set proper exo hos version for 12.1.0
Even if 12.0.0 one is api compatible, there was a master key change on 12.1.0.
2023-03-31 09:17:13 +03:00
CTCaer
3c3fcb29f9 hekate: clear rtc interrupt and stop alarm
Stopping rtc alarm is now done in the function that actually checks it, in order to avoid power offs from HOS if it's fired and user wants to continue booting.

Additionally, clear the interrupt which is the actual thing that is checked by HOS.
2023-03-31 09:15:56 +03:00
CTCaer
8528e6a08a bdk: util: do not edit rtc alarm in power function 2023-03-31 09:12:58 +03:00
CTCaer
27ae312227 bdk: minor naming edits 2023-03-31 09:11:55 +03:00
CTCaer
50811aacfa bdk: touch: reorder power on
So touch IC reset can be properly done on a fast power cycle.
2023-03-31 09:08:20 +03:00
CTCaer
f4bf48e76a bdk: sdmmc: add driver type set support 2023-03-31 09:04:10 +03:00
CTCaer
d258c82d52 bdk: sdmmc: add UHS DDR200 support
The bdk flag BDK_SDMMC_UHS_DDR200_SUPPORT can be used to enable it.

SD Card DDR200 (DDR208) support

Proper procedure:
1. Check that Vendor Specific Command System is supported.
   Used as Enable DDR200 Bus.
2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6.
   Access Mode group is left to default 0 (SDR12).
3. Setup clock to 200 or 208 MHz.
4. Set host to DDR bus mode that supports such high clocks.
   Some hosts have special mode, others use DDR50 and others HS400.
5. Execute Tuning.

The true validation that this value in Group 2 activates it, is that DDR50 bus
and clocks/timings work fully after that point.

On Tegra X1, that can be done with DDR50 host mode.
Tuning though can't be done automatically on any DDR mode.
So it needs to be done manually and selected tap will be applied from the
biggest sampling window.

Finally, all that simply works, because the marketing materials for DDR200 are
basically overstatements to sell the feature. DDR200 is simply SDR104 in DDR mode,
so sampling on rising and falling edge and with variable output data window.
It can be supported by any host that is fast enough to support DDR at 200/208MHz
and can do hw/sw tuning for finding the proper sampling window in that mode.

Using a SDMMC controller on DDR200 mode at 400MHz, has latency allowance implications. The MC/EMC must be clocked enough to be able to serve the requests in time (512B in 1.28 ns).
2023-03-31 08:54:13 +03:00
CTCaer
7f32c6d211 bdk: sd: better removal detection handling 2023-03-31 08:31:20 +03:00
CTCaer
2f7e841b50 bdk: sdmmc: move sdr12 setup for better readability 2023-03-31 08:29:20 +03:00
CTCaer
29e32f09fb bdk: sdmmc: properly identify sdmmc1 clk config
Remove schmitt trigger config from clock pin on sdmmc1 for identifying previous pinmuxing state.
2023-03-31 08:27:48 +03:00
CTCaer
b123571c56 bdk: sdmmc: only allow power raise if SDR50 and up
As per spec.
2023-03-31 08:26:19 +03:00
CTCaer
b7164a629f bdk: sdmmc: allow max power limit to be set
Even if it defaults to 1.44W.
Some cards' firmware maybe be bugged.

The 3.3V regulator on all SKUs allow more than 800mA current anyway.
2023-03-31 08:24:52 +03:00
CTCaer
25be98b7e3 bdk: sdmmc: add UHS DDR50 support
But disable it by default in the auto selection.
2023-03-31 08:23:10 +03:00
CTCaer
76a5facbc3 bdk: clock: rename clock_t to clk_rst_t
To avoid redefines when standard math header is used.
2023-03-31 08:18:45 +03:00
CTCaer
502fc1ed50 bdk: sdmmc: rename ddr100 to the actual HS100 name 2023-03-31 08:15:40 +03:00
CTCaer
5e134ed54b bdk: sdmmc: refactor defines 2023-03-31 08:00:14 +03:00
CTCaer
4cfe5f241e bdk: sdmmc: remove eMMC OC
Additionally, the flag BDK_SDMMC_OC_AND_EXTRA_PRINT is now just BDK_SDMMC_EXTRA_PRINT
2023-03-31 07:55:17 +03:00
CTCaer
9a222e0e49 bdk: sdmmc: rename divisor param to card clock 2023-03-31 07:53:46 +03:00
CTCaer
298893f404 bdk: sdmmc: remove powersave arg from sdmmc init 2023-03-31 07:51:43 +03:00
CTCaer
1ce5bb10f8 bdk: sdmmc: refactor debug prints 2023-03-31 07:49:26 +03:00
CTCaer
107fbd1d24 bdk: gpio: add debounce set function
The debounce time is not per pin but per bank. So software should manage proper time for sibling pins
2023-03-31 07:43:16 +03:00
CTCaer
1edb6583ac bdk: gpio: reorder gpio config
Since there are some bootloaders that mess with the states of some power gpios, reorder gpio configuration for input/output in order to prevent power pin glitches.
2023-03-31 07:41:50 +03:00
CTCaer
5bdf323e5c Bump hekate to v6.0.2 and Nyx to v1.5.2 2023-02-23 01:25:19 +02:00
CTCaer
d286ee4e9d bdk: sd: only clear inserted when requested
Also rename var to further explain its usage
2023-02-23 01:25:05 +02:00
CTCaer
17cdd5af0d bdk: hwdeinit: restore order of bpmp clock set
Restore order of bpmp clock scale down in deinit, in order to decrease pressure on clock deinits.
2023-02-22 14:48:43 +02:00
CTCaer
26fa363ca4 nyx: reset SD speed to SDR104 if init fails 2023-02-22 13:46:50 +02:00
CTCaer
2e8bfc1f56 hos: add 16.0.0 support 2023-02-22 13:45:46 +02:00
CTCaer
07dafe8185 nyx: fix pkg1 dump/split
Broken since v5.3.1.
2023-02-22 13:24:49 +02:00
CTCaer
7f92f65c26 fatfs/nyx: set minimum year to 2023 2023-02-22 13:23:40 +02:00
CTCaer
55e01ca735 bdk: sd: improve init error handling
- Management of sd init done is now on sd init retry function
 Also manages inserted, since it can set the sd init done to false if failed
- Init will now always check if SD is also initialized, since it doesn't manage it anymore. Because of that, mounting is no longer forced, but checked first.
- Unmount/End will now always set the sd as unmounted, since no data residue is expected after the fact

The above will improve handling of faulty SD cards or faulty SD readers.
2023-02-22 13:19:12 +02:00
CTCaer
a44a4881d4 hekate/nyx: stylistic and copyright updates 2023-02-22 13:04:42 +02:00
CTCaer
c279fa2521 bdk: max77621: ckkadv is basically an enum 2023-02-22 13:00:36 +02:00
CTCaer
0f6f5f06c7 nyx: improve FS error handling on init
In case of FS corruption or SD issues, do the following:
- Try 2 times to init SD.
- Try 2 times to load resources
- Fatal if fail with an error message.
2023-02-12 00:17:24 +02:00
CTCaer
8600174d66 nyx: info: improve sd power limits info 2023-02-12 00:00:26 +02:00
CTCaer
a6d7fa7fe1 nyx: disable reboot to OFW button if autorcm 2023-02-11 23:59:30 +02:00
CTCaer
c9405680f2 nyx: update bpmp clock manage
- Test max clock on T210B01 also
- Add 3rd mode with lower clock. Manually applied only.
- Test max clock for 10s instead of 5s
2023-02-11 23:56:16 +02:00
CTCaer
64dac28073 hekate: allow accessing launch options without ini 2023-02-11 23:52:43 +02:00
CTCaer
5193416658 hekate/nyx: stylistic corrections 2023-02-11 23:51:43 +02:00
CTCaer
9a98c1afb9 bdk: stylistic corrections
And update copyrights
2023-02-11 23:46:38 +02:00
CTCaer
361aaf8629 l4t: disable AHB aperture and pllc war
We don't need AHB aperture after that point and new deinit fixes the pllc init issue on L4T boot.
2023-02-11 23:25:22 +02:00
CTCaer
080e3e2aa7 hos: disable AHB aperture before secmon launch
Seems that old secmon were missing that and it may cause bad behavior on boot.

Only affects stock old secmon versions.
2023-02-11 23:22:53 +02:00
CTCaer
72abe60a3b bdk: hw init: remove support for broken hwinits
It's 2023 already.
2023-02-11 23:19:56 +02:00
CTCaer
ee682fdf24 bdk: l4t: minerva: don't rely on UB 2023-02-11 23:17:27 +02:00
CTCaer
42859a2373 bdk: usb: ums: print errors when sdmmc init fails 2023-02-11 23:16:37 +02:00
CTCaer
22bdd0e0ff bdk: sdmmc: remove unused power limits
Also name some magic numbers
2023-02-11 23:15:28 +02:00
CTCaer
114abba815 bdk: hw init: do not touch audio clocks on t210b01 2023-02-11 23:13:41 +02:00
CTCaer
ec8c04db8a bdk: bpmp: add 563MHz clock for worst binnings 2023-02-11 23:12:14 +02:00
CTCaer
4d7eb6a647 bdk: clock: improve pllc deinit 2023-02-11 23:11:24 +02:00
CTCaer
fd3cf1b7f8 bdk: reg-5v: remove X3 pin
X3 is vbus enable on mariko.
2023-02-11 23:10:43 +02:00
CTCaer
47f0734ba0 bdk: display: add more oled color mode info 2023-02-11 23:09:38 +02:00
CTCaer
5bb9a244ea bdk: utilize new gpio functions 2023-02-11 23:08:32 +02:00
CTCaer
05b5e4f297 bdk: gpio: add simple gpio direction functions 2023-02-11 22:55:22 +02:00
CTCaer
4e15e034b8 bdk: sdram: remove (lp)ddr2/3 support 2023-02-11 22:44:31 +02:00
CTCaer
ee3fc499cd bdk: bm92t36: add sanity checks
If bm92t i2c comms are broken, it can hang hekate. So sanitize buffer and max profile print supported.
2023-02-11 22:40:47 +02:00
CTCaer
f9e99212fc Bump hekate to v6.0.1 and Nyx to v1.5.1 2022-12-22 12:39:51 +02:00
CTCaer
1666daf447 l4t: fix several issues
- Fixed an issue where cached data would not be flushed after setting the fw carveout. Now they are flushed before setting it.
- Fixed and off-by-one bug and setting incorrect number of mtc entries.
2022-12-22 12:37:56 +02:00
CTCaer
cfbfe403c6 bdk: di: wait 8ms before setting window for vic 2022-12-22 12:32:05 +02:00
CTCaer
47784faab2 Bump hekate to v6.0.0 and Nyx to v1.5.0 2022-12-20 17:01:42 +02:00
CTCaer
a2a302b9d5 l4t: Add L4T loader for T210 and T210B01 2022-12-20 17:00:33 +02:00
CTCaer
50dd458cfd bdk: ums: use emmc_end instead of sdmmc_storage_end 2022-12-20 16:55:16 +02:00
CTCaer
2218ae228f nyx: changes to partition manager 2022-12-20 16:50:04 +02:00
CTCaer
20915dd661 hekate: blink 3 times on OLED for auto hos pwr off
The OLED panel does not allow for variable PWM fade without sending DCS commands, so blink instead.
2022-12-19 06:03:53 +02:00
CTCaer
0ba9b49074 nyx: add nobox and hue combo for launch
`_hue_nobox` is now supported which colorizes the icon and also removes the border.
2022-12-19 05:53:31 +02:00
CTCaer
1582ef3a29 nyx: add sd card power info and more vendors 2022-12-19 05:50:08 +02:00
CTCaer
0a367b114c nyx: add missing HOS info on 17 burnt fuses 2022-12-19 05:45:41 +02:00
CTCaer
f49aecad19 hekate: update to ini_check_special_section 2022-12-19 05:43:48 +02:00
CTCaer
0b1bb521d8 bdk: ini: add l4t key parsing 2022-12-19 05:38:03 +02:00
CTCaer
2e989c2338 hekate: increase battery enough limits 2022-12-19 05:35:45 +02:00
CTCaer
0e1eece04f bdk: hw-init: remove charger forced enable
Anything that doesn't manage it properly should fix itself.
(Like for example disabling charging on sleep or something. They should use the gpio equivalent.)
2022-12-19 05:35:04 +02:00
CTCaer
2119401b5c hekate: add T210B01 R2P 2022-12-19 05:31:35 +02:00
CTCaer
c9ab6352f6 bdk: rtc: add T210B01 R2P 2022-12-19 05:30:23 +02:00
CTCaer
09ca75dd8c bdk: max77812: exit if RAM reg and not 211 phase 2022-12-19 05:28:35 +02:00
CTCaer
157464753f nyx: add the new dram chips
Still no solid info, only vendor, so "contact me".
2022-12-19 05:26:35 +02:00
CTCaer
560f077196 bdk: sdram: rename new dram chips 2022-12-19 05:25:26 +02:00
CTCaer
4d823d5909 bdk: slight refactor 2022-12-19 05:22:55 +02:00
CTCaer
a1fde0d9b6 bdk: display: disable LCD DVDD on display deinit 2022-12-19 05:16:35 +02:00
CTCaer
d0b22bf374 bdk: manage host1x only in hw init 2022-12-19 05:14:39 +02:00
CTCaer
4da1d10553 nyx: Force 4MiB eMMC boot0/1 on backup/restore
Simplify ops on big eMMC replacements.
2022-12-19 05:09:37 +02:00
CTCaer
f16159542c hekate/nyx: slight refactor 2022-12-19 05:04:50 +02:00
CTCaer
6257d20db9 bdk: emmc: add emmc_set_partition
Additionally, add SDMMC index info to errors.
2022-12-19 04:53:50 +02:00
CTCaer
227fe9b7ea cfg: remove creation from hekate and move to Nyx
There's no reason for hekate to create the hekate config if missing, since Nyx is the sole manager of it.

So move the auto creation there to save binary space.
2022-12-19 04:41:21 +02:00
CTCaer
24795891ec loader: refactor 2022-12-19 04:31:54 +02:00
CTCaer
c86554e954 Cleanup for years unused code
Compiler was also getting confused and actually not removing the unused functions.
So that also saves binary space.
2022-12-19 04:27:38 +02:00
CTCaer
c0cc9c9f4f bdk: vic: ease stress to APB when enabling VIC clk 2022-10-13 00:16:08 +03:00
CTCaer
1bef259571 Bump hekate to v5.9.0 and Nyx to v1.4.0 2022-10-12 12:31:31 +03:00
CTCaer
fe0bd89c4c bdk: pmc: extend pmc scratch locker 2022-10-11 14:41:42 +03:00
CTCaer
f534d5e316 bdk: i2c: fix send packet mode 2022-10-11 14:40:58 +03:00
CTCaer
8d2fac60ea nyx: info: remove unused dram ids 2022-10-11 10:39:19 +03:00
CTCaer
2ea595e98d bdk: sdram: add new dram ids/configs
On T210B01 dram ids 7 and 16 got removed.
29 to 34 were added.

Additionally, remove all deprecated and unused dram id enums.
2022-10-11 10:38:43 +03:00
CTCaer
7e7e86b713 hos: add HOS 15.0.0 support 2022-10-11 10:29:41 +03:00
CTCaer
a6d0bf54cd hos: improve warmboot config
Add more checks, simplify it and allow it to be called on non-HOS code.
2022-10-11 08:53:46 +03:00
CTCaer
e455fe043f nyx: add black theme option
New experimental black theme.
2022-10-11 08:32:32 +03:00
CTCaer
1a8075669d bdk: lvgl: allow theme to take a bg color value 2022-10-11 08:22:48 +03:00
CTCaer
31c8292f23 config: set default auto hos power off to enabled for T210B01
For new users, set Auto HOS Power Off feature to enabled if T210B01 based SoC.
2022-10-11 07:51:45 +03:00
CTCaer
414721a1ff bootloader: Add animated ticker for VOL- wait
Now an animated line is drawn while bootlogo wait is active.
This will remind user to press VOL- if needed and also give visible feedback.

A new config key was added to disable it for custom bootlogos. Set `noticker=1` in `[config]` section.
It always show for default hekate one.

For now now there's no GUI option for it.
2022-10-11 07:49:17 +03:00
CTCaer
9c1238f99d Update Warnings flags in makefiles 2022-10-11 07:25:21 +03:00
CTCaer
c0b16320cc bootloader: improve launch code
- Fix error not showing if payload is missing or can't be read
- Move errors to their callee function to save binary space
- Refactor various parameters and comments
- Reduce size on some errors
- Do not read HOS specific config in case of payload launch
- Remove unneeded code
2022-10-11 07:21:41 +03:00
CTCaer
e7866387cd bootloader: remove volatile from reloc
To save binary space, as it's not needed.
2022-10-11 07:00:24 +03:00
CTCaer
6739f03893 bootloader: remove rtc stop alarm from auto hos powerr off
It's done in power_set_state anyway.
2022-10-11 06:59:39 +03:00
CTCaer
0a9c71d5d6 bootloader: simplify emmcsn_path_impl 2022-10-11 06:58:22 +03:00
CTCaer
833f060c7b nyx: utilize VIC for hw rotation
It completely removes the waterfall-like slow rendering on T210B01 and speeds up even more rendering on T210.
2022-10-11 06:51:33 +03:00
CTCaer
9d889e2c3e bdk: Add driver for VIC
VIC is a HW engine that allows for frame/texture buffer manipulation.
2022-10-11 06:41:38 +03:00
CTCaer
efe6e2f206 nyx: also backup payload.bin if full not possible
Partition manager does a backup on the following if it can't do a full backup:
- bootloader (existed)
- Mariko Warmboot Storage (MWS) (existed)
- payload.bin  (newly added)
2022-10-11 06:36:06 +03:00
CTCaer
5cdee01c05 nyx: part manager: rename twrp to recovery
And add support for both twrp.img and recovery.img.
2022-10-11 06:31:24 +03:00
CTCaer
6337b06212 nyx: Rename Nyx Options to Nyx Settings
In order to not be confused with the hekate general Options.
2022-10-11 06:27:50 +03:00
CTCaer
f5fb0a1ee9 nyx: config: rename entries column var 2022-10-11 06:24:52 +03:00
CTCaer
7cac7fe095 nyx: info: warn for fuel gauge in init state
An icon and reason will be shown if design cap is 1000 mAh, which means that fuel gauge was reset and HOS not booted at least once.

A reason for the warning in battery voltage is now also given if low.
2022-10-11 06:20:19 +03:00
CTCaer
fefa7d9149 nyx: correct error message for emummc creation 2022-10-11 06:18:02 +03:00
CTCaer
bfad719fcd bdk: small refactor 2022-10-11 06:16:38 +03:00
CTCaer
4f2a6f16d3 nyx: fix use after free and a heap corruption
Fix use after free and a heap corruption on emummc config loading/freeing that could cause hangs when entering emummc window.
2022-10-11 04:37:17 +03:00
CTCaer
f41d6be8d4 nyx: do not allow padding buttons to be pressed
So closing the window from a miss-touch can be avoided.
2022-10-11 04:32:53 +03:00
CTCaer
5392971c2c hekate/nyx: utilize emmc_end 2022-10-11 04:19:29 +03:00
CTCaer
07695196cb bdk: emmc: utilize emmc_end 2022-10-11 04:12:04 +03:00
CTCaer
8bbe403e41 bdk: util: replace strtol/atoi w/ custom versions
To get rid of reentrancy baggage (which is not needed) and save binary space
2022-10-11 04:11:21 +03:00
CTCaer
d08fac5a08 bdk: xusb: improve clock deinit
Allows L4T to use XUSB on T210B01 after a UMS usage.
T210 somehow was fine.
2022-10-11 04:07:24 +03:00
CTCaer
197ce4c76f bdk: sdmmc: timing changes
- Correct HS102 naming to DDR100
- Fix clock for DDR50 (even if it's unused)
2022-10-11 04:05:12 +03:00
CTCaer
eaa25114ad bdk: lvgl: do not do unneeded invalidations
A bug was fixed that was causing full parent object invalidations when tapping into a window.

Now if the object is already on top the invalidation is skipped and the whole rerender/draw is skipped, saving valuable cpu time.
2022-10-11 04:00:41 +03:00
CTCaer
0b2c2aa564 bdk: regulator 5V: improve management per SKU 2022-10-11 03:57:17 +03:00
CTCaer
2aa251c44f bdk: max77812: uncomment RAM regulator 2022-10-11 03:53:17 +03:00
CTCaer
c52c11e7bc bdk: mem: improve emc MRR reading 2022-10-11 03:51:12 +03:00
CTCaer
ff5ee9758d bdk: joycon: refactor some structs and comments 2022-10-11 03:49:18 +03:00
CTCaer
a33663f759 nyx: Add info about Sharp LQ055T1SW10 panel 2022-10-11 03:47:05 +03:00
CTCaer
44b429d5cd bdk: display: Name panel 1040 to Sharp LQ055T1SW10 2022-10-11 03:45:49 +03:00
CTCaer
b891657fb6 bdk: tsec: fix regression on HOS 6.2.0 not booting
With the latest BDK changes on enabling always on AHB redirect with a compile time flag, TSEC fw boot was regressed because it needs it off.

Always disable redirect and if the flag is enabled, enable it on exit.
2022-07-11 22:28:09 +03:00
CTCaer
801ebd3543 bdk: xusb: fully clear device mode ctrl register on deinit 2022-07-11 22:13:13 +03:00
CTCaer
d259d6f6d6 bdk: watchdog: clear timer interrupt also in handling 2022-07-11 22:10:41 +03:00
CTCaer
70523e404f bdk: whitespace refactor 2022-07-11 22:10:11 +03:00
CTCaer
1499f958dd Bump hekate to v5.8.0 and Nyx to v1.3.0 2022-07-01 13:47:47 +03:00
CTCaer
b787053c2d bdk: joycon: fixup hori pads
For Hori game pads:
- Restore the no power down fix
- Revert RTS signal back to active high
2022-07-01 13:47:41 +03:00
CTCaer
fe7fd6370e hekate/nyx: push some missed changes 2022-07-01 11:33:43 +03:00
CTCaer
535ea95086 hekate/nyx: gfx: add text color defines
And reduce code size when using W/EPRINTF macros
2022-07-01 04:37:57 +03:00
CTCaer
eba6b285ec hekate: utilize watchdog to catch sd based hangs
Utilize watchdog when configuring LP0/Minerva.
A problematic SD card connector can cause corrupted reads to happen and thus cause hekate to hang on a black screen.

By using a watchdog there, such issues can be avoided and the user can get notified visually.
2022-06-29 12:19:19 +03:00
CTCaer
e921d8f51c bdk: update memory map with more used addresses 2022-06-29 12:13:04 +03:00
CTCaer
57c8fd1f8c bdk: fiq: watchdog handling
`BDK_WATCHDOG_FIQ_ENABLE` enables watchdog handling.
`BDK_RESTART_BL_ON_WDT` causes a reload of bootloader on FIQ

These 2 are useful when wanting to detect and handle hangs.
2022-06-29 12:12:03 +03:00
CTCaer
d38ddad873 bdk: display: correct night mode value 2022-06-27 10:27:18 +03:00
CTCaer
b0c0a86108 bdk: migrate timers/sleeps to timer driver 2022-06-27 10:22:19 +03:00
CTCaer
061e10152f bdk: timer: add timer/watchdog driver 2022-06-27 10:20:25 +03:00
CTCaer
b65b2d7f71 bdk: se: do not use heap for linked lists 2022-06-27 09:14:43 +03:00
CTCaer
3369dcd110 nyx: if no full backup, backup MWS folder also
When full backup is not possible, together with bootloader folder, also backup mariko warmboot storage if it exists.
2022-06-25 06:47:12 +03:00
CTCaer
677770bfee nyx: offer wipe if partitioning can backup files 2022-06-25 06:41:34 +03:00
CTCaer
50886382bf bdk: list: add LIST_FOREACH_INVERSE and LIST_FOREACH_ENTRY_INVERSE 2022-06-25 05:59:53 +03:00
CTCaer
2378bf2863 bdk: ini: simplify kv free 2022-06-25 05:56:11 +03:00
CTCaer
e5ddac5211 bdk: sdmmc: rename current limit to power limit 2022-06-25 05:53:04 +03:00
CTCaer
489e222aac bdk: sdmmc: expose csd/scr functions 2022-06-25 05:48:54 +03:00
CTCaer
16af97c79a uart: rename print to printf 2022-06-25 05:42:42 +03:00
CTCaer
bdb8f6d352 ccplex: name some flow control values 2022-06-25 05:42:19 +03:00
CTCaer
e2f6e925c4 nyx: info: show total size of fat partition 2022-06-19 12:39:02 +03:00
CTCaer
258a343e21 bdk: usb: support deconfiguration of endpoints
TODO: Signal that to userspace and manage it.
2022-06-14 18:48:21 +03:00
CTCaer
f6c9e636d1 bdk: usb: improve USB2/XUSB power down
TODO: add more power downs on XUSB stack
2022-06-14 18:46:46 +03:00
CTCaer
605f270f98 bdk: usb: fix a race condition in USB2 stack
When RAM is slow (no training), it's possible to have the stack failing to negotiate configuration successfully.

The race condition is caused by not flushing cache before sending a configuration packet reply.
Although, cache is write-through, this needs to happen.
2022-06-14 18:41:33 +03:00
CTCaer
3fa01a1975 hekate: fix a bug in low battery monitor
Do not try to deinit display if it's not enabled.

Can happen if LBM disables display to reserve power while charging and user presses both VOL buttons to exit the mode.
2022-06-04 22:03:47 +03:00
CTCaer
0e526bf9e8 nyx: tools: fix hybrid mbr changes
- MBR is now checked if it has GPT partition, in order to avoid revival of a dead but valid GPT
- MBR secret attributes can now be cleared even if there's no GPT
2022-05-27 04:44:42 +03:00
CTCaer
c77c741c07 bdk: sdmmc: correct lower speed mode checks
Both bus widths of 8 and 4 should be checked for HS200 support and host type support, instead of giving 8-bit bus width a free pass.
2022-05-26 03:04:27 +03:00
CTCaer
358896eb7d nyx: tools: inform user on erros in archive bit fixer 2022-05-21 14:24:43 +03:00
CTCaer
10205b17dd hekate: remove sd mount/unmout management for payload launch
Callers manage it anyway.
Fixes a case where missing the payload would result to Nyx not relaunching because sd was unmount.
2022-05-21 13:10:12 +03:00
CTCaer
75b7d91abf hekate: always init sublist on section creation
Even if there are no edge cases here
2022-05-21 13:08:46 +03:00
CTCaer
369df25cd3 nyx: fatfs: add failsafes for wrong mkfs usage 2022-05-19 15:17:54 +03:00
CTCaer
af22085172 nyx: move emuMMC backup folder to {emmc_sn}/emummc 2022-05-19 15:15:36 +03:00
CTCaer
38010ce65e nyx: utilize ini free and fix various memleaks
With the new changes the heap and heap node usage drops 95% on boot. Subsequent accesses to Launch/More config keep the counter the same.
2022-05-19 15:14:05 +03:00
CTCaer
8428ce1a2e hekate/nyx: gfx: changes to putn 2022-05-19 15:06:37 +03:00
CTCaer
bf00c79edb bdk: ini: add ini free
Additionally, fix a bug where a list could not be initialized if section type is comment or caption.
2022-05-19 15:03:00 +03:00
CTCaer
429074293a bdk: sprintf: no support for lower case hex and base that is not 10/16 2022-05-19 15:01:10 +03:00
CTCaer
2c768db542 bdk: heap: add nodes info 2022-05-19 14:53:02 +03:00
CTCaer
889317da58 bdk: sdmmc: add missing sd block size define 2022-05-16 13:34:36 +03:00
CTCaer
e09710e3eb bdk: fatfs: mkfs alignment changes
- Default data alignment is now 1MB **when it's not set**
- Default volume alignment is now based on data alignment and not hardcoded to 16MB.
- Change max allowed alignment to 64MB.

The above changes allow selecting alignments for volume and data between 1MB and 64MB.
(From the previous 1 to 16MB for data and 16MB for volume).
2022-05-16 13:33:38 +03:00
CTCaer
fb45804adf nyx: refactor various functions and add comments
Emphasis on partition manager deduplication and remove of some magic numbers.
2022-05-16 13:28:38 +03:00
CTCaer
796207a41b nyx: do not allow joycon pairing info dump on Hoag 2022-05-16 13:12:45 +03:00
CTCaer
1649d446cd nyx: options: set min year for clock offset to 2022 2022-05-16 13:12:11 +03:00
CTCaer
7459214fed nyx: info: add mov r1 print for patched t210 2022-05-16 13:06:40 +03:00
CTCaer
e9587a325c bdk: fuse: add ipatch support for T210B01 2022-05-16 13:05:12 +03:00
CTCaer
331f1926d1 bdk: display: remove unneeded pinmuxing on Aula 2022-05-16 10:16:24 +03:00
CTCaer
87fe374b3b bdk: uart: use 2 STOP bits based on baudrate 2022-05-14 12:25:02 +03:00
CTCaer
b56e788d12 bdk: pinmux: more proper uart pinmuxing 2022-05-14 12:20:57 +03:00
CTCaer
abdf621ad5 nyx: simplify uart debug port path 2022-05-13 03:57:09 +03:00
CTCaer
9e613a7600 bdk: hwinit: simplify uart debug port paths 2022-05-13 03:56:59 +03:00
CTCaer
c2ff5dbd1c nyx: add no box and 5 entries per line support
Icons that have `_nobox.bmp` in their name will make the grey background disappear.

Additionally a new option was added in Nyx Options called `Extended Boot Entries` that allows user to have a total of 10 entries showing up in Launch and More configs menus.
2022-05-13 03:49:32 +03:00
CTCaer
b9cdf5d697 nyx: fix s_printf bugs pointed by format checker 2022-05-12 16:43:18 +03:00
CTCaer
b6384d5da5 bdk: utils: Set format attribute for s_printf
This allows the custom sprintf to be recognized as printf by gcc and effectively doing format checking.

NOTE: 64bit formatting is not supported for now, even if gcc asks to be set.
2022-05-12 16:40:34 +03:00
CTCaer
7df76bff4a nyx: input: add Sio support (for Hoag) 2022-05-09 06:13:10 +03:00
CTCaer
54b054c940 bdk: usb: add Sio support to hid gadget 2022-05-09 06:10:49 +03:00
CTCaer
f31170bb51 bdk: joycon: add Sio support (for Hoag) 2022-05-09 06:09:06 +03:00
CTCaer
f452d916c9 bdk: clock: add ext peripheral clock control 2022-05-09 06:08:39 +03:00
CTCaer
47d06d0e8a bdk: joycon: use flow control to improve packet integrity 2022-05-09 05:55:06 +03:00
CTCaer
2aed1b3b83 bdk: joycon: add 3 mbaud support and full init
Additionally use states for proper init
2022-05-09 05:48:10 +03:00
CTCaer
12aac3a0fc bdk: clock: add 3 megabaud support for UART 2022-05-09 05:47:08 +03:00
CTCaer
833a115eb2 bdk: joycon: improve and streamline jc detect 2022-05-09 05:39:45 +03:00
CTCaer
9f30c51bd1 bdk: joycon: refactor driver 2022-05-09 05:32:32 +03:00
CTCaer
62d68b33c3 nyx: tools: use actual gpt entries num in part manager 2022-05-08 05:59:57 +03:00
CTCaer
c51877d588 nyx: tools: add mbr hidden attr fixer in hybrid mbr fixer 2022-05-08 05:59:32 +03:00
CTCaer
471f3c50ea nyx: tools: do not allow part manager backup/restore to hang on corruption 2022-05-08 05:57:59 +03:00
CTCaer
6d66bfc168 nyx: tools: do not allow arc bit fixer to hang on corruption
Check if path exceeds 1024 characters.
2022-05-08 05:56:44 +03:00
CTCaer
9163151dd0 nyx: info: add battery lot and another old panel rev 2022-05-08 05:55:46 +03:00
CTCaer
334d89973f hekate/nyx: adhere to uart driver changes 2022-05-08 05:46:23 +03:00
CTCaer
f7bf4af3ec bdk: uart: refactor and add new functionality
- Allow to set CTS/RTS mode (only specific combos supported for now)
- Support the above modes in receiving
- Set 2 stop bits to decreases errors on high baudrates
2022-05-08 05:45:16 +03:00
CTCaer
ae394d9f37 nyx: remove negative decimal external handling 2022-05-08 05:32:21 +03:00
CTCaer
c2869703af hekate: gfx: add negative decimals printing
And remove external handling
2022-05-08 05:29:30 +03:00
CTCaer
ebe7b5a603 bdk: utils: add approx. square root calc for u64 2022-05-08 05:27:05 +03:00
CTCaer
ebf0db77ee bdk: sprintf: add negative number support for %d
This will now force a number as negative if bit31 is set and properly create the relevant string.

That means that external handling in order to show sign is now not needed.
2022-05-08 05:26:01 +03:00
CTCaer
81730c5f7e bdk: pinmux/pmc: add more defines 2022-05-08 05:22:41 +03:00
CTCaer
76d1b4e221 bdk: sdmmc: refactor defines
And fix a bug with tuning trim values
2022-05-08 05:21:29 +03:00
CTCaer
4a1cb1f2ea bdk: fan: add Hoag and Aula SKUs support
Now that what was hanging Aula is found (using PWM with its clock disabled), add full support for fan control on both SKUs.
2022-05-08 05:07:38 +03:00
CTCaer
58a2094448 bdk: reg 5v: add support for Hoag and Aula SKUs
Add support back and make it more proper.
Also add fan regulator support also.
2022-05-08 05:05:39 +03:00
CTCaer
1b7b7ab7f5 nyx: info: add new hynix chip model info 2022-05-08 05:00:46 +03:00
CTCaer
37de367fef bdk: sdram: deduplicate dram configs
Additionally add info about new hynix chip and correct ids 3 and 5 on T210B01 based Switch.
2022-05-08 04:58:36 +03:00
CTCaer
450d95e573 bdk: di: correct samsung backlight set
Now that vblank writes are fixed we can return to proper backlight set.

Additionally, account for the pwm smoothing when backlight is turned off. That's to avoid visible green tint glitches when display is also turned off.
2022-05-08 04:53:13 +03:00
CTCaer
969a49edba bdk: di: reselect winA when done with winD config 2022-05-08 04:49:28 +03:00
CTCaer
9908eb8bb3 bdk: di: samsung panel: better init
- Set display color profile to natural (it's still vivid but not overblown.)
- Enable PWM slope and set it to 6 frames in order to have smooth backlight transitions
2022-05-08 04:48:55 +03:00
CTCaer
56dcbb2b23 bdk: di: cleanup configs
Nintendo or Nvidia copied pasted the dynamic display code into static arrays in order to do the static hw init in bootloader and boot sysmodule.

Ofc that does double the work that is not needed at all, making it suboptimal.

Clean up every single config based on how tegra display interface hw works in order to save up space and make the process a bit faster.
2022-05-08 04:45:03 +03:00
CTCaer
b9f40fed7a bdk: di: move plld setup code out of display obj 2022-05-08 04:41:05 +03:00
CTCaer
6ae4904c8f bdk: di: make dsi normal/vblank writes more robust 2022-05-08 04:36:20 +03:00
CTCaer
dd2bb0f555 bdk: di: refractor configs 2022-05-08 04:34:44 +03:00
CTCaer
0b8cdaf0ea bdk: di: split normal and vblank dsi reads
And also make vblank reads more robust
2022-05-08 04:23:31 +03:00
CTCaer
8f540b2543 Bump hekate to v5.7.2 and Nyx to v1.2.2 2022-03-23 19:34:59 +02:00
CTCaer
f687c4f6da hos: add support for HOS 14.0.0 2022-03-23 02:21:59 +02:00
CTCaer
5c4e895c35 nyx: update dram/touch info for HOS 14.0.0 2022-03-23 02:21:21 +02:00
CTCaer
83c95d8a3b bdk: sdram: update 20/21/22 ids for new dram
Dram chip is Samsung 4GB built on 1z-nm that allows for 40% lower power usage.
2022-03-23 02:20:55 +02:00
CTCaer
ff214f25c1 bdk: update l4t hekatf prep functions 2022-03-23 00:58:20 +02:00
CTCaer
f818d094c5 Add .exe version of the tools in .gitignore 2022-03-23 00:56:32 +02:00
CTCaer
69c312daac nyx: clear B button context on option actions
Fixes an issue that was causing an NULL pointer dereference when a certain access path was followed
2022-03-23 00:55:18 +02:00
CTCaer
b7e59dfc28 nyx: print sd oemid in hex also 2022-03-23 00:53:56 +02:00
CTCaer
c04d423f4b nyx: add option to use right joycon as mouse control
`jcforceright=1` in nyx.ini enables that feature.
Useful for users with broken touch screen and broken left joycon rail.
2022-03-23 00:49:47 +02:00
CTCaer
af1ece903b nyx: Do not reserve alignment space if no extra partitions 2022-03-23 00:24:51 +02:00
CTCaer
547c90a0a9 hekate: remove ipatches info from main hekate 2022-03-23 00:24:13 +02:00
CTCaer
0fef90dc4c bdk: sd: return proper error for sd file save 2022-02-15 00:36:23 +02:00
CTCaer
a76ad9838e nyx: cosmetics 2022-02-15 00:29:23 +02:00
CTCaer
499a9cf5f3 hekate: disable heap defrag 2022-02-15 00:27:17 +02:00
CTCaer
cfd6567f5d pkg1: move warmboot rsa patching into pkg1
And create a function for hekatf to be used
2022-02-15 00:26:07 +02:00
CTCaer
ee465b98af bdk: sdmmc correct exit on eMMC < 4.0 modules 2022-02-15 00:24:53 +02:00
CTCaer
9aa55c2d76 hekate/nyx: correct type on heap_init 2022-02-15 00:23:23 +02:00
CTCaer
83b895a062 bdk: heap: improvements
Correct types everywhere.
Add BDK_MALLOC_NO_DEFRAG that disables defragmentation on the heap.
2022-02-15 00:22:38 +02:00
CTCaer
ad4014f295 hekate: sd info: always reset mode after done 2022-02-15 00:18:24 +02:00
CTCaer
ce8d1eca91 bdk: remove sd mounts from ianos and check if sd is mounted in sd ops 2022-02-15 00:17:53 +02:00
CTCaer
73d38e1183 hos: loop through counter instead of explicit sets 2022-02-15 00:16:42 +02:00
CTCaer
3f65a30b2e bdk: more atf prep 2022-02-15 00:14:53 +02:00
CTCaer
7c74391754 bdk: bpmp: do not use full maintenance
Instead use proper clean/invalidation of dcache.
2022-02-15 00:14:14 +02:00
CTCaer
70ee61f0da More 2022 copyright updates 2022-01-29 01:43:35 +02:00
CTCaer
b0b538f8f2 build: force dwarf v4 2022-01-29 01:43:16 +02:00
CTCaer
52bb6a96e5 bdk: nx emmc bis: fix out of cluster bounds accesses 2022-01-29 01:40:38 +02:00
CTCaer
6666dd4b46 bdk: fatfs: better PrFILE2 SAFE record creation 2022-01-29 01:40:05 +02:00
CTCaer
4a13a1d190 nyx: fix aula full emummc creation (for real this time) 2022-01-29 01:39:01 +02:00
CTCaer
2b7217242d nyx: align down resized emu sectors to cluster size 2022-01-29 01:37:57 +02:00
CTCaer
ce16a08694 main: check pstore log size if 0 2022-01-29 01:37:02 +02:00
CTCaer
0ad42762e7 main: rename logo buffer 2022-01-29 01:36:35 +02:00
CTCaer
5f337bffd6 config: do not unmount on exit
Fixes Nyx not found for new users without hekate_ipl.ini
2022-01-29 01:35:09 +02:00
CTCaer
3fdb72ce37 bdk: i2c: correct order of spinlock wait 2022-01-29 01:34:01 +02:00
CTCaer
9a80f8b4b5 bdk: minerva: fix fsp op/wr check for l4t 2022-01-29 01:31:28 +02:00
CTCaer
c0c8fb263a hekate/nyx: enable ahb arbitration 2022-01-29 01:29:39 +02:00
CTCaer
ef5790cc2c bdk: mc: always on ahb arbitration
- Removed disables
- SDMMC code now just checks if it has access
2022-01-29 01:29:02 +02:00
CTCaer
7bb8b1da62 di: restore window config wait for inv pitch and block linear 2022-01-29 01:26:00 +02:00
CTCaer
aee5861f65 hekate/nyx: improve cyclomatic complexity 2022-01-29 01:23:40 +02:00
CTCaer
2f1d1572f7 Bump hekate to v5.7.0 and Nyx to v1.2.0 2022-01-20 14:34:54 +02:00
CTCaer
d52283f0c2 nyx: add support for FULL emuMMC for OLED model
That supports creating a 64GB emuMMC partition.
That's added for consistency.
Because it's a waste of space, better use resized emuMMC.
2022-01-20 14:11:36 +02:00
CTCaer
6be12f32e6 nyx: remove nx_emmc_bis objects as they reside in bdk now 2022-01-20 14:08:39 +02:00
CTCaer
49f34581bb hos: add 13.2.1 support 2022-01-20 14:06:50 +02:00
CTCaer
0a1db98210 nyx: add eMMC hw issues reporting 2022-01-20 14:00:45 +02:00
CTCaer
17b0270eb5 hekate: move display init above others that need it 2022-01-20 13:57:25 +02:00
CTCaer
39ce19e6f4 hekate: remove unnecessary sd mounts
- Main already mounts sd. Also by trying again it takes forever to go into TUI
- Skip l4t kernel pstore dump and auto launch fw if sd failed to mount
2022-01-20 13:56:36 +02:00
CTCaer
b18b5076b3 hos: change order of deinits and update for newer exo 2022-01-20 13:49:29 +02:00
CTCaer
6ac9d79282 pkg2: do not hash kernel/ini1 if exo 2022-01-20 13:34:18 +02:00
CTCaer
836530d4e3 pkg2: refactor bitflags and remove debugging code 2022-01-20 13:32:48 +02:00
CTCaer
3b2f438f69 pkg2: ini patches: reduce heap fragmentation/pressure 2022-01-20 13:31:16 +02:00
CTCaer
781f377083 nyx: adhere to nx_emmc_bis changes 2022-01-20 13:26:24 +02:00
CTCaer
20c4d6dba6 minerva: update copyright years 2022-01-20 13:22:39 +02:00
CTCaer
192a936a31 bdk: add NX eMMC BIS driver 2022-01-20 13:21:04 +02:00
CTCaer
23945ee12f nyx: use new bdk compile time flags 2022-01-20 13:20:06 +02:00
CTCaer
8327de8e2e bdk: replace NYX flag with proper flags
- BDK_MINERVA_CFG_FROM_RAM: enables support for getting minerva configuration from nyx storage
- BDK_HW_EXTRA_DEINIT: enables extra deinit in hw_reinit_workaround
- BDK_SDMMC_OC_AND_EXTRA_PRINT: enables eMMC OC support (533 MB/s) and extra error printing
2022-01-20 13:19:48 +02:00
CTCaer
960f3b23e7 bdk: ums: adhere to emmc ops changes also 2022-01-20 13:17:55 +02:00
CTCaer
28167b7304 hekate/nyx: move emmc ops to bdk and adhere to changes 2022-01-20 13:15:04 +02:00
CTCaer
b08e36a7b0 bdk: add emmc ops
- Add support for lower eMMC bus speed init in case of failures
- Add error count reporting
- Function names and defines changed from nx_emmc to emmc (except autorcm helper function)
- Enabling emuMMC support needs BDK_EMUMMC_ENABLE flag passed over
2022-01-20 13:14:38 +02:00
CTCaer
943f675046 hekate/main: move sd ops into bdk 2022-01-20 12:49:18 +02:00
CTCaer
00110a8863 bdk: move sd ops into bdk 2022-01-20 12:48:41 +02:00
CTCaer
7ae4fd03c2 bdk: minerva: prep for ATF direct boot support 2022-01-20 12:43:24 +02:00
CTCaer
e071fe44b0 bdk: ini: reduce heap fragmentation/pressure 2022-01-20 12:41:20 +02:00
CTCaer
39d411dc68 bdk: uart: add uart va print 2022-01-20 12:39:32 +02:00
CTCaer
82f90fae28 bdk: utils: add vprintf 2022-01-20 12:37:41 +02:00
CTCaer
10e1f67dc5 bdk: utils: add strcpy with head/tail whitespace removal 2022-01-20 12:36:25 +02:00
CTCaer
10b479dc1c bdk: clock: add apb/ahb clock control 2022-01-20 12:32:57 +02:00
CTCaer
3dd12321f8 bdk: add activity monitor driver 2022-01-20 12:32:02 +02:00
CTCaer
c1441a64c7 bdk: se: expose xts functions and add nx xts 2022-01-20 12:28:26 +02:00
CTCaer
0e35e68fd5 bdk: se: add t210b01 data coherency WAR 2022-01-20 12:27:25 +02:00
CTCaer
853f10f774 bdk: pmc: update tzram defines 2022-01-20 12:13:35 +02:00
CTCaer
4628ee6dc5 bdk: di: window fb changes
- Get fb address from in window regs
- Remove 2 frames wait
2022-01-20 12:12:19 +02:00
CTCaer
3bb46c6470 bdk: di: allocate fifo buffer once 2022-01-20 12:09:29 +02:00
CTCaer
6a74f6ed04 minerva: make is_pllmb and fsp automatic
No need to keep these values around.
Software will automatically check the proper registers to get status.
2022-01-16 01:43:16 +02:00
CTCaer
d1c0d464dc minerva: name needs_training flags 2022-01-16 01:41:24 +02:00
CTCaer
6092994240 nyx: sd part: set attributes to folders also on restore 2022-01-16 01:38:47 +02:00
CTCaer
5a88f7bc06 nyx: info: highlight battery temp info if cold/hot 2022-01-16 01:37:26 +02:00
CTCaer
06e7af150e hekate/nyx: improve exceptions reporting
- Do not report HOS panic if status is 0
- Do not report LP0/MTC libs missing if failed to mount sd
- Rename panics to be explicit of their source
2022-01-16 01:33:07 +02:00
CTCaer
864ec50a2d main: add L4T kernel panic report back
L4T kernel now uses a PANIC magic flag instead of a bitflag and so it's simpler to detect.
2022-01-16 01:23:39 +02:00
CTCaer
aa0a9da37b fatfs: default year to 2022 2022-01-16 01:09:45 +02:00
CTCaer
30a4861da6 exo: change BOOT2 error message 2022-01-16 01:08:56 +02:00
CTCaer
5e6a7c486b bdk: btn: enable HOME button as input 2022-01-16 01:05:42 +02:00
CTCaer
1a9c6bf983 bdk: correct reg init as per TRM 2022-01-16 01:04:52 +02:00
CTCaer
70504c295e bdk: various functionality independent changes 2022-01-16 01:03:24 +02:00
CTCaer
5894062b93 hekate/nyx: utilize bdk global header 2022-01-16 00:04:34 +02:00
CTCaer
a5cd962f99 bdk: add global header 2022-01-15 23:58:27 +02:00
CTCaer
01b6e645b3 Bump hekate to v5.6.5 and Nyx to v1.1.1 2021-10-26 11:39:53 +03:00
CTCaer
db8c41cdaa hos: pkg2: add 13.1.0 support 2021-10-26 11:39:32 +03:00
CTCaer
b0fe84070f nyx: add new touch panel fw info
Additionally, do not alloc/free heap every time status bar update must run
2021-10-26 10:55:11 +03:00
CTCaer
4d91d2baff bdk: fan: clamp duty before checking if the same 2021-10-26 10:53:22 +03:00
CTCaer
c6fdb637ca Bump hekate to v5.6.4 and Nyx to v1.1.0 2021-10-19 09:16:49 +03:00
CTCaer
bdd9e48606 nyx: simplify touch ic fw ids 2021-10-19 09:16:18 +03:00
CTCaer
25a7544010 nyx: add new mircon ram model info 2021-10-19 09:15:28 +03:00
CTCaer
821ad23341 nyx: add fuses keygen revision info 2021-10-19 09:14:36 +03:00
CTCaer
981c986b3f bdk: sdram: name the new micron modules 2021-10-19 09:13:14 +03:00
CTCaer
09b3e47ac8 bdk: touch: rename samsung touch panel 2021-10-19 09:11:58 +03:00
CTCaer
d2684f66a1 hos: change exfat check order 2021-10-19 09:11:36 +03:00
CTCaer
964381854e readme: fix key name in description 2021-10-15 16:52:11 +03:00
CTCaer
d8670fbd87 nyx: bis: correct lookup check 2021-10-15 16:50:56 +03:00
CTCaer
3c81ac91df nyx: fix months that have 30/31 days on date picker 2021-10-15 16:50:16 +03:00
CTCaer
147c82e0e2 nyx: fix text color on restore emmc errors 2021-10-15 16:49:28 +03:00
CTCaer
339ce2d861 minerva: change some types and fix temp check
Temperature error check for over temp compensation was wrong.

It's still unused though, so it didn't matter.
2021-10-15 16:48:51 +03:00
CTCaer
a7f0701cbf hos: move storage end above final touches 2021-10-15 16:47:06 +03:00
CTCaer
65b3b87c99 hos: pkg1: explicitly which type pkg1 is wrongly flashed 2021-10-15 16:42:39 +03:00
CTCaer
8d3700b76b hos: improve error for missing BEK or corrupt pkg1 on T210B01 2021-10-15 16:40:06 +03:00
CTCaer
d2595a00b6 nyx: move autorcm protection in nyx 2021-10-15 16:34:15 +03:00
CTCaer
c4bf129d5e hos: name pkg1/secmon states 2021-10-15 16:30:14 +03:00
CTCaer
503f4d4cd6 tui: tools: simplify autorcm warning 2021-10-15 16:26:57 +03:00
CTCaer
31d6c7d85d bdk: reg 5v: fix a hang with T210B01 and Hoag/Aula
- Hoag and Aula do not have a USB based 5V bus source, so do not touch CC4 pin.

- More importantly, in T210B01 the GPIO AO IO rail seems to be working properly from boot.
Plus it also seems that is needed by various components.

That was found when running on Aula. It was causing an immediate hang. Probably SoC wide.

Only allow control of it on T210 to avoid such issues.
2021-10-15 16:26:11 +03:00
CTCaer
9a17ca2628 bdk: disable fan control on Hoag and Aula
TODO: Add support for them.
These use a different way to init/control fan.
2021-10-15 16:19:16 +03:00
CTCaer
49bcaf3914 bdk: correct some types and warnings 2021-10-15 16:18:06 +03:00
CTCaer
82d0346615 bdk: fatfs: remove errors that depend on full diskio 2021-10-15 16:17:08 +03:00
CTCaer
808da1bce0 bdk: di: adjust OLED panel brightness curve
The Samsung AMOLED panel least legible backlight is at a high duty (45 / 255).
Change the linear curve to a more appropriate one.
2021-10-15 16:16:24 +03:00
CTCaer
6992ece762 bdk: touch: add samsung touch model name 2021-10-15 16:09:25 +03:00
CTCaer
734e70b755 nyx: add samsung display/touch model info 2021-10-15 16:08:48 +03:00
CTCaer
681182540e bdk: di: add model name for the samsung panel 2021-10-15 16:07:18 +03:00
CTCaer
9c29ee437a Bump hekate to v5.6.3 and Nyx to v1.0.8 2021-10-01 15:54:49 +03:00
CTCaer
785baad5ea hos: exo: better fatal description for boot2 2021-10-01 15:46:38 +03:00
CTCaer
91b08f10fd hekate/nyx: use size defines where applicable 2021-10-01 15:45:25 +03:00
CTCaer
c801ef8dda bdk: use size defines where applicable 2021-10-01 15:03:18 +03:00
CTCaer
b47c01981f hekate: add OS panic error reporting 2021-10-01 14:35:39 +03:00
CTCaer
7e4c71748f bdk: types: refactor and add size defines 2021-10-01 14:33:55 +03:00
CTCaer
a1910156d8 bdk: hwinit: save boot reason for later usage 2021-10-01 14:32:42 +03:00
CTCaer
99d15eaac8 bdk: fatfs: check if string is null for puts/printf
Avoid writing garbage to a file by checking string pointer passed to f_puts and f_printf.

Important on many embedded platforms that do not abort on NULL dereference.
2021-10-01 14:27:57 +03:00
CTCaer
e31d6446db nyx: correct reboot name for patched devices 2021-09-26 12:53:34 +03:00
CTCaer
05ce867064 hekate: move emummc config load inside relevant functions
This ensures that hekate can re-read it in case of sd card swap while in TUI and also doesn't read it if not needed.
2021-09-26 12:23:54 +03:00
CTCaer
609a76045a nyx: remove always true check 2021-09-26 12:16:04 +03:00
CTCaer
000ea3096a nyx: check if emuMMC path is null before producing the ID 2021-09-26 12:15:25 +03:00
220 changed files with 19755 additions and 19299 deletions

2
.gitignore vendored
View file

@ -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

View file

@ -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 \
)
@ -63,8 +64,12 @@ 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
@ -74,10 +79,12 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
#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 -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)
CFLAGS = $(ARCH) -O2 -g -gdwarf-4 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
MODULEDIRS := $(wildcard modules/*)

View file

@ -81,6 +81,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
| 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. |
@ -105,13 +106,22 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
| 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. |
| ---------------------- | ---------------------------------------------------------- |
| 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. |
| 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. |
@ -159,38 +169,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-2024, CTCaer.
Nyx GUI (c) 2019-2021, CTCaer.
Nyx GUI (c) 2019-2024, 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
___
.-' `'.

View file

@ -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.)

View file

@ -1,11 +1,11 @@
# IPL Version.
BLVERSION_MAJOR := 5
BLVERSION_MINOR := 6
BLVERSION_MAJOR := 6
BLVERSION_MINOR := 2
BLVERSION_HOTFX := 2
BLVERSION_RSVD := 0
BLVERSION_REL := 0
# Nyx Version.
NYXVERSION_MAJOR := 1
NYXVERSION_MINOR := 0
NYXVERSION_HOTFX := 7
NYXVERSION_RSVD := 0
NYXVERSION_MINOR := 6
NYXVERSION_HOTFX := 4
NYXVERSION_REL := 0

80
bdk/bdk.h Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef BDK_H
#define BDK_H
#include <memory_map.h>
#include <display/di.h>
#include <display/vic.h>
#include <input/als.h>
#include <input/joycon.h>
#include <input/touch.h>
#include <mem/emc.h>
#include <mem/heap.h>
#include <mem/mc.h>
#include <mem/minerva.h>
#include <mem/sdram.h>
#include <mem/smmu.h>
#include <module.h>
#include <power/bm92t36.h>
#include <power/bq24193.h>
#include <power/max17050.h>
#include <power/max77620.h>
#include <power/max7762x.h>
#include <power/max77812.h>
#include <power/regulator_5v.h>
#include <rtc/max77620-rtc.h>
#include <sec/se.h>
#include <sec/tsec.h>
#include <soc/actmon.h>
#include <soc/bpmp.h>
#include <soc/ccplex.h>
#include <soc/clock.h>
#include <soc/fuse.h>
#include <soc/gpio.h>
#include <soc/hw_init.h>
#include <soc/i2c.h>
#include <soc/irq.h>
#include <soc/kfuse.h>
#include <soc/pinmux.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <soc/uart.h>
#include <storage/emmc.h>
#include <storage/mbr_gpt.h>
#include <storage/mmc.h>
#include <storage/nx_emmc_bis.h>
#include <storage/ramdisk.h>
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <thermal/fan.h>
#include <thermal/tmp451.h>
#include <usb/usbd.h>
#include <utils/aarch64_util.h>
#include <utils/btn.h>
#include <utils/dirlist.h>
#include <utils/ini.h>
#include <utils/list.h>
#include <utils/sprintf.h>
#include <utils/types.h>
#include <utils/util.h>
#include <gfx_utils.h>
#endif

File diff suppressed because it is too large Load diff

View file

@ -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,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)
@ -433,30 +539,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 +703,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 +717,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
#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 +727,8 @@
#define MIPI_DCS_PRIV_UNK_D6 0xD6
#define MIPI_DCS_PRIV_UNK_D8 0xD8
#define MIPI_DCS_PRIV_UNK_D9 0xD9
// 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 +763,57 @@
#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_BRIGHTNESS_CTRL BIT(5)
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
#define DCS_SM_COLOR_MODE_WASHED 0x45
#define DCS_SM_COLOR_MODE_BASIC 0x03
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
#define DCS_SM_COLOR_MODE_VIVID 0x65
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
#define DCS_SM_COLOR_MODE_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 +826,7 @@
* 10h: Japan Display Inc.
* 20h: InnoLux Corporation
* 30h: AU Optronics
* 40h: Unknown0
* 40h: Sharp
* 50h: Samsung
*
* Boards, Panel Size:
@ -702,18 +844,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 +882,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

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
//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},
};

560
bdk/display/vic.c Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "vic.h"
#include <mem/heap.h>
#include <soc/bpmp.h>
#include <soc/clock.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/types.h>
/* 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();
}

66
bdk/display/vic.h Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef _VIC_H_
#define _VIC_H_
#include <utils/types.h>
#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

View file

@ -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

View file

@ -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

305
bdk/fatfs_conf.h Normal file
View file

@ -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 <somertos.h> // 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 ---*/

View file

@ -29,33 +29,34 @@
#ifndef ELF_H
#define ELF_H
#include <stdint.h>
typedef uint8_t Elf_Byte;
#include <utils/types.h>
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 */

View file

@ -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;

View file

@ -22,8 +22,6 @@
#include "elfarch.h"
#include "elf.h"
#include <utils/types.h>
#ifdef DEBUG
#include <gfx_utils.h>
#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

View file

@ -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)
{

View file

@ -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;

View file

@ -22,7 +22,7 @@
#include <module.h>
#include <mem/heap.h>
#include <power/max7762x.h>
#include <storage/nx_sd.h>
#include <storage/sd.h>
#include <utils/types.h>
#include <gfx_utils.h>
@ -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;
}

View file

@ -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)
{
@ -73,7 +73,7 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
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 +83,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 +116,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;

File diff suppressed because it is too large Load diff

View file

@ -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
#endif

View file

@ -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 <soc/pinmux.h>
#include <power/max7762x.h>
#include <soc/gpio.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/btn.h>
#include <utils/util.h>
#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);

View file

@ -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);
}

View file

@ -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

View file

@ -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 <mem/heap.h> /* 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 <string.h> /* memset, memcpy */
#define MEM_INIT memset

View file

@ -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) */
@ -4712,9 +4709,9 @@ DWORD *f_expand_cltbl (
}
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 +5879,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 +5915,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 +6228,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 +6243,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 +6746,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 +6774,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);

View file

@ -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 <bdk.h>
#include <libs/fatfs/ff.h>
#include "../../config.h"
#include <mem/heap.h>
#include <rtc/max77620-rtc.h>
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));

View file

@ -17,7 +17,7 @@
#ifndef LV_CONF_H
#define LV_CONF_H
#include <utils/types.h>
#include <soc/timer.h>
#include <memory_map.h>
/*===================
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 <utils/util.h> /*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 <soc/timer.h> /*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

View file

@ -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*/
}
}

View file

@ -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*/

View file

@ -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)))
/**

View file

@ -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;
}
/**

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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 <gfx_utils.h>
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;
}

View file

@ -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);

View file

@ -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 <memory_map.h>
#include <mem/mc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <soc/clock.h>
#include <utils/util.h>
//#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();

View file

@ -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

View file

@ -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)

View file

@ -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 <soc/clock.h>
#include <ianos/ianos.h>
#include <mem/emc.h>
#include <soc/clock.h>
#include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/t210.h>
#include <utils/util.h>
#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);
}
}
}
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;
}

View file

@ -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

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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 <utils/types.h>
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__ */

View file

@ -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 <utils/types.h>
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

View file

@ -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;

View file

@ -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 <string.h>
#include <soc/bpmp.h>
#include <soc/ccplex.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <mem/mc_t210.h>
#include <mem/smmu.h>
#include <utils/util.h>
#include <utils/aarch64_util.h>
#include <memory_map.h>
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();
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <utils/types.h>
#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);

View file

@ -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))

View file

@ -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;

View file

@ -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)

View file

@ -24,7 +24,7 @@
#include "max17050.h"
#include <soc/i2c.h>
#include <utils/util.h>
#include <soc/timer.h>
#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);
}

View file

@ -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_ */

View file

@ -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

View file

@ -20,8 +20,8 @@
#include <power/max77812.h>
#include <soc/fuse.h>
#include <soc/i2c.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/util.h>
#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);
}
}

View file

@ -20,6 +20,14 @@
#include <utils/types.h>
/*
* 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();

View file

@ -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

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <soc/fuse.h>
#include <soc/gpio.h>
#include <soc/hw_init.h>
#include <soc/pinmux.h>
#include <soc/pmc.h>
#include <soc/t210.h>
@ -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);

View file

@ -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 <rtc/max77620-rtc.h>
#include <soc/i2c.h>
#include <utils/util.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
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;
}

View file

@ -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_ */

View file

@ -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,
@ -18,12 +18,13 @@
#include <string.h>
#include "se.h"
#include "se_t210.h"
#include <memory_map.h>
#include <mem/heap.h>
#include <soc/bpmp.h>
#include <soc/hw_init.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/util.h>
typedef struct _se_ll_t
{
@ -32,6 +33,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 +52,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 +83,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 +130,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 +182,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);
u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
@ -159,7 +194,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
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 +207,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 +226,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 +238,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 +281,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 +341,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 +363,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,7 +386,7 @@ 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);
@ -335,7 +399,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 +407,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];
@ -359,18 +423,87 @@ 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 +513,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 +562,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 +574,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 +584,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 +602,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 +614,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 +623,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 +653,62 @@ 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;
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
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:;
free(key);
free(last_block);
return res;
}

View file

@ -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 <utils/types.h>
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

View file

@ -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)

View file

@ -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 <memory_map.h>
#include <mem/heap.h>
#include <mem/mc.h>
#include <mem/smmu.h>
#include <sec/se_t210.h>
#include <soc/bpmp.h>
#include <soc/clock.h>
#include <soc/kfuse.h>
#include <soc/pmc.h>
#include <soc/t210.h>
#include <mem/heap.h>
#include <mem/mc.h>
#include <mem/smmu.h>
#include <utils/util.h>
#include <soc/timer.h>
// #include <gfx_utils.h>
@ -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;
}

View file

@ -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);

View file

@ -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)

172
bdk/soc/actmon.c Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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();
}

62
bdk/soc/actmon.h Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __ACTMON_H_
#define __ACTMON_H_
#include <utils/types.h>
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

View file

@ -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 <soc/bpmp.h>
#include <soc/clock.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <memory_map.h>
#include <utils/util.h>
#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;
}

View file

@ -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();

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <memory_map.h>
#include <soc/ccplex.h>
#include <soc/hw_init.h>
#include <soc/i2c.h>
@ -26,7 +27,9 @@
#include <power/max77812.h>
#include <utils/util.h>
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();
}

View file

@ -19,6 +19,7 @@
#include <utils/types.h>
void ccplex_boot_cpu0(u32 entry);
void ccplex_boot_cpu0(u32 entry, bool lock);
void ccplex_powergate_cpu0();
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <soc/bpmp.h>
#include <soc/clock.h>
#include <soc/hw_init.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <storage/sdmmc.h>
#include <utils/util.h>
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);
}

View file

@ -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);

View file

@ -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,6 +19,7 @@
#include <string.h>
#include <mem/heap.h>
#include <sec/se.h>
#include <sec/se_t210.h>
#include <soc/fuse.h>
@ -42,12 +43,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 +88,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 +167,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 +182,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 +210,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 +238,7 @@ static int _patch_hash_one(u32 *word)
return 1;
}
}
return 2;
}
@ -246,9 +259,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 +271,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 +286,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 +303,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 +344,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 +363,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 +413,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 +426,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 +453,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)
{

View file

@ -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 <utils/types.h>
/*! 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

View file

@ -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 <soc/gpio.h>
#include <soc/t210.h>
#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];
}
}

View file

@ -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);

View file

@ -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 <soc/hw_init.h>
#include <display/di.h>
#include <display/vic.h>
#include <input/joycon.h>
#include <input/touch.h>
#include <sec/se.h>
@ -31,6 +32,7 @@
#include <soc/pinmux.h>
#include <soc/pmc.h>
#include <soc/uart.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <mem/mc.h>
#include <mem/minerva.h>
@ -39,7 +41,7 @@
#include <power/max77620.h>
#include <power/max7762x.h>
#include <power/regulator_5v.h>
#include <storage/nx_sd.h>
#include <storage/sd.h>
#include <storage/sdmmc.h>
#include <thermal/fan.h>
#include <thermal/tmp451.h>
@ -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();
}
}

View file

@ -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 <utils/types.h>
#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

View file

@ -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 <string.h>
#include <soc/i2c.h>
#include <utils/util.h>
#include <soc/t210.h>
#include <soc/timer.h>
#define I2C_PACKET_PROT_I2C BIT(4)
#define I2C_HEADER_CONT_XFER BIT(15)
@ -81,34 +82,28 @@
#define MSTR_CONFIG_LOAD BIT(0)
#define TIMEOUT_CONFIG_LOAD BIT(2)
static const u32 i2c_addrs[] = {
0x7000C000, // I2C_1.
0x7000C400, // I2C_2.
0x7000C500, // I2C_3.
0x7000C700, // I2C_4.
0x7000D000, // I2C_5.
0x7000D100 // I2C_6.
};
/* I2C_1, 2, 3, 4, 5 and 6. */
static const u16 _i2c_base_offsets[6] = { 0x0, 0x400, 0x500, 0x700, 0x1000, 0x1100 };
static void _i2c_load_cfg_wait(vu32 *base)
{
base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
for (u32 i = 0; i < 20; i++)
{
usleep(1);
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
break;
usleep(1);
}
}
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, const u8 *buf, u32 size)
{
if (size > 8)
return 0;
u32 tmp = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and send mode.
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
@ -154,7 +149,7 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
if (size > 8)
return 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
@ -198,15 +193,15 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
// Set device address and send mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE;
// Set recv mode.
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
@ -270,7 +265,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
@ -352,7 +347,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
void i2c_init(u32 i2c_idx)
{
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
@ -362,9 +357,9 @@ void i2c_init(u32 i2c_idx)
for (u32 i = 0; i < 10; i++)
{
usleep(20000);
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
break;
usleep(25);
}
(vu32)base[I2C_BUS_CLEAR_STATUS];
@ -389,9 +384,9 @@ int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
}
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size)
{
u8 tmp[4];
u8 tmp[8];
if (size > 7)
return 0;

View file

@ -31,7 +31,7 @@ void i2c_init(u32 i2c_idx);
int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, const u8 *buf, u32 size);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);

View file

@ -1,7 +1,7 @@
/*
* BPMP-Lite IRQ driver for Tegra X1
*
* 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,6 +19,7 @@
#include <string.h>
#include "irq.h"
#include <soc/timer.h>
#include <soc/t210.h>
#include <gfx_utils.h>
#include <mem/heap.h>
@ -26,6 +27,7 @@
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...)
extern void excp_reset();
extern void irq_disable();
extern void irq_enable_cpu_irq_exceptions();
extern void irq_disable_cpu_irq_exceptions();
@ -69,29 +71,19 @@ static void _irq_disable_and_ack_all()
{
u32 enabled_irqs = ICTLR(ctrl_idx, PRI_ICTLR_COP_IER);
ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = enabled_irqs;
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs;
}
}
static void _irq_ack_source(u32 irq)
{
u32 ctrl_idx = irq >> 5;
u32 bit = irq % 32;
// Force stop the interrupt as it's serviced here.
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = BIT(bit);
}
void irq_free(u32 irq)
{
for (u32 idx = 0; idx < IRQ_MAX_HANDLERS; idx++)
{
if (irqs[idx].irq == irq && irqs[idx].handler)
{
irqs[idx].irq = 0;
irqs[idx].irq = 0;
irqs[idx].handler = NULL;
irqs[idx].data = NULL;
irqs[idx].flags = 0;
irqs[idx].data = NULL;
irqs[idx].flags = 0;
_irq_disable_source(irq);
}
@ -106,10 +98,10 @@ static void _irq_free_all()
{
_irq_disable_source(irqs[idx].irq);
irqs[idx].irq = 0;
irqs[idx].irq = 0;
irqs[idx].handler = NULL;
irqs[idx].data = NULL;
irqs[idx].flags = 0;
irqs[idx].data = NULL;
irqs[idx].flags = 0;
}
}
}
@ -119,7 +111,6 @@ static irq_status_t _irq_handle_source(u32 irq)
int status = IRQ_NONE;
_irq_disable_source(irq);
_irq_ack_source(irq);
u32 idx;
for (idx = 0; idx < IRQ_MAX_HANDLERS; idx++)
@ -133,8 +124,8 @@ static irq_status_t _irq_handle_source(u32 irq)
}
}
// Do not re-enable if not handled.
if (status == IRQ_NONE)
// Do not re-enable if not handled or error.
if (status != IRQ_HANDLED)
return status;
if (irqs[idx].flags & IRQ_FLAG_ONE_OFF)
@ -153,7 +144,6 @@ void irq_handler()
if (!irq_init_done)
{
_irq_disable_source(irq);
_irq_ack_source(irq);
return;
}
@ -192,10 +182,9 @@ void irq_wait_event(u32 irq)
_irq_enable_source(irq);
// Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ.
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
_irq_disable_source(irq);
_irq_ack_source(irq);
irq_enable_cpu_irq_exceptions();
}
@ -218,10 +207,10 @@ irq_status_t irq_request(u32 irq, irq_handler_t handler, void *data, irq_flags_t
DPRINTF("Registered handler, IRQ: %d, Slot: %d\n", irq, idx);
DPRINTF("Handler: %08p, Flags: %x\n", (u32)handler, flags);
irqs[idx].irq = irq;
irqs[idx].irq = irq;
irqs[idx].handler = handler;
irqs[idx].data = data;
irqs[idx].flags = flags;
irqs[idx].data = data;
irqs[idx].flags = flags;
_irq_enable_source(irq);
@ -270,4 +259,14 @@ void __attribute__ ((target("arm"), interrupt ("FIQ"))) fiq_handler()
len--;
}
*/
#ifdef BDK_WATCHDOG_FIQ_ENABLE
// Set watchdog timeout status and disable WDT and its FIQ signal.
watchdog_handle();
#ifdef BDK_RESTART_BL_ON_WDT
// Restart bootloader.
excp_reset();
#endif
#endif
}

View file

@ -180,6 +180,7 @@
#define IRQ_EVENT_GPIO_A 162
#define IRQ_EVENT_GPIO_B 163
#define IRQ_EVENT_GPIO_C 164
#define IRQ_EVENT_GPIO_D_T210B01 165
#define IRQ_FLOW_RSM_CPU 168
#define IRQ_FLOW_RSM_COP 169
#define IRQ_TMR_SHARED 170

View file

@ -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,
@ -19,10 +20,10 @@
void pinmux_config_uart(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
}
void pinmux_config_i2c(u32 idx)
@ -30,3 +31,11 @@ void pinmux_config_i2c(u32 idx)
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;
}
void pinmux_config_i2s(u32 idx)
{
PINMUX_AUX(PINMUX_AUX_X_I2S_LRCK(idx)) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN;
PINMUX_AUX(PINMUX_AUX_X_I2C_DIN(idx)) = PINMUX_DRIVE_4X | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_DOWN;
PINMUX_AUX(PINMUX_AUX_X_I2C_DOUT(idx)) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN;
PINMUX_AUX(PINMUX_AUX_X_I2C_BCLK(idx)) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN;
}

View file

@ -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,
@ -39,6 +40,7 @@
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
#define PINMUX_AUX_SDMMC3_DAT3 0x30
#define PINMUX_AUX_SATA_LED_ACTIVE 0x4C
#define PINMUX_AUX_GPIO_PA5_T210B01 PINMUX_AUX_SATA_LED_ACTIVE
#define PINMUX_AUX_DMIC3_CLK 0xB4
#define PINMUX_AUX_DMIC3_DAT 0xB8
#define PINMUX_AUX_CAM_I2C_SCL 0xD4
@ -46,7 +48,10 @@
#define PINMUX_AUX_UART2_TX 0xF4
#define PINMUX_AUX_UART3_TX 0x104
#define PINMUX_AUX_DAP4_DIN 0x148
#define PINMUX_AUX_DAP4_DOUT 0x14C
#define PINMUX_AUX_DAP4_SCLK 0x150
#define PINMUX_AUX_CLK_32K_OUT 0x164
#define PINMUX_AUX_AUD_MCLK 0x180
#define PINMUX_AUX_GPIO_X1_AUD 0x18C
#define PINMUX_AUX_GPIO_X3_AUD 0x190
#define PINMUX_AUX_SPDIF_IN 0x1A4
@ -57,20 +62,29 @@
#define PINMUX_AUX_AP_WAKE_NFC 0x1CC
#define PINMUX_AUX_NFC_EN 0x1D0
#define PINMUX_AUX_NFC_INT 0x1D4
#define PINMUX_AUX_CAM_RST 0x1E0
#define PINMUX_AUX_CAM1_PWDN 0x1EC
#define PINMUX_AUX_CAM2_PWDN 0x1F0
#define PINMUX_AUX_CAM1_STROBE 0x1F4
#define PINMUX_AUX_LCD_BL_PWM 0x1FC
#define PINMUX_AUX_LCD_BL_EN 0x200
#define PINMUX_AUX_LCD_RST 0x204
#define PINMUX_AUX_LCD_GPIO1 0x208
#define PINMUX_AUX_LCD_GPIO2 0x20C
#define PINMUX_AUX_TOUCH_RST 0x214
#define PINMUX_AUX_TOUCH_CLK 0x218
#define PINMUX_AUX_TOUCH_INT 0x220
#define PINMUX_AUX_MOTION_INT 0x224
#define PINMUX_AUX_ALS_PROX_INT 0x228
#define PINMUX_AUX_BUTTON_POWER_ON 0x230
#define PINMUX_AUX_BUTTON_HOME 0x240
#define PINMUX_AUX_GPIO_PE6 0x248
#define PINMUX_AUX_GPIO_PE7 0x24C
#define PINMUX_AUX_GPIO_PH6 0x250
#define PINMUX_AUX_GPIO_PK3 0x260
#define PINMUX_AUX_GPIO_PK7 0x270
#define PINMUX_AUX_GPIO_PZ1 0x280
#define PINMUX_AUX_GPIO_PZ4 0x28C
/* Only in T210B01 */
#define PINMUX_AUX_SDMMC2_DAT0 0x294
#define PINMUX_AUX_SDMMC2_DAT1 0x298
@ -91,6 +105,11 @@
/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */
#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))
#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))
/*! 0:I2S1, 1:I2S2 */
#define PINMUX_AUX_X_I2S_LRCK(x) (0x124 + 0x10 * (x))
#define PINMUX_AUX_X_I2C_DIN(x) (0x128 + 0x10 * (x))
#define PINMUX_AUX_X_I2C_DOUT(x) (0x12c + 0x10 * (x))
#define PINMUX_AUX_X_I2C_BCLK(x) (0x130 + 0x10 * (x))
#define PINMUX_FUNC_MASK (3 << 0)
@ -116,7 +135,10 @@
#define PINMUX_DRIVE_3X (2 << 13)
#define PINMUX_DRIVE_4X (3 << 13)
#define PINMUX_PREEMP BIT(15)
void pinmux_config_uart(u32 idx);
void pinmux_config_i2c(u32 idx);
void pinmux_config_i2s(u32 idx);
#endif

View file

@ -16,31 +16,28 @@
#include <soc/hw_init.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/util.h>
void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
{
// Lock Private key disable, Fuse write enable, MC carveout, Warmboot PA id and Warmboot address.
// Happens on T210B01 LP0 always.
if (lock_mask & PMC_SEC_LOCK_MISC)
{
PMC(APBDEV_PMC_SEC_DISABLE) |= 0x700FF0; // RW lock: 0-3.
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0xFC000000; // RW lock: 21-23.
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0x3F0FFF00; // RW lock: 28-33, 36-38.
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xC000000; // RW lock: 85.
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF00FF00; // RW lock: 108-111, 116-119.
// SE2 context.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
{
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FF; // RW lock: 120-124. (0xB38)
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150.
}
// Default: 0xFF00FF00: RW lock: 108-111, 116-119. Gets locked in LP0.
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF005500; // W lock: 108-111, RW lock: 116-119.
}
// Happens on T210B01 LP0 always.
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS)
{
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20.
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20. L4T expects 8-15 as write locked only.
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF; // RW lock: 40-50, 52-54.
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF; // RW lock: 56-71.
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F; // RW lock: 72-73, 79-84, 86-87.
@ -60,6 +57,7 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
PMC(APBDEV_PMC_SEC_DISABLE7) |= 0xFFC00000; // RW lock: 99-103.
}
// HOS specific.
if (lock_mask & PMC_SEC_LOCK_TZ_CMAC_W)
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0x550000; // W lock: 112-115.
@ -71,9 +69,34 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
if (lock_mask & PMC_SEC_LOCK_TZ_KEK_R)
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0xAA; // R lock: 24-27.
// End of HOS specific.
if (lock_mask & PMC_SEC_LOCK_SE_SRK)
PMC(APBDEV_PMC_SEC_DISABLE) |= 0xFF000; // RW lock: 4-7
if (lock_mask & PMC_SEC_LOCK_SE2_SRK_B01)
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1).
if (lock_mask & PMC_SEC_LOCK_MISC_B01)
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always.
if (lock_mask & PMC_SEC_LOCK_CARVEOUTS_L4T)
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x5555; // W: 8-15 LP0 and Carveouts. Superseded by LP0 lock.
// NVTBOOT misses APBDEV_PMC_SCRATCH_WRITE_LOCK_DISABLE_STICKY. bit0: SCRATCH_WR_DIS_ON.
// They could also use the NS write disable registers instead.
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS_B01)
{
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1) |= 0x583FF; // W lock: 24-33, 39-40, 42.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2) |= 0x1BE; // W lock: 44-48, 50-51.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3) = 0xFFFFFFFF; // W lock: 56-87.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4) |= 0xFFFFFFF; // W lock: 88-115.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5) |= 0xFFFFFFF8; // W lock: 123-151.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6) = 0xFFFFFFFF; // W lock: 152-183.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7) |= 0xFC00FFFF; // W lock: 184-199, 210-215.
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8) |= 0xF; // W lock: 216-219.
}
}
int pmc_enable_partition(pmc_power_rail_t part, u32 enable)

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* 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,
@ -22,95 +22,196 @@
#include <utils/types.h>
/*! PMC registers. */
#define APBDEV_PMC_CNTRL 0x0
#define PMC_CNTRL_MAIN_RST BIT(4)
#define APBDEV_PMC_SEC_DISABLE 0x4
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
#define APBDEV_PMC_PWRGATE_STATUS 0x38
#define APBDEV_PMC_NO_IOPOWER 0x44
#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
#define APBDEV_PMC_SCRATCH0 0x50
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
#define PMC_SCRATCH0_MODE_RCM BIT(1)
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
#define PMC_SCRATCH0_MODE_FASTBOOT BIT(30)
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
#define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
#define APBDEV_PMC_PWR_DET_VAL 0xE4
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
#define PMC_PWR_DET_AUDIO_HV BIT(18)
#define PMC_PWR_DET_GPIO_IO_EN BIT(21)
#define APBDEV_PMC_DDR_PWR 0xE8
#define APBDEV_PMC_USB_AO 0xF0
#define APBDEV_PMC_CRYPTO_OP 0xF4
#define PMC_CRYPTO_OP_SE_ENABLE 0
#define PMC_CRYPTO_OP_SE_DISABLE 1
#define APBDEV_PMC_SCRATCH33 0x120
#define APBDEV_PMC_SCRATCH37 0x130
#define PMC_SCRATCH37_KERNEL_PANIC_FLAG BIT(24)
#define APBDEV_PMC_SCRATCH40 0x13C
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
#define APBDEV_PMC_RST_STATUS 0x1B4
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
#define PMC_IO_DPD_REQ_DPD_OFF BIT(30)
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
#define APBDEV_PMC_VDDP_SEL 0x1CC
#define APBDEV_PMC_DDR_CFG 0x1D0
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
#define APBDEV_PMC_SCRATCH45 0x234
#define APBDEV_PMC_SCRATCH46 0x238
#define APBDEV_PMC_SCRATCH49 0x244
#define APBDEV_PMC_TSC_MULT 0x2B4
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
#define APBDEV_PMC_WEAK_BIAS 0x2C8
#define APBDEV_PMC_REG_SHORT 0x2CC
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT 0x10
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
#define APBDEV_PMC_CNTRL2 0x440
#define PMC_CNTRL2_HOLD_CKE_LOW_EN 0x1000
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
#define APBDEV_PMC_DDR_CNTRL 0x4E4
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
#define APBDEV_PMC_SCRATCH188 0x810
#define APBDEV_PMC_SCRATCH190 0x818
#define APBDEV_PMC_SCRATCH200 0x840
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
#define APBDEV_PMC_CNTRL 0x0
#define PMC_CNTRL_RTC_CLK_DIS BIT(1)
#define PMC_CNTRL_RTC_RST BIT(2)
#define PMC_CNTRL_MAIN_RST BIT(4)
#define PMC_CNTRL_LATCHWAKE_EN BIT(5)
#define PMC_CNTRL_BLINK_EN BIT(7)
#define PMC_CNTRL_PWRREQ_OE BIT(9)
#define PMC_CNTRL_SYSCLK_OE BIT(11)
#define PMC_CNTRL_PWRGATE_DIS BIT(12)
#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14)
#define PMC_CNTRL_CPUPWRREQ_OE BIT(16)
#define PMC_CNTRL_FUSE_OVERRIDE BIT(18)
#define PMC_CNTRL_SHUTDOWN_OE BIT(22)
#define APBDEV_PMC_SEC_DISABLE 0x4
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
#define APBDEV_PMC_PWRGATE_STATUS 0x38
#define APBDEV_PMC_NO_IOPOWER 0x44
#define PMC_NO_IOPOWER_MEM BIT(7)
#define PMC_NO_IOPOWER_SDMMC1 BIT(12)
#define PMC_NO_IOPOWER_SDMMC4 BIT(14)
#define PMC_NO_IOPOWER_MEM_COMP BIT(16)
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
#define PMC_NO_IOPOWER_GPIO BIT(21)
#define APBDEV_PMC_SCRATCH0 0x50
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
#define PMC_SCRATCH0_MODE_RCM BIT(1)
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | \
PMC_SCRATCH0_MODE_BOOTLOADER | \
PMC_SCRATCH0_MODE_PAYLOAD)
#define APBDEV_PMC_BLINK_TIMER 0x40
#define PMC_BLINK_ON(n) ((n & 0x7FFF))
#define PMC_BLINK_FORCE BIT(15)
#define PMC_BLINK_OFF(n) ((u32)(n & 0xFFFF) << 16)
#define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0 // ODM data/config scratch.
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
#define APBDEV_PMC_PWR_DET_VAL 0xE4
#define PMC_PWR_DET_33V_SDMMC1 BIT(12)
#define PMC_PWR_DET_33V_AUDIO_HV BIT(18)
#define PMC_PWR_DET_33V_GPIO BIT(21)
#define APBDEV_PMC_DDR_PWR 0xE8
#define APBDEV_PMC_USB_AO 0xF0
#define APBDEV_PMC_CRYPTO_OP 0xF4
#define PMC_CRYPTO_OP_SE_ENABLE 0
#define PMC_CRYPTO_OP_SE_DISABLE 1
#define APBDEV_PMC_PLLP_WB0_OVERRIDE 0xF8
#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE_ENABLE BIT(11)
#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
#define APBDEV_PMC_SCRATCH33 0x120
#define APBDEV_PMC_SCRATCH37 0x130
#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 // "TPAN"
#define APBDEV_PMC_SCRATCH39 0x138
#define APBDEV_PMC_SCRATCH40 0x13C
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER BIT(22)
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
#define PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN BIT(10)
#define PMC_CLK_OUT_CNTRL_CLK3_FORCE_EN BIT(18)
#define PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(src) (((src) & 3) << 6)
#define PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(src) (((src) & 3) << 14)
#define PMC_CLK_OUT_CNTRL_CLK3_SRC_SEL(src) (((src) & 3) << 22)
#define OSC_DIV1 0
#define OSC_DIV2 1
#define OSC_DIV4 2
#define OSC_CAR 3
#define APBDEV_PMC_RST_STATUS 0x1B4
#define PMC_RST_STATUS_MASK 7
#define PMC_RST_STATUS_POR 0
#define PMC_RST_STATUS_WATCHDOG 1
#define PMC_RST_STATUS_SENSOR 2
#define PMC_RST_STATUS_SW_MAIN 3
#define PMC_RST_STATUS_LP0 4
#define PMC_RST_STATUS_AOTAG 5
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
#define PMC_IO_DPD_REQ_DPD_IDLE (0 << 30u)
#define PMC_IO_DPD_REQ_DPD_OFF (1 << 30u)
#define PMC_IO_DPD_REQ_DPD_ON (2 << 30u)
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
#define APBDEV_PMC_VDDP_SEL 0x1CC
#define APBDEV_PMC_DDR_CFG 0x1D0
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
#define APBDEV_PMC_SCRATCH45 0x234
#define APBDEV_PMC_SCRATCH46 0x238
#define APBDEV_PMC_SCRATCH49 0x244
#define APBDEV_PMC_SCRATCH52 0x250
#define APBDEV_PMC_SCRATCH53 0x254
#define APBDEV_PMC_SCRATCH54 0x258
#define APBDEV_PMC_SCRATCH55 0x25C
#define APBDEV_PMC_TSC_MULT 0x2B4
#define APBDEV_PMC_STICKY_BITS 0x2C0
#define PMC_STICKY_BITS_HDA_LPBK_DIS BIT(0)
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
#define APBDEV_PMC_WEAK_BIAS 0x2C8
#define APBDEV_PMC_REG_SHORT 0x2CC
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT BIT(4)
#define APBDEV_PMC_SECURE_SCRATCH22 0x338 // AArch32 reset address.
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
#define APBDEV_PMC_SECURE_SCRATCH34 0x368 // AArch64 reset address.
#define APBDEV_PMC_SECURE_SCRATCH35 0x36C // AArch64 reset hi-address.
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
#define APBDEV_PMC_CNTRL2 0x440
#define PMC_CNTRL2_WAKE_INT_EN BIT(0)
#define PMC_CNTRL2_WAKE_DET_EN BIT(9)
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
#define APBDEV_PMC_FUSE_CONTROL 0x450
#define PMC_FUSE_CONTROL_PS18_LATCH_SET BIT(8)
#define PMC_FUSE_CONTROL_PS18_LATCH_CLR BIT(9)
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
#define APBDEV_PMC_DDR_CNTRL 0x4E4
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
#define APBDEV_PMC_SCRATCH188 0x810
#define APBDEV_PMC_SCRATCH190 0x818
#define APBDEV_PMC_SCRATCH200 0x840
#define APBDEV_PMC_SCRATCH201 0x844
#define APBDEV_PMC_SCRATCH250 0x908
#define APBDEV_PMC_SECURE_SCRATCH108 0xB08
#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C
#define APBDEV_PMC_SECURE_SCRATCH110 0xB10
#define APBDEV_PMC_SECURE_SCRATCH112 0xB18
#define APBDEV_PMC_SECURE_SCRATCH113 0xB1C
#define APBDEV_PMC_SECURE_SCRATCH114 0xB20
#define APBDEV_PMC_SECURE_SCRATCH119 0xB34
// Only in T210B01.
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE0 0xA48
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE1 0xA4C
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE2 0xA50
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE3 0xA54
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE4 0xA58
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE5 0xA5C
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE6 0xA60
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE7 0xA64
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE8 0xA68
#define APBDEV_PMC_LED_BREATHING_CTRL 0xB48
#define PMC_LED_BREATHING_CTRL_ENABLE BIT(0)
#define PMC_LED_BREATHING_CTRL_COUNTER1_EN BIT(1)
#define APBDEV_PMC_LED_BREATHING_SLOPE_STEPS 0xB4C
#define APBDEV_PMC_LED_BREATHING_ON_COUNTER 0xB50
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER1 0xB54
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER0 0xB58
#define PMC_LED_BREATHING_COUNTER_HZ 32768
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
#define PMC_LED_BREATHING_FSM_STS_IDLE 0
#define PMC_LED_BREATHING_FSM_STS_UP_RAMP 1
#define PMC_LED_BREATHING_FSM_STS_PLATEAU 2
#define PMC_LED_BREATHING_FSM_STS_DOWN_RAMP 3
#define PMC_LED_BREATHING_FSM_STS_SHORT_LOW_PERIOD 4
#define PMC_LED_BREATHING_FSM_STS_LONG_LOW_PERIOD 5
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0)
#define PMC_TZRAM_DISABLE_REG_READ BIT(1)
typedef enum _pmc_sec_lock_t
{
PMC_SEC_LOCK_MISC = BIT(0),
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
PMC_SEC_LOCK_SE_SRK = BIT(8),
PMC_SEC_LOCK_MISC = BIT(0),
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
PMC_SEC_LOCK_SE_SRK = BIT(8),
PMC_SEC_LOCK_SE2_SRK_B01 = BIT(9),
PMC_SEC_LOCK_MISC_B01 = BIT(10),
PMC_SEC_LOCK_CARVEOUTS_L4T = BIT(11),
PMC_SEC_LOCK_LP0_PARAMS_B01 = BIT(12),
} pmc_sec_lock_t;
typedef enum _pmc_power_rail_t

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* 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,
@ -19,202 +20,250 @@
#include <utils/types.h>
#define BOOTROM_BASE 0x100000
#define IRAM_BASE 0x40000000
#define HOST1X_BASE 0x50000000
#define BPMP_CACHE_BASE 0x50040000
#define DISPLAY_A_BASE 0x54200000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define TSEC_BASE 0x54500000
#define SOR1_BASE 0x54580000
#define ICTLR_BASE 0x60004000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
#define FLOW_CTLR_BASE 0x60007000
#define AHBDMA_BASE 0x60008000
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define GPIO_BASE 0x6000D000
#define GPIO_1_BASE (GPIO_BASE)
#define GPIO_2_BASE (GPIO_BASE + 0x100)
#define GPIO_3_BASE (GPIO_BASE + 0x200)
#define GPIO_4_BASE (GPIO_BASE + 0x300)
#define GPIO_5_BASE (GPIO_BASE + 0x400)
#define GPIO_6_BASE (GPIO_BASE + 0x500)
#define GPIO_7_BASE (GPIO_BASE + 0x600)
#define GPIO_8_BASE (GPIO_BASE + 0x700)
#define EXCP_VEC_BASE 0x6000F000
#define IPATCH_BASE 0x6001DC00
#define APBDMA_BASE 0x60020000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define PWM_BASE 0x7000A000
#define RTC_BASE 0x7000E000
#define PMC_BASE 0x7000E400
#define SYSCTR0_BASE 0x700F0000
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define IROM_BASE 0x100000
#define IRAM_BASE 0x40000000
#define HOST1X_BASE 0x50000000
#define BPMP_CACHE_BASE 0x50040000
#define MSELECT_BASE 0x50060000
#define DPAUX1_BASE 0x54040000
#define TSEC2_BASE 0x54100000
#define DISPLAY_A_BASE 0x54200000
#define DISPLAY_B_BASE 0x54240000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define NVJPG_BASE 0x54380000
#define NVDEC_BASE 0x54480000
#define NVENC_BASE 0x544C0000
#define TSEC_BASE 0x54500000
#define SOR1_BASE 0x54580000
#define GPU_BASE 0x57000000
#define GPU_USER_BASE 0x58000000
#define RES_SEMAPH_BASE 0x60001000
#define ARB_SEMAPH_BASE 0x60002000
#define ARB_PRI_BASE 0x60003000
#define ICTLR_BASE 0x60004000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
#define FLOW_CTLR_BASE 0x60007000
#define AHBDMA_BASE 0x60008000
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define ACTMON_BASE 0x6000C800
#define GPIO_BASE 0x6000D000
#define EXCP_VEC_BASE 0x6000F000
#define IPATCH_BASE 0x6001DC00
#define APBDMA_BASE 0x60020000
#define VGPIO_BASE 0x60024000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define PWM_BASE 0x7000A000
#define I2C_BASE 0x7000C000
#define RTC_BASE 0x7000E000
#define PMC_BASE 0x7000E400
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define TSENSOR_BASE 0x70014000
#define ATOMICS_BASE 0x70016000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define XUSB_PADCTL_BASE 0x7009F000
#define XUSB_DEV_BASE 0x700D0000
#define MIPI_CAL_BASE 0x700E3000
#define CL_DVFS_BASE 0x70110000
#define I2S_BASE 0x702D1000
#define ADMA_BASE 0x702E2000
#define TZRAM_BASE 0x7C010000
#define USB_BASE 0x7D000000
#define USB_OTG_BASE USB_BASE
#define USB1_BASE 0x7D004000
#define XUSB_DEV_BASE 0x700D0000
#define SDMMC_BASE 0x700B0000
#define SOC_THERM_BASE 0x700E2000
#define MIPI_CAL_BASE 0x700E3000
#define SYSCTR0_BASE 0x700F0000
#define SYSCTR1_BASE 0x70100000
#define CL_DVFS_BASE 0x70110000
#define APE_BASE 0x702C0000
#define AHUB_BASE 0x702D0000
#define ADMAIF_BASE 0x702D0000
#define AXBAR_BASE 0x702D0800
#define I2S_BASE 0x702D1000
#define ADMA_BASE 0x702E2000
#define SE2_BASE 0x70412000
#define SE_PKA1_BASE 0x70420000
#define TZRAM_BASE 0x7C010000
#define TZRAM_SIZE 0x10000
#define TZRAM_T210B01_SIZE 0x3C000
#define USB_BASE 0x7D000000
#define USB_OTG_BASE USB_BASE
#define USB1_BASE 0x7D004000
#define EMEM_BASE 0x80000000
#define _REG(base, off) *(vu32 *)((base) + (off))
#define MMIO_REG32(base, off) *(vu32 *)((base) + (off))
#define HOST1X(off) _REG(HOST1X_BASE, off)
#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
#define DSI(off) _REG(DSI_BASE, off)
#define VIC(off) _REG(VIC_BASE, off)
#define TSEC(off) _REG(TSEC_BASE, off)
#define SOR1(off) _REG(SOR1_BASE, off)
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off)
#define TMR(off) _REG(TMR_BASE, off)
#define CLOCK(off) _REG(CLOCK_BASE, off)
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
#define SYSREG(off) _REG(SYSREG_BASE, off)
#define AHB_GIZMO(off) _REG(SYSREG_BASE, off)
#define SB(off) _REG(SB_BASE, off)
#define GPIO(off) _REG(GPIO_BASE, off)
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
#define GPIO_3(off) _REG(GPIO_3_BASE, off)
#define GPIO_4(off) _REG(GPIO_4_BASE, off)
#define GPIO_5(off) _REG(GPIO_5_BASE, off)
#define GPIO_6(off) _REG(GPIO_6_BASE, off)
#define GPIO_7(off) _REG(GPIO_7_BASE, off)
#define GPIO_8(off) _REG(GPIO_8_BASE, off)
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
#define PWM(off) _REG(PWM_BASE, off)
#define RTC(off) _REG(RTC_BASE, off)
#define PMC(off) _REG(PMC_BASE, off)
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
#define FUSE(off) _REG(FUSE_BASE, off)
#define KFUSE(off) _REG(KFUSE_BASE, off)
#define SE(off) _REG(SE_BASE, off)
#define MC(off) _REG(MC_BASE, off)
#define EMC(off) _REG(EMC_BASE, off)
#define EMC_CH0(off) _REG(EMC0_BASE, off)
#define EMC_CH1(off) _REG(EMC1_BASE, off)
#define XUSB_HOST(off) _REG(XUSB_HOST_BASE, off)
#define XUSB_PADCTL(off) _REG(XUSB_PADCTL_BASE, off)
#define XUSB_DEV(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_XHCI(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_PCI(off) _REG(XUSB_DEV_BASE + 0x8000, off)
#define XUSB_DEV_DEV(off) _REG(XUSB_DEV_BASE + 0x9000, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)
#define I2S(off) _REG(I2S_BASE, off)
#define ADMA(off) _REG(ADMA_BASE, off)
#define USB(off) _REG(USB_BASE, off)
#define USB1(off) _REG(USB1_BASE, off)
#define TEST_REG(off) _REG(0x0, off)
#define HOST1X(off) MMIO_REG32(HOST1X_BASE, off)
#define BPMP_CACHE_CTRL(off) MMIO_REG32(BPMP_CACHE_BASE, off)
#define MSELECT(off) MMIO_REG32(MSELECT_BASE, off)
#define DPAUX1(off) MMIO_REG32(DPAUX1_BASE, off)
#define TSEC2(off) MMIO_REG32(TSEC2_BASE, off)
#define DISPLAY_A(off) MMIO_REG32(DISPLAY_A_BASE, off)
#define DISPLAY_B(off) MMIO_REG32(DISPLAY_B_BASE, off)
#define DSI(off) MMIO_REG32(DSI_BASE, off)
#define VIC(off) MMIO_REG32(VIC_BASE, off)
#define NVJPG(off) MMIO_REG32(NVJPG_BASE, off)
#define NVDEC(off) MMIO_REG32(NVDEC_BASE, off)
#define NVENC(off) MMIO_REG32(NVENC_BASE, off)
#define TSEC(off) MMIO_REG32(TSEC_BASE, off)
#define SOR1(off) MMIO_REG32(SOR1_BASE, off)
#define GPU(off) MMIO_REG32(GPU_BASE, off)
#define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
#define ARB_PRI(off) MMIO_REG32(ARB_PRI_BASE, off)
#define ICTLR(cidx, off) MMIO_REG32(ICTLR_BASE + (0x100 * (cidx)), off)
#define TMR(off) MMIO_REG32(TMR_BASE, off)
#define CLOCK(off) MMIO_REG32(CLOCK_BASE, off)
#define FLOW_CTLR(off) MMIO_REG32(FLOW_CTLR_BASE, off)
#define AHBDMA(off) MMIO_REG32(AHBDMA_BASE, off)
#define SYSREG(off) MMIO_REG32(SYSREG_BASE, off)
#define AHB_GIZMO(off) MMIO_REG32(SYSREG_BASE, off)
#define SB(off) MMIO_REG32(SB_BASE, off)
#define ACTMON(off) MMIO_REG32(ACTMON_BASE, off)
#define GPIO(off) MMIO_REG32(GPIO_BASE, off)
#define EXCP_VEC(off) MMIO_REG32(EXCP_VEC_BASE, off)
#define APBDMA(off) MMIO_REG32(APBDMA_BASE, off)
#define VGPIO(off) MMIO_REG32(VGPIO_BASE, off)
#define APB_MISC(off) MMIO_REG32(APB_MISC_BASE, off)
#define PINMUX_AUX(off) MMIO_REG32(PINMUX_AUX_BASE, off)
#define PWM(off) MMIO_REG32(PWM_BASE, off)
#define RTC(off) MMIO_REG32(RTC_BASE, off)
#define PMC(off) MMIO_REG32(PMC_BASE, off)
#define SYSCTR0(off) MMIO_REG32(SYSCTR0_BASE, off)
#define SYSCTR1(off) MMIO_REG32(SYSCTR1_BASE, off)
#define FUSE(off) MMIO_REG32(FUSE_BASE, off)
#define KFUSE(off) MMIO_REG32(KFUSE_BASE, off)
#define SE(off) MMIO_REG32(SE_BASE, off)
#define MC(off) MMIO_REG32(MC_BASE, off)
#define EMC(off) MMIO_REG32(EMC_BASE, off)
#define EMC_CH0(off) MMIO_REG32(EMC0_BASE, off)
#define EMC_CH1(off) MMIO_REG32(EMC1_BASE, off)
#define XUSB_HOST(off) MMIO_REG32(XUSB_HOST_BASE, off)
#define XUSB_PADCTL(off) MMIO_REG32(XUSB_PADCTL_BASE, off)
#define XUSB_DEV(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define XUSB_DEV_XHCI(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define XUSB_DEV_PCI(off) MMIO_REG32(XUSB_DEV_BASE + 0x8000, off)
#define XUSB_DEV_DEV(off) MMIO_REG32(XUSB_DEV_BASE + 0x9000, off)
#define MIPI_CAL(off) MMIO_REG32(MIPI_CAL_BASE, off)
#define CL_DVFS(off) MMIO_REG32(CL_DVFS_BASE, off)
#define I2S(off) MMIO_REG32(I2S_BASE, off)
#define ADMA(off) MMIO_REG32(ADMA_BASE, off)
#define SE2(off) MMIO_REG32(SE2_BASE, off)
#define SE_PKA1(off) MMIO_REG32(SE_PKA1_BASE, off)
#define USB(off) MMIO_REG32(USB_BASE, off)
#define USB1(off) MMIO_REG32(USB1_BASE, off)
#define TEST_REG(off) MMIO_REG32(0x0, off)
/* HOST1X registers. */
#define HOST1X_CH0_SYNC_BASE 0x2100
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4)
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200)
/* HOST1X v3 registers. */
#define HOST1X_CH0_SYNC_BASE 0x2100
#define HOST1X_CH0_SYNC_SYNCPT_BASE (HOST1X_CH0_SYNC_BASE + 0xF80)
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x24)
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x280)
/*! EVP registers. */
#define EVP_CPU_RESET_VECTOR 0x100
#define EVP_COP_RESET_VECTOR 0x200
#define EVP_COP_UNDEF_VECTOR 0x204
#define EVP_COP_SWI_VECTOR 0x208
#define EVP_CPU_RESET_VECTOR 0x100
#define EVP_COP_RESET_VECTOR 0x200
#define EVP_COP_UNDEF_VECTOR 0x204
#define EVP_COP_SWI_VECTOR 0x208
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
#define EVP_COP_DATA_ABORT_VECTOR 0x210
#define EVP_COP_RSVD_VECTOR 0x214
#define EVP_COP_IRQ_VECTOR 0x218
#define EVP_COP_FIQ_VECTOR 0x21C
#define EVP_COP_IRQ_STS 0x220
#define EVP_COP_DATA_ABORT_VECTOR 0x210
#define EVP_COP_RSVD_VECTOR 0x214
#define EVP_COP_IRQ_VECTOR 0x218
#define EVP_COP_FIQ_VECTOR 0x21C
#define EVP_COP_IRQ_STS 0x220
/*! Primary Interrupt Controller registers. */
#define PRI_ICTLR_FIR 0x14
#define PRI_ICTLR_FIR_SET 0x18
#define PRI_ICTLR_FIR_CLR 0x1C
#define PRI_ICTLR_CPU_IER 0x20
#define PRI_ICTLR_CPU_IER_SET 0x24
#define PRI_ICTLR_CPU_IER_CLR 0x28
#define PRI_ICTLR_ISR 0x10
#define PRI_ICTLR_FIR 0x14
#define PRI_ICTLR_FIR_SET 0x18
#define PRI_ICTLR_FIR_CLR 0x1C
#define PRI_ICTLR_CPU_IER 0x20
#define PRI_ICTLR_CPU_IER_SET 0x24
#define PRI_ICTLR_CPU_IER_CLR 0x28
#define PRI_ICTLR_CPU_IEP_CLASS 0x2C
#define PRI_ICTLR_COP_IER 0x30
#define PRI_ICTLR_COP_IER_SET 0x34
#define PRI_ICTLR_COP_IER_CLR 0x38
#define PRI_ICTLR_COP_IER 0x30
#define PRI_ICTLR_COP_IER_SET 0x34
#define PRI_ICTLR_COP_IER_CLR 0x38
#define PRI_ICTLR_COP_IEP_CLASS 0x3C
/* Arbiter registers */
#define ARB_PRIO_CPU_PRIORITY 0x0
#define ARB_PRIO_COP_PRIORITY 0x4
#define ARB_PRIO_VCP_PRIORITY 0x8
#define ARB_PRIO_DMA_PRIORITY 0xC
#define ARB_PRIO_UCQ_PRIORITY 0x10
/*! AHB Gizmo registers. */
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
#define AHB_GIZMO_AHB_MEM 0x10
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
#define AHB_MEM_IMMEDIATE BIT(18)
#define AHB_GIZMO_APB_DMA 0x14
#define AHB_GIZMO_USB 0x20
#define AHB_GIZMO_SDMMC4 0x48
#define AHB_GIZMO_USB2 0x7C
#define AHB_GIZMO_USB3 0x80
#define AHB_GIZMO_IMMEDIATE BIT(18)
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
#define MST_ID(x) (((x) & 0x1F) << 26)
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
#define MEM_PREFETCH_ENABLE BIT(31)
#define AHB_AHB_SPARE_REG 0x110
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
#define AHB_GIZMO_AHB_MEM 0x10
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
#define AHB_MEM_IMMEDIATE BIT(18)
#define AHB_GIZMO_APB_DMA 0x14
#define AHB_GIZMO_USB 0x20
#define AHB_GIZMO_SDMMC4 0x48
#define AHB_GIZMO_USB2 0x7C
#define AHB_GIZMO_USB3 0x80
#define AHB_GIZMO_IMMEDIATE BIT(18)
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
#define MST_ID(x) (((x) & 0x1F) << 26)
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
#define MEM_PREFETCH_ENABLE BIT(31)
#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC
#define MEM_WRQUE_SE_MST_ID BIT(14)
#define AHB_AHB_SPARE_REG 0x110
/*! Misc registers. */
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
#define APB_MISC_GP_HIDREV 0x804
#define GP_HIDREV_MAJOR_T210 0x1
#define GP_HIDREV_MAJOR_T210B01 0x2
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
#define APB_MISC_PP_STRAPPING_OPT_A 0x8
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
#define APB_MISC_GP_HIDREV 0x804
#define GP_HIDREV_MAJOR_T210 0x1
#define GP_HIDREV_MAJOR_T210B01 0x2
#define APB_MISC_GP_ASDBGREG 0x810
#define APB_MISC_GP_TRANSACTOR_SCRATCH 0x864
#define APB_MISC_GP_AVP_TRANSACTOR_SCRATCH 0x880
#define APB_MISC_GP_CPU0_TRANSACTOR_SCRATCH 0x884
#define APB_MISC_GP_CPU1_TRANSACTOR_SCRATCH 0x888
#define APB_MISC_GP_CPU2_TRANSACTOR_SCRATCH 0x88C
#define APB_MISC_GP_CPU3_TRANSACTOR_SCRATCH 0x890
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
#define APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL 0xABC
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
/*! Secure boot registers. */
#define SB_CSR 0x0
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
#define SB_CSR_PIROM_DISABLE BIT(4)
#define SB_AA64_RESET_LOW 0x30
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
#define SB_AA64_RESET_HIGH 0x34
#define SB_CSR 0x0
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
#define SB_CSR_PIROM_DISABLE BIT(4)
#define SB_AA64_RESET_LOW 0x30
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
#define SB_AA64_RESET_HIGH 0x34
/*! SOR registers. */
#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8
#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB 0x208
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB 0x20C
#define SOR_DP_HDCP_BKSV_LSB 0x1E8
#define SOR_TMDS_HDCP_BKSV_LSB 0x21C
#define SOR_TMDS_HDCP_CN_MSB 0x208
#define SOR_TMDS_HDCP_CN_LSB 0x20C
/*! RTC registers. */
#define APBDEV_RTC_SECONDS 0x8
@ -222,42 +271,28 @@
#define APBDEV_RTC_MILLI_SECONDS 0x10
/*! SYSCTR0 registers. */
#define SYSCTR0_CNTFID0 0x20
#define SYSCTR0_CNTCR 0x00
#define SYSCTR0_COUNTERID0 0xFE0
#define SYSCTR0_COUNTERID1 0xFE4
#define SYSCTR0_COUNTERID2 0xFE8
#define SYSCTR0_COUNTERID3 0xFEC
#define SYSCTR0_COUNTERID4 0xFD0
#define SYSCTR0_COUNTERID5 0xFD4
#define SYSCTR0_COUNTERID6 0xFD8
#define SYSCTR0_COUNTERID7 0xFDC
#define SYSCTR0_COUNTERID8 0xFF0
#define SYSCTR0_COUNTERID9 0xFF4
#define SYSCTR0_COUNTERID10 0xFF8
#define SYSCTR0_COUNTERID11 0xFFC
#define SYSCTR0_CNTCR 0x00
#define SYSCTR0_CNTFID0 0x20
#define SYSCTR0_COUNTERS_BASE 0xFD0
#define SYSCTR0_COUNTERS 12
#define SYSCTR0_COUNTERID0 0xFE0
#define SYSCTR0_COUNTERID1 0xFE4
#define SYSCTR0_COUNTERID2 0xFE8
#define SYSCTR0_COUNTERID3 0xFEC
#define SYSCTR0_COUNTERID4 0xFD0
#define SYSCTR0_COUNTERID5 0xFD4
#define SYSCTR0_COUNTERID6 0xFD8
#define SYSCTR0_COUNTERID7 0xFDC
#define SYSCTR0_COUNTERID8 0xFF0
#define SYSCTR0_COUNTERID9 0xFF4
#define SYSCTR0_COUNTERID10 0xFF8
#define SYSCTR0_COUNTERID11 0xFFC
/*! TMR registers. */
#define TIMERUS_CNTR_1US (0x10 + 0x0)
#define TIMERUS_USEC_CFG (0x10 + 0x4)
#define TIMER_TMR8_TMR_PTV 0x78
#define TIMER_TMR9_TMR_PTV 0x80
#define TIMER_PER_EN BIT(30)
#define TIMER_EN BIT(31)
#define TIMER_TMR8_TMR_PCR 0x7C
#define TIMER_TMR9_TMR_PCR 0x8C
#define TIMER_INTR_CLR BIT(30)
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
#define TIMER_SRC(TMR) ((TMR) & 0xF)
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
#define TIMER_SYSRESET_EN BIT(14)
#define TIMER_PMCRESET_EN BIT(15)
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
#define TIMER_START_CNT BIT(0)
#define TIMER_CNT_DISABLE BIT(1)
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
#define TIMER_MAGIC_PTRN 0xC45A
/*! IPATCH registers. */
#define IPATCH_CAM_VALID 0x0
#define IPATCH_CAM_BASE 0x4
#define IPATCH_CAM(i) (IPATCH_CAM_BASE + (i) * 4)
#define IPATCH_CAM_ENTRIES 12
/*! I2S registers. */
#define I2S1_CG 0x88
@ -283,25 +318,60 @@
#define EMC_HEKA_UPD BIT(30)
/*! Flow controller registers. */
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define HALT_COP_GIC_IRQ BIT(9)
#define HALT_COP_LIC_IRQ BIT(11)
#define HALT_COP_SEC BIT(23)
#define HALT_COP_MSEC BIT(24)
#define HALT_COP_USEC BIT(25)
#define HALT_COP_JTAG BIT(28)
#define HALT_COP_WAIT_EVENT BIT(30)
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
#define HALT_COP_MAX_CNT 0xFF
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_CPU1_CSR 0x18
#define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define FLOW_CTLR_RAM_REPAIR 0x40
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define HALT_GIC_IRQ BIT(9)
#define HALT_LIC_IRQ BIT(11)
#define HALT_SEC BIT(23)
#define HALT_MSEC BIT(24)
#define HALT_USEC BIT(25)
#define HALT_JTAG BIT(28)
#define HALT_MODE_NONE (0 << 29u)
#define HALT_MODE_RUN_AND_INT (1 << 29u)
#define HALT_MODE_WAITEVENT (2 << 29u)
#define HALT_MODE_WAITEVENT_AND_INT (3 << 29u)
#define HALT_MODE_STOP_UNTIL_IRQ (4 << 29u)
#define HALT_MODE_STOP_UNTIL_IRQ_AND_INT (5 << 29u)
#define HALT_MODE_STOP_UNTIL_EVENT_AND_IRQ (6 << 29u)
#define HALT_MAX_CNT 0xFF
#define FLOW_CTLR_COP_CSR 0xC
#define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_CPU1_CSR 0x18
#define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define CSR_ENABLE BIT(0)
#define CSR_WAIT_WFI_NONE (0 << 8u)
#define CSR_WAIT_WFI_CPU0 (BIT(0) << 8u)
#define CSR_ENABLE_EXT_CPU_ONLY (0 << 12u)
#define CSR_ENABLE_EXT_CPU_NCPU (1 << 12u)
#define CSR_ENABLE_EXT_CPU_RAIL (2 << 12u)
#define CSR_EVENT_FLAG BIT(14)
#define CSR_INTR_FLAG BIT(15)
#define CSR_HALT BIT(22)
#define FLOW_CTLR_CPU_PWR_CSR 0x38
#define CPU_PWR_RAIL_STS_MASK (3 << 1u)
#define CPU_PWR_RAIL_OFF 0
#define FLOW_CTLR_RAM_REPAIR 0x40
#define RAM_REPAIR_REQ BIT(0)
#define RAM_REPAIR_STS BIT(1)
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
/* MSelect registers */
#define MSELECT_CONFIG 0x00
#define MSELECT_CFG_ERR_RESP_EN_PCIE BIT(24)
#define MSELECT_CFG_ERR_RESP_EN_GPU BIT(25)
#define MSELECT_CFG_WRAP_TO_INCR_BPMP BIT(27)
#define MSELECT_CFG_WRAP_TO_INCR_PCIE BIT(28)
#define MSELECT_CFG_WRAP_TO_INCR_GPU BIT(29)
/* NVDEC registers */
#define NVDEC_SA_KEYSLOT_FALCON 0x2100
#define NVDEC_SA_KEYSLOT_TZ 0x2104
#define NVDEC_SA_KEYSLOT_OTF 0x210C
#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118
#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C
#endif

123
bdk/soc/timer.c Normal file
View file

@ -0,0 +1,123 @@
/*
* Timer/Watchdog driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <soc/bpmp.h>
#include <soc/irq.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/types.h>
#define EXCP_TYPE_ADDR 0x4003FFF8
#define EXCP_TYPE_WDT 0x544457 // "WDT".
#define USE_RTC_TIMER
u32 get_tmr_s()
{
(void)RTC(APBDEV_RTC_MILLI_SECONDS);
return (u32)RTC(APBDEV_RTC_SECONDS);
}
u32 get_tmr_ms()
{
// The registers must be read with the following order:
// RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
return (u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000));
}
u32 get_tmr_us()
{
return (u32)TMR(TIMERUS_CNTR_1US);
}
void msleep(u32 ms)
{
#ifdef USE_RTC_TIMER
u32 start = (u32)RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000);
// Casting to u32 is important!
while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms)
;
#else
bpmp_msleep(ms);
#endif
}
void usleep(u32 us)
{
#ifdef USE_RTC_TIMER
u32 start = (u32)TMR(TIMERUS_CNTR_1US);
// Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately.
if ((start + us) < start)
bpmp_usleep(us);
else
while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important!
;
#else
bpmp_usleep(us);
#endif
}
// Instruction wait loop. Each loop is 3 cycles (SUBS+BGT). Usage: isleep(ILOOP(instr)). Base 408MHz: 7.35ns.
void __attribute__((target("arm"))) isleep(u32 is)
{
asm volatile( "0:" "SUBS %[is_cnt], #1;" "BGT 0b;" : [is_cnt] "+r" (is));
}
void timer_usleep(u32 us)
{
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;
irq_wait_event(IRQ_TMR8);
TMR(TIMER_TMR8_TMR_PCR) = TIMER_INTR_CLR;
}
void watchdog_start(u32 us, u32 mode)
{
// WDT4 is for BPMP.
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN | us;
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | mode;
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
}
void watchdog_end()
{
// WDT4 is for BPMP.
TMR(TIMER_TMR9_TMR_PTV) = 0;
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; // Re-arm to clear any interrupts.
TMR(TIMER_WDT4_COMMAND) = TIMER_CNT_DISABLE;
TMR(TIMER_TMR9_TMR_PCR) = TIMER_INTR_CLR;
}
void watchdog_handle()
{
// Disable watchdog and clear its interrupts.
watchdog_end();
// Set watchdog magic.
*(u32 *)EXCP_TYPE_ADDR = EXCP_TYPE_WDT;
}
bool watchdog_fired()
{
// Return if watchdog got fired. User handles clearing.
return (*(u32 *)EXCP_TYPE_ADDR == EXCP_TYPE_WDT);
}

64
bdk/soc/timer.h Normal file
View file

@ -0,0 +1,64 @@
/*
* Timer/Watchdog driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include <utils/types.h>
// TMR registers.
#define TIMERUS_CNTR_1US (0x10 + 0x0)
#define TIMERUS_USEC_CFG (0x10 + 0x4)
#define TIMER_TMR8_TMR_PTV 0x78
#define TIMER_TMR9_TMR_PTV 0x80
#define TIMER_PER_EN BIT(30)
#define TIMER_EN BIT(31)
#define TIMER_TMR8_TMR_PCR 0x7C
#define TIMER_TMR9_TMR_PCR 0x8C
#define TIMER_INTR_CLR BIT(30)
// WDT registers.
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
#define TIMER_SRC(TMR) ((TMR) & 0xF)
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
#define TIMER_IRQENABL_EN BIT(12)
#define TIMER_FIQENABL_EN BIT(13)
#define TIMER_SYSRESET_EN BIT(14)
#define TIMER_PMCRESET_EN BIT(15)
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
#define TIMER_START_CNT BIT(0)
#define TIMER_CNT_DISABLE BIT(1)
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
#define TIMER_MAGIC_PTRN 0xC45A
u32 get_tmr_us();
u32 get_tmr_ms();
u32 get_tmr_s();
void usleep(u32 us);
void msleep(u32 ms);
#define ILOOP(is) ((is) / 3)
void isleep(u32 is);
void timer_usleep(u32 us);
void watchdog_start(u32 us, u32 mode);
void watchdog_end();
void watchdog_handle();
bool watchdog_fired();
#endif

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2020 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,
@ -17,62 +17,75 @@
#include <soc/uart.h>
#include <soc/clock.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/util.h>
/* UART A, B, C, D and E. */
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
static const u16 _uart_base_offsets[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
void uart_init(u32 idx, u32 baud)
void uart_init(u32 idx, u32 baud, u32 mode)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
// Make sure no data is being sent.
uart_wait_idle(idx, UART_TX_IDLE);
if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR)))
uart_wait_xfer(idx, UART_TX_IDLE);
// Set clock.
bool clk_type = clock_uart_use_src_div(idx, baud);
// 2 STOP bits for rates > 1M. (Reduced efficiency but less errors on high baudrates).
u32 uart_lcr_stop = baud > 1000000 ? UART_LCR_STOP : 0;
// Misc settings.
u32 div = clk_type ? ((8 * baud + 408000000) / (16 * baud)) : 1; // DIV_ROUND_CLOSEST.
uart->UART_IER_DLAB = 0; // Disable interrupts.
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
uart->UART_IER_DLAB = (u8)(div >> 8); // Divisor latch MSB.
uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Disable DLAB.
// Disable DLAB and set STOP bits setting if applicable.
uart->UART_LCR = uart_lcr_stop | UART_LCR_WORD_LENGTH_8;
(void)uart->UART_SPR;
// Setup and flush fifo.
// Enable fifo.
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO;
(void)uart->UART_SPR;
usleep(20);
uart->UART_MCR = 0; // Disable hardware flow control.
// Disable hardware flow control.
uart->UART_MCR = 0;
usleep(96);
// Clear tx/rx fifos.
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR;
// Set hardware flow control.
uart->UART_MCR = mode;
// Wait 3 symbols for baudrate change.
usleep(3 * ((baud + 999999) / baud));
uart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE);
uart_wait_xfer(idx, UART_TX_IDLE | UART_RX_RDYR);
}
void uart_wait_idle(u32 idx, u32 which)
void uart_wait_xfer(u32 idx, u32 which)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (UART_TX_IDLE & which)
{
while (!(uart->UART_LSR & UART_LSR_TMTY))
;
}
if (UART_RX_IDLE & which)
if (UART_RX_RDYR & which)
{
while (uart->UART_LSR & UART_LSR_RDR)
;
(void)uart->UART_THR_DLAB;
}
}
void uart_send(u32 idx, const u8 *buf, u32 len)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
for (u32 i = 0; i != len; i++)
{
@ -84,32 +97,37 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
u32 uart_recv(u32 idx, u8 *buf, u32 len)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
bool manual_mode = uart->UART_MCR & UART_MCR_RTS;
u32 timeout = get_tmr_us() + 250;
u32 i;
if (manual_mode)
uart->UART_MCR &= ~UART_MCR_RTS;
for (i = 0; ; i++)
{
while (!(uart->UART_LSR & UART_LSR_RDR))
{
if (timeout < get_tmr_us())
break;
if (len && len < i)
break;
}
if (timeout < get_tmr_us())
if (len && len <= i)
break;
while (!(uart->UART_LSR & UART_LSR_RDR))
if (timeout < get_tmr_us())
goto out;
buf[i] = uart->UART_THR_DLAB;
timeout = get_tmr_us() + 250;
}
return i ? (len ? (i - 1) : i) : 0;
out:
if (manual_mode)
uart->UART_MCR |= UART_MCR_RTS;
return i;
}
void uart_invert(u32 idx, bool enable, u32 invert_mask)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (enable)
uart->UART_IRDA_CSR |= invert_mask;
@ -118,9 +136,17 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask)
(void)uart->UART_SPR;
}
void uart_set_mode(u32 idx, u32 mode)
{
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_MCR = mode;
(void)uart->UART_SPR;
}
u32 uart_get_IIR(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
u32 iir = uart->UART_IIR_FCR & UART_IIR_INT_MASK;
@ -132,7 +158,7 @@ u32 uart_get_IIR(u32 idx)
void uart_set_IIR(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD;
(void)uart->UART_SPR;
@ -142,20 +168,20 @@ void uart_set_IIR(u32 idx)
void uart_empty_fifo(u32 idx, u32 which)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_MCR = 0;
(void)uart->UART_SPR;
usleep(96);
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR;
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | which;
(void)uart->UART_SPR;
usleep(18);
u32 tries = 0;
if (UART_IIR_FCR_TX_CLR & which)
{
while (tries < 10 && uart->UART_LSR & UART_LSR_TMTY)
while (tries < 10 && !(uart->UART_LSR & UART_LSR_TMTY))
{
tries++;
usleep(100);
@ -165,10 +191,31 @@ void uart_empty_fifo(u32 idx, u32 which)
if (UART_IIR_FCR_RX_CLR & which)
{
while (tries < 10 && !uart->UART_LSR & UART_LSR_RDR)
while (tries < 10 && (uart->UART_LSR & UART_LSR_RDR))
{
tries++;
usleep(100);
}
}
}
#ifdef DEBUG_UART_PORT
#include <stdarg.h>
#include <string.h>
#include <utils/sprintf.h>
void uart_printf(const char *fmt, ...)
{
va_list ap;
//! NOTE: Anything more and it will hang. Heap usage is out of the question.
char text[256];
va_start(ap, fmt);
s_vprintf(text, fmt, ap);
va_end(ap);
uart_send(DEBUG_UART_PORT, (u8 *)text, strlen(text));
}
#endif

Some files were not shown because too many files have changed in this diff Show more