Compare commits

...

75 Commits
emmc ... master

Author SHA1 Message Date
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
66 changed files with 1172 additions and 884 deletions

View File

@ -188,20 +188,26 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
```
hekate (c) 2018, naehrwert, st4rk.
(c) 2018-2023, CTCaer.
(c) 2018-2024, CTCaer.
Nyx GUI (c) 2019-2023, 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

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

View File

@ -373,24 +373,10 @@ void display_init()
// Get Chip ID.
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
// T210B01: Power on SD2 regulator for supplying LDO0.
if (!tegra_t210)
{
// Set SD2 regulator voltage.
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
// Set slew rate and enable SD2 regulator.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
max7762x_regulator_enable(REGULATOR_SD2, true);
}
// Enable LCD DVDD.
// Enable DSI AVDD.
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
max7762x_regulator_enable(REGULATOR_LDO0, true);
if (tegra_t210)
max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> LCD.
// Enable Display Interface specific clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
@ -448,26 +434,19 @@ void display_init()
clock_enable_plld(3, 20, true, tegra_t210);
// Setup Display Interface initial window configuration.
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, CFG_SIZE(_di_dc_setup_win_config));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, ARRAY_SIZE(_di_dc_setup_win_config));
// Setup dsi init sequence packets.
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config0, CFG_SIZE(_di_dsi_init_irq_pkt_config0));
if (tegra_t210)
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
else
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config1, CFG_SIZE(_di_dsi_init_irq_pkt_config1));
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_config0, ARRAY_SIZE(_di_dsi_init_config0));
DSI(_DSIREG(tegra_t210 ? DSI_INIT_SEQ_DATA_15 : DSI_INIT_SEQ_DATA_15_B01)) = 0;
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_config1, ARRAY_SIZE(_di_dsi_init_config1));
// Reset pad trimmers for T210B01.
if (!tegra_t210)
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, CFG_SIZE(_di_dsi_init_pads_t210b01));
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, ARRAY_SIZE(_di_dsi_init_pads_t210b01));
// Setup init sequence packets and timings.
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config2, CFG_SIZE(_di_dsi_init_timing_pkt_config2));
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3.
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pwrctrl_config, CFG_SIZE(_di_dsi_init_timing_pwrctrl_config));
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3.
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config3, CFG_SIZE(_di_dsi_init_timing_pkt_config3));
// Setup init sequence packets, timings and power on DSI.
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_config2, ARRAY_SIZE(_di_dsi_init_config2));
usleep(10000);
// Enable LCD Reset.
@ -505,9 +484,9 @@ void display_init()
{
case PANEL_SAM_AMS699VC01:
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
// Set color mode to natural. Stock is Saturated (0x00). (Reset value is 0x20).
// Set color mode to basic (natural). Stock is Saturated (0x00). (Reset value is 0x20).
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_NATURAL << 8), 0);
MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_BASIC << 8), 0);
// Enable backlight and smooth PWM.
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM,
MIPI_DCS_SET_CONTROL_DISPLAY | ((DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL) << 8), 0);
@ -537,7 +516,7 @@ void display_init()
break;
case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, CFG_SIZE(_di_dsi_panel_init_config_jdi));
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, ARRAY_SIZE(_di_dsi_panel_init_config_jdi));
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
break;
@ -578,21 +557,24 @@ void display_init()
clock_enable_plld(1, 24, false, tegra_t210);
// Finalize DSI init packet sequence configuration.
DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
exec_cfg((u32 *)DSI_BASE, _di_dsi_init_seq_pkt_final_config, CFG_SIZE(_di_dsi_init_seq_pkt_final_config));
reg_write_array((u32 *)DSI_BASE, _di_dsi_init_seq_pkt_final_config, ARRAY_SIZE(_di_dsi_init_seq_pkt_final_config));
// Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate.
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
// Set DSI mode.
exec_cfg((u32 *)DSI_BASE, _di_dsi_mode_config, CFG_SIZE(_di_dsi_mode_config));
reg_write_array((u32 *)DSI_BASE, _di_dsi_mode_config, ARRAY_SIZE(_di_dsi_mode_config));
usleep(10000);
// Calibrate display communication pads.
u32 loops = tegra_t210 ? 1 : 2; // Calibrate pads 2 times on T210B01.
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, CFG_SIZE(_di_mipi_pad_cal_config));
for (u32 i = 0; i < loops; i++)
/*
* Calibrate display communication pads.
* When switching to the 16ff pad brick, the clock lane termination control
* is separated from data lane termination. This change of the mipi cal
* brings in a bug that the DSI pad clock termination code can't be loaded
* in one time calibration. Trigger calibration twice.
*/
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, ARRAY_SIZE(_di_mipi_pad_cal_config));
for (u32 i = 0; i < 2; i++)
{
// Set MIPI bias pad config.
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
@ -601,22 +583,25 @@ void display_init()
// Set pad trimmers and set MIPI DSI cal offsets.
if (tegra_t210)
{
exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, CFG_SIZE(_di_dsi_pad_cal_config_t210));
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210));
reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, ARRAY_SIZE(_di_dsi_pad_cal_config_t210));
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210));
}
else
{
exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, CFG_SIZE(_di_dsi_pad_cal_config_t210b01));
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210b01, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210b01));
reg_write_array((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, ARRAY_SIZE(_di_dsi_pad_cal_config_t210b01));
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_prod_config_t210b01, ARRAY_SIZE(_di_mipi_dsi_cal_prod_config_t210b01));
}
// Reset all MIPI cal offsets and start calibration.
exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_start_dsi_cal_config, CFG_SIZE(_di_mipi_start_dsi_cal_config));
// Reset all unused MIPI cal offsets.
reg_write_array((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_unused_config, ARRAY_SIZE(_di_mipi_dsi_cal_unused_config));
// Set Prescale/filter and start calibration.
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_CAL_CTRL)) = 0x2A000001;
}
usleep(10000);
// Enable video display controller.
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, CFG_SIZE(_di_dc_video_enable_config));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, ARRAY_SIZE(_di_dc_video_enable_config));
}
void display_backlight_pwm_init()
@ -624,12 +609,15 @@ void display_backlight_pwm_init()
if (_display_id == PANEL_SAM_AMS699VC01)
return;
// Enable PWM clock.
clock_enable_pwm();
// Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN;
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
usleep(2);
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
}
@ -650,9 +638,9 @@ static void _display_dsi_backlight_brightness(u32 duty)
u16 bl_ctrl = byte_swap_16((u16)candela);
display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
// Wait for backlight to completely turn off. 6+1 frames.
// Wait for backlight to completely turn off. 6 frames.
if (!duty)
usleep(120000);
usleep(100000);
_dsi_bl = duty;
}
@ -696,7 +684,10 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
u32 display_get_backlight_brightness()
{
if (_display_id != PANEL_SAM_AMS699VC01)
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
else
return _dsi_bl;
}
static void _display_panel_and_hw_end(bool no_panel_deinit)
@ -713,14 +704,15 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
// Wait for 5 frames (HOST1X_CH0_SYNC_SYNCPT_9).
// Not here.
// Not here. Wait for 1 frame manually.
usleep(20000);
// Propagate changes to all register buffers and disable host cmd packets during video.
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX_ACTIVE | WRITE_MUX_ACTIVE;
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
// De-initialize video controller.
exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, CFG_SIZE(_di_dc_video_disable_config));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, ARRAY_SIZE(_di_dc_video_disable_config));
// Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
@ -728,7 +720,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210);
// Set timings for lowpower clocks.
exec_cfg((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, CFG_SIZE(_di_dsi_timing_deinit_config));
reg_write_array((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, ARRAY_SIZE(_di_dsi_timing_deinit_config));
if (_display_id != PANEL_SAM_AMS699VC01)
usleep(10000);
@ -737,11 +729,11 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
switch (_display_id)
{
case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, CFG_SIZE(_di_dsi_panel_deinit_config_jdi));
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, ARRAY_SIZE(_di_dsi_panel_deinit_config_jdi));
break;
case PANEL_AUO_A062TAN01:
exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, CFG_SIZE(_di_dsi_panel_deinit_config_auo));
reg_write_array((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, ARRAY_SIZE(_di_dsi_panel_deinit_config_auo));
break;
case PANEL_INL_2J055IA_27A:
@ -796,6 +788,10 @@ skip_panel_deinit:
{
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD AVDD -5.4V disable.
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD AVDD +5.4V disable.
// Make sure LCD PWM backlight pin is in PWM0 mode.
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode.
}
usleep(10000);
@ -810,14 +806,7 @@ skip_panel_deinit:
DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
// Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
if (!_nx_aula)
{
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode.
}
// Disable LCD DVDD.
// Disable DSI AVDD.
max7762x_regulator_enable(REGULATOR_LDO0, false);
}
@ -846,14 +835,15 @@ void display_set_decoded_panel_id(u32 id)
void display_color_screen(u32 color)
{
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_one_color, CFG_SIZE(_di_win_one_color));
// Disable all windows.
reg_write_array((u32 *)DISPLAY_A_BASE, _di_win_one_color, ARRAY_SIZE(_di_win_one_color));
// Configure display to show single color.
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE | WIN_D_UPDATE;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ | WIN_D_ACT_REQ;
usleep(35000); // Wait 2 frames. No need on Aula.
if (_display_id != PANEL_SAM_AMS699VC01)
@ -862,58 +852,108 @@ void display_color_screen(u32 color)
display_backlight_brightness(150, 0);
}
u32 *display_init_framebuffer_pitch()
u32 *display_init_window_a_pitch()
{
// Sanitize framebuffer area.
memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ);
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch, CFG_SIZE(_di_win_framebuffer_pitch));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch, ARRAY_SIZE(_di_winA_pitch));
//usleep(35000); // Wait 2 frames. No need on Aula.
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_pitch_vic()
u32 *display_init_window_a_pitch_vic()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
if (_display_id != PANEL_SAM_AMS699VC01)
usleep(8000); // Wait half frame for PWM to apply.
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_vic, CFG_SIZE(_di_win_framebuffer_pitch_vic));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_vic, ARRAY_SIZE(_di_winA_pitch_vic));
if (_display_id != PANEL_SAM_AMS699VC01)
usleep(35000); // Wait 2 frames.
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_pitch_inv()
u32 *display_init_window_a_pitch_inv()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_inv, CFG_SIZE(_di_win_framebuffer_pitch_inv));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_pitch_inv, ARRAY_SIZE(_di_winA_pitch_inv));
usleep(35000); // Wait 2 frames. No need on Aula.
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_block()
u32 *display_init_window_a_block()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280.
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_block, CFG_SIZE(_di_win_framebuffer_block));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winA_block, ARRAY_SIZE(_di_winA_block));
usleep(35000); // Wait 2 frames. No need on Aula.
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_log()
u32 *display_init_window_d_console()
{
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_log, CFG_SIZE(_di_win_framebuffer_log));
reg_write_array((u32 *)DISPLAY_A_BASE, _di_winD_log, ARRAY_SIZE(_di_winD_log));
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
void display_activate_console()
void display_window_disable(u32 window)
{
// Select window C.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
// Disable window C.
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0;
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
}
void display_set_framebuffer(u32 window, void *fb)
{
// Select window.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
// Set new fb address.
DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
}
void display_move_framebuffer(u32 window, void *fb)
{
// Select window.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = BIT(WINDOW_SELECT + window);
// Get current framebuffer address.
void *fb_curr = (void *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
u32 win_size = DISPLAY_A(_DIREG(DC_WIN_PRESCALED_SIZE));
win_size = (win_size & 0x7FFF) * ((win_size >> 16) & 0x1FFF);
// Copy fb over.
memcpy(fb, fb_curr, win_size);
// Set new fb address.
DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)) = (u32)fb;
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | BIT(WIN_UPDATE + window);
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | BIT(WIN_ACT_REQ + window);
}
void display_window_d_console_enable()
{
// Only update active registers on vsync.
DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_REG_ACT_CONTROL)) & ~WIN_D_ACT_HCNTR_SEL;
// Select window D.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
@ -942,12 +982,9 @@ void display_activate_console()
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
// Re-select window A.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT;
}
void display_deactivate_console()
void display_window_d_console_disable()
{
// Select window D.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT;
@ -971,12 +1008,9 @@ void display_deactivate_console()
// Arm and activate changes.
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
// Re-select window A.
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT;
}
void display_init_cursor(void *crs_fb, u32 size)
void display_cursor_init(void *crs_fb, u32 size)
{
// Setup cursor.
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
@ -992,7 +1026,7 @@ void display_init_cursor(void *crs_fb, u32 size)
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
}
void display_set_pos_cursor(u32 x, u32 y)
void display_cursor_set_pos(u32 x, u32 y)
{
// Set cursor position.
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
@ -1002,7 +1036,7 @@ void display_set_pos_cursor(u32 x, u32 y)
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
}
void display_deinit_cursor()
void display_cursor_deinit()
{
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 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,8 +48,8 @@
// 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 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
@ -52,7 +57,7 @@
#define SYNCPT_CNTRL_NO_STALL BIT(8)
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xff) << 0)
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xFF) << 0)
#define SYNCPT_VSYNC_ENABLE BIT(8)
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
@ -77,19 +82,24 @@
#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)
@ -98,6 +108,7 @@
#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)
@ -137,6 +148,31 @@
#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
// DC_DISP shadowed registers.
@ -153,30 +189,30 @@
#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 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 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 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 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 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 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)
@ -207,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)
@ -221,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)
@ -242,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
@ -253,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)
@ -269,17 +310,22 @@
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
#define DC_WINC_COLOR_PALETTE 0x500
#define DC_WINC_COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off))
#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_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_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
@ -290,15 +336,17 @@
#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
@ -324,6 +372,10 @@
#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
@ -338,33 +390,37 @@
#define WIN_COLOR_DEPTH_YUV444SP 0x3C
#define DC_WIN_POSITION 0x704
#define H_POSITION(x) (((x) & 0xffff) << 0) // Support negative.
#define V_POSITION(x) (((x) & 0xffff) << 16) // Support negative.
#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_BLEND_DEPTH(x) (((x) & 0xff) << 0)
#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)
@ -395,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
@ -408,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)
@ -486,8 +544,8 @@
#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 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
@ -495,20 +553,20 @@
#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
@ -810,6 +868,12 @@ void display_wait_interrupt(u32 intr);
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);
@ -818,21 +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 720x1280 resolution (B8G8R8A8, line stride 720, framebuffer size = 720*1280*4 bytes). */
u32 *display_init_framebuffer_pitch();
u32 *display_init_framebuffer_pitch_vic();
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();
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);
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-2022 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,
@ -16,37 +16,35 @@
*/
// Display A config.
static const cfg_op_t _di_dc_setup_win_config[] = {
{DC_CMD_STATE_ACCESS, 0},
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, 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 | WINDOW_B_SELECT | 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 | SYNCPT_VSYNC_INDX(9)},
{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_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},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT | WINDOW_D_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_DV_CONTROL, 0},
/* Setup default YUV colorspace conversion coefficients */
{DC_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_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
@ -55,21 +53,18 @@ static const cfg_op_t _di_dc_setup_win_config[] = {
{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 | WINDOW_B_SELECT | WINDOW_C_SELECT},
{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 | WINDOW_B_SELECT | 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 _di_dsi_init_irq_pkt_config0[] = {
static const reg_cfg_t _di_dsi_init_config0[] = {
{DSI_WR_DATA, 0},
{DSI_INT_ENABLE, 0},
{DSI_INT_STATUS, 0},
@ -79,7 +74,7 @@ static const cfg_op_t _di_dsi_init_irq_pkt_config0[] = {
{DSI_INIT_SEQ_DATA_2, 0},
{DSI_INIT_SEQ_DATA_3, 0}
};
static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = {
static const reg_cfg_t _di_dsi_init_config1[] = {
{DSI_DCS_CMDS, 0},
{DSI_PKT_SEQ_0_LO, 0},
{DSI_PKT_SEQ_1_LO, 0},
@ -95,7 +90,7 @@ static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = {
{DSI_PKT_SEQ_5_HI, 0},
{DSI_CONTROL, 0}
};
static const cfg_op_t _di_dsi_init_pads_t210b01[] = {
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},
@ -104,7 +99,7 @@ static const cfg_op_t _di_dsi_init_pads_t210b01[] = {
{DSI_PAD_CONTROL_6_B01, 0},
{DSI_PAD_CONTROL_7_B01, 0}
};
static const cfg_op_t _di_dsi_init_timing_pkt_config2[] = {
static const reg_cfg_t _di_dsi_init_config2[] = {
{DSI_PAD_CONTROL_CD, 0},
{DSI_SOL_DELAY, 24},
{DSI_MAX_THRESHOLD, 480},
@ -114,23 +109,21 @@ static const cfg_op_t _di_dsi_init_timing_pkt_config2[] = {
{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 _di_dsi_init_timing_pwrctrl_config[] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
{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 _di_dsi_init_timing_pkt_config3[] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118},
{DSI_BTA_TIMING, 0x190A14},
@ -148,7 +141,7 @@ static const cfg_op_t _di_dsi_init_timing_pkt_config3[] = {
};
// DSI panel JDI config.
static const cfg_op_t _di_dsi_panel_init_config_jdi[] = {
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},
@ -195,7 +188,9 @@ static const cfg_op_t _di_dsi_panel_init_config_jdi[] = {
};
// DSI packet config.
static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = {
static const reg_cfg_t _di_dsi_init_seq_pkt_final_config[] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30172},
{DSI_BTA_TIMING, 0x190A14},
@ -218,7 +213,7 @@ static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = {
};
// DSI mode config.
static const cfg_op_t _di_dsi_mode_config[] = {
static const reg_cfg_t _di_dsi_mode_config[] = {
{DSI_TRIGGER, 0},
{DSI_CONTROL, 0},
{DSI_SOL_DELAY, 6},
@ -232,7 +227,7 @@ static const cfg_op_t _di_dsi_mode_config[] = {
};
// MIPI CAL config.
static const cfg_op_t _di_mipi_pad_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},
@ -240,13 +235,13 @@ static const cfg_op_t _di_mipi_pad_cal_config[] = {
};
// DSI pad config.
static const cfg_op_t _di_dsi_pad_cal_config_t210[] = {
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 _di_dsi_pad_cal_config_t210b01[] = {
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},
@ -257,19 +252,19 @@ static const cfg_op_t _di_dsi_pad_cal_config_t210b01[] = {
};
// MIPI CAL config.
static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210[] = {
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 _di_mipi_dsi_cal_offsets_config_t210b01[] = {
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 _di_mipi_start_dsi_cal_config[] = {
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},
@ -280,48 +275,11 @@ static const cfg_op_t _di_mipi_start_dsi_cal_config[] = {
{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} // Set Prescale and filter and start calibration.
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0}
};
// Display A enable config.
static const cfg_op_t _di_dc_video_enable_config[] = {
{DC_CMD_STATE_ACCESS, 0},
/* Setup Windows A/B/C */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{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},
/* End of color coefficients */
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
{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 | WINDOW_B_SELECT | WINDOW_C_SELECT},
{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 | WINDOW_B_SELECT | 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},
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)},
@ -334,53 +292,49 @@ static const cfg_op_t _di_dc_video_enable_config[] = {
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
{DC_DISP_DISP_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 | WINDOW_B_SELECT | 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, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{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 disable config.
static const cfg_op_t _di_dc_video_disable_config[] = {
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
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, 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},
// LCD panels should sleep for 40ms here.
// 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 deinit config.
static const cfg_op_t _di_dsi_timing_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}, //mariko changes
{DSI_PHY_TIMING_0, 0x6070603},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118},
{DSI_BTA_TIMING, 0x190A14},
@ -397,7 +351,7 @@ static const cfg_op_t _di_dsi_timing_deinit_config[] = {
};
// DSI panel JDI deinit config.
static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = {
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},
@ -423,7 +377,7 @@ static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = {
};
// DSI panel AUO deinit config.
static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = {
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},
@ -464,24 +418,24 @@ static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = {
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
static const cfg_op_t _di_init_config_invert[] = {
/*
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 Window A one color config.
static const cfg_op_t _di_win_one_color[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
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 Window A linear pitch config.
static const cfg_op_t _di_win_framebuffer_pitch[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT | WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
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},
@ -505,9 +459,7 @@ static const cfg_op_t _di_win_framebuffer_pitch[] = {
};
// Display A Window A linear pitch + Win D support config.
static const cfg_op_t _di_win_framebuffer_pitch_vic[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
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},
@ -531,9 +483,7 @@ static const cfg_op_t _di_win_framebuffer_pitch_vic[] = {
};
// Display A Window A linear pitch inverse + Win D support config.
static const cfg_op_t _di_win_framebuffer_pitch_inv[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
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},
@ -557,9 +507,7 @@ static const cfg_op_t _di_win_framebuffer_pitch_inv[] = {
};
// Display A Window A block linear config.
static const cfg_op_t _di_win_framebuffer_block[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
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},
@ -583,7 +531,7 @@ static const cfg_op_t _di_win_framebuffer_block[] = {
};
// Display A Window D config.
static const cfg_op_t _di_win_framebuffer_log[] = {
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},
@ -602,5 +550,5 @@ static const cfg_op_t _di_win_framebuffer_log[] = {
{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_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ},
};

View File

@ -1,7 +1,7 @@
/*
* VIC driver for Tegra X1
*
* Copyright (c) 2018-2023 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,
@ -406,6 +406,9 @@ void vic_set_surface(vic_surface_t *sfc)
// 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:
@ -536,14 +539,8 @@ int vic_compose()
int vic_init()
{
// Ease the stress to APB.
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
clock_enable_vic();
// Restore sys clock.
bpmp_clk_rate_set(prev_fid);
// Load Fetch Control Engine microcode.
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
{

View File

@ -33,6 +33,10 @@ typedef enum _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.
@ -42,7 +46,6 @@ typedef enum _vic_pix_format_t
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

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

View File

@ -1,7 +1,7 @@
/*
* Joy-Con UART driver for Nintendo Switch
*
* Copyright (c) 2019-2023 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,
@ -104,10 +104,10 @@ enum
enum
{
JC_BATT_EMTPY = 0,
JC_BATT_CRIT = 2,
JC_BATT_LOW = 4,
JC_BATT_MID = 6,
JC_BATT_FULL = 8
JC_BATT_CRIT = 1,
JC_BATT_LOW = 2,
JC_BATT_MID = 3,
JC_BATT_FULL = 4
};
static const u8 sio_init[] = {
@ -234,7 +234,7 @@ typedef struct _jc_hid_in_rpt_t
u8 stick_h_right;
u8 stick_m_right;
u8 stick_v_right;
u8 vib_decider; // right:8, left:8. (bit3 en, bit2-0 buffer avail).
u8 vib_decider; // right:4, left:4 (bit3 en, bit2-0 buffer avail).
u8 submcd_ack;
u8 subcmd;
u8 subcmd_data[];
@ -407,12 +407,16 @@ static void _jc_detect()
if (!jc_gamepad.sio_mode)
{
// Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled.
PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE;
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
usleep(20);
//! HW BUG: Unlatch gpio buffer.
(void)gpio_read(GPIO_PORT_H, GPIO_PIN_6);
(void)gpio_read(GPIO_PORT_E, GPIO_PIN_6);
// Read H6/E6 which are shared with UART TX pins.
jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6);
jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6);
@ -532,8 +536,8 @@ static u8 _jc_hid_pkt_id_incr()
static void _jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
{
const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
static const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 };
static const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 };
u8 temp[0x30] = {0};
@ -596,13 +600,13 @@ static void _jc_charging_decider(u8 batt, u8 uart)
u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000;
// Power supply control based on battery levels and charging.
if ((batt >> 1 << 1) < JC_BATT_LOW) // Level without checking charging.
if ((batt >> 1) < JC_BATT_LOW) // Level without checking charging.
_jc_power_supply(uart, true);
else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID)) // Addresses the charging bit.
else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID) << 1) // Addresses the charging bit.
_jc_power_supply(uart, false);
}
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8 *packet, int size)
{
u32 btn_tmp;
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
@ -610,7 +614,14 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
switch (hid_pkt->cmd)
{
case JC_HORI_INPUT_RPT:
if (!(jc->type & JC_ID_HORI))
return;
case JC_HID_INPUT_RPT:
// Discard incomplete hid packets.
if (size < 12)
break;
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
if (jc->type & JC_ID_L)
@ -670,8 +681,12 @@ static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
}
}
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8 *data, int size)
{
// Discard empty packets.
if (size <= 0)
return;
switch (data[0])
{
case JC_WIRED_CMD_GET_INFO:
@ -694,13 +709,13 @@ static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
}
}
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, size_t size)
static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, int size)
{
switch (pkt->cmd)
{
case JC_HORI_INPUT_RPT_CMD:
case JC_WIRED_HID:
_jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
_jc_parse_wired_hid(jc, pkt->payload, size - sizeof(jc_wired_hdr_t));
break;
case JC_WIRED_INIT_REPLY:
_jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
@ -715,11 +730,15 @@ static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, siz
jc->last_received_time = get_tmr_ms();
}
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload, u32 size)
static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8 *payload, int size)
{
switch (cmd)
{
case JC_SIO_CMD_STATUS:
// Discard incomplete packets.
if (size < 12)
break;
jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload;
jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3);
@ -740,7 +759,7 @@ static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload,
}
}
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, u32 size)
static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, int size)
{
if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0))
return;
@ -757,7 +776,7 @@ static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt
break;
case JC_SIO_CMD_IAP_VER:
case JC_SIO_CMD_STATUS:
_jc_sio_parse_payload(jc, cmd, pkt->payload, pkt->payload_size);
_jc_sio_parse_payload(jc, cmd, pkt->payload, size - sizeof(jc_sio_in_rpt_t));
break;
case JC_SIO_CMD_UNK02:
case JC_SIO_CMD_UNK20:
@ -784,7 +803,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf;
if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3))
{
_jc_uart_pkt_parse(jc, jc_pkt, jc_pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t));
_jc_uart_pkt_parse(jc, jc_pkt, len);
return;
}
@ -793,7 +812,7 @@ static void _jc_rcv_pkt(joycon_ctxt_t *jc)
jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf);
if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK)
{
_jc_sio_uart_pkt_parse(jc, sio_pkt, sio_pkt->payload_size + sizeof(jc_sio_in_rpt_t));
_jc_sio_uart_pkt_parse(jc, sio_pkt, len);
return;
}
@ -842,7 +861,7 @@ static void _jc_req_nx_pad_status(joycon_ctxt_t *jc)
else
_joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
jc->last_status_req_time = get_tmr_ms() + 15;
jc->last_status_req_time = get_tmr_ms() + (!jc->sio_mode ? 15 : 7);
}
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
@ -1196,17 +1215,11 @@ void jc_init_hw()
pinmux_config_uart(UART_B);
pinmux_config_uart(UART_C);
// Ease the stress to APB.
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
// Enable UART B and C clocks.
if (!jc_gamepad.sio_mode)
clock_enable_uart(UART_B);
clock_enable_uart(UART_C);
// Restore OC.
bpmp_clk_rate_set(prev_fid);
jc_init_done = true;
#endif
}

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

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,27 +54,30 @@ 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;
}
}
@ -82,17 +85,17 @@ int blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const
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,16 +92,6 @@
# 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
**************************************/

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,

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

View File

@ -184,6 +184,41 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
return data;
}
void sdram_div_disable(bool enable)
{
static bool enabled = false;
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210 && enable == enabled)
return;
enabled = enable;
// Clear CC interrupt.
EMC(EMC_INTSTATUS) = BIT(4);
(void)EMC(EMC_INTSTATUS);
u32 clk_src_emc = _dram_cfg_08_10_12_14_samsung_hynix_4gb.emc_clock_source;
if (enable)
{
// Check if clock source is not the expected one.
if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) != clk_src_emc)
return;
// Clear div.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_src_emc & ~0xF;
}
else
{
// Restore MC/EMC clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_src_emc;
}
// Wait for CC interrupt.
while (!(EMC(EMC_INTSTATUS) & BIT(4)))
;
}
static void _sdram_config_t210(const sdram_params_t210_t *params)
{
// Program DPD3/DPD4 regs (coldboot path).
@ -1469,7 +1504,7 @@ static void _sdram_init_t210()
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); // Normally params->pmc_ddr_pwr.
// Turn on MEM IO Power.
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
@ -1492,7 +1527,7 @@ static void _sdram_init_t210b01()
usleep(params->pmc_vddp_sel_wait);
// Turn on MEM IO Power.
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_SDMMC1; // Only keep SDMMC1 state. (Was params->pmc_no_io_power).
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;

View File

@ -48,7 +48,14 @@ enum sdram_ids_erista
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.
/*
* 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.
};
@ -128,6 +135,7 @@ void sdram_init();
void *sdram_get_params_patched();
void *sdram_get_params_t210b01();
void sdram_lp0_save_params(const void *params);
void sdram_div_disable(bool enable);
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);
#endif

View File

@ -32,24 +32,24 @@ void regulator_5v_enable(u8 dev)
// 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_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.
// 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_IO_EN;
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO;
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
// Override power detect for GPIO AO IO rails.
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN;
// Inform GPIO IO pads that we switched to 1.8V.
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_GPIO;
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
usb_src = false;

View File

@ -75,7 +75,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
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_tsec();
@ -305,7 +305,7 @@ out:
clock_disable_sor_safe();
clock_disable_tsec();
bpmp_mmu_enable();
bpmp_clk_rate_set(prev_fid);
bpmp_clk_rate_relaxed(false);
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
// Re-enable AHB aperture.

View File

@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019-2023 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,
@ -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 }
@ -140,7 +140,7 @@ void bpmp_mmu_maintenance(u32 op, bool force)
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;
@ -200,10 +200,44 @@ 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[] = {
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.
@ -213,8 +247,6 @@ const u8 pll_divn[] = {
//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;
@ -237,45 +269,35 @@ 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;
}
// The following functions halt BPMP to reduce power while sleeping.

View File

@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019-2023 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,
@ -59,11 +59,12 @@ typedef enum
#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_usleep(u32 us);
void bpmp_msleep(u32 ms);
void bpmp_halt();

View File

@ -15,6 +15,7 @@
* 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>
@ -153,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)
@ -247,7 +254,13 @@ void clock_disable_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()
@ -323,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()
@ -398,10 +417,8 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
if (lowpower && tegra_t210)
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
// Set DISP1 clock source and parent clock.
if (lowpower)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = (2 << 29u) | CLK_SRC_DIV(1); // PLLD_OUT0.
// 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;
@ -464,10 +481,10 @@ 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.
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 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,
@ -93,6 +93,24 @@ static void _config_oscillators()
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.
static void _config_gpios(bool nx_hoag)
{
@ -268,7 +286,7 @@ static void _config_se_brom()
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)
@ -277,22 +295,27 @@ static void _config_regulators(bool tegra_t210)
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO/Core power.
// Make sure SDMMC1 IO/Core are powered off.
max7762x_regulator_enable(REGULATOR_LDO2, false);
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
sd_power_cycle_time_start = get_tmr_ms();
// Disable LCD DVDD to make sure it's in a reset state.
// 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;
// Disable DSI AVDD to make sure it's in a reset state.
max7762x_regulator_enable(REGULATOR_LDO0, false);
// 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);
@ -301,13 +324,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);
@ -315,8 +338,26 @@ 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()
@ -355,18 +396,6 @@ void hw_init()
// Initialize pin configuration.
_config_gpios(nx_hoag);
#ifdef 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
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
clock_enable_cl_dvfs();
@ -380,19 +409,12 @@ void hw_init()
// Initialize I2C5, mandatory for PMIC.
i2c_init(I2C_5);
// 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);
}
// 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);
_config_pmc_scratch(); // Missing from 4.x+
// Set BPMP/SCLK to PLLP_OUT (408MHz).
@ -406,6 +428,9 @@ void hw_init()
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();
@ -413,9 +438,22 @@ void hw_init()
// 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)
{
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
@ -426,7 +464,7 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
// 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);
@ -439,6 +477,9 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
// 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.
if (tegra_t210)
{
@ -458,7 +499,7 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
gpio_config(GPIO_PORT_D, GPIO_PIN_1, 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.

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,
@ -27,7 +27,8 @@ 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,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,
@ -71,19 +71,9 @@ 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++)
@ -121,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++)
@ -155,7 +144,6 @@ void irq_handler()
if (!irq_init_done)
{
_irq_disable_source(irq);
_irq_ack_source(irq);
return;
}
@ -197,7 +185,6 @@ void irq_wait_event(u32 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();
}

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,
@ -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,
@ -50,6 +51,7 @@
#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
@ -69,6 +71,7 @@
#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
@ -81,6 +84,7 @@
#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
@ -101,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)
@ -130,5 +139,6 @@
void pinmux_config_uart(u32 idx);
void pinmux_config_i2c(u32 idx);
void pinmux_config_i2s(u32 idx);
#endif

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2022 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,
@ -39,10 +39,12 @@
#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_SDMMC4_IO_EN BIT(14)
#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_IO_EN BIT(21)
#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)
@ -61,9 +63,9 @@
#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 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

View File

@ -40,7 +40,7 @@
#define GPU_USER_BASE 0x58000000
#define RES_SEMAPH_BASE 0x60001000
#define ARB_SEMAPH_BASE 0x60002000
#define ARBPRI_BASE 0x60003000
#define ARB_PRI_BASE 0x60003000
#define ICTLR_BASE 0x60004000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
@ -81,6 +81,7 @@
#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
@ -112,6 +113,7 @@
#define SOR1(off) MMIO_REG32(SOR1_BASE, off)
#define GPU(off) MMIO_REG32(GPU_BASE, off)
#define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
#define 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)
@ -174,6 +176,7 @@
#define EVP_COP_IRQ_STS 0x220
/*! Primary Interrupt Controller registers. */
#define PRI_ICTLR_ISR 0x10
#define PRI_ICTLR_FIR 0x14
#define PRI_ICTLR_FIR_SET 0x18
#define PRI_ICTLR_FIR_CLR 0x1C
@ -186,6 +189,13 @@
#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)

View File

@ -46,7 +46,7 @@
/* OCR bit definitions */
#define SD_OCR_VDD_18 (1U << 7) /* VDD voltage 1.8 */
#define SD_VHD_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
#define SD_VHS_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD voltage 3.2 ~ 3.3 */
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */

View File

@ -233,6 +233,8 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
int sdmmc_storage_end(sdmmc_storage_t *storage)
{
DPRINTF("[SDMMC%d] end\n", storage->sdmmc->id);
if (!_sdmmc_storage_go_idle_state(storage))
return 0;
@ -275,7 +277,7 @@ reinit_try:
// Disk IO failure! Reinit SD/EMMC to a lower speed.
if (storage->sdmmc->id == SDMMC_1 || storage->sdmmc->id == SDMMC_4)
{
int res;
int res = 0;
if (storage->sdmmc->id == SDMMC_1)
{
@ -910,7 +912,7 @@ void _sd_storage_debug_print_ssr(u8 *raw_ssr)
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
{
sdmmc_cmd_t cmdbuf;
u16 vhd_pattern = SD_VHD_27_36 | 0xAA;
u16 vhd_pattern = SD_VHS_27_36 | 0xAA;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
{
@ -1132,17 +1134,20 @@ static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limi
u32 pwr = SD_SET_POWER_LIMIT_0_72;
// If UHS-I only, anything above 1.44W defaults to 1.44W.
/*
if (power_limit & SD_MAX_POWER_2_88)
pwr = SD_SET_POWER_LIMIT_2_88;
else if (power_limit & SD_MAX_POWER_2_16)
pwr = SD_SET_POWER_LIMIT_2_16;
else if (power_limit & SD_MAX_POWER_1_44)
*/
if (power_limit & SD_MAX_POWER_1_44)
pwr = SD_SET_POWER_LIMIT_1_44;
_sd_storage_switch(storage, buf, SD_SWITCH_SET, SD_SWITCH_GRP_PWRLIM, pwr);
switch ((buf[15] >> 4) & 0x0F)
{
/*
case SD_SET_POWER_LIMIT_2_88:
DPRINTF("[SD] power limit raised to 2880 mW\n");
break;
@ -1150,7 +1155,7 @@ static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limi
case SD_SET_POWER_LIMIT_2_16:
DPRINTF("[SD] power limit raised to 2160 mW\n");
break;
*/
case SD_SET_POWER_LIMIT_1_44:
DPRINTF("[SD] power limit raised to 1440 mW\n");
break;
@ -1396,7 +1401,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
}
// Try to raise the power limit to let the card perform better.
if (hs_type != UHS_SDR25_BUS_SPEED)
if (hs_type != UHS_SDR25_BUS_SPEED) // Not applicable for SDR12/SDR25.
_sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
// Setup and set selected card and bus speed.
@ -1424,9 +1429,6 @@ static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
// Try to raise the power limit to let the card perform better.
_sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
if (!(fmodes.access_mode & SD_MODE_HIGH_SPEED))
return 1;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 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,
@ -109,8 +109,8 @@ void sdmmc_save_tap_value(sdmmc_t *sdmmc)
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
{
const u32 dqs_trim_val = 40; // 24 if HS533/HS667.
const u8 tap_values_t210[4] = { 4, 0, 3, 0 };
static const u32 dqs_trim_val = 40; // 24 if HS533/HS667.
static const u8 tap_values_t210[4] = { 4, 0, 3, 0 };
u32 tap_val = 0;
@ -222,6 +222,9 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
{
sdmmc->regs->autocalcfg &= ~SDHCI_TEGRA_AUTOCAL_ENABLE;
_sdmmc_pad_config_fallback(sdmmc, power);
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC%d: Comp Pad cal timeout!", sdmmc->id + 1);
#endif
}
// Disable E_INPUT (SD) or enable E_PWRD (eMMC) to conserve power.
@ -403,7 +406,7 @@ static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
sdmmc->card_clock_enabled = 1;
}
static void _sdmmc_sd_clock_disable(sdmmc_t *sdmmc)
static void _sdmmc_card_clock_disable(sdmmc_t *sdmmc)
{
sdmmc->card_clock_enabled = 0;
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
@ -934,7 +937,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
if (norintsts & SDHCI_INT_ERROR)
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X\n", sdmmc->id + 1, norintsts, errintsts);
EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
#endif
sdmmc->regs->errintsts = errintsts;
return SDMMC_MASKINT_ERROR;
@ -1152,7 +1155,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
int result = _sdmmc_wait_response(sdmmc);
#ifdef ERROR_EXTRA_PRINTING
if (!result)
EPRINTFARGS("SDMMC%d: Transfer timeout!", sdmmc->id + 1);
EPRINTFARGS("SDMMC%d: Transfer error!", sdmmc->id + 1);
#endif
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
@ -1273,16 +1276,7 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
if (!sdmmc_get_sd_inserted())
return 0;
/*
* Pinmux config:
* DRV_TYPE = DRIVE_2X (for 33 Ohm driver)
* E_SCHMT = ENABLE (for 1.8V), DISABLE (for 3.3V)
* E_INPUT = ENABLE
* TRISTATE = PASSTHROUGH
* APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK
*/
// Enable deep loopback for SDMMC1 CLK pad.
// Enable deep loopback for SDMMC1 CLK pad so reads work.
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;
// Configure SDMMC1 CLK pinmux, based on state and SoC type.
@ -1302,18 +1296,18 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
_sdmmc_config_sdmmc1_schmitt();
// Make sure the SDMMC1 controller is powered.
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1_IO_EN;
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
usleep(1000);
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
// Set enable SD card power.
// Enable SD card power. Powers LDO2 also.
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2;
gpio_direction_output(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
usleep(10000);
// Inform IO pads that voltage is gonna be 3.3V.
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
// Enable SD card IO power.
@ -1366,8 +1360,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
u16 divisor;
u8 vref_sel = 7;
const u8 trim_values_t210[4] = { 2, 8, 3, 8 };
const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 };
static const u8 trim_values_t210[4] = { 2, 8, 3, 8 };
static const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 };
const u8 *trim_values;
if (id > SDMMC_4 || id == SDMMC_3)
@ -1403,19 +1397,18 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
// Disable clock if enabled.
if (clock_sdmmc_is_not_reset_and_enabled(id))
{
_sdmmc_sd_clock_disable(sdmmc);
_sdmmc_card_clock_disable(sdmmc);
_sdmmc_commit_changes(sdmmc);
}
// Configure and enable selected clock.
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
clock_sdmmc_enable(id, clock);
sdmmc->clock_stopped = 0;
// Make sure all sdmmc registers are reset.
_sdmmc_reset_all(sdmmc);
sdmmc->clock_stopped = 0;
// Set default pad IO trimming configuration.
sdmmc->regs->iospare |= BIT(19); // Enable 1 cycle delayed cmd_oen.
sdmmc->regs->veniotrimctl &= ~BIT(2); // Set Band Gap VREG to supply DLL.
@ -1456,23 +1449,23 @@ void sdmmc1_disable_power()
// T210B01 WAR: Set pads to discharge state.
_sdmmc_config_sdmmc1_pads(true);
// Disable SD card IO power regulator.
// Disable SD card IO power.
max7762x_regulator_enable(REGULATOR_LDO2, false);
usleep(4000);
// Disable SD card IO power pin.
// Disable SD card power.
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
// T210/T210B01 WAR: Set start timer for IO and Controller power discharge.
sd_power_cycle_time_start = get_tmr_ms();
usleep(1000); // To power cycle, min 1ms without power is needed.
usleep(10000); // To power cycle, min 1ms without power is needed.
// Disable SDMMC1 controller power.
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1_IO_EN;
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
// Inform IO pads that next voltage might be 3.3V.
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
// T210B01 WAR: Restore pads to reset state.
@ -1486,7 +1479,7 @@ void sdmmc_end(sdmmc_t *sdmmc)
{
if (!sdmmc->clock_stopped)
{
_sdmmc_sd_clock_disable(sdmmc);
_sdmmc_card_clock_disable(sdmmc);
// Disable SDMMC power.
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_OFF);
_sdmmc_commit_changes(sdmmc);
@ -1547,7 +1540,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
usleep(150);
// Inform IO pads that we switched to 1.8V.
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(PMC_PWR_DET_SDMMC1_IO_EN);
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_SDMMC1;
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
// Enable schmitt trigger for better duty cycle and low jitter clock.

View File

@ -1,7 +1,7 @@
/*
* Fan driver for Nintendo Switch
*
* Copyright (c) 2018-2023 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,
@ -27,7 +27,7 @@
#include <soc/timer.h>
#include <soc/t210.h>
void set_fan_duty(u32 duty)
void fan_set_duty(u32 duty)
{
static bool fan_init = false;
static u16 curr_duty = -1;
@ -49,16 +49,8 @@ void set_fan_duty(u32 duty)
// Enable PWM if disabled.
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA)
{
// Ease the stress to APB.
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
clock_enable_pwm();
// Restore OC.
bpmp_clk_rate_set(prev_fid);
}
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan.
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
@ -91,7 +83,7 @@ void set_fan_duty(u32 duty)
}
}
void get_fan_speed(u32 *duty, u32 *rpm)
void fan_get_speed(u32 *duty, u32 *rpm)
{
if (rpm)
{
@ -122,3 +114,15 @@ void get_fan_speed(u32 *duty, u32 *rpm)
if (duty)
*duty = 236 - ((PWM(PWM_CONTROLLER_PWM_CSR_1) >> 16) & 0xFF);
}
void fan_set_from_temp(u32 temp)
{
if (temp >= 52)
fan_set_duty(102);
else if (temp >= 47)
fan_set_duty(76);
else if (temp >= 42)
fan_set_duty(51);
else if (temp <= 39)
fan_set_duty(0);
}

View File

@ -1,7 +1,7 @@
/*
* Fan driver for Nintendo Switch
*
* 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,
@ -22,8 +22,10 @@
#include <utils/types.h>
// Disable: 0 (0 RPM), min duty: 1 (960 RPM), max duty 235 (11000 RPM).
void set_fan_duty(u32 duty);
// Passing NULL ptr on either of the two, disables parsing of it.
void get_fan_speed(u32 *duty, u32 *rpm);
void fan_set_duty(u32 duty);
// Passing NULL ptr on either of the two, disables results.
void fan_get_speed(u32 *duty, u32 *rpm);
void fan_set_from_temp(u32 temp);
#endif /* __FAN_H_ */

View File

@ -71,6 +71,12 @@ typedef struct _jc_cal_t
u16 cry_min;
} jc_cal_t;
enum {
INPUT_POLL_HAS_PACKET,
INPUT_POLL_NO_PACKET,
INPUT_POLL_EXIT,
};
static jc_cal_t jc_cal_ctx;
static usb_ops_t usb_ops;
@ -119,22 +125,24 @@ static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
return true;
}
static bool _jc_poll(gamepad_report_t *rpt)
static int _jc_poll(gamepad_report_t *rpt)
{
static gamepad_report_t prev_rpt = {0};
// Poll Joy-Con.
jc_gamepad_rpt_t *jc_pad = joycon_poll();
if (!jc_pad)
return false;
return INPUT_POLL_NO_PACKET;
// Exit emulation if Left stick and Home are pressed.
if (jc_pad->l3 && jc_pad->home)
return true;
return INPUT_POLL_EXIT;
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS || jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{
if (!_jc_calibration(jc_pad))
return false;
return INPUT_POLL_NO_PACKET;
}
// Re-calibrate on disconnection.
@ -282,7 +290,12 @@ static bool _jc_poll(gamepad_report_t *rpt)
//rpt->btn13 = jc_pad->cap;
//rpt->btn14 = jc_pad->home;
return false;
if (!memcmp(rpt, &prev_rpt, sizeof(gamepad_report_t)))
return INPUT_POLL_NO_PACKET;
memcpy(&prev_rpt, rpt, sizeof(gamepad_report_t));
return INPUT_POLL_HAS_PACKET;
}
typedef struct _touchpad_report_t
@ -351,10 +364,12 @@ static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
static bool _hid_poll_jc(usb_ctxt_t *usbs)
{
if (_jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR))
int res = _jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
if (res == INPUT_POLL_EXIT)
return true;
// Send HID report.
if (res == INPUT_POLL_HAS_PACKET)
if (_hid_transfer_start(usbs, sizeof(gamepad_report_t)))
return true; // EP Error.

View File

@ -4,7 +4,7 @@
* Copyright (c) 2003-2008 Alan Stern
* Copyright (c) 2009 Samsung Electronics
* Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
* Copyright (c) 2019-2023 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,
@ -1845,6 +1845,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
ums.lun.ro = usbs->ro;
ums.lun.type = usbs->type;
ums.lun.partition = usbs->partition;
ums.lun.num_sectors = usbs->sectors;
ums.lun.offset = usbs->offset;
ums.lun.removable = 1; // Always removable to force OSes to use prevent media removal.
ums.lun.unit_attention_data = SS_RESET_OCCURRED;
@ -1898,10 +1899,14 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
ums.set_text(ums.label, "#C7EA46 Status:# Started UMS");
if (usbs->sectors)
ums.lun.num_sectors = usbs->sectors;
// If partition sectors are not set get them from hardware.
if (!ums.lun.num_sectors)
{
if (usbs->type == MMC_EMMC && (ums.lun.partition - 1)) // eMMC BOOT0/1.
ums.lun.num_sectors = emmc_storage.ext_csd.boot_mult << 8;
else
ums.lun.num_sectors = ums.lun.storage->sec_cnt;
ums.lun.num_sectors = ums.lun.storage->sec_cnt; // eMMC GPP or SD.
}
do
{

View File

@ -1,7 +1,7 @@
/*
* Enhanced USB Device (EDCI) driver for Tegra X1
*
* Copyright (c) 2019-2023 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,
@ -355,9 +355,15 @@ int usb_device_init()
if (usb_init_done)
return USB_RES_OK;
// Ease the stress to APB.
bpmp_clk_rate_relaxed(true);
// Initialize USB2 controller PHY.
_usb_init_phy();
// Restore OC.
bpmp_clk_rate_relaxed(false);
// AHB USB performance cfg.
AHB_GIZMO(AHB_GIZMO_AHB_MEM) |= AHB_MEM_DONT_SPLIT_AHB_WR | AHB_MEM_ENB_FAST_REARBITRATE;
AHB_GIZMO(AHB_GIZMO_USB) |= AHB_GIZMO_IMMEDIATE;

View File

@ -1,7 +1,7 @@
/*
* eXtensible USB Device driver (XDCI) for Tegra X1
*
* Copyright (c) 2020-2022 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,
@ -883,6 +883,9 @@ static void _xusbd_init_device_clocks()
int xusb_device_init()
{
// Ease the stress to APB.
bpmp_clk_rate_relaxed(true);
// Disable USB2 device controller clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD);
@ -920,6 +923,9 @@ int xusb_device_init()
// Initialize device clocks.
_xusbd_init_device_clocks();
// Restore OC.
bpmp_clk_rate_relaxed(false);
// Enable AHB redirect for access to IRAM for Event/EP ring buffers.
mc_enable_ahb_redirect();

View File

@ -28,10 +28,32 @@ static void _s_putc(char c)
*sout_buf += 1;
}
static void _s_puts(char *s)
static void _s_putspace(int fcnt)
{
if (fcnt <= 0)
return;
for (int i = 0; i < fcnt; i++)
_s_putc(' ');
}
static void _s_puts(char *s, char fill, int fcnt)
{
if (fcnt)
{
fcnt = fcnt - strlen(s);
// Left padding. Check if padding is not space based (dot counts as such).
if (fill != '.')
_s_putspace(fcnt);
}
for (; *s; s++)
_s_putc(*s);
// Right padding. Check if padding is space based (dot counts as such).
if (fill == '.')
_s_putspace(fcnt);
}
static void _s_putn(u32 v, int base, char fill, int fcnt)
@ -75,9 +97,28 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
}
}
_s_puts(p);
_s_puts(p, 0, 0);
}
/*
* Padding:
* Numbers:
* %3d: Fill: ' ', Count: 3.
* % 3d: Fill: ' ', Count: 3.
* %.3d: Fill: '.', Count: 3.
* %23d: Fill: '2', Count: 3.
* % 23d: Fill: ' ', Count: 23.
* %223d: Fill: '2', Count: 23.
*
* Strings, Fill: ' ':
* %3s: Count: 5, Left.
* %23s: Count: 5, Left.
* %223s: Count: 25, Left.
* %.3s: Count: 5, Right.
* %.23s: Count: 25, Right.
* %.223s: Count: 225, Right.
*/
void s_printf(char *out_buf, const char *fmt, ...)
{
va_list ap;
@ -94,8 +135,8 @@ void s_printf(char *out_buf, const char *fmt, ...)
fill = 0;
fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
// Check for padding. Number or space based (dot count as space for string).
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ' || *fmt == '.')
{
fcnt = *fmt; // Padding size or padding type.
fmt++;
@ -132,7 +173,7 @@ parse_padding_dec:
break;
case 's':
_s_puts(va_arg(ap, char *));
_s_puts(va_arg(ap, char *), fill, fcnt);
break;
case 'd':
@ -221,7 +262,7 @@ parse_padding_dec:
break;
case 's':
_s_puts(va_arg(ap, char *));
_s_puts(va_arg(ap, char *), fill, fcnt);
break;
case 'd':

View File

@ -21,6 +21,24 @@
#include <utils/types.h>
/*
* Padding:
* Numbers:
* %3d: Fill: ' ', Count: 3.
* % 3d: Fill: ' ', Count: 3.
* %23d: Fill: '2', Count: 3.
* % 23d: Fill: ' ', Count: 23.
* %223d: Fill: '2', Count: 23.
*
* Strings, Fill: ' ':
* %3s: Count: 5, Left.
* %23s: Count: 5, Left.
* %223s: Count: 25, Left.
* %.3s: Count: 5, Right.
* %.23s: Count: 25, Right.
* %.223s: Count: 225, Right.
*/
void s_printf(char *out_buf, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void s_vprintf(char *out_buf, const char *fmt, va_list ap);

View File

@ -98,10 +98,12 @@ typedef unsigned long uptr;
#define OFFSET_OF(t, m) ((uptr)&((t *)NULL)->m)
#define CONTAINER_OF(mp, t, mn) ((t *)((uptr)mp - OFFSET_OF(t, mn)))
#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00))
#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
(((num) >> 8 ) & 0xff00) | (((num) << 24) & 0xff000000))
#define byte_swap_16(num) ((((num) >> 8) & 0xFF) | (((num) & 0xFF) << 8))
#define byte_swap_32(num) ((((num) >> 24) & 0xFF) | (((num) & 0xFF00) << 8 ) | \
(((num) >> 8 ) & 0xFF00) | (((num) & 0xFF) << 24))
#define likely(x) (__builtin_expect((x) != 0, 1))
#define unlikely(x) (__builtin_expect((x) != 0, 0))
/* Bootloader/Nyx */
#define BOOT_CFG_AUTOBOOT_EN BIT(0)

View File

@ -197,10 +197,11 @@ int atoi(const char *nptr)
return (int)strtol(nptr, (char **)NULL, 10);
}
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
void reg_write_array(u32 *base, const reg_cfg_t *cfg, u32 num_cfg)
{
for (u32 i = 0; i < num_ops; i++)
base[ops[i].off] = ops[i].val;
// Expected register offset is a u32 array index.
for (u32 i = 0; i < num_cfg; i++)
base[cfg[i].idx] = cfg[i].val;
}
u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
@ -262,7 +263,7 @@ void power_set_state(power_state_t state)
sd_end();
// De-initialize and power down various hardware.
hw_reinit_workaround(false, 0);
hw_deinit(false, 0);
// Set power state.
switch (state)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 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,8 +21,6 @@
#include <utils/types.h>
#include <mem/minerva.h>
#define CFG_SIZE(array) (sizeof(array) / sizeof(cfg_op_t))
#define NYX_NEW_INFO 0x3058594E
typedef enum
@ -53,11 +51,11 @@ typedef enum
ERR_EXCEPTION = BIT(31),
} hekate_errors_t;
typedef struct _cfg_op_t
typedef struct _reg_cfg_t
{
u32 off;
u32 idx;
u32 val;
} cfg_op_t;
} reg_cfg_t;
typedef struct _nyx_info_t
{
@ -88,7 +86,7 @@ u64 sqrt64(u64 num);
long strtol(const char *nptr, char **endptr, register int base);
int atoi(const char *nptr);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
void reg_write_array(u32 *base, const reg_cfg_t *cfg, u32 num_cfg);
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
void panic(u32 val);

View File

@ -26,7 +26,6 @@
#include <libs/fatfs/ff.h>
extern hekate_config h_cfg;
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
#pragma GCC push_options
#pragma GCC optimize ("Os")

View File

@ -672,7 +672,7 @@ DPRINTF("Parsed GPT\n");
goto out;
// Read in package2 header and get package2 real size.
const u32 BCT_SIZE = SZ_16K;
static const u32 BCT_SIZE = SZ_16K;
bctBuf = (u8 *)malloc(BCT_SIZE);
emmc_part_read(pkg2_part, BCT_SIZE / EMMC_BLOCKSIZE, 1, bctBuf);
u32 *hdr = (u32 *)(bctBuf + 0x100);
@ -759,6 +759,7 @@ int hos_launch(ini_sec_t *cfg)
volatile secmon_mailbox_t *secmon_mailbox;
minerva_change_freq(FREQ_1600);
sdram_div_disable(true);
list_init(&ctxt.kip1_list);
ctxt.cfg = cfg;
@ -839,7 +840,7 @@ int hos_launch(ini_sec_t *cfg)
if (!ctxt.stock)
{
u32 fuses = fuse_read_odm(7);
if ((h_cfg.autonogc &&
if ((h_cfg.autonogc && // Prevent GC fuse burning (sysMMC and emuMMC).
(
(!(fuses & ~0xF) && (ctxt.pkg1_id->fuses >= 5)) || // LAFW v2, 4.0.0+
(!(fuses & ~0x3FF) && (ctxt.pkg1_id->fuses >= 11)) || // LAFW v3, 9.0.0+
@ -848,12 +849,12 @@ int hos_launch(ini_sec_t *cfg)
(!(fuses & ~0x3FFF) && (ctxt.pkg1_id->fuses >= 15)) // LAFW v5, 12.0.2+
)
)
|| ((emummc_enabled) &&
|| ((emummc_enabled) && // Force NOGC if already burnt (only emuMMC).
(
((fuses & 0x400) && (ctxt.pkg1_id->fuses <= 10)) || // HOS 9.0.0+ fuses burnt.
((fuses & 0x2000) && (ctxt.pkg1_id->fuses <= 13)) || // HOS 11.0.0+ fuses burnt.
((fuses & BIT(10)) && (ctxt.pkg1_id->fuses <= 10)) || // HOS 9.0.0+ fuses burnt.
((fuses & BIT(13)) && (ctxt.pkg1_id->fuses <= 13)) || // HOS 11.0.0+ fuses burnt.
// Detection broken! Use kip1patch=nogc // HOS 12.0.0+
((fuses & 0x4000) && (ctxt.pkg1_id->fuses <= 14)) // HOS 12.0.2+ fuses burnt.
((fuses & BIT(14)) && (ctxt.pkg1_id->fuses <= 14)) // HOS 12.0.2+ fuses burnt.
)
))
config_kip1patch(&ctxt, "nogc");
@ -1016,7 +1017,7 @@ int hos_launch(ini_sec_t *cfg)
}
// In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode.
kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
const kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
if (kernel_patchset != NULL)
{
gfx_printf("%kPatching kernel%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
@ -1165,6 +1166,7 @@ int hos_launch(ini_sec_t *cfg)
// Disable display. This must be executed before secmon to provide support for all fw versions.
display_end();
clock_disable_host1x();
// Override uCID if set.
EMC(EMC_SCRATCH0) = ctxt.ucid;
@ -1173,8 +1175,12 @@ int hos_launch(ini_sec_t *cfg)
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_AHBDMA) | BIT(CLK_H_APBDMA) | BIT(CLK_H_USB2);
// Reset arbiter.
hw_config_arbiter(true);
// Scale down RAM OC if enabled.
minerva_prep_boot_freq();
sdram_div_disable(false);
// Flush cache and disable MMU.
bpmp_mmu_disable();
@ -1189,6 +1195,7 @@ int hos_launch(ini_sec_t *cfg)
error:
_free_launch_components(&ctxt);
sdram_div_disable(false);
emmc_end();
EPRINTF("\nFailed to launch HOS!");

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2023 CTCaer
* Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@ -267,7 +267,7 @@ const u8 *pkg1_unpack(void *wm_dst, u32 *wb_sz, void *sm_dst, void *ldr_dst, con
void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01)
{
patch_t *secmon_patchset;
const patch_t *secmon_patchset;
launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt;
// Patch Secmon to allow for an unsigned package2 and patched kernel.
@ -320,7 +320,7 @@ void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01)
void pkg1_warmboot_patch(void *hos_ctxt)
{
launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt;
patch_t *warmboot_patchset;
const patch_t *warmboot_patchset;
// Patch warmboot on T210 to allow downgrading.
switch (ctxt->pkg1_id->kb)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2022-2023 CTCaer
* Copyright (c) 2022-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,
@ -41,7 +41,7 @@ typedef struct _patch_t
} patch_t;
#define PATCHSET_DEF(name, ...) \
patch_t name[] = { \
const patch_t name[] = { \
__VA_ARGS__, \
{ 0xFFFFFFFF, 0xFFFFFFFF } \
}
@ -79,7 +79,7 @@ typedef struct _pkg1_id_t
u16 pkg11_off;
u32 secmon_base;
u32 warmboot_base;
patch_t *secmon_patchset;
const patch_t *secmon_patchset;
} pkg1_id_t;
typedef struct _pk11_hdr_t

View File

@ -57,7 +57,7 @@ enum kip_offset_section
#include "pkg2_patches.inl"
static kip1_id_t *_kip_id_sets = _kip_ids;
static kip1_id_t *_kip_id_sets = (kip1_id_t *)_kip_ids;
static u32 _kip_id_sets_cnt = ARRAY_SIZE(_kip_ids);
void pkg2_get_ids(kip1_id_t **ids, u32 *entries)
@ -511,10 +511,7 @@ const char *pkg2_patch_kips(link_t *info, char *patch_names)
}
if (strcmp(patches[i], "nogc"))
{
parse_external_kip_patches();
break;
}
}
u32 kip_hash[SE_SHA_256_SIZE / sizeof(u32)];
@ -534,7 +531,7 @@ const char *pkg2_patch_kips(link_t *info, char *patch_names)
// Check if there are patches to apply.
bool patches_found = false;
kip1_patchset_t *patchset = _kip_id_sets[kip_id_idx].patchset;
const kip1_patchset_t *patchset = _kip_id_sets[kip_id_idx].patchset;
while (patchset != NULL && patchset->name != NULL && !patches_found)
{
for (u32 i = 0; i < patches_num; i++)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 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,
@ -43,11 +43,11 @@ typedef struct _kernel_patch_t
u32 id;
u32 off;
u32 val;
u32 *ptr;
const u32 *ptr;
} kernel_patch_t;
#define KERNEL_PATCHSET_DEF(name, ...) \
kernel_patch_t name[] = { \
static const kernel_patch_t name[] = { \
__VA_ARGS__, \
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32 *)0xFFFFFFFF} \
}
@ -124,7 +124,7 @@ typedef struct _pkg2_kip1_info_t
typedef struct _pkg2_kernel_id_t
{
u8 hash[8];
kernel_patch_t *kernel_patchset;
const kernel_patch_t *kernel_patchset;
} pkg2_kernel_id_t;
#define KIP1_PATCH_SRC_NO_CHECK (char *)(-1)
@ -140,14 +140,14 @@ typedef struct _kip1_patch_t
typedef struct _kip1_patchset_t
{
char *name; // NULL means end.
kip1_patch_t *patches; // NULL means not necessary.
const kip1_patch_t *patches; // NULL means not necessary.
} kip1_patchset_t;
typedef struct _kip1_id_t
{
const char *name;
u8 hash[8];
kip1_patchset_t *patchset;
const kip1_patchset_t *patchset;
} kip1_id_t;
void pkg2_get_newkern_info(u8 *kern_data);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2023 CTCaer
* Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
@ -63,37 +63,37 @@
#define ID_RCV_OFF_1101 0x22B28
#define ID_RCV_OFF_1200 0x23424
static u32 PRC_ID_SND_100[] =
static const u32 PRC_ID_SND_100[] =
{
0xA9BF2FEA, 0x2A0E03EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9412948, 0xA8C12FEA
};
#define CODE_OFF_2ND_100 (CODE_OFF_1ST_100 + sizeof(PRC_ID_SND_100) + sizeof(u32))
static u32 PRC_ID_RCV_100[] =
static const u32 PRC_ID_RCV_100[] =
{
0xA9BF2FEA, 0x2A1C03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9412968, 0xA8C12FEA
};
static u32 PRC_ID_SND_200[] =
static const u32 PRC_ID_SND_200[] =
{
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9413148, 0xA8C12FEA
};
#define CODE_OFF_2ND_200 (CODE_OFF_1ST_200 + sizeof(PRC_ID_SND_200) + sizeof(u32))
static u32 PRC_ID_RCV_200[] =
static const u32 PRC_ID_RCV_200[] =
{
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9413168, 0xA8C12FEA
};
static u32 PRC_ID_SND_300[] =
static const u32 PRC_ID_SND_300[] =
{
0xA9BF2FEA, 0x2A1803EB, 0xD37EF56B, 0xF86B6B8B, 0x92FFFFE9, 0x8A090168, 0xD2FFFFE9, 0x8A09016B,
0xD2FFFFC9, 0xEB09017F, 0x54000040, 0xF9415548, 0xA8C12FEA
};
#define CODE_OFF_2ND_300 (CODE_OFF_1ST_300 + sizeof(PRC_ID_SND_300) + sizeof(u32))
static u32 PRC_ID_RCV_300[] =
static const u32 PRC_ID_RCV_300[] =
{
0xA9BF2FEA, 0x2A0F03EA, 0xD37EF54A, 0xF9405FEB, 0xF86A696A, 0xF9407BEB, 0x92FFFFE9, 0x8A090148,
0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415568, 0xA8C12FEA
@ -101,52 +101,52 @@ static u32 PRC_ID_RCV_300[] =
#define CODE_OFF_2ND_302 (CODE_OFF_1ST_302 + sizeof(PRC_ID_SND_300) + sizeof(u32))
static u32 PRC_ID_SND_400[] =
static const u32 PRC_ID_SND_400[] =
{
0x2A1703EA, 0xD37EF54A, 0xF86A6B8A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
0xEB09015F, 0x54000060, 0xF94053EA, 0xF9415948, 0xF94053EA
};
#define CODE_OFF_2ND_400 (CODE_OFF_1ST_400 + sizeof(PRC_ID_SND_400) + sizeof(u32))
static u32 PRC_ID_RCV_400[] =
static const u32 PRC_ID_RCV_400[] =
{
0xF9403BED, 0x2A0E03EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B28, 0xD503201F
};
static u32 PRC_ID_SND_500[] =
static const u32 PRC_ID_SND_500[] =
{
0x2A1703EA, 0xD37EF54A, 0xF86A6B6A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9,
0xEB09015F, 0x54000060, 0xF94043EA, 0xF9415948, 0xF94043EA
};
#define CODE_OFF_2ND_500 (CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500) + sizeof(u32))
static u32 PRC_ID_RCV_500[] =
static const u32 PRC_ID_RCV_500[] =
{
0xF9403BED, 0x2A1503EA, 0xD37EF54A, 0xF86A69AA, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A,
0xD2FFFFC9, 0xEB09015F, 0x54000040, 0xF9415B08, 0xF9406FEA
};
static u32 PRC_ID_SND_600[] =
static const u32 PRC_ID_SND_600[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_600 (CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600) + sizeof(u32))
static u32 PRC_ID_RCV_600[] =
static const u32 PRC_ID_RCV_600[] =
{
0xA9BF2FEA, 0xF94043EB, 0x2A1503EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_700[] =
static const u32 PRC_ID_SND_700[] =
{
0xA9BF2FEA, 0xF9403BEB, 0x2A1903EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_700 (CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700) + sizeof(u32))
static u32 PRC_ID_RCV_700[] =
static const u32 PRC_ID_RCV_700[] =
{
0xA9BF2FEA, 0xF9404FEB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
@ -155,56 +155,56 @@ static u32 PRC_ID_RCV_700[] =
#define CODE_OFF_2ND_800 (CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700) + sizeof(u32))
static u32 PRC_ID_SND_900[] =
static const u32 PRC_ID_SND_900[] =
{
0xA9BF2FEA, 0xF94037EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_900 (CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900) + sizeof(u32))
static u32 PRC_ID_RCV_900[] =
static const u32 PRC_ID_RCV_900[] =
{
0xA9BF2FEA, 0xF9404BEB, 0x2A1703EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400368, 0xF9401D08, 0xAA1B03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1000[] =
static const u32 PRC_ID_SND_1000[] =
{
0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1000 (CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000) + sizeof(u32))
static u32 PRC_ID_RCV_1000[] =
static const u32 PRC_ID_RCV_1000[] =
{
0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1100[] =
static const u32 PRC_ID_SND_1100[] =
{
0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1100 (CODE_OFF_1ST_1100 + sizeof(PRC_ID_SND_1100) + sizeof(u32))
static u32 PRC_ID_RCV_1100[] =
static const u32 PRC_ID_RCV_1100[] =
{
0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1200[] =
static const u32 PRC_ID_SND_1200[] =
{
0xA9BF2FEA, 0xF9404FEB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002C8, 0xF9401D08, 0xAA1603E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define CODE_OFF_2ND_1200 (CODE_OFF_1ST_1200 + sizeof(PRC_ID_SND_1200) + sizeof(u32))
static u32 PRC_ID_RCV_1200[] =
static const u32 PRC_ID_RCV_1200[] =
{
0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
@ -448,354 +448,354 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
};
// All kip patch offsets are without the 0x100-sized header.
static kip1_patchset_t _fs_patches_100[] = {
static const kip1_patchset_t _fs_patches_100[] = {
{ "nogc", NULL },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_40x[] = {
static const kip1_patch_t _fs_nogc_40x[] = {
{ KPS(KIP_TEXT) | 0xA3458, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
{ KPS(KIP_TEXT) | 0xAAB44, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_40x[] = {
static const kip1_patchset_t _fs_patches_40x[] = {
{ "nogc", _fs_nogc_40x },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_410[] = {
static const kip1_patch_t _fs_nogc_410[] = {
{ KPS(KIP_TEXT) | 0xA34BC, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x72" },
{ KPS(KIP_TEXT) | 0xAABA8, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_410[] = {
static const kip1_patchset_t _fs_patches_410[] = {
{ "nogc", _fs_nogc_410 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_50x[] = {
static const kip1_patch_t _fs_nogc_50x[] = {
{ KPS(KIP_TEXT) | 0xCF3C4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ KPS(KIP_TEXT) | 0xD73A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_50x[] = {
static const kip1_patchset_t _fs_patches_50x[] = {
{ "nogc", _fs_nogc_50x },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_510[] = {
static const kip1_patch_t _fs_nogc_510[] = {
{ KPS(KIP_TEXT) | 0xCF794, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ KPS(KIP_TEXT) | 0xD7770, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_510[] = {
static const kip1_patchset_t _fs_patches_510[] = {
{ "nogc", _fs_nogc_510 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_600[] = {
static const kip1_patch_t _fs_nogc_600[] = {
{ KPS(KIP_TEXT) | 0x12CC20, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1538F4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patch_t _fs_nogc_600_exfat[] = {
static const kip1_patch_t _fs_nogc_600_exfat[] = {
{ KPS(KIP_TEXT) | 0x138320, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EFF4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_600[] = {
static const kip1_patchset_t _fs_patches_600[] = {
{ "nogc", _fs_nogc_600 },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_600_exfat[] = {
static const kip1_patchset_t _fs_patches_600_exfat[] = {
{ "nogc", _fs_nogc_600_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_700[] = {
static const kip1_patch_t _fs_nogc_700[] = {
{ KPS(KIP_TEXT) | 0x134160, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15BF04, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patch_t _fs_nogc_700_exfat[] = {
static const kip1_patch_t _fs_nogc_700_exfat[] = {
{ KPS(KIP_TEXT) | 0x13F710, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1674B4, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_700[] = {
static const kip1_patchset_t _fs_patches_700[] = {
{ "nogc", _fs_nogc_700 },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_700_exfat[] = {
static const kip1_patchset_t _fs_patches_700_exfat[] = {
{ "nogc", _fs_nogc_700_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_800[] = {
static const kip1_patch_t _fs_nogc_800[] = {
{ KPS(KIP_TEXT) | 0x136800, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x15EB94, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patch_t _fs_nogc_800_exfat[] = {
static const kip1_patch_t _fs_nogc_800_exfat[] = {
{ KPS(KIP_TEXT) | 0x141DB0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x16A144, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_800[] = {
static const kip1_patchset_t _fs_patches_800[] = {
{ "nogc", _fs_nogc_800 },
{ NULL, NULL }
};
static kip1_patchset_t _fs_patches_800_exfat[] = {
static const kip1_patchset_t _fs_patches_800_exfat[] = {
{ "nogc", _fs_nogc_800_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_900[] = {
static const kip1_patch_t _fs_nogc_900[] = {
{ KPS(KIP_TEXT) | 0x129420, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_900[] = {
static const kip1_patchset_t _fs_patches_900[] = {
{ "nogc", _fs_nogc_900 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_910[] = {
static const kip1_patch_t _fs_nogc_910[] = {
{ KPS(KIP_TEXT) | 0x129430, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x143278, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_910[] = {
static const kip1_patchset_t _fs_patches_910[] = {
{ "nogc", _fs_nogc_910 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1000[] = {
static const kip1_patch_t _fs_nogc_1000[] = {
{ KPS(KIP_TEXT) | 0x13BE90, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14DE08, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1000[] = {
static const kip1_patchset_t _fs_patches_1000[] = {
{ "nogc", _fs_nogc_1000 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1020[] = {
static const kip1_patch_t _fs_nogc_1020[] = {
{ KPS(KIP_TEXT) | 0x13C2F0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14E268, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1020[] = {
static const kip1_patchset_t _fs_patches_1020[] = {
{ "nogc", _fs_nogc_1020 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1100[] = {
static const kip1_patch_t _fs_nogc_1100[] = {
{ KPS(KIP_TEXT) | 0x1398B4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x156EB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1100[] = {
static const kip1_patchset_t _fs_patches_1100[] = {
{ "nogc", _fs_nogc_1100 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1200[] = {
static const kip1_patch_t _fs_nogc_1200[] = {
{ KPS(KIP_TEXT) | 0x13EA24, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155368, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1200[] = {
static const kip1_patchset_t _fs_patches_1200[] = {
{ "nogc", _fs_nogc_1200 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1203[] = {
static const kip1_patch_t _fs_nogc_1203[] = {
{ KPS(KIP_TEXT) | 0x13EB34, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155478, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1203[] = {
static const kip1_patchset_t _fs_patches_1203[] = {
{ "nogc", _fs_nogc_1203 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1300[] = {
static const kip1_patch_t _fs_nogc_1300[] = {
{ KPS(KIP_TEXT) | 0x1425D0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x159018, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1300[] = {
static const kip1_patchset_t _fs_patches_1300[] = {
{ "nogc", _fs_nogc_1300 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1310[] = {
static const kip1_patch_t _fs_nogc_1310[] = {
{ KPS(KIP_TEXT) | 0x142570, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x158FB8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1310[] = {
static const kip1_patchset_t _fs_patches_1310[] = {
{ "nogc", _fs_nogc_1310 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1400[] = {
static const kip1_patch_t _fs_nogc_1400[] = {
{ KPS(KIP_TEXT) | 0x164230, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18A2E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1400[] = {
static const kip1_patchset_t _fs_patches_1400[] = {
{ "nogc", _fs_nogc_1400 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1400_exfat[] = {
static const kip1_patch_t _fs_nogc_1400_exfat[] = {
{ KPS(KIP_TEXT) | 0x16F5B0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195668, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1400_exfat[] = {
static const kip1_patchset_t _fs_patches_1400_exfat[] = {
{ "nogc", _fs_nogc_1400_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1500[] = {
static const kip1_patch_t _fs_nogc_1500[] = {
{ KPS(KIP_TEXT) | 0x15ECE4, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x184158, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1500[] = {
static const kip1_patchset_t _fs_patches_1500[] = {
{ "nogc", _fs_nogc_1500 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1500_exfat[] = {
static const kip1_patch_t _fs_nogc_1500_exfat[] = {
{ KPS(KIP_TEXT) | 0x169C74, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18F0E8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1500_exfat[] = {
static const kip1_patchset_t _fs_patches_1500_exfat[] = {
{ "nogc", _fs_nogc_1500_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1600[] = {
static const kip1_patch_t _fs_nogc_1600[] = {
{ KPS(KIP_TEXT) | 0x160B70, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1865D8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1600[] = {
static const kip1_patchset_t _fs_patches_1600[] = {
{ "nogc", _fs_nogc_1600 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1600_exfat[] = {
static const kip1_patch_t _fs_nogc_1600_exfat[] = {
{ KPS(KIP_TEXT) | 0x16B850, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x1912B8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1600_exfat[] = {
static const kip1_patchset_t _fs_patches_1600_exfat[] = {
{ "nogc", _fs_nogc_1600_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1603[] = {
static const kip1_patch_t _fs_nogc_1603[] = {
{ KPS(KIP_TEXT) | 0x160BC0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x186628, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1603[] = {
static const kip1_patchset_t _fs_patches_1603[] = {
{ "nogc", _fs_nogc_1603 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1603_exfat[] = {
static const kip1_patch_t _fs_nogc_1603_exfat[] = {
{ KPS(KIP_TEXT) | 0x16B8A0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x191308, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1603_exfat[] = {
static const kip1_patchset_t _fs_patches_1603_exfat[] = {
{ "nogc", _fs_nogc_1603_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1700[] = {
static const kip1_patch_t _fs_nogc_1700[] = {
{ KPS(KIP_TEXT) | 0x165100, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18B048, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1700[] = {
static const kip1_patchset_t _fs_patches_1700[] = {
{ "nogc", _fs_nogc_1700 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1700_exfat[] = {
static const kip1_patch_t _fs_nogc_1700_exfat[] = {
{ KPS(KIP_TEXT) | 0x16FF60, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195EA8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1700_exfat[] = {
static const kip1_patchset_t _fs_patches_1700_exfat[] = {
{ "nogc", _fs_nogc_1700_exfat },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1800[] = {
static const kip1_patch_t _fs_nogc_1800[] = {
{ KPS(KIP_TEXT) | 0x164A50, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x18AE48, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1800[] = {
static const kip1_patchset_t _fs_patches_1800[] = {
{ "nogc", _fs_nogc_1800 },
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1800_exfat[] = {
static const kip1_patch_t _fs_nogc_1800_exfat[] = {
{ KPS(KIP_TEXT) | 0x16FAE0, 8, KIP1_PATCH_SRC_NO_CHECK, "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x195ED8, 4, KIP1_PATCH_SRC_NO_CHECK, "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1800_exfat[] = {
static const kip1_patchset_t _fs_patches_1800_exfat[] = {
{ "nogc", _fs_nogc_1800_exfat },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
static const kip1_id_t _kip_ids[] =
{
{ "FS", "\xde\x9f\xdd\xa4\x08\x5d\xd5\xfe", _fs_patches_100 }, // FS 1.0.0
{ "FS", "\xfc\x3e\x80\x99\x1d\xca\x17\x96", _fs_patches_100 }, // FS 1.0.0 exFAT
@ -855,4 +855,6 @@ static kip1_id_t _kip_ids[] =
{ "FS", "\xEE\x0F\x4B\xAC\x6D\x1F\xFC\x4B", _fs_patches_1700_exfat }, // FS 17.0.0 exFAT
{ "FS", "\x79\x5F\x5A\x5E\xB0\xC6\x77\x9E", _fs_patches_1800 }, // FS 18.0.0
{ "FS", "\x1E\x2C\x64\xB1\xCC\xE2\x78\x24", _fs_patches_1800_exfat }, // FS 18.0.0 exFAT
{ "FS", "\xA3\x39\xF0\x1C\x95\xBF\xA7\x68", _fs_patches_1800 }, // FS 18.1.0
{ "FS", "\x20\x4C\xBA\x86\xDE\x08\x44\x6A", _fs_patches_1800_exfat }, // FS 18.1.0 exFAT
};

View File

@ -1151,7 +1151,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
_l4t_mc_config_carveout(t210b01);
// Deinit any unneeded HW.
hw_reinit_workaround(false, BL_MAGIC_L4TLDR_SLD);
hw_deinit(false, BL_MAGIC_L4TLDR_SLD);
// Do late hardware config.
_l4t_late_hw_config(t210b01);

View File

@ -46,44 +46,7 @@ const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage)
{
static char emmc_sn[9] = {0};
// Check if not valid S/N and get actual eMMC S/N.
if (!storage && !emmc_sn[0])
{
if (!emmc_initialize(false))
strcpy(emmc_sn, "00000000");
else
{
itoa(emmc_storage.cid.serial, emmc_sn, 16);
emmc_end();
}
}
else
itoa(storage->cid.serial, emmc_sn, 16);
// Create main folder.
strcpy(path, "backup");
f_mkdir(path);
// Create eMMC S/N folder.
strcat(path, "/");
strcat(path, emmc_sn);
f_mkdir(path);
// Create sub folder if defined. Dir slash must be included.
strcat(path, sub_dir); // Can be a null-terminator.
if (strlen(sub_dir))
f_mkdir(path);
// Add filename.
strcat(path, "/");
strcat(path, filename); // Can be a null-terminator.
}
void check_power_off_from_hos()
static void _check_power_off_from_hos()
{
// Power off on alarm wakeup from HOS shutdown. For modchips/dongles.
u8 hos_wakeup = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_IRQTOP);
@ -252,7 +215,7 @@ static void _launch_payload(char *path, bool update, bool clear_screen)
else
_reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
hw_deinit(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
}
else
{
@ -262,18 +225,20 @@ static void _launch_payload(char *path, bool update, bool clear_screen)
u32 magic = 0;
char *magic_ptr = buf + COREBOOT_VER_OFF;
memcpy(&magic, magic_ptr + strlen(magic_ptr) - 4, 4);
hw_reinit_workaround(true, magic);
hw_deinit(true, magic);
}
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
sdmmc_storage_init_wait_sd();
void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR;
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
// Launch our payload.
if (!update)
{
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
sdmmc_storage_init_wait_sd();
(*ext_payload_ptr)();
}
else
{
// Set updated flag to skip check on launch.
@ -292,20 +257,18 @@ out:
static void _launch_payloads()
{
u8 max_entries = 61;
ment_t *ments = NULL;
char *filelist = NULL;
char *file_sec = NULL;
char *dir = NULL;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
if (!sd_mount())
{
free(ments);
goto failed_sd_mount;
}
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
dir = (char *)malloc(256);
memcpy(dir, "bootloader/payloads", 20);
@ -354,9 +317,6 @@ static void _launch_payloads()
else
EPRINTF("No payloads found.");
free(ments);
free(filelist);
if (file_sec)
{
memcpy(dir + strlen(dir), "/", 2);
@ -366,8 +326,10 @@ static void _launch_payloads()
}
failed_sd_mount:
sd_end();
free(dir);
free(ments);
free(filelist);
sd_end();
btn_wait();
}
@ -377,6 +339,7 @@ static void _launch_ini_list()
u8 max_entries = 61;
char *special_path = NULL;
char *emummc_path = NULL;
ment_t *ments = NULL;
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_list_sections);
@ -395,7 +358,7 @@ static void _launch_ini_list()
}
// Build configuration menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
@ -458,7 +421,6 @@ static void _launch_ini_list()
}
else
EPRINTF("No extra configs found.");
free(ments);
parse_failed:
if (!cfg_sec)
@ -494,6 +456,7 @@ wrong_emupath:
}
out:
free(ments);
btn_wait();
}
@ -504,7 +467,9 @@ static void _launch_config()
char *special_path = NULL;
char *emummc_path = NULL;
ment_t *ments = NULL;
ini_sec_t *cfg_sec = NULL;
LIST_INIT(ini_sections);
gfx_clear_grey(0x1B);
@ -520,7 +485,7 @@ static void _launch_config()
ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false);
// Build configuration menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 6));
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 6));
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
@ -597,8 +562,6 @@ static void _launch_config()
return;
}
free(ments);
parse_failed:
if (!cfg_sec)
{
@ -638,6 +601,8 @@ wrong_emupath:
out:
sd_end();
free(ments);
h_cfg.emummc_force_disable = false;
btn_wait();
@ -885,7 +850,7 @@ static void _auto_launch()
}
if (h_cfg.autohosoff && !(b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN))
check_power_off_from_hos();
_check_power_off_from_hos();
if (h_cfg.autoboot_list || (boot_from_id && !cfg_sec))
{
@ -1295,7 +1260,7 @@ static void _check_low_battery()
if (!screen_on)
{
display_init();
u32 *fb = display_init_framebuffer_pitch();
u32 *fb = display_init_window_a_pitch();
gfx_init_ctxt(fb, 720, 1280, 720);
gfx_set_rect_rgb(battery_icon, BATTERY_EMPTY_WIDTH, BATTERY_EMPTY_BATT_HEIGHT, 16, battery_icon_y_pos);
@ -1332,7 +1297,7 @@ out:
max77620_low_battery_monitor_config(true);
}
static void _r2p_get_config_t210b01()
static void _r2c_get_config_t210b01()
{
rtc_reboot_reason_t rr;
if (!max77620_rtc_get_reboot_reason(&rr))
@ -1372,7 +1337,7 @@ static void _r2p_get_config_t210b01()
static void _ipl_reload()
{
hw_reinit_workaround(false, 0);
hw_deinit(false, 0);
// Reload hekate.
void (*ipl_ptr)() = (void *)IPL_LOAD_ADDR;
@ -1383,7 +1348,7 @@ static void _about()
{
static const char credits[] =
"\nhekate (c) 2018, naehrwert, st4rk\n\n"
" (c) 2018-2023, CTCaer\n\n"
" (c) 2018-2024, CTCaer\n\n"
" ___________________________________________\n\n"
"Thanks to: %kderrek, nedwill, plutoo,\n"
" shuffle2, smea, thexyz, yellows8%k\n"
@ -1393,11 +1358,12 @@ static void _about()
" ___________________________________________\n\n"
"Open source and free packages used:\n\n"
" - FatFs R0.13c\n"
" (c) 2018, ChaN\n\n"
" (c) 2006-2018, ChaN\n"
" (c) 2018-2022, CTCaer\n\n"
" - bcl-1.2.0\n"
" (c) 2003-2006, Marcus Geelnard\n\n"
" - Atmosphere (Exo st/types, prc id patches)\n"
" (c) 2018-2019, Atmosphere-NX\n\n"
" - blz\n"
" (c) 2018, SciresM\n\n"
" - elfload\n"
" (c) 2014, Owen Shepherd\n"
" (c) 2018, M4xw\n"
@ -1478,7 +1444,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate v6.1.1", 0, 0 };
menu_t menu_top = { ment_top, "hekate v6.2.0", 0, 0 };
extern void pivot_stack(u32 stack_top);
@ -1487,10 +1453,10 @@ void ipl_main()
// Do initial HW configuration. This is compatible with consecutive reruns without a reset.
hw_init();
// Pivot the stack so we have enough space.
pivot_stack(IPL_STACK_TOP);
// Pivot the stack under IPL. (Only max 4KB is needed).
pivot_stack(IPL_LOAD_ADDR);
// Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between.
// Place heap at a place outside of L4T/HOS configuration and binaries.
heap_init((void *)IPL_HEAP_START);
#ifdef DEBUG_UART_PORT
@ -1504,12 +1470,15 @@ void ipl_main()
// Set bootloader's default configuration.
set_default_configuration();
// Prep RTC regs for read. Needed for T210B01 R2P.
// Prep RTC regs for read. Needed for T210B01 R2C.
max77620_rtc_prep_read();
// Initialize display.
display_init();
// Overclock BPMP.
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Mount SD Card.
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
@ -1534,19 +1503,17 @@ void ipl_main()
skip_lp0_minerva_config:
// Initialize display window, backlight and gfx console.
u32 *fb = display_init_framebuffer_pitch();
u32 *fb = display_init_window_a_pitch();
gfx_init_ctxt(fb, 720, 1280, 720);
gfx_con_init();
// Initialize backlight PWM.
display_backlight_pwm_init();
//display_backlight_brightness(h_cfg.backlight, 1000);
// Overclock BPMP.
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Get R2P config from RTC.
// Get R2C config from RTC.
if (h_cfg.t210b01)
_r2p_get_config_t210b01();
_r2c_get_config_t210b01();
// Show exceptions, HOS errors, library errors and L4T kernel panics.
_show_errors();

View File

@ -60,7 +60,8 @@ _reloc_ipl:
BX R3
_real_start:
/* Initially, we place our stack in IRAM but will move it to SDRAM later. */
/* Initially, we place our stack under relocator but will move it to under the payload. */
/* This depends on application scope. */
LDR SP, =0x4003FF00
LDR R0, =__bss_start
EOR R1, R1, R1

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,
@ -37,7 +37,7 @@ const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver
.rsvd1 = 0
};
const volatile char __attribute__((section ("._octopus"))) octopus[] =
const char __attribute__((section ("._octopus"))) octopus[] =
"\n"
" ___\n"
" .-' `'.\n"
@ -67,6 +67,12 @@ void loader_main()
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).
// Set arbiter.
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;
// Get Payload size.
u32 payload_size = sizeof(payload_00) + sizeof(payload_01); // Actual payload size.
payload_size += (u32)payload_01 - (u32)payload_00 - sizeof(payload_00); // Add compiler alignment.

View File

@ -28,7 +28,7 @@ $(BUILD)/%.o: ./%.c
$(TARGET).bso: $(OBJS)
@$(CC) $(LDFLAGS) -e _modInit $^ -o $(OUTPUT)/$(TARGET).bso
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
@echo -e "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
clean:
@rm -rf $(OUTPUT)/$(TARGET).bso

View File

@ -981,6 +981,7 @@ struct sdram_params_t210b01
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 mc_mts_carveout_reg_ctrl;
/* Specifies the clients that are allowed to access untranslated memory */
u32 mc_untranslated_region_check;
/* Just a place holder for special usage when there is no BCT for certain registers */

View File

@ -28,7 +28,7 @@ $(BUILD)/%.o: ./%.c
$(TARGET).bso: $(OBJS)
@$(CC) $(LDFLAGS) -e _minerva_init $^ -o $(OUTPUT)/$(TARGET).bso
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
@echo -e "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
clean:
@rm -rf $(OUTPUT)/$(TARGET).bso

View File

@ -35,7 +35,7 @@ $(BUILD)/%.o: ./%.c
$(TARGET).bso: $(OBJS)
@$(CC) $(LDFLAGS) -e _modInit $^ -o $(OUTPUT)/$(TARGET).bso
@$(STRIP) -g $(OUTPUT)/$(TARGET).bso
@echo "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
@echo -e "-------------\nBuilt module: "$(TARGET)".bso\n-------------"
clean:
@rm -rf $(OUTPUT)/$(TARGET).bso

View File

@ -145,7 +145,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
u32 prevPct = 200;
u32 sdFileSector = 0;
int res = 0;
const char hexa[] = "0123456789abcdef";
static const char hexa[] = "0123456789abcdef";
DWORD *clmt = NULL;
u8 hashEm[SE_SHA_256_SIZE];
@ -340,8 +340,8 @@ bool partial_sd_full_unmount = false;
static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part, sdmmc_storage_t *storage, emmc_part_t *part)
{
const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
const u32 SECTORS_TO_MIB_COEFF = 11;
static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF;
static const u32 SECTORS_TO_MIB_COEFF = 11;
partial_sd_full_unmount = false;
@ -942,7 +942,7 @@ out:
static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_part, sdmmc_storage_t *storage, emmc_part_t *part, bool allow_multi_part)
{
const u32 SECTORS_TO_MIB_COEFF = 11;
static const u32 SECTORS_TO_MIB_COEFF = 11;
u32 lba_end = part->lba_end;
u32 totalSectors = part->lba_end - part->lba_start + 1;

View File

@ -64,7 +64,8 @@ char *text_color;
typedef struct _jc_lv_driver_t
{
lv_indev_t *indev;
lv_indev_t *indev_jc;
lv_indev_t *indev_touch;
// LV_INDEV_READ_PERIOD * JC_CAL_MAX_STEPS = 264 ms.
#define JC_CAL_MAX_STEPS 8
u32 calibration_step;
@ -107,10 +108,10 @@ static void _nyx_disp_init()
vic_compose();
// Switch to new window configuration.
display_init_framebuffer_pitch_vic();
display_init_window_a_pitch_vic();
// Enable logging on window D.
display_init_framebuffer_log();
display_init_window_d_console();
// Switch back the backlight.
display_backlight_brightness(h_cfg.backlight - 20, 1000);
}
@ -463,7 +464,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
{
if (!console_enabled)
{
display_activate_console();
display_window_d_console_enable();
console_enabled = true;
gfx_con_getpos(&gfx_con.savedx, &gfx_con.savedy, &gfx_con.savedcol);
gfx_con_setpos(964, 630, GFX_COL_AUTO);
@ -472,7 +473,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
}
else
{
display_deactivate_console();
display_window_d_console_disable();
console_enabled = false;
}
@ -489,10 +490,9 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
gfx_con_getpos(&gfx_con.savedx, &gfx_con.savedy, &gfx_con.savedcol);
gfx_con_setpos(32, 630, GFX_COL_AUTO);
gfx_con.fntsz = 8;
gfx_printf("x: %4X, y: %4X | b: %06X | bt: %d %d | cx: %03X - %03X, cy: %03X - %03X",
jc_pad->lstick_x, jc_pad->lstick_y, jc_pad->buttons,
jc_pad->batt_info_l, jc_pad->batt_info_r,
jc_drv_ctx.cx_min, jc_drv_ctx.cx_max, jc_drv_ctx.cy_min, jc_drv_ctx.cy_max);
gfx_printf("x: %4X, y: %4X | rx: %4X, ry: %4X | b: %06X | bt: %d %d",
jc_pad->lstick_x, jc_pad->lstick_y, jc_pad->rstick_x, jc_pad->rstick_y,
jc_pad->buttons, jc_pad->batt_info_l, jc_pad->batt_info_r);
gfx_con_setpos(gfx_con.savedx, gfx_con.savedy, gfx_con.savedcol);
gfx_con.fntsz = 16;
@ -585,7 +585,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
jc_drv_ctx.cursor_hidden = false;
jc_drv_ctx.cursor_timeout = get_tmr_ms();
lv_indev_set_cursor(jc_drv_ctx.indev, jc_drv_ctx.cursor);
lv_indev_set_cursor(jc_drv_ctx.indev_jc, jc_drv_ctx.cursor);
// Un hide cursor.
lv_obj_set_opa_scale_enable(jc_drv_ctx.cursor, false);
@ -597,7 +597,7 @@ static bool _jc_virt_mouse_read(lv_indev_data_t *data)
if (((u32)get_tmr_ms() - jc_drv_ctx.cursor_timeout) > 3000)
{
// Remove cursor and hide it.
lv_indev_set_cursor(jc_drv_ctx.indev, NULL);
lv_indev_set_cursor(jc_drv_ctx.indev_jc, NULL);
lv_obj_set_opa_scale_enable(jc_drv_ctx.cursor, true);
lv_obj_set_opa_scale(jc_drv_ctx.cursor, LV_OPA_TRANSP);
@ -923,7 +923,7 @@ static void _launch_hos(u8 autoboot, u8 autoboot_list)
sd_end();
hw_reinit_workaround(false, 0);
hw_deinit(false, 0);
(*main_ptr)();
}
@ -939,10 +939,7 @@ void reload_nyx()
sd_end();
hw_reinit_workaround(false, 0);
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
sdmmc_storage_init_wait_sd();
hw_deinit(false, 0);
(*main_ptr)();
}
@ -1235,9 +1232,9 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
lv_label_set_recolor(lbl_credits, true);
lv_label_set_static_text(lbl_credits,
"#C7EA46 hekate# (c) 2018, #C7EA46 naehrwert#, #C7EA46 st4rk#\n"
" (c) 2018-2023, #C7EA46 CTCaer#\n"
" (c) 2018-2024, #C7EA46 CTCaer#\n"
"\n"
"#C7EA46 Nyx GUI# (c) 2019-2023, #C7EA46 CTCaer#\n"
"#C7EA46 Nyx# (c) 2019-2024, #C7EA46 CTCaer#\n"
"\n"
"Thanks to: #00CCFF derrek, nedwill, plutoo, #\n"
" #00CCFF shuffle2, smea, thexyz, yellows8 #\n"
@ -1245,18 +1242,19 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
"Greetings to: fincs, hexkyz, SciresM,\n"
" Shiny Quagsire, WinterMute\n"
"\n"
"Open source and free packages used:\n\n"
"Open source and free packages used: \n" // Label width alignment padding.
" - Littlev Graphics Library,\n"
" Copyright (c) 2016-2018, Gabor Kiss-Vamosi\n\n"
" - FatFs R0.13c,\n"
" Copyright (c) 2018, ChaN\n\n"
" Copyright (c) 2006-2018, ChaN\n"
" Copyright (c) 2018-2022, CTCaer\n\n"
" - bcl-1.2.0,\n"
" Copyright (c) 2003-2006, Marcus Geelnard\n\n"
" - Atmosphere (Exosphere types/panic, proc id patches),\n"
" Copyright (c) 2018-2019, Atmosphere-NX\n\n"
" - blz,\n"
" Copyright (c) 2018, SciresM\n\n"
" - elfload,\n"
" Copyright (c) 2014, Owen Shepherd\n"
" Copyright (c) 2018, M4xw\n\n"
" - Littlev Graphics Library,\n"
" Copyright (c) 2016 Gabor Kiss-Vamosi"
" Copyright (c) 2018, M4xw"
);
lv_obj_t * lbl_octopus = lv_label_create(parent, NULL);
@ -1321,15 +1319,8 @@ static void _update_status_bar(void *params)
max17050_get_property(MAX17050_Current, &batt_curr);
// Enable fan if more than 41 oC.
u32 soc_temp_dec = (soc_temp >> 8);
if (soc_temp_dec > 51)
set_fan_duty(102);
else if (soc_temp_dec > 46)
set_fan_duty(76);
else if (soc_temp_dec > 41)
set_fan_duty(51);
else if (soc_temp_dec < 40)
set_fan_duty(0);
u32 soc_temp_dec = soc_temp >> 8;
fan_set_from_temp(soc_temp_dec);
if (!label)
label = (char *)malloc(512);
@ -2431,7 +2422,7 @@ void nyx_load_and_run()
indev_drv_jc.type = LV_INDEV_TYPE_POINTER;
indev_drv_jc.read = _jc_virt_mouse_read;
memset(&jc_drv_ctx, 0, sizeof(jc_lv_driver_t));
jc_drv_ctx.indev = lv_indev_drv_register(&indev_drv_jc);
jc_drv_ctx.indev_jc = lv_indev_drv_register(&indev_drv_jc);
close_btn = NULL;
// Initialize touch.
@ -2440,7 +2431,7 @@ void nyx_load_and_run()
lv_indev_drv_init(&indev_drv_touch);
indev_drv_touch.type = LV_INDEV_TYPE_POINTER;
indev_drv_touch.read = _fts_touch_read;
lv_indev_drv_register(&indev_drv_touch);
jc_drv_ctx.indev_touch = lv_indev_drv_register(&indev_drv_touch);
touchpad.touch = false;
// Initialize temperature sensor.

View File

@ -917,7 +917,8 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
else
strcat(txt_buf, "#FFDD00 Error!#");
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# %08X (", touch_fw.fw_id);
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# %02X.%02X.%02X.%02X (",
(touch_fw.fw_id >> 24) & 0xFF, (touch_fw.fw_id >> 16) & 0xFF, (touch_fw.fw_id >> 8) & 0xFF, touch_fw.fw_id & 0xFF);
// Check panel pair info.
switch (touch_fw.fw_id)
@ -1627,10 +1628,11 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
break;
}
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c\n%d.%d\n%04X\n%02d/%04d\n\n",
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c (%02X)\n%d.%d\n%04X\n%02d/%04d\n\n",
emmc_storage.cid.manfid,
emmc_storage.cid.prod_name[0], emmc_storage.cid.prod_name[1], emmc_storage.cid.prod_name[2],
emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5],
emmc_storage.cid.oemid,
emmc_storage.cid.prv & 0xF, emmc_storage.cid.prv >> 4,
emmc_storage.cid.serial, emmc_storage.cid.month, emmc_storage.cid.year);
@ -1741,10 +1743,10 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
u32 boot_size = emmc_storage.ext_csd.boot_mult << 17;
u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17;
strcpy(txt_buf, "#00DDFF eMMC Physical Partitions:#\n");
s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB (Sect: 0x%08X)\n", rpmb_size / 1024, rpmb_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB (Sect: 0x%08X)\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt);
s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB Sectors: 0x%08X\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB Sectors: 0x%08X\n", boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB Sectors: 0x%08X\n", rpmb_size / 1024, rpmb_size / EMMC_BLOCKSIZE);
s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB Sectors: 0x%08X\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt);
strcat(txt_buf, "\n#00DDFF GPP (eMMC USER) Partition Table:#\n");
emmc_set_partition(EMMC_GPP);
@ -1752,28 +1754,31 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
emmc_gpt_parse(&gpt);
u32 idx = 0;
u32 lines_left = 20;
s_printf(txt_buf + strlen(txt_buf), "#FFBA00 Idx Name Size Offset Sectors#\n");
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link)
{
if (idx > 10)
int lines = strlen(part->name) > 25 ? 2 : 1;
if ((lines_left - lines) <= 0)
{
strcat(txt_buf, "#FFDD00 Table does not fit on screen!#");
break;
}
if (part->index < 2)
if (lines == 2)
{
s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#%s Size: %d MiB (Sect: 0x%X), Start: %06X\n",
part->index, part->name, !part->name[8] ? " " : "",
(part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF,
part->lba_end - part->lba_start + 1, part->lba_start);
s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#\n %6d MiB %8Xh %8Xh\n",
part->index, part->name, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF,
part->lba_start, part->lba_end - part->lba_start + 1);
}
else
{
s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#\n Size: %7d MiB (Sect: 0x%07X), Start: %07X\n",
s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %.25s# %6d MiB %8Xh %8Xh\n",
part->index, part->name, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF,
part->lba_end - part->lba_start + 1, part->lba_start);
part->lba_start, part->lba_end - part->lba_start + 1);
}
lines_left -= lines;
idx++;
}
if (!idx)

View File

@ -545,7 +545,7 @@ static lv_res_t _preset_hue_action(lv_obj_t *btn)
return LV_RES_OK;
}
const u16 theme_colors[17] = {
static const u16 theme_colors[17] = {
4, 13, 23, 33, 43, 54, 66, 89, 124, 167, 187, 200, 208, 231, 261, 291, 341
};

View File

@ -362,7 +362,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
sd_end();
minerva_change_freq(FREQ_800);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_clk_rate_relaxed(true);
display_backlight_brightness(10, 1000);
usb_ctxt_t usbs;
@ -374,7 +374,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Restore BPMP, RAM and backlight.
minerva_change_freq(FREQ_1600);
bpmp_clk_rate_set(prev_fid);
bpmp_clk_rate_relaxed(false);
display_backlight_brightness(h_cfg.backlight - 20, 1000);
return LV_RES_OK;
@ -386,7 +386,7 @@ static lv_res_t _action_hid_touch(lv_obj_t *btn)
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
sd_end();
minerva_change_freq(FREQ_800);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_clk_rate_relaxed(true);
display_backlight_brightness(10, 1000);
usb_ctxt_t usbs;
@ -398,7 +398,7 @@ static lv_res_t _action_hid_touch(lv_obj_t *btn)
// Restore BPMP, RAM and backlight.
minerva_change_freq(FREQ_1600);
bpmp_clk_rate_set(prev_fid);
bpmp_clk_rate_relaxed(false);
display_backlight_brightness(h_cfg.backlight - 20, 1000);
return LV_RES_OK;
@ -431,7 +431,7 @@ static lv_res_t _action_ums_emmc_boot0(lv_obj_t *btn)
usbs.type = MMC_EMMC;
usbs.partition = EMMC_BOOT0 + 1;
usbs.offset = 0;
usbs.sectors = 0x2000;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
@ -450,7 +450,7 @@ static lv_res_t _action_ums_emmc_boot1(lv_obj_t *btn)
usbs.type = MMC_EMMC;
usbs.partition = EMMC_BOOT1 + 1;
usbs.offset = 0;
usbs.sectors = 0x2000;
usbs.sectors = 0;
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
@ -516,7 +516,7 @@ static lv_res_t _action_ums_emuemmc_boot0(lv_obj_t *btn)
{
usbs.type = MMC_SD;
usbs.partition = EMMC_BOOT0 + 1;
usbs.sectors = 0x2000;
usbs.sectors = 0x2000; // Forced 4MB.
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;
@ -563,7 +563,7 @@ static lv_res_t _action_ums_emuemmc_boot1(lv_obj_t *btn)
{
usbs.type = MMC_SD;
usbs.partition = EMMC_BOOT1 + 1;
usbs.sectors = 0x2000;
usbs.sectors = 0x2000; // Forced 4MB.
usbs.ro = usb_msc_emmc_read_only;
usbs.system_maintenance = &manual_system_maintenance;
usbs.set_text = &usb_gadget_set_text;

View File

@ -267,7 +267,7 @@ out:
static void _create_gpt_partition(gpt_t *gpt, u8 *gpt_idx, u32 *curr_part_lba, u32 size_lba, char *name, int name_size)
{
const u8 linux_part_guid[] = { 0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4 };
static const u8 linux_part_guid[] = { 0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4 };
u8 random_number[16];
// Create GPT partition.
@ -985,7 +985,7 @@ static lv_res_t _action_reboot_recovery(lv_obj_t * btns, const char * txt)
// Deinit hardware.
sd_end();
hw_reinit_workaround(false, 0);
hw_deinit(false, 0);
// Chainload to hekate main.
(*main_ptr)();
@ -1844,7 +1844,7 @@ static lv_res_t _action_slider_emu(lv_obj_t *slider)
#define EMUMMC_32GB_FULL 29856
#define EMUMMC_64GB_FULL (59664 + 1) // 1MB extra for backup GPT.
const u32 rsvd_mb = 4 + 4 + 16 + 8; // BOOT0 + BOOT1 + 16MB offset + 8MB alignment.
static const u32 rsvd_mb = 4 + 4 + 16 + 8; // BOOT0 + BOOT1 + 16MB offset + 8MB alignment.
u32 size;
char lbl_text[64];
bool prev_emu_double = part_info.emu_double;

View File

@ -1,3 +1,19 @@
/*
* 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/>.
*/
#ifndef _LOGOS_GUI_H_
#define _LOGOS_GUI_H_
@ -374,7 +390,7 @@ const u8 touch_cursor_map[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
lv_img_dsc_t touch_cursor = {
const lv_img_dsc_t touch_cursor = {
.header.always_zero = 0,
.header.w = 33,
.header.h = 33,
@ -385,7 +401,7 @@ lv_img_dsc_t touch_cursor = {
#ifdef HEKATE_LOGO
lv_img_dsc_t hekate_logo = {
const lv_img_dsc_t hekate_logo = {
.header.always_zero = 0,
.header.w = 193,
.header.h = 76,
@ -394,7 +410,7 @@ lv_img_dsc_t hekate_logo = {
.data = (const uint8_t *)(NYX_RES_ADDR + 0x1D900),
};
lv_img_dsc_t ctcaer_logo = {
const lv_img_dsc_t ctcaer_logo = {
.header.always_zero = 0,
.header.w = 147,
.header.h = 76,

View File

@ -179,12 +179,12 @@ lv_res_t launch_payload(lv_obj_t *list)
if (size < 0x30000)
{
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
hw_deinit(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
}
else
{
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
hw_reinit_workaround(true, 0);
hw_deinit(true, 0);
}
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
@ -354,8 +354,8 @@ static void _show_errors(int sd_error)
gfx_clear_grey(0);
gfx_con_setpos(0, 0, 0);
display_backlight_brightness(150, 1000);
display_init_framebuffer_log();
display_activate_console();
display_init_window_d_console();
display_window_d_console_enable();
}
switch (sd_error)