mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2025-01-24 18:23:13 -03:00
Update BDK to Hekate 6.0.5
This commit is contained in:
parent
09fc492610
commit
ee6ea3e64c
103 changed files with 6271 additions and 3746 deletions
|
@ -19,5 +19,10 @@ For future reference if updating the BDK
|
|||
## /bdk/utils/ini.c
|
||||
- Added initial 'unknown' section to parse prod.keys
|
||||
|
||||
## /bdk/utils/types.h
|
||||
- Added colors from lockpick-rcm
|
||||
- Add ALWAYS_INLINE, LOG2, DIV_ROUND_UP defs
|
||||
- Add 'open_mode_t' and 'validity_t' enums
|
||||
|
||||
## /bdk/libs
|
||||
- Added nx-savedata from [Lockpick_RCM](https://github.com/shchmue/Lockpick_RCM)
|
|
@ -20,6 +20,7 @@
|
|||
#include <memory_map.h>
|
||||
|
||||
#include <display/di.h>
|
||||
#include <display/vic.h>
|
||||
#include <input/als.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
|
@ -51,6 +52,7 @@
|
|||
#include <soc/kfuse.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/uart.h>
|
||||
#include <storage/emmc.h>
|
||||
|
|
648
bdk/display/di.c
648
bdk/display/di.c
File diff suppressed because it is too large
Load diff
136
bdk/display/di.h
136
bdk/display/di.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -43,13 +43,17 @@
|
|||
|
||||
// DC_CMD non-shadowed command/sync registers.
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
#define SYNCPT_GENERAL_INDX(x) (((x) & 0xff) << 0)
|
||||
#define SYNCPT_GENERAL_COND(x) (((x) & 0xff) << 8)
|
||||
#define COND_REG_WR_SAFE 3
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_SOFT_RESET BIT(0)
|
||||
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
#define SYNCPT_VSYNC_INDX(x) (((x) & 0xff) << 0)
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
|
@ -72,6 +76,7 @@
|
|||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
||||
#define DC_CMD_INT_V_BLANK_INT BIT(2)
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX BIT(0)
|
||||
|
@ -98,7 +103,13 @@
|
|||
#define WINDOW_C_SELECT BIT(6)
|
||||
#define WINDOW_D_SELECT BIT(7)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x43
|
||||
#define GENERAL_ACT_HCNTR_SEL BIT(0)
|
||||
#define WIN_A_ACT_HCNTR_SEL BIT(2)
|
||||
#define WIN_B_ACT_HCNTR_SEL BIT(4)
|
||||
#define WIN_C_ACT_HCNTR_SEL BIT(6)
|
||||
#define CURSOR_ACT_HCNTR_SEL BIT(7)
|
||||
#define WIN_D_ACT_HCNTR_SEL BIT(10)
|
||||
|
||||
// DC_D_WIN_DD window D instance of DC_WIN
|
||||
#define DC_D_WIN_DD_WIN_OPTIONS 0x80
|
||||
|
@ -124,6 +135,7 @@
|
|||
#define DC_COM_CRC_CONTROL 0x300
|
||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
|
||||
|
||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||
|
||||
|
@ -139,12 +151,29 @@
|
|||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
|
||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||
#define VSYNC_H_POSITION(x) (((x) & 0x1fff) << 0)
|
||||
|
||||
#define DC_DISP_REF_TO_SYNC 0x406
|
||||
#define H_REF_TO_SYNC(x) (((x) & 0x1fff) << 0) // Min 0 pixel clock.
|
||||
#define V_REF_TO_SYNC(x) (((x) & 0x1fff) << 16) // Min 1 line clock.
|
||||
|
||||
#define DC_DISP_SYNC_WIDTH 0x407
|
||||
#define H_SYNC_WIDTH(x) (((x) & 0x1fff) << 0) // Min 1 pixel clock.
|
||||
#define V_SYNC_WIDTH(x) (((x) & 0x1fff) << 16) // Min 1 line clock.
|
||||
|
||||
#define DC_DISP_BACK_PORCH 0x408
|
||||
#define H_BACK_PORCH(x) (((x) & 0x1fff) << 0)
|
||||
#define V_BACK_PORCH(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_DISP_ACTIVE 0x409
|
||||
#define H_DISP_ACTIVE(x) (((x) & 0x1fff) << 0) // Min 16 pixel clock.
|
||||
#define V_DISP_ACTIVE(x) (((x) & 0x1fff) << 16) // Min 16 line clock.
|
||||
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
#define H_FRONT_PORCH(x) (((x) & 0x1fff) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1
|
||||
#define V_FRONT_PORCH(x) (((x) & 0x1fff) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
|
@ -239,6 +268,10 @@
|
|||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#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 DC_WINC_PALETTE_COLOR_EXT 0x600
|
||||
|
||||
#define DC_WIN_CSC_YOF 0x611
|
||||
#define DC_WIN_CSC_KYRGB 0x612
|
||||
#define DC_WIN_CSC_KUR 0x613
|
||||
|
@ -253,12 +286,13 @@
|
|||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define COLOR_PALETTE_ENABLE BIT(16)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define BUFFER_CONTROL_HOST 0
|
||||
|
@ -290,10 +324,22 @@
|
|||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||
#define WIN_COLOR_DEPTH_YCbCr444P 0x29
|
||||
#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A
|
||||
#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B
|
||||
#define WIN_COLOR_DEPTH_YCrCb422SP 0x2C
|
||||
#define WIN_COLOR_DEPTH_YCbCr422SP 0x2D
|
||||
#define WIN_COLOR_DEPTH_YUV444P 0x34
|
||||
#define WIN_COLOR_DEPTH_YVU420SP 0x35
|
||||
#define WIN_COLOR_DEPTH_YUV420SP 0x36
|
||||
#define WIN_COLOR_DEPTH_YVU422SP 0x37
|
||||
#define WIN_COLOR_DEPTH_YUV422SP 0x38
|
||||
#define WIN_COLOR_DEPTH_YVU444SP 0x3B
|
||||
#define WIN_COLOR_DEPTH_YUV444SP 0x3C
|
||||
|
||||
#define DC_WIN_POSITION 0x704
|
||||
#define H_POSITION(x) (((x) & 0xFfff) << 0)
|
||||
#define V_POSITION(x) (((x) & 0x1fff) << 16)
|
||||
#define H_POSITION(x) (((x) & 0xffff) << 0) // Support negative.
|
||||
#define V_POSITION(x) (((x) & 0xffff) << 16) // Support negative.
|
||||
|
||||
#define DC_WIN_SIZE 0x705
|
||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
||||
|
@ -316,6 +362,7 @@
|
|||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
|
||||
#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_ENABLE (0 << 24)
|
||||
|
@ -386,6 +433,7 @@
|
|||
#define DSI_HOST_CONTROL_FIFO_SEL BIT(4)
|
||||
#define DSI_HOST_CONTROL_HS BIT(5)
|
||||
#define DSI_HOST_CONTROL_RAW BIT(6)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_MASK (3 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
|
@ -433,10 +481,14 @@
|
|||
#define DSI_PKT_SEQ_5_LO 0x2D
|
||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define PKT0_LEN(x) (((x) & 0xffff) << 0)
|
||||
#define PKT1_LEN(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DSI_PHY_TIMING_0 0x3C
|
||||
#define DSI_PHY_TIMING_1 0x3D
|
||||
#define DSI_PHY_TIMING_2 0x3E
|
||||
|
@ -593,6 +645,7 @@
|
|||
#define MIPI_DCS_GET_SCANLINE 0x45
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
|
||||
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
|
||||
#define MIPI_DSI_AREA_COLOR_MODE 0x4C
|
||||
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_GET_BRIGHTNESS 0x52 // 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
|
||||
|
@ -606,7 +659,9 @@
|
|||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_UNK_A0 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_COLOR_MODE 0xA0
|
||||
#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0
|
||||
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames.
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
#define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands.
|
||||
#define MIPI_DCS_PRIV_UNK_BD 0xBD
|
||||
|
@ -614,6 +669,8 @@
|
|||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||
|
||||
|
@ -648,12 +705,25 @@
|
|||
#define DCS_GAMMA_CURVE_GC2_1_0 BIT(2)
|
||||
#define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more?
|
||||
|
||||
#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
|
||||
#define PANEL_OLED_BL_COEFF 82 // 82%.
|
||||
#define PANEL_OLED_BL_OFFSET 45 // Least legible backlight duty.
|
||||
#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut?
|
||||
#define DCS_SM_COLOR_MODE_WASHED 0x45
|
||||
#define DCS_SM_COLOR_MODE_BASIC 0x03
|
||||
#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on.
|
||||
#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural..
|
||||
#define DCS_SM_COLOR_MODE_VIVID 0x65
|
||||
#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural.
|
||||
#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid.
|
||||
|
||||
#define DCS_SM_COLOR_MODE_ENABLE BIT(0)
|
||||
|
||||
#define PANEL_SM_BL_CANDELA_MAX 2047
|
||||
|
||||
/* Switch Panels:
|
||||
*
|
||||
|
@ -662,19 +732,28 @@
|
|||
* [10] 96 [09]: JDI LAM062M109A
|
||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV]
|
||||
* [20] 97 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
|
||||
* [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
|
||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3 (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
|
||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||
* [30] 97 [0F]: AUO A062TAN02 (59.06A33.002) [From photo of assumed same panel]
|
||||
* [30] 98 [0F]: AUO A062TAN0? [UNCONFIRMED MODEL]
|
||||
* [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID]
|
||||
*
|
||||
* 5.5" panels for Hoag SKUs:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||
* [30] 93 [10]: AUO A055TAN01 (59.05A30.001)
|
||||
* [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
|
||||
*
|
||||
* 7.0" OLED panels for Aula SKUs:
|
||||
* 5.5" panels for Hoag SKU:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) (6203B001P4000)
|
||||
* [20] 95 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [20] 96 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV]
|
||||
* [30] 93 [10]: AUO A055TAN01 (59.05A30.001)
|
||||
* [30] 94 [10]: AUO A055TAN02 (59.05A30.002)
|
||||
* [30] 95 [10]: AUO A055TAN03 (59.05A30.003)
|
||||
* [40] 94 [10]: Sharp LQ055T1SW10 (Rev P)
|
||||
*
|
||||
*
|
||||
* 7.0" OLED panels for Aula SKU:
|
||||
* [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5)
|
||||
*/
|
||||
|
||||
|
@ -688,7 +767,7 @@
|
|||
* 10h: Japan Display Inc.
|
||||
* 20h: InnoLux Corporation
|
||||
* 30h: AU Optronics
|
||||
* 40h: Unknown0
|
||||
* 40h: Sharp
|
||||
* 50h: Samsung
|
||||
*
|
||||
* Boards, Panel Size:
|
||||
|
@ -706,7 +785,7 @@ enum
|
|||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030,
|
||||
PANEL_V40_55_UNK = 0x1040,
|
||||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||
PANEL_SAM_AMS699VC01 = 0x2050
|
||||
};
|
||||
|
||||
|
@ -726,8 +805,9 @@ void display_backlight(bool enable);
|
|||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
u32 display_get_backlight_brightness();
|
||||
|
||||
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
/*! 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();
|
||||
|
@ -737,7 +817,9 @@ void display_init_cursor(void *crs_fb, u32 size);
|
|||
void display_set_pos_cursor(u32 x, u32 y);
|
||||
void display_deinit_cursor();
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,33 +15,29 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
// Display A config.
|
||||
static const cfg_op_t _di_dc_setup_win_config[] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C.
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_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 | 0x9}, // 9: SYNCPT
|
||||
{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_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
|
||||
/* 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_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
|
@ -52,66 +48,19 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
|||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_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},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_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},
|
||||
|
@ -119,18 +68,18 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
|||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
|
||||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_dsi_init_config_part1[8] = {
|
||||
// DSI Init config.
|
||||
static const cfg_op_t _di_dsi_init_irq_pkt_config0[] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
{DSI_INT_MASK, 0},
|
||||
{DSI_INT_MASK, 0},
|
||||
{DSI_INIT_SEQ_DATA_0, 0},
|
||||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
||||
static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = {
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
|
@ -146,7 +95,7 @@ static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
|||
{DSI_PKT_SEQ_5_HI, 0},
|
||||
{DSI_CONTROL, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
||||
static const cfg_op_t _di_dsi_init_pads_t210b01[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
|
@ -155,10 +104,10 @@ static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
|||
{DSI_PAD_CONTROL_6_B01, 0},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part4[10] = {
|
||||
static const cfg_op_t _di_dsi_init_timing_pkt_config2[] = {
|
||||
{DSI_PAD_CONTROL_CD, 0},
|
||||
{DSI_SOL_DELAY, 0x18},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_SOL_DELAY, 24},
|
||||
{DSI_MAX_THRESHOLD, 480},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0},
|
||||
{DSI_PKT_LEN_0_1, 0},
|
||||
|
@ -167,12 +116,12 @@ static const cfg_op_t _display_dsi_init_config_part4[10] = {
|
|||
{DSI_PKT_LEN_6_7, 0},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part5[12] = {
|
||||
static const cfg_op_t _di_dsi_init_timing_pwrctrl_config[] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{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_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_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
|
@ -181,25 +130,25 @@ static const cfg_op_t _display_dsi_init_config_part5[12] = {
|
|||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part6[14] = {
|
||||
static const cfg_op_t _di_dsi_init_timing_pkt_config3[] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI panel config.
|
||||
static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
// DSI panel JDI config.
|
||||
static const cfg_op_t _di_dsi_panel_init_config_jdi[] = {
|
||||
{DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
|
@ -245,13 +194,13 @@ static const cfg_op_t _display_init_config_jdi[43] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//DSI packet config.
|
||||
static const cfg_op_t _display_dsi_packet_config[19] = {
|
||||
// DSI packet config.
|
||||
static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
|
@ -261,66 +210,66 @@ static const cfg_op_t _display_dsi_packet_config[19] = {
|
|||
{DSI_PKT_SEQ_3_HI, 0x2CC},
|
||||
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
|
||||
{DSI_PKT_SEQ_5_HI, 0x2CC},
|
||||
{DSI_PKT_LEN_0_1, 0xCE0000},
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_PKT_LEN_0_1, PKT1_LEN(206) | PKT0_LEN(0)},
|
||||
{DSI_PKT_LEN_2_3, PKT1_LEN(2160) | PKT0_LEN(418)},
|
||||
{DSI_PKT_LEN_4_5, PKT1_LEN(0) | PKT0_LEN(400)},
|
||||
{DSI_PKT_LEN_6_7, PKT1_LEN(0) | PKT0_LEN(400)},
|
||||
{DSI_HOST_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI mode config.
|
||||
static const cfg_op_t _display_dsi_mode_config[10] = {
|
||||
// DSI mode config.
|
||||
static const cfg_op_t _di_dsi_mode_config[] = {
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_SOL_DELAY, 6},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
{DSI_MAX_THRESHOLD, 480},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_pad_cal_config[4] = {
|
||||
// MIPI CAL config.
|
||||
static const cfg_op_t _di_mipi_pad_cal_config[] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
|
||||
// DSI pad config.
|
||||
static const cfg_op_t _di_dsi_pad_cal_config_t210[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
static const cfg_op_t _di_dsi_pad_cal_config_t210b01[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
{DSI_PAD_CONTROL_5_B01, 0x77777},
|
||||
{DSI_PAD_CONTROL_6_B01, 0x1111},
|
||||
{DSI_PAD_CONTROL_6_B01, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
|
||||
// MIPI CAL config.
|
||||
static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = {
|
||||
static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210b01[] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
||||
static const cfg_op_t _di_mipi_start_dsi_cal_config[] = {
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||
|
@ -332,19 +281,17 @@ static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
|||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001}
|
||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001} // Set Prescale and filter and start calibration.
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
// Display A enable config.
|
||||
static const cfg_op_t _di_dc_video_enable_config[] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
|
||||
/* 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_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
|
@ -355,66 +302,19 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
|||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_DV_CONTROL, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
/* Setup default YUV colorspace conversion coefficients */
|
||||
{DC_WIN_CSC_YOF, 0xF0},
|
||||
{DC_WIN_CSC_KYRGB, 0x12A},
|
||||
{DC_WIN_CSC_KUR, 0},
|
||||
{DC_WIN_CSC_KVR, 0x198},
|
||||
{DC_WIN_CSC_KUG, 0x39B},
|
||||
{DC_WIN_CSC_KVG, 0x32F},
|
||||
{DC_WIN_CSC_KUB, 0x204},
|
||||
{DC_WIN_CSC_KVB, 0},
|
||||
/* End of color coefficients */
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
|
||||
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_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},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_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},
|
||||
|
@ -422,34 +322,13 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
|||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
|
||||
/* Set Display timings
|
||||
*
|
||||
* DC_DISP_REF_TO_SYNC:
|
||||
* V_REF_TO_SYNC - 1
|
||||
* H_REF_TO_SYNC - 0
|
||||
*
|
||||
* DC_DISP_SYNC_WIDTH:
|
||||
* V_SYNC_WIDTH - 1
|
||||
* H_SYNC_WIDTH - 72
|
||||
*
|
||||
* DC_DISP_BACK_PORCH:
|
||||
* V_BACK_PORCH - 9
|
||||
* H_BACK_PORCH - 72
|
||||
*
|
||||
* DC_DISP_ACTIVE:
|
||||
* V_DISP_ACTIVE - 1280
|
||||
* H_DISP_ACTIVE - 720
|
||||
*
|
||||
* DC_DISP_FRONT_PORCH:
|
||||
* V_FRONT_PORCH - 10
|
||||
* H_FRONT_PORCH - 136
|
||||
*/
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, 0x10000},
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
|
||||
/* Set panel timings */
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)},
|
||||
{DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)},
|
||||
{DC_DISP_SYNC_WIDTH, V_SYNC_WIDTH(1) | H_SYNC_WIDTH(72)},
|
||||
{DC_DISP_BACK_PORCH, V_BACK_PORCH(9) | H_BACK_PORCH(72)},
|
||||
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
|
||||
{DC_DISP_ACTIVE, V_DISP_ACTIVE(1280) | H_DISP_ACTIVE(720)},
|
||||
/* End of Display timings */
|
||||
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
|
@ -458,23 +337,18 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
|||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_DISP_DISP_CLOCK_CONTROL, 0},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_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_C_DISPLAY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{DC_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, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
|
@ -483,9 +357,9 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
|||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
|
||||
};
|
||||
|
||||
////Display A config.
|
||||
static const cfg_op_t _display_video_disp_controller_disable_config[17] = {
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
// Display A disable config.
|
||||
static const cfg_op_t _di_dc_video_disable_config[] = {
|
||||
{DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)},
|
||||
{DC_CMD_INT_MASK, 0},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_INT_ENABLE, 0},
|
||||
|
@ -493,39 +367,37 @@ static const cfg_op_t _display_video_disp_controller_disable_config[17] = {
|
|||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},
|
||||
{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_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
// LCD panels should sleep for 40ms here.
|
||||
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
|
||||
// DSI deinit config.
|
||||
static const cfg_op_t _di_dsi_timing_deinit_config[] = {
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_0, 0x6070601}, //mariko changes
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_MAX_THRESHOLD, 0x40},
|
||||
{DSI_MAX_THRESHOLD, 64},
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_TX_CRC, 0},
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_deinit_config_jdi[22] = {
|
||||
// DSI panel JDI deinit config.
|
||||
static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
|
@ -550,7 +422,8 @@ static const cfg_op_t _display_deinit_config_jdi[22] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
// DSI panel AUO deinit config.
|
||||
static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
|
@ -591,156 +464,143 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
|
|||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_init_config_invert[3] = {
|
||||
static const cfg_op_t _di_init_config_invert[] = {
|
||||
{DSI_WR_DATA, 0x239},
|
||||
{DSI_WR_DATA, 0x02C1}, // INV_EN.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
// Display A Window A one color config.
|
||||
static const cfg_op_t _di_win_one_color[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
||||
};
|
||||
|
||||
//Display A config linear pitch.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
// 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},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config linear pitch inverse + Win D support.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
// 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},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
// Display A Window A linear pitch inverse + Win D support config.
|
||||
static const 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},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config block linear.
|
||||
static const cfg_op_t cfg_display_framebuffer_block[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
// 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},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC. Block in HOS: 0x13FF.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display D config.
|
||||
static const cfg_op_t cfg_display_framebuffer_log[20] = {
|
||||
// Display A Window D config.
|
||||
static const cfg_op_t _di_win_framebuffer_log[] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)},
|
||||
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
|
||||
{DC_WIN_WIN_OPTIONS, 0}, // Enable window DD.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
|
||||
};
|
||||
|
|
563
bdk/display/vic.c
Normal file
563
bdk/display/vic.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
* VIC driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "vic.h"
|
||||
#include <mem/heap.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
/* VIC Private registers */
|
||||
#define PVIC_FALCON_PA_OFFSET 0x1000
|
||||
#define PVIC_FALCON_ADDR 0x10AC
|
||||
#define PVIC_FALCON_IDLESTATE 0x104C
|
||||
|
||||
/* VIC Control and Status registers. */
|
||||
/* Fetch Control registers. */
|
||||
#define VIC_FC_COMPOSE 0x10000
|
||||
#define COMPOSE_START BIT(0)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04
|
||||
#define SLOT_ENABLE BIT(0)
|
||||
#define FIELD_CURRENT_ENABLE BIT(8)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C
|
||||
#define CACHE_WIDTH(n) ((n) << 16)
|
||||
#define CACHE_WIDTH_16BX16 0 // Block Linear.
|
||||
#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear.
|
||||
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch.
|
||||
#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch.
|
||||
#define OUTPUT_FLIP_X BIT(20)
|
||||
#define OUTPUT_FLIP_Y BIT(21)
|
||||
#define OUTPUT_TRANSPOSE BIT(22)
|
||||
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30
|
||||
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34
|
||||
#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38
|
||||
#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C
|
||||
#define VIC_FC_SLOT_MAP 0x10C00
|
||||
|
||||
#define VIC_FC_FCE_CTRL 0x11000
|
||||
#define START_TRIGGER BIT(0)
|
||||
#define HALT_TRIGGER BIT(1)
|
||||
#define CLEAR_ERROR BIT(8)
|
||||
|
||||
#define VIC_FC_FCE_UCODE_ADDR 0x11200
|
||||
#define VIC_FC_FCE_UCODE_INST 0x11300
|
||||
|
||||
/* Surface List registers. */
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300
|
||||
#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400
|
||||
#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500
|
||||
#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600
|
||||
|
||||
/* Surface Cache registers. */
|
||||
#define VIC_SC_PRAMBASE 0x14000
|
||||
#define VIC_SC_PRAMSIZE 0x14100
|
||||
#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100)
|
||||
|
||||
/* Blending Output registers. */
|
||||
#define VIC_BL_TARGET_BASADR 0x22000
|
||||
#define VIC_BL_CONFIG 0x22800
|
||||
#define SUBPARTITION_MODE BIT(0)
|
||||
#define PROCESS_CFG_STRUCT_TRIGGER BIT(2)
|
||||
#define SLOTMASK(n) ((n) << 8)
|
||||
|
||||
#define VIC_BL_CFG_STRUCT_CFG0 0x22C00
|
||||
#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04
|
||||
#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08
|
||||
#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C
|
||||
#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10
|
||||
#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14
|
||||
|
||||
// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0.
|
||||
#define BLK_KIND(n) ((n) << 8)
|
||||
#define BLK_KIND_PITCH 0
|
||||
#define BLK_KIND_GENERIC_16BX2 1
|
||||
#define BLK_HEIGHT(n) ((n) << 12)
|
||||
#define BLK_HEIGHT_ONE_GOB 0
|
||||
#define BLK_HEIGHT_SIXTEEN_GOBS 4
|
||||
|
||||
// Generic size macros.
|
||||
#define SIZE_WIDTH(n) (((n) - 1) << 0)
|
||||
#define SIZE_HEIGHT(n) (((n) - 1) << 16)
|
||||
#define RECT_LEFT(n) ((n) << 0)
|
||||
#define RECT_RIGHT(n) (((n) - 1) << 16)
|
||||
#define RECT_TOP(n) ((n) << 0)
|
||||
#define RECT_BOTTOM(n) (((n) - 1) << 16)
|
||||
|
||||
#define FORMAT_PROGRESSIVE 0
|
||||
#define SOFT_CLAMP_MIN 0
|
||||
#define SOFT_CLAMP_MAX 0x3FFu
|
||||
#define ALPHA_1_0 0x3FFu
|
||||
|
||||
typedef struct _OutputConfig {
|
||||
u64 AlphaFillMode:3;
|
||||
u64 AlphaFillSlot:3;
|
||||
u64 BackgroundAlpha:10;
|
||||
u64 BackgroundR:10;
|
||||
u64 BackgroundG:10;
|
||||
u64 BackgroundB:10;
|
||||
u64 RegammaMode:2;
|
||||
u64 OutputFlipX:1;
|
||||
u64 OutputFlipY:1;
|
||||
u64 OutputTranspose:1;
|
||||
u64 rsvd1:1;
|
||||
u64 rsvd2:12;
|
||||
u64 TargetRectLeft:14;
|
||||
u64 rsvd3:2;
|
||||
u64 TargetRectRight:14;
|
||||
u64 rsvd4:2;
|
||||
u64 TargetRectTop:14;
|
||||
u64 rsvd5:2;
|
||||
u64 TargetRectBottom:14;
|
||||
u64 rsvd6:2;
|
||||
} OutputConfig;
|
||||
|
||||
typedef struct _OutputSurfaceConfig {
|
||||
u64 OutPixelFormat:7;
|
||||
u64 OutChromaLocHoriz:2;
|
||||
u64 OutChromaLocVert:2;
|
||||
u64 OutBlkKind:4;
|
||||
u64 OutBlkHeight:4;
|
||||
u64 rsvd0:3;
|
||||
u64 rsvd1:10;
|
||||
u64 OutSurfaceWidth:14;
|
||||
u64 OutSurfaceHeight:14;
|
||||
u64 rsvd2:4;
|
||||
u64 OutLumaWidth:14;
|
||||
u64 OutLumaHeight:14;
|
||||
u64 rsvd3:4;
|
||||
u64 OutChromaWidth:14;
|
||||
u64 OutChromaHeight:14;
|
||||
u64 rsvd4:4;
|
||||
} OutputSurfaceConfig;
|
||||
|
||||
typedef struct _SlotConfig {
|
||||
u64 SlotEnable:1;
|
||||
u64 DeNoise:1;
|
||||
u64 AdvancedDenoise:1;
|
||||
u64 CadenceDetect:1;
|
||||
u64 MotionMap:1;
|
||||
u64 MMapCombine:1;
|
||||
u64 IsEven:1;
|
||||
u64 ChromaEven:1;
|
||||
u64 CurrentFieldEnable:1;
|
||||
u64 PrevFieldEnable:1;
|
||||
u64 NextFieldEnable:1;
|
||||
u64 NextNrFieldEnable:1;
|
||||
u64 CurMotionFieldEnable:1;
|
||||
u64 PrevMotionFieldEnable:1;
|
||||
u64 PpMotionFieldEnable:1;
|
||||
u64 CombMotionFieldEnable:1;
|
||||
u64 FrameFormat:4;
|
||||
u64 FilterLengthY:2;
|
||||
u64 FilterLengthX:2;
|
||||
u64 Panoramic:12;
|
||||
u64 rsvd1:22;
|
||||
u64 DetailFltClamp:6;
|
||||
u64 FilterNoise:10;
|
||||
u64 FilterDetail:10;
|
||||
u64 ChromaNoise:10;
|
||||
u64 ChromaDetail:10;
|
||||
u64 DeinterlaceMode:4;
|
||||
u64 MotionAccumWeight:3;
|
||||
u64 NoiseIir:11;
|
||||
u64 LightLevel:4;
|
||||
u64 rsvd4:2;
|
||||
u64 SoftClampLow:10;
|
||||
u64 SoftClampHigh:10;
|
||||
u64 rsvd5:3;
|
||||
u64 rsvd6:9;
|
||||
u64 PlanarAlpha:10;
|
||||
u64 ConstantAlpha:1;
|
||||
u64 StereoInterleave:3;
|
||||
u64 ClipEnabled:1;
|
||||
u64 ClearRectMask:8;
|
||||
u64 DegammaMode:2;
|
||||
u64 rsvd7:1;
|
||||
u64 DecompressEnable:1;
|
||||
u64 rsvd9:5;
|
||||
u64 DecompressCtbCount:8;
|
||||
u64 DecompressZbcColor:32;
|
||||
u64 rsvd12:24;
|
||||
u64 SourceRectLeft:30;
|
||||
u64 rsvd14:2;
|
||||
u64 SourceRectRight:30;
|
||||
u64 rsvd15:2;
|
||||
u64 SourceRectTop:30;
|
||||
u64 rsvd16:2;
|
||||
u64 SourceRectBottom:30;
|
||||
u64 rsvd17:2;
|
||||
u64 DestRectLeft:14;
|
||||
u64 rsvd18:2;
|
||||
u64 DestRectRight:14;
|
||||
u64 rsvd19:2;
|
||||
u64 DestRectTop:14;
|
||||
u64 rsvd20:2;
|
||||
u64 DestRectBottom:14;
|
||||
u64 rsvd21:2;
|
||||
u64 rsvd22:32;
|
||||
u64 rsvd23:32;
|
||||
} SlotConfig;
|
||||
|
||||
typedef struct _SlotSurfaceConfig {
|
||||
u64 SlotPixelFormat:7;
|
||||
u64 SlotChromaLocHoriz:2;
|
||||
u64 SlotChromaLocVert:2;
|
||||
u64 SlotBlkKind:4;
|
||||
u64 SlotBlkHeight:4;
|
||||
u64 SlotCacheWidth:3;
|
||||
u64 rsvd0:10;
|
||||
u64 SlotSurfaceWidth:14;
|
||||
u64 SlotSurfaceHeight:14;
|
||||
u64 rsvd1:4;
|
||||
u64 SlotLumaWidth:14;
|
||||
u64 SlotLumaHeight:14;
|
||||
u64 rsvd2:4;
|
||||
u64 SlotChromaWidth:14;
|
||||
u64 SlotChromaHeight:14;
|
||||
u64 rsvd3:4;
|
||||
} SlotSurfaceConfig;
|
||||
|
||||
typedef struct _SlotStruct {
|
||||
SlotConfig slot_cfg;
|
||||
SlotSurfaceConfig slot_sfc_cfg;
|
||||
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 lumaKeyStruct[0x10];
|
||||
u8 colorMatrixStruct[0x20];
|
||||
u8 gamutMatrixStruct[0x20];
|
||||
u8 blendingSlotStruct[0x10];
|
||||
} SlotStruct;
|
||||
|
||||
typedef struct _vic_config_t {
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 pipeConfig[0x10];
|
||||
|
||||
OutputConfig out_cfg;
|
||||
OutputSurfaceConfig out_sfc_cfg;
|
||||
|
||||
// No need to configure. Reset to zeros.
|
||||
u8 out_color_matrix[0x20];
|
||||
u8 clear_rect[0x10 * 4];
|
||||
|
||||
SlotStruct slots[8];
|
||||
} vic_config_t;
|
||||
|
||||
// VIC Fetch Control Engine microcode. Dumped from L4T r33.
|
||||
u8 vic_fce_ucode[] = {
|
||||
0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00,
|
||||
0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00,
|
||||
0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00,
|
||||
0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00,
|
||||
0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
||||
0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00,
|
||||
0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
||||
0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00,
|
||||
0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00,
|
||||
0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00,
|
||||
0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00,
|
||||
0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00,
|
||||
0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00,
|
||||
0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00,
|
||||
0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00,
|
||||
0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00,
|
||||
0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00,
|
||||
0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00,
|
||||
0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00,
|
||||
0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00,
|
||||
0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00,
|
||||
0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00,
|
||||
0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00,
|
||||
0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00,
|
||||
0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00,
|
||||
0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00,
|
||||
0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00,
|
||||
0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00,
|
||||
0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00,
|
||||
0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00,
|
||||
0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00,
|
||||
0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00,
|
||||
0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00,
|
||||
0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00,
|
||||
0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00,
|
||||
0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
||||
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
||||
0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00,
|
||||
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00,
|
||||
0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00,
|
||||
0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00,
|
||||
0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
||||
0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00,
|
||||
0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00,
|
||||
0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00,
|
||||
0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00,
|
||||
0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
||||
0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00,
|
||||
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00,
|
||||
0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
||||
0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00,
|
||||
0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
||||
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00,
|
||||
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00,
|
||||
0x6F, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0};
|
||||
|
||||
u32 _vic_read_priv(u32 addr)
|
||||
{
|
||||
u32 addr_lsb = addr & 0xFF;
|
||||
|
||||
// Set address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
||||
|
||||
// Set address.
|
||||
u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6));
|
||||
|
||||
// Unset address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void _vic_write_priv(u32 addr, u32 data)
|
||||
{
|
||||
u32 addr_lsb = addr & 0xFF;
|
||||
|
||||
// Set address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
||||
|
||||
// Set address.
|
||||
VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data;
|
||||
|
||||
// Unset address LSB.
|
||||
if (addr_lsb)
|
||||
VIC(PVIC_FALCON_ADDR) = 0;
|
||||
}
|
||||
|
||||
static int _vic_wait_idle()
|
||||
{
|
||||
u32 timeout_count = 15000; // 150ms.
|
||||
|
||||
while (VIC(PVIC_FALCON_IDLESTATE))
|
||||
{
|
||||
usleep(10);
|
||||
|
||||
timeout_count--;
|
||||
if (!timeout_count)
|
||||
return -1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vic_set_surface(vic_surface_t *sfc)
|
||||
{
|
||||
u32 flip_x = 0;
|
||||
u32 flip_y = 0;
|
||||
u32 swap_xy = 0;
|
||||
u32 const_alpha = 0;
|
||||
|
||||
u32 width = sfc->width;
|
||||
u32 height = sfc->height;
|
||||
u32 pix_fmt = sfc->pix_fmt;
|
||||
u32 src_buf = sfc->src_buf;
|
||||
u32 dst_buf = sfc->dst_buf;
|
||||
|
||||
// Get format alpha type.
|
||||
switch (sfc->pix_fmt)
|
||||
{
|
||||
case VIC_PIX_FORMAT_X8B8G8R8:
|
||||
case VIC_PIX_FORMAT_X8R8G8B8:
|
||||
case VIC_PIX_FORMAT_B8G8R8X8:
|
||||
case VIC_PIX_FORMAT_R8G8B8X8:
|
||||
const_alpha = 1;
|
||||
break;
|
||||
|
||||
case VIC_PIX_FORMAT_A8B8G8R8:
|
||||
case VIC_PIX_FORMAT_A8R8G8B8:
|
||||
case VIC_PIX_FORMAT_B8G8R8A8:
|
||||
case VIC_PIX_FORMAT_R8G8B8A8:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Get rotation parameters.
|
||||
switch (sfc->rotation)
|
||||
{
|
||||
case VIC_ROTATION_90:
|
||||
swap_xy = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_180:
|
||||
flip_x = 1;
|
||||
flip_y = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_270:
|
||||
flip_x = 1;
|
||||
swap_xy = 1;
|
||||
break;
|
||||
|
||||
case VIC_ROTATION_0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set output surface format.
|
||||
vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt;
|
||||
vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH;
|
||||
vic_cfg.out_sfc_cfg.OutBlkHeight = 0;
|
||||
|
||||
// Set output rotation/flip.
|
||||
vic_cfg.out_cfg.OutputFlipX = flip_x;
|
||||
vic_cfg.out_cfg.OutputFlipY = flip_y;
|
||||
vic_cfg.out_cfg.OutputTranspose = swap_xy;
|
||||
|
||||
// Set output surface resolution.
|
||||
vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1;
|
||||
vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1;
|
||||
vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1;
|
||||
vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1;
|
||||
|
||||
// Set output destination rectangle. Anything outside will not be touched at output buffer.
|
||||
vic_cfg.out_cfg.TargetRectLeft = 0;
|
||||
vic_cfg.out_cfg.TargetRectRight = width - 1;
|
||||
vic_cfg.out_cfg.TargetRectTop = 0;
|
||||
vic_cfg.out_cfg.TargetRectBottom = height - 1;
|
||||
|
||||
// Initialize slot parameters.
|
||||
vic_cfg.slots[0].slot_cfg.SlotEnable = 1;
|
||||
vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN;
|
||||
vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX;
|
||||
vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0;
|
||||
vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha;
|
||||
vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE;
|
||||
|
||||
// Set input source rectangle.
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectTop = 0;
|
||||
vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16;
|
||||
|
||||
// Set input destination rectangle.
|
||||
vic_cfg.slots[0].slot_cfg.DestRectLeft = 0;
|
||||
vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1);
|
||||
vic_cfg.slots[0].slot_cfg.DestRectTop = 0;
|
||||
vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1);
|
||||
|
||||
// Set input surface format.
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4;
|
||||
|
||||
// Set input surface resolution.
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1;
|
||||
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1;
|
||||
|
||||
// Flush data.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
// Set parameters base and size. Causes a parse by surface cache.
|
||||
_vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8);
|
||||
_vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
|
||||
// Set slot mapping.
|
||||
_vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
|
||||
|
||||
// Set input surface buffer.
|
||||
_vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8);
|
||||
|
||||
// Set output surface buffer.
|
||||
_vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8);
|
||||
|
||||
// Set blending config and push changes to surface cache.
|
||||
_vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
|
||||
|
||||
// Wait for surface cache to get ready.
|
||||
_vic_wait_idle();
|
||||
}
|
||||
|
||||
int vic_compose()
|
||||
{
|
||||
// Wait for surface cache to get ready. Otherwise VIC will hang.
|
||||
int res = _vic_wait_idle();
|
||||
|
||||
// Start composition of a single frame.
|
||||
_vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int vic_init()
|
||||
{
|
||||
// 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++)
|
||||
{
|
||||
_vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32)));
|
||||
_vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]);
|
||||
}
|
||||
|
||||
// Start Fetch Control Engine.
|
||||
_vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
|
||||
|
||||
return _vic_wait_idle();
|
||||
}
|
||||
|
||||
void vic_end()
|
||||
{
|
||||
clock_disable_vic();
|
||||
}
|
63
bdk/display/vic.h
Normal file
63
bdk/display/vic.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* VIC driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _VIC_H_
|
||||
#define _VIC_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define VIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
|
||||
|
||||
typedef enum _vic_rotation_t
|
||||
{
|
||||
VIC_ROTATION_0 = 0,
|
||||
VIC_ROTATION_90 = 1,
|
||||
VIC_ROTATION_180 = 2,
|
||||
VIC_ROTATION_270 = 3,
|
||||
} vic_rotation_t;
|
||||
|
||||
typedef enum _vic_pix_format_t
|
||||
{
|
||||
VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
|
||||
VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
|
||||
VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
|
||||
VIC_PIX_FORMAT_R8G8B8A8 = 34, // 32-bit RGBA.
|
||||
|
||||
VIC_PIX_FORMAT_X8B8G8R8 = 35, // 32-bit XBGR.
|
||||
VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
|
||||
VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
|
||||
VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
|
||||
|
||||
} vic_pix_format_t;
|
||||
|
||||
typedef struct _vic_surface_t
|
||||
{
|
||||
u32 src_buf;
|
||||
u32 dst_buf;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 pix_fmt;
|
||||
u32 rotation;
|
||||
} vic_surface_t;
|
||||
|
||||
void vic_set_surface(vic_surface_t *sfc);
|
||||
int vic_compose();
|
||||
int vic_init();
|
||||
void vic_end();
|
||||
|
||||
#endif
|
|
@ -97,6 +97,10 @@ _irq_setup:
|
|||
MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x40040000
|
||||
|
||||
/* Setup FIQ stack pointer */
|
||||
MSR CPSR, #(MODE_FIQ | IRQ | FIQ) /* FIQ mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x40040000
|
||||
|
||||
/* Setup SYS stack pointer */
|
||||
MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
|
||||
|
@ -111,7 +115,9 @@ _irq_setup:
|
|||
B ipl_main
|
||||
B .
|
||||
|
||||
_reset:
|
||||
.globl excp_reset
|
||||
.type excp_reset, %function
|
||||
excp_reset:
|
||||
LDR R0, =EXCP_EN_ADDR
|
||||
LDR R1, =0x30505645 /* EVP0 */
|
||||
STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
|
||||
|
@ -129,25 +135,25 @@ _reset_handler:
|
|||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x545352 /* RST */
|
||||
STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_undefined_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x464455 /* UDF */
|
||||
STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_prefetch_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424150 /* PABT */
|
||||
STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
_data_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424144 /* DABT */
|
||||
STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
B excp_reset
|
||||
|
||||
.globl irq_enable_cpu_irq_exceptions
|
||||
.type irq_enable_cpu_irq_exceptions, %function
|
||||
|
|
|
@ -445,7 +445,7 @@ typedef struct
|
|||
/* Dynamic structure */
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
Elf32_Word d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
|
|
|
@ -74,19 +74,16 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
el_ctx ctx;
|
||||
uintptr_t epaddr = 0;
|
||||
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
// Read library.
|
||||
fileBuf = sd_file_read(path, NULL);
|
||||
|
||||
if (!fileBuf)
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
// Set our relocated library's buffer.
|
||||
switch (type & 0xFFFF)
|
||||
|
@ -100,15 +97,15 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
}
|
||||
|
||||
if (!elfBuf)
|
||||
goto elfLoadFinalOut;
|
||||
goto out;
|
||||
|
||||
// Load and relocate library.
|
||||
ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;
|
||||
if (el_load(&ctx, _ianos_alloc_cb))
|
||||
goto elfFreeOut;
|
||||
goto out_free;
|
||||
|
||||
if (el_relocate(&ctx))
|
||||
goto elfFreeOut;
|
||||
goto out_free;
|
||||
|
||||
// Launch.
|
||||
epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;
|
||||
|
@ -116,11 +113,11 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
|||
|
||||
_ianos_call_ep(ep, moduleConfig);
|
||||
|
||||
elfFreeOut:
|
||||
out_free:
|
||||
free(fileBuf);
|
||||
elfBuf = NULL;
|
||||
fileBuf = NULL;
|
||||
|
||||
elfLoadFinalOut:
|
||||
out:
|
||||
return epaddr;
|
||||
}
|
|
@ -73,7 +73,7 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
|||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
als_ctxt->gain = gain;
|
||||
|
@ -83,25 +83,25 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
|||
void get_als_lux(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
u32 data[2];
|
||||
u32 visible_light;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u64 lux = 0;
|
||||
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
|
||||
|
||||
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
|
||||
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
|
||||
visible_light = data[0];
|
||||
vi_light = data[0];
|
||||
ir_light = data[1];
|
||||
|
||||
als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
|
||||
als_ctxt->vi_light = visible_light;
|
||||
als_ctxt->vi_light = vi_light;
|
||||
als_ctxt->ir_light = ir_light;
|
||||
als_ctxt->over_limit = vi_light > 65534 || ir_light > 65534;
|
||||
|
||||
if (!visible_light)
|
||||
if (!vi_light)
|
||||
{
|
||||
als_ctxt->lux = 0;
|
||||
|
||||
|
@ -116,7 +116,7 @@ void get_als_lux(als_ctxt_t *als_ctxt)
|
|||
// Apply optical window calibration coefficients.
|
||||
for (u32 i = 0; i < opt_win_cal_count; i++)
|
||||
{
|
||||
if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
|
||||
if (1000 * ir_light / vi_light < opt_win_cal[i].rc)
|
||||
{
|
||||
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,13 +83,23 @@ typedef struct _jc_gamepad_rpt_t
|
|||
bool center_stick_r;
|
||||
bool conn_l;
|
||||
bool conn_r;
|
||||
u8 batt_info_l;
|
||||
u8 batt_info_r;
|
||||
bool sio_mode;
|
||||
u8 batt_info_l; // Also Sio Connected status.
|
||||
u8 batt_info_r; // Also Sio IRQ.
|
||||
jc_bt_conn_t bt_conn_l;
|
||||
jc_bt_conn_t bt_conn_r;
|
||||
} jc_gamepad_rpt_t;
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable);
|
||||
typedef struct _jc_calib_t
|
||||
{
|
||||
u16 x_max:12;
|
||||
u16 y_max:12;
|
||||
u16 x_center:12;
|
||||
u16 y_center:12;
|
||||
u16 x_min:12;
|
||||
u16 y_min:12;
|
||||
} __attribute__((packed)) jc_calib_t;
|
||||
|
||||
void jc_init_hw();
|
||||
void jc_deinit();
|
||||
jc_gamepad_rpt_t *joycon_poll();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -24,9 +24,9 @@
|
|||
#include <soc/pinmux.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/util.h>
|
||||
#include "touch.h"
|
||||
|
||||
|
||||
|
@ -35,12 +35,12 @@
|
|||
|
||||
static touch_panel_info_t _panels[] =
|
||||
{
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },
|
||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },
|
||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },
|
||||
{ 3, 1, 0, 0, "GiS 5.5\"" },
|
||||
{ 4, 0, 0, 1, "Samsung BH2109" },
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" }
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0.
|
||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
|
||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
|
||||
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
|
||||
{ 4, 0, 0, 1, "Samsung BH2109" },// 5?
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
|
||||
};
|
||||
|
||||
static int touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
|
@ -87,19 +87,19 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
|||
|
||||
static void _touch_compensate_limits(touch_event *event, bool touching)
|
||||
{
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
event->x -= EDGE_OFFSET;
|
||||
u32 x_adj = (1280 * 1000) / (X_REAL_MAX - EDGE_OFFSET);
|
||||
event->x = ((u32)event->x * x_adj) / 1000;
|
||||
event->x = ((u32)event->x * x_adj) / 1000;
|
||||
|
||||
if (touching)
|
||||
{
|
||||
event->y = MAX(event->y, EDGE_OFFSET);
|
||||
event->y = MIN(event->y, Y_REAL_MAX);
|
||||
event->y = MAX(event->y, EDGE_OFFSET);
|
||||
event->y = MIN(event->y, Y_REAL_MAX);
|
||||
event->y -= EDGE_OFFSET;
|
||||
u32 y_adj = (720 * 1000) / (Y_REAL_MAX - EDGE_OFFSET);
|
||||
event->y = ((u32)event->y * y_adj) / 1000;
|
||||
event->y = ((u32)event->y * y_adj) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,7 @@ static void _touch_process_contact_event(touch_event *event, bool touching)
|
|||
|
||||
event->z = event->raw[5] | (event->raw[6] << 8);
|
||||
event->z = event->z << 6;
|
||||
|
||||
u16 tmp = 0x40;
|
||||
if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F)
|
||||
tmp = event->raw[7] & 0x3F;
|
||||
|
@ -245,7 +246,7 @@ int touch_get_fw_info(touch_fw_info_t *fw)
|
|||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
if (!res)
|
||||
{
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->ftb_ver = (buf[6] << 8) | buf[5];
|
||||
}
|
||||
|
||||
|
@ -400,30 +401,29 @@ static int touch_init()
|
|||
|
||||
int touch_power_on()
|
||||
{
|
||||
// Enable LDO6 for touchscreen AVDD supply.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Configure touchscreen VDD GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||
|
||||
// Touscreen IRQ.
|
||||
// PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3;
|
||||
// gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
// gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW);
|
||||
|
||||
// Configure Touscreen and GCAsic shared GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2; // Unused.
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||
|
||||
// Configure touchscreen Touch Reset pin.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
usleep(20);
|
||||
|
||||
// Enable LDO6 for touchscreen AVDD and DVDD supply.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Initialize I2C3.
|
||||
pinmux_config_i2c(I2C_3);
|
||||
clock_enable_i2c(I2C_3);
|
||||
i2c_init(I2C_3);
|
||||
usleep(1000);
|
||||
|
||||
// Set Touch Reset pin.
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||
usleep(10000);
|
||||
|
||||
// Wait for the touchscreen module to get ready.
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include <utils/types.h>
|
||||
#include <soc/timer.h>
|
||||
#include <memory_map.h>
|
||||
/*===================
|
||||
Dynamic memory
|
||||
|
@ -147,10 +147,10 @@
|
|||
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
|
||||
|
||||
/*HAL settings*/
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE <utils/util.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE <soc/timer.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((u32)get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
|
@ -296,6 +296,9 @@
|
|||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define USE_LV_MBOX 1
|
||||
#if USE_LV_MBOX != 0
|
||||
# define LV_MBOX_CLOSE_ANIM_TIME 200 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define USE_LV_TA 1
|
||||
|
|
|
@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
|
|||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
|||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
|
||||
/*Send a signal about the press*/
|
||||
|
|
|
@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
|||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
|
||||
#else
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
|
||||
((uint32_t) c & 0xFF))
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
|
||||
((uint32_t) (c) & 0xFF))
|
||||
#endif
|
||||
|
||||
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
|
||||
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
|
||||
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
|
||||
((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
|
||||
((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
|
|||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
{
|
||||
bool changed = ll_new_p->head != node;
|
||||
|
||||
lv_ll_rem(ll_ori_p, node);
|
||||
|
||||
/*Set node as head*/
|
||||
|
@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
|||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||
ll_new_p->tail = node;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
|
|||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
|
||||
/**
|
||||
* Return with head node of the linked list
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -32,13 +32,16 @@
|
|||
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
||||
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
||||
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
||||
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
|
||||
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
|
||||
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
|
||||
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
|
||||
#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
|
||||
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
||||
|
||||
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
|
||||
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
|
||||
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
|
||||
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
|
||||
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
@ -57,8 +60,9 @@ static lv_style_t def;
|
|||
static lv_style_t sb;
|
||||
|
||||
/*Saved input parameters*/
|
||||
static uint16_t _hue;
|
||||
static uint16_t _hue;
|
||||
static lv_font_t * _font;
|
||||
uint32_t theme_bg_color;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -80,18 +84,17 @@ static void basic_init(void)
|
|||
//def.image.opa = LV_OPA_COVER;
|
||||
|
||||
lv_style_copy(&bg, &def);
|
||||
bg.body.main_color = COLOR_HOS_BG;
|
||||
//bg.body.main_color = LV_COLOR_BLACK;
|
||||
bg.body.main_color = COLOR_BG;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.radius = 0;
|
||||
bg.body.empty = 1;
|
||||
|
||||
lv_style_copy(&panel, &def);
|
||||
panel.body.radius = DEF_RADIUS;
|
||||
panel.body.main_color = COLOR_HOS_BG;
|
||||
panel.body.grad_color = COLOR_HOS_BG;
|
||||
panel.body.main_color = COLOR_BG;
|
||||
panel.body.grad_color = COLOR_BG;
|
||||
panel.body.border.width = 1;
|
||||
panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
|
||||
panel.body.border.color = COLOR_LIGHT_BORDER;
|
||||
panel.body.border.opa = LV_OPA_COVER;
|
||||
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
||||
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
|
@ -129,7 +132,7 @@ static void btn_init(void)
|
|||
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
||||
|
||||
lv_style_copy(&rel, &def);
|
||||
rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.main_color = COLOR_BG_LIGHT;
|
||||
rel.body.grad_color = rel.body.main_color;
|
||||
rel.body.radius = 6;
|
||||
rel.body.padding.hor = LV_DPI / 3;
|
||||
|
@ -139,7 +142,7 @@ static void btn_init(void)
|
|||
rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
rel.body.shadow.width = 6;
|
||||
rel.body.border.width = 0;
|
||||
rel.body.border.color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.border.color = COLOR_BG_LIGHT;
|
||||
rel.body.border.part = LV_BORDER_FULL;
|
||||
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
||||
|
||||
|
@ -162,7 +165,7 @@ static void btn_init(void)
|
|||
tgl_pr.body.shadow.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &rel);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
//ina.body.shadow.width = 0;
|
||||
ina.text.color = LV_COLOR_HEX(0x888888);
|
||||
|
@ -207,7 +210,7 @@ static void img_init(void)
|
|||
img_light.image.intense = LV_OPA_80;
|
||||
|
||||
lv_style_copy(&img_dark, &def);
|
||||
img_dark.image.color = COLOR_HOS_BG_DARKER;
|
||||
img_dark.image.color = COLOR_BG_DARKER;
|
||||
img_dark.image.intense = LV_OPA_80;
|
||||
|
||||
|
||||
|
@ -250,7 +253,7 @@ static void bar_init(void)
|
|||
static lv_style_t bar_bg, bar_indic;
|
||||
|
||||
lv_style_copy(&bar_bg, &def);
|
||||
bar_bg.body.main_color = COLOR_HOS_LIGHT_BORDER;
|
||||
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
|
||||
bar_bg.body.grad_color = bar_bg.body.main_color;
|
||||
bar_bg.body.radius = 3;
|
||||
bar_bg.body.border.width = 0;
|
||||
|
@ -536,9 +539,9 @@ static void mbox_init(void)
|
|||
static lv_style_t bg;
|
||||
|
||||
lv_style_copy(&bg, theme.panel);
|
||||
bg.body.main_color = LV_COLOR_HEX(0x464646);
|
||||
bg.body.main_color = COLOR_BG_LIGHTER;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.shadow.color = COLOR_HOS_BG;
|
||||
bg.body.shadow.color = COLOR_BG;
|
||||
bg.body.shadow.type = LV_SHADOW_FULL;
|
||||
bg.body.shadow.width = 8;
|
||||
|
||||
|
@ -628,7 +631,7 @@ static void list_init(void)
|
|||
// pr.text.font = _font;
|
||||
|
||||
lv_style_copy(&tgl_rel, &pr);
|
||||
tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_rel.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_rel.body.grad_color = tgl_rel.body.main_color;
|
||||
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
|
||||
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
||||
|
@ -639,7 +642,7 @@ static void list_init(void)
|
|||
tgl_pr.body.border.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &pr);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
|
||||
theme.list.sb = &sb;
|
||||
|
@ -667,7 +670,7 @@ static void ddlist_init(void)
|
|||
bg.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&sel, &bg);
|
||||
sel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
sel.body.main_color = COLOR_BG_LIGHT;
|
||||
sel.body.grad_color = sel.body.main_color;
|
||||
|
||||
theme.ddlist.bg = &bg;
|
||||
|
@ -713,7 +716,7 @@ static void tabview_init(void)
|
|||
indic.body.opa = LV_OPA_0;
|
||||
|
||||
lv_style_copy(&btn_bg, &def);
|
||||
btn_bg.body.main_color = COLOR_HOS_BG;
|
||||
btn_bg.body.main_color = COLOR_BG;
|
||||
btn_bg.body.grad_color = btn_bg.body.main_color;
|
||||
btn_bg.body.radius = 0;
|
||||
btn_bg.body.empty = 1;
|
||||
|
@ -734,7 +737,7 @@ static void tabview_init(void)
|
|||
rel.text.font = _font;
|
||||
|
||||
lv_style_copy(&pr, &def);
|
||||
pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
pr.body.main_color = COLOR_BG_LIGHT;
|
||||
pr.body.grad_color = pr.body.main_color;
|
||||
pr.body.border.width = 0;
|
||||
pr.body.empty = 0;
|
||||
|
@ -750,7 +753,7 @@ static void tabview_init(void)
|
|||
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&tgl_pr, &def);
|
||||
tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_pr.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||
tgl_pr.body.border.width = 0;
|
||||
tgl_pr.body.empty = 0;
|
||||
|
@ -797,7 +800,7 @@ static void win_init(void)
|
|||
static lv_style_t header, rel, pr;
|
||||
|
||||
lv_style_copy(&header, &def);
|
||||
header.body.main_color = COLOR_HOS_BG;
|
||||
header.body.main_color = COLOR_BG;
|
||||
header.body.grad_color = header.body.main_color;
|
||||
header.body.radius = 0;
|
||||
header.body.border.width = 0;
|
||||
|
@ -843,10 +846,11 @@ static void win_init(void)
|
|||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
|
||||
{
|
||||
if(font == NULL) font = LV_FONT_DEFAULT;
|
||||
|
||||
theme_bg_color = bg_color;
|
||||
_hue = hue;
|
||||
_font = font;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -35,6 +35,14 @@ extern "C" {
|
|||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
|
||||
#define COLOR_HOS_BG_BASE_BLACK 0x000000
|
||||
|
||||
#define COLOR_HOS_BG_DARKER 0x1B1B1B
|
||||
#define COLOR_HOS_BG_DARK 0x222222
|
||||
#define COLOR_HOS_BG 0x2D2D2D
|
||||
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
|
||||
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
@ -44,13 +52,15 @@ extern "C" {
|
|||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
extern uint32_t theme_bg_color;
|
||||
|
||||
/**
|
||||
* Initialize the material theme
|
||||
* @param hue [0..360] hue value from HSV color space to define the theme's base color
|
||||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
|
||||
|
||||
/**
|
||||
* Get a pointer to the theme
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 shchmue
|
||||
* Copyright (c) 2019-2022 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -61,7 +61,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#define VERSION_RMAP 0x10000
|
||||
#define VERSION_IVFC 0x20000
|
||||
|
||||
#define SAVE_BLOCK_SIZE_DEFAULT 0x4000
|
||||
#define SAVE_BLOCK_SIZE_DEFAULT SZ_16K
|
||||
|
||||
#define SAVE_NUM_HEADERS 2
|
||||
|
||||
|
@ -232,6 +232,6 @@ typedef struct {
|
|||
};
|
||||
} save_header_t;
|
||||
|
||||
static_assert(sizeof(save_header_t) == 0x4000, "Save header size is wrong!");
|
||||
static_assert(sizeof(save_header_t) == SZ_16K, "Save header size is wrong!");
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 shchmue
|
||||
* Copyright (c) 2019-2022 shchmue
|
||||
*
|
||||
* 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 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <stdint.h>
|
||||
|
||||
#define RMAP_ALIGN_SMALL 0x200
|
||||
#define RMAP_ALIGN_LARGE 0x4000
|
||||
#define RMAP_ALIGN_LARGE SZ_16K
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic; /* RMAP */
|
||||
|
|
|
@ -34,7 +34,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include "save.h"
|
||||
|
||||
#include <bdk.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
#include <rtc/max77620-rtc.h>
|
||||
#include <sec/se.h>
|
||||
#include <storage/sd.h>
|
||||
#include <utils/ini.h>
|
||||
#include <utils/sprintf.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -99,9 +99,10 @@ bool save_data_file_write(save_data_file_ctx_t *ctx, uint64_t *out_bytes_written
|
|||
if (!save_data_file_validate_write_params(ctx, offset, count, ctx->mode, &is_resize_needed))
|
||||
return false;
|
||||
|
||||
if (!save_data_file_set_size(ctx, offset + count))
|
||||
return false;
|
||||
|
||||
if (is_resize_needed) {
|
||||
if (!save_data_file_set_size(ctx, offset + count))
|
||||
return false;
|
||||
}
|
||||
|
||||
*out_bytes_written = save_allocation_table_storage_write(&ctx->base_storage, buffer, offset, count);
|
||||
return true;
|
||||
|
|
|
@ -250,7 +250,7 @@ uint32_t save_fs_list_allocate_entry(save_filesystem_list_ctx_t *ctx) {
|
|||
if (capacity == 0 || length >= capacity) {
|
||||
uint64_t current_size, new_size;
|
||||
save_allocation_table_storage_get_size(&ctx->storage, ¤t_size);
|
||||
if (!save_allocation_table_storage_set_size(&ctx->storage, current_size + 0x4000))
|
||||
if (!save_allocation_table_storage_set_size(&ctx->storage, current_size + SZ_16K))
|
||||
return 0;
|
||||
save_allocation_table_storage_get_size(&ctx->storage, &new_size);
|
||||
if (!save_fs_list_set_capacity(ctx, (uint32_t)(new_size / sizeof(save_fs_list_entry_t))))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 shchmue
|
||||
* Copyright (c) 2019-2022 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
|
|
@ -698,6 +698,8 @@
|
|||
|
||||
typedef enum _emc_mr_t
|
||||
{
|
||||
MR0_FEAT = 0,
|
||||
MR4_TEMP = 4,
|
||||
MR5_MAN_ID = 5,
|
||||
MR6_REV_ID1 = 6,
|
||||
MR7_REV_ID2 = 7,
|
||||
|
|
|
@ -19,33 +19,44 @@
|
|||
#include "heap.h"
|
||||
#include <gfx_utils.h>
|
||||
|
||||
static void _heap_create(heap_t *heap, u32 start)
|
||||
heap_t _heap;
|
||||
|
||||
static void _heap_create(void *start)
|
||||
{
|
||||
heap->start = start;
|
||||
heap->first = NULL;
|
||||
_heap.start = start;
|
||||
_heap.first = NULL;
|
||||
_heap.last = NULL;
|
||||
}
|
||||
|
||||
// Node info is before node address.
|
||||
static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
static void *_heap_alloc(u32 size)
|
||||
{
|
||||
hnode_t *node, *new_node;
|
||||
|
||||
// Align to cache line size.
|
||||
size = ALIGN(size, sizeof(hnode_t));
|
||||
|
||||
if (!heap->first)
|
||||
// First allocation.
|
||||
if (!_heap.first)
|
||||
{
|
||||
node = (hnode_t *)heap->start;
|
||||
node = (hnode_t *)_heap.start;
|
||||
node->used = 1;
|
||||
node->size = size;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
heap->first = node;
|
||||
|
||||
return (u32)node + sizeof(hnode_t);
|
||||
_heap.first = node;
|
||||
_heap.last = node;
|
||||
|
||||
return (void *)node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
node = heap->first;
|
||||
#ifdef BDK_MALLOC_NO_DEFRAG
|
||||
// Get the last allocated block.
|
||||
node = _heap.last;
|
||||
#else
|
||||
// Get first block and find the first available one.
|
||||
node = _heap.first;
|
||||
while (true)
|
||||
{
|
||||
// Check if there's available unused node.
|
||||
|
@ -53,7 +64,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
{
|
||||
// Size and offset of the new unused node.
|
||||
u32 new_size = node->size - size;
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + size);
|
||||
|
||||
// If there's aligned unused space from the old node,
|
||||
// create a new one and set the leftover size.
|
||||
|
@ -76,7 +87,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
node->size = size;
|
||||
node->used = 1;
|
||||
|
||||
return (u32)node + sizeof(hnode_t);
|
||||
return (void *)node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
// No unused node found, try the next one.
|
||||
|
@ -85,23 +96,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
|||
else
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// No unused node found, create a new one.
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
||||
new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size);
|
||||
new_node->used = 1;
|
||||
new_node->size = size;
|
||||
new_node->prev = node;
|
||||
new_node->next = NULL;
|
||||
node->next = new_node;
|
||||
|
||||
return (u32)new_node + sizeof(hnode_t);
|
||||
node->next = new_node;
|
||||
_heap.last = new_node;
|
||||
|
||||
return (void *)new_node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
static void _heap_free(heap_t *heap, u32 addr)
|
||||
static void _heap_free(void *addr)
|
||||
{
|
||||
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
|
||||
node->used = 0;
|
||||
node = heap->first;
|
||||
node = _heap.first;
|
||||
|
||||
#ifndef BDK_MALLOC_NO_DEFRAG
|
||||
// Do simple defragmentation on next blocks.
|
||||
while (node)
|
||||
{
|
||||
if (!node->used)
|
||||
|
@ -117,36 +134,35 @@ static void _heap_free(heap_t *heap, u32 addr)
|
|||
}
|
||||
node = node->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
heap_t _heap;
|
||||
|
||||
void heap_init(u32 base)
|
||||
void heap_init(void *base)
|
||||
{
|
||||
_heap_create(&_heap, base);
|
||||
_heap_create(base);
|
||||
}
|
||||
|
||||
void heap_copy(heap_t *heap)
|
||||
void heap_set(heap_t *heap)
|
||||
{
|
||||
memcpy(&_heap, heap, sizeof(heap_t));
|
||||
}
|
||||
|
||||
void *malloc(u32 size)
|
||||
{
|
||||
return (void *)_heap_alloc(&_heap, size);
|
||||
return _heap_alloc(size);
|
||||
}
|
||||
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||
void *res = (void *)_heap_alloc(num * size);
|
||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
void free(void *buf)
|
||||
{
|
||||
if ((u32)buf >= _heap.start)
|
||||
_heap_free(&_heap, (u32)buf);
|
||||
if (buf >= _heap.start)
|
||||
_heap_free(buf);
|
||||
}
|
||||
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
|
@ -158,7 +174,10 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
|||
while (true)
|
||||
{
|
||||
if (node->used)
|
||||
{
|
||||
mon->nodes_used++;
|
||||
mon->used += node->size + sizeof(hnode_t);
|
||||
}
|
||||
else
|
||||
mon->total += node->size + sizeof(hnode_t);
|
||||
|
||||
|
@ -174,4 +193,5 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
|||
break;
|
||||
}
|
||||
mon->total += mon->used;
|
||||
mon->nodes_total = count;
|
||||
}
|
||||
|
|
|
@ -31,18 +31,21 @@ typedef struct _hnode
|
|||
|
||||
typedef struct _heap
|
||||
{
|
||||
u32 start;
|
||||
void *start;
|
||||
hnode_t *first;
|
||||
hnode_t *last;
|
||||
} heap_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 total;
|
||||
u32 used;
|
||||
u32 total;
|
||||
u32 used;
|
||||
u32 nodes_total;
|
||||
u32 nodes_used;
|
||||
} heap_monitor_t;
|
||||
|
||||
void heap_init(u32 base);
|
||||
void heap_copy(heap_t *heap);
|
||||
void heap_init(void *base);
|
||||
void heap_set(heap_t *heap);
|
||||
void *malloc(u32 size);
|
||||
void *calloc(u32 num, u32 size);
|
||||
void free(void *buf);
|
||||
|
|
36
bdk/mem/mc.c
36
bdk/mem/mc.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,11 +17,9 @@
|
|||
|
||||
#include <memory_map.h>
|
||||
#include <mem/mc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
//#define CONFIG_ENABLE_AHB_REDIRECT
|
||||
|
||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
|
||||
{
|
||||
|
@ -125,13 +123,13 @@ void mc_config_carveout()
|
|||
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
|
||||
}
|
||||
|
||||
void mc_enable_ahb_redirect(bool full_aperture)
|
||||
void mc_enable_ahb_redirect()
|
||||
{
|
||||
// Enable ARC_CLK_OVR_ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000;
|
||||
//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
|
||||
MC(MC_IRAM_BOM) = 0x40000000;
|
||||
MC(MC_IRAM_TOM) = full_aperture ? DRAM_START : 0x4003F000;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
||||
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
||||
MC(MC_IRAM_BOM) = IRAM_BASE;
|
||||
MC(MC_IRAM_TOM) = DRAM_START; // Default is only IRAM: 0x4003F000.
|
||||
}
|
||||
|
||||
void mc_disable_ahb_redirect()
|
||||
|
@ -139,15 +137,27 @@ void mc_disable_ahb_redirect()
|
|||
MC(MC_IRAM_BOM) = 0xFFFFF000;
|
||||
MC(MC_IRAM_TOM) = 0;
|
||||
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
||||
//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
|
||||
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
||||
// Disable ARC_CLK_OVR_ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
||||
}
|
||||
|
||||
bool mc_client_has_access(void *address)
|
||||
{
|
||||
// Check if address is in DRAM or if arbitration for IRAM is enabled.
|
||||
if ((u32)address >= DRAM_START)
|
||||
return true; // Access by default.
|
||||
else if ((u32)address >= IRAM_BASE && MC(MC_IRAM_BOM) == IRAM_BASE)
|
||||
return true; // Access by AHB arbitration.
|
||||
|
||||
// No access to address space.
|
||||
return false;
|
||||
}
|
||||
|
||||
void mc_enable()
|
||||
{
|
||||
// Reset EMC source to PLLP.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29);
|
||||
// Enable memory clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
|
||||
|
@ -156,7 +166,7 @@ void mc_enable()
|
|||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
|
||||
usleep(5);
|
||||
|
||||
#ifdef CONFIG_ENABLE_AHB_REDIRECT
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
mc_enable_ahb_redirect();
|
||||
#else
|
||||
mc_disable_ahb_redirect();
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
||||
void mc_config_carveout();
|
||||
void mc_config_carveout_finalize();
|
||||
void mc_enable_ahb_redirect(bool full_aperture);
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_disable_ahb_redirect();
|
||||
bool mc_client_has_access(void *address);
|
||||
void mc_enable();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -464,6 +464,98 @@
|
|||
#define MC_UNTRANSLATED_REGION_CHECK 0x948
|
||||
#define MC_DA_CONFIG0 0x9dc
|
||||
|
||||
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */
|
||||
#define SEC_CARVEOUT_CA0_R_PTCR BIT(0)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0B BIT(3)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0BB BIT(4)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0C BIT(5)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAY0CB BIT(6)
|
||||
#define SEC_CARVEOUT_CA0_R_AFI BIT(14)
|
||||
#define SEC_CARVEOUT_CA0_R_BPMP_C BIT(15)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAYHC BIT(16)
|
||||
#define SEC_CARVEOUT_CA0_R_DISPLAYHCB BIT(17)
|
||||
#define SEC_CARVEOUT_CA0_R_HDA BIT(21)
|
||||
#define SEC_CARVEOUT_CA0_R_HOST1XDMA BIT(22)
|
||||
#define SEC_CARVEOUT_CA0_R_HOST1X BIT(23)
|
||||
#define SEC_CARVEOUT_CA0_R_NVENC BIT(28)
|
||||
#define SEC_CARVEOUT_CA0_R_PPCSAHBDMA BIT(29)
|
||||
#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30)
|
||||
#define SEC_CARVEOUT_CA0_R_SATAR BIT(31)
|
||||
|
||||
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */
|
||||
#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2)
|
||||
#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3)
|
||||
#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4)
|
||||
#define SEC_CARVEOUT_CA1_R_VDETPE BIT(5)
|
||||
#define SEC_CARVEOUT_CA1_R_CCPLEXLP_C BIT(6)
|
||||
#define SEC_CARVEOUT_CA1_R_CCPLEX_C BIT(7)
|
||||
#define SEC_CARVEOUT_CA1_W_NVENC BIT(11)
|
||||
#define SEC_CARVEOUT_CA1_W_AFI BIT(17)
|
||||
#define SEC_CARVEOUT_CA1_W_BPMP_C BIT(18)
|
||||
#define SEC_CARVEOUT_CA1_W_HDA BIT(21)
|
||||
#define SEC_CARVEOUT_CA1_W_HOST1X BIT(22)
|
||||
#define SEC_CARVEOUT_CA1_W_CCPLEXLP_C BIT(24)
|
||||
#define SEC_CARVEOUT_CA1_W_CCPLEX_C BIT(25)
|
||||
#define SEC_CARVEOUT_CA1_W_PPCSAHBDMA BIT(27)
|
||||
#define SEC_CARVEOUT_CA1_W_PPCSAHBSLV BIT(28)
|
||||
#define SEC_CARVEOUT_CA1_W_SATA BIT(29)
|
||||
#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30)
|
||||
#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31)
|
||||
|
||||
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */
|
||||
#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0)
|
||||
#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1)
|
||||
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
|
||||
#define SEC_CARVEOUT_CA2_W_ISPWA BIT(6)
|
||||
#define SEC_CARVEOUT_CA2_W_ISPWB BIT(7)
|
||||
#define SEC_CARVEOUT_CA2_R_XUSB_HOST BIT(10)
|
||||
#define SEC_CARVEOUT_CA2_W_XUSB_HOST BIT(11)
|
||||
#define SEC_CARVEOUT_CA2_R_XUSB_DEV BIT(12)
|
||||
#define SEC_CARVEOUT_CA2_W_XUSB_DEV BIT(13)
|
||||
#define SEC_CARVEOUT_CA2_R_SE2 BIT(14)
|
||||
#define SEC_CARVEOUT_CA2_W_SE2 BIT(16)
|
||||
#define SEC_CARVEOUT_CA2_R_TSEC BIT(20)
|
||||
#define SEC_CARVEOUT_CA2_W_TSEC BIT(21)
|
||||
#define SEC_CARVEOUT_CA2_R_ADSP_SC BIT(22)
|
||||
#define SEC_CARVEOUT_CA2_W_ADSP_SC BIT(23)
|
||||
#define SEC_CARVEOUT_CA2_R_GPU BIT(24)
|
||||
#define SEC_CARVEOUT_CA2_W_GPU BIT(25)
|
||||
#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26)
|
||||
|
||||
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
|
||||
#define SEC_CARVEOUT_CA3_R_SDMMCAB BIT(3)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCA BIT(4)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCAA BIT(5)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMC BIT(6)
|
||||
#define SEC_CARVEOUT_CA3_W_SDMMCAB BIT(7)
|
||||
#define SEC_CARVEOUT_CA3_R_VIC BIT(12)
|
||||
#define SEC_CARVEOUT_CA3_W_VIC BIT(13)
|
||||
#define SEC_CARVEOUT_CA3_W_VIW BIT(18)
|
||||
#define SEC_CARVEOUT_CA3_R_DISPLAYD BIT(19)
|
||||
#define SEC_CARVEOUT_CA3_R_NVDEC BIT(24)
|
||||
#define SEC_CARVEOUT_CA3_W_NVDEC BIT(25)
|
||||
#define SEC_CARVEOUT_CA3_R_APE BIT(26)
|
||||
#define SEC_CARVEOUT_CA3_W_APE BIT(27)
|
||||
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
|
||||
#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31)
|
||||
|
||||
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */
|
||||
#define SEC_CARVEOUT_CA4_R_SE BIT(0)
|
||||
#define SEC_CARVEOUT_CA4_W_SE BIT(1)
|
||||
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)
|
||||
#define SEC_CARVEOUT_CA4_W_AXIAP BIT(3)
|
||||
#define SEC_CARVEOUT_CA4_R_ETR BIT(4)
|
||||
#define SEC_CARVEOUT_CA4_W_ETR BIT(5)
|
||||
#define SEC_CARVEOUT_CA4_R_TSECB BIT(6)
|
||||
#define SEC_CARVEOUT_CA4_W_TSECB BIT(7)
|
||||
#define SEC_CARVEOUT_CA4_R_GPU2 BIT(8)
|
||||
#define SEC_CARVEOUT_CA4_W_GPU2 BIT(9)
|
||||
|
||||
// MC_VIDEO_PROTECT_REG_CTRL
|
||||
#define VPR_LOCK_MODE_SHIFT 0
|
||||
#define VPR_CTRL_UNLOCKED (0 << VPR_LOCK_MODE_SHIFT)
|
||||
|
@ -475,8 +567,8 @@
|
|||
// MC_SECURITY_CARVEOUTX_CFG0
|
||||
// Mode of LOCK_MODE.
|
||||
#define PROTECT_MODE_SHIFT 0
|
||||
#define SEC_CARVEOUT_CFG_SECURE (0 << PROTECT_MODE_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_ALL_SECURE (0 << PROTECT_MODE_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT)
|
||||
// Enables PROTECT_MODE.
|
||||
#define LOCK_MODE_SHIFT 1
|
||||
#define SEC_CARVEOUT_CFG_UNLOCKED (0 << LOCK_MODE_SHIFT)
|
||||
|
@ -487,30 +579,31 @@
|
|||
#define SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY (1 << ADDRESS_TYPE_SHIFT)
|
||||
|
||||
#define READ_ACCESS_LEVEL_SHIFT 3
|
||||
#define SEC_CARVEOUT_CFG_RD_ALL (1 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_UNK (2 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_NS (1 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_SEC (2 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_FALCON_LS (4 << READ_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_RD_FALCON_HS (8 << READ_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define WRITE_ACCESS_LEVEL_SHIFT 7
|
||||
#define SEC_CARVEOUT_CFG_WR_ALL (1 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_UNK (2 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_NS (1 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_SEC (2 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_FALCON_LS (4 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_WR_FALCON_HS (8 << WRITE_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define SEC_CARVEOUT_CFG_APERTURE_ID_MASK (3 << 11)
|
||||
#define SEC_CARVEOUT_CFG_APERTURE_ID(id) ((id) << 11)
|
||||
|
||||
#define DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT 14
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L0 (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L1 (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L2 (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L3 (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_NS (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_SEC (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_LS (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_HS (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT 18
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L0 (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L1 (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L2 (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L3 (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_NS (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_SEC (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_LS (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_HS (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
|
||||
|
||||
#define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU BIT(22)
|
||||
|
||||
|
|
|
@ -27,13 +27,18 @@
|
|||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define LA_REGS_OFFSET_T210 0x1284
|
||||
#define LA_REGS_OFFSET_T210B01 0xFA4
|
||||
#define LA_SDMMC1_INDEX 6
|
||||
#define LA_SDMMC4_INDEX 9
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
|
||||
u32 minerva_init()
|
||||
{
|
||||
u32 curr_ram_idx = 0;
|
||||
u32 tbl_idx = 0;
|
||||
|
||||
minerva_cfg = NULL;
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
@ -98,13 +103,13 @@ u32 minerva_init()
|
|||
|
||||
// Get current frequency
|
||||
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
|
||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
|
||||
{
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
|
||||
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
|
||||
break;
|
||||
}
|
||||
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
|
||||
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
|
||||
mtc_cfg->rate_to = FREQ_204;
|
||||
mtc_cfg->train_mode = OP_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
@ -140,6 +145,15 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||
}
|
||||
}
|
||||
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01)
|
||||
{
|
||||
|
||||
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? LA_REGS_OFFSET_T210B01 : LA_REGS_OFFSET_T210));
|
||||
|
||||
// Promote SDMMC1 latency allowance to SDMMC4 (SD to eMMC).
|
||||
la_scale_regs[LA_SDMMC1_INDEX] = la_scale_regs[LA_SDMMC4_INDEX];
|
||||
}
|
||||
|
||||
void minerva_prep_boot_freq()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
|
@ -157,13 +171,27 @@ void minerva_prep_boot_freq()
|
|||
minerva_change_freq(FREQ_800);
|
||||
}
|
||||
|
||||
void minerva_prep_boot_l4t()
|
||||
void minerva_prep_boot_l4t(int oc_freq)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Program SDMMC LA regs.
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
|
||||
// Add OC frequency.
|
||||
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
|
||||
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
|
||||
sizeof(emc_table_t));
|
||||
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
|
||||
mtc_cfg->table_entries++;
|
||||
}
|
||||
|
||||
// Set init frequency.
|
||||
minerva_change_freq(FREQ_204);
|
||||
|
||||
|
@ -181,11 +209,25 @@ void minerva_prep_boot_l4t()
|
|||
}
|
||||
|
||||
// Do FSP WAR and scale to 800 MHz as boot freq.
|
||||
bool fsp_opwr_enabled = !!(EMC(EMC_MRW3) & 0xC0);
|
||||
if (fsp_opwr_enabled)
|
||||
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
|
||||
if (fsp_opwr_disabled)
|
||||
minerva_change_freq(FREQ_666);
|
||||
minerva_change_freq(FREQ_800);
|
||||
|
||||
// Trim table.
|
||||
int entries = 0;
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
{
|
||||
// Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above.
|
||||
int rate = mtc_cfg->mtc_table[i].rate_khz;
|
||||
if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600)
|
||||
{
|
||||
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
mtc_cfg->table_entries = entries;
|
||||
|
||||
// Do not let other mtc ops.
|
||||
mtc_cfg->init_done = 0;
|
||||
}
|
||||
|
@ -211,3 +253,12 @@ emc_table_t *minerva_get_mtc_table()
|
|||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->mtc_table;
|
||||
}
|
||||
|
||||
int minerva_get_mtc_table_entries()
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return 0;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
return mtc_cfg->table_entries;
|
||||
}
|
||||
|
|
|
@ -61,9 +61,11 @@ typedef enum
|
|||
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
u32 minerva_init();
|
||||
void minerva_change_freq(minerva_freq_t freq);
|
||||
void minerva_sdmmc_la_program(void *table, bool t210b01);
|
||||
void minerva_prep_boot_freq();
|
||||
void minerva_prep_boot_l4t();
|
||||
void minerva_prep_boot_l4t(int oc_freq);
|
||||
void minerva_periodic_training();
|
||||
emc_table_t *minerva_get_mtc_table();
|
||||
int minerva_get_mtc_table_entries();
|
||||
|
||||
#endif
|
||||
|
|
1043
bdk/mem/sdram.c
1043
bdk/mem/sdram.c
File diff suppressed because it is too large
Load diff
114
bdk/mem/sdram.h
114
bdk/mem/sdram.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020-2021 CTCaer
|
||||
* Copyright (c) 2020-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -23,26 +23,20 @@
|
|||
/*
|
||||
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
||||
*
|
||||
* Note: BWbits T210 = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
|
||||
* BWbits T210B01 = Hz x ddr x bus width x channels = Hz x 2 x 64 x 2.
|
||||
* Both assume that both sub-partitions are used and thus reaching max
|
||||
* bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit).
|
||||
* Retail Mariko use one sub-partition, in order to meet Erista perf.
|
||||
*
|
||||
* T210 T210B01
|
||||
* 40.8 MHz: 0.61 1.22 GiB/s
|
||||
* 68.0 MHz: 1.01 2.02 GiB/s
|
||||
* 102.0 MHz: 1.52 3.04 GiB/s
|
||||
* 204.0 MHz: 3.04 6.08 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
|
||||
* 408.0 MHz: 6.08 12.16 GiB/s
|
||||
* 665.6 MHz: 9.92 19.84 GiB/s
|
||||
* 800.0 MHz: 11.92 23.84 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
||||
* 1065.6 MHz: 15.89 31.78 GiB/s
|
||||
* 1331.2 MHz: 19.84 39.68 GiB/s
|
||||
* 1600.0 MHz: 23.84 47.68 GiB/s <-- Tegra X1/X1+ HOS Max Frequency
|
||||
* 1862.4 MHz: 27.75 55.50 GiB/s <-- Tegra X1 Official Max Frequency
|
||||
* 2131.2 MHz: 31.76 63.52 GiB/s <-- Tegra X1+ Official Max Frequency
|
||||
* Note: Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
|
||||
* Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
|
||||
* Configurations supported: 1x32, 2x32, 1x64.
|
||||
* x64 ram modules can be used by combining the 2 32-bit channels into one.
|
||||
*
|
||||
* 204.0 MHz: 3.04 <-- Tegra X1/X1+ Init/SC7 Frequency
|
||||
* 408.0 MHz: 6.08
|
||||
* 665.6 MHz: 9.92
|
||||
* 800.0 MHz: 11.92 <-- Tegra X1/X1+ Nvidia OS Boot Frequency
|
||||
* 1065.6 MHz: 15.89
|
||||
* 1331.2 MHz: 19.84
|
||||
* 1600.0 MHz: 23.84
|
||||
* 1862.4 MHz: 27.75 <-- Tegra X1 Official Max Frequency
|
||||
* 2131.2 MHz: 31.76 <-- Tegra X1+ Official Max Frequency. Not all regs have support for > 2046 MHz.
|
||||
*/
|
||||
|
||||
enum sdram_ids_erista
|
||||
|
@ -51,73 +45,75 @@ enum sdram_ids_erista
|
|||
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
|
||||
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
|
||||
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C.
|
||||
LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3, // Changed to Iowa Hynix 4GB 1Y-A.
|
||||
|
||||
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
|
||||
LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5, // Changed to Hoag Hynix 4GB 1Y-A.
|
||||
LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6, // Changed to Aula Hynix 4GB 1Y-A.
|
||||
|
||||
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // Custom 8GB. XX: CH/CJ/CL. 7 since it can be easily applied in fuses.
|
||||
};
|
||||
|
||||
enum sdram_ids_mariko
|
||||
{
|
||||
// LPDDR4X 4266Mbps.
|
||||
LPDDR4X_IOWA_4GB_HYNIX_1Y_A = 3, // Replaced from Copper.
|
||||
LPDDR4X_HOAG_4GB_HYNIX_1Y_A = 5, // Replaced from Copper.
|
||||
LPDDR4X_AULA_4GB_HYNIX_1Y_A = 6, // Replaced from Copper.
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01).
|
||||
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01).
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01).
|
||||
|
||||
// LPDDR4X 3733Mbps.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7,
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 8 banks. 3733Mbps.
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M.
|
||||
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M.
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E.
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E. D9WGB.
|
||||
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M.
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 8 banks. 3733Mbps.
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M.
|
||||
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M.
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E.
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E. D9WGB.
|
||||
|
||||
// LPDDR4X 4266Mbps.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16,
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A.
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A.
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A.
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. 1z nm. 40% lower power usage. (1z-01).
|
||||
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. 1z nm. 40% lower power usage. (1z-01).
|
||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. 1z nm. 40% lower power usage. (1z-01).
|
||||
|
||||
LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20,
|
||||
LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21,
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03).
|
||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps.
|
||||
|
||||
// LPDDR4X_AULA_8GB_SAMSUNG_1Y_A = 22, // Unused.
|
||||
|
||||
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A.
|
||||
LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A.
|
||||
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F.
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F.
|
||||
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F.
|
||||
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
||||
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
||||
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
|
||||
|
||||
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A.
|
||||
|
||||
LPDDR4X_UNK0_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 29, // Die-M. 1a nm. 61% lower power usage. (1a-01).
|
||||
LPDDR4X_UNK1_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 30, // Die-M. 1a nm. 61% lower power usage. (1a-01).
|
||||
LPDDR4X_UNK2_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 31, // Die-M. 1a nm. 61% lower power usage. (1a-01).
|
||||
|
||||
LPDDR4X_UNK0_4GB_MICRON_1A = 32, // 1a nm. 61% lower power usage. (1a-01).
|
||||
LPDDR4X_UNK1_4GB_MICRON_1A = 33, // 1a nm. 61% lower power usage. (1a-01).
|
||||
LPDDR4X_UNK2_4GB_MICRON_1A = 34, // 1a nm. 61% lower power usage. (1a-01).
|
||||
};
|
||||
|
||||
enum sdram_codes_mariko
|
||||
{
|
||||
LPDDR4X_NO_PATCH = 0,
|
||||
LPDDR4X_UNUSED = 0,
|
||||
LPDDR4X_NO_PATCH = 0,
|
||||
LPDDR4X_UNUSED = 0,
|
||||
|
||||
// LPDDR4X_4GB_SAMSUNG_K4U6E3S4AM_MGCJ DRAM IDs: 08, 12.
|
||||
// LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLHR_NME DRAM IDs: 10, 14.
|
||||
|
||||
LPDDR4X_4GB_SAMSUNG_X1X2 = 1, // DRAM IDs: 07.
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 2, // DRAM IDs: 09, 13.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 3, // DRAM IDs: 11, 15.
|
||||
LPDDR4X_4GB_SAMSUNG_Y = 4, // DRAM IDs: 16.
|
||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 5, // DRAM IDs: 17, 19, 24.
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 6, // DRAM IDs: 18, 23, 28.
|
||||
LPDDR4X_4GB_SAMSUNG_1Y_Y = 7, // DRAM IDs: 20.
|
||||
LPDDR4X_8GB_SAMSUNG_1Y_Y = 8, // DRAM IDs: 21.
|
||||
//LPDDR4X_8GB_SAMSUNG_1Y_A = 9, // DRAM IDs: 22. Unused.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 10, // DRAM IDs: 25, 26, 27.
|
||||
LPDDR4X_4GB_HYNIX_1Y_A = 11, // DRAM IDs: 03, 05, 06.
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 1, // DRAM IDs: 09, 13.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
|
||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
|
||||
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
|
||||
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 5, // DRAM IDs: 20, 21, 22.
|
||||
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27.
|
||||
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
|
||||
|
||||
LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI = 8, // DRAM IDs: 29, 30, 31.
|
||||
LPDDR4X_4GB_MICRON_1A = 9, // DRAM IDs: 32, 33, 34.
|
||||
};
|
||||
|
||||
void sdram_init();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020-2021 CTCaer
|
||||
* Copyright (c) 2020-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,8 +17,6 @@
|
|||
|
||||
#define DRAM_CFG_T210_SIZE 1896
|
||||
|
||||
#define DRAM_ID(x) BIT(x)
|
||||
|
||||
static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
/* Specifies the type of memory device */
|
||||
.memory_type = MEMORY_TYPE_LPDDR4,
|
||||
|
@ -543,8 +541,12 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
|||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
|
||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR.
|
||||
.mc_video_protect_vpr_override1 = 0x00001ED3,
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
|
@ -657,40 +659,13 @@ static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
|
|||
{ 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density.
|
||||
{ 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
|
||||
|
||||
#ifdef CONFIG_SDRAM_COPPER_SUPPORT
|
||||
// Copper prototype Samsung/Hynix/Micron timing configs.
|
||||
{ 0x0000003A, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh.
|
||||
{ 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
|
||||
{ 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w.
|
||||
{ 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra.
|
||||
{ 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width.
|
||||
{ 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
|
||||
{ 0x0000003B, 0x1C0 / 4, DRAM_ID(6) }, // emc_txsr.
|
||||
{ 0x0000003B, 0x1C4 / 4, DRAM_ID(6) }, // emc_txsr_dll.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
|
||||
{ 0x00120015, 0x334 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x00160012, 0x338 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
||||
{ 0x00120015, 0x34C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00160012, 0x350 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
||||
{ 0x002F0032, 0x354 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00310032, 0x358 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00360034, 0x35C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0033002F, 0x360 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
||||
{ 0x00000006, 0x364 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x002F0032, 0x36C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00310032, 0x370 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00360034, 0x374 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0033002F, 0x378 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
||||
{ 0x00000006, 0x37C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00150015, 0x3A4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x00120012, 0x3AC / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
|
||||
{ 0x00160016, 0x3B0 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
|
||||
{ 0x00000015, 0x3B4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x00000012, 0x49C / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
|
||||
{ 0x00000012, 0x4A0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
|
||||
{ 0x00000210, 0x4F4 / 4, DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
|
||||
{ 0x00000005, 0x5C0 / 4, DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
|
||||
{ 0x00000007, 0x5C8 / 4, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
|
||||
{ 0x72A30504, 0x5D4 / 4, DRAM_ID(6) }, // mc_emem_arb_misc0.
|
||||
#endif
|
||||
// Samsung 8GB density config.
|
||||
{ 0x0000003A, 0xEC / 4, DRAM_ID(7) }, // emc_rfc.
|
||||
{ 0x0000001D, 0xF0 / 4, DRAM_ID(7) }, // emc_rfc_pb.
|
||||
{ 0x0000003B, 0x1C0 / 4, DRAM_ID(7) }, // emc_txsr.
|
||||
{ 0x0000003B, 0x1C4 / 4, DRAM_ID(7) }, // emc_txsr_dll.
|
||||
{ 0x00000713, 0x2B4 / 4, DRAM_ID(7) }, // emc_dyn_self_ref_control.
|
||||
{ 0x00080302, 0x56C / 4, DRAM_ID(7) }, // mc_emem_adr_cfg_dev0. 1024MB Rank 0 density.
|
||||
{ 0x00080302, 0x570 / 4, DRAM_ID(7) }, // mc_emem_adr_cfg_dev1. 1024MB Rank 1 density.
|
||||
{ 0x00002000, 0x584 / 4, DRAM_ID(7) }, // mc_emem_cfg. 8GB total density.
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 CTCaer
|
||||
* Copyright (c) 2020-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,
|
||||
|
@ -594,10 +594,15 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
|
||||
.mc_video_protect_vpr_override = 0xE4BAC343,
|
||||
.mc_video_protect_vpr_override1 = 0x06001ED3, // Add SE2, SE2B.
|
||||
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B.
|
||||
.mc_video_protect_vpr_override1 = 0x06001ED3,
|
||||
|
||||
.mc_video_protect_gpu_override0 = 0x00000000,
|
||||
.mc_video_protect_gpu_override1 = 0x00000000,
|
||||
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
|
@ -701,292 +706,102 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
|
|||
.bct_na = 0x00000000,
|
||||
};
|
||||
|
||||
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
|
||||
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_AUTOCAL_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_DYN_SELF_CTRL (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_QUSE_EINPUT (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
|
||||
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEI) | \
|
||||
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
|
||||
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
|
||||
|
||||
#define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
|
||||
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
|
||||
|
||||
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
|
||||
|
||||
// Samsung LPDDR4X 4GB X1X2 for prototype Iowa.
|
||||
{ 0x000E0022, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x001B0010, 0x3B0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
|
||||
{ 0x000E0022, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x001B0010, 0x3C8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
|
||||
{ 0x00490043, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00420045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00490047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x00460047, 0x3D8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
|
||||
{ 0x00000016, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00100000, 0x3E0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_5.
|
||||
{ 0x00490043, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00420045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00490047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x00460047, 0x3F0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
|
||||
{ 0x00000016, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00100000, 0x3F8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_5.
|
||||
{ 0x00220022, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000E000E, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00100010, 0x424 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_2.
|
||||
{ 0x001B001B, 0x428 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_3.
|
||||
{ 0x00000022, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_4.
|
||||
|
||||
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_adr_cfg. 2 Ranks.
|
||||
{ 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput_duration.
|
||||
{ 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_dev_select. Both devices.
|
||||
{ 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x00100010, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00100010, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00100010, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00100010, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00100010, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00100010, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00100010, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00100010, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
{ 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_adr_cfg. 2 Ranks.
|
||||
{ 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override1.
|
||||
{ 0x35353535, 0x350 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x35353535, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00100010, 0x400 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00100010, 0x404 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00100010, 0x408 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00100010, 0x40C / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00100010, 0x410 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00100010, 0x414 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
|
||||
// Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT:E Die-E for retail Iowa and Hoag.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_dyn_self_ref_control.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // mc_video_protect_gpu_override1.
|
||||
/*! Shared patched between DRAM Codes. */
|
||||
{ 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x2A800000, 0x6DC / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override1.
|
||||
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
|
||||
|
||||
// Samsung LPDDR4X 4GB (Y01) Die-? for Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_dyn_self_ref_control.
|
||||
{ 0x32323232, 0x350 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x32323232, 0x354 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00780078, 0x3FC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00780078, 0x400 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00780078, 0x404 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00780078, 0x408 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00780078, 0x40C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00780078, 0x410 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00780078, 0x414 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00780078, 0x418 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
{ 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // mc_video_protect_gpu_override1.
|
||||
{ 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control.
|
||||
|
||||
// Samsung LPDDR4X 4GB K4U6E3S4AA-MGCL 10nm-class (1y-X03) Die-A for retail Iowa, Hoag and Aula.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000006, 0x1CC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput_duration.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_dyn_self_ref_control.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // mc_video_protect_gpu_override1.
|
||||
{ 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration.
|
||||
|
||||
// Samsung LPDDR4X 8GB K4UBE3D4AA-MGCL 10nm-class (1y-X03) Die-A for SDEV Iowa, Hoag and Aula.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_adr_cfg. 2 Ranks.
|
||||
{ 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput_duration.
|
||||
{ 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_tfaw.
|
||||
{ 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_dev_select. Both devices.
|
||||
{ 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_adr_cfg. 2 Ranks.
|
||||
{ 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_faw.
|
||||
{ 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_video_protect_gpu_override1.
|
||||
{ 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw.
|
||||
{ 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw.
|
||||
|
||||
// Samsung LPDDR4X 4GB 10nm-class (1y-Y01) Die-? for Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000008, 0x24C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_tfaw.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_dyn_self_ref_control.
|
||||
{ 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x00000001, 0x670 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override1.
|
||||
{ 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC.
|
||||
{ 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
|
||||
|
||||
// Samsung LPDDR4X 8GB 10nm-class (1y-Y01) Die-? for SDEV Iowa.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_adr_cfg. 2 Ranks.
|
||||
{ 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_tfaw.
|
||||
{ 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_dev_select. Both devices.
|
||||
{ 0x32323232, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x32323232, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x000F0018, 0x3AC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
|
||||
{ 0x000F0018, 0x3C4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
|
||||
{ 0x00440048, 0x3CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
|
||||
{ 0x00440045, 0x3D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
|
||||
{ 0x00470047, 0x3D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
|
||||
{ 0x0005000D, 0x3DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
|
||||
{ 0x00440048, 0x3E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
|
||||
{ 0x00440045, 0x3E8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
|
||||
{ 0x00470047, 0x3EC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
|
||||
{ 0x0005000D, 0x3F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
|
||||
{ 0x00180018, 0x41C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0.
|
||||
{ 0x000F000F, 0x420 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1.
|
||||
{ 0x00000018, 0x42C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4.
|
||||
{ 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_adr_cfg. 2 Ranks.
|
||||
{ 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw.
|
||||
{ 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_da_turns.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override1.
|
||||
|
||||
/*
|
||||
// Samsung LPDDR4X 8GB 10nm-class (1y-A01) Die-? for SDEV Aula?
|
||||
{ 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_adr_cfg. 2 Ranks.
|
||||
{ 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_dev_select. Both devices.
|
||||
{ 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_0.
|
||||
{ 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_1.
|
||||
{ 0x35353535, 0x358 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_0.
|
||||
{ 0x35353535, 0x35C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_1.
|
||||
{ 0x00480048, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
|
||||
{ 0x00480048, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
|
||||
{ 0x00480048, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
|
||||
{ 0x00480048, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
|
||||
{ 0x00480048, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
|
||||
{ 0x00480048, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
|
||||
{ 0x00480048, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
|
||||
{ 0x00480048, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
|
||||
{ 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_init_dev1.
|
||||
{ 0x00010100, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00400010, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_adr_cfg. 2 Ranks.
|
||||
{ 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000002, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_faw.
|
||||
{ 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_da_turns.
|
||||
*/
|
||||
|
||||
// Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT:F 10nm-class (1y-01) Die-F for Newer Iowa/Hoag/Aula.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000006, 0x1CC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_einput_duration.
|
||||
{ 0x00000008, 0x24C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_tfaw.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_dyn_self_ref_control.
|
||||
{ 0x00000001, 0x670 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // mc_emem_arb_timing_faw.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // mc_video_protect_gpu_override1.
|
||||
|
||||
// Hynix LPDDR4X 4GB 10nm-class (1y-01) Die-A for Unknown Iowa/Hoag/Aula.
|
||||
{ 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_config2.
|
||||
{ 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_vref_sel0.
|
||||
{ 0x00000006, 0x1CC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse.
|
||||
{ 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse_width.
|
||||
{ 0x00000003, 0x1DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput.
|
||||
{ 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput_duration.
|
||||
{ 0x00000008, 0x24C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_tfaw.
|
||||
{ 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_mrw14.
|
||||
{ 0x80000713, 0x32C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_dyn_self_ref_control.
|
||||
{ 0x00000001, 0x670 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_emem_arb_timing_faw.
|
||||
{ 0xE4FACB43, 0x6D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override. + TSEC, NVENC.
|
||||
{ 0x0600FED3, 0x6D8 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
|
||||
{ 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override0.
|
||||
{ 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override1.
|
||||
|
||||
//!TODO: Too many duplicates.
|
||||
{ 0x00000001, 0x134 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_adr_cfg. 2 Ranks.
|
||||
{ 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw1.
|
||||
{ 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw2.
|
||||
{ 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw3.
|
||||
{ 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw6.
|
||||
{ 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw8.
|
||||
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw9.
|
||||
{ 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw10.
|
||||
{ 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw12.
|
||||
{ 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw13.
|
||||
{ 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw14.
|
||||
{ 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_mrw_extra.
|
||||
{ 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_dev_select. Both devices.
|
||||
{ 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_zcal_mrw_cmd.
|
||||
{ 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_8GB }, // emc_zcal_init_dev1.
|
||||
{ 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_pmacro_tx_pwrd4.
|
||||
{ 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_8GB }, // emc_pmacro_tx_pwrd5.
|
||||
{ 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_adr_cfg. 2 Ranks.
|
||||
{ 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_cfg. 8GB total density.
|
||||
{ 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_arb_timing_r2r.
|
||||
{ 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_8GB }, // mc_emem_arb_da_turns.
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,10 +19,10 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc_t210.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/util.h>
|
||||
#include <utils/aarch64_util.h>
|
||||
|
||||
bool smmu_used = false;
|
||||
|
@ -70,18 +71,19 @@ void smmu_flush_all()
|
|||
{
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
smmu_flush_regs();
|
||||
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
smmu_flush_regs();
|
||||
}
|
||||
|
||||
void smmu_init(u32 secmon_base)
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = 0;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_PTB_ASID) = 0;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
|
||||
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
MC(MC_SMMU_TLB_FLUSH) = 0;
|
||||
|
||||
// Set the secmon address
|
||||
*(u32 *)(smmu_payload + 0x30) = secmon_base;
|
||||
|
@ -163,8 +165,8 @@ u32 *smmu_init_for_tsec()
|
|||
|
||||
void smmu_deinit_for_tsec()
|
||||
{
|
||||
MC(MC_SMMU_PTB_ASID) = 1;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_PTB_ASID) = 1;
|
||||
MC(MC_SMMU_PTB_DATA) = 0;
|
||||
MC(MC_SMMU_TSEC_ASID) = 0;
|
||||
smmu_flush_regs();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#ifndef _MEMORY_MAP_H_
|
||||
#define _MEMORY_MAP_H_
|
||||
|
||||
//#define IPL_STACK_TOP 0x4003FF00
|
||||
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
||||
/* --- IPL: 0x40008000 - 0x40028000 --- */
|
||||
#define LDR_LOAD_ADDR 0x40007000
|
||||
|
@ -25,13 +24,20 @@
|
|||
#define IPL_LOAD_ADDR 0x40008000
|
||||
#define IPL_SZ_MAX SZ_128K
|
||||
|
||||
/* --- XUSB EP context and TRB ring buffers --- */
|
||||
#define XUSB_RING_ADDR 0x40020000
|
||||
#define XUSB_RING_ADDR 0x40020000 // XUSB EP context and TRB ring buffers.
|
||||
|
||||
#define SECMON_MIN_START 0x4002B000
|
||||
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
||||
|
||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||
|
||||
/* start.S / exception_handlers.S */
|
||||
#define SYS_STACK_TOP_INIT 0x4003FF00
|
||||
#define FIQ_STACK_TOP 0x40040000
|
||||
#define IRQ_STACK_TOP 0x40040000
|
||||
#define IPL_RELOC_ADDR 0x4003FF00
|
||||
#define IPL_RELOC_SZ 0x10
|
||||
#define EXCP_STORAGE_ADDR 0x4003FFF0
|
||||
#define EXCP_STORAGE_SZ 0x10
|
||||
|
||||
/* --- DRAM START --- */
|
||||
#define DRAM_START 0x80000000
|
||||
|
@ -95,6 +101,7 @@
|
|||
#define NYX_FB2_ADDRESS 0xF6600000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
|
||||
/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */
|
||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -73,18 +73,23 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
|||
|
||||
if (inserted)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = buf[0] & STATUS1_INSERT ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||
memcpy(pdos, &buf[1], 28);
|
||||
|
||||
memset(usb_pd, 0, sizeof(usb_pd_objects_t));
|
||||
usb_pd->pdo_no = buf[0] / sizeof(pd_object_t);
|
||||
|
||||
if (usb_pd->pdo_no > 7)
|
||||
usb_pd->pdo_no = 7;
|
||||
|
||||
for (u32 i = 0; i < usb_pd->pdo_no; i++)
|
||||
{
|
||||
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// REG 1 masks.
|
||||
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
|
||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) // 3000uV HOS default.
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
|
||||
#define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1<<4)
|
||||
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "max17050.h"
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define BASE_SNS_UOHM 5000
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@
|
|||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C // OTP version.
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
#define MAX77620_REG_CID5 0x5D // ES version.
|
||||
#define MAX77620_CID_DIDO_MASK 0xF
|
||||
#define MAX77620_CID_DIDO_SHIFT 0
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include <power/max77812.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define REGULATOR_SD 0
|
||||
#define REGULATOR_LDO 1
|
||||
|
@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
|
|||
|
||||
static const max77620_regulator_t _pmic_regulators[] = {
|
||||
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
|
||||
{ "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||
{ "sd1", 12500, 600000, 1125000, 1175000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
|
||||
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
|
||||
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
|
||||
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
|
||||
|
@ -88,11 +88,11 @@ static const max77620_regulator_t _pmic_regulators[] = {
|
|||
{ "ldo7", 50000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO7, 1, 4, 3 }} },
|
||||
{ "ldo8", 50000, 800000, 1050000, 2800000, REGULATOR_LDO, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO8, 3, 7, 0 }} },
|
||||
|
||||
{ "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_VOUT_REG, MAX77621_VOUT_DVS_REG, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_VOUT_REG, MAX77621_VOUT_DVS_REG, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} },
|
||||
{ "max77812_CPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M4_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M4_MASK, MAX77812_EN_CTRL_EN_M4_SHIFT, 0, 0 }} },
|
||||
{ "max77812_RAM", 5000, 250000, 600000, 650000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration.
|
||||
//{ "max77812_GPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M1_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M1_MASK, MAX77812_EN_CTRL_EN_M1_SHIFT, 0, 0 }} },
|
||||
//{ "max77812_RAM", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration.
|
||||
};
|
||||
|
||||
static u8 _max77812_get_address()
|
||||
|
@ -121,7 +121,12 @@ static u8 _max7762x_get_i2c_address(u32 id)
|
|||
case REGULATOR_BC0:
|
||||
return (id == REGULATOR_CPU0 ? MAX77621_CPU_I2C_ADDR : MAX77621_GPU_I2C_ADDR);
|
||||
case REGULATOR_BC1:
|
||||
return _max77812_get_address();
|
||||
{
|
||||
u8 reg_addr = _max77812_get_address();
|
||||
if (id == REGULATOR_RAM0 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
|
||||
reg_addr = 0;
|
||||
return reg_addr;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -175,20 +180,22 @@ int max77620_regulator_config_fps(u32 id)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 mv)
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 uv)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->uv_min || mv > reg->uv_max)
|
||||
if (uv < reg->uv_min || uv > reg->uv_max)
|
||||
return 0;
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
// Calculate voltage multiplier.
|
||||
u32 mult = (mv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
|
||||
u32 mult = (uv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step;
|
||||
u8 val = i2c_recv_byte(I2C_5, addr, reg->volt_addr);
|
||||
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
|
||||
|
@ -249,6 +256,8 @@ int max7762x_regulator_enable(u32 id, bool enable)
|
|||
}
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
// Read and enable/disable.
|
||||
u8 val = i2c_recv_byte(I2C_5, addr, reg_addr);
|
||||
|
@ -291,6 +300,8 @@ void max77621_config_default(u32 id, bool por)
|
|||
return;
|
||||
|
||||
u8 addr = _max7762x_get_i2c_address(id);
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
if (por)
|
||||
{
|
||||
|
@ -299,13 +310,13 @@ void max77621_config_default(u32 id, bool por)
|
|||
max7762x_regulator_enable(id, false);
|
||||
|
||||
// Configure to default.
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_CONTROL1_REG, reg->ctrl.ctrl1_por);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_por);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_por);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_por);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_CONTROL1_REG, reg->ctrl.ctrl1_hos);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_hos);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_hos);
|
||||
i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_hos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,22 +66,22 @@
|
|||
#define REGULATOR_LDO6 10
|
||||
#define REGULATOR_LDO7 11
|
||||
#define REGULATOR_LDO8 12
|
||||
#define REGULATOR_CPU0 13
|
||||
#define REGULATOR_GPU0 14
|
||||
#define REGULATOR_CPU1 15
|
||||
//#define REGULATOR_GPU1 16
|
||||
//#define REGULATOR_GPU1 17
|
||||
#define REGULATOR_MAX 15
|
||||
#define REGULATOR_CPU0 13 // T210 CPU.
|
||||
#define REGULATOR_GPU0 14 // T210 CPU.
|
||||
#define REGULATOR_CPU1 15 // T210B01 CPU.
|
||||
#define REGULATOR_RAM0 16 // T210B01 RAM for PHASE211.
|
||||
//#define REGULATOR_GPU1 17 // T210B01 CPU.
|
||||
#define REGULATOR_MAX REGULATOR_RAM0
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
|
||||
#define MAX77621_VOUT_REG 0x00
|
||||
#define MAX77621_VOUT_DVS_REG 0x01
|
||||
#define MAX77621_CONTROL1_REG 0x02
|
||||
#define MAX77621_CONTROL2_REG 0x03
|
||||
#define MAX77621_CHIPID1_REG 0x04
|
||||
#define MAX77621_CHIPID2_REG 0x05
|
||||
#define MAX77621_REG_VOUT 0x00
|
||||
#define MAX77621_REG_VOUT_DVS 0x01
|
||||
#define MAX77621_REG_CONTROL1 0x02
|
||||
#define MAX77621_REG_CONTROL2 0x03
|
||||
#define MAX77621_REG_CHIPID1 0x04
|
||||
#define MAX77621_REG_CHIPID2 0x05
|
||||
|
||||
/* MAX77621_VOUT_DVC_DVS */
|
||||
#define MAX77621_DVC_DVS_VOLT_MASK 0x7F
|
||||
|
@ -114,11 +114,10 @@
|
|||
#define MAX77621_INDUCTOR_PLUS_60_PER 3
|
||||
#define MAX77621_INDUCTOR_MASK 3
|
||||
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US BIT(2)
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS BIT(3)
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE (BIT(2) | BIT(3))
|
||||
#define MAX77621_CKKADV_TRIP_MASK (BIT(2) | BIT(3))
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US (0 << 2)
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US (1u << 2)
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE (3u << 2)
|
||||
#define MAX77621_CKKADV_TRIP_MASK (3u << 2)
|
||||
|
||||
#define MAX77621_FT_ENABLE BIT(4)
|
||||
#define MAX77621_DISCH_ENABLE BIT(5)
|
||||
|
@ -126,18 +125,17 @@
|
|||
#define MAX77621_T_JUNCTION_120 BIT(7)
|
||||
|
||||
#define MAX77621_CPU_CTRL1_POR_DEFAULT (MAX77621_RAMP_50mV_PER_US)
|
||||
#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \
|
||||
MAX77621_NFSR_ENABLE | \
|
||||
MAX77621_SNS_ENABLE | \
|
||||
#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \
|
||||
MAX77621_NFSR_ENABLE | \
|
||||
MAX77621_SNS_ENABLE | \
|
||||
MAX77621_RAMP_12mV_PER_US)
|
||||
#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_FT_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | \
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | \
|
||||
#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_FT_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_DISABLE | \
|
||||
MAX77621_INDUCTOR_NOMINAL)
|
||||
#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_WDTMR_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_75mV_PER_US | \
|
||||
#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \
|
||||
MAX77621_WDTMR_ENABLE | \
|
||||
MAX77621_CKKADV_TRIP_75mV_PER_US | \
|
||||
MAX77621_INDUCTOR_NOMINAL)
|
||||
|
||||
#define MAX77621_CTRL_HOS_CFG 0
|
||||
|
@ -145,7 +143,7 @@
|
|||
|
||||
int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max7762x_regulator_set_voltage(u32 id, u32 uv);
|
||||
int max7762x_regulator_enable(u32 id, bool enable);
|
||||
void max77620_config_gpio(u32 id, bool enable);
|
||||
void max77620_config_default();
|
||||
|
|
|
@ -66,21 +66,22 @@
|
|||
#define MAX77812_REG_M2_VOUT_S 0x2C
|
||||
#define MAX77812_REG_M3_VOUT_S 0x2D
|
||||
#define MAX77812_REG_M4_VOUT_S 0x2E
|
||||
#define MAX77812_REG_M1_CFG 0x2F
|
||||
#define MAX77812_REG_M2_CFG 0x30
|
||||
#define MAX77812_REG_M3_CFG 0x31
|
||||
#define MAX77812_REG_M4_CFG 0x32
|
||||
#define MAX77812_REG_GLB_CFG1 0x33
|
||||
#define MAX77812_REG_GLB_CFG2 0x34
|
||||
#define MAX77812_REG_M1_CFG 0x2F // HOS: M1_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M2_CFG 0x30 // HOS: M2_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M3_CFG 0x31 // HOS: M3_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_M4_CFG 0x32 // HOS: M4_ILIM - 7.2A/4.8A.
|
||||
#define MAX77812_REG_GLB_CFG1 0x33 // HOS: B_SD_SR/B_SS_SR - 5mV/us.
|
||||
#define MAX77812_REG_GLB_CFG2 0x34 // HOS: B_RD_SR/B_RU_SR - 5mV/us
|
||||
#define MAX77812_REG_GLB_CFG3 0x35
|
||||
|
||||
/*! Protected area and settings only for MAX77812_ES2_VERSION */
|
||||
#define MAX77812_REG_GLB_CFG4 0x36
|
||||
#define MAX77812_REG_GLB_CFG5 0x37
|
||||
#define MAX77812_REG_GLB_CFG6 0x38
|
||||
#define MAX77812_REG_GLB_CFG5 0x37 // HOS: 0x3E. Unmasked write.
|
||||
#define MAX77812_REG_GLB_CFG6 0x38 // HOS: 0x90. Unmasked write.
|
||||
#define MAX77812_REG_GLB_CFG7 0x39
|
||||
#define MAX77812_REG_GLB_CFG8 0x3A
|
||||
#define MAX77812_REG_PROT_ACCESS 0xFD
|
||||
#define MAX77812_REG_GLB_CFG8 0x3A // HOS: 0x3A. Unmasked write.
|
||||
|
||||
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
|
||||
#define MAX77812_REG_MAX 0xFD
|
||||
|
||||
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -27,38 +27,31 @@ static bool usb_src = false;
|
|||
|
||||
void regulator_5v_enable(u8 dev)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// The power supply selection from battery or USB is automatic.
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Fan and Rail power from battery 5V regulator.
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
|
||||
|
||||
// Only Icosa and Iowa have USB 5V VBUS rails. Skip on Hoag/Aula.
|
||||
u32 hw_type = fuse_read_hw_type();
|
||||
if (hw_type == FUSE_NX_HW_TYPE_ICOSA ||
|
||||
hw_type == FUSE_NX_HW_TYPE_IOWA)
|
||||
// Only Icosa has USB 5V VBUS rails.
|
||||
if (tegra_t210)
|
||||
{
|
||||
// Fan and Rail power from USB 5V VBUS.
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
}
|
||||
|
||||
// Enable GPIO AO IO rail for T210.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
{
|
||||
// Make sure GPIO power is enabled.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
|
||||
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
|
||||
// Make sure GPIO IO power is enabled.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
|
||||
(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;
|
||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||
|
||||
// Override power detect for GPIO AO IO rails.
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN;
|
||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||
}
|
||||
usb_src = false;
|
||||
}
|
||||
reg_5v_dev |= dev;
|
||||
|
@ -66,36 +59,23 @@ void regulator_5v_enable(u8 dev)
|
|||
|
||||
void regulator_5v_disable(u8 dev)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
reg_5v_dev &= ~dev;
|
||||
|
||||
if (!reg_5v_dev)
|
||||
{
|
||||
// Rail power from battery 5V regulator.
|
||||
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
|
||||
// Only Icosa and Iowa have USB 5V VBUS rails. Skip on Hoag/Aula.
|
||||
u32 hw_type = fuse_read_hw_type();
|
||||
if (hw_type == FUSE_NX_HW_TYPE_ICOSA ||
|
||||
hw_type == FUSE_NX_HW_TYPE_IOWA)
|
||||
// Only Icosa has USB 5V VBUS rails.
|
||||
if (tegra_t210)
|
||||
{
|
||||
// Rail power from USB 5V VBUS.
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO);
|
||||
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE;
|
||||
usb_src = false;
|
||||
|
||||
}
|
||||
|
||||
// GPIO AO IO rails.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
{
|
||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN;
|
||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,10 +86,8 @@ bool regulator_5v_get_dev_enabled(u8 dev)
|
|||
|
||||
void regulator_5v_usb_src_enable(bool enable)
|
||||
{
|
||||
// Only for Icosa/Iowa. Skip on Hoag/Aula.
|
||||
u32 hw_type = fuse_read_hw_type();
|
||||
if (hw_type != FUSE_NX_HW_TYPE_ICOSA &&
|
||||
hw_type != FUSE_NX_HW_TYPE_IOWA)
|
||||
// Only for Icosa.
|
||||
if (hw_get_chip_id() != GP_HIDREV_MAJOR_T210)
|
||||
return;
|
||||
|
||||
if (enable && !usb_src)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2019 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -19,7 +19,14 @@
|
|||
|
||||
#include <rtc/max77620-rtc.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
void max77620_rtc_prep_read()
|
||||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
||||
}
|
||||
|
||||
void max77620_rtc_get_time(rtc_time_t *time)
|
||||
{
|
||||
|
@ -35,7 +42,7 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||
// Get time.
|
||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
time->hour = hour & 0x1F;
|
||||
|
||||
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
|
||||
|
@ -53,7 +60,7 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
|||
}
|
||||
|
||||
// Get date.
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
||||
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
||||
}
|
||||
|
@ -64,6 +71,7 @@ void max77620_rtc_stop_alarm()
|
|||
|
||||
// Update RTC regs from RTC clock.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
|
||||
msleep(16);
|
||||
|
||||
// Stop alarm for both ALARM1 and ALARM2. Horizon uses ALARM2.
|
||||
for (int i = 0; i < (MAX77620_RTC_NR_TIME_REGS * 2); i++)
|
||||
|
@ -82,9 +90,9 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
|||
u32 tmp, edays, year, month, day;
|
||||
|
||||
// Set time.
|
||||
time->sec = epoch % 60;
|
||||
time->sec = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->min = epoch % 60;
|
||||
time->min = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->hour = epoch % 24;
|
||||
epoch /= 24;
|
||||
|
@ -99,14 +107,14 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
|||
day = edays - month * 30 - month * 601 / 1000;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 14)
|
||||
if (month < 14)
|
||||
{
|
||||
year -= 4716;
|
||||
month--;
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 4715;
|
||||
year -= 4715;
|
||||
month -= 13;
|
||||
}
|
||||
|
||||
|
@ -129,13 +137,13 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
|||
month = time->month;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
if (month < 3)
|
||||
{
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
|
@ -145,3 +153,45 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
|||
|
||||
return epoch;
|
||||
}
|
||||
|
||||
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
|
||||
{
|
||||
max77620_rtc_stop_alarm();
|
||||
|
||||
// Set reboot reason.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG, rr->enc.val1);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG, rr->enc.val2);
|
||||
|
||||
// Set reboot reason magic.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC);
|
||||
|
||||
// Update RTC clock from RTC regs.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
|
||||
msleep(16);
|
||||
}
|
||||
|
||||
bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr)
|
||||
{
|
||||
u8 magic[2];
|
||||
|
||||
// Get reboot reason magic.
|
||||
magic[0] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG);
|
||||
magic[1] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG);
|
||||
|
||||
// Magic must be correct and match on both registers.
|
||||
if (magic[0] != RTC_REBOOT_REASON_MAGIC || magic[0] != magic[1])
|
||||
return false;
|
||||
|
||||
// Reboot reason setter is expected to have updated the actual regs already.
|
||||
rr->enc.val1 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG);
|
||||
rr->enc.val2 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG);
|
||||
|
||||
// Clear magic and update actual regs.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
|
||||
|
||||
// Return reboot reason. False if [config] was selected.
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
#define MAX77620_RTC_NR_TIME_REGS 7
|
||||
|
||||
#define MAX77620_RTC_RTCINT_REG 0x00
|
||||
#define MAX77620_RTC_RTCINTM_REG 0x01
|
||||
#define MAX77620_RTC_CONTROLM_REG 0x02
|
||||
#define MAX77620_RTC_CONTROL_REG 0x03
|
||||
#define MAX77620_RTC_BIN_FORMAT BIT(0)
|
||||
|
@ -34,6 +36,9 @@
|
|||
#define MAX77620_RTC_WRITE_UPDATE BIT(0)
|
||||
#define MAX77620_RTC_READ_UPDATE BIT(4)
|
||||
|
||||
#define MAX77620_RTC_UPDATE1_REG 0x05
|
||||
#define MAX77620_RTC_RTCSMPL_REG 0x06
|
||||
|
||||
#define MAX77620_RTC_SEC_REG 0x07
|
||||
#define MAX77620_RTC_MIN_REG 0x08
|
||||
#define MAX77620_RTC_HOUR_REG 0x09
|
||||
|
@ -69,9 +74,45 @@ typedef struct _rtc_time_t {
|
|||
u16 year;
|
||||
} rtc_time_t;
|
||||
|
||||
#define RTC_REBOOT_REASON_MAGIC 0x77 // 7-bit reg.
|
||||
|
||||
enum {
|
||||
REBOOT_REASON_NOP = 0, // Use [config].
|
||||
REBOOT_REASON_SELF = 1, // Use autoboot_idx/autoboot_list.
|
||||
REBOOT_REASON_MENU = 2, // Force menu.
|
||||
REBOOT_REASON_UMS = 3, // Force selected UMS partition.
|
||||
REBOOT_REASON_REC = 4, // Set PMC_SCRATCH0_MODE_RECOVERY and reboot to self.
|
||||
REBOOT_REASON_PANIC = 5 // Inform bootloader that panic occured if T210B01.
|
||||
};
|
||||
|
||||
typedef struct _rtc_rr_decoded_t
|
||||
{
|
||||
u16 reason:4;
|
||||
u16 autoboot_idx:4;
|
||||
u16 autoboot_list:1;
|
||||
u16 ums_idx:3;
|
||||
} rtc_rr_decoded_t;
|
||||
|
||||
typedef struct _rtc_rr_encoded_t
|
||||
{
|
||||
u16 val1:6; // 6-bit reg.
|
||||
u16 val2:6; // 6-bit reg.
|
||||
} rtc_rr_encoded_t;
|
||||
|
||||
typedef struct _rtc_reboot_reason_t
|
||||
{
|
||||
union {
|
||||
rtc_rr_decoded_t dec;
|
||||
rtc_rr_encoded_t enc;
|
||||
};
|
||||
} rtc_reboot_reason_t;
|
||||
|
||||
void max77620_rtc_prep_read();
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr);
|
||||
bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr);
|
||||
|
||||
#endif /* _MFD_MAX77620_RTC_H_ */
|
||||
|
|
246
bdk/sec/se.c
246
bdk/sec/se.c
|
@ -23,8 +23,8 @@
|
|||
#include <soc/bpmp.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
typedef struct _se_ll_t
|
||||
{
|
||||
|
@ -33,7 +33,8 @@ typedef struct _se_ll_t
|
|||
vu32 size;
|
||||
} se_ll_t;
|
||||
|
||||
se_ll_t *ll_dst, *ll_src;
|
||||
se_ll_t ll_src, ll_dst;
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
|
||||
|
||||
static void _gf256_mul_x(void *block)
|
||||
{
|
||||
|
@ -69,12 +70,12 @@ static void _gf256_mul_x_le(void *block)
|
|||
|
||||
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
|
||||
{
|
||||
ll->num = 0;
|
||||
ll->num = 0;
|
||||
ll->addr = addr;
|
||||
ll->size = size;
|
||||
}
|
||||
|
||||
static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
|
||||
static void _se_ll_set(se_ll_t *src, se_ll_t *dst)
|
||||
{
|
||||
SE(SE_IN_LL_ADDR_REG) = (u32)src;
|
||||
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
|
||||
|
@ -89,13 +90,16 @@ static int _se_wait()
|
|||
;
|
||||
|
||||
// Check for errors.
|
||||
if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
|
||||
if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
|
||||
(SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
|
||||
SE(SE_ERR_STATUS_REG) != 0)
|
||||
(SE(SE_ERR_STATUS_REG) != 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// T210B01: IRAM/TZRAM/DRAM AHB coherency WAR.
|
||||
if (!tegra_t210 && ll_dst)
|
||||
if (!tegra_t210 && ll_dst_ptr)
|
||||
{
|
||||
u32 timeout = get_tmr_us() + 1000000;
|
||||
// Ensure data is out from SE.
|
||||
|
@ -107,7 +111,7 @@ static int _se_wait()
|
|||
}
|
||||
|
||||
// Ensure data is out from AHB.
|
||||
if(ll_dst->addr >= DRAM_START)
|
||||
if (ll_dst_ptr->addr >= DRAM_START)
|
||||
{
|
||||
timeout = get_tmr_us() + 200000;
|
||||
while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID)
|
||||
|
@ -122,75 +126,52 @@ static int _se_wait()
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_dst = NULL;
|
||||
ll_src = NULL;
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_dst, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_src, (u32)src, src_size);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_dst, ll_src);
|
||||
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG) = op;
|
||||
|
||||
if (is_oneshot)
|
||||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
if (src)
|
||||
{
|
||||
free(ll_src);
|
||||
ll_src = NULL;
|
||||
}
|
||||
if (dst)
|
||||
{
|
||||
free(ll_dst);
|
||||
ll_dst = NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute_finalize()
|
||||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
// Invalidate data after OP is done.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
if (ll_src)
|
||||
{
|
||||
free(ll_src);
|
||||
ll_src = NULL;
|
||||
}
|
||||
if (ll_dst)
|
||||
{
|
||||
free(ll_dst);
|
||||
ll_dst = NULL;
|
||||
}
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src_ptr = &ll_src;
|
||||
_se_ll_init(ll_src_ptr, (u32)src, src_size);
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst_ptr = &ll_dst;
|
||||
_se_ll_init(ll_dst_ptr, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_src_ptr, ll_dst_ptr);
|
||||
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
// Flush data before starting OP.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG) = op;
|
||||
|
||||
if (is_oneshot)
|
||||
return _se_execute_finalize();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
return _se_execute(op, dst, dst_size, src, src_size, true);
|
||||
|
@ -201,8 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
|||
if (!src || !dst)
|
||||
return 0;
|
||||
|
||||
u8 *block = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||
memset(block, 0, SE_AES_BLOCK_SIZE);
|
||||
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE);
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
|
@ -227,7 +207,7 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
|||
{
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
|
||||
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||
SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG;
|
||||
if (flags & SE_RSA_KEY_LOCK_FLAG)
|
||||
SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
|
||||
|
@ -304,8 +284,8 @@ void se_aes_iv_clear(u32 ks)
|
|||
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
|
@ -333,14 +313,14 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
|
|||
if (enc)
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
|
||||
}
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
|
@ -355,8 +335,9 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
|
|||
{
|
||||
SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_CNTN(1);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
|
||||
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
|
||||
SE_CRYPTO_CTR_CNTN(1);
|
||||
_se_aes_ctr_set(ctr);
|
||||
|
||||
u32 src_size_aligned = src_size & 0xFFFFFFF0;
|
||||
|
@ -570,9 +551,9 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
|||
int se_gen_prng128(void *dst)
|
||||
{
|
||||
// Setup config for X931 PRNG.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
|
||||
//SE(SE_RNG_SRC_CONFIG_REG) =
|
||||
// SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE);
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG) = 1;
|
||||
|
@ -588,9 +569,9 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
|
||||
|
||||
// Set Secure Random Key.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0);
|
||||
|
||||
|
@ -600,7 +581,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
|
@ -609,7 +590,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
if (keysize > SE_KEY_128_SIZE)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
|
@ -640,6 +621,51 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
|||
se_aes_key_clear(3);
|
||||
}
|
||||
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *secret = (u8 *)malloc(0x40);
|
||||
u8 *ipad = (u8 *)malloc(0x40 + src_size);
|
||||
u8 *opad = (u8 *)malloc(0x60);
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
free(secret);
|
||||
free(ipad);
|
||||
free(opad);
|
||||
return res;
|
||||
}
|
||||
|
||||
// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
|
@ -648,7 +674,7 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
|||
u8 *last_block = (u8 *)calloc(0x10, 1);
|
||||
|
||||
// generate derived key
|
||||
if (!se_aes_crypt_block_ecb(ks, 1, key, key))
|
||||
if (!se_aes_crypt_block_ecb(ks, ENCRYPT, key, key))
|
||||
goto out;
|
||||
_gf256_mul_x(key);
|
||||
if (src_size & 0xF)
|
||||
|
@ -693,48 +719,4 @@ out:;
|
|||
free(key);
|
||||
free(last_block);
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *secret = (u8 *)malloc(0x40);
|
||||
u8 *ipad = (u8 *)malloc(0x40 + src_size);
|
||||
u8 *opad = (u8 *)malloc(0x60);
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
free(secret);
|
||||
free(ipad);
|
||||
free(opad);
|
||||
return res;
|
||||
}
|
|
@ -42,7 +42,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u6
|
|||
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
|
||||
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
|
||||
int se_gen_prng128(void *dst);
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -20,16 +20,17 @@
|
|||
|
||||
#include "tsec.h"
|
||||
#include "tsec_t210.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/kfuse.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
// #include <gfx_utils.h>
|
||||
|
||||
|
@ -57,9 +58,9 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse
|
|||
else
|
||||
cmd = TSEC_DMATRFCMD_IMEM; // DMA IMEM (Instruction memmory)
|
||||
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFFBOFFS) = pa_offset;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
|
||||
return _tsec_dma_wait_idle();
|
||||
}
|
||||
|
@ -76,16 +77,16 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
// Enable clocks.
|
||||
clock_enable_host1x();
|
||||
usleep(2);
|
||||
clock_enable_tsec();
|
||||
clock_enable_sor_safe();
|
||||
clock_enable_sor0();
|
||||
clock_enable_sor1();
|
||||
clock_enable_kfuse();
|
||||
|
||||
kfuse_wait_ready();
|
||||
|
||||
// Disable AHB aperture.
|
||||
mc_disable_ahb_redirect();
|
||||
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
{
|
||||
// Disable all CCPLEX core rails.
|
||||
|
@ -95,23 +96,23 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
||||
|
||||
// Enable AHB aperture and set it to full mmio.
|
||||
mc_enable_ahb_redirect(true);
|
||||
mc_enable_ahb_redirect();
|
||||
}
|
||||
|
||||
// Configure Falcon.
|
||||
TSEC(TSEC_DMACTL) = 0;
|
||||
TSEC(TSEC_IRQMSET) =
|
||||
TSEC_IRQMSET_EXT(0xFF) |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_SWGEN1;
|
||||
TSEC(TSEC_IRQDEST) =
|
||||
TSEC_IRQDEST_EXT(0xFF) |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_SWGEN1;
|
||||
TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN;
|
||||
if (!_tsec_dma_wait_idle())
|
||||
|
@ -128,6 +129,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
fwbuf = (u8 *)malloc(SZ_16K);
|
||||
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100);
|
||||
memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size);
|
||||
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8;
|
||||
}
|
||||
|
||||
|
@ -180,7 +182,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
mc = page_alloc(1);
|
||||
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
||||
mc[MC_IRAM_BOM / 4] = 0;
|
||||
mc[MC_IRAM_TOM / 4] = 0x80000000;
|
||||
mc[MC_IRAM_TOM / 4] = DRAM_START;
|
||||
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE);
|
||||
|
||||
// IRAM
|
||||
|
@ -197,15 +199,15 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
|
||||
// Execute firmware.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
|
||||
TSEC(TSEC_STATUS) = 0;
|
||||
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
TSEC(TSEC_MAILBOX1) = 0;
|
||||
TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
{
|
||||
u32 start = get_tmr_us();
|
||||
u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
|
||||
u32 timeout = get_tmr_us() + 125000;
|
||||
u32 key[16] = {0};
|
||||
u32 kidx = 0;
|
||||
|
||||
|
@ -220,7 +222,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
}
|
||||
|
||||
// Failsafe.
|
||||
if ((u32)get_tmr_us() - start > 125000)
|
||||
if ((u32)get_tmr_us() > timeout)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -243,7 +245,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
// for (int i = 0; i < kidx; i++)
|
||||
// gfx_printf("key %08X\n", key[i]);
|
||||
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
|
||||
|
||||
// u32 errst = MC(MC_ERR_STATUS);
|
||||
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
|
||||
|
@ -259,14 +261,18 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
res = -3;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!TSEC(TSEC_STATUS))
|
||||
while (!TSEC(TSEC_MAILBOX1))
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = -4;
|
||||
goto out_free;
|
||||
}
|
||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
||||
}
|
||||
|
||||
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
|
||||
{
|
||||
res = -5;
|
||||
goto out_free;
|
||||
|
@ -275,23 +281,22 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
|||
// Fetch result.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
|
||||
u32 buf[4];
|
||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
|
||||
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
out_free:;
|
||||
out_free:
|
||||
free(fwbuf);
|
||||
|
||||
out:;
|
||||
|
||||
out:
|
||||
// Disable clocks.
|
||||
clock_disable_kfuse();
|
||||
clock_disable_sor1();
|
||||
|
@ -301,9 +306,10 @@ out:;
|
|||
bpmp_mmu_enable();
|
||||
bpmp_clk_rate_set(prev_fid);
|
||||
|
||||
// Disable AHB aperture.
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
mc_disable_ahb_redirect();
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
// Re-enable AHB aperture.
|
||||
mc_enable_ahb_redirect();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ enum tsec_fw_type
|
|||
{
|
||||
// Retail Hovi Keygen.
|
||||
TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
|
||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated enviroment.
|
||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
|
||||
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,8 +17,8 @@
|
|||
#ifndef _TSEC_T210_H_
|
||||
#define _TSEC_T210_H_
|
||||
|
||||
#define TSEC_BOOTKEYVER 0x1040
|
||||
#define TSEC_STATUS 0x1044
|
||||
#define TSEC_MAILBOX0 0x1040
|
||||
#define TSEC_MAILBOX1 0x1044
|
||||
#define TSEC_ITFEN 0x1048
|
||||
#define TSEC_ITFEN_CTXEN BIT(0)
|
||||
#define TSEC_ITFEN_MTHDEN BIT(1)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,9 +18,9 @@
|
|||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <memory_map.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define BPMP_MMU_CACHE_LINE_SIZE 0x20
|
||||
|
||||
|
@ -134,7 +134,7 @@ void bpmp_mmu_maintenance(u32 op, bool force)
|
|||
// This is a blocking operation.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;
|
||||
|
||||
while(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
while (!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE))
|
||||
;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
|
||||
|
@ -150,8 +150,8 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
|
|||
if (entry->enable)
|
||||
{
|
||||
mmu_entry->start_addr = ALIGN(entry->start_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE);
|
||||
mmu_entry->attr = entry->attr;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx);
|
||||
|
||||
|
@ -166,9 +166,9 @@ void bpmp_mmu_enable()
|
|||
return;
|
||||
|
||||
// Init BPMP MMU.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;
|
||||
|
||||
// Init BPMP MMU entries.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;
|
||||
|
@ -206,6 +206,7 @@ void bpmp_mmu_disable()
|
|||
const u8 pll_divn[] = {
|
||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
// Do not use for public releases!
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -47,12 +47,14 @@ typedef enum
|
|||
{
|
||||
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
||||
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
|
||||
BPMP_CLK_HIGH2_BOOST, // 563MHz 38% - 141MHz APB.
|
||||
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_MAX
|
||||
} bpmp_freq_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -15,6 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <soc/ccplex.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
|
@ -51,7 +52,7 @@ void _ccplex_enable_power_t210b01()
|
|||
void ccplex_boot_cpu0(u32 entry)
|
||||
{
|
||||
// Set ACTIVE_CLUSER to FAST.
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
|
||||
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
_ccplex_enable_power_t210();
|
||||
|
@ -62,12 +63,12 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
|
||||
// Configure MSELECT source and enable clock to 102MHz.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Configure initial CPU clock frequency and enable clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
|
||||
|
||||
clock_enable_coresight();
|
||||
|
||||
|
@ -81,9 +82,9 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
// Enable CPU0 rail.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
||||
|
||||
// Request and wait for RAM repair.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
|
||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||
while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & RAM_REPAIR_STS))
|
||||
;
|
||||
|
||||
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
|
||||
|
@ -100,7 +101,7 @@ void ccplex_boot_cpu0(u32 entry)
|
|||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
// Clear NONCPU reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
|
||||
// Clear CPU0 reset.
|
||||
|
|
286
bdk/soc/clock.c
286
bdk/soc/clock.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,9 +17,10 @@
|
|||
|
||||
#include <soc/clock.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
typedef struct _clock_osc_t
|
||||
{
|
||||
|
@ -38,9 +39,9 @@ static const clock_osc_t _clock_osc_cnt[] = {
|
|||
{ 48000, 2836, 3023 }
|
||||
};
|
||||
|
||||
/* clock_t: reset, enable, source, index, clk_src, clk_div */
|
||||
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clock_t _clock_uart[] = {
|
||||
static const clk_rst_t _clock_uart[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||
|
@ -49,7 +50,7 @@ static const clock_t _clock_uart[] = {
|
|||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
static const clock_t _clock_i2c[] = {
|
||||
static const clk_rst_t _clock_i2c[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
|
@ -58,61 +59,68 @@ static const clock_t _clock_i2c[] = {
|
|||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz.
|
||||
static clk_rst_t _clock_se = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz. Default: 408MHz. Max: 627.2 MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
static clk_rst_t _clock_tzram = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz.
|
||||
static clk_rst_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz.
|
||||
static clk_rst_t _clock_tsec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
static clk_rst_t _clock_nvdec = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, 0 // 408 MHz. Max: 716.8/979.2MHz.
|
||||
};
|
||||
static clock_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0
|
||||
static clk_rst_t _clock_nvjpg = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 // 204MHz.
|
||||
static clk_rst_t _clock_vic = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
static clk_rst_t _clock_sor_safe = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
static clk_rst_t _clock_sor0 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0
|
||||
};
|
||||
static clock_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz.
|
||||
static clk_rst_t _clock_sor1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 // 204MHz.
|
||||
};
|
||||
|
||||
static clock_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
static clk_rst_t _clock_kfuse = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_sdmmc_legacy_tm = {
|
||||
static clk_rst_t _clock_cl_dvfs = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_coresight = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz.
|
||||
};
|
||||
static clk_rst_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
};
|
||||
static clk_rst_t _clock_sdmmc_legacy_tm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66
|
||||
};
|
||||
|
||||
static clock_t _clock_apbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0
|
||||
static clk_rst_t _clock_apbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 // Max: 204MHz.
|
||||
};
|
||||
static clk_rst_t _clock_ahbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_actmon = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, 0 // 19.2MHz.
|
||||
};
|
||||
static clk_rst_t _clock_extperiph1 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, 0
|
||||
};
|
||||
static clk_rst_t _clock_extperiph2 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, 202 // 4.0MHz
|
||||
};
|
||||
|
||||
static clock_t _clock_ahbdma = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0
|
||||
};
|
||||
|
||||
static clock_t _clock_actmon = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, 0 // 19.2MHz.
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
void clock_enable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
|
@ -129,7 +137,7 @@ void clock_enable(const clock_t *clk)
|
|||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||
}
|
||||
|
||||
void clock_disable(const clock_t *clk)
|
||||
void clock_disable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
|
@ -159,7 +167,9 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
|
|||
{
|
||||
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||
|
||||
if (baud == 1000000)
|
||||
if (baud == 3000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15;
|
||||
else if (baud == 1000000)
|
||||
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
|
||||
else
|
||||
{
|
||||
|
@ -215,6 +225,36 @@ void clock_disable_tsec()
|
|||
clock_disable(&_clock_tsec);
|
||||
}
|
||||
|
||||
void clock_enable_nvdec()
|
||||
{
|
||||
clock_enable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_disable_nvdec()
|
||||
{
|
||||
clock_disable(&_clock_nvdec);
|
||||
}
|
||||
|
||||
void clock_enable_nvjpg()
|
||||
{
|
||||
clock_enable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_disable_nvjpg()
|
||||
{
|
||||
clock_disable(&_clock_nvjpg);
|
||||
}
|
||||
|
||||
void clock_enable_vic()
|
||||
{
|
||||
clock_enable(&_clock_vic);
|
||||
}
|
||||
|
||||
void clock_disable_vic()
|
||||
{
|
||||
clock_disable(&_clock_vic);
|
||||
}
|
||||
|
||||
void clock_enable_sor_safe()
|
||||
{
|
||||
clock_enable(&_clock_sor_safe);
|
||||
|
@ -321,6 +361,56 @@ void clock_disable_actmon()
|
|||
clock_disable(&_clock_actmon);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph1()
|
||||
{
|
||||
clock_enable(&_clock_extperiph1);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph1()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph1);
|
||||
}
|
||||
|
||||
void clock_enable_extperiph2()
|
||||
{
|
||||
clock_enable(&_clock_extperiph2);
|
||||
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
void clock_disable_extperiph2()
|
||||
{
|
||||
PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN);
|
||||
clock_disable(&_clock_extperiph2);
|
||||
}
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
||||
{
|
||||
u32 plld_div = (divp << 20) | (divn << 11) | 1;
|
||||
|
||||
// N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
|
||||
u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
|
||||
if (lowpower && tegra_t210)
|
||||
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
|
||||
|
||||
|
||||
// Set DISP1 clock source and parent clock.
|
||||
if (lowpower)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0.
|
||||
|
||||
// Set dividers and enable PLLD.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||
|
||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||
}
|
||||
|
||||
void clock_enable_pllx()
|
||||
{
|
||||
// Configure and enable PLLX if disabled.
|
||||
|
@ -357,7 +447,7 @@ void clock_enable_pllc(u32 divn)
|
|||
|
||||
// Take PLLC out of reset and set basic misc parameters.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
|
||||
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
|
@ -384,11 +474,11 @@ void clock_enable_pllc(u32 divn)
|
|||
void clock_disable_pllc()
|
||||
{
|
||||
// Disable PLLC and PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~(PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_REF_DIS;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) |= PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
|
@ -413,7 +503,7 @@ static void _clock_enable_pllc4(u32 mask)
|
|||
usleep(10);
|
||||
|
||||
// Set PLLC4 dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||
|
||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
||||
|
@ -451,9 +541,9 @@ void clock_enable_pllu()
|
|||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
|
||||
u32 timeout = get_tmr_us() + 1300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
||||
if ((u32)TMR(TIMERUS_CNTR_1US) > timeout)
|
||||
if (get_tmr_us() > timeout)
|
||||
break;
|
||||
usleep(10);
|
||||
|
||||
|
@ -463,9 +553,9 @@ void clock_enable_pllu()
|
|||
|
||||
void clock_disable_pllu()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~BIT(30); // Disable PLLU.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~BIT(29); // Enable reference clock.
|
||||
}
|
||||
|
||||
void clock_enable_utmipll()
|
||||
|
@ -594,7 +684,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
clock_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
|
@ -609,6 +699,7 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
|||
|
||||
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
|
@ -626,79 +717,88 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
|||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
break;
|
||||
|
||||
case 26000:
|
||||
*pclock = 25500;
|
||||
divisor = 30; // 16 div.
|
||||
break;
|
||||
case 40800:
|
||||
*pclock = 40800;
|
||||
divisor = 18; // 10 div.
|
||||
break;
|
||||
|
||||
case 50000:
|
||||
*pclock = 48000;
|
||||
divisor = 15; // 8.5 div.
|
||||
break;
|
||||
|
||||
case 52000:
|
||||
*pclock = 51000;
|
||||
divisor = 14; // 8 div.
|
||||
break;
|
||||
|
||||
case 82000:
|
||||
*pclock = 81600;
|
||||
divisor = 8; // 5 div.
|
||||
break;
|
||||
|
||||
case 100000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
*pclock = 99840;
|
||||
divisor = 2; // 2 div.
|
||||
break;
|
||||
|
||||
case 164000:
|
||||
*pclock = 163200;
|
||||
divisor = 3; // 2.5 div.
|
||||
break;
|
||||
case 200000: // 240MHz evo+.
|
||||
|
||||
case 200000:
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
|
||||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
divisor = 0; // 1 div.
|
||||
break;
|
||||
default:
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case 400000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
|
||||
*pclock = 399360;
|
||||
divisor = 3; // 2.5 div
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[id].clock = val;
|
||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
||||
|
||||
// Enable PLLC4 if in use by any SDMMC.
|
||||
if (source)
|
||||
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||
_clock_enable_pllc4(BIT(id));
|
||||
|
||||
// Set SDMMC legacy timeout clock.
|
||||
_clock_sdmmc_config_legacy_tm();
|
||||
|
||||
// Set SDMMC clock.
|
||||
u32 src_div = (source << 29) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -728,54 +828,71 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
|||
// Get Card clock divisor.
|
||||
switch (type)
|
||||
{
|
||||
case SDHCI_TIMING_MMC_ID: // Actual IO Freq: 380.59 KHz.
|
||||
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||
*pclock = 26000;
|
||||
*pdivisor = 66;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_LS26:
|
||||
*pclock = 26000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS52:
|
||||
*pclock = 52000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
*pclock = 200000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_SD_ID: // Actual IO Freq: 380.43 KHz.
|
||||
|
||||
case SDHCI_TIMING_SD_ID: // Actual card clock: 386.38 KHz.
|
||||
*pclock = 25000;
|
||||
*pdivisor = 64;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_DS12:
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
*pclock = 25000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_HS25:
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
*pclock = 50000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
*pclock = 100000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
*pclock = 164000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
*pclock = 40800;
|
||||
*pdivisor = 1;
|
||||
|
||||
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||
*pclock = 82000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
|
||||
|
||||
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SDHCI_TIMING_UHS_DDR200: // Actual card clock: 199.68 KHz.
|
||||
*pclock = 400000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,7 +911,8 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
|||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + clock - 1) / clock);
|
||||
// Wait 100 cycles for reset and for clocks to stabilize.
|
||||
usleep((100 * 1000 + clock - 1) / clock);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
|
|
306
bdk/soc/clock.h
306
bdk/soc/clock.h
|
@ -117,8 +117,10 @@
|
|||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_AHUB 0x3D0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
|
@ -154,8 +156,12 @@
|
|||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC
|
||||
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE 0x710
|
||||
|
@ -221,138 +227,232 @@
|
|||
/*! PTO IDs. */
|
||||
typedef enum _clock_pto_id_t
|
||||
{
|
||||
CLK_PTO_PCLK_SYS = 0x06,
|
||||
CLK_PTO_HCLK_SYS = 0x07,
|
||||
CLK_PTO_PCLK_SYS = 0x06,
|
||||
CLK_PTO_HCLK_SYS = 0x07,
|
||||
CLK_PTO_DMIC1 = 0x08,
|
||||
CLK_PTO_DMIC2 = 0x09,
|
||||
CLK_PTO_HDMI_SLOWCLK_DIV2 = 0x0A,
|
||||
CLK_PTO_JTAG_REG = 0x0B,
|
||||
CLK_PTO_UTMIP_240_A = 0x0C,
|
||||
CLK_PTO_UTMIP_240_B = 0x0D,
|
||||
|
||||
CLK_PTO_UTMIP_240 = 0x0C,
|
||||
CLK_PTO_CCLK_G = 0x12,
|
||||
CLK_PTO_CCLK_G_DIV2 = 0x13,
|
||||
CLK_PTO_MIPIBIF = 0x14,
|
||||
|
||||
CLK_PTO_CCLK_G = 0x12,
|
||||
CLK_PTO_CCLK_G_DIV2 = 0x13,
|
||||
CLK_PTO_SPI1 = 0x17,
|
||||
CLK_PTO_SPI2 = 0x18,
|
||||
CLK_PTO_SPI3 = 0x19,
|
||||
CLK_PTO_SPI4 = 0x1A,
|
||||
CLK_PTO_MAUD = 0x1B,
|
||||
CLK_PTO_SCLK = 0x1C,
|
||||
|
||||
CLK_PTO_SPI1 = 0x17,
|
||||
CLK_PTO_SPI2 = 0x18,
|
||||
CLK_PTO_SPI3 = 0x19,
|
||||
CLK_PTO_SPI4 = 0x1A,
|
||||
CLK_PTO_MAUD = 0x1B,
|
||||
CLK_PTO_SCLK = 0x1C,
|
||||
CLK_PTO_SDMMC1 = 0x20,
|
||||
CLK_PTO_SDMMC2 = 0x21,
|
||||
CLK_PTO_SDMMC3 = 0x22,
|
||||
CLK_PTO_SDMMC4 = 0x23,
|
||||
CLK_PTO_EMC = 0x24,
|
||||
|
||||
CLK_PTO_SDMMC1 = 0x20,
|
||||
CLK_PTO_SDMMC2 = 0x21,
|
||||
CLK_PTO_SDMMC3 = 0x22,
|
||||
CLK_PTO_SDMMC4 = 0x23,
|
||||
CLK_PTO_EMC = 0x24,
|
||||
CLK_PTO_DMIC3 = 0x2A,
|
||||
CLK_PTO_CCLK_LP = 0x2B,
|
||||
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
|
||||
|
||||
CLK_PTO_CCLK_LP = 0x2B,
|
||||
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
|
||||
CLK_PTO_MSELECT = 0x2F,
|
||||
|
||||
CLK_PTO_MSELECT = 0x2F,
|
||||
CLK_PTO_VI_SENSOR2 = 0x33,
|
||||
CLK_PTO_VI_SENSOR = 0x34,
|
||||
CLK_PTO_VIC = 0x35,
|
||||
CLK_PTO_VIC_SKIP = 0x36,
|
||||
CLK_PTO_ISP_SKIP = 0x37,
|
||||
CLK_PTO_ISPB_SE2_SKIP = 0x38,
|
||||
CLK_PTO_NVDEC_SKIP = 0x39,
|
||||
CLK_PTO_NVENC_SKIP = 0x3A,
|
||||
CLK_PTO_NVJPG_SKIP = 0x3B,
|
||||
CLK_PTO_TSEC_SKIP = 0x3C,
|
||||
CLK_PTO_TSECB_SKIP = 0x3D,
|
||||
CLK_PTO_SE_SKIP = 0x3E,
|
||||
CLK_PTO_VI_SKIP = 0x3F,
|
||||
|
||||
CLK_PTO_VIC = 0x36,
|
||||
CLK_PTO_PLLX_OBS = 0x40,
|
||||
CLK_PTO_PLLC_OBS = 0x41,
|
||||
CLK_PTO_PLLM_OBS = 0x42,
|
||||
CLK_PTO_PLLP_OBS = 0x43,
|
||||
CLK_PTO_PLLA_OBS = 0x44,
|
||||
CLK_PTO_PLLMB_OBS = 0x45,
|
||||
CLK_PTO_SATA_OOB = 0x46,
|
||||
|
||||
CLK_PTO_NVDEC = 0x39,
|
||||
CLK_PTO_FCPU_DVFS_DIV12_CPU = 0x48,
|
||||
|
||||
CLK_PTO_NVENC = 0x3A,
|
||||
CLK_PTO_NVJPG = 0x3B,
|
||||
CLK_PTO_TSEC = 0x3C,
|
||||
CLK_PTO_TSECB = 0x3D,
|
||||
CLK_PTO_SE = 0x3E,
|
||||
CLK_PTO_EQOS_AXI = 0x4C,
|
||||
CLK_PTO_EQOS_PTP_REF = 0x4D,
|
||||
CLK_PTO_EQOS_TX = 0x4E,
|
||||
CLK_PTO_EQOS_RX = 0x4F,
|
||||
|
||||
CLK_PTO_DSIA_LP = 0x62,
|
||||
CLK_PTO_CILAB = 0x52,
|
||||
CLK_PTO_CILCD = 0x53,
|
||||
|
||||
CLK_PTO_ISP = 0x64,
|
||||
CLK_PTO_MC = 0x6A,
|
||||
CLK_PTO_CILEF = 0x55,
|
||||
CLK_PTO_PLLA1_PTO_OBS = 0x56,
|
||||
CLK_PTO_PLLC4_PTO_OBS = 0x57,
|
||||
|
||||
CLK_PTO_ACTMON = 0x6B,
|
||||
CLK_PTO_CSITE = 0x6C,
|
||||
CLK_PTO_PLLC2_PTO_OBS = 0x59,
|
||||
CLK_PTO_PLLC3_PTO_OBS = 0x5B,
|
||||
|
||||
CLK_PTO_HOST1X = 0x6F,
|
||||
CLK_PTO_DSIA_LP = 0x62,
|
||||
CLK_PTO_DSIB_LP = 0x63,
|
||||
CLK_PTO_ISP = 0x64,
|
||||
CLK_PTO_PEX_PAD = 0x65,
|
||||
|
||||
CLK_PTO_SE_2 = 0x74, // Same as CLK_PTO_SE.
|
||||
CLK_PTO_SOC_THERM = 0x75,
|
||||
CLK_PTO_MC = 0x6A,
|
||||
|
||||
CLK_PTO_TSEC_2 = 0x77, // Same as CLK_PTO_TSEC.
|
||||
CLK_PTO_ACTMON = 0x6B,
|
||||
CLK_PTO_CSITE = 0x6C,
|
||||
CLK_PTO_VI_I2C = 0x6D,
|
||||
|
||||
CLK_PTO_ACLK = 0x7C,
|
||||
CLK_PTO_QSPI = 0x7D,
|
||||
CLK_PTO_HOST1X = 0x6F,
|
||||
|
||||
CLK_PTO_I2S1 = 0x80,
|
||||
CLK_PTO_I2S2 = 0x81,
|
||||
CLK_PTO_I2S3 = 0x82,
|
||||
CLK_PTO_I2S4 = 0x83,
|
||||
CLK_PTO_I2S5 = 0x84,
|
||||
CLK_PTO_AHUB = 0x85,
|
||||
CLK_PTO_APE = 0x86,
|
||||
CLK_PTO_QSPI_2X = 0x71,
|
||||
CLK_PTO_NVDEC = 0x72,
|
||||
CLK_PTO_NVJPG = 0x73,
|
||||
CLK_PTO_SE = 0x74,
|
||||
CLK_PTO_SOC_THERM = 0x75,
|
||||
|
||||
CLK_PTO_DVFS_SOC = 0x88,
|
||||
CLK_PTO_DVFS_REF = 0x89,
|
||||
CLK_PTO_TSEC = 0x77,
|
||||
CLK_PTO_TSECB = 0x78,
|
||||
CLK_PTO_VI = 0x79,
|
||||
CLK_PTO_LA = 0x7A,
|
||||
CLK_PTO_SCLK_SKIP = 0x7B,
|
||||
|
||||
CLK_PTO_SPDIF = 0x8F,
|
||||
CLK_PTO_SPDIF_IN = 0x90,
|
||||
CLK_PTO_ADSP_SKIP = 0x7C,
|
||||
CLK_PTO_QSPI = 0x7D,
|
||||
|
||||
CLK_PTO_SDMMC2_SHAPER = 0x7E,
|
||||
CLK_PTO_SDMMC4_SHAPER = 0x7F,
|
||||
CLK_PTO_I2S1 = 0x80,
|
||||
CLK_PTO_I2S2 = 0x81,
|
||||
CLK_PTO_I2S3 = 0x82,
|
||||
CLK_PTO_I2S4 = 0x83,
|
||||
CLK_PTO_I2S5 = 0x84,
|
||||
CLK_PTO_AHUB = 0x85,
|
||||
CLK_PTO_APE = 0x86,
|
||||
|
||||
CLK_PTO_DVFS_SOC = 0x88,
|
||||
CLK_PTO_DVFS_REF = 0x89,
|
||||
CLK_PTO_ADSP_CLK = 0x8A,
|
||||
CLK_PTO_ADSP_DIV2_CLK = 0x8B,
|
||||
|
||||
CLK_PTO_SPDIF_OUT = 0x8F,
|
||||
CLK_PTO_SPDIF_IN = 0x90,
|
||||
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
|
||||
CLK_PTO_SYS2HSIO_SATA_CLK = 0x92,
|
||||
CLK_PTO_PWM = 0x93,
|
||||
CLK_PTO_I2C1 = 0x94,
|
||||
CLK_PTO_I2C2 = 0x95,
|
||||
CLK_PTO_I2C3 = 0x96,
|
||||
CLK_PTO_I2C4 = 0x97,
|
||||
CLK_PTO_I2C5 = 0x98,
|
||||
CLK_PTO_I2C6 = 0x99,
|
||||
CLK_PTO_I2C_SLOW = 0x9A,
|
||||
CLK_PTO_UARTAPE = 0x9B,
|
||||
|
||||
CLK_PTO_PWM = 0x93,
|
||||
CLK_PTO_I2C1 = 0x94,
|
||||
CLK_PTO_I2C2 = 0x95,
|
||||
CLK_PTO_I2C3 = 0x96,
|
||||
CLK_PTO_I2C4 = 0x97,
|
||||
CLK_PTO_I2C5 = 0x98,
|
||||
CLK_PTO_I2C6 = 0x99,
|
||||
CLK_PTO_I2C_SLOW = 0x9A,
|
||||
CLK_PTO_UARTAPE = 0x9B,
|
||||
CLK_PTO_EXTPERIPH1 = 0x9D,
|
||||
CLK_PTO_EXTPERIPH2 = 0x9E,
|
||||
CLK_PTO_EXTPERIPH3 = 0x9F,
|
||||
CLK_PTO_ENTROPY = 0xA0,
|
||||
CLK_PTO_UARTA = 0xA1,
|
||||
CLK_PTO_UARTB = 0xA2,
|
||||
CLK_PTO_UARTC = 0xA3,
|
||||
CLK_PTO_UARTD = 0xA4,
|
||||
CLK_PTO_OWR = 0xA5,
|
||||
CLK_PTO_TSENSOR = 0xA6,
|
||||
CLK_PTO_HDA2CODEC_2X = 0xA7,
|
||||
CLK_PTO_HDA = 0xA8,
|
||||
CLK_PTO_EMC_LATENCY = 0xA9,
|
||||
CLK_PTO_EMC_DLL = 0xAA,
|
||||
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
|
||||
CLK_PTO_DBGAPB = 0xAC,
|
||||
|
||||
CLK_PTO_EXTPERIPH1 = 0x9D,
|
||||
CLK_PTO_EXTPERIPH2 = 0x9E,
|
||||
CLK_PTO_SOR0 = 0xC0,
|
||||
CLK_PTO_SOR1 = 0xC1,
|
||||
CLK_PTO_HDMI = 0xC2,
|
||||
|
||||
CLK_PTO_ENTROPY = 0xA0,
|
||||
CLK_PTO_UARTA = 0xA1,
|
||||
CLK_PTO_UARTB = 0xA2,
|
||||
CLK_PTO_UARTC = 0xA3,
|
||||
CLK_PTO_UARTD = 0xA4,
|
||||
CLK_PTO_OWR = 0xA5,
|
||||
CLK_PTO_DISP2 = 0xC4,
|
||||
CLK_PTO_DISP1 = 0xC5,
|
||||
|
||||
CLK_PTO_HDA2CODEC_2X = 0xA7,
|
||||
CLK_PTO_HDA = 0xA8,
|
||||
CLK_PTO_PLLD_OBS = 0xCA,
|
||||
CLK_PTO_PLLD2_PTO_OBS = 0xCC,
|
||||
CLK_PTO_PLLDP_OBS = 0xCE,
|
||||
CLK_PTO_PLLE_OBS = 0x10A,
|
||||
CLK_PTO_PLLU_OBS = 0x10C,
|
||||
CLK_PTO_PLLREFE_OBS = 0x10E,
|
||||
|
||||
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
|
||||
CLK_PTO_XUSB_FALCON = 0x110,
|
||||
CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
|
||||
CLK_PTO_USB_L0_RX = 0x112,
|
||||
CLK_PTO_USB_L3_RX = 0x113,
|
||||
CLK_PTO_USB_RX = 0x114,
|
||||
CLK_PTO_USB3_L0_TXCLKREF = 0x115,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
|
||||
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
|
||||
CLK_PTO_PEX_L4_RX = 0x11A,
|
||||
CLK_PTO_PEX_TXCLKREF = 0x11B,
|
||||
CLK_PTO_PEX_TXCLKREF_DIV2 = 0x11C,
|
||||
CLK_PTO_PEX_TXCLKREF2 = 0x11D,
|
||||
CLK_PTO_PEX_L0_RX = 0x11E,
|
||||
CLK_PTO_PEX_L1_RX = 0x11F,
|
||||
CLK_PTO_PEX_L2_RX = 0x120,
|
||||
CLK_PTO_PEX_L3_RX = 0x121,
|
||||
CLK_PTO_SATA_TXCLKREF = 0x122,
|
||||
CLK_PTO_SATA_TXCLKREF_DIV2 = 0x123,
|
||||
CLK_PTO_USB_L5_RX = 0x124,
|
||||
CLK_PTO_SATA_TX = 0x125,
|
||||
CLK_PTO_SATA_L0_RX = 0x126,
|
||||
|
||||
CLK_PTO_SOR0 = 0xC0,
|
||||
CLK_PTO_SOR1 = 0xC1,
|
||||
CLK_PTO_USB3_L1_TXCLKREF = 0x129,
|
||||
CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
|
||||
CLK_PTO_USB3_L7_RX = 0x12B,
|
||||
CLK_PTO_USB3_TX = 0x12C,
|
||||
CLK_PTO_UTMIP_PLL_PAD = 0x12D,
|
||||
|
||||
CLK_PTO_DISP2 = 0xC4,
|
||||
CLK_PTO_DISP1 = 0xC5,
|
||||
CLK_PTO_XUSB_FS = 0x136,
|
||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
||||
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
||||
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
||||
|
||||
CLK_PTO_XUSB_FALCON = 0x110,
|
||||
|
||||
CLK_PTO_XUSB_FS = 0x136,
|
||||
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
|
||||
CLK_PTO_XUSB_CORE_HOST = 0x138,
|
||||
CLK_PTO_XUSB_CORE_DEV = 0x139,
|
||||
CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
|
||||
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
|
||||
CLK_PTO_USB_L4_RX = 0x13E,
|
||||
CLK_PTO_USB_L6_RX = 0x13F,
|
||||
|
||||
/*
|
||||
* PLL need PTO enabled in MISC registers.
|
||||
* Normal div is 2 so result is multiplied with it.
|
||||
*/
|
||||
CLK_PTO_PLLC_DIV2 = 0x01,
|
||||
CLK_PTO_PLLM_DIV2 = 0x02,
|
||||
CLK_PTO_PLLP_DIV2 = 0x03,
|
||||
CLK_PTO_PLLA_DIV2 = 0x04,
|
||||
CLK_PTO_PLLX_DIV2 = 0x05,
|
||||
CLK_PTO_PLLC_DIV2 = 0x01,
|
||||
CLK_PTO_PLLM_DIV2 = 0x02,
|
||||
CLK_PTO_PLLP_DIV2 = 0x03,
|
||||
CLK_PTO_PLLA_DIV2 = 0x04,
|
||||
CLK_PTO_PLLX_DIV2 = 0x05,
|
||||
|
||||
CLK_PTO_PLLMB_DIV2 = 0x25,
|
||||
CLK_PTO_PLLMB_DIV2 = 0x25,
|
||||
|
||||
CLK_PTO_PLLC4_DIV2 = 0x51,
|
||||
CLK_PTO_PLLC4_DIV2 = 0x51,
|
||||
|
||||
CLK_PTO_PLLA1_DIV2 = 0x55,
|
||||
CLK_PTO_PLLC2_DIV2 = 0x58,
|
||||
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
||||
CLK_PTO_PLLA1_DIV2 = 0x55,
|
||||
CLK_PTO_PLLC2_DIV2 = 0x58,
|
||||
CLK_PTO_PLLC3_DIV2 = 0x5A,
|
||||
|
||||
CLK_PTO_PLLD_DIV2 = 0xCB,
|
||||
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
||||
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
||||
CLK_PTO_PLLD_DIV2 = 0xCB,
|
||||
CLK_PTO_PLLD2_DIV2 = 0xCD,
|
||||
CLK_PTO_PLLDP_DIV2 = 0xCF,
|
||||
|
||||
CLK_PTO_PLLU_DIV2 = 0x10D,
|
||||
CLK_PTO_PLLE_DIV2 = 0x10B,
|
||||
|
||||
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
||||
CLK_PTO_PLLU_DIV2 = 0x10D,
|
||||
|
||||
CLK_PTO_PLLREFE_DIV2 = 0x10F,
|
||||
} clock_pto_id_t;
|
||||
|
||||
/*
|
||||
|
@ -619,7 +719,7 @@ enum CLK_Y_DEV
|
|||
};
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _clock_t
|
||||
typedef struct _clk_rst_t
|
||||
{
|
||||
u16 reset;
|
||||
u16 enable;
|
||||
|
@ -627,11 +727,11 @@ typedef struct _clock_t
|
|||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
} clock_t;
|
||||
} clk_rst_t;
|
||||
|
||||
/*! Generic clock enable/disable. */
|
||||
void clock_enable(const clock_t *clk);
|
||||
void clock_disable(const clock_t *clk);
|
||||
void clock_enable(const clk_rst_t *clk);
|
||||
void clock_disable(const clk_rst_t *clk);
|
||||
|
||||
/*! Clock control for specific hardware portions. */
|
||||
void clock_enable_fuse(bool enable);
|
||||
|
@ -646,6 +746,12 @@ void clock_enable_host1x();
|
|||
void clock_disable_host1x();
|
||||
void clock_enable_tsec();
|
||||
void clock_disable_tsec();
|
||||
void clock_enable_nvdec();
|
||||
void clock_disable_nvdec();
|
||||
void clock_enable_nvjpg();
|
||||
void clock_disable_nvjpg();
|
||||
void clock_enable_vic();
|
||||
void clock_disable_vic();
|
||||
void clock_enable_sor_safe();
|
||||
void clock_disable_sor_safe();
|
||||
void clock_enable_sor0();
|
||||
|
@ -666,13 +772,19 @@ void clock_enable_ahbdma();
|
|||
void clock_disable_ahbdma();
|
||||
void clock_enable_actmon();
|
||||
void clock_disable_actmon();
|
||||
void clock_enable_extperiph1();
|
||||
void clock_disable_extperiph1();
|
||||
void clock_enable_extperiph2();
|
||||
void clock_disable_extperiph2();
|
||||
|
||||
void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210);
|
||||
void clock_enable_pllx();
|
||||
void clock_enable_pllc(u32 divn);
|
||||
void clock_disable_pllc();
|
||||
void clock_enable_pllu();
|
||||
void clock_disable_pllu();
|
||||
void clock_enable_utmipll();
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
|
|
115
bdk/soc/fuse.c
115
bdk/soc/fuse.c
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-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,
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/fuse.h>
|
||||
|
@ -42,12 +43,19 @@ static const u32 evp_thunk_template[] = {
|
|||
0xe3822001, // ORR R2, R2, #1
|
||||
0xe8bd0003, // LDMFD SP!, {R0,R1}
|
||||
0xe12fff12, // BX R2
|
||||
// idx: 15:
|
||||
0x001007b0, // off_1007EC DCD evp_thunk_template
|
||||
0x001007f8, // off_1007F0 DCD thunk_end
|
||||
0x40004c30, // off_1007F4 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
|
||||
|
||||
static const u32 evp_thunk_func_offsets_t210b01[] = {
|
||||
0x0010022c, // off_100268 DCD evp_thunk_template
|
||||
0x00100174, // off_10026C DCD thunk_end
|
||||
0x40004164, // off_100270 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
|
||||
// treated as 12bit values
|
||||
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
|
||||
|
@ -80,19 +88,26 @@ u32 fuse_read_odm_keygen_rev()
|
|||
|
||||
u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
u32 dramid = (fuse_read_odm(4) & 0xF8) >> 3;
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
u32 odm4 = fuse_read_odm(4);
|
||||
|
||||
u32 dramid = (odm4 & 0xF8) >> 3;
|
||||
|
||||
// Get extended dram id info.
|
||||
if (!tegra_t210)
|
||||
dramid |= (odm4 & 0x7000) >> 7;
|
||||
|
||||
if (raw_id)
|
||||
return dramid;
|
||||
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
if (tegra_t210)
|
||||
{
|
||||
if (dramid > 6)
|
||||
if (dramid > 7)
|
||||
dramid = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dramid > 28)
|
||||
if (dramid > 34)
|
||||
dramid = 8;
|
||||
}
|
||||
|
||||
|
@ -170,7 +185,8 @@ u32 fuse_read(u32 addr)
|
|||
|
||||
void fuse_read_array(u32 *words)
|
||||
{
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192;
|
||||
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
|
||||
FUSE_ARRAY_WORDS_NUM_T210B01 : FUSE_ARRAY_WORDS_NUM;
|
||||
|
||||
for (u32 i = 0; i < array_size; i++)
|
||||
words[i] = fuse_read(i);
|
||||
|
@ -180,9 +196,8 @@ static u32 _parity32_even(u32 *words, u32 count)
|
|||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
{
|
||||
acc ^= words[i];
|
||||
}
|
||||
|
||||
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
|
||||
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
|
||||
u32 x = hi ^ lo;
|
||||
|
@ -198,26 +213,26 @@ static int _patch_hash_one(u32 *word)
|
|||
u32 bits20_31 = *word & 0xfff00000;
|
||||
u32 parity_bit = _parity32_even(&bits20_31, 1);
|
||||
u32 hash = 0;
|
||||
|
||||
for (u32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (*word & (1 << (20 + i)))
|
||||
{
|
||||
hash ^= hash_vals[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*word ^= 1 << 24;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++)
|
||||
{
|
||||
if (hash_vals[i] == hash)
|
||||
|
@ -226,6 +241,7 @@ static int _patch_hash_one(u32 *word)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -246,9 +262,7 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
for (u32 bitpos = 0; bitpos < 32; bitpos++)
|
||||
{
|
||||
if ((w >> bitpos) & 1)
|
||||
{
|
||||
hash ^= 0x4000 + i * 32 + bitpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -260,16 +274,14 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
words[0] ^= 0x8000;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
u32 bitcount = hash - 0x4000;
|
||||
if (bitcount < 16 || bitcount >= count * 32)
|
||||
{
|
||||
|
@ -277,14 +289,11 @@ static int _patch_hash_multi(u32 *words, u32 count)
|
|||
for (u32 bitpos = 0; bitpos < 15; bitpos++)
|
||||
{
|
||||
if ((hash >> bitpos) & 1)
|
||||
{
|
||||
num_set++;
|
||||
}
|
||||
}
|
||||
if (num_set != 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
words[0] ^= hash;
|
||||
return 1;
|
||||
}
|
||||
|
@ -302,24 +311,30 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
if (ipatch_count)
|
||||
{
|
||||
|
@ -332,13 +347,14 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
|||
ipatch(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
|
@ -354,29 +370,44 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
bool t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
|
||||
u32 *evp_thunk_tmp = (u32 *)malloc(sizeof(evp_thunk_template));
|
||||
|
||||
memcpy(evp_thunk_tmp, evp_thunk_template, sizeof(evp_thunk_template));
|
||||
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
|
||||
|
||||
if (t210b01)
|
||||
memcpy(&evp_thunk_tmp[15], evp_thunk_func_offsets_t210b01, sizeof(evp_thunk_func_offsets_t210b01));
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAY_SIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
{
|
||||
words[i] = fuse_read(word_addr--);
|
||||
// Parse extra T210B01 fuses when the difference is reached.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
|
||||
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
|
||||
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
|
||||
{
|
||||
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
u32 insn_count = word_count - ipatch_count - 1;
|
||||
if (insn_count)
|
||||
|
@ -385,10 +416,10 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
{
|
||||
evp_thunk_dst_addr = (void *)iram_evp_thunks;
|
||||
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
|
||||
evp_thunk_dst_addr += evp_thunk_template_len;
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_tmp, sizeof(evp_thunk_template));
|
||||
evp_thunk_dst_addr += sizeof(evp_thunk_template);
|
||||
evp_thunk_written = 1;
|
||||
*iram_evp_thunks_len = evp_thunk_template_len;
|
||||
*iram_evp_thunks_len = sizeof(evp_thunk_template);
|
||||
|
||||
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
|
||||
}
|
||||
|
@ -398,16 +429,22 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
|||
evp_thunk_dst_addr += thunk_patch_len;
|
||||
*iram_evp_thunks_len += thunk_patch_len;
|
||||
}
|
||||
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
free(evp_thunk_tmp);
|
||||
return 3;
|
||||
}
|
||||
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
free(evp_thunk_tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -419,7 +456,7 @@ bool fuse_check_patched_rcm()
|
|||
|
||||
// Check if RCM is ipatched.
|
||||
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||
u32 word_addr = 191;
|
||||
u32 word_addr = FUSE_ARRAY_WORDS_NUM - 1;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -82,12 +82,15 @@
|
|||
/*! Fuse cache registers. */
|
||||
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
|
||||
|
||||
#define FUSE_ARRAY_WORDS_NUM 192
|
||||
#define FUSE_ARRAY_WORDS_NUM_T210B01 256
|
||||
|
||||
enum
|
||||
{
|
||||
FUSE_NX_HW_TYPE_ICOSA,
|
||||
FUSE_NX_HW_TYPE_IOWA,
|
||||
FUSE_NX_HW_TYPE_HOAG,
|
||||
FUSE_NX_HW_TYPE_AULA
|
||||
FUSE_NX_HW_TYPE_AULA
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,23 +18,27 @@
|
|||
#include <soc/gpio.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||
#define GPIO_BANK_IDX(port) ((port) >> 2)
|
||||
#define GPIO_PORT_OFFSET(port) ((GPIO_BANK_IDX(port) << 8) + (((port) % 4) << 2))
|
||||
|
||||
#define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_CNF_OFFSET(port) (0x00 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OE_OFFSET(port) (0x10 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OUT_OFFSET(port) (0x20 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_IN_OFFSET(port) (0x30 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_STA_OFFSET(port) (0x40 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_ENB_OFFSET(port) (0x50 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_LVL_OFFSET(port) (0x60 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_CLR_OFFSET(port) (0x70 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
|
||||
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_DB_CTRL_OFFSET(port) (0xB0 + GPIO_PORT_OFFSET(port))
|
||||
#define GPIO_DB_CNT_OFFSET(port) (0xF0 + GPIO_PORT_OFFSET(port))
|
||||
|
||||
#define GPIO_IRQ_BANK1 32
|
||||
#define GPIO_IRQ_BANK2 33
|
||||
|
@ -52,7 +56,7 @@ static u8 gpio_bank_irq_ids[8] = {
|
|||
|
||||
void gpio_config(u32 port, u32 pins, int mode)
|
||||
{
|
||||
u32 offset = GPIO_CNF_OFFSET(port);
|
||||
const u32 offset = GPIO_CNF_OFFSET(port);
|
||||
|
||||
if (mode)
|
||||
GPIO(offset) |= pins;
|
||||
|
@ -64,7 +68,7 @@ void gpio_config(u32 port, u32 pins, int mode)
|
|||
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_OE_OFFSET(port);
|
||||
const u32 port_offset = GPIO_OE_OFFSET(port);
|
||||
|
||||
if (enable)
|
||||
GPIO(port_offset) |= pins;
|
||||
|
@ -76,7 +80,7 @@ void gpio_output_enable(u32 port, u32 pins, int enable)
|
|||
|
||||
void gpio_write(u32 port, u32 pins, int high)
|
||||
{
|
||||
u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||
const u32 port_offset = GPIO_OUT_OFFSET(port);
|
||||
|
||||
if (high)
|
||||
GPIO(port_offset) |= pins;
|
||||
|
@ -86,16 +90,49 @@ void gpio_write(u32 port, u32 pins, int high)
|
|||
(void)GPIO(port_offset); // Commit the write.
|
||||
}
|
||||
|
||||
void gpio_direction_input(u32 port, u32 pins)
|
||||
{
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE);
|
||||
}
|
||||
|
||||
void gpio_direction_output(u32 port, u32 pins, int high)
|
||||
{
|
||||
gpio_config(port, pins, GPIO_MODE_GPIO);
|
||||
gpio_write(port, pins, high);
|
||||
gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE);
|
||||
}
|
||||
|
||||
int gpio_read(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
const u32 port_offset = GPIO_IN_OFFSET(port);
|
||||
|
||||
return (GPIO(port_offset) & pins) ? 1 : 0;
|
||||
}
|
||||
|
||||
void gpio_set_debounce(u32 port, u32 pins, u32 ms)
|
||||
{
|
||||
const u32 db_ctrl_offset = GPIO_DB_CTRL_OFFSET(port);
|
||||
const u32 db_cnt_offset = GPIO_DB_CNT_OFFSET(port);
|
||||
|
||||
if (ms)
|
||||
{
|
||||
if (ms > 255)
|
||||
ms = 255;
|
||||
|
||||
// Debounce time affects all pins of the same port.
|
||||
GPIO(db_cnt_offset) = ms;
|
||||
GPIO(db_ctrl_offset) = (pins << 8) | pins;
|
||||
}
|
||||
else
|
||||
GPIO(db_ctrl_offset) = (pins << 8) | 0;
|
||||
|
||||
(void)GPIO(db_ctrl_offset); // Commit the write.
|
||||
}
|
||||
|
||||
static void _gpio_interrupt_clear(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_CLR_OFFSET(port);
|
||||
|
||||
GPIO(port_offset) |= pins;
|
||||
|
||||
|
@ -104,10 +141,10 @@ static void _gpio_interrupt_clear(u32 port, u32 pins)
|
|||
|
||||
int gpio_interrupt_status(u32 port, u32 pins)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||
u32 enabled = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||
const u32 port_offset = GPIO_INT_STA_OFFSET(port);
|
||||
const u32 enabled_mask = GPIO(GPIO_INT_ENB_OFFSET(port)) & pins;
|
||||
|
||||
int status = ((GPIO(port_offset) & pins) && enabled) ? 1 : 0;
|
||||
int status = ((GPIO(port_offset) & pins) && enabled_mask) ? 1 : 0;
|
||||
|
||||
// Clear the interrupt status.
|
||||
if (status)
|
||||
|
@ -118,7 +155,7 @@ int gpio_interrupt_status(u32 port, u32 pins)
|
|||
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_ENB_OFFSET(port);
|
||||
|
||||
// Clear any possible stray interrupt.
|
||||
_gpio_interrupt_clear(port, pins);
|
||||
|
@ -133,7 +170,7 @@ void gpio_interrupt_enable(u32 port, u32 pins, int enable)
|
|||
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
||||
{
|
||||
u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||
const u32 port_offset = GPIO_INT_LVL_OFFSET(port);
|
||||
|
||||
u32 val = GPIO(port_offset);
|
||||
|
||||
|
@ -162,7 +199,7 @@ void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta)
|
|||
|
||||
u32 gpio_get_bank_irq_id(u32 port)
|
||||
{
|
||||
u32 bank_idx = GPIO_BANK_IDX(port);
|
||||
const u32 bank_idx = GPIO_BANK_IDX(port);
|
||||
|
||||
return gpio_bank_irq_ids[bank_idx];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -85,8 +85,11 @@
|
|||
|
||||
void gpio_config(u32 port, u32 pins, int mode);
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_direction_input(u32 port, u32 pins);
|
||||
void gpio_direction_output(u32 port, u32 pins, int high);
|
||||
void gpio_write(u32 port, u32 pins, int high);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
void gpio_set_debounce(u32 port, u32 pins, u32 ms);
|
||||
int gpio_interrupt_status(u32 port, u32 pins);
|
||||
void gpio_interrupt_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_interrupt_level(u32 port, u32 pins, int high, int edge, int delta);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <soc/hw_init.h>
|
||||
#include <display/di.h>
|
||||
#include <display/vic.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <sec/se.h>
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/uart.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
|
@ -71,24 +73,24 @@ u32 hw_get_chip_id()
|
|||
static void _config_oscillators()
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
|
||||
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
|
||||
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
|
||||
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
|
||||
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
|
||||
}
|
||||
|
||||
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
|
||||
|
@ -99,53 +101,39 @@ static void _config_gpios(bool nx_hoag)
|
|||
|
||||
if (!nx_hoag)
|
||||
{
|
||||
// Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
|
||||
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
|
||||
|
||||
// Set pin mode for UARTB/C TX pins.
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
#endif
|
||||
|
||||
// Enable input logic for UARTB/C TX pins.
|
||||
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
|
||||
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
|
||||
}
|
||||
|
||||
// Set Joy-Con IsAttached direction.
|
||||
// Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
|
||||
// Set Joy-Con IsAttached mode.
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
|
||||
// Enable input logic for Joy-Con IsAttached pins.
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
// Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
|
||||
gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
|
||||
gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
|
||||
|
||||
pinmux_config_i2c(I2C_1);
|
||||
pinmux_config_i2c(I2C_5);
|
||||
pinmux_config_uart(UART_A);
|
||||
|
||||
// Configure volume up/down as inputs.
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
|
||||
|
||||
// Configure HOME as inputs.
|
||||
// Configure HOME as input. (Shared with UARTB RTS).
|
||||
PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
|
||||
|
||||
// Power button can be configured for hoag here. Only SKU where it's connected.
|
||||
}
|
||||
|
||||
static void _config_pmc_scratch()
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
|
||||
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
|
@ -178,8 +166,9 @@ static void _mbist_workaround()
|
|||
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
|
||||
// Set SLCG overrides.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
|
||||
VIC(0x8C) = 0xFFFFFFFF;
|
||||
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||
usleep(2);
|
||||
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
|
@ -246,9 +235,9 @@ static void _mbist_workaround()
|
|||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
static void _config_se_brom()
|
||||
|
@ -263,17 +252,19 @@ static void _config_se_brom()
|
|||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
// This memset needs to happen here, else TZRAM will behave weirdly later on.
|
||||
memset((void *)TZRAM_BASE, 0, SZ_64K);
|
||||
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
|
||||
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
|
||||
SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts.
|
||||
|
||||
// Clear SE interrupts.
|
||||
SE(SE_INT_STATUS_REG) = SE_INT_OP_DONE | SE_INT_OUT_DONE | SE_INT_OUT_LL_BUF_WR | SE_INT_IN_DONE | SE_INT_IN_LL_BUF_RD;
|
||||
|
||||
// Save reset reason.
|
||||
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
|
||||
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
|
||||
|
||||
// Clear the boot reason to avoid problems later.
|
||||
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
|
||||
PMC(APBDEV_PMC_RST_STATUS) = 0x0;
|
||||
PMC(APBDEV_PMC_SCRATCH200) = 0;
|
||||
PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
|
||||
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
|
||||
}
|
||||
|
||||
|
@ -291,6 +282,9 @@ static void _config_regulators(bool tegra_t210)
|
|||
max7762x_regulator_enable(REGULATOR_LDO2, false);
|
||||
sd_power_cycle_time_start = get_tmr_ms();
|
||||
|
||||
// Disable LCD DVDD.
|
||||
max7762x_regulator_enable(REGULATOR_LDO0, false);
|
||||
|
||||
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.
|
||||
|
@ -327,15 +321,17 @@ static void _config_regulators(bool tegra_t210)
|
|||
|
||||
void hw_init()
|
||||
{
|
||||
// Get Chip ID.
|
||||
// Get Chip ID and SKU.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||
|
||||
// Bootrom stuff we skipped by going through rcm.
|
||||
_config_se_brom();
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
|
||||
|
||||
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
|
||||
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
|
||||
|
||||
// Perform Memory Built-In Self Test WAR if T210.
|
||||
if (tegra_t210)
|
||||
|
@ -360,8 +356,14 @@ void hw_init()
|
|||
_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_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
|
||||
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
|
||||
#endif
|
||||
|
||||
|
@ -378,7 +380,7 @@ void hw_init()
|
|||
// Initialize I2C5, mandatory for PMIC.
|
||||
i2c_init(I2C_5);
|
||||
|
||||
//! TODO: Why? Device is NFC MCU on Lite.
|
||||
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
|
||||
if (nx_hoag)
|
||||
{
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
|
||||
|
@ -391,9 +393,6 @@ void hw_init()
|
|||
// Initialize various regulators based on Erista/Mariko platform.
|
||||
_config_regulators(tegra_t210);
|
||||
|
||||
// Enable charger in case it's disabled.
|
||||
bq24193_enable_charger();
|
||||
|
||||
_config_pmc_scratch(); // Missing from 4.x+
|
||||
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
|
@ -402,24 +401,30 @@ void hw_init()
|
|||
// Power on T210B01 shadow TZRAM and lock the reg.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
}
|
||||
|
||||
// Initialize External memory controller and configure DRAM parameters.
|
||||
sdram_init();
|
||||
|
||||
bpmp_mmu_enable();
|
||||
|
||||
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
|
||||
clock_enable_host1x();
|
||||
}
|
||||
|
||||
void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
||||
{
|
||||
// Disable BPMP max clock.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// Scale down BPMP clock.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
#ifdef BDK_HW_EXTRA_DEINIT
|
||||
// Disable temperature sensor, touchscreen, 5V regulators and Joy-Con.
|
||||
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
|
||||
vic_end();
|
||||
tmp451_end();
|
||||
set_fan_duty(0);
|
||||
touch_power_off();
|
||||
|
@ -427,14 +432,19 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||
regulator_5v_disable(REGULATOR_5V_ALL);
|
||||
#endif
|
||||
|
||||
// Flush/disable MMU cache and set DRAM clock to 204MHz.
|
||||
bpmp_mmu_disable();
|
||||
// set DRAM clock to 204MHz.
|
||||
minerva_change_freq(FREQ_204);
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
// Flush/disable MMU cache.
|
||||
bpmp_mmu_disable();
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
}
|
||||
|
||||
// Do coreboot mitigations.
|
||||
if (coreboot)
|
||||
|
@ -443,11 +453,9 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
// Disable Joy-con GPIOs.
|
||||
// Disable Joy-con detect in order to restore UART TX.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);
|
||||
|
||||
// Reinstate SD controller power.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
|
@ -463,17 +471,11 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
|
|||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
display_backlight_brightness(brightness, 0);
|
||||
break;
|
||||
case BL_MAGIC_L4TLDR_SLD:
|
||||
// Do not disable display or backlight at all.
|
||||
break;
|
||||
default:
|
||||
display_end();
|
||||
}
|
||||
|
||||
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
|
||||
if (bl_magic == BL_MAGIC_BROKEN_HWI)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
|
||||
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
|
||||
clock_disable_cl_dvfs();
|
||||
|
||||
msleep(200);
|
||||
clock_disable_host1x();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
#include <utils/types.h>
|
||||
|
||||
#define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0.
|
||||
#define BL_MAGIC_HEKATF_SLD 0x31444C53 // SLD1, seamless display type 1.
|
||||
#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit.
|
||||
#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1.
|
||||
|
||||
extern u32 hw_rst_status;
|
||||
extern u32 hw_rst_reason;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,7 +18,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <soc/i2c.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
#define I2C_PACKET_PROT_I2C BIT(4)
|
||||
#define I2C_HEADER_CONT_XFER BIT(15)
|
||||
|
@ -95,9 +95,9 @@ static void _i2c_load_cfg_wait(vu32 *base)
|
|||
base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
|
||||
break;
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,8 +205,8 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
|
|||
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ;
|
||||
base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
|
||||
|
||||
// Set device address and recv mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
|
||||
// Set device address and send mode.
|
||||
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE;
|
||||
|
||||
// Set recv mode.
|
||||
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
|
||||
|
@ -362,9 +362,9 @@ void i2c_init(u32 i2c_idx)
|
|||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
|
||||
break;
|
||||
usleep(25);
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "irq.h"
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <mem/heap.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
|
||||
extern void excp_reset();
|
||||
extern void irq_disable();
|
||||
extern void irq_enable_cpu_irq_exceptions();
|
||||
extern void irq_disable_cpu_irq_exceptions();
|
||||
|
@ -69,7 +71,7 @@ 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;
|
||||
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,10 +90,10 @@ void irq_free(u32 irq)
|
|||
{
|
||||
if (irqs[idx].irq == irq && irqs[idx].handler)
|
||||
{
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
|
||||
_irq_disable_source(irq);
|
||||
}
|
||||
|
@ -106,10 +108,10 @@ static void _irq_free_all()
|
|||
{
|
||||
_irq_disable_source(irqs[idx].irq);
|
||||
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].irq = 0;
|
||||
irqs[idx].handler = NULL;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
irqs[idx].data = NULL;
|
||||
irqs[idx].flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -218,10 +220,10 @@ irq_status_t irq_request(u32 irq, irq_handler_t handler, void *data, irq_flags_t
|
|||
DPRINTF("Registered handler, IRQ: %d, Slot: %d\n", irq, idx);
|
||||
DPRINTF("Handler: %08p, Flags: %x\n", (u32)handler, flags);
|
||||
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].irq = irq;
|
||||
irqs[idx].handler = handler;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
irqs[idx].data = data;
|
||||
irqs[idx].flags = flags;
|
||||
|
||||
_irq_enable_source(irq);
|
||||
|
||||
|
@ -270,4 +272,14 @@ void __attribute__ ((target("arm"), interrupt ("FIQ"))) fiq_handler()
|
|||
len--;
|
||||
}
|
||||
*/
|
||||
#ifdef BDK_WATCHDOG_FIQ_ENABLE
|
||||
// Set watchdog timeout status and disable WDT and its FIQ signal.
|
||||
watchdog_handle();
|
||||
|
||||
#ifdef BDK_RESTART_BL_ON_WDT
|
||||
// Restart bootloader.
|
||||
excp_reset();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
void pinmux_config_uart(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;
|
||||
PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
}
|
||||
|
||||
void pinmux_config_i2c(u32 idx)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
|
||||
#define PINMUX_AUX_SDMMC3_DAT3 0x30
|
||||
#define PINMUX_AUX_SATA_LED_ACTIVE 0x4C
|
||||
#define PINMUX_AUX_GPIO_PA5_T210B01 PINMUX_AUX_SATA_LED_ACTIVE
|
||||
#define PINMUX_AUX_DMIC3_CLK 0xB4
|
||||
#define PINMUX_AUX_DMIC3_DAT 0xB8
|
||||
#define PINMUX_AUX_CAM_I2C_SCL 0xD4
|
||||
|
@ -46,7 +47,9 @@
|
|||
#define PINMUX_AUX_UART2_TX 0xF4
|
||||
#define PINMUX_AUX_UART3_TX 0x104
|
||||
#define PINMUX_AUX_DAP4_DIN 0x148
|
||||
#define PINMUX_AUX_DAP4_DOUT 0x14C
|
||||
#define PINMUX_AUX_DAP4_SCLK 0x150
|
||||
#define PINMUX_AUX_CLK_32K_OUT 0x164
|
||||
#define PINMUX_AUX_GPIO_X1_AUD 0x18C
|
||||
#define PINMUX_AUX_GPIO_X3_AUD 0x190
|
||||
#define PINMUX_AUX_SPDIF_IN 0x1A4
|
||||
|
@ -57,19 +60,26 @@
|
|||
#define PINMUX_AUX_AP_WAKE_NFC 0x1CC
|
||||
#define PINMUX_AUX_NFC_EN 0x1D0
|
||||
#define PINMUX_AUX_NFC_INT 0x1D4
|
||||
#define PINMUX_AUX_CAM_RST 0x1E0
|
||||
#define PINMUX_AUX_CAM1_PWDN 0x1EC
|
||||
#define PINMUX_AUX_CAM2_PWDN 0x1F0
|
||||
#define PINMUX_AUX_CAM1_STROBE 0x1F4
|
||||
#define PINMUX_AUX_LCD_BL_PWM 0x1FC
|
||||
#define PINMUX_AUX_LCD_BL_EN 0x200
|
||||
#define PINMUX_AUX_LCD_RST 0x204
|
||||
#define PINMUX_AUX_LCD_GPIO1 0x208
|
||||
#define PINMUX_AUX_LCD_GPIO2 0x20C
|
||||
#define PINMUX_AUX_TOUCH_CLK 0x218
|
||||
#define PINMUX_AUX_TOUCH_INT 0x220
|
||||
#define PINMUX_AUX_MOTION_INT 0x224
|
||||
#define PINMUX_AUX_ALS_PROX_INT 0x228
|
||||
#define PINMUX_AUX_BUTTON_POWER_ON 0x230
|
||||
#define PINMUX_AUX_BUTTON_HOME 0x240
|
||||
#define PINMUX_AUX_GPIO_PE6 0x248
|
||||
#define PINMUX_AUX_GPIO_PE7 0x24C
|
||||
#define PINMUX_AUX_GPIO_PH6 0x250
|
||||
#define PINMUX_AUX_GPIO_PK3 0x260
|
||||
#define PINMUX_AUX_GPIO_PK7 0x270
|
||||
#define PINMUX_AUX_GPIO_PZ1 0x280
|
||||
/* Only in T210B01 */
|
||||
#define PINMUX_AUX_SDMMC2_DAT0 0x294
|
||||
|
@ -116,6 +126,8 @@
|
|||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
#define PINMUX_PREEMP BIT(15)
|
||||
|
||||
void pinmux_config_uart(u32 idx);
|
||||
void pinmux_config_i2c(u32 idx);
|
||||
|
||||
|
|
|
@ -16,31 +16,28 @@
|
|||
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
{
|
||||
// Lock Private key disable, Fuse write enable, MC carveout, Warmboot PA id and Warmboot address.
|
||||
|
||||
// Happens on T210B01 LP0 always.
|
||||
if (lock_mask & PMC_SEC_LOCK_MISC)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) |= 0x700FF0; // RW lock: 0-3.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0xFC000000; // RW lock: 21-23.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0x3F0FFF00; // RW lock: 28-33, 36-38.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xC000000; // RW lock: 85.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF00FF00; // RW lock: 108-111, 116-119.
|
||||
|
||||
// SE2 context.
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FF; // RW lock: 120-124. (0xB38)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150.
|
||||
}
|
||||
// Default: 0xFF00FF00: RW lock: 108-111, 116-119. Gets locked in LP0.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF005500; // W lock: 108-111, RW lock: 116-119.
|
||||
}
|
||||
|
||||
// Happens on T210B01 LP0 always.
|
||||
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS)
|
||||
{
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20. L4T expects 8-15 as write locked only.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF; // RW lock: 40-50, 52-54.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF; // RW lock: 56-71.
|
||||
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F; // RW lock: 72-73, 79-84, 86-87.
|
||||
|
@ -60,6 +57,7 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
|||
PMC(APBDEV_PMC_SEC_DISABLE7) |= 0xFFC00000; // RW lock: 99-103.
|
||||
}
|
||||
|
||||
// HOS specific.
|
||||
if (lock_mask & PMC_SEC_LOCK_TZ_CMAC_W)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0x550000; // W lock: 112-115.
|
||||
|
||||
|
@ -71,9 +69,34 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
|||
|
||||
if (lock_mask & PMC_SEC_LOCK_TZ_KEK_R)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE3) |= 0xAA; // R lock: 24-27.
|
||||
// End of HOS specific.
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_SE_SRK)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE) |= 0xFF000; // RW lock: 4-7
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_SE2_SRK_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1).
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_MISC_B01)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always.
|
||||
|
||||
if (lock_mask & PMC_SEC_LOCK_CARVEOUTS_L4T)
|
||||
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x5555; // W: 8-15 LP0 and Carveouts. Superseded by LP0 lock.
|
||||
|
||||
// NVTBOOT misses APBDEV_PMC_SCRATCH_WRITE_LOCK_DISABLE_STICKY. bit0: SCRATCH_WR_DIS_ON.
|
||||
// They could also use the NS write disable registers instead.
|
||||
if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS_B01)
|
||||
{
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1) |= 0x583FF; // W lock: 24-33, 39-40, 42.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2) |= 0x1BE; // W lock: 44-48, 50-51.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3) = 0xFFFFFFFF; // W lock: 56-87.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4) |= 0xFFFFFFF; // W lock: 88-115.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5) |= 0xFFFFFFF8; // W lock: 123-151.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6) = 0xFFFFFFFF; // W lock: 152-183.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7) |= 0xFC00FFFF; // W lock: 184-199, 210-215.
|
||||
PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8) |= 0xF; // W lock: 216-219.
|
||||
}
|
||||
}
|
||||
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable)
|
||||
|
|
267
bdk/soc/pmc.h
267
bdk/soc/pmc.h
|
@ -22,108 +22,183 @@
|
|||
#include <utils/types.h>
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
|
||||
#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
|
||||
#define PMC_SCRATCH0_MODE_RCM BIT(1)
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
|
||||
#define PMC_SCRATCH0_MODE_FASTBOOT BIT(30)
|
||||
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_PWR_DET_AUDIO_HV BIT(18)
|
||||
#define PMC_PWR_DET_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_USB_AO 0xF0
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000
|
||||
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define PMC_RST_STATUS_MASK 0x7
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
#define PMC_RST_STATUS_SW_MAIN 3
|
||||
#define PMC_RST_STATUS_LP0 4
|
||||
#define PMC_RST_STATUS_AOTAG 5
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define PMC_IO_DPD_REQ_DPD_OFF BIT(30)
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
|
||||
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT 0x10
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define PMC_CNTRL2_HOLD_CKE_LOW_EN 0x1000
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
|
||||
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_RTC_CLK_DIS BIT(1)
|
||||
#define PMC_CNTRL_RTC_RST BIT(2)
|
||||
#define PMC_CNTRL_MAIN_RST BIT(4)
|
||||
#define PMC_CNTRL_LATCHWAKE_EN BIT(5)
|
||||
#define PMC_CNTRL_BLINK_EN BIT(7)
|
||||
#define PMC_CNTRL_PWRREQ_OE BIT(9)
|
||||
#define PMC_CNTRL_SYSCLK_OE BIT(11)
|
||||
#define PMC_CNTRL_PWRGATE_DIS BIT(12)
|
||||
#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14)
|
||||
#define PMC_CNTRL_CPUPWRREQ_OE BIT(16)
|
||||
#define PMC_CNTRL_FUSE_OVERRIDE BIT(18)
|
||||
#define PMC_CNTRL_SHUTDOWN_OE BIT(22)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_NO_IOPOWER_SDMMC4_IO_EN BIT(14)
|
||||
#define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
|
||||
#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
|
||||
#define PMC_SCRATCH0_MODE_RCM BIT(1)
|
||||
#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
|
||||
#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
|
||||
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
|
||||
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | \
|
||||
PMC_SCRATCH0_MODE_BOOTLOADER | \
|
||||
PMC_SCRATCH0_MODE_PAYLOAD)
|
||||
#define APBDEV_PMC_BLINK_TIMER 0x40
|
||||
#define PMC_BLINK_ON(n) ((n & 0x7FFF))
|
||||
#define PMC_BLINK_FORCE BIT(15)
|
||||
#define PMC_BLINK_OFF(n) ((u32)(n & 0xFFFF) << 16)
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0 // ODM data/config scratch.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
|
||||
#define PMC_PWR_DET_AUDIO_HV BIT(18)
|
||||
#define PMC_PWR_DET_GPIO_IO_EN BIT(21)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_USB_AO 0xF0
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_PLLP_WB0_OVERRIDE 0xF8
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE_ENABLE BIT(11)
|
||||
#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH37 0x130
|
||||
#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 // "TPAN"
|
||||
#define APBDEV_PMC_SCRATCH39 0x138
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER BIT(22)
|
||||
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN BIT(10)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_FORCE_EN BIT(18)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(src) (((src) & 3) << 6)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(src) (((src) & 3) << 14)
|
||||
#define PMC_CLK_OUT_CNTRL_CLK3_SRC_SEL(src) (((src) & 3) << 22)
|
||||
#define OSC_DIV1 0
|
||||
#define OSC_DIV2 1
|
||||
#define OSC_DIV4 2
|
||||
#define OSC_CAR 3
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define PMC_RST_STATUS_MASK 7
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
#define PMC_RST_STATUS_SW_MAIN 3
|
||||
#define PMC_RST_STATUS_LP0 4
|
||||
#define PMC_RST_STATUS_AOTAG 5
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define PMC_IO_DPD_REQ_DPD_OFF BIT(30)
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
|
||||
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_SCRATCH52 0x250
|
||||
#define APBDEV_PMC_SCRATCH53 0x254
|
||||
#define APBDEV_PMC_SCRATCH54 0x258
|
||||
#define APBDEV_PMC_SCRATCH55 0x25C
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_STICKY_BITS 0x2C0
|
||||
#define PMC_STICKY_BITS_HDA_LPBK_DIS BIT(0)
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT BIT(4)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH22 0x338 // AArch32 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH34 0x368 // AArch64 reset address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH35 0x36C // AArch64 reset hi-address.
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define PMC_CNTRL2_WAKE_INT_EN BIT(0)
|
||||
#define PMC_CNTRL2_WAKE_DET_EN BIT(9)
|
||||
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
|
||||
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
|
||||
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SEC_DISABLE9 0x5C4
|
||||
#define APBDEV_PMC_SEC_DISABLE10 0x5C8
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define APBDEV_PMC_SCRATCH201 0x844
|
||||
#define APBDEV_PMC_SCRATCH250 0x908
|
||||
#define APBDEV_PMC_SECURE_SCRATCH108 0xB08
|
||||
#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH110 0xB10
|
||||
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
|
||||
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
|
||||
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
|
||||
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
|
||||
#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0)
|
||||
#define PMC_TZRAM_DISABLE_REG_READ BIT(1)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH112 0xB18
|
||||
#define APBDEV_PMC_SECURE_SCRATCH113 0xB1C
|
||||
#define APBDEV_PMC_SECURE_SCRATCH114 0xB20
|
||||
#define APBDEV_PMC_SECURE_SCRATCH119 0xB34
|
||||
|
||||
// Only in T210B01.
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE0 0xA48
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE1 0xA4C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE2 0xA50
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE3 0xA54
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE4 0xA58
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE5 0xA5C
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE6 0xA60
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE7 0xA64
|
||||
#define APBDEV_PMC_SCRATCH_WRITE_DISABLE8 0xA68
|
||||
#define APBDEV_PMC_LED_BREATHING_CTRL 0xB48
|
||||
#define PMC_LED_BREATHING_CTRL_ENABLE BIT(0)
|
||||
#define PMC_LED_BREATHING_CTRL_COUNTER1_EN BIT(1)
|
||||
#define APBDEV_PMC_LED_BREATHING_SLOPE_STEPS 0xB4C
|
||||
#define APBDEV_PMC_LED_BREATHING_ON_COUNTER 0xB50
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER1 0xB54
|
||||
#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER0 0xB58
|
||||
#define PMC_LED_BREATHING_COUNTER_HZ 32768
|
||||
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
|
||||
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
|
||||
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
|
||||
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
|
||||
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
|
||||
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
|
||||
#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0)
|
||||
#define PMC_TZRAM_DISABLE_REG_READ BIT(1)
|
||||
|
||||
typedef enum _pmc_sec_lock_t
|
||||
{
|
||||
PMC_SEC_LOCK_MISC = BIT(0),
|
||||
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
|
||||
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
|
||||
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
|
||||
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
|
||||
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
|
||||
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
|
||||
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
|
||||
PMC_SEC_LOCK_SE_SRK = BIT(8),
|
||||
PMC_SEC_LOCK_MISC = BIT(0),
|
||||
PMC_SEC_LOCK_LP0_PARAMS = BIT(1),
|
||||
PMC_SEC_LOCK_RST_VECTOR = BIT(2),
|
||||
PMC_SEC_LOCK_CARVEOUTS = BIT(3),
|
||||
PMC_SEC_LOCK_TZ_CMAC_W = BIT(4),
|
||||
PMC_SEC_LOCK_TZ_CMAC_R = BIT(5),
|
||||
PMC_SEC_LOCK_TZ_KEK_W = BIT(6),
|
||||
PMC_SEC_LOCK_TZ_KEK_R = BIT(7),
|
||||
PMC_SEC_LOCK_SE_SRK = BIT(8),
|
||||
PMC_SEC_LOCK_SE2_SRK_B01 = BIT(9),
|
||||
PMC_SEC_LOCK_MISC_B01 = BIT(10),
|
||||
PMC_SEC_LOCK_CARVEOUTS_L4T = BIT(11),
|
||||
PMC_SEC_LOCK_LP0_PARAMS_B01 = BIT(12),
|
||||
} pmc_sec_lock_t;
|
||||
|
||||
typedef enum _pmc_power_rail_t
|
||||
|
|
265
bdk/soc/t210.h
265
bdk/soc/t210.h
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -26,8 +27,10 @@
|
|||
#define DISPLAY_A_BASE 0x54200000
|
||||
#define DSI_BASE 0x54300000
|
||||
#define VIC_BASE 0x54340000
|
||||
#define NVDEC_BASE 0x54480000
|
||||
#define TSEC_BASE 0x54500000
|
||||
#define SOR1_BASE 0x54580000
|
||||
#define MSELECT_BASE 0x50060000
|
||||
#define ICTLR_BASE 0x60004000
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
|
@ -70,6 +73,8 @@
|
|||
#define I2S_BASE 0x702D1000
|
||||
#define ADMA_BASE 0x702E2000
|
||||
#define TZRAM_BASE 0x7C010000
|
||||
#define TZRAM_SIZE 0x10000
|
||||
#define TZRAM_T210B01_SIZE 0x3C000
|
||||
#define USB_BASE 0x7D000000
|
||||
#define USB_OTG_BASE USB_BASE
|
||||
#define USB1_BASE 0x7D004000
|
||||
|
@ -81,8 +86,10 @@
|
|||
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
|
||||
#define DSI(off) _REG(DSI_BASE, off)
|
||||
#define VIC(off) _REG(VIC_BASE, off)
|
||||
#define NVDEC(off) _REG(NVDEC_BASE, off)
|
||||
#define TSEC(off) _REG(TSEC_BASE, off)
|
||||
#define SOR1(off) _REG(SOR1_BASE, off)
|
||||
#define MSELECT(off) _REG(MSELECT_BASE, off)
|
||||
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off)
|
||||
#define TMR(off) _REG(TMR_BASE, off)
|
||||
#define CLOCK(off) _REG(CLOCK_BASE, off)
|
||||
|
@ -128,98 +135,99 @@
|
|||
#define USB1(off) _REG(USB1_BASE, off)
|
||||
#define TEST_REG(off) _REG(0x0, off)
|
||||
|
||||
/* HOST1X registers. */
|
||||
#define HOST1X_CH0_SYNC_BASE 0x2100
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4)
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200)
|
||||
/* HOST1X v3 registers. */
|
||||
#define HOST1X_CH0_SYNC_BASE 0x2100
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_BASE (HOST1X_CH0_SYNC_BASE + 0xF80)
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x24)
|
||||
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x280)
|
||||
|
||||
/*! EVP registers. */
|
||||
#define EVP_CPU_RESET_VECTOR 0x100
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_CPU_RESET_VECTOR 0x100
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
#define EVP_COP_IRQ_STS 0x220
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
#define EVP_COP_IRQ_STS 0x220
|
||||
|
||||
/*! Primary Interrupt Controller registers. */
|
||||
#define PRI_ICTLR_FIR 0x14
|
||||
#define PRI_ICTLR_FIR_SET 0x18
|
||||
#define PRI_ICTLR_FIR_CLR 0x1C
|
||||
#define PRI_ICTLR_CPU_IER 0x20
|
||||
#define PRI_ICTLR_CPU_IER_SET 0x24
|
||||
#define PRI_ICTLR_CPU_IER_CLR 0x28
|
||||
#define PRI_ICTLR_FIR 0x14
|
||||
#define PRI_ICTLR_FIR_SET 0x18
|
||||
#define PRI_ICTLR_FIR_CLR 0x1C
|
||||
#define PRI_ICTLR_CPU_IER 0x20
|
||||
#define PRI_ICTLR_CPU_IER_SET 0x24
|
||||
#define PRI_ICTLR_CPU_IER_CLR 0x28
|
||||
#define PRI_ICTLR_CPU_IEP_CLASS 0x2C
|
||||
#define PRI_ICTLR_COP_IER 0x30
|
||||
#define PRI_ICTLR_COP_IER_SET 0x34
|
||||
#define PRI_ICTLR_COP_IER_CLR 0x38
|
||||
#define PRI_ICTLR_COP_IER 0x30
|
||||
#define PRI_ICTLR_COP_IER_SET 0x34
|
||||
#define PRI_ICTLR_COP_IER_CLR 0x38
|
||||
#define PRI_ICTLR_COP_IEP_CLASS 0x3C
|
||||
|
||||
/*! AHB Gizmo registers. */
|
||||
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
|
||||
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
|
||||
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
|
||||
#define AHB_GIZMO_AHB_MEM 0x10
|
||||
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
|
||||
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
|
||||
#define AHB_MEM_IMMEDIATE BIT(18)
|
||||
#define AHB_GIZMO_APB_DMA 0x14
|
||||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8
|
||||
#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29)
|
||||
#define PRIORITY_SELECT_USB BIT(6) // USB-OTG.
|
||||
#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC.
|
||||
#define PRIORITY_SELECT_USB3 BIT(17) // XUSB.
|
||||
#define AHB_GIZMO_AHB_MEM 0x10
|
||||
#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2)
|
||||
#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7)
|
||||
#define AHB_MEM_IMMEDIATE BIT(18)
|
||||
#define AHB_GIZMO_APB_DMA 0x14
|
||||
#define AHB_GIZMO_USB 0x20
|
||||
#define AHB_GIZMO_SDMMC4 0x48
|
||||
#define AHB_GIZMO_USB2 0x7C
|
||||
#define AHB_GIZMO_USB3 0x80
|
||||
#define AHB_GIZMO_IMMEDIATE BIT(18)
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0
|
||||
#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
|
||||
#define MST_ID(x) (((x) & 0x1F) << 26)
|
||||
#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5)
|
||||
#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG.
|
||||
#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC.
|
||||
#define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB.
|
||||
#define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21)
|
||||
#define MEM_PREFETCH_ENABLE BIT(31)
|
||||
#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC
|
||||
#define MEM_WRQUE_SE_MST_ID BIT(14)
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
#define MEM_WRQUE_SE_MST_ID BIT(14)
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
|
||||
/*! Misc registers. */
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_HIDREV 0x804
|
||||
#define GP_HIDREV_MAJOR_T210 0x1
|
||||
#define GP_HIDREV_MAJOR_T210B01 0x2
|
||||
#define APB_MISC_GP_ASDBGREG 0x810
|
||||
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
|
||||
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x8
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_HIDREV 0x804
|
||||
#define GP_HIDREV_MAJOR_T210 0x1
|
||||
#define GP_HIDREV_MAJOR_T210B01 0x2
|
||||
#define APB_MISC_GP_ASDBGREG 0x810
|
||||
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
|
||||
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
|
||||
#define APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL 0xABC
|
||||
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
|
||||
/*! Secure boot registers. */
|
||||
#define SB_CSR 0x0
|
||||
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
|
||||
#define SB_CSR_PIROM_DISABLE BIT(4)
|
||||
#define SB_AA64_RESET_LOW 0x30
|
||||
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
|
||||
#define SB_AA64_RESET_HIGH 0x34
|
||||
#define SB_CSR 0x0
|
||||
#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
|
||||
#define SB_CSR_PIROM_DISABLE BIT(4)
|
||||
#define SB_AA64_RESET_LOW 0x30
|
||||
#define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
|
||||
#define SB_AA64_RESET_HIGH 0x34
|
||||
|
||||
/*! SOR registers. */
|
||||
#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8
|
||||
#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C
|
||||
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB 0x208
|
||||
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB 0x20C
|
||||
#define SOR_DP_HDCP_BKSV_LSB 0x1E8
|
||||
#define SOR_TMDS_HDCP_BKSV_LSB 0x21C
|
||||
#define SOR_TMDS_HDCP_CN_MSB 0x208
|
||||
#define SOR_TMDS_HDCP_CN_LSB 0x20C
|
||||
|
||||
/*! RTC registers. */
|
||||
#define APBDEV_RTC_SECONDS 0x8
|
||||
|
@ -227,42 +235,22 @@
|
|||
#define APBDEV_RTC_MILLI_SECONDS 0x10
|
||||
|
||||
/*! SYSCTR0 registers. */
|
||||
#define SYSCTR0_CNTFID0 0x20
|
||||
#define SYSCTR0_CNTCR 0x00
|
||||
#define SYSCTR0_COUNTERID0 0xFE0
|
||||
#define SYSCTR0_COUNTERID1 0xFE4
|
||||
#define SYSCTR0_COUNTERID2 0xFE8
|
||||
#define SYSCTR0_COUNTERID3 0xFEC
|
||||
#define SYSCTR0_COUNTERID4 0xFD0
|
||||
#define SYSCTR0_COUNTERID5 0xFD4
|
||||
#define SYSCTR0_COUNTERID6 0xFD8
|
||||
#define SYSCTR0_COUNTERID7 0xFDC
|
||||
#define SYSCTR0_COUNTERID8 0xFF0
|
||||
#define SYSCTR0_COUNTERID9 0xFF4
|
||||
#define SYSCTR0_COUNTERID10 0xFF8
|
||||
#define SYSCTR0_COUNTERID11 0xFFC
|
||||
|
||||
/*! TMR registers. */
|
||||
#define TIMERUS_CNTR_1US (0x10 + 0x0)
|
||||
#define TIMERUS_USEC_CFG (0x10 + 0x4)
|
||||
#define TIMER_TMR8_TMR_PTV 0x78
|
||||
#define TIMER_TMR9_TMR_PTV 0x80
|
||||
#define TIMER_PER_EN BIT(30)
|
||||
#define TIMER_EN BIT(31)
|
||||
#define TIMER_TMR8_TMR_PCR 0x7C
|
||||
#define TIMER_TMR9_TMR_PCR 0x8C
|
||||
#define TIMER_INTR_CLR BIT(30)
|
||||
|
||||
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
|
||||
#define TIMER_SRC(TMR) ((TMR) & 0xF)
|
||||
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
|
||||
#define TIMER_SYSRESET_EN BIT(14)
|
||||
#define TIMER_PMCRESET_EN BIT(15)
|
||||
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
|
||||
#define TIMER_START_CNT BIT(0)
|
||||
#define TIMER_CNT_DISABLE BIT(1)
|
||||
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
|
||||
#define TIMER_MAGIC_PTRN 0xC45A
|
||||
#define SYSCTR0_CNTCR 0x00
|
||||
#define SYSCTR0_CNTFID0 0x20
|
||||
#define SYSCTR0_COUNTERS_BASE 0xFD0
|
||||
#define SYSCTR0_COUNTERS 12
|
||||
#define SYSCTR0_COUNTERID0 0xFE0
|
||||
#define SYSCTR0_COUNTERID1 0xFE4
|
||||
#define SYSCTR0_COUNTERID2 0xFE8
|
||||
#define SYSCTR0_COUNTERID3 0xFEC
|
||||
#define SYSCTR0_COUNTERID4 0xFD0
|
||||
#define SYSCTR0_COUNTERID5 0xFD4
|
||||
#define SYSCTR0_COUNTERID6 0xFD8
|
||||
#define SYSCTR0_COUNTERID7 0xFDC
|
||||
#define SYSCTR0_COUNTERID8 0xFF0
|
||||
#define SYSCTR0_COUNTERID9 0xFF4
|
||||
#define SYSCTR0_COUNTERID10 0xFF8
|
||||
#define SYSCTR0_COUNTERID11 0xFFC
|
||||
|
||||
/*! I2S registers. */
|
||||
#define I2S1_CG 0x88
|
||||
|
@ -288,25 +276,42 @@
|
|||
#define EMC_HEKA_UPD BIT(30)
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define HALT_COP_GIC_IRQ BIT(9)
|
||||
#define HALT_COP_LIC_IRQ BIT(11)
|
||||
#define HALT_COP_SEC BIT(23)
|
||||
#define HALT_COP_MSEC BIT(24)
|
||||
#define HALT_COP_USEC BIT(25)
|
||||
#define HALT_COP_JTAG BIT(28)
|
||||
#define HALT_COP_WAIT_EVENT BIT(30)
|
||||
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
#define HALT_COP_GIC_IRQ BIT(9)
|
||||
#define HALT_COP_LIC_IRQ BIT(11)
|
||||
#define HALT_COP_SEC BIT(23)
|
||||
#define HALT_COP_MSEC BIT(24)
|
||||
#define HALT_COP_USEC BIT(25)
|
||||
#define HALT_COP_JTAG BIT(28)
|
||||
#define HALT_COP_WAIT_EVENT BIT(30)
|
||||
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
|
||||
#define FLOW_CTLR_CPU0_CSR 0x8
|
||||
#define FLOW_CTLR_CPU1_CSR 0x18
|
||||
#define FLOW_CTLR_CPU2_CSR 0x20
|
||||
#define FLOW_CTLR_CPU3_CSR 0x28
|
||||
#define FLOW_CTLR_RAM_REPAIR 0x40
|
||||
#define RAM_REPAIR_REQ BIT(0)
|
||||
#define RAM_REPAIR_STS BIT(1)
|
||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
|
||||
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
|
||||
|
||||
/* MSelect registers */
|
||||
#define MSELECT_CONFIG 0x00
|
||||
#define MSELECT_CFG_ERR_RESP_EN_PCIE BIT(24)
|
||||
#define MSELECT_CFG_ERR_RESP_EN_GPU BIT(25)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_BPMP BIT(27)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_PCIE BIT(28)
|
||||
#define MSELECT_CFG_WRAP_TO_INCR_GPU BIT(29)
|
||||
|
||||
/* NVDEC registers */
|
||||
#define NVDEC_SA_KEYSLOT_FALCON 0x2100
|
||||
#define NVDEC_SA_KEYSLOT_TZ 0x2104
|
||||
#define NVDEC_SA_KEYSLOT_OTF 0x210C
|
||||
#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118
|
||||
#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C
|
||||
#endif
|
||||
|
|
121
bdk/soc/timer.c
Normal file
121
bdk/soc/timer.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Timer/Watchdog driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_TYPE_WDT 0x544457 // "WDT".
|
||||
|
||||
u32 get_tmr_s()
|
||||
{
|
||||
(void)RTC(APBDEV_RTC_MILLI_SECONDS);
|
||||
return (u32)RTC(APBDEV_RTC_SECONDS);
|
||||
}
|
||||
|
||||
u32 get_tmr_ms()
|
||||
{
|
||||
// The registers must be read with the following order:
|
||||
// RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
|
||||
return (u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000));
|
||||
}
|
||||
|
||||
u32 get_tmr_us()
|
||||
{
|
||||
return (u32)TMR(TIMERUS_CNTR_1US);
|
||||
}
|
||||
|
||||
void msleep(u32 ms)
|
||||
{
|
||||
#ifdef USE_RTC_TIMER
|
||||
u32 start = (u32)RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000);
|
||||
// Casting to u32 is important!
|
||||
while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms)
|
||||
;
|
||||
#else
|
||||
bpmp_msleep(ms);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usleep(u32 us)
|
||||
{
|
||||
#ifdef USE_RTC_TIMER
|
||||
u32 start = (u32)TMR(TIMERUS_CNTR_1US);
|
||||
|
||||
// Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately.
|
||||
if ((start + us) < start)
|
||||
bpmp_usleep(us);
|
||||
else
|
||||
while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important!
|
||||
;
|
||||
#else
|
||||
bpmp_usleep(us);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Instruction wait loop. Each loop is 3 cycles (SUBS+BGT). Usage: isleep(ILOOP(instr)). Base 408MHz: 7.35ns.
|
||||
void __attribute__((target("arm"))) isleep(u32 is)
|
||||
{
|
||||
asm volatile( "0:" "SUBS %[is_cnt], #1;" "BGT 0b;" : [is_cnt] "+r" (is));
|
||||
}
|
||||
|
||||
void timer_usleep(u32 us)
|
||||
{
|
||||
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;
|
||||
|
||||
irq_wait_event(IRQ_TMR8);
|
||||
|
||||
TMR(TIMER_TMR8_TMR_PCR) = TIMER_INTR_CLR;
|
||||
}
|
||||
|
||||
void watchdog_start(u32 us, u32 mode)
|
||||
{
|
||||
// WDT4 is for BPMP.
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN | us;
|
||||
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | mode;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
|
||||
}
|
||||
|
||||
void watchdog_end()
|
||||
{
|
||||
// WDT4 is for BPMP.
|
||||
TMR(TIMER_TMR9_TMR_PTV) = 0;
|
||||
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; // Re-arm to clear any interrupts.
|
||||
TMR(TIMER_WDT4_COMMAND) = TIMER_CNT_DISABLE;
|
||||
TMR(TIMER_TMR9_TMR_PCR) = TIMER_INTR_CLR;
|
||||
}
|
||||
|
||||
void watchdog_handle()
|
||||
{
|
||||
// Disable watchdog and clear its interrupts.
|
||||
watchdog_end();
|
||||
|
||||
// Set watchdog magic.
|
||||
*(u32 *)EXCP_TYPE_ADDR = EXCP_TYPE_WDT;
|
||||
}
|
||||
|
||||
bool watchdog_fired()
|
||||
{
|
||||
// Return if watchdog got fired. User handles clearing.
|
||||
return (*(u32 *)EXCP_TYPE_ADDR == EXCP_TYPE_WDT);
|
||||
}
|
64
bdk/soc/timer.h
Normal file
64
bdk/soc/timer.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Timer/Watchdog driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
// TMR registers.
|
||||
#define TIMERUS_CNTR_1US (0x10 + 0x0)
|
||||
#define TIMERUS_USEC_CFG (0x10 + 0x4)
|
||||
#define TIMER_TMR8_TMR_PTV 0x78
|
||||
#define TIMER_TMR9_TMR_PTV 0x80
|
||||
#define TIMER_PER_EN BIT(30)
|
||||
#define TIMER_EN BIT(31)
|
||||
#define TIMER_TMR8_TMR_PCR 0x7C
|
||||
#define TIMER_TMR9_TMR_PCR 0x8C
|
||||
#define TIMER_INTR_CLR BIT(30)
|
||||
|
||||
// WDT registers.
|
||||
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
|
||||
#define TIMER_SRC(TMR) ((TMR) & 0xF)
|
||||
#define TIMER_PER(PER) (((PER) & 0xFF) << 4)
|
||||
#define TIMER_IRQENABL_EN BIT(12)
|
||||
#define TIMER_FIQENABL_EN BIT(13)
|
||||
#define TIMER_SYSRESET_EN BIT(14)
|
||||
#define TIMER_PMCRESET_EN BIT(15)
|
||||
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
|
||||
#define TIMER_START_CNT BIT(0)
|
||||
#define TIMER_CNT_DISABLE BIT(1)
|
||||
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
|
||||
#define TIMER_MAGIC_PTRN 0xC45A
|
||||
|
||||
u32 get_tmr_us();
|
||||
u32 get_tmr_ms();
|
||||
u32 get_tmr_s();
|
||||
void usleep(u32 us);
|
||||
void msleep(u32 ms);
|
||||
#define ILOOP(is) ((is) / 3)
|
||||
void isleep(u32 is);
|
||||
|
||||
void timer_usleep(u32 us);
|
||||
|
||||
void watchdog_start(u32 us, u32 mode);
|
||||
void watchdog_end();
|
||||
void watchdog_handle();
|
||||
bool watchdog_fired();
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,45 +17,58 @@
|
|||
|
||||
#include <soc/uart.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
/* UART A, B, C, D and E. */
|
||||
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
|
||||
|
||||
void uart_init(u32 idx, u32 baud)
|
||||
void uart_init(u32 idx, u32 baud, u32 mode)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
|
||||
// Make sure no data is being sent.
|
||||
uart_wait_idle(idx, UART_TX_IDLE);
|
||||
if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR)))
|
||||
uart_wait_xfer(idx, UART_TX_IDLE);
|
||||
|
||||
// Set clock.
|
||||
bool clk_type = clock_uart_use_src_div(idx, baud);
|
||||
|
||||
// 2 STOP bits for rates > 1M. (Reduced efficiency but less errors on high baudrates).
|
||||
u32 uart_lcr_stop = baud > 1000000 ? UART_LCR_STOP : 0;
|
||||
|
||||
// Misc settings.
|
||||
u32 div = clk_type ? ((8 * baud + 408000000) / (16 * baud)) : 1; // DIV_ROUND_CLOSEST.
|
||||
uart->UART_IER_DLAB = 0; // Disable interrupts.
|
||||
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
||||
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
|
||||
uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.
|
||||
uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB.
|
||||
uart->UART_IER_DLAB = (u8)(div >> 8); // Divisor latch MSB.
|
||||
uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Disable DLAB.
|
||||
|
||||
// Disable DLAB and set STOP bits setting if applicable.
|
||||
uart->UART_LCR = uart_lcr_stop | UART_LCR_WORD_LENGTH_8;
|
||||
(void)uart->UART_SPR;
|
||||
|
||||
// Setup and flush fifo.
|
||||
// Enable fifo.
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO;
|
||||
(void)uart->UART_SPR;
|
||||
usleep(20);
|
||||
uart->UART_MCR = 0; // Disable hardware flow control.
|
||||
|
||||
// Disable hardware flow control.
|
||||
uart->UART_MCR = 0;
|
||||
usleep(96);
|
||||
|
||||
// Clear tx/rx fifos.
|
||||
uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR;
|
||||
|
||||
// Set hardware flow control.
|
||||
uart->UART_MCR = mode;
|
||||
|
||||
// Wait 3 symbols for baudrate change.
|
||||
usleep(3 * ((baud + 999999) / baud));
|
||||
uart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE);
|
||||
uart_wait_xfer(idx, UART_TX_IDLE | UART_RX_RDYR);
|
||||
}
|
||||
|
||||
void uart_wait_idle(u32 idx, u32 which)
|
||||
void uart_wait_xfer(u32 idx, u32 which)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
if (UART_TX_IDLE & which)
|
||||
|
@ -63,10 +76,10 @@ void uart_wait_idle(u32 idx, u32 which)
|
|||
while (!(uart->UART_LSR & UART_LSR_TMTY))
|
||||
;
|
||||
}
|
||||
if (UART_RX_IDLE & which)
|
||||
if (UART_RX_RDYR & which)
|
||||
{
|
||||
while (uart->UART_LSR & UART_LSR_RDR)
|
||||
;
|
||||
(void)uart->UART_THR_DLAB;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,26 +98,31 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
|
|||
u32 uart_recv(u32 idx, u8 *buf, u32 len)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
bool manual_mode = uart->UART_MCR & UART_MCR_RTS;
|
||||
u32 timeout = get_tmr_us() + 250;
|
||||
u32 i;
|
||||
|
||||
if (manual_mode)
|
||||
uart->UART_MCR &= ~UART_MCR_RTS;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR))
|
||||
{
|
||||
if (timeout < get_tmr_us())
|
||||
break;
|
||||
if (len && len < i)
|
||||
break;
|
||||
}
|
||||
if (timeout < get_tmr_us())
|
||||
if (len && len <= i)
|
||||
break;
|
||||
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR))
|
||||
if (timeout < get_tmr_us())
|
||||
goto out;
|
||||
|
||||
buf[i] = uart->UART_THR_DLAB;
|
||||
timeout = get_tmr_us() + 250;
|
||||
}
|
||||
|
||||
return i ? (len ? (i - 1) : i) : 0;
|
||||
out:
|
||||
if (manual_mode)
|
||||
uart->UART_MCR |= UART_MCR_RTS;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void uart_invert(u32 idx, bool enable, u32 invert_mask)
|
||||
|
@ -118,6 +136,14 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask)
|
|||
(void)uart->UART_SPR;
|
||||
}
|
||||
|
||||
void uart_set_mode(u32 idx, u32 mode)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
|
||||
uart->UART_MCR = mode;
|
||||
(void)uart->UART_SPR;
|
||||
}
|
||||
|
||||
u32 uart_get_IIR(u32 idx)
|
||||
{
|
||||
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
|
||||
|
@ -179,9 +205,11 @@ void uart_empty_fifo(u32 idx, u32 which)
|
|||
|
||||
#include <utils/sprintf.h>
|
||||
|
||||
void uart_print(const char *fmt, ...)
|
||||
void uart_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
//! NOTE: Anything more and it will hang. Heap usage is out of the question.
|
||||
char text[256];
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
|
|
@ -28,33 +28,33 @@
|
|||
|
||||
#define BAUD_115200 115200
|
||||
|
||||
#define UART_TX_IDLE 0x1
|
||||
#define UART_RX_IDLE 0x2
|
||||
#define UART_TX_IDLE BIT(0)
|
||||
#define UART_RX_RDYR BIT(1)
|
||||
|
||||
#define UART_TX_FIFO_FULL 0x100
|
||||
#define UART_RX_FIFO_EMPTY 0x200
|
||||
#define UART_TX_FIFO_FULL BIT(8)
|
||||
#define UART_RX_FIFO_EMPTY BIT(9)
|
||||
|
||||
#define UART_INVERT_RXD 0x01
|
||||
#define UART_INVERT_TXD 0x02
|
||||
#define UART_INVERT_CTS 0x04
|
||||
#define UART_INVERT_RTS 0x08
|
||||
#define UART_INVERT_RXD BIT(0)
|
||||
#define UART_INVERT_TXD BIT(1)
|
||||
#define UART_INVERT_CTS BIT(2)
|
||||
#define UART_INVERT_RTS BIT(3)
|
||||
|
||||
#define UART_IER_DLAB_IE_EORD 0x20
|
||||
#define UART_IER_DLAB_IE_EORD BIT(5)
|
||||
|
||||
#define UART_LCR_DLAB 0x80
|
||||
#define UART_LCR_STOP 0x4
|
||||
#define UART_LCR_WORD_LENGTH_8 0x3
|
||||
#define UART_LCR_STOP BIT(2)
|
||||
#define UART_LCR_DLAB BIT(7)
|
||||
|
||||
#define UART_LSR_RDR 0x1
|
||||
#define UART_LSR_THRE 0x20
|
||||
#define UART_LSR_TMTY 0x40
|
||||
#define UART_LSR_FIFOE 0x80
|
||||
#define UART_LSR_RDR BIT(0)
|
||||
#define UART_LSR_THRE BIT(5)
|
||||
#define UART_LSR_TMTY BIT(6)
|
||||
#define UART_LSR_FIFOE BIT(7)
|
||||
|
||||
#define UART_IIR_FCR_TX_CLR 0x4
|
||||
#define UART_IIR_FCR_RX_CLR 0x2
|
||||
#define UART_IIR_FCR_EN_FIFO 0x1
|
||||
#define UART_IIR_FCR_EN_FIFO BIT(0)
|
||||
#define UART_IIR_FCR_RX_CLR BIT(1)
|
||||
#define UART_IIR_FCR_TX_CLR BIT(2)
|
||||
|
||||
#define UART_IIR_NO_INT BIT(0)
|
||||
#define UART_IIR_NO_INT BIT(0)
|
||||
#define UART_IIR_INT_MASK 0xF
|
||||
/* Custom returned interrupt results. Actual interrupts are -1 */
|
||||
#define UART_IIR_NOI 0 // No interrupt.
|
||||
|
@ -65,8 +65,10 @@
|
|||
#define UART_IIR_REDI 5 // Receiver end of data interrupt.
|
||||
#define UART_IIR_RDTI 7 // Receiver data timeout interrupt.
|
||||
|
||||
#define UART_MCR_RTS 0x2
|
||||
#define UART_MCR_DTR 0x1
|
||||
#define UART_MCR_DTR BIT(0)
|
||||
#define UART_MCR_RTS BIT(1)
|
||||
#define UART_MCR_CTS_EN BIT(5)
|
||||
#define UART_MCR_RTS_EN BIT(6)
|
||||
|
||||
typedef struct _uart_t
|
||||
{
|
||||
|
@ -86,16 +88,29 @@ typedef struct _uart_t
|
|||
/* 0x3C */ vu32 UART_ASR;
|
||||
} uart_t;
|
||||
|
||||
void uart_init(u32 idx, u32 baud);
|
||||
void uart_wait_idle(u32 idx, u32 which);
|
||||
//! TODO: Commented out modes are not supported yet.
|
||||
typedef enum _uart_mode_t
|
||||
{
|
||||
UART_AO_TX_AO_RX = 0,
|
||||
//UART_MN_TX_AO_RX = UART_MCR_RTS | UART_MCR_DTR,
|
||||
UART_AO_TX_MN_RX = UART_MCR_RTS, // Up to 36 bytes read.
|
||||
//UART_MN_TX_AO_RX = UART_MCR_DTR,
|
||||
//UART_HW_TX_HW_RX = UART_MCR_RTS_EN | UART_MCR_CTS_EN,
|
||||
UART_AO_TX_HW_RX = UART_MCR_RTS_EN,
|
||||
//UART_HW_TX_AO_RX = UART_MCR_CTS_EN,
|
||||
} uart_mode_t;
|
||||
|
||||
void uart_init(u32 idx, u32 baud, u32 mode);
|
||||
void uart_wait_xfer(u32 idx, u32 which);
|
||||
void uart_send(u32 idx, const u8 *buf, u32 len);
|
||||
u32 uart_recv(u32 idx, u8 *buf, u32 len);
|
||||
void uart_invert(u32 idx, bool enable, u32 invert_mask);
|
||||
void uart_set_mode(u32 idx, u32 mode);
|
||||
u32 uart_get_IIR(u32 idx);
|
||||
void uart_set_IIR(u32 idx);
|
||||
void uart_empty_fifo(u32 idx, u32 which);
|
||||
#ifdef DEBUG_UART_PORT
|
||||
void uart_print(const char *fmt, ...);
|
||||
void uart_printf(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,8 @@ u32 emmc_get_mode()
|
|||
return emmc_mode;
|
||||
}
|
||||
|
||||
void emmc_end() { sdmmc_storage_end(&emmc_storage); }
|
||||
|
||||
int emmc_init_retry(bool power_cycle)
|
||||
{
|
||||
u32 bus_width = SDMMC_BUS_WIDTH_8;
|
||||
|
@ -70,7 +72,7 @@ int emmc_init_retry(bool power_cycle)
|
|||
if (power_cycle)
|
||||
{
|
||||
emmc_mode--;
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
emmc_end();
|
||||
}
|
||||
|
||||
// Get init parameters.
|
||||
|
@ -105,7 +107,7 @@ bool emmc_initialize(bool power_cycle)
|
|||
emmc_mode = EMMC_MMC_HS400;
|
||||
|
||||
if (power_cycle)
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
emmc_end();
|
||||
|
||||
int res = !emmc_init_retry(false);
|
||||
|
||||
|
@ -124,11 +126,13 @@ bool emmc_initialize(bool power_cycle)
|
|||
}
|
||||
}
|
||||
|
||||
sdmmc_storage_end(&emmc_storage);
|
||||
emmc_end();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int emmc_set_partition(u32 partition) { return sdmmc_storage_set_mmc_partition(&emmc_storage, partition); }
|
||||
|
||||
void emmc_gpt_parse(link_t *gpt)
|
||||
{
|
||||
gpt_t *gpt_buf = (gpt_t *)calloc(GPT_NUM_BLOCKS, EMMC_BLOCKSIZE);
|
||||
|
@ -150,10 +154,10 @@ void emmc_gpt_parse(link_t *gpt)
|
|||
if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba)
|
||||
continue;
|
||||
|
||||
part->index = i;
|
||||
part->index = i;
|
||||
part->lba_start = gpt_buf->entries[i].lba_start;
|
||||
part->lba_end = gpt_buf->entries[i].lba_end;
|
||||
part->attrs = gpt_buf->entries[i].attrs;
|
||||
part->lba_end = gpt_buf->entries[i].lba_end;
|
||||
part->attrs = gpt_buf->entries[i].attrs;
|
||||
|
||||
// ASCII conversion. Copy only the LSByte of the UTF-16LE name.
|
||||
for (u32 j = 0; j < 36; j++)
|
||||
|
|
|
@ -30,18 +30,18 @@
|
|||
|
||||
enum
|
||||
{
|
||||
EMMC_INIT_FAIL = 0,
|
||||
EMMC_1BIT_HS52 = 1,
|
||||
EMMC_8BIT_HS52 = 2,
|
||||
EMMC_MMC_HS200 = 3,
|
||||
EMMC_MMC_HS400 = 4,
|
||||
EMMC_INIT_FAIL = 0,
|
||||
EMMC_1BIT_HS52 = 1,
|
||||
EMMC_8BIT_HS52 = 2,
|
||||
EMMC_MMC_HS200 = 3,
|
||||
EMMC_MMC_HS400 = 4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EMMC_ERROR_INIT_FAIL = 0,
|
||||
EMMC_ERROR_RW_FAIL = 1,
|
||||
EMMC_ERROR_RW_RETRY = 2
|
||||
EMMC_ERROR_INIT_FAIL = 0,
|
||||
EMMC_ERROR_RW_FAIL = 1,
|
||||
EMMC_ERROR_RW_RETRY = 2
|
||||
};
|
||||
|
||||
typedef struct _emmc_part_t
|
||||
|
@ -63,6 +63,8 @@ u16 *emmc_get_error_count();
|
|||
u32 emmc_get_mode();
|
||||
int emmc_init_retry(bool power_cycle);
|
||||
bool emmc_initialize(bool power_cycle);
|
||||
int emmc_set_partition(u32 partition);
|
||||
void emmc_end();
|
||||
|
||||
void emmc_gpt_parse(link_t *gpt);
|
||||
void emmc_gpt_free(link_t *gpt);
|
||||
|
|
|
@ -39,40 +39,40 @@ typedef struct _mbr_part_t
|
|||
|
||||
typedef struct _mbr_t
|
||||
{
|
||||
u8 bootstrap[440];
|
||||
u32 signature;
|
||||
u16 copy_protected;
|
||||
mbr_part_t partitions[4];
|
||||
u16 boot_signature;
|
||||
/* 0x000 */ u8 bootstrap[440];
|
||||
/* 0x1B8 */ u32 signature;
|
||||
/* 0x1BC */ u16 copy_protected;
|
||||
/* 0x1BE */ mbr_part_t partitions[4];
|
||||
/* 0x1FE */ u16 boot_signature;
|
||||
} __attribute__((packed)) mbr_t;
|
||||
|
||||
typedef struct _gpt_entry_t
|
||||
{
|
||||
u8 type_guid[0x10];
|
||||
u8 part_guid[0x10];
|
||||
u64 lba_start;
|
||||
u64 lba_end;
|
||||
u64 attrs;
|
||||
u16 name[36];
|
||||
/* 0x00 */ u8 type_guid[0x10];
|
||||
/* 0x10 */ u8 part_guid[0x10];
|
||||
/* 0x20 */ u64 lba_start;
|
||||
/* 0x28 */ u64 lba_end;
|
||||
/* 0x30 */ u64 attrs;
|
||||
/* 0x38 */ u16 name[36];
|
||||
} gpt_entry_t;
|
||||
|
||||
typedef struct _gpt_header_t
|
||||
{
|
||||
u64 signature; // "EFI PART"
|
||||
u32 revision;
|
||||
u32 size;
|
||||
u32 crc32;
|
||||
u32 res1;
|
||||
u64 my_lba;
|
||||
u64 alt_lba;
|
||||
u64 first_use_lba;
|
||||
u64 last_use_lba;
|
||||
u8 disk_guid[0x10];
|
||||
u64 part_ent_lba;
|
||||
u32 num_part_ents;
|
||||
u32 part_ent_size;
|
||||
u32 part_ents_crc32;
|
||||
u8 res2[420]; // Used as first 3 partition entries backup for HOS.
|
||||
/* 0x00 */ u64 signature; // "EFI PART"
|
||||
/* 0x08 */ u32 revision;
|
||||
/* 0x0C */ u32 size;
|
||||
/* 0x10 */ u32 crc32;
|
||||
/* 0x14 */ u32 res1;
|
||||
/* 0x18 */ u64 my_lba;
|
||||
/* 0x20 */ u64 alt_lba;
|
||||
/* 0x28 */ u64 first_use_lba;
|
||||
/* 0x30 */ u64 last_use_lba;
|
||||
/* 0x38 */ u8 disk_guid[0x10];
|
||||
/* 0x48 */ u64 part_ent_lba;
|
||||
/* 0x50 */ u32 num_part_ents;
|
||||
/* 0x54 */ u32 part_ent_size;
|
||||
/* 0x58 */ u32 part_ents_crc32;
|
||||
/* 0x5C */ u8 res2[420]; // Used as first 3 partition entries backup for HOS.
|
||||
} gpt_header_t;
|
||||
|
||||
typedef struct _gpt_t
|
||||
|
|
|
@ -408,7 +408,10 @@
|
|||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_LEVEL_2 0x2
|
||||
#define EXT_CSD_BKOPS_OK 0x0
|
||||
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
|
||||
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
|
||||
#define EXT_CSD_BKOPS_CRITICAL 0x3
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
|
|
|
@ -251,7 +251,12 @@ int nx_emmc_bis_read(u32 sector, u32 count, void *buff)
|
|||
|
||||
while (count)
|
||||
{
|
||||
u32 sct_cnt = MIN(count, BIS_CLUSTER_SECTORS);
|
||||
// Get sector index in cluster and use it as boundary check.
|
||||
u32 cnt_max = (curr_sct % BIS_CLUSTER_SECTORS);
|
||||
cnt_max = BIS_CLUSTER_SECTORS - cnt_max;
|
||||
|
||||
u32 sct_cnt = MIN(count, cnt_max); // Only allow cluster sized access.
|
||||
|
||||
if (nx_emmc_bis_read_block(curr_sct, sct_cnt, buf))
|
||||
return 0;
|
||||
|
||||
|
@ -270,7 +275,12 @@ int nx_emmc_bis_write(u32 sector, u32 count, void *buff)
|
|||
|
||||
while (count)
|
||||
{
|
||||
u32 sct_cnt = MIN(count, BIS_CLUSTER_SECTORS);
|
||||
// Get sector index in cluster and use it as boundary check.
|
||||
u32 cnt_max = (curr_sct % BIS_CLUSTER_SECTORS);
|
||||
cnt_max = BIS_CLUSTER_SECTORS - cnt_max;
|
||||
|
||||
u32 sct_cnt = MIN(count, cnt_max); // Only allow cluster sized access.
|
||||
|
||||
if (nx_emmc_bis_write_block(curr_sct, sct_cnt, buf, false))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -85,13 +85,13 @@ typedef struct _nx_emmc_cal0_t
|
|||
u8 bd_mac[6];
|
||||
u8 crc16_pad4[2];
|
||||
u8 rsvd2[8];
|
||||
u8 acc_offset[6];
|
||||
u16 acc_offset[3];
|
||||
u8 crc16_pad5[2];
|
||||
u8 acc_scale[6];
|
||||
u16 acc_scale[3];
|
||||
u8 crc16_pad6[2];
|
||||
u8 gyro_offset[6];
|
||||
u16 gyro_offset[3];
|
||||
u8 crc16_pad7[2];
|
||||
u8 gyro_scale[6];
|
||||
u16 gyro_scale[3];
|
||||
u8 crc16_pad8[2];
|
||||
char serial_number[0x18];
|
||||
u8 crc16_pad9[8];
|
||||
|
@ -213,11 +213,15 @@ typedef struct _nx_emmc_cal0_t
|
|||
|
||||
// 6.0.0 and up.
|
||||
u8 battery_ver;
|
||||
u8 crc16_pad58[0x1F];
|
||||
u8 crc16_pad58[0xF];
|
||||
|
||||
// 10.0.0 and up.
|
||||
u8 touch_ic_vendor_id;
|
||||
u8 crc16_pad59[0xF];
|
||||
|
||||
// 9.0.0 and up.
|
||||
u32 home_menu_scheme_model;
|
||||
u8 crc16_pad59[0xC];
|
||||
u32 color_model;
|
||||
u8 crc16_pad60[0xC];
|
||||
|
||||
// 10.0.0 and up.
|
||||
u8 console_6axis_sensor_mount_type;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -22,10 +22,18 @@
|
|||
#include <libs/fatfs/ff.h>
|
||||
#include <mem/heap.h>
|
||||
|
||||
#ifndef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
#define SD_DEFAULT_SPEED SD_UHS_SDR104
|
||||
#else
|
||||
#define SD_DEFAULT_SPEED SD_UHS_DDR208
|
||||
#endif
|
||||
|
||||
static bool sd_mounted = false;
|
||||
static bool sd_init_done = false;
|
||||
static bool insertion_event = false;
|
||||
static u16 sd_errors[3] = { 0 }; // Init and Read/Write errors.
|
||||
static u32 sd_mode = SD_UHS_SDR104;
|
||||
static u32 sd_mode = SD_DEFAULT_SPEED;
|
||||
|
||||
|
||||
sdmmc_t sd_sdmmc;
|
||||
sdmmc_storage_t sd_storage;
|
||||
|
@ -54,7 +62,7 @@ u16 *sd_get_error_count()
|
|||
|
||||
bool sd_get_card_removed()
|
||||
{
|
||||
if (sd_init_done && !sdmmc_get_sd_inserted())
|
||||
if (insertion_event && !sdmmc_get_sd_inserted())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -78,7 +86,11 @@ u32 sd_get_mode()
|
|||
int sd_init_retry(bool power_cycle)
|
||||
{
|
||||
u32 bus_width = SDMMC_BUS_WIDTH_4;
|
||||
#ifndef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
u32 type = SDHCI_TIMING_UHS_SDR104;
|
||||
#else
|
||||
u32 type = SDHCI_TIMING_UHS_DDR200;
|
||||
#endif
|
||||
|
||||
// Power cycle SD card.
|
||||
if (power_cycle)
|
||||
|
@ -92,24 +104,45 @@ int sd_init_retry(bool power_cycle)
|
|||
{
|
||||
case SD_INIT_FAIL: // Reset to max.
|
||||
return 0;
|
||||
|
||||
case SD_1BIT_HS25:
|
||||
bus_width = SDMMC_BUS_WIDTH_1;
|
||||
type = SDHCI_TIMING_SD_HS25;
|
||||
break;
|
||||
|
||||
case SD_4BIT_HS25:
|
||||
type = SDHCI_TIMING_SD_HS25;
|
||||
break;
|
||||
|
||||
case SD_UHS_SDR82:
|
||||
type = SDHCI_TIMING_UHS_SDR82;
|
||||
break;
|
||||
|
||||
case SD_UHS_SDR104:
|
||||
type = SDHCI_TIMING_UHS_SDR104;
|
||||
break;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SD_UHS_DDR208:
|
||||
type = SDHCI_TIMING_UHS_DDR200;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
sd_mode = SD_UHS_SDR104;
|
||||
sd_mode = SD_DEFAULT_SPEED;
|
||||
break;
|
||||
}
|
||||
|
||||
return sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, bus_width, type);
|
||||
int res = sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, bus_width, type);
|
||||
if (res)
|
||||
{
|
||||
sd_init_done = true;
|
||||
insertion_event = true;
|
||||
}
|
||||
else
|
||||
sd_init_done = false;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool sd_initialize(bool power_cycle)
|
||||
|
@ -125,7 +158,7 @@ bool sd_initialize(bool power_cycle)
|
|||
return true;
|
||||
else if (!sdmmc_get_sd_inserted()) // SD Card is not inserted.
|
||||
{
|
||||
sd_mode = SD_UHS_SDR104;
|
||||
sd_mode = SD_DEFAULT_SPEED;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -146,7 +179,7 @@ bool sd_initialize(bool power_cycle)
|
|||
|
||||
bool sd_mount()
|
||||
{
|
||||
if (sd_mounted)
|
||||
if (sd_init_done && sd_mounted)
|
||||
return true;
|
||||
|
||||
int res = 0;
|
||||
|
@ -165,8 +198,8 @@ bool sd_mount()
|
|||
}
|
||||
else
|
||||
{
|
||||
sd_init_done = true;
|
||||
res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD.
|
||||
if (!sd_mounted)
|
||||
res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD.
|
||||
if (res == FR_OK)
|
||||
{
|
||||
sd_mounted = true;
|
||||
|
@ -184,19 +217,25 @@ bool sd_mount()
|
|||
|
||||
static void _sd_deinit(bool deinit)
|
||||
{
|
||||
if (deinit && sd_mode == SD_INIT_FAIL)
|
||||
sd_mode = SD_UHS_SDR104;
|
||||
if (deinit)
|
||||
{
|
||||
insertion_event = false;
|
||||
if (sd_mode == SD_INIT_FAIL)
|
||||
sd_mode = SD_DEFAULT_SPEED;
|
||||
}
|
||||
|
||||
if (sd_init_done && sd_mounted)
|
||||
if (sd_init_done)
|
||||
{
|
||||
f_mount(NULL, "0:", 1); // Volume 0 is SD.
|
||||
sd_mounted = false;
|
||||
}
|
||||
if (sd_init_done && deinit)
|
||||
{
|
||||
sdmmc_storage_end(&sd_storage);
|
||||
sd_init_done = false;
|
||||
if (sd_mounted)
|
||||
f_mount(NULL, "0:", 1); // Volume 0 is SD.
|
||||
|
||||
if (deinit)
|
||||
{
|
||||
sdmmc_storage_end(&sd_storage);
|
||||
sd_init_done = false;
|
||||
}
|
||||
}
|
||||
sd_mounted = false;
|
||||
}
|
||||
|
||||
void sd_unmount() { _sd_deinit(false); }
|
||||
|
@ -210,6 +249,9 @@ bool sd_is_gpt()
|
|||
void *sd_file_read(const char *path, u32 *fsize)
|
||||
{
|
||||
FIL fp;
|
||||
if (!sd_get_card_mounted())
|
||||
return NULL;
|
||||
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||
return NULL;
|
||||
|
||||
|
@ -237,6 +279,9 @@ int sd_save_to_file(void *buf, u32 size, const char *filename)
|
|||
{
|
||||
FIL fp;
|
||||
u32 res = 0;
|
||||
if (!sd_get_card_mounted())
|
||||
return FR_DISK_ERR;
|
||||
|
||||
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -22,13 +22,19 @@
|
|||
#include <storage/sdmmc_driver.h>
|
||||
#include <libs/fatfs/ff.h>
|
||||
|
||||
#define SD_BLOCKSIZE 512
|
||||
|
||||
enum
|
||||
{
|
||||
SD_INIT_FAIL = 0,
|
||||
SD_1BIT_HS25 = 1,
|
||||
SD_4BIT_HS25 = 2,
|
||||
SD_UHS_SDR82 = 3,
|
||||
SD_UHS_SDR104 = 4
|
||||
SD_UHS_SDR104 = 4,
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
SD_UHS_DDR208 = 5
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 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
|
||||
|
@ -45,15 +45,14 @@
|
|||
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
|
||||
|
||||
/* OCR bit definitions */
|
||||
#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */
|
||||
#define SD_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */
|
||||
#define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */
|
||||
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
|
||||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
||||
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
||||
#define SD_OCR_BUSY (1 << 31) /* Card Power up Status */
|
||||
#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_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 */
|
||||
#define SD_OCR_XPC (1U << 28) /* SDXC power control */
|
||||
#define SD_OCR_CCS (1U << 30) /* Card Capacity Status */
|
||||
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
|
||||
|
||||
/*
|
||||
* SD_SWITCH argument format:
|
||||
|
@ -90,8 +89,8 @@
|
|||
#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
|
||||
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
||||
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
|
||||
#define SD_SCR_BUS_WIDTH_1 (1<<0)
|
||||
#define SD_SCR_BUS_WIDTH_4 (1<<2)
|
||||
#define SD_SCR_BUS_WIDTH_1 (1U << 0)
|
||||
#define SD_SCR_BUS_WIDTH_4 (1U << 2)
|
||||
|
||||
/*
|
||||
* SD bus widths
|
||||
|
@ -102,33 +101,55 @@
|
|||
/*
|
||||
* SD bus speeds
|
||||
*/
|
||||
#define UHS_SDR12_BUS_SPEED 0
|
||||
#define UHS_SDR12_BUS_SPEED 0
|
||||
#define HIGH_SPEED_BUS_SPEED 1
|
||||
#define UHS_SDR25_BUS_SPEED 1
|
||||
#define UHS_SDR50_BUS_SPEED 2
|
||||
#define UHS_SDR25_BUS_SPEED 1
|
||||
#define UHS_SDR50_BUS_SPEED 2
|
||||
#define UHS_SDR104_BUS_SPEED 3
|
||||
#define UHS_DDR50_BUS_SPEED 4
|
||||
#define HS400_BUS_SPEED 5
|
||||
#define UHS_DDR50_BUS_SPEED 4
|
||||
#define HS400_BUS_SPEED 5
|
||||
|
||||
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
|
||||
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
|
||||
#define SD_MODE_HIGH_SPEED (1U << HIGH_SPEED_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR12 (1U << UHS_SDR12_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR25 (1U << UHS_SDR25_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR50 (1U << UHS_SDR50_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR104 (1U << UHS_SDR104_BUS_SPEED)
|
||||
#define SD_MODE_UHS_DDR50 (1U << UHS_DDR50_BUS_SPEED)
|
||||
|
||||
#define SD_DRIVER_TYPE_B 0x01
|
||||
#define SD_DRIVER_TYPE_A 0x02
|
||||
|
||||
#define SD_SET_CURRENT_LIMIT_200 0
|
||||
#define SD_SET_CURRENT_LIMIT_400 1
|
||||
#define SD_SET_CURRENT_LIMIT_600 2
|
||||
#define SD_SET_CURRENT_LIMIT_800 3
|
||||
#define SD_SET_DRIVER_TYPE_B 0
|
||||
#define SD_SET_DRIVER_TYPE_A 1
|
||||
#define SD_SET_DRIVER_TYPE_C 2
|
||||
#define SD_SET_DRIVER_TYPE_D 3
|
||||
|
||||
#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200)
|
||||
#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400)
|
||||
#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600)
|
||||
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
|
||||
#define SD_DRIVER_TYPE_B (1U << SD_SET_DRIVER_TYPE_B)
|
||||
#define SD_DRIVER_TYPE_A (1U << SD_SET_DRIVER_TYPE_A)
|
||||
#define SD_DRIVER_TYPE_C (1U << SD_SET_DRIVER_TYPE_C)
|
||||
#define SD_DRIVER_TYPE_D (1U << SD_SET_DRIVER_TYPE_D)
|
||||
|
||||
#define SD_SET_POWER_LIMIT_0_72 0
|
||||
#define SD_SET_POWER_LIMIT_1_44 1
|
||||
#define SD_SET_POWER_LIMIT_2_16 2
|
||||
#define SD_SET_POWER_LIMIT_2_88 3
|
||||
|
||||
#define SD_MAX_POWER_0_72 (1U << SD_SET_POWER_LIMIT_0_72)
|
||||
#define SD_MAX_POWER_1_44 (1U << SD_SET_POWER_LIMIT_1_44)
|
||||
#define SD_MAX_POWER_2_16 (1U << SD_SET_POWER_LIMIT_2_16)
|
||||
#define SD_MAX_POWER_2_88 (1U << SD_SET_POWER_LIMIT_2_88)
|
||||
|
||||
#define SD_SET_CMD_SYSTEM_DEF 0
|
||||
#define SD_SET_CMD_SYSTEM_MEC 1
|
||||
#define SD_SET_CMD_SYSTEM_OTP 3
|
||||
#define SD_SET_CMD_SYSTEM_OSD 3
|
||||
#define SD_SET_CMD_SYSTEM_VND 14
|
||||
#define UHS_DDR200_BUS_SPEED SD_SET_CMD_SYSTEM_VND
|
||||
|
||||
#define SD_CMD_SYSTEM_DEF (1U << SD_SET_CMD_SYSTEM_DEF)
|
||||
#define SD_CMD_SYSTEM_MEC (1U << SD_SET_CMD_SYSTEM_MEC)
|
||||
#define SD_CMD_SYSTEM_OTP (1U << SD_SET_CMD_SYSTEM_OTP)
|
||||
#define SD_CMD_SYSTEM_OSD (1U << SD_SET_CMD_SYSTEM_OSD)
|
||||
#define SD_CMD_SYSTEM_VND (1U << SD_SET_CMD_SYSTEM_VND)
|
||||
#define SD_MODE_UHS_DDR200 SD_CMD_SYSTEM_VND
|
||||
|
||||
/*
|
||||
* SD_SWITCH mode
|
||||
|
@ -140,11 +161,14 @@
|
|||
* SD_SWITCH function groups
|
||||
*/
|
||||
#define SD_SWITCH_GRP_ACCESS 0
|
||||
#define SD_SWITCH_GRP_CMDSYS 1
|
||||
#define SD_SWITCH_GRP_DRVSTR 2
|
||||
#define SD_SWITCH_GRP_PWRLIM 3
|
||||
|
||||
/*
|
||||
* SD_SWITCH access modes
|
||||
*/
|
||||
#define SD_SWITCH_ACCESS_DEF 0
|
||||
#define SD_SWITCH_ACCESS_HS 1
|
||||
#define SD_SWITCH_ACCESS_HS 1
|
||||
|
||||
#endif /* SD_DEF_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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,
|
||||
|
@ -129,10 +129,7 @@ typedef struct _mmc_csd
|
|||
u16 cmdclass;
|
||||
u32 c_size;
|
||||
u32 r2w_factor;
|
||||
u32 max_dtr;
|
||||
u32 erase_size; /* In sectors */
|
||||
u32 read_blkbits;
|
||||
u32 write_blkbits;
|
||||
u32 capacity;
|
||||
u8 write_protect;
|
||||
u16 busspeed;
|
||||
|
@ -186,6 +183,7 @@ typedef struct _sdmmc_storage_t
|
|||
int is_low_voltage;
|
||||
u32 partition;
|
||||
int initialized;
|
||||
u32 card_power_limit;
|
||||
u8 raw_cid[0x10];
|
||||
u8 raw_csd[0x10];
|
||||
u8 raw_scr[8];
|
||||
|
@ -209,6 +207,9 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
|||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
||||
|
||||
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf);
|
||||
|
||||
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf);
|
||||
int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf);
|
||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -27,16 +27,15 @@
|
|||
#include <soc/hw_init.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
//#define ERROR_EXTRA_PRINTING
|
||||
#define DPRINTF(...)
|
||||
|
||||
#ifdef BDK_SDMMC_OC_AND_EXTRA_PRINT
|
||||
#ifdef BDK_SDMMC_EXTRA_PRINT
|
||||
#define ERROR_EXTRA_PRINTING
|
||||
#define SDMMC_EMMC_OC
|
||||
#endif
|
||||
|
||||
/*! SCMMC controller base addresses. */
|
||||
|
@ -88,9 +87,9 @@ static int _sdmmc_set_io_power(sdmmc_t *sdmmc, u32 power)
|
|||
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc)
|
||||
{
|
||||
u32 h = sdmmc->regs->hostctl;
|
||||
if (h & SDHCI_CTRL_8BITBUS)
|
||||
if (h & SDHCI_CTRL_8BITBUS) // eMMC only (or UHS-II).
|
||||
return SDMMC_BUS_WIDTH_8;
|
||||
if (h & SDHCI_CTRL_4BITBUS)
|
||||
if (h & SDHCI_CTRL_4BITBUS) // SD only.
|
||||
return SDMMC_BUS_WIDTH_4;
|
||||
return SDMMC_BUS_WIDTH_1;
|
||||
}
|
||||
|
@ -102,28 +101,28 @@ void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)
|
|||
if (bus_width == SDMMC_BUS_WIDTH_1)
|
||||
sdmmc->regs->hostctl = host_control;
|
||||
else if (bus_width == SDMMC_BUS_WIDTH_4)
|
||||
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_4BITBUS;
|
||||
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_4BITBUS; // SD only.
|
||||
else if (bus_width == SDMMC_BUS_WIDTH_8)
|
||||
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS;
|
||||
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS; // eMMC only (or UHS-II).
|
||||
}
|
||||
|
||||
void sdmmc_save_tap_value(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16;
|
||||
sdmmc->venclkctl_tap = (sdmmc->regs->venclkctl & 0xFF0000) >> 16;
|
||||
sdmmc->venclkctl_set = 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
{
|
||||
const u32 dqs_trim_val = 0x28;
|
||||
const u32 tap_values_t210[] = { 4, 0, 3, 0 };
|
||||
const u32 dqs_trim_val = 40; // 24 if HS533/HS667.
|
||||
const u8 tap_values_t210[4] = { 4, 0, 3, 0 };
|
||||
|
||||
u32 tap_val = 0;
|
||||
|
||||
if (type == SDHCI_TIMING_MMC_HS400)
|
||||
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8);
|
||||
|
||||
sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
if (type == SDHCI_TIMING_MMC_HS400)
|
||||
{
|
||||
|
@ -140,9 +139,9 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_commit_changes(sdmmc_t *sdmmc)
|
||||
static void _sdmmc_commit_changes(sdmmc_t *sdmmc)
|
||||
{
|
||||
return sdmmc->regs->clkcon;
|
||||
(void)sdmmc->regs->clkcon;
|
||||
}
|
||||
|
||||
static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
|
||||
|
@ -173,8 +172,8 @@ static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
|
|||
break;
|
||||
|
||||
case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16, B01: PU:10, PD:10.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) =
|
||||
(APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | (sdmmc->t210b01 ? 0xA28 : 0x1040);
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) |
|
||||
(sdmmc->t210b01 ? 0xA28 : 0x1040);
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
|
||||
break;
|
||||
}
|
||||
|
@ -189,21 +188,21 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
|||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
// Enable E_INPUT power.
|
||||
if (!(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD))
|
||||
// Enable E_INPUT (SD) or Disable E_PWRD (eMMC) power.
|
||||
if (!(sdmmc->regs->sdmemcmppadctl & SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD))
|
||||
{
|
||||
sdmmc->regs->sdmemcmppadctl |= TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD;
|
||||
sdmmc->regs->sdmemcmppadctl |= SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
// Enable auto calibration and start auto configuration.
|
||||
sdmmc->regs->autocalcfg |= TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE | TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START;
|
||||
sdmmc->regs->autocalcfg |= SDHCI_TEGRA_AUTOCAL_ENABLE | SDHCI_TEGRA_AUTOCAL_START;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(2);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 10;
|
||||
while (sdmmc->regs->autocalsts & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE)
|
||||
while (sdmmc->regs->autocalsts & SDHCI_TEGRA_AUTOCAL_ACTIVE)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
|
@ -215,33 +214,29 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
|
|||
#ifdef ERROR_EXTRA_PRINTING
|
||||
// Check if Comp pad is open or short to ground.
|
||||
// SDMMC1: CZ pads - T210/T210B01: 7-bit/5-bit. SDMMC2/4: LV_CZ pads - 5-bit.
|
||||
u8 code_mask = (sdmmc->t210b01 || sdmmc->id != SDMMC_1) ? 0x1F : 0x7F;
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask;
|
||||
// Use 0x1F mask for all.
|
||||
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
|
||||
if (!autocal_pu_status)
|
||||
EPRINTF("SDMMC: Comp Pad short to gnd!");
|
||||
else if (autocal_pu_status == code_mask)
|
||||
EPRINTF("SDMMC: Comp Pad open!");
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1);
|
||||
else if (autocal_pu_status == 0x1F)
|
||||
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
|
||||
#endif
|
||||
|
||||
// In case auto calibration fails, we load suggested standard values.
|
||||
if (!timeout)
|
||||
{
|
||||
sdmmc->regs->autocalcfg &= ~SDHCI_TEGRA_AUTOCAL_ENABLE;
|
||||
_sdmmc_pad_config_fallback(sdmmc, power);
|
||||
sdmmc->regs->autocalcfg &= ~TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE;
|
||||
}
|
||||
|
||||
// Disable E_INPUT to conserve power.
|
||||
sdmmc->regs->sdmemcmppadctl &= ~TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD;
|
||||
// Disable E_INPUT (SD) or enable E_PWRD (eMMC) to conserve power.
|
||||
sdmmc->regs->sdmemcmppadctl &= ~SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD;
|
||||
|
||||
if(should_enable_sd_clock)
|
||||
if (should_enable_sd_clock)
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
#ifdef SDMMC_EMMC_OC
|
||||
static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc, bool overclock)
|
||||
#else
|
||||
static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
|
||||
#endif
|
||||
{
|
||||
int result = 1, should_disable_sd_clock = 0;
|
||||
|
||||
|
@ -251,17 +246,15 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
|
|||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
}
|
||||
|
||||
#ifdef SDMMC_EMMC_OC
|
||||
// Add -4 TX_DLY_CODE_OFFSET if HS533.
|
||||
if (sdmmc->id == SDMMC_4 && overclock)
|
||||
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7);
|
||||
#endif
|
||||
// Add -4 TX_DLY_CODE_OFFSET if HS533/HS667.
|
||||
// if (sdmmc->id == SDMMC_4 && sdmmc->card_clock > 208000)
|
||||
// sdmmc->regs->vendllctl0 = sdmmc->regs->vendllctl0 &= 0xFFFFC07F | (0x7C << 7);
|
||||
|
||||
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
|
||||
sdmmc->regs->vendllcalcfg |= SDHCI_TEGRA_DLLCAL_CALIBRATE;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 5;
|
||||
while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE)
|
||||
while (sdmmc->regs->vendllcalcfg & SDHCI_TEGRA_DLLCAL_CALIBRATE)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
|
@ -271,7 +264,7 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
|
|||
}
|
||||
|
||||
timeout = get_tmr_ms() + 10;
|
||||
while (sdmmc->regs->vendllcalcfgsts & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE)
|
||||
while (sdmmc->regs->vendllcalcfgsts & SDHCI_TEGRA_DLLCAL_ACTIVE)
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
|
@ -286,7 +279,7 @@ out:;
|
|||
return result;
|
||||
}
|
||||
|
||||
static void _sdmmc_reset(sdmmc_t *sdmmc)
|
||||
static void _sdmmc_reset_cmd_data(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
@ -304,6 +297,13 @@ static void _sdmmc_reset_all(sdmmc_t *sdmmc)
|
|||
;
|
||||
}
|
||||
|
||||
void sdmmc_setup_drv_type(sdmmc_t *sdmmc, u32 type)
|
||||
{
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_DRV_TYPE_MASK)) | SDHCI_CTRL_DRV_TYPE(type);
|
||||
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
}
|
||||
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
||||
{
|
||||
// Disable the SD clock if it was enabled, and reenable it later.
|
||||
|
@ -316,7 +316,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||
|
||||
_sdmmc_config_tap_val(sdmmc, type);
|
||||
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -335,28 +335,35 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_UHS_SDR50: // T210 Errata for SDR50, the host must be set to SDR104.
|
||||
case SDHCI_TIMING_UHS_SDR50: // T210 Errata: the host must be set to SDR104 to WAR a CRC issue.
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;
|
||||
case SDHCI_TIMING_MMC_HS100:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR104_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
// Non standard.
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR25_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR25_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR12_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR12_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SDHCI_TIMING_UHS_DDR200:
|
||||
#endif
|
||||
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_DDR50_BUS_SPEED;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
|
||||
break;
|
||||
}
|
||||
|
@ -367,31 +374,22 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||
u16 divisor;
|
||||
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
|
||||
clock_sdmmc_config_clock_source(&clock, sdmmc->id, clock);
|
||||
sdmmc->divisor = (clock + divisor - 1) / divisor;
|
||||
sdmmc->card_clock = (clock + divisor - 1) / divisor;
|
||||
|
||||
//if divisor != 1 && divisor << 31 -> error
|
||||
// (divisor != 1) && (divisor & 1) -> error
|
||||
|
||||
u16 div = divisor >> 1;
|
||||
divisor = 0;
|
||||
if (div > 0xFF)
|
||||
divisor = div >> SDHCI_DIVIDER_SHIFT;
|
||||
u16 div_lo = divisor >> 1;
|
||||
u16 div_hi = div_lo >> 8;
|
||||
|
||||
sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK))
|
||||
| (div << SDHCI_DIVIDER_SHIFT) | (divisor << SDHCI_DIVIDER_HI_SHIFT);
|
||||
sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK)) |
|
||||
(div_lo << SDHCI_DIV_LO_SHIFT) | (div_hi << SDHCI_DIV_HI_SHIFT);
|
||||
|
||||
// Enable the SD clock again.
|
||||
if (should_enable_sd_clock)
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
|
||||
if (type == SDHCI_TIMING_MMC_HS400)
|
||||
{
|
||||
#ifdef SDMMC_EMMC_OC
|
||||
bool overclock_en = clock > 208000;
|
||||
return _sdmmc_dll_cal_execute(sdmmc, overclock_en);
|
||||
#else
|
||||
return _sdmmc_dll_cal_execute(sdmmc);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -521,10 +519,10 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
|
|||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while(sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT)
|
||||
while (sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT)
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -534,7 +532,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
|
|||
while (sdmmc->regs->prnsts & SDHCI_DATA_INHIBIT)
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -547,10 +545,10 @@ static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc)
|
|||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL_MASK))
|
||||
while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL))
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -594,7 +592,7 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
|
|||
if (cmd->check_busy)
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
else
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_2:
|
||||
|
@ -611,8 +609,9 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
|
|||
|
||||
if (is_data_present)
|
||||
cmdflags |= SDHCI_CMD_DATA;
|
||||
|
||||
sdmmc->regs->argument = cmd->arg;
|
||||
sdmmc->regs->cmdreg = (cmd->cmd << 8) | cmdflags;
|
||||
sdmmc->regs->cmdreg = SDHCI_CMD_IDX(cmd->cmd) | cmdflags;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -627,10 +626,8 @@ static void _sdmmc_send_tuning_cmd(sdmmc_t *sdmmc, u32 cmd)
|
|||
_sdmmc_send_cmd(sdmmc, &cmdbuf, true);
|
||||
}
|
||||
|
||||
static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
||||
static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd, u32 tap)
|
||||
{
|
||||
if (sdmmc->powersave_enabled)
|
||||
return 0;
|
||||
if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, true))
|
||||
return 0;
|
||||
|
||||
|
@ -640,11 +637,21 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
|||
sdmmc->regs->norintsts = sdmmc->regs->norintsts;
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
// Set tap if manual tuning.
|
||||
if (tap != HW_TAP_TUNING)
|
||||
{
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap << 16);
|
||||
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
}
|
||||
#endif
|
||||
|
||||
_sdmmc_send_tuning_cmd(sdmmc, cmd);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep(1);
|
||||
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
@ -657,59 +664,170 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
|
|||
sdmmc->regs->norintsts = SDHCI_INT_DATA_AVAIL;
|
||||
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
|
||||
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
typedef struct _sdmmc_manual_tuning_t
|
||||
{
|
||||
u32 result[8];
|
||||
u32 num_iter;
|
||||
u32 tap_start;
|
||||
u32 tap_end;
|
||||
} sdmmc_manual_tuning_t;
|
||||
|
||||
static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *tuning)
|
||||
{
|
||||
u32 tap_start = INVALID_TAP;
|
||||
u32 win_size = 0;
|
||||
u32 best_tap = 0;
|
||||
u32 best_size = 0;
|
||||
|
||||
for (u32 i = 0; i < tuning->num_iter; i++)
|
||||
{
|
||||
u32 iter_end = i == (tuning->num_iter - 1) ? 1 : 0;
|
||||
u32 stable = tuning->result[i / 32] & BIT(i % 32);
|
||||
if (stable && !iter_end)
|
||||
{
|
||||
if (tap_start == INVALID_TAP)
|
||||
tap_start = i;
|
||||
|
||||
win_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tap_start != INVALID_TAP)
|
||||
{
|
||||
u32 tap_end = !iter_end ? (i - 1) : i;
|
||||
|
||||
// Check if window is wider.
|
||||
if (win_size > best_size)
|
||||
{
|
||||
best_tap = (tap_start + tap_end) / 2;
|
||||
best_size = win_size + iter_end;
|
||||
}
|
||||
|
||||
tap_start = INVALID_TAP;
|
||||
win_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if failed or window too small.
|
||||
if (!best_tap || best_size < SAMPLING_WINDOW_SIZE_MIN)
|
||||
return 0;
|
||||
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
// Set tap.
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (best_tap << 16);
|
||||
|
||||
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SD Card DDR200 (DDR208) support
|
||||
*
|
||||
* On Tegra X1, that can be done with DDR50 host mode.
|
||||
* That's because HS400 4-bit or HS400 generally, is not supported on SDMMC1/3.
|
||||
* And also, tuning can't be done automatically on any DDR mode.
|
||||
* So it needs to be done manually and selected tap will be applied from the biggest
|
||||
* sampling window.
|
||||
* That allows DDR200 support on every DDR200 sd card, other than the original maker
|
||||
* of DDR200, Sandisk. Since Sandisk cards mandate DLL syncing.
|
||||
*/
|
||||
static int sdmmc_tuning_execute_ddr200(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc_manual_tuning_t manual_tuning = { 0 };
|
||||
manual_tuning.num_iter = 128;
|
||||
|
||||
sdmmc->regs->ventunctl1 = 0; // step_size 1.
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | (2 << 13); // 128 Tries.
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
|
||||
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
|
||||
|
||||
for (u32 i = 0; i < manual_tuning.num_iter; i++)
|
||||
{
|
||||
_sdmmc_tuning_execute_once(sdmmc, MMC_SEND_TUNING_BLOCK, i);
|
||||
|
||||
// Save result for manual tuning.
|
||||
int sampled = (sdmmc->regs->hostctl2 >> SDHCI_CTRL_TUNED_CLK_SHIFT) & 1;
|
||||
manual_tuning.result[i / 32] |= sampled << (i % 32);
|
||||
|
||||
if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))
|
||||
break;
|
||||
}
|
||||
|
||||
return _sdmmc_manual_tuning_set_tap(sdmmc, &manual_tuning);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
|
||||
{
|
||||
u32 max = 0, flag = 0;
|
||||
u32 num_iter, flag;
|
||||
|
||||
if (sdmmc->powersave_enabled)
|
||||
return 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
max = 128;
|
||||
num_iter = 128;
|
||||
flag = (2 << 13); // 128 iterations.
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
case SDHCI_TIMING_MMC_HS102:
|
||||
max = 256;
|
||||
case SDHCI_TIMING_UHS_DDR50: // HW tuning is not supported on DDR modes. But it sets tap to 0 which is proper.
|
||||
case SDHCI_TIMING_MMC_HS100:
|
||||
num_iter = 256;
|
||||
flag = (4 << 13); // 256 iterations.
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
return 1;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SDHCI_TIMING_UHS_DDR200:
|
||||
return sdmmc_tuning_execute_ddr200(sdmmc);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdmmc->regs->ventunctl1 = 0; // step_size 1.
|
||||
sdmmc->regs->ventunctl1 = 0; // step_size 1.
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries.
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
|
||||
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries.
|
||||
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
|
||||
sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
|
||||
|
||||
for (u32 i = 0; i < max; i++)
|
||||
for (u32 i = 0; i < num_iter; i++)
|
||||
{
|
||||
_sdmmc_tuning_execute_once(sdmmc, cmd);
|
||||
_sdmmc_tuning_execute_once(sdmmc, cmd, HW_TAP_TUNING);
|
||||
|
||||
if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))
|
||||
break;
|
||||
}
|
||||
|
@ -734,14 +852,15 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
|
|||
|
||||
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;
|
||||
sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE;
|
||||
// Enable 32/64bit addressing if used (sysad. if blkcnt it fallbacks to 16bit).
|
||||
sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN;
|
||||
|
||||
if (!(sdmmc->regs->capareg & SDHCI_CAN_64BIT))
|
||||
if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT))
|
||||
return 0;
|
||||
|
||||
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
|
||||
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK;
|
||||
sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 0xE;
|
||||
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
|
||||
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK; // Use SDMA. Host V4 enabled so adma address regs in use.
|
||||
sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 14; // TMCLK * 2^27.
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -766,8 +885,8 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
|
|||
{
|
||||
if (!sdmmc->t210b01)
|
||||
{
|
||||
off_pd = 123;
|
||||
off_pu = 123;
|
||||
off_pd = 0x7B; // -5.
|
||||
off_pu = 0x7B; // -5.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -779,7 +898,7 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
|
|||
{
|
||||
if (!sdmmc->t210b01)
|
||||
{
|
||||
off_pd = 125;
|
||||
off_pd = 0x7D; // -3.
|
||||
off_pu = 0;
|
||||
}
|
||||
}
|
||||
|
@ -806,12 +925,12 @@ static void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)
|
|||
sdmmc->regs->norintstsen &= ~(SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
|
||||
}
|
||||
|
||||
static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
||||
{
|
||||
u16 norintsts = sdmmc->regs->norintsts;
|
||||
u16 errintsts = sdmmc->regs->errintsts;
|
||||
|
||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
|
||||
if (pout)
|
||||
*pout = norintsts;
|
||||
|
@ -820,7 +939,7 @@ DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
|||
if (norintsts & SDHCI_INT_ERROR)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
||||
EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X\n", sdmmc->id + 1, norintsts, errintsts);
|
||||
#endif
|
||||
sdmmc->regs->errintsts = errintsts;
|
||||
return SDMMC_MASKINT_ERROR;
|
||||
|
@ -841,12 +960,12 @@ static int _sdmmc_wait_response(sdmmc_t *sdmmc)
|
|||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (true)
|
||||
{
|
||||
int result = _sdmmc_check_mask_interrupt(sdmmc, NULL, SDHCI_INT_RESPONSE);
|
||||
u32 result = _sdmmc_check_mask_interrupt(sdmmc, NULL, SDHCI_INT_RESPONSE);
|
||||
if (result == SDMMC_MASKINT_MASKED)
|
||||
break;
|
||||
if (result != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout)
|
||||
{
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -896,11 +1015,11 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
|||
should_disable_sd_clock = true;
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
}
|
||||
|
||||
int result = _sdmmc_stop_transmission_inner(sdmmc, rsp);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
|
||||
if (should_disable_sd_clock)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
|
@ -908,7 +1027,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
{
|
||||
if (!req->blksize || !req->num_sectors)
|
||||
return 0;
|
||||
|
@ -925,19 +1044,19 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
|||
sdmmc->regs->admaaddr = admaaddr;
|
||||
sdmmc->regs->admaaddr_hi = 0;
|
||||
|
||||
sdmmc->dma_addr_next = (admaaddr + 0x80000) & 0xFFF80000;
|
||||
sdmmc->dma_addr_next = ALIGN_DOWN((admaaddr + SZ_512K), SZ_512K);
|
||||
|
||||
sdmmc->regs->blksize = req->blksize | 0x7000; // DMA 512KB (Detects A18 carry out).
|
||||
sdmmc->regs->blkcnt = blkcnt;
|
||||
sdmmc->regs->blksize = req->blksize | (7u << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
|
||||
sdmmc->regs->blkcnt = blkcnt;
|
||||
|
||||
if (blkcnt_out)
|
||||
*blkcnt_out = blkcnt;
|
||||
|
||||
u32 trnmode = SDHCI_TRNS_DMA;
|
||||
u32 trnmode = SDHCI_TRNS_DMA | SDHCI_TRNS_RTYPE_R1;
|
||||
|
||||
// Set mulitblock request.
|
||||
// Set multiblock request.
|
||||
if (req->is_multi_block)
|
||||
trnmode = SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DMA;
|
||||
trnmode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN;
|
||||
|
||||
// Set request direction.
|
||||
if (!req->is_write)
|
||||
|
@ -954,7 +1073,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int _sdmmc_update_dma(sdmmc_t *sdmmc)
|
||||
static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
|
||||
{
|
||||
u16 blkcnt = 0;
|
||||
do
|
||||
|
@ -963,13 +1082,13 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
|
|||
u32 timeout = get_tmr_ms() + 1500;
|
||||
do
|
||||
{
|
||||
int result = 0;
|
||||
u32 result = SDMMC_MASKINT_MASKED;
|
||||
while (true)
|
||||
{
|
||||
u16 intr = 0;
|
||||
result = _sdmmc_check_mask_interrupt(sdmmc, &intr,
|
||||
SDHCI_INT_DATA_END | SDHCI_INT_DMA_END);
|
||||
if (result < 0)
|
||||
if (result != SDMMC_MASKINT_MASKED)
|
||||
break;
|
||||
|
||||
if (intr & SDHCI_INT_DATA_END)
|
||||
|
@ -980,21 +1099,24 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
|
|||
// Update DMA.
|
||||
sdmmc->regs->admaaddr = sdmmc->dma_addr_next;
|
||||
sdmmc->regs->admaaddr_hi = 0;
|
||||
sdmmc->dma_addr_next += 0x80000;
|
||||
sdmmc->dma_addr_next += SZ_512K;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != SDMMC_MASKINT_NOERROR)
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("%08X!", result);
|
||||
EPRINTFARGS("SDMMC%d: int error!", sdmmc->id + 1);
|
||||
#endif
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
} while (get_tmr_ms() < timeout);
|
||||
} while (sdmmc->regs->blkcnt != blkcnt);
|
||||
|
||||
_sdmmc_reset(sdmmc);
|
||||
_sdmmc_reset_cmd_data(sdmmc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1008,16 +1130,16 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||
bool is_data_present = false;
|
||||
if (req)
|
||||
{
|
||||
if (!_sdmmc_config_dma(sdmmc, &blkcnt, req))
|
||||
if (!_sdmmc_config_sdma(sdmmc, &blkcnt, req))
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTF("SDMMC: DMA Wrong cfg!");
|
||||
EPRINTFARGS("SDMMC%d: DMA Wrong cfg!", sdmmc->id + 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Flush cache before starting the transfer.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
is_data_present = true;
|
||||
}
|
||||
|
@ -1027,7 +1149,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||
if (!_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
|
||||
{
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
EPRINTFARGS("SDMMC: Wrong Response type %08X!", cmd->rsp_type);
|
||||
EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -1035,9 +1157,9 @@ 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)
|
||||
EPRINTF("SDMMC: Transfer timeout!");
|
||||
EPRINTFARGS("SDMMC%d: Transfer timeout!", sdmmc->id + 1);
|
||||
#endif
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
if (result)
|
||||
{
|
||||
|
@ -1047,15 +1169,15 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
|||
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
if (!result)
|
||||
EPRINTF("SDMMC: Unknown response type!");
|
||||
EPRINTFARGS("SDMMC%d: Unknown response type!", sdmmc->id + 1);
|
||||
#endif
|
||||
}
|
||||
if (req && result)
|
||||
{
|
||||
result = _sdmmc_update_dma(sdmmc);
|
||||
result = _sdmmc_update_sdma(sdmmc);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
if (!result)
|
||||
EPRINTF("SDMMC: DMA Update failed!");
|
||||
EPRINTFARGS("SDMMC%d: DMA Update failed!", sdmmc->id + 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1066,8 +1188,8 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
|||
{
|
||||
if (req)
|
||||
{
|
||||
// Flush cache after transfer.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
// Invalidate cache after transfer.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
if (blkcnt_out)
|
||||
*blkcnt_out = blkcnt;
|
||||
|
@ -1081,7 +1203,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
|
|||
result = _sdmmc_wait_card_busy(sdmmc);
|
||||
#ifdef ERROR_EXTRA_PRINTING
|
||||
if (!result)
|
||||
EPRINTF("SDMMC: Busy timeout!");
|
||||
EPRINTFARGS("SDMMC%d: Busy timeout!", sdmmc->id + 1);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -1149,12 +1271,11 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
|
|||
// Configure SD card detect.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up.
|
||||
APB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0;
|
||||
gpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
|
||||
gpio_direction_input(GPIO_PORT_Z, GPIO_PIN_1);
|
||||
usleep(100);
|
||||
|
||||
// Check if SD card is inserted.
|
||||
if(!sdmmc_get_sd_inserted())
|
||||
if (!sdmmc_get_sd_inserted())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -1170,6 +1291,7 @@ static int _sdmmc_config_sdmmc1(bool t210b01)
|
|||
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;
|
||||
|
||||
// Configure SDMMC1 CLK pinmux, based on state and SoC type.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) &= ~PINMUX_SCHMT;
|
||||
if (PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) != (PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN)) // Check if CLK pad is already configured.
|
||||
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | (t210b01 ? PINMUX_PULL_NONE : PINMUX_PULL_DOWN);
|
||||
|
||||
|
@ -1185,20 +1307,20 @@ 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;
|
||||
usleep(1000);
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
|
||||
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
|
||||
|
||||
// Set enable SD card power.
|
||||
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;
|
||||
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
|
||||
|
||||
// Set enable SD card power.
|
||||
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Pull down.
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO);
|
||||
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
|
||||
usleep(10000);
|
||||
|
||||
// Enable SD card IO power.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO2, 3300000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO2, true);
|
||||
|
@ -1235,7 +1357,7 @@ static void _sdmmc_config_emmc(u32 id, bool t210b01)
|
|||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
|
||||
// Set default pad cfg.
|
||||
if (t210b01)
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS powedown.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS weak pull up/down.
|
||||
// Enable schmitt trigger.
|
||||
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1;
|
||||
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
|
||||
|
@ -1243,15 +1365,15 @@ static void _sdmmc_config_emmc(u32 id, bool t210b01)
|
|||
}
|
||||
}
|
||||
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable)
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
|
||||
{
|
||||
u32 clock;
|
||||
u16 divisor;
|
||||
u8 vref_sel = 7;
|
||||
|
||||
const u32 trim_values_t210[] = { 2, 8, 3, 8 };
|
||||
const u32 trim_values_t210b01[] = { 14, 13, 15, 13 };
|
||||
const u32 *trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210;
|
||||
const u8 trim_values_t210[4] = { 2, 8, 3, 8 };
|
||||
const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 };
|
||||
const u8 *trim_values;
|
||||
|
||||
if (id > SDMMC_4 || id == SDMMC_3)
|
||||
return 0;
|
||||
|
@ -1263,6 +1385,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p
|
|||
sdmmc->clock_stopped = 1;
|
||||
sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
|
||||
|
||||
trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210;
|
||||
|
||||
// Do specific SDMMC HW configuration.
|
||||
switch (id)
|
||||
{
|
||||
|
@ -1298,11 +1422,10 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p
|
|||
sdmmc->clock_stopped = 0;
|
||||
|
||||
// Set default pad IO trimming configuration.
|
||||
sdmmc->regs->iospare |= 0x80000; // Enable muxing.
|
||||
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB; // Set Band Gap VREG to supply DLL.
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | (trim_values[sdmmc->id] << 24);
|
||||
sdmmc->regs->sdmemcmppadctl =
|
||||
(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | vref_sel;
|
||||
sdmmc->regs->iospare |= BIT(19); // Enable 1 cycle delayed cmd_oen.
|
||||
sdmmc->regs->veniotrimctl &= ~BIT(2); // Set Band Gap VREG to supply DLL.
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | ((u32)trim_values[sdmmc->id] << 24);
|
||||
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & ~SDHCI_TEGRA_PADCTRL_VREF_SEL_MASK) | vref_sel;
|
||||
|
||||
// Configure auto calibration values.
|
||||
if (!_sdmmc_autocal_config_offset(sdmmc, power))
|
||||
|
@ -1319,7 +1442,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p
|
|||
|
||||
if (sdmmc_setup_clock(sdmmc, type))
|
||||
{
|
||||
sdmmc_card_clock_powersave(sdmmc, powersave_enable);
|
||||
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_DISABLE);
|
||||
_sdmmc_card_clock_enable(sdmmc);
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
||||
|
@ -1405,11 +1528,11 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
|||
should_disable_sd_clock = 1;
|
||||
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
}
|
||||
|
||||
int result = _sdmmc_execute_cmd_inner(sdmmc, cmd, req, blkcnt_out);
|
||||
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
|
||||
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
|
||||
|
||||
if (should_disable_sd_clock)
|
||||
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
|
||||
|
@ -1419,10 +1542,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
|
|||
|
||||
int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
|
||||
{
|
||||
if(sdmmc->id != SDMMC_1)
|
||||
return 0;
|
||||
|
||||
if (!sdmmc_setup_clock(sdmmc, SDHCI_TIMING_UHS_SDR12))
|
||||
if (sdmmc->id != SDMMC_1)
|
||||
return 0;
|
||||
|
||||
_sdmmc_commit_changes(sdmmc);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -22,21 +22,16 @@
|
|||
#include <storage/sdmmc_t210.h>
|
||||
|
||||
/*! SDMMC controller IDs. */
|
||||
#define SDMMC_1 0
|
||||
#define SDMMC_2 1
|
||||
#define SDMMC_3 2
|
||||
#define SDMMC_4 3
|
||||
#define SDMMC_1 0 // Version 4.00.
|
||||
#define SDMMC_2 1 // Version 5.0 + SW CQE + Enhanced Strobe.
|
||||
#define SDMMC_3 2 // Version 4.00.
|
||||
#define SDMMC_4 3 // Version 5.0 + SW CQE + Enhanced Strobe.
|
||||
|
||||
/*! SDMMC power types. */
|
||||
#define SDMMC_POWER_OFF 0
|
||||
#define SDMMC_POWER_1_8 1
|
||||
#define SDMMC_POWER_3_3 2
|
||||
|
||||
/*! SDMMC bus widths. */
|
||||
#define SDMMC_BUS_WIDTH_1 0
|
||||
#define SDMMC_BUS_WIDTH_4 1
|
||||
#define SDMMC_BUS_WIDTH_8 2
|
||||
|
||||
/*! SDMMC response types. */
|
||||
#define SDMMC_RSP_TYPE_0 0
|
||||
#define SDMMC_RSP_TYPE_1 1
|
||||
|
@ -45,131 +40,203 @@
|
|||
#define SDMMC_RSP_TYPE_4 4
|
||||
#define SDMMC_RSP_TYPE_5 5
|
||||
|
||||
/*! SDMMC bus widths. */
|
||||
#define SDMMC_BUS_WIDTH_1 0
|
||||
#define SDMMC_BUS_WIDTH_4 1
|
||||
#define SDMMC_BUS_WIDTH_8 2
|
||||
|
||||
/*! SDMMC mask interrupt status. */
|
||||
#define SDMMC_MASKINT_MASKED 0
|
||||
#define SDMMC_MASKINT_NOERROR -1
|
||||
#define SDMMC_MASKINT_ERROR -2
|
||||
#define SDMMC_MASKINT_NOERROR 1
|
||||
#define SDMMC_MASKINT_ERROR 2
|
||||
|
||||
/*! SDMMC present state. */
|
||||
#define SDHCI_CMD_INHIBIT 0x1
|
||||
#define SDHCI_DATA_INHIBIT 0x2
|
||||
#define SDHCI_DOING_WRITE 0x100
|
||||
#define SDHCI_DOING_READ 0x200
|
||||
#define SDHCI_SPACE_AVAILABLE 0x400
|
||||
#define SDHCI_DATA_AVAILABLE 0x800
|
||||
#define SDHCI_CARD_PRESENT 0x10000
|
||||
#define SDHCI_CD_STABLE 0x20000
|
||||
#define SDHCI_CD_LVL 0x40000
|
||||
#define SDHCI_WRITE_PROTECT 0x80000
|
||||
/*! SDMMC present state. 0x24. */
|
||||
#define SDHCI_CMD_INHIBIT BIT(0)
|
||||
#define SDHCI_DATA_INHIBIT BIT(1)
|
||||
#define SDHCI_DAT_LINE_ACTIVE BIT(2)
|
||||
#define SDHCI_RETUNING_REQUEST BIT(3)
|
||||
#define SDHCI_EMMC_LINE_LVL_MASK (0xFU << 4)
|
||||
#define SDHCI_DATA_4_LVL BIT(4) // eMMC only.
|
||||
#define SDHCI_DATA_5_LVL BIT(5) // eMMC only.
|
||||
#define SDHCI_DATA_6_LVL BIT(6) // eMMC only.
|
||||
#define SDHCI_DATA_7_LVL BIT(7) // eMMC only.
|
||||
#define SDHCI_DOING_WRITE BIT(8)
|
||||
#define SDHCI_DOING_READ BIT(9) // SD only.
|
||||
#define SDHCI_SPACE_AVAILABLE BIT(10) // Write buffer empty.
|
||||
#define SDHCI_DATA_AVAILABLE BIT(11) // Read buffer has data.
|
||||
#define SDHCI_CARD_PRESENT BIT(16)
|
||||
#define SDHCI_CD_STABLE BIT(17)
|
||||
#define SDHCI_CD_LVL BIT(18)
|
||||
#define SDHCI_WRITE_PROTECT BIT(19)
|
||||
#define SDHCI_DATA_LVL_MASK 0xF00000
|
||||
#define SDHCI_DATA_0_LVL_MASK 0x100000
|
||||
#define SDHCI_CMD_LVL 0x1000000
|
||||
#define SDHCI_DATA_0_LVL BIT(20)
|
||||
#define SDHCI_DATA_1_LVL BIT(21)
|
||||
#define SDHCI_DATA_2_LVL BIT(22)
|
||||
#define SDHCI_DATA_3_LVL BIT(23)
|
||||
#define SDHCI_CMD_LVL BIT(24)
|
||||
|
||||
/*! SDMMC transfer mode. */
|
||||
#define SDHCI_TRNS_DMA 0x01
|
||||
#define SDHCI_TRNS_BLK_CNT_EN 0x02
|
||||
#define SDHCI_TRNS_AUTO_CMD12 0x04
|
||||
#define SDHCI_TRNS_AUTO_CMD23 0x08
|
||||
#define SDHCI_TRNS_AUTO_SEL 0x0C
|
||||
#define SDHCI_TRNS_WRITE 0x00
|
||||
#define SDHCI_TRNS_READ 0x10
|
||||
#define SDHCI_TRNS_MULTI 0x20
|
||||
/*! SDMMC transfer mode. 0x0C. */
|
||||
#define SDHCI_TRNS_DMA BIT(0)
|
||||
#define SDHCI_TRNS_BLK_CNT_EN BIT(1)
|
||||
#define SDHCI_TRNS_AUTO_CMD12 (1U << 2)
|
||||
#define SDHCI_TRNS_AUTO_CMD23 (2U << 2)
|
||||
#define SDHCI_TRNS_WRITE (0U << 4)
|
||||
#define SDHCI_TRNS_READ BIT(4)
|
||||
#define SDHCI_TRNS_MULTI BIT(5)
|
||||
#define SDHCI_TRNS_RTYPE_R1 (0U << 6)
|
||||
#define SDHCI_TRNS_RTYPE_R5 BIT(6)
|
||||
#define SDHCI_TRNS_RSP_ERR_CHK BIT(7)
|
||||
#define SDHCI_TRNS_RSP_INT_DIS BIT(8)
|
||||
|
||||
/*! SDMMC command. */
|
||||
/*! SDMMC command. 0x0E. */
|
||||
#define SDHCI_CMD_RESP_MASK 0x3
|
||||
#define SDHCI_CMD_RESP_NO_RESP 0x0
|
||||
#define SDHCI_CMD_RESP_LEN136 0x1
|
||||
#define SDHCI_CMD_RESP_LEN48 0x2
|
||||
#define SDHCI_CMD_RESP_LEN48_BUSY 0x3
|
||||
#define SDHCI_CMD_CRC 0x08
|
||||
#define SDHCI_CMD_INDEX 0x10
|
||||
#define SDHCI_CMD_DATA 0x20
|
||||
#define SDHCI_CMD_ABORTCMD 0xC0
|
||||
#define SDHCI_CMD_CRC BIT(3)
|
||||
#define SDHCI_CMD_INDEX BIT(4)
|
||||
#define SDHCI_CMD_DATA BIT(5)
|
||||
#define SDHCI_CMD_TYPE_NORMAL (0U << 6)
|
||||
#define SDHCI_CMD_TYPE_SUSPEND (1U << 6)
|
||||
#define SDHCI_CMD_TYPE_RESUME (2U << 6)
|
||||
#define SDHCI_CMD_TYPE_ABORT (3U << 6)
|
||||
#define SDHCI_CMD_IDX(cmd) ((cmd) << 8)
|
||||
|
||||
/*! SDMMC host control. */
|
||||
#define SDHCI_CTRL_LED 0x01
|
||||
#define SDHCI_CTRL_4BITBUS 0x02
|
||||
#define SDHCI_CTRL_HISPD 0x04
|
||||
#define SDHCI_CTRL_DMA_MASK 0x18
|
||||
#define SDHCI_CTRL_SDMA 0x00
|
||||
#define SDHCI_CTRL_ADMA1 0x08
|
||||
#define SDHCI_CTRL_ADMA32 0x10
|
||||
#define SDHCI_CTRL_ADMA64 0x18
|
||||
#define SDHCI_CTRL_8BITBUS 0x20
|
||||
#define SDHCI_CTRL_CDTEST_INS 0x40
|
||||
#define SDHCI_CTRL_CDTEST_EN 0x80
|
||||
|
||||
/*! SDMMC host control 2. */
|
||||
#define SDHCI_CTRL_UHS_MASK 0xFFF8
|
||||
#define SDHCI_CTRL_VDD_180 8
|
||||
#define SDHCI_CTRL_DRV_TYPE_B 0x00
|
||||
#define SDHCI_CTRL_DRV_TYPE_A 0x10
|
||||
#define SDHCI_CTRL_DRV_TYPE_C 0x20
|
||||
#define SDHCI_CTRL_DRV_TYPE_D 0x30
|
||||
#define SDHCI_CTRL_EXEC_TUNING 0x40
|
||||
#define SDHCI_CTRL_TUNED_CLK 0x80
|
||||
#define SDHCI_HOST_VERSION_4_EN 0x1000
|
||||
#define SDHCI_ADDRESSING_64BIT_EN 0x2000
|
||||
#define SDHCI_CTRL_PRESET_VAL_EN 0x8000
|
||||
/*! SDMMC host control. 0x28. */
|
||||
#define SDHCI_CTRL_LED BIT(0)
|
||||
#define SDHCI_CTRL_4BITBUS BIT(1) // SD only.
|
||||
#define SDHCI_CTRL_HISPD BIT(2) // SD only.
|
||||
#define SDHCI_CTRL_DMA_MASK (3U << 3)
|
||||
#define SDHCI_CTRL_SDMA (0U << 3)
|
||||
#define SDHCI_CTRL_ADMA1 (1U << 3)
|
||||
#define SDHCI_CTRL_ADMA32 (2U << 3)
|
||||
#define SDHCI_CTRL_ADMA64 (3U << 3)
|
||||
#define SDHCI_CTRL_8BITBUS BIT(5) // eMMC only (or UHS-II).
|
||||
#define SDHCI_CTRL_CDTEST_INS BIT(6)
|
||||
#define SDHCI_CTRL_CDTEST_EN BIT(7)
|
||||
|
||||
/*! SDMMC power control. */
|
||||
#define SDHCI_POWER_ON 0x01
|
||||
#define SDHCI_POWER_180 0x0A
|
||||
#define SDHCI_POWER_300 0x0C
|
||||
#define SDHCI_POWER_330 0x0E
|
||||
#define SDHCI_POWER_MASK 0xF1
|
||||
/*! SDMMC host control 2. 0x3E. */
|
||||
#define SDHCI_CTRL_UHS_MASK 0x7
|
||||
#define SDHCI_CTRL_VDD_180 BIT(3)
|
||||
#define SDHCI_CTRL_DRV_TYPE_MASK (3U << 4)
|
||||
#define SDHCI_CTRL_DRV_TYPE_B (0U << 4)
|
||||
#define SDHCI_CTRL_DRV_TYPE_A (1U << 4)
|
||||
#define SDHCI_CTRL_DRV_TYPE_C (2U << 4)
|
||||
#define SDHCI_CTRL_DRV_TYPE_D (3U << 4)
|
||||
#define SDHCI_CTRL_DRV_TYPE(type) ((type) << 4)
|
||||
#define SDHCI_CTRL_EXEC_TUNING BIT(6)
|
||||
#define SDHCI_CTRL_TUNED_CLK_SHIFT 7
|
||||
#define SDHCI_CTRL_TUNED_CLK BIT(7)
|
||||
#define SDHCI_HOST_VERSION_4_EN BIT(12)
|
||||
#define SDHCI_ADDRESSING_64BIT_EN BIT(13)
|
||||
#define SDHCI_CTRL_PRESET_VAL_EN BIT(15)
|
||||
|
||||
// /*! SDMMC max current. */
|
||||
// #define SDHCI_MAX_CURRENT_330_MASK 0xFF
|
||||
// #define SDHCI_MAX_CURRENT_180_MASK 0xFF0000
|
||||
// #define SDHCI_MAX_CURRENT_MULTIPLIER 4
|
||||
/*! SDMMC power control. 0x29. */
|
||||
#define SDHCI_POWER_ON BIT(0)
|
||||
#define SDHCI_POWER_180 (5U << 1)
|
||||
#define SDHCI_POWER_300 (6U << 1)
|
||||
#define SDHCI_POWER_330 (7U << 1)
|
||||
#define SDHCI_POWER_MASK 0xF1 // UHS-II only.
|
||||
|
||||
/*! SDMMC clock control. */
|
||||
#define SDHCI_DIVIDER_SHIFT 8
|
||||
#define SDHCI_DIVIDER_HI_SHIFT 6
|
||||
#define SDHCI_DIV_MASK 0xFF00
|
||||
#define SDHCI_DIV_HI_MASK 0xC0
|
||||
#define SDHCI_PROG_CLOCK_MODE 0x20
|
||||
#define SDHCI_CLOCK_CARD_EN 0x4
|
||||
#define SDHCI_CLOCK_INT_STABLE 0x2
|
||||
#define SDHCI_CLOCK_INT_EN 0x1
|
||||
/*! SDMMC clock control. 0x2C. */
|
||||
#define SDHCI_CLOCK_INT_EN BIT(0) // Internal Clock.
|
||||
#define SDHCI_CLOCK_INT_STABLE BIT(1) // Internal Clock Stable.
|
||||
#define SDHCI_CLOCK_CARD_EN BIT(2)
|
||||
#define SDHCI_PROG_CLOCK_MODE BIT(5)
|
||||
#define SDHCI_DIV_HI_SHIFT 6
|
||||
#define SDHCI_DIV_HI_MASK (3U << SDHCI_DIV_HI_SHIFT)
|
||||
#define SDHCI_DIV_LO_SHIFT 8
|
||||
#define SDHCI_DIV_MASK (0xFFU << SDHCI_DIV_LO_SHIFT)
|
||||
|
||||
/*! SDMMC software reset. */
|
||||
#define SDHCI_RESET_ALL 0x01
|
||||
#define SDHCI_RESET_CMD 0x02
|
||||
#define SDHCI_RESET_DATA 0x04
|
||||
|
||||
/*! SDMMC interrupt status and control. */
|
||||
#define SDHCI_INT_RESPONSE 0x1
|
||||
#define SDHCI_INT_DATA_END 0x2
|
||||
#define SDHCI_INT_BLK_GAP 0x4
|
||||
#define SDHCI_INT_DMA_END 0x8
|
||||
#define SDHCI_INT_SPACE_AVAIL 0x10
|
||||
#define SDHCI_INT_DATA_AVAIL 0x20
|
||||
#define SDHCI_INT_CARD_INSERT 0x40
|
||||
#define SDHCI_INT_CARD_REMOVE 0x80
|
||||
#define SDHCI_INT_CARD_INT 0x100
|
||||
#define SDHCI_INT_RETUNE 0x1000
|
||||
#define SDHCI_INT_CQE 0x4000
|
||||
#define SDHCI_INT_ERROR 0x8000
|
||||
/*! SDMMC software reset. 0x2F. */
|
||||
#define SDHCI_RESET_ALL BIT(0)
|
||||
#define SDHCI_RESET_CMD BIT(1)
|
||||
#define SDHCI_RESET_DATA BIT(2)
|
||||
|
||||
/*! SDMMC error interrupt status and control. */
|
||||
#define SDHCI_ERR_INT_TIMEOUT 0x1
|
||||
#define SDHCI_ERR_INT_CRC 0x2
|
||||
#define SDHCI_ERR_INT_END_BIT 0x4
|
||||
#define SDHCI_ERR_INT_INDEX 0x8
|
||||
#define SDHCI_ERR_INT_DATA_TIMEOUT 0x10
|
||||
#define SDHCI_ERR_INT_DATA_CRC 0x20
|
||||
#define SDHCI_ERR_INT_DATA_END_BIT 0x40
|
||||
#define SDHCI_ERR_INT_BUS_POWER 0x80
|
||||
#define SDHCI_ERR_INT_AUTO_CMD_ERR 0x100
|
||||
#define SDHCI_ERR_INT_ADMA_ERROR 0x200
|
||||
/*! SDMMC interrupt status and control. 0x30/0x34. */
|
||||
#define SDHCI_INT_RESPONSE BIT(0)
|
||||
#define SDHCI_INT_DATA_END BIT(1)
|
||||
#define SDHCI_INT_BLK_GAP BIT(2)
|
||||
#define SDHCI_INT_DMA_END BIT(3)
|
||||
#define SDHCI_INT_SPACE_AVAIL BIT(4) // Write buffer empty.
|
||||
#define SDHCI_INT_DATA_AVAIL BIT(5) // Read buffer has data.
|
||||
#define SDHCI_INT_CARD_INSERT BIT(6)
|
||||
#define SDHCI_INT_CARD_REMOVE BIT(7)
|
||||
#define SDHCI_INT_CARD_INT BIT(8)
|
||||
#define SDHCI_INT_RETUNE BIT(12)
|
||||
#define SDHCI_INT_ERROR BIT(15)
|
||||
|
||||
/*! SDMMC error interrupt status and control. 0x32/0x36. */
|
||||
#define SDHCI_ERR_INT_TIMEOUT BIT(0)
|
||||
#define SDHCI_ERR_INT_CRC BIT(1)
|
||||
#define SDHCI_ERR_INT_END_BIT BIT(2)
|
||||
#define SDHCI_ERR_INT_INDEX BIT(3)
|
||||
#define SDHCI_ERR_INT_DATA_TIMEOUT BIT(4)
|
||||
#define SDHCI_ERR_INT_DATA_CRC BIT(5)
|
||||
#define SDHCI_ERR_INT_DATA_END_BIT BIT(6)
|
||||
#define SDHCI_ERR_INT_BUS_POWER BIT(7)
|
||||
#define SDHCI_ERR_INT_AUTO_CMD12 BIT(8)
|
||||
#define SDHCI_ERR_INT_ADMA BIT(9)
|
||||
#define SDHCI_ERR_INT_TUNE BIT(10)
|
||||
#define SDHCI_ERR_INT_RSP BIT(11)
|
||||
#define SDHCI_ERR_INT_TARGET_RSP BIT(12)
|
||||
#define SDHCI_ERR_INT_SPI BIT(13)
|
||||
#define SDHCI_ERR_INT_VND_BOOT_TMO BIT(14)
|
||||
#define SDHCI_ERR_INT_VND_BOOT_ACK BIT(15)
|
||||
|
||||
#define SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR \
|
||||
(SDHCI_ERR_INT_AUTO_CMD_ERR | SDHCI_ERR_INT_DATA_END_BIT | \
|
||||
SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \
|
||||
SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \
|
||||
SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT)
|
||||
(SDHCI_ERR_INT_AUTO_CMD12 | SDHCI_ERR_INT_DATA_END_BIT | \
|
||||
SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \
|
||||
SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \
|
||||
SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT)
|
||||
|
||||
/*! Host Capability 1. 0x40. */
|
||||
#define SDHCI_CAP_TM_CLK_FREQ_MASK 0x3F
|
||||
#define SDHCI_CAP_TM_UNIT_MHZ BIT(7)
|
||||
#define SDHCI_CAP_BASE_CLK_FREQ_MASK (0xFFU << 8)
|
||||
#define SDHCI_CAP_MAX_BLK_LEN_MASK (3U << 16)
|
||||
#define SDHCI_CAP_EMMC_8BIT BIT(18)
|
||||
#define SDHCI_CAP_ADMA2 BIT(19)
|
||||
#define SDHCI_CAP_HISPD BIT(21)
|
||||
#define SDHCI_CAP_SDMA BIT(22)
|
||||
#define SDHCI_CAP_SUSPEND_RESUME BIT(23)
|
||||
#define SDHCI_CAP_3_3_V BIT(24)
|
||||
#define SDHCI_CAP_3_0_V BIT(25)
|
||||
#define SDHCI_CAP_1_8_V BIT(26)
|
||||
#define SDHCI_CAP_64BIT BIT(28)
|
||||
#define SDHCI_CAP_ASYNC_INT BIT(29)
|
||||
#define SDHCI_CAP_SLOT_TYPE_MASK (3U << 30)
|
||||
#define SDHCI_CAP_SLOT_TYPE_REMOVABLE (0U << 30)
|
||||
#define SDHCI_CAP_SLOT_TYPE_EMBEDDED (1U << 30)
|
||||
#define SDHCI_CAP_SLOT_TYPE_SHARED (2U << 30)
|
||||
#define SDHCI_CAP_SLOT_TYPE_UHS2 (3U << 30)
|
||||
|
||||
/*! Host Capability 2. 0x44. */
|
||||
#define SDHCI_CAP_SDR50 BIT(0)
|
||||
#define SDHCI_CAP_SDR5104 BIT(1)
|
||||
#define SDHCI_CAP_DDR50 BIT(2)
|
||||
#define SDHCI_CAP_UHS2 BIT(3)
|
||||
#define SDHCI_CAP_DRV_TYPE_A BIT(4)
|
||||
#define SDHCI_CAP_DRV_TYPE_C BIT(5)
|
||||
#define SDHCI_CAP_DRV_TYPE_D BIT(6)
|
||||
#define SDHCI_CAP_RSP_TIMER_CNT_MASK (0xFU << 8)
|
||||
#define SDHCI_CAP_SDR50_TUNING BIT(13)
|
||||
#define SDHCI_CAP_RSP_MODES_MASK (3U << 14)
|
||||
#define SDHCI_CAP_CLK_MULT (0xFFU << 16)
|
||||
#define SDHCI_CAP_ADMA3 BIT(27)
|
||||
#define SDHCI_CAP_VDD2_1_8V BIT(28)
|
||||
|
||||
/*! SDMMC max current. 0x48 */
|
||||
#define SDHCI_MAX_CURRENT_3_3_V_MASK (0xFFU << 0)
|
||||
#define SDHCI_MAX_CURRENT_3_0_V_MASK (0xFFU << 8)
|
||||
#define SDHCI_MAX_CURRENT_1_8_V_MASK (0xFFU << 16)
|
||||
#define SDHCI_MAX_CURRENT_MULTIPLIER 4
|
||||
|
||||
/*! SDMMC max current. 0x4C */
|
||||
#define SDHCI_MAX_CURRENT_1_8_V_VDD2_MASK (0xFFU << 0)
|
||||
|
||||
/*! SD bus speeds. */
|
||||
#define UHS_SDR12_BUS_SPEED 0
|
||||
|
@ -193,11 +260,11 @@
|
|||
#define SDHCI_TIMING_UHS_SDR25 9
|
||||
#define SDHCI_TIMING_UHS_SDR50 10
|
||||
#define SDHCI_TIMING_UHS_SDR104 11
|
||||
#define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock.
|
||||
#define SDHCI_TIMING_UHS_DDR50 13
|
||||
#define SDHCI_TIMING_MMC_HS102 14
|
||||
|
||||
#define SDHCI_CAN_64BIT 0x10000000
|
||||
#define SDHCI_TIMING_UHS_DDR50 12
|
||||
// SDR104 with a 163.2MHz -> 81.6MHz clock.
|
||||
#define SDHCI_TIMING_UHS_SDR82 13 // GC FPGA. Obsolete and Repurposed. MMC_HS50 -> SDR82.
|
||||
#define SDHCI_TIMING_MMC_HS100 14 // GC ASIC.
|
||||
#define SDHCI_TIMING_UHS_DDR200 15
|
||||
|
||||
/*! SDMMC Low power features. */
|
||||
#define SDMMC_POWER_SAVE_DISABLE 0
|
||||
|
@ -206,12 +273,16 @@
|
|||
/*! Helper for SWITCH command argument. */
|
||||
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
|
||||
|
||||
#define HW_TAP_TUNING 0x100
|
||||
#define INVALID_TAP 0x100
|
||||
#define SAMPLING_WINDOW_SIZE_MIN 8
|
||||
|
||||
/*! SDMMC controller context. */
|
||||
typedef struct _sdmmc_t
|
||||
{
|
||||
t210_sdmmc_t *regs;
|
||||
u32 id;
|
||||
u32 divisor;
|
||||
u32 card_clock;
|
||||
u32 clock_stopped;
|
||||
int powersave_enabled;
|
||||
int manual_cal;
|
||||
|
@ -249,13 +320,14 @@ int sdmmc_get_io_power(sdmmc_t *sdmmc);
|
|||
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
|
||||
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
|
||||
void sdmmc_save_tap_value(sdmmc_t *sdmmc);
|
||||
void sdmmc_setup_drv_type(sdmmc_t *sdmmc, u32 type);
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
|
||||
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable);
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
|
||||
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd);
|
||||
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
|
||||
bool sdmmc_get_sd_inserted();
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable);
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type);
|
||||
void sdmmc_end(sdmmc_t *sdmmc);
|
||||
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
|
||||
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,92 +18,112 @@
|
|||
#ifndef _SDMMC_T210_H_
|
||||
#define _SDMMC_T210_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW 0x20000
|
||||
#define TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE 0x80000000
|
||||
#define TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE 0x80000000
|
||||
#define TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD 0x80000000
|
||||
#define TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK 0xFFFFFFF0
|
||||
#define TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE 0x20000000
|
||||
#define TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START 0x80000000
|
||||
#define TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE 0x80000000
|
||||
#define SDHCI_TEGRA_TUNING_TAP_HW_UPDATED BIT(17)
|
||||
#define SDHCI_TEGRA_DLLCAL_CALIBRATE BIT(31)
|
||||
#define SDHCI_TEGRA_DLLCAL_ACTIVE BIT(31)
|
||||
#define SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD BIT(31)
|
||||
#define SDHCI_TEGRA_PADCTRL_VREF_SEL_MASK 0xF
|
||||
#define SDHCI_TEGRA_AUTOCAL_SLW_OVERRIDE BIT(28)
|
||||
#define SDHCI_TEGRA_AUTOCAL_ENABLE BIT(29)
|
||||
#define SDHCI_TEGRA_AUTOCAL_START BIT(31)
|
||||
#define SDHCI_TEGRA_AUTOCAL_ACTIVE BIT(31)
|
||||
|
||||
typedef struct _t210_sdmmc_t
|
||||
{
|
||||
vu32 sysad;
|
||||
vu16 blksize;
|
||||
vu16 blkcnt;
|
||||
vu32 argument;
|
||||
vu16 trnmod;
|
||||
vu16 cmdreg;
|
||||
vu32 rspreg0;
|
||||
vu32 rspreg1;
|
||||
vu32 rspreg2;
|
||||
vu32 rspreg3;
|
||||
vu32 bdata;
|
||||
vu32 prnsts;
|
||||
vu8 hostctl;
|
||||
vu8 pwrcon;
|
||||
vu8 blkgap;
|
||||
vu8 wakcon;
|
||||
vu16 clkcon;
|
||||
vu8 timeoutcon;
|
||||
vu8 swrst;
|
||||
vu16 norintsts;
|
||||
vu16 errintsts;
|
||||
vu16 norintstsen; // Enable irq status.
|
||||
vu16 errintstsen; // Enable irq status.
|
||||
vu16 norintsigen; // Enable irq signal to LIC/GIC.
|
||||
vu16 errintsigen; // Enable irq signal to LIC/GIC.
|
||||
vu16 acmd12errsts;
|
||||
vu16 hostctl2;
|
||||
vu32 capareg;
|
||||
vu32 capareg_1;
|
||||
vu32 maxcurr;
|
||||
vu8 rsvd0[4]; // 4C-4F reserved for more max current.
|
||||
vu16 setacmd12err;
|
||||
vu16 setinterr;
|
||||
vu8 admaerr;
|
||||
vu8 rsvd1[3]; // 55-57 reserved.
|
||||
vu32 admaaddr;
|
||||
vu32 admaaddr_hi;
|
||||
vu8 rsvd2[156]; // 60-FB reserved.
|
||||
vu16 slotintsts;
|
||||
vu16 hcver;
|
||||
vu32 venclkctl;
|
||||
vu32 vensysswctl;
|
||||
vu32 venerrintsts;
|
||||
vu32 vencapover;
|
||||
vu32 venbootctl;
|
||||
vu32 venbootacktout;
|
||||
vu32 venbootdattout;
|
||||
vu32 vendebouncecnt;
|
||||
vu32 venmiscctl;
|
||||
vu32 maxcurrover;
|
||||
vu32 maxcurrover_hi;
|
||||
vu32 unk0[32]; // 0x12C
|
||||
vu32 veniotrimctl;
|
||||
vu32 vendllcalcfg;
|
||||
vu32 vendllctl0;
|
||||
vu32 vendllctl1;
|
||||
vu32 vendllcalcfgsts;
|
||||
vu32 ventunctl0;
|
||||
vu32 ventunctl1;
|
||||
vu32 ventunsts0;
|
||||
vu32 ventunsts1;
|
||||
vu32 venclkgatehystcnt;
|
||||
vu32 venpresetval0;
|
||||
vu32 venpresetval1;
|
||||
vu32 venpresetval2;
|
||||
vu32 sdmemcmppadctl;
|
||||
vu32 autocalcfg;
|
||||
vu32 autocalintval;
|
||||
vu32 autocalsts;
|
||||
vu32 iospare;
|
||||
vu32 mcciffifoctl;
|
||||
vu32 timeoutwcoal;
|
||||
vu32 unk1;
|
||||
/* 0x00 */ vu32 sysad; // sdma system address.
|
||||
/* 0x04 */ vu16 blksize;
|
||||
/* 0x06 */ vu16 blkcnt;
|
||||
/* 0x08 */ vu32 argument;
|
||||
/* 0x0C */ vu16 trnmod;
|
||||
/* 0x0E */ vu16 cmdreg;
|
||||
/* 0x10 */ vu32 rspreg0;
|
||||
/* 0x14 */ vu32 rspreg1;
|
||||
/* 0x18 */ vu32 rspreg2;
|
||||
/* 0x1C */ vu32 rspreg3;
|
||||
/* 0x20 */ vu32 bdata; // Buffer data port.
|
||||
/* 0x24 */ vu32 prnsts;
|
||||
/* 0x28 */ vu8 hostctl;
|
||||
/* 0x29 */ vu8 pwrcon;
|
||||
/* 0x2A */ vu8 blkgap;
|
||||
/* 0x2B */ vu8 wakcon;
|
||||
/* 0x2C */ vu16 clkcon;
|
||||
/* 0x2E */ vu8 timeoutcon;
|
||||
/* 0x2F */ vu8 swrst;
|
||||
/* 0x30 */ vu16 norintsts; // Normal interrupt status.
|
||||
/* 0x32 */ vu16 errintsts; // Error interrupt status.
|
||||
/* 0x34 */ vu16 norintstsen; // Enable irq status.
|
||||
/* 0x36 */ vu16 errintstsen; // Enable irq status.
|
||||
/* 0x38 */ vu16 norintsigen; // Enable irq signal to LIC/GIC.
|
||||
/* 0x3A */ vu16 errintsigen; // Enable irq signal to LIC/GIC.
|
||||
/* 0x3C */ vu16 acmd12errsts;
|
||||
/* 0x3E */ vu16 hostctl2;
|
||||
|
||||
// CAP0: 0x376CD08C.
|
||||
// 12 MHz timeout clock. 208 MHz max base clock. 512B max block length. 8-bit support.
|
||||
// ADMA2 support. HS25 support. SDMA support. No suspend/resume support. 3.3/3.0/1.8V support.
|
||||
// 64bit addressing for V3/V4 support. Async IRQ support. All report as removable.
|
||||
/* 0x40 */ vu32 capareg;
|
||||
// CAP1: 0x10002F73.
|
||||
// SDR50/SDR104 support. No DDR50 support. Drive A/B/C/D support.
|
||||
// Timer re-tuning info from other source. SDR50 requires re-tuning.
|
||||
// Tuning uses timer and transfers should be 4MB limited.
|
||||
// ADMA3 not supported. 1.8V VDD2 supported.
|
||||
/* 0x44 */ vu32 capareg_hi;
|
||||
|
||||
/* 0x48 */ vu32 maxcurr; // Get information by another method. Can be overriden via maxcurrover and maxcurrover_hi.
|
||||
/* 0x4C */ vu32 maxcurr_hi;
|
||||
/* 0x50 */ vu16 setacmd12err; // Force error in acmd12errsts.
|
||||
/* 0x52 */ vu16 setinterr;
|
||||
/* 0x54 */ vu8 admaerr;
|
||||
/* 0x55 */ vu8 rsvd1[3]; // 55-57 reserved.
|
||||
/* 0x58 */ vu32 admaaddr;
|
||||
/* 0x5C */ vu32 admaaddr_hi;
|
||||
/* 0x60 */ vu16 presets[11];
|
||||
/* 0x76 */ vu16 rsvd2;
|
||||
/* 0x78 */ vu32 adma3addr;
|
||||
/* 0x7C */ vu32 adma3addr_hi;
|
||||
/* 0x80 */ vu8 uhs2[124]; // 80-FB UHS-II.
|
||||
/* 0xFC */ vu16 slotintsts;
|
||||
/* 0xFE */ vu16 hcver; // 0x303 (4.00).
|
||||
|
||||
/* UHS-II range. Used for Vendor registers here */
|
||||
/* 0x100 */ vu32 venclkctl;
|
||||
/* 0x104 */ vu32 vensysswctl;
|
||||
/* 0x108 */ vu32 venerrintsts;
|
||||
/* 0x10C */ vu32 vencapover;
|
||||
/* 0x110 */ vu32 venbootctl;
|
||||
/* 0x114 */ vu32 venbootacktout;
|
||||
/* 0x118 */ vu32 venbootdattout;
|
||||
/* 0x11C */ vu32 vendebouncecnt;
|
||||
/* 0x120 */ vu32 venmiscctl;
|
||||
/* 0x124 */ vu32 maxcurrover;
|
||||
/* 0x128 */ vu32 maxcurrover_hi;
|
||||
/* 0x12C */ vu32 unk0[32]; // 0x12C
|
||||
/* 0x1AC */ vu32 veniotrimctl;
|
||||
/* 0x1B0 */ vu32 vendllcalcfg;
|
||||
/* 0x1B4 */ vu32 vendllctl0;
|
||||
/* 0x1B8 */ vu32 vendllctl1;
|
||||
/* 0x1BC */ vu32 vendllcalcfgsts;
|
||||
/* 0x1C0 */ vu32 ventunctl0;
|
||||
/* 0x1C4 */ vu32 ventunctl1;
|
||||
/* 0x1C8 */ vu32 ventunsts0;
|
||||
/* 0x1CC */ vu32 ventunsts1;
|
||||
/* 0x1D0 */ vu32 venclkgatehystcnt;
|
||||
/* 0x1D4 */ vu32 venpresetval0;
|
||||
/* 0x1D8 */ vu32 venpresetval1;
|
||||
/* 0x1DC */ vu32 venpresetval2;
|
||||
/* 0x1E0 */ vu32 sdmemcmppadctl;
|
||||
/* 0x1E4 */ vu32 autocalcfg;
|
||||
/* 0x1E8 */ vu32 autocalintval;
|
||||
/* 0x1EC */ vu32 autocalsts;
|
||||
/* 0x1F0 */ vu32 iospare;
|
||||
/* 0x1F4 */ vu32 mcciffifoctl;
|
||||
/* 0x1F8 */ vu32 timeoutwcoal;
|
||||
} t210_sdmmc_t;
|
||||
|
||||
static_assert(sizeof(t210_sdmmc_t) == 0x1FC, "T210 SDMMC REG size is wrong!");
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Fan driver for Nintendo Switch
|
||||
*
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,11 +18,14 @@
|
|||
|
||||
#include <thermal/fan.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
void set_fan_duty(u32 duty)
|
||||
{
|
||||
|
@ -37,18 +40,24 @@ void set_fan_duty(u32 duty)
|
|||
|
||||
curr_duty = duty;
|
||||
|
||||
//! TODO: Add HOAG/AULA support.
|
||||
u32 hw_type = fuse_read_hw_type();
|
||||
if (hw_type != FUSE_NX_HW_TYPE_ICOSA &&
|
||||
hw_type != FUSE_NX_HW_TYPE_IOWA)
|
||||
return;
|
||||
|
||||
if (!fan_init)
|
||||
{
|
||||
// Fan tachometer.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1;
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
u32 pull_resistor = hw_get_chip_id() == GP_HIDREV_MAJOR_T210 ? PINMUX_PULL_UP : 0;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | pull_resistor | 1;
|
||||
gpio_direction_input(GPIO_PORT_S, GPIO_PIN_7);
|
||||
|
||||
// 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.
|
||||
|
||||
|
@ -68,8 +77,8 @@ void set_fan_duty(u32 duty)
|
|||
regulator_5v_disable(REGULATOR_5V_FAN);
|
||||
|
||||
// Disable fan.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) =
|
||||
PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_DOWN; // Set source to PWM1.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = PINMUX_INPUT_ENABLE | PINMUX_PARKED |
|
||||
PINMUX_TRISTATE | PINMUX_PULL_DOWN; // Set source to PWM1.
|
||||
}
|
||||
else // Set PWM duty.
|
||||
{
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "btn.h"
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
#include <power/max77620.h>
|
||||
|
||||
u8 btn_read()
|
||||
|
@ -29,6 +29,7 @@ u8 btn_read()
|
|||
res |= BTN_VOL_DOWN;
|
||||
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
|
||||
res |= BTN_VOL_UP;
|
||||
// HOAG can use the GPIO. Icosa/Iowa/AULA cannot. Traces are there but they miss a resistor.
|
||||
if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFSTAT) & MAX77620_ONOFFSTAT_EN0)
|
||||
res |= BTN_POWER;
|
||||
return res;
|
||||
|
|
|
@ -47,6 +47,9 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
|
|||
csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name);
|
||||
csec->type = type;
|
||||
|
||||
// Initialize list.
|
||||
list_init(&csec->kvs);
|
||||
|
||||
return csec;
|
||||
}
|
||||
|
||||
|
@ -54,11 +57,11 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
{
|
||||
FIL fp;
|
||||
u32 lblen;
|
||||
u32 pathlen = strlen(ini_path);
|
||||
u32 k = 0;
|
||||
u32 pathlen = strlen(ini_path);
|
||||
ini_sec_t *csec = NULL;
|
||||
|
||||
char *lbuf = NULL;
|
||||
char *lbuf = NULL;
|
||||
char *filelist = NULL;
|
||||
char *filename = (char *)malloc(256);
|
||||
|
||||
|
@ -102,7 +105,6 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
|
||||
lbuf = malloc(512);
|
||||
csec = _ini_create_section(dst, csec, "Unknown", INI_CHOICE);
|
||||
list_init(&csec->kvs);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -120,7 +122,6 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
_find_section_name(lbuf, lblen, ']');
|
||||
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
|
||||
list_init(&csec->kvs);
|
||||
}
|
||||
else if (lblen > 1 && lbuf[0] == '{') // Create new caption. Support empty caption '{}'.
|
||||
{
|
||||
|
@ -142,8 +143,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
u32 i = _find_section_name(lbuf, lblen, '=');
|
||||
|
||||
// Calculate total allocation size.
|
||||
u32 klen = strlen(&lbuf[0]) + 1;
|
||||
u32 vlen = strlen(&lbuf[i + 1]) + 1;
|
||||
u32 klen = strlen(&lbuf[0]) + 1;
|
||||
u32 vlen = strlen(&lbuf[i + 1]) + 1;
|
||||
char *buf = calloc(sizeof(ini_kv_t) + klen + vlen, 1);
|
||||
|
||||
ini_kv_t *kv = (ini_kv_t *)buf;
|
||||
|
@ -155,6 +156,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
}
|
||||
} while (!f_eof(&fp));
|
||||
|
||||
free(lbuf);
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
if (csec)
|
||||
|
@ -165,23 +168,61 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
}
|
||||
} while (is_dir);
|
||||
|
||||
free(lbuf);
|
||||
free(filename);
|
||||
free(filelist);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ini_check_payload_section(ini_sec_t *cfg)
|
||||
char *ini_check_special_section(ini_sec_t *cfg)
|
||||
{
|
||||
if (cfg == NULL)
|
||||
return NULL;
|
||||
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||
{
|
||||
if (!strcmp("payload", kv->key))
|
||||
if (!strcmp("l4t", kv->key))
|
||||
return ((kv->val[0] == '1') ? (char *)-1 : NULL);
|
||||
else if (!strcmp("payload", kv->key))
|
||||
return kv->val;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ini_free(link_t *src)
|
||||
{
|
||||
ini_sec_t *prev_sec = NULL;
|
||||
|
||||
// Parse and free all ini sections.
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, src, link)
|
||||
{
|
||||
ini_kv_t *prev_kv = NULL;
|
||||
|
||||
// Free all ini key allocations if they exist.
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
{
|
||||
// Free previous key.
|
||||
if (prev_kv)
|
||||
free(prev_kv);
|
||||
|
||||
// Set next key to free.
|
||||
prev_kv = kv;
|
||||
}
|
||||
|
||||
// Free last key.
|
||||
if (prev_kv)
|
||||
free(prev_kv);
|
||||
|
||||
// Free previous section.
|
||||
if (prev_sec)
|
||||
free(prev_sec);
|
||||
|
||||
// Set next section to free.
|
||||
prev_sec = ini_sec;
|
||||
}
|
||||
|
||||
// Free last section.
|
||||
if (prev_sec)
|
||||
free(prev_sec);
|
||||
}
|
||||
|
|
|
@ -43,8 +43,9 @@ typedef struct _ini_sec_t
|
|||
u32 color;
|
||||
} ini_sec_t;
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||
char *ini_check_payload_section(ini_sec_t *cfg);
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||
char *ini_check_special_section(ini_sec_t *cfg);
|
||||
void ini_free(link_t *src);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,16 +28,25 @@
|
|||
|
||||
/*! Iterate over all list links. */
|
||||
#define LIST_FOREACH(iter, list) \
|
||||
for(link_t *iter = (list)->next; iter != (list); iter = iter->next)
|
||||
for (link_t *iter = (list)->next; iter != (list); iter = iter->next)
|
||||
|
||||
/*! Iterate over all list links backwards. */
|
||||
#define LIST_FOREACH_INVERSE(iter, list) \
|
||||
for (link_t *iter = (list)->prev; iter != (list); iter = iter->prev)
|
||||
|
||||
/*! Safely iterate over all list links. */
|
||||
#define LIST_FOREACH_SAFE(iter, list) \
|
||||
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
|
||||
for (link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
|
||||
|
||||
/*! Iterate over all list members and make sure that the list has at least one entry. */
|
||||
#define LIST_FOREACH_ENTRY(etype, iter, list, mn) \
|
||||
if ((list)->next != (list)) \
|
||||
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
|
||||
for (etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
|
||||
|
||||
/* Iterate over all list members backwards and make sure that the list has at least one entry. */
|
||||
#define LIST_FOREACH_ENTRY_INVERSE(type, iter, list, mn) \
|
||||
if ((list)->prev != (list)) \
|
||||
for (type *iter = CONTAINER_OF((list)->prev, type, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.prev, type, mn))
|
||||
|
||||
typedef struct _link_t
|
||||
{
|
||||
|
@ -53,7 +62,7 @@ static inline void link_init(link_t *l)
|
|||
|
||||
static inline int link_used(link_t *l)
|
||||
{
|
||||
if(l->next == NULL)
|
||||
if (l->next == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,7 +98,7 @@ static inline void list_remove(link_t *l)
|
|||
|
||||
static inline int list_empty(link_t *lh)
|
||||
{
|
||||
if(lh->next == lh)
|
||||
if (lh->next == lh)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,14 +36,24 @@ static void _s_puts(char *s)
|
|||
|
||||
static void _s_putn(u32 v, int base, char fill, int fcnt)
|
||||
{
|
||||
char buf[65];
|
||||
static const char digits[] = "0123456789ABCDEFghijklmnopqrstuvwxyz";
|
||||
char *p;
|
||||
int c = fcnt;
|
||||
static const char digits[] = "0123456789ABCDEF";
|
||||
|
||||
if (base > 36)
|
||||
char *p;
|
||||
char buf[65];
|
||||
int c = fcnt;
|
||||
bool negative = false;
|
||||
|
||||
if (base != 10 && base != 16)
|
||||
return;
|
||||
|
||||
// Account for negative numbers.
|
||||
if (base == 10 && v & 0x80000000)
|
||||
{
|
||||
negative = true;
|
||||
v = (int)v * -1;
|
||||
c--;
|
||||
}
|
||||
|
||||
p = buf + 64;
|
||||
*p = 0;
|
||||
do
|
||||
|
@ -53,9 +63,12 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
|
|||
v /= base;
|
||||
} while (v);
|
||||
|
||||
if (negative)
|
||||
*--p = '-';
|
||||
|
||||
if (fill != 0)
|
||||
{
|
||||
while (c > 0)
|
||||
while (c > 0 && p > buf)
|
||||
{
|
||||
*--p = fill;
|
||||
c--;
|
||||
|
@ -73,9 +86,9 @@ void s_printf(char *out_buf, const char *fmt, ...)
|
|||
sout_buf = &out_buf;
|
||||
|
||||
va_start(ap, fmt);
|
||||
while(*fmt)
|
||||
while (*fmt)
|
||||
{
|
||||
if(*fmt == '%')
|
||||
if (*fmt == '%')
|
||||
{
|
||||
fmt++;
|
||||
fill = 0;
|
||||
|
@ -96,7 +109,7 @@ void s_printf(char *out_buf, const char *fmt, ...)
|
|||
fcnt -= '0';
|
||||
}
|
||||
}
|
||||
switch(*fmt)
|
||||
switch (*fmt)
|
||||
{
|
||||
case 'c':
|
||||
_s_putc(va_arg(ap, u32));
|
||||
|
@ -140,9 +153,9 @@ void s_vprintf(char *out_buf, const char *fmt, va_list ap)
|
|||
|
||||
sout_buf = &out_buf;
|
||||
|
||||
while(*fmt)
|
||||
while (*fmt)
|
||||
{
|
||||
if(*fmt == '%')
|
||||
if (*fmt == '%')
|
||||
{
|
||||
fmt++;
|
||||
fill = 0;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include <utils/types.h>
|
||||
|
||||
void s_printf(char *out_buf, const char *fmt, ...);
|
||||
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);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue