uplift bdk

Signed-off-by: Damien Zhao <zdm65477730@126.com>
This commit is contained in:
Damien Zhao committed 2024-04-13 12:27:17 +08:00
1 parent cf9ec7683b
commit 029b32f722
109 files changed
+58029 -2056

No files matched your search

+27 -12
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -42,6 +42,26 @@ static bool _nx_aula = false;
static void _display_panel_and_hw_end(bool no_panel_deinit); static void _display_panel_and_hw_end(bool no_panel_deinit);
void display_enable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) |= intr;
}
void display_disable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) &= ~intr;
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
}
void display_wait_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
// Interrupts are masked. Poll status register for checking if fired.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & intr))
;
}
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask) static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
{ {
u32 end = get_tmr_us() + timeout; u32 end = get_tmr_us() + timeout;
@@ -64,22 +84,18 @@ static void _display_dsi_wait_vblank(bool enable)
if (enable) if (enable)
{ {
// Enable vblank interrupt. // Enable vblank interrupt.
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT; display_enable_interrupt(DC_CMD_INT_FRAME_END_INT);
// Use the 4th line to transmit the host cmd packet. // Use the 4th line to transmit the host cmd packet.
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4); DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
// Wait for vblank before starting the transfer. // Wait for vblank before starting the transfer.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
} }
else else
{ {
// Wait for vblank before resetting sync points. // Wait for vblank before resetting sync points.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
usleep(14); usleep(14);
// Reset all states of syncpt block. // Reset all states of syncpt block.
@@ -94,8 +110,7 @@ static void _display_dsi_wait_vblank(bool enable)
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
// Disable and clear vblank interrupt. // Disable and clear vblank interrupt.
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0; display_disable_interrupt(DC_CMD_INT_FRAME_END_INT);
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
} }
} }
@@ -383,10 +398,10 @@ void display_init()
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz). CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = CLK_SRC_DIV(6); // Set PLLP_OUT3 and div 6 (17MHz).
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
// Bring every IO rail out of deep power down. // Bring every IO rail out of deep power down.
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF; PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
+15 -2
View File
@@ -732,9 +732,10 @@
* [10] 96 [09]: JDI LAM062M109A * [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1) * [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1) * [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
* [20] 96 [0F]: InnoLux P062CCA-AZ3 (Rev XX) [UNCONFIRMED MODEL+REV] * [20] 96 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV] * [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV] * [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000) * [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001) * [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002) * [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
@@ -786,13 +787,25 @@ enum
PANEL_INL_2J055IA_27A = 0x1020, PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030, PANEL_AUO_A055TAN01 = 0x1030,
PANEL_SHP_LQ055T1SW10 = 0x1040, PANEL_SHP_LQ055T1SW10 = 0x1040,
PANEL_SAM_AMS699VC01 = 0x2050 PANEL_SAM_AMS699VC01 = 0x2050,
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
PANEL_OEM_CLONE_6_2 = 0x0F83,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE_5_5 = 0x00B3,
// Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
PANEL_OEM_CLONE = 0x0000
}; };
void display_init(); void display_init();
void display_backlight_pwm_init(); void display_backlight_pwm_init();
void display_end(); void display_end();
/*! Interrupt management. */
void display_enable_interrupt(u32 intr);
void display_disable_interrupt(u32 intr);
void display_wait_interrupt(u32 intr);
/*! Get/Set Display panel ID. */ /*! Get/Set Display panel ID. */
u16 display_get_decoded_panel_id(); u16 display_get_decoded_panel_id();
void display_set_decoded_panel_id(u32 id); void display_set_decoded_panel_id(u32 id);
+1 -1
View File
@@ -38,7 +38,7 @@
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 1 #define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#if FF_USE_MKFS #if FF_USE_MKFS
+4 -2
View File
@@ -43,7 +43,9 @@
#define JC_HORI_INPUT_RPT 0x00 #define JC_HORI_INPUT_RPT 0x00
#define JC_WIRED_CMD_GET_INFO 0x01 #define JC_WIRED_CMD_GET_INFO 0x01
#define JC_WIRED_CMD_CHRG_CFG 0x02 #define JC_WIRED_CMD_SET_CHARGER 0x02
#define JC_WIRED_CMD_GET_CHARGER 0x03
#define JC_WIRED_CMD_BATT_VOLT 0x06
#define JC_WIRED_CMD_WAKE_REASON 0x07 #define JC_WIRED_CMD_WAKE_REASON 0x07
#define JC_WIRED_CMD_HID_CONN 0x10 #define JC_WIRED_CMD_HID_CONN 0x10
#define JC_WIRED_CMD_HID_DISC 0x11 #define JC_WIRED_CMD_HID_DISC 0x11
@@ -304,7 +306,7 @@ typedef struct _jc_sio_hid_in_rpt_t
u8 stick_h_right; u8 stick_h_right;
u8 stick_m_right; u8 stick_m_right;
u8 stick_v_right; u8 stick_v_right;
u8 siaxis_rpt_num; // Max 15. u8 siaxis_rpt; // bit0-3: report num. bit4-7: imu type.
// Each report is 800 us? // Each report is 800 us?
jc_hid_in_sixaxis_rpt_t sixaxis[15]; jc_hid_in_sixaxis_rpt_t sixaxis[15];
} jc_sio_hid_in_rpt_t; } jc_sio_hid_in_rpt_t;
+10
View File
@@ -90,6 +90,16 @@ typedef struct _jc_gamepad_rpt_t
jc_bt_conn_t bt_conn_r; jc_bt_conn_t bt_conn_r;
} jc_gamepad_rpt_t; } jc_gamepad_rpt_t;
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_init_hw();
void jc_deinit(); void jc_deinit();
jc_gamepad_rpt_t *joycon_poll(); jc_gamepad_rpt_t *joycon_poll();
+1 -1
View File
@@ -39,7 +39,7 @@ static touch_panel_info_t _panels[] =
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1. { 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3. { 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4. { 3, 1, 0, 0, "GiS 5.5\"" },// 4.
{ 4, 0, 0, 1, "Samsung BH2109" },// 5? { 4, 0, 0, 1, "Samsung TSP" },// 5?
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2. { -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
}; };
+1 -1
View File
@@ -107,7 +107,7 @@
**************************************/ **************************************/
#include <mem/heap.h> /* malloc, calloc, free */ #include <mem/heap.h> /* malloc, calloc, free */
#define ALLOC(s) malloc(s) #define ALLOC(s) malloc(s)
#define ALLOC_AND_ZERO(s) calloc(1,s) #define ALLOC_AND_ZERO(s) zalloc(s)
#define FREEMEM free #define FREEMEM free
#include <string.h> /* memset, memcpy */ #include <string.h> /* memset, memcpy */
#define MEM_INIT memset #define MEM_INIT memset
+2
View File
@@ -6333,6 +6333,8 @@ FRESULT f_mkfs (
LEAVE_MKFS(FR_OK); LEAVE_MKFS(FR_OK);
} }
#if FF_MULTI_PARTITION #if FF_MULTI_PARTITION
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Create Partition Table on the Physical Drive */ /* Create Partition Table on the Physical Drive */
+57
View File
@@ -0,0 +1,57 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C) ChaN, 2018 */
/* (C) CTCaer, 2018-2024 */
/*------------------------------------------------------------------------*/
#include <bdk.h>
#include <libs/fatfs/ff.h>
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
// Ensure size is aligned to SDMMC block size.
return malloc(ALIGN(msize, SDMMC_DAT_BLOCKSIZE)); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
}
#endif
#if FF_FS_NORTC == 0
/*------------------------------------------------------------------------*/
/* Get real time clock */
/*------------------------------------------------------------------------*/
DWORD get_fattime (
void
)
{
rtc_time_t time;
max77620_rtc_get_time_adjusted(&time);
return (((DWORD)(time.year - 1980) << 25) | ((DWORD)time.month << 21) | ((DWORD)time.day << 16) |
((DWORD)time.hour << 11) | ((DWORD)time.min << 5) | (time.sec >> 1));
}
#endif
+7 -4
View File
@@ -17,7 +17,7 @@
#ifndef LV_CONF_H #ifndef LV_CONF_H
#define LV_CONF_H #define LV_CONF_H
#include <utils/types.h> #include <soc/timer.h>
#include <memory_map.h> #include <memory_map.h>
/*=================== /*===================
Dynamic memory Dynamic memory
@@ -126,7 +126,7 @@
#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ #define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/
/*Text settings*/ /*Text settings*/
#define LV_TXT_UTF8 0 /*Enable UTF-8 coded Unicode character usage */ #define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */
#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/ #define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/
#define LV_TXT_LINE_BREAK_LONG_LEN 12 /* If a character is at least this long, will break wherever "prettiest" */ #define LV_TXT_LINE_BREAK_LONG_LEN 12 /* If a character is at least this long, will break wherever "prettiest" */
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 /* Minimum number of characters of a word to put on a line before a break */ #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 /* Minimum number of characters of a word to put on a line before a break */
@@ -147,10 +147,10 @@
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/ #define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
/*HAL settings*/ /*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 #if LV_TICK_CUSTOM == 1
#define LV_TICK_CUSTOM_INCLUDE <soc/timer.h> /*Header for the sys time function*/ #define LV_TICK_CUSTOM_INCLUDE <soc/timer.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_SYS_TIME_EXPR ((u32)get_tmr_ms()) /*Expression evaluating to current systime in ms*/
#endif /*LV_TICK_CUSTOM*/ #endif /*LV_TICK_CUSTOM*/
@@ -296,6 +296,9 @@
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ /*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
#define USE_LV_MBOX 1 #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)*/ /*Text area (dependencies: lv_label, lv_page)*/
#define USE_LV_TA 1 #define USE_LV_TA 1
+2 -2
View File
@@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
/*Move the last_top object to the foreground*/ /*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top); lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/ /*After list change it will be the new head*/
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top); if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
lv_obj_invalidate(last_top); lv_obj_invalidate(last_top); /*Only invalidate if not top*/
} }
} }
+2 -2
View File
@@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*Move the last_top object to the foreground*/ /*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top); lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/ /*After list change it will be the new head*/
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top); if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
lv_obj_invalidate(last_top); lv_obj_invalidate(last_top); /*Only invalidate if not top*/
} }
/*Send a signal about the press*/ /*Send a signal about the press*/
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
#endif #endif
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set. #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 #else
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 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)((uint32_t)(c) >> 8) & 0xFF), \
((uint32_t) c & 0xFF)) ((uint32_t) (c) & 0xFF))
#endif #endif
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/ /*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)), \ #define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \ ((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
((uint32_t)(c & 0xF) | ((c & 0xF) << 4))) ((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
/** /**
+6 -1
View File
@@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
* @param ll_ori_p pointer to the original (old) linked list * @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list * @param ll_new_p pointer to the new linked list
* @param node pointer to a node * @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); lv_ll_rem(ll_ori_p, node);
/*Set node as head*/ /*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*/ if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
ll_new_p->tail = node; ll_new_p->tail = node;
} }
return changed;
} }
/** /**
+2 -1
View File
@@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
* @param ll_ori_p pointer to the original (old) linked list * @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list * @param ll_new_p pointer to the new linked list
* @param node pointer to a node * @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 * Return with head node of the linked list
+31 -27
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2022 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * 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_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_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500) #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_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 * TYPEDEFS
**********************/ **********************/
@@ -57,8 +60,9 @@ static lv_style_t def;
static lv_style_t sb; static lv_style_t sb;
/*Saved input parameters*/ /*Saved input parameters*/
static uint16_t _hue; static uint16_t _hue;
static lv_font_t * _font; static lv_font_t * _font;
uint32_t theme_bg_color;
/********************** /**********************
* MACROS * MACROS
@@ -80,18 +84,17 @@ static void basic_init(void)
//def.image.opa = LV_OPA_COVER; //def.image.opa = LV_OPA_COVER;
lv_style_copy(&bg, &def); lv_style_copy(&bg, &def);
bg.body.main_color = COLOR_HOS_BG; bg.body.main_color = COLOR_BG;
//bg.body.main_color = LV_COLOR_BLACK;
bg.body.grad_color = bg.body.main_color; bg.body.grad_color = bg.body.main_color;
bg.body.radius = 0; bg.body.radius = 0;
bg.body.empty = 1; bg.body.empty = 1;
lv_style_copy(&panel, &def); lv_style_copy(&panel, &def);
panel.body.radius = DEF_RADIUS; panel.body.radius = DEF_RADIUS;
panel.body.main_color = COLOR_HOS_BG; panel.body.main_color = COLOR_BG;
panel.body.grad_color = COLOR_HOS_BG; panel.body.grad_color = COLOR_BG;
panel.body.border.width = 1; 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.border.opa = LV_OPA_COVER;
panel.body.shadow.color = COLOR_SHADOW_LIGHT; panel.body.shadow.color = COLOR_SHADOW_LIGHT;
panel.body.shadow.type = LV_SHADOW_BOTTOM; 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; static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
lv_style_copy(&rel, &def); 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.grad_color = rel.body.main_color;
rel.body.radius = 6; rel.body.radius = 6;
rel.body.padding.hor = LV_DPI / 3; 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.type = LV_SHADOW_BOTTOM;
rel.body.shadow.width = 6; rel.body.shadow.width = 6;
rel.body.border.width = 0; 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.body.border.part = LV_BORDER_FULL;
//rel.text.color = COLOR_HOS_TXT_WHITE; //rel.text.color = COLOR_HOS_TXT_WHITE;
@@ -162,7 +165,7 @@ static void btn_init(void)
tgl_pr.body.shadow.width = 0; tgl_pr.body.shadow.width = 0;
lv_style_copy(&ina, &rel); 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.grad_color = ina.body.main_color;
//ina.body.shadow.width = 0; //ina.body.shadow.width = 0;
ina.text.color = LV_COLOR_HEX(0x888888); ina.text.color = LV_COLOR_HEX(0x888888);
@@ -207,7 +210,7 @@ static void img_init(void)
img_light.image.intense = LV_OPA_80; img_light.image.intense = LV_OPA_80;
lv_style_copy(&img_dark, &def); 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; img_dark.image.intense = LV_OPA_80;
@@ -250,7 +253,7 @@ static void bar_init(void)
static lv_style_t bar_bg, bar_indic; static lv_style_t bar_bg, bar_indic;
lv_style_copy(&bar_bg, &def); 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.grad_color = bar_bg.body.main_color;
bar_bg.body.radius = 3; bar_bg.body.radius = 3;
bar_bg.body.border.width = 0; bar_bg.body.border.width = 0;
@@ -536,9 +539,9 @@ static void mbox_init(void)
static lv_style_t bg; static lv_style_t bg;
lv_style_copy(&bg, theme.panel); 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.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.type = LV_SHADOW_FULL;
bg.body.shadow.width = 8; bg.body.shadow.width = 8;
@@ -628,7 +631,7 @@ static void list_init(void)
// pr.text.font = _font; // pr.text.font = _font;
lv_style_copy(&tgl_rel, &pr); 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.body.grad_color = tgl_rel.body.main_color;
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95); //tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER; tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
@@ -639,7 +642,7 @@ static void list_init(void)
tgl_pr.body.border.width = 0; tgl_pr.body.border.width = 0;
lv_style_copy(&ina, &pr); 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; ina.body.grad_color = ina.body.main_color;
theme.list.sb = &sb; theme.list.sb = &sb;
@@ -667,7 +670,7 @@ static void ddlist_init(void)
bg.text.color = COLOR_HOS_TURQUOISE; bg.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&sel, &bg); 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; sel.body.grad_color = sel.body.main_color;
theme.ddlist.bg = &bg; theme.ddlist.bg = &bg;
@@ -713,7 +716,7 @@ static void tabview_init(void)
indic.body.opa = LV_OPA_0; indic.body.opa = LV_OPA_0;
lv_style_copy(&btn_bg, &def); 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.grad_color = btn_bg.body.main_color;
btn_bg.body.radius = 0; btn_bg.body.radius = 0;
btn_bg.body.empty = 1; btn_bg.body.empty = 1;
@@ -734,7 +737,7 @@ static void tabview_init(void)
rel.text.font = _font; rel.text.font = _font;
lv_style_copy(&pr, &def); 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.grad_color = pr.body.main_color;
pr.body.border.width = 0; pr.body.border.width = 0;
pr.body.empty = 0; pr.body.empty = 0;
@@ -750,7 +753,7 @@ static void tabview_init(void)
tgl_rel.text.color = COLOR_HOS_TURQUOISE; tgl_rel.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&tgl_pr, &def); 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.grad_color = tgl_pr.body.main_color;
tgl_pr.body.border.width = 0; tgl_pr.body.border.width = 0;
tgl_pr.body.empty = 0; tgl_pr.body.empty = 0;
@@ -797,7 +800,7 @@ static void win_init(void)
static lv_style_t header, rel, pr; static lv_style_t header, rel, pr;
lv_style_copy(&header, &def); 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.grad_color = header.body.main_color;
header.body.radius = 0; header.body.radius = 0;
header.body.border.width = 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) * @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme * @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; if(font == NULL) font = LV_FONT_DEFAULT;
theme_bg_color = bg_color;
_hue = hue; _hue = hue;
_font = font; _font = font;
+12 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2022 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -35,6 +35,14 @@ extern "C" {
/********************* /*********************
* DEFINES * 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 * TYPEDEFS
@@ -44,13 +52,15 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
extern uint32_t theme_bg_color;
/** /**
* Initialize the material theme * Initialize the material theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color * @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) * @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme * @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 * Get a pointer to the theme
+21 -21
View File
@@ -70,89 +70,89 @@ typedef struct {
allocation_table_header_t *header; allocation_table_header_t *header;
} allocation_table_ctx_t; } allocation_table_ctx_t;
static ALWAYS_INLINE uint32_t allocation_table_entry_index_to_block(uint32_t entry_index) { static inline __attribute__((always_inline)) uint32_t allocation_table_entry_index_to_block(uint32_t entry_index) {
return entry_index - 1; return entry_index - 1;
} }
static ALWAYS_INLINE uint32_t allocation_table_block_to_entry_index(uint32_t block_index) { static inline __attribute__((always_inline)) uint32_t allocation_table_block_to_entry_index(uint32_t block_index) {
return block_index + 1; return block_index + 1;
} }
static ALWAYS_INLINE int allocation_table_get_prev(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) int allocation_table_get_prev(allocation_table_entry_t *entry) {
return entry->prev & 0x7FFFFFFF; return entry->prev & 0x7FFFFFFF;
} }
static ALWAYS_INLINE int allocation_table_get_next(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) int allocation_table_get_next(allocation_table_entry_t *entry) {
return entry->next & 0x7FFFFFFF; return entry->next & 0x7FFFFFFF;
} }
static ALWAYS_INLINE int allocation_table_is_list_start(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) int allocation_table_is_list_start(allocation_table_entry_t *entry) {
return entry->prev == 0x80000000; return entry->prev == 0x80000000;
} }
static ALWAYS_INLINE int allocation_table_is_list_end(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) int allocation_table_is_list_end(allocation_table_entry_t *entry) {
return (entry->next & 0x7FFFFFFF) == 0; return (entry->next & 0x7FFFFFFF) == 0;
} }
static ALWAYS_INLINE bool allocation_table_is_multi_block_segment(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) bool allocation_table_is_multi_block_segment(allocation_table_entry_t *entry) {
return entry->next & 0x80000000; return entry->next & 0x80000000;
} }
static ALWAYS_INLINE void allocation_table_make_multi_block_segment(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) void allocation_table_make_multi_block_segment(allocation_table_entry_t *entry) {
entry->next |= 0x80000000; entry->next |= 0x80000000;
} }
static ALWAYS_INLINE void allocation_table_make_single_block_segment(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) void allocation_table_make_single_block_segment(allocation_table_entry_t *entry) {
entry->next &= 0x7FFFFFFF; entry->next &= 0x7FFFFFFF;
} }
static ALWAYS_INLINE bool allocation_table_is_single_block_segment(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) bool allocation_table_is_single_block_segment(allocation_table_entry_t *entry) {
return (entry->next & 0x80000000) == 0; return (entry->next & 0x80000000) == 0;
} }
static ALWAYS_INLINE void allocation_table_make_list_start(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) void allocation_table_make_list_start(allocation_table_entry_t *entry) {
entry->prev = 0x80000000; entry->prev = 0x80000000;
} }
static ALWAYS_INLINE bool allocation_table_is_range_entry(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) bool allocation_table_is_range_entry(allocation_table_entry_t *entry) {
return (entry->prev & 0x80000000) == 0x80000000 && entry->prev != 0x80000000; return (entry->prev & 0x80000000) == 0x80000000 && entry->prev != 0x80000000;
} }
static ALWAYS_INLINE void allocation_table_make_range_entry(allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) void allocation_table_make_range_entry(allocation_table_entry_t *entry) {
entry->prev |= 0x80000000; entry->prev |= 0x80000000;
} }
static ALWAYS_INLINE void allocation_table_set_next(allocation_table_entry_t *entry, int val) { static inline __attribute__((always_inline)) void allocation_table_set_next(allocation_table_entry_t *entry, int val) {
entry->next = (entry->next & 0x80000000) | val; entry->next = (entry->next & 0x80000000) | val;
} }
static ALWAYS_INLINE void allocation_table_set_prev(allocation_table_entry_t *entry, int val) { static inline __attribute__((always_inline)) void allocation_table_set_prev(allocation_table_entry_t *entry, int val) {
entry->prev = val; entry->prev = val;
} }
static ALWAYS_INLINE void allocation_table_set_range(allocation_table_entry_t *entry, int start_index, int end_index) { static inline __attribute__((always_inline)) void allocation_table_set_range(allocation_table_entry_t *entry, int start_index, int end_index) {
entry->next = end_index; entry->next = end_index;
entry->prev = start_index; entry->prev = start_index;
allocation_table_make_range_entry(entry); allocation_table_make_range_entry(entry);
} }
static ALWAYS_INLINE uint64_t allocation_table_query_size(uint32_t block_count) { static inline __attribute__((always_inline)) uint64_t allocation_table_query_size(uint32_t block_count) {
return SAVE_FAT_ENTRY_SIZE * allocation_table_block_to_entry_index(block_count); return SAVE_FAT_ENTRY_SIZE * allocation_table_block_to_entry_index(block_count);
} }
static ALWAYS_INLINE allocation_table_entry_t *save_allocation_table_read_entry(allocation_table_ctx_t *ctx, uint32_t entry_index) { static inline __attribute__((always_inline)) allocation_table_entry_t *save_allocation_table_read_entry(allocation_table_ctx_t *ctx, uint32_t entry_index) {
return (allocation_table_entry_t *)((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE); return (allocation_table_entry_t *)((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE);
} }
static ALWAYS_INLINE void save_allocation_table_write_entry(allocation_table_ctx_t *ctx, uint32_t entry_index, allocation_table_entry_t *entry) { static inline __attribute__((always_inline)) void save_allocation_table_write_entry(allocation_table_ctx_t *ctx, uint32_t entry_index, allocation_table_entry_t *entry) {
memcpy((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE, entry, SAVE_FAT_ENTRY_SIZE); memcpy((uint8_t *)ctx->base_storage + entry_index * SAVE_FAT_ENTRY_SIZE, entry, SAVE_FAT_ENTRY_SIZE);
} }
static ALWAYS_INLINE uint32_t save_allocation_table_get_free_list_entry_index(allocation_table_ctx_t *ctx) { static inline __attribute__((always_inline)) uint32_t save_allocation_table_get_free_list_entry_index(allocation_table_ctx_t *ctx) {
return allocation_table_get_next(save_allocation_table_read_entry(ctx, ctx->free_list_entry_index)); return allocation_table_get_next(save_allocation_table_read_entry(ctx, ctx->free_list_entry_index));
} }
static ALWAYS_INLINE uint32_t save_allocation_table_get_free_list_block_index(allocation_table_ctx_t *ctx) { static inline __attribute__((always_inline)) uint32_t save_allocation_table_get_free_list_block_index(allocation_table_ctx_t *ctx) {
return allocation_table_entry_index_to_block(save_allocation_table_get_free_list_entry_index(ctx)); return allocation_table_entry_index_to_block(save_allocation_table_get_free_list_entry_index(ctx));
} }
@@ -48,7 +48,7 @@ typedef struct {
uint64_t _length; uint64_t _length;
} allocation_table_storage_ctx_t; } allocation_table_storage_ctx_t;
static ALWAYS_INLINE void save_allocation_table_storage_get_size(allocation_table_storage_ctx_t *ctx, uint64_t *out_size) { static inline __attribute__((always_inline)) void save_allocation_table_storage_get_size(allocation_table_storage_ctx_t *ctx, uint64_t *out_size) {
*out_size = ctx->_length; *out_size = ctx->_length;
} }
+1 -1
View File
@@ -39,7 +39,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h> #include <string.h>
static ALWAYS_INLINE cache_block_t *cache_block_init(cached_storage_ctx_t *ctx) { static inline __attribute__((always_inline)) cache_block_t *cache_block_init(cached_storage_ctx_t *ctx) {
cache_block_t *block = calloc(1, sizeof(cache_block_t)); cache_block_t *block = calloc(1, sizeof(cache_block_t));
block->buffer = malloc(ctx->block_size); block->buffer = malloc(ctx->block_size);
block->index = -1; block->index = -1;
+3 -3
View File
@@ -57,15 +57,15 @@ typedef struct {
substorage base_storage; substorage base_storage;
} duplex_storage_ctx_t; } duplex_storage_ctx_t;
static ALWAYS_INLINE void save_bitmap_set_bit(void *buffer, uint64_t bit_offset) { static inline __attribute__((always_inline)) void save_bitmap_set_bit(void *buffer, uint64_t bit_offset) {
*((uint8_t *)buffer + (bit_offset >> 3)) |= 1 << (bit_offset & 7); *((uint8_t *)buffer + (bit_offset >> 3)) |= 1 << (bit_offset & 7);
} }
static ALWAYS_INLINE void save_bitmap_clear_bit(void *buffer, uint64_t bit_offset) { static inline __attribute__((always_inline)) void save_bitmap_clear_bit(void *buffer, uint64_t bit_offset) {
*((uint8_t *)buffer + (bit_offset >> 3)) &= ~(uint8_t)(1 << (bit_offset & 7)); *((uint8_t *)buffer + (bit_offset >> 3)) &= ~(uint8_t)(1 << (bit_offset & 7));
} }
static ALWAYS_INLINE uint8_t save_bitmap_check_bit(const void *buffer, uint64_t bit_offset) { static inline __attribute__((always_inline)) uint8_t save_bitmap_check_bit(const void *buffer, uint64_t bit_offset) {
return *((uint8_t *)buffer + (bit_offset >> 3)) & (1 << (bit_offset & 7)); return *((uint8_t *)buffer + (bit_offset >> 3)) & (1 << (bit_offset & 7));
} }
+2 -2
View File
@@ -28,12 +28,12 @@ typedef struct {
uint32_t high; uint32_t high;
} fs_int64_t; } fs_int64_t;
static ALWAYS_INLINE void fs_int64_set(fs_int64_t *i, int64_t val) { static inline __attribute__((always_inline)) void fs_int64_set(fs_int64_t *i, int64_t val) {
i->low = (uint32_t)((val & (uint64_t)(0x00000000FFFFFFFFul)) >> 0); i->low = (uint32_t)((val & (uint64_t)(0x00000000FFFFFFFFul)) >> 0);
i->high = (uint32_t)((val & (uint64_t)(0xFFFFFFFF00000000ul)) >> 32); i->high = (uint32_t)((val & (uint64_t)(0xFFFFFFFF00000000ul)) >> 32);
} }
static ALWAYS_INLINE const int64_t fs_int64_get(fs_int64_t *i) { static inline __attribute__((always_inline)) const int64_t fs_int64_get(fs_int64_t *i) {
return ((int64_t)(i->high) << 32) | ((int64_t)i->low); return ((int64_t)(i->high) << 32) | ((int64_t)i->low);
} }
@@ -311,7 +311,7 @@ bool save_hierarchical_file_table_rename_file(hierarchical_save_file_table_ctx_t
return save_fs_list_change_key(&ctx->file_table, &old_key, &new_key); return save_fs_list_change_key(&ctx->file_table, &old_key, &new_key);
} }
static ALWAYS_INLINE bool save_is_sub_path(const char *path1, const char *path2) { static inline __attribute__((always_inline)) bool save_is_sub_path(const char *path1, const char *path2) {
/* Check if either path is subpath of the other. */ /* Check if either path is subpath of the other. */
uint64_t path1_len = strlen(path1), path2_len = strlen(path2); uint64_t path1_len = strlen(path1), path2_len = strlen(path2);
if (path1_len == 0 || path2_len == 0) if (path1_len == 0 || path2_len == 0)
@@ -50,13 +50,13 @@ void save_ivfc_storage_init(integrity_verification_storage_ctx_t *ctx, integrity
} }
/* buffer must have size count + 0x20 for salt to by copied in at offset 0. */ /* buffer must have size count + 0x20 for salt to by copied in at offset 0. */
static ALWAYS_INLINE void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) { static inline __attribute__((always_inline)) void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) {
memcpy(buffer, ctx->salt, sizeof(ctx->salt)); memcpy(buffer, ctx->salt, sizeof(ctx->salt));
se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt)); se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt));
out_hash[0x1F] |= 0x80; out_hash[0x1F] |= 0x80;
} }
static ALWAYS_INLINE bool is_empty(const void *buffer, uint64_t count) { static inline __attribute__((always_inline)) bool is_empty(const void *buffer, uint64_t count) {
bool empty = true; bool empty = true;
const uint8_t *buf = (const uint8_t *)buffer; const uint8_t *buf = (const uint8_t *)buffer;
for (uint64_t i = 0; i < count; i++) { for (uint64_t i = 0; i < count; i++) {
@@ -39,6 +39,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdint.h> #include <stdint.h>
typedef enum
{
VALIDITY_UNCHECKED = 0,
VALIDITY_INVALID,
VALIDITY_VALID
} validity_t;
typedef struct { typedef struct {
substorage hash_storage; substorage hash_storage;
int integrity_check_level; int integrity_check_level;
+2 -2
View File
@@ -71,11 +71,11 @@ typedef struct {
uint8_t *free_blocks; uint8_t *free_blocks;
} journal_map_ctx_t; } journal_map_ctx_t;
static ALWAYS_INLINE uint32_t save_journal_map_entry_make_physical_index(uint32_t index) { static inline __attribute__((always_inline)) uint32_t save_journal_map_entry_make_physical_index(uint32_t index) {
return index | 0x80000000; return index | 0x80000000;
} }
static ALWAYS_INLINE uint32_t save_journal_map_entry_get_physical_index(uint32_t index) { static inline __attribute__((always_inline)) uint32_t save_journal_map_entry_get_physical_index(uint32_t index) {
return index & 0x7FFFFFFF; return index & 0x7FFFFFFF;
} }
+1 -1
View File
@@ -47,7 +47,7 @@ typedef struct {
bool _finished; bool _finished;
} path_parser_ctx_t; } path_parser_ctx_t;
static ALWAYS_INLINE bool save_path_parser_is_finished(path_parser_ctx_t *ctx) { static inline __attribute__((always_inline)) bool save_path_parser_is_finished(path_parser_ctx_t *ctx) {
return ctx->_finished; return ctx->_finished;
} }
+1 -1
View File
@@ -80,7 +80,7 @@ remap_segment_ctx_t *save_remap_storage_init_segments(remap_storage_ctx_t *ctx)
return segments; return segments;
} }
static ALWAYS_INLINE remap_entry_ctx_t *save_remap_storage_get_map_entry(remap_storage_ctx_t *ctx, uint64_t offset) { static inline __attribute__((always_inline)) remap_entry_ctx_t *save_remap_storage_get_map_entry(remap_storage_ctx_t *ctx, uint64_t offset) {
uint32_t segment_idx = save_remap_get_segment_from_virtual_offset(ctx->header, offset); uint32_t segment_idx = save_remap_get_segment_from_virtual_offset(ctx->header, offset);
if (segment_idx < ctx->header->map_segment_count) { if (segment_idx < ctx->header->map_segment_count) {
for (unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++) { for (unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++) {
+2 -2
View File
@@ -89,11 +89,11 @@ typedef struct {
substorage base_storage; substorage base_storage;
} remap_storage_ctx_t; } remap_storage_ctx_t;
static ALWAYS_INLINE uint32_t save_remap_get_segment_from_virtual_offset(remap_header_t *header, uint64_t offset) { static inline __attribute__((always_inline)) uint32_t save_remap_get_segment_from_virtual_offset(remap_header_t *header, uint64_t offset) {
return (uint32_t)(offset >> (64 - header->segment_bits)); return (uint32_t)(offset >> (64 - header->segment_bits));
} }
static ALWAYS_INLINE uint64_t save_remap_get_virtual_offset(remap_header_t *header, uint64_t segment) { static inline __attribute__((always_inline)) uint64_t save_remap_get_virtual_offset(remap_header_t *header, uint64_t segment) {
return segment << (64 - header->segment_bits); return segment << (64 - header->segment_bits);
} }
+3 -3
View File
@@ -106,7 +106,7 @@ static bool save_process_header(save_ctx_t *ctx) {
uint8_t cmac[0x10] __attribute__((aligned(4))); uint8_t cmac[0x10] __attribute__((aligned(4)));
se_aes_key_set(10, ctx->save_mac_key, 0x10); se_aes_key_set(10, ctx->save_mac_key, 0x10);
se_aes_cmac(10, cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout)); se_aes_cmac_128(10, cmac, &ctx->header.layout, sizeof(ctx->header.layout));
if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) { if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) {
ctx->header_cmac_validity = VALIDITY_VALID; ctx->header_cmac_validity = VALIDITY_VALID;
} else { } else {
@@ -298,7 +298,7 @@ void save_free_contexts(save_ctx_t *ctx) {
free(ctx->fat_storage); free(ctx->fat_storage);
} }
static ALWAYS_INLINE bool save_flush(save_ctx_t *ctx) { static inline __attribute__((always_inline)) bool save_flush(save_ctx_t *ctx) {
if (ctx->header.layout.version < VERSION_DISF_5) { if (ctx->header.layout.version < VERSION_DISF_5) {
if (!save_cached_storage_flush(ctx->core_data_ivfc_storage.data_level)) { if (!save_cached_storage_flush(ctx->core_data_ivfc_storage.data_level)) {
EPRINTF("Failed to flush cached storage!"); EPRINTF("Failed to flush cached storage!");
@@ -329,7 +329,7 @@ bool save_commit(save_ctx_t *ctx) {
se_calc_sha256_oneshot(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size); se_calc_sha256_oneshot(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size);
se_aes_key_set(10, ctx->save_mac_key, 0x10); se_aes_key_set(10, ctx->save_mac_key, 0x10);
se_aes_cmac(10, ctx->header.cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout)); se_aes_cmac_128(10, ctx->header.cmac, &ctx->header.layout, sizeof(ctx->header.layout));
if (substorage_write(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) { if (substorage_write(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) {
EPRINTF("Failed to write save header!"); EPRINTF("Failed to write save header!");
+12 -12
View File
@@ -95,7 +95,7 @@ typedef struct {
static_assert(sizeof(save_data_creation_info_t) == 0x40, "Save data creation info size is wrong!"); static_assert(sizeof(save_data_creation_info_t) == 0x40, "Save data creation info size is wrong!");
static ALWAYS_INLINE uint32_t save_calc_map_entry_storage_size(int32_t entry_count) { static inline __attribute__((always_inline)) uint32_t save_calc_map_entry_storage_size(int32_t entry_count) {
int32_t val = entry_count < 1 ? entry_count : entry_count - 1; int32_t val = entry_count < 1 ? entry_count : entry_count - 1;
return (entry_count + (val >> 1)) * sizeof(remap_entry_t); return (entry_count + (val >> 1)) * sizeof(remap_entry_t);
} }
@@ -107,47 +107,47 @@ bool save_create_system_save_data(save_ctx_t *ctx, uint32_t version, const char
void save_free_contexts(save_ctx_t *ctx); void save_free_contexts(save_ctx_t *ctx);
bool save_commit(save_ctx_t *ctx); bool save_commit(save_ctx_t *ctx);
static ALWAYS_INLINE bool save_create_directory(save_ctx_t *ctx, const char *path) { static inline __attribute__((always_inline)) bool save_create_directory(save_ctx_t *ctx, const char *path) {
return save_data_file_system_core_create_directory(&ctx->save_filesystem_core, path); return save_data_file_system_core_create_directory(&ctx->save_filesystem_core, path);
} }
static ALWAYS_INLINE bool save_create_file(save_ctx_t *ctx, const char *path, uint64_t size) { static inline __attribute__((always_inline)) bool save_create_file(save_ctx_t *ctx, const char *path, uint64_t size) {
return save_data_file_system_core_create_file(&ctx->save_filesystem_core, path, size); return save_data_file_system_core_create_file(&ctx->save_filesystem_core, path, size);
} }
static ALWAYS_INLINE bool save_delete_directory(save_ctx_t *ctx, const char *path) { static inline __attribute__((always_inline)) bool save_delete_directory(save_ctx_t *ctx, const char *path) {
return save_data_file_system_core_delete_directory(&ctx->save_filesystem_core,path); return save_data_file_system_core_delete_directory(&ctx->save_filesystem_core,path);
} }
static ALWAYS_INLINE bool save_delete_file(save_ctx_t *ctx, const char *path) { static inline __attribute__((always_inline)) bool save_delete_file(save_ctx_t *ctx, const char *path) {
return save_data_file_system_core_delete_file(&ctx->save_filesystem_core, path); return save_data_file_system_core_delete_file(&ctx->save_filesystem_core, path);
} }
static ALWAYS_INLINE bool save_open_directory(save_ctx_t *ctx, save_data_directory_ctx_t *directory, const char *path, open_directory_mode_t mode) { static inline __attribute__((always_inline)) bool save_open_directory(save_ctx_t *ctx, save_data_directory_ctx_t *directory, const char *path, open_directory_mode_t mode) {
return save_data_file_system_core_open_directory(&ctx->save_filesystem_core, directory, path, mode); return save_data_file_system_core_open_directory(&ctx->save_filesystem_core, directory, path, mode);
} }
static ALWAYS_INLINE bool save_open_file(save_ctx_t *ctx, save_data_file_ctx_t *file, const char *path, open_mode_t mode) { static inline __attribute__((always_inline)) bool save_open_file(save_ctx_t *ctx, save_data_file_ctx_t *file, const char *path, open_mode_t mode) {
return save_data_file_system_core_open_file(&ctx->save_filesystem_core, file, path, mode); return save_data_file_system_core_open_file(&ctx->save_filesystem_core, file, path, mode);
} }
static ALWAYS_INLINE bool save_rename_directory(save_ctx_t *ctx, const char *old_path, const char *new_path) { static inline __attribute__((always_inline)) bool save_rename_directory(save_ctx_t *ctx, const char *old_path, const char *new_path) {
return save_data_file_system_core_rename_directory(&ctx->save_filesystem_core, old_path, new_path); return save_data_file_system_core_rename_directory(&ctx->save_filesystem_core, old_path, new_path);
} }
static ALWAYS_INLINE bool save_rename_file(save_ctx_t *ctx, const char *old_path, const char *new_path) { static inline __attribute__((always_inline)) bool save_rename_file(save_ctx_t *ctx, const char *old_path, const char *new_path) {
return save_data_file_system_core_rename_file(&ctx->save_filesystem_core, old_path, new_path); return save_data_file_system_core_rename_file(&ctx->save_filesystem_core, old_path, new_path);
} }
static ALWAYS_INLINE bool save_get_entry_type(save_ctx_t *ctx, directory_entry_type_t *out_entry_type, const char *path) { static inline __attribute__((always_inline)) bool save_get_entry_type(save_ctx_t *ctx, directory_entry_type_t *out_entry_type, const char *path) {
return save_data_file_system_core_get_entry_type(&ctx->save_filesystem_core, out_entry_type, path); return save_data_file_system_core_get_entry_type(&ctx->save_filesystem_core, out_entry_type, path);
} }
static ALWAYS_INLINE void save_get_free_space_size(save_ctx_t *ctx, uint64_t *out_free_space) { static inline __attribute__((always_inline)) void save_get_free_space_size(save_ctx_t *ctx, uint64_t *out_free_space) {
return save_data_file_system_core_get_free_space_size(&ctx->save_filesystem_core, out_free_space); return save_data_file_system_core_get_free_space_size(&ctx->save_filesystem_core, out_free_space);
} }
static ALWAYS_INLINE void save_get_total_space_size(save_ctx_t *ctx, uint64_t *out_total_size) { static inline __attribute__((always_inline)) void save_get_total_space_size(save_ctx_t *ctx, uint64_t *out_total_size) {
return save_data_file_system_core_get_total_space_size(&ctx->save_filesystem_core, out_total_size); return save_data_file_system_core_get_total_space_size(&ctx->save_filesystem_core, out_total_size);
} }
+10 -1
View File
@@ -42,6 +42,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdint.h> #include <stdint.h>
typedef enum
{
OPEN_MODE_READ = 1,
OPEN_MODE_WRITE = 2,
OPEN_MODE_ALLOW_APPEND = 4,
OPEN_MODE_READ_WRITE = OPEN_MODE_READ | OPEN_MODE_WRITE,
OPEN_MODE_ALL = OPEN_MODE_READ | OPEN_MODE_WRITE | OPEN_MODE_ALLOW_APPEND
} open_mode_t;
typedef struct { typedef struct {
allocation_table_storage_ctx_t base_storage; allocation_table_storage_ctx_t base_storage;
const char *path; const char *path;
@@ -50,7 +59,7 @@ typedef struct {
open_mode_t mode; open_mode_t mode;
} save_data_file_ctx_t; } save_data_file_ctx_t;
static ALWAYS_INLINE void save_data_file_get_size(save_data_file_ctx_t *ctx, uint64_t *out_size) { static inline __attribute__((always_inline)) void save_data_file_get_size(save_data_file_ctx_t *ctx, uint64_t *out_size) {
*out_size = ctx->size; *out_size = ctx->size;
} }
@@ -41,7 +41,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <gfx_utils.h> #include <gfx_utils.h>
#include <mem/heap.h> #include <mem/heap.h>
static ALWAYS_INLINE bool save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) { static inline __attribute__((always_inline)) bool save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) {
return save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index); return save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index);
} }
@@ -49,20 +49,20 @@ typedef struct {
hierarchical_save_file_table_ctx_t file_table; hierarchical_save_file_table_ctx_t file_table;
} save_data_file_system_core_ctx_t; } save_data_file_system_core_ctx_t;
static ALWAYS_INLINE bool save_data_file_system_core_rename_directory(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) { static inline __attribute__((always_inline)) bool save_data_file_system_core_rename_directory(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
return save_hierarchical_file_table_rename_directory(&ctx->file_table, old_path, new_path); return save_hierarchical_file_table_rename_directory(&ctx->file_table, old_path, new_path);
} }
static ALWAYS_INLINE bool save_data_file_system_core_rename_file(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) { static inline __attribute__((always_inline)) bool save_data_file_system_core_rename_file(save_data_file_system_core_ctx_t *ctx, const char *old_path, const char *new_path) {
return save_hierarchical_file_table_rename_file(&ctx->file_table, old_path, new_path); return save_hierarchical_file_table_rename_file(&ctx->file_table, old_path, new_path);
} }
static ALWAYS_INLINE void save_data_file_system_core_get_free_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_free_space) { static inline __attribute__((always_inline)) void save_data_file_system_core_get_free_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_free_space) {
uint32_t free_block_count = save_allocation_table_get_free_list_length(&ctx->allocation_table); uint32_t free_block_count = save_allocation_table_get_free_list_length(&ctx->allocation_table);
*out_free_space = ctx->header->block_size * free_block_count; *out_free_space = ctx->header->block_size * free_block_count;
} }
static ALWAYS_INLINE void save_data_file_system_core_get_total_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_total_space) { static inline __attribute__((always_inline)) void save_data_file_system_core_get_total_space_size(save_data_file_system_core_ctx_t *ctx, uint64_t *out_total_space) {
*out_total_space = ctx->header->block_size * ctx->header->block_count; *out_total_space = ctx->header->block_size * ctx->header->block_count;
} }
+4 -4
View File
@@ -43,7 +43,7 @@ void save_fs_list_init(save_filesystem_list_ctx_t *ctx) {
ctx->used_list_head_index = 1; ctx->used_list_head_index = 1;
} }
static ALWAYS_INLINE uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx_t *ctx) { static inline __attribute__((always_inline)) uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx_t *ctx) {
uint32_t capacity; uint32_t capacity;
if (save_allocation_table_storage_read(&ctx->storage, &capacity, 4, 4) != 4) { if (save_allocation_table_storage_read(&ctx->storage, &capacity, 4, 4) != 4) {
EPRINTF("Failed to read FS list capacity!"); EPRINTF("Failed to read FS list capacity!");
@@ -52,7 +52,7 @@ static ALWAYS_INLINE uint32_t save_fs_list_get_capacity(save_filesystem_list_ctx
return capacity; return capacity;
} }
static ALWAYS_INLINE uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t *ctx) { static inline __attribute__((always_inline)) uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t *ctx) {
uint32_t length; uint32_t length;
if (save_allocation_table_storage_read(&ctx->storage, &length, 0, 4) != 4) { if (save_allocation_table_storage_read(&ctx->storage, &length, 0, 4) != 4) {
EPRINTF("Failed to read FS list length!"); EPRINTF("Failed to read FS list length!");
@@ -61,11 +61,11 @@ static ALWAYS_INLINE uint32_t save_fs_list_get_length(save_filesystem_list_ctx_t
return length; return length;
} }
static ALWAYS_INLINE bool save_fs_list_set_capacity(save_filesystem_list_ctx_t *ctx, uint32_t capacity) { static inline __attribute__((always_inline)) bool save_fs_list_set_capacity(save_filesystem_list_ctx_t *ctx, uint32_t capacity) {
return save_allocation_table_storage_write(&ctx->storage, &capacity, 4, 4) == 4; return save_allocation_table_storage_write(&ctx->storage, &capacity, 4, 4) == 4;
} }
static ALWAYS_INLINE bool save_fs_list_set_length(save_filesystem_list_ctx_t *ctx, uint32_t length) { static inline __attribute__((always_inline)) bool save_fs_list_set_length(save_filesystem_list_ctx_t *ctx, uint32_t length) {
return save_allocation_table_storage_write(&ctx->storage, &length, 0, 4) == 4; return save_allocation_table_storage_write(&ctx->storage, &length, 0, 4) == 4;
} }
+2 -2
View File
@@ -76,11 +76,11 @@ typedef struct {
static_assert(sizeof(save_fs_list_entry_t) == 0x60, "Save filesystem list entry size is wrong!"); static_assert(sizeof(save_fs_list_entry_t) == 0x60, "Save filesystem list entry size is wrong!");
static ALWAYS_INLINE uint32_t save_fs_list_read_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, void *entry) { static inline __attribute__((always_inline)) uint32_t save_fs_list_read_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, void *entry) {
return save_allocation_table_storage_read(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE); return save_allocation_table_storage_read(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
} }
static ALWAYS_INLINE uint32_t save_fs_list_write_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, const void *entry) { static inline __attribute__((always_inline)) uint32_t save_fs_list_write_entry(save_filesystem_list_ctx_t *ctx, uint32_t index, const void *entry) {
return save_allocation_table_storage_write(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE); return save_allocation_table_storage_write(&ctx->storage, entry, index * SAVE_FS_LIST_ENTRY_SIZE, SAVE_FS_LIST_ENTRY_SIZE);
} }
+7 -5
View File
@@ -39,6 +39,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <utils/types.h> #include <utils/types.h>
#define DIV_ROUND_UP(a, b) ((a + b - 1) / b)
typedef struct { typedef struct {
uint32_t (*read)(void *ctx, void *buffer, uint64_t offset, uint64_t count); uint32_t (*read)(void *ctx, void *buffer, uint64_t offset, uint64_t count);
uint32_t (*write)(void *ctx, const void *buffer, uint64_t offset, uint64_t count); uint32_t (*write)(void *ctx, const void *buffer, uint64_t offset, uint64_t count);
@@ -51,7 +53,7 @@ typedef struct {
void *ctx; void *ctx;
} storage; } storage;
static void ALWAYS_INLINE storage_init(storage *this, const storage_vt *vt, void *ctx) { static void inline __attribute__((always_inline)) storage_init(storage *this, const storage_vt *vt, void *ctx) {
this->vt = vt; this->vt = vt;
this->ctx = ctx; this->ctx = ctx;
} }
@@ -65,15 +67,15 @@ typedef struct {
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length); void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length);
bool substorage_init_from_other(substorage *this, const substorage *other, uint64_t offset, uint64_t length); bool substorage_init_from_other(substorage *this, const substorage *other, uint64_t offset, uint64_t length);
static ALWAYS_INLINE uint32_t substorage_read(substorage *ctx, void *buffer, uint64_t offset, uint64_t count) { static inline __attribute__((always_inline)) uint32_t substorage_read(substorage *ctx, void *buffer, uint64_t offset, uint64_t count) {
return ctx->base_storage.vt->read(ctx->base_storage.ctx, buffer, ctx->offset + offset, count); return ctx->base_storage.vt->read(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
} }
static ALWAYS_INLINE uint32_t substorage_write(substorage *ctx, const void *buffer, uint64_t offset, uint64_t count) { static inline __attribute__((always_inline)) uint32_t substorage_write(substorage *ctx, const void *buffer, uint64_t offset, uint64_t count) {
return ctx->base_storage.vt->write(ctx->base_storage.ctx, buffer, ctx->offset + offset, count); return ctx->base_storage.vt->write(ctx->base_storage.ctx, buffer, ctx->offset + offset, count);
} }
static ALWAYS_INLINE void substorage_get_size(substorage *ctx, uint64_t *out_size) { static inline __attribute__((always_inline)) void substorage_get_size(substorage *ctx, uint64_t *out_size) {
ctx->base_storage.vt->get_size(ctx->base_storage.ctx, out_size); ctx->base_storage.vt->get_size(ctx->base_storage.ctx, out_size);
} }
@@ -162,7 +164,7 @@ static const storage_vt hierarchical_duplex_storage_vt = {
save_hierarchical_duplex_storage_get_size_wrapper save_hierarchical_duplex_storage_get_size_wrapper
}; };
static ALWAYS_INLINE bool is_range_valid(uint64_t offset, uint64_t size, uint64_t total_size) { static inline __attribute__((always_inline)) bool is_range_valid(uint64_t offset, uint64_t size, uint64_t total_size) {
return offset >= 0 && return offset >= 0 &&
size >= 0 && size >= 0 &&
size <= total_size && size <= total_size &&
+9 -1
View File
@@ -698,6 +698,8 @@
typedef enum _emc_mr_t typedef enum _emc_mr_t
{ {
MR0_FEAT = 0,
MR4_TEMP = 4,
MR5_MAN_ID = 5, MR5_MAN_ID = 5,
MR6_REV_ID1 = 6, MR6_REV_ID1 = 6,
MR7_REV_ID2 = 7, MR7_REV_ID2 = 7,
@@ -710,7 +712,7 @@ enum
EMC_CHAN1 = 1 EMC_CHAN1 = 1
}; };
typedef struct _emc_mr_data_t typedef struct _emc_mr_chip_data_t
{ {
// Device 0. // Device 0.
u8 rank0_ch0; u8 rank0_ch0;
@@ -719,6 +721,12 @@ typedef struct _emc_mr_data_t
// Device 1. // Device 1.
u8 rank1_ch0; u8 rank1_ch0;
u8 rank1_ch1; u8 rank1_ch1;
} emc_mr_chip_data_t;
typedef struct _emc_mr_data_t
{
emc_mr_chip_data_t chip0;
emc_mr_chip_data_t chip1;
} emc_mr_data_t; } emc_mr_data_t;
#endif #endif
+8 -1
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -159,6 +159,13 @@ void *calloc(u32 num, u32 size)
return res; return res;
} }
void *zalloc(u32 size)
{
void *res = (void *)_heap_alloc(size);
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
return res;
}
void free(void *buf) void free(void *buf)
{ {
if (buf >= _heap.start) if (buf >= _heap.start)
+2 -1
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -48,6 +48,7 @@ void heap_init(void *base);
void heap_set(heap_t *heap); void heap_set(heap_t *heap);
void *malloc(u32 size); void *malloc(u32 size);
void *calloc(u32 num, u32 size); void *calloc(u32 num, u32 size);
void *zalloc(u32 size);
void free(void *buf); void free(void *buf);
void heap_monitor(heap_monitor_t *mon, bool print_node_stats); void heap_monitor(heap_monitor_t *mon, bool print_node_stats);
+25 -76
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -21,7 +21,7 @@
#include <soc/t210.h> #include <soc/t210.h>
#include <soc/clock.h> #include <soc/clock.h>
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock) void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
{ {
MC(MC_SEC_CARVEOUT_BOM) = bom; MC(MC_SEC_CARVEOUT_BOM) = bom;
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb; MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
@@ -31,96 +31,47 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
void mc_config_carveout() void mc_config_carveout()
{ {
// Enable ACR GSR3.
*(vu32 *)0x8005FFFC = 0xC0EDBBCC; *(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MC(MC_VIDEO_PROTECT_BOM) = 0; MC(MC_VIDEO_PROTECT_BOM) = 0;
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0; MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
// Configure TSEC carveout @ 0x90000000, 1MB. // Configure TZDRAM carveout @ 0x90000000, 1MB.
//mc_config_tsec_carveout(0x90000000, 1, false); //mc_config_tzdram_carveout(0x90000000, 1, false);
mc_config_tsec_carveout(0, 0, true); mc_config_tzdram_carveout(0, 0, true);
MC(MC_MTS_CARVEOUT_BOM) = 0; MC(MC_MTS_CARVEOUT_BOM) = 0;
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1; MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0; MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0; MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0; MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0; MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0; SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0; SEC_CARVEOUT_CFG_APERTURE_ID(0) |
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0; SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000; MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0; MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0; MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0; MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0; MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0; MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0; SEC_CARVEOUT_CFG_LOCKED |
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0; SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0; SEC_CARVEOUT_CFG_RD_NS |
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0; SEC_CARVEOUT_CFG_WR_NS;
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0; MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0; MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0; MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0; SEC_CARVEOUT_CFG_LOCKED |
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0; SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0; SEC_CARVEOUT_CFG_RD_NS |
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0; SEC_CARVEOUT_CFG_WR_NS;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
} }
void mc_enable_ahb_redirect() void mc_enable_ahb_redirect()
@@ -157,12 +108,10 @@ bool mc_client_has_access(void *address)
void mc_enable() void mc_enable()
{ {
// Reset EMC source to PLLP. // Reset EMC source to PLLP.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29); CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
// Enable memory clocks. // Enable and clear reset for 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_EMC) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
// Clear clock resets for memory.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM); CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
usleep(5); usleep(5);
+23 -6
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved. * Copyright (c) 2014, NVIDIA Corporation.
* Copyright (c) 2018-2023, CTCaer
* *
* This software is licensed under the terms of the GNU General Public * This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and * License version 2, as published by the Free Software Foundation, and
@@ -14,6 +15,22 @@
#ifndef _MC_T210_H_ #ifndef _MC_T210_H_
#define _MC_T210_H_ #define _MC_T210_H_
/*! MC SMMU registers */
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
/*! MC General registers */
#define MC_INTSTATUS 0x0 #define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4 #define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8 #define MC_ERR_STATUS 0x8
@@ -464,7 +481,7 @@
#define MC_UNTRANSLATED_REGION_CHECK 0x948 #define MC_UNTRANSLATED_REGION_CHECK 0x948
#define MC_DA_CONFIG0 0x9dc #define MC_DA_CONFIG0 0x9dc
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */
#define SEC_CARVEOUT_CA0_R_PTCR BIT(0) #define SEC_CARVEOUT_CA0_R_PTCR BIT(0)
#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1) #define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1)
#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2) #define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2)
@@ -484,7 +501,7 @@
#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30) #define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30)
#define SEC_CARVEOUT_CA0_R_SATAR BIT(31) #define SEC_CARVEOUT_CA0_R_SATAR BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */
#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2) #define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2)
#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3) #define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3)
#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4) #define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4)
@@ -504,7 +521,7 @@
#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30) #define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30)
#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31) #define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */
#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0) #define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0)
#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1) #define SEC_CARVEOUT_CA2_W_VDETPM BIT(1)
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4) #define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
@@ -524,7 +541,7 @@
#define SEC_CARVEOUT_CA2_W_GPU BIT(25) #define SEC_CARVEOUT_CA2_W_GPU BIT(25)
#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26) #define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */
#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0) #define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0)
#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1) #define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1)
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2) #define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
@@ -544,7 +561,7 @@
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30) #define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31) #define SEC_CARVEOUT_CA3_W_NVJPG BIT(31)
/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */ /*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */
#define SEC_CARVEOUT_CA4_R_SE BIT(0) #define SEC_CARVEOUT_CA4_R_SE BIT(0)
#define SEC_CARVEOUT_CA4_W_SE BIT(1) #define SEC_CARVEOUT_CA4_W_SE BIT(1)
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2) #define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)
+60 -25
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -27,13 +27,18 @@
#include <soc/t210.h> #include <soc/t210.h>
#include <utils/util.h> #include <utils/util.h>
#define TABLE_FREQ_KHZ_OFFSET 0x40
#define TABLE_LA_REGS_T210_OFFSET 0x1284
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
#define LA_SDMMC1_INDEX 6
extern volatile nyx_storage_t *nyx_str; extern volatile nyx_storage_t *nyx_str;
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *); void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init() u32 minerva_init()
{ {
u32 curr_ram_idx = 0; u32 tbl_idx = 0;
minerva_cfg = NULL; minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
@@ -98,13 +103,13 @@ u32 minerva_init()
// Get current frequency // Get current frequency
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC); 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; 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->rate_to = FREQ_204;
mtc_cfg->train_mode = OP_TRAIN; mtc_cfg->train_mode = OP_TRAIN;
minerva_cfg(mtc_cfg, NULL); minerva_cfg(mtc_cfg, NULL);
@@ -140,6 +145,27 @@ void minerva_change_freq(minerva_freq_t freq)
} }
} }
void minerva_sdmmc_la_program(void *table, bool t210b01)
{
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
// Adjust SDMMC1 latency allowance.
switch (freq)
{
case 204000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
break;
case 408000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
break;
default:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
break;
}
}
void minerva_prep_boot_freq() void minerva_prep_boot_freq()
{ {
if (!minerva_cfg) if (!minerva_cfg)
@@ -157,23 +183,46 @@ void minerva_prep_boot_freq()
minerva_change_freq(FREQ_800); minerva_change_freq(FREQ_800);
} }
void minerva_prep_boot_l4t(int oc_freq) void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
{ {
if (!minerva_cfg) if (!minerva_cfg)
return; return;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; 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. // Add OC frequency.
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600) 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], memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1], &mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
sizeof(emc_table_t)); sizeof(emc_table_t));
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
mtc_cfg->table_entries++; mtc_cfg->table_entries++;
} }
// Trim table.
int entries = 0;
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
int rate = mtc_cfg->mtc_table[i].rate_khz;
if (rate == FREQ_204 ||
rate == FREQ_408 ||
rate == FREQ_800 ||
rate >= FREQ_1333)
{
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
entries++;
}
}
mtc_cfg->table_entries = entries;
// Set init frequency. // Set init frequency.
minerva_change_freq(FREQ_204); minerva_change_freq(FREQ_204);
@@ -181,35 +230,21 @@ void minerva_prep_boot_l4t(int oc_freq)
mtc_cfg->train_mode = OP_TRAIN; mtc_cfg->train_mode = OP_TRAIN;
for (u32 i = 0; i < mtc_cfg->table_entries; i++) for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{ {
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz; // Skip already trained frequencies and OC freq (Arachne handles it).
// Skip already trained frequencies. if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
if (mtc_cfg->rate_to == FREQ_204 || mtc_cfg->rate_to == FREQ_800 || mtc_cfg->rate_to == FREQ_1600)
continue; continue;
// Train frequency. // Train frequency.
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
minerva_cfg(mtc_cfg, NULL); minerva_cfg(mtc_cfg, NULL);
} }
// Do FSP WAR and scale to 800 MHz as boot freq. // Do FSP WAR and scale to 800 MHz as boot freq.
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0); bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
if (fsp_opwr_disabled) if (fsp_opwr_disabled)
minerva_change_freq(FREQ_666); minerva_change_freq(FREQ_1333);
minerva_change_freq(FREQ_800); 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. // Do not let other mtc ops.
mtc_cfg->init_done = 0; mtc_cfg->init_done = 0;
} }
+4 -2
View File
@@ -53,16 +53,18 @@ enum train_mode_t
typedef enum typedef enum
{ {
FREQ_204 = 204000, FREQ_204 = 204000,
FREQ_666 = 665600, FREQ_408 = 408000,
FREQ_800 = 800000, FREQ_800 = 800000,
FREQ_1333 = 1331200,
FREQ_1600 = 1600000 FREQ_1600 = 1600000
} minerva_freq_t; } minerva_freq_t;
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *); extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init(); u32 minerva_init();
void minerva_change_freq(minerva_freq_t freq); 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_freq();
void minerva_prep_boot_l4t(int oc_freq); void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom);
void minerva_periodic_training(); void minerva_periodic_training();
emc_table_t *minerva_get_mtc_table(); emc_table_t *minerva_get_mtc_table();
int minerva_get_mtc_table_entries(); int minerva_get_mtc_table_entries();
+2 -1
View File
@@ -481,7 +481,8 @@ typedef struct
u32 rate_khz; u32 rate_khz;
u32 min_volt; u32 min_volt;
u32 gpu_min_volt; u32 gpu_min_volt;
char clock_src[32]; char clock_src[28];
u32 opt_custom;
u32 clk_src_emc; u32 clk_src_emc;
u32 needs_training; u32 needs_training;
u32 training_pattern; u32 training_pattern;
+68 -43
View File
@@ -42,8 +42,8 @@
typedef struct _sdram_vendor_patch_t typedef struct _sdram_vendor_patch_t
{ {
u32 val; u32 val;
u32 offset:16;
u32 dramcf:16; u32 dramcf:16;
u32 offset:16;
} sdram_vendor_patch_t; } sdram_vendor_patch_t;
static const u8 dram_encoding_t210b01[] = { static const u8 dram_encoding_t210b01[] = {
@@ -67,21 +67,21 @@ static const u8 dram_encoding_t210b01[] = {
/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, /* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, /* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, /* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 20 */ LPDDR4X_4GB_SAMSUNG_1Z, /* 20 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 21 */ LPDDR4X_4GB_SAMSUNG_1Z, /* 21 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 22 */ LPDDR4X_4GB_SAMSUNG_1Z, /* 22 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, /* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, /* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, /* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, /* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, /* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, /* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 29 */ LPDDR4X_4GB_HYNIX_1A, /* 29 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 30 */ LPDDR4X_4GB_HYNIX_1A, /* 30 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 31 */ LPDDR4X_4GB_HYNIX_1A, /* 31 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 32 */ LPDDR4X_4GB_MICRON_1A, /* 32 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 33 */ LPDDR4X_4GB_MICRON_1A, /* 33 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 34 */ LPDDR4X_4GB_MICRON_1A, /* 34 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
}; };
#include "sdram_config.inl" #include "sdram_config.inl"
@@ -127,15 +127,19 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel)
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
{ {
emc_mr_data_t data; emc_mr_data_t data;
u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; u32 mrr;
bool dual_rank = EMC(EMC_ADR_CFG) & 1;
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; // Each EMC channel is a RAM chip module.
// Clear left overs. // Clear left overs.
for (u32 i = 0; i < 32; i++) for (u32 i = 0; i < 16; i++)
{ {
(void)EMC(EMC_MRR); (void)EMC(EMC_MRR);
usleep(1); usleep(1);
} }
memset(&data, 0xFF, sizeof(emc_mr_data_t));
/* /*
* When a dram chip has only one rank, then the info from the 2 ranks differs. * When a dram chip has only one rank, then the info from the 2 ranks differs.
* Info not matching is only allowed on different channels. * Info not matching is only allowed on different channels.
@@ -143,21 +147,38 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx)
// Get Device 0 (Rank 0) info from both dram chips (channels). // Get Device 0 (Rank 0) info from both dram chips (channels).
_sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel); _sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel);
data.rank0_ch0 = EMC(EMC_MRR) & 0xFF;
data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); // Ram module 0 info.
mrr = EMC_CH0(EMC_MRR);
data.chip0.rank0_ch0 = mrr & 0xFF;
data.chip0.rank0_ch1 = (mrr & 0xFF00 >> 8);
// Ram module 1 info.
if (dual_channel)
{
mrr = EMC_CH1(EMC_MRR);
data.chip1.rank0_ch0 = mrr & 0xFF;
data.chip1.rank0_ch1 = (mrr & 0xFF00 >> 8);
}
// If Rank 1 exists, get info. // If Rank 1 exists, get info.
if (EMC(EMC_ADR_CFG) & 1) if (dual_rank)
{ {
// Get Device 1 (Rank 1) info from both dram chips (channels). // Get Device 1 (Rank 1) info from both dram chips (channels).
_sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel); _sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel);
data.rank1_ch0 = EMC(EMC_MRR) & 0xFF;
data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); // Ram module 0 info.
} mrr = EMC_CH0(EMC_MRR);
else data.chip0.rank1_ch0 = mrr & 0xFF;
{ data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
data.rank1_ch0 = 0xFF;
data.rank1_ch1 = 0xFF; // Ram module 1 info.
if (dual_channel)
{
mrr = EMC_CH1(EMC_MRR);
data.chip1.rank1_ch0 = mrr & 0xFF;
data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
}
} }
return data; return data;
@@ -167,12 +188,12 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
{ {
// Program DPD3/DPD4 regs (coldboot path). // Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins. // Enable sel_dpd on unused pins.
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000; u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF; PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
usleep(params->pmc_io_dpd3_req_wait); usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen. // Disable e_dpd_vttgen.
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000; dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000; PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
usleep(params->pmc_io_dpd4_req_wait); usleep(params->pmc_io_dpd4_req_wait);
@@ -209,7 +230,7 @@ break_nosleep:
if (params->emc_clock_source_dll) if (params->emc_clock_source_dll)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll; CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1) if (params->clear_clock2_mc1)
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_MC1); // Clear Reset to MC1.
// Enable and clear reset for memory clocks. // Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
@@ -233,7 +254,7 @@ break_nosleep:
// Program CMD mapping. Required before brick mapping, else // Program CMD mapping. Required before brick mapping, else
// we can't guarantee CK will be differential at all times. // we can't guarantee CK will be differential at all times.
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7; EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0; EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1; EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2; EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
@@ -246,7 +267,7 @@ break_nosleep:
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0; EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1; EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2; EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte; EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
// Program brick mapping. // Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0; EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
@@ -289,13 +310,13 @@ break_nosleep:
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7; EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8; EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term; EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive; EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive; EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive; EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common; EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel; EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl; EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0; EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1; EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
@@ -328,7 +349,7 @@ break_nosleep:
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode; EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl; EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
EMC(EMC_CFG_3) = params->emc_cfg3; EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0; EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1; EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2; EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
@@ -561,9 +582,11 @@ break_nosleep:
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl; EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
EMC(EMC_DBG) = params->emc_dbg; EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst; EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1; EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0; EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe; EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv; EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask; EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@@ -616,7 +639,7 @@ break_nosleep:
} }
// Release SEL_DPD_CMD. // Release SEL_DPD_CMD.
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000; PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | (1 << 30u);
usleep(params->pmc_io_dpd3_req_wait); usleep(params->pmc_io_dpd3_req_wait);
// Set autocal interval if not configured. // Set autocal interval if not configured.
@@ -707,7 +730,7 @@ break_nosleep:
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3; EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
// Enable refresh. // Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000; EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control; EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update; EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
@@ -717,7 +740,7 @@ break_nosleep:
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit. // Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2; EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions. EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
@@ -751,15 +774,15 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Program DPD3/DPD4 regs (coldboot path). // Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins. // Enable sel_dpd on unused pins.
PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15; PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000; PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) | (2 << 30u);
usleep(params->pmc_io_dpd3_req_wait); usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen. // Disable e_dpd_vttgen.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | 0x80000000; PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | (2 << 30u);
usleep(params->pmc_io_dpd4_req_wait); usleep(params->pmc_io_dpd4_req_wait);
// Disable e_dpd_bg. // Disable e_dpd_bg.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | 0x80000000; PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | (2 << 30u);
usleep(1); usleep(1);
// Program CMD mapping. Required before brick mapping, else // Program CMD mapping. Required before brick mapping, else
@@ -1155,9 +1178,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width; EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
EMC(EMC_DBG) = params->emc_dbg; EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst; EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1; EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0; EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe; EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv; EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask; EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@@ -1219,7 +1244,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17; *(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
// Release SEL_DPD_CMD. // Release SEL_DPD_CMD.
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000; PMC(APBDEV_PMC_IO_DPD3_REQ) = (params->emc_pmc_scratch1 & 0xFFF0000) | (1 << 30u);
usleep(params->pmc_io_dpd3_req_wait); usleep(params->pmc_io_dpd3_req_wait);
// Set transmission pad control parameters. // Set transmission pad control parameters.
@@ -1315,7 +1340,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30); EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
// Enable refresh. // Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000; EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control; EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG) = params->emc_cfg; EMC(EMC_CFG) = params->emc_cfg;
@@ -1324,7 +1349,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit. // Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2; EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions. EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
+59 -55
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2020-2023 CTCaer * Copyright (c) 2020-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -23,81 +23,86 @@
/* /*
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart: * 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. * Note: Max BWbits = 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. * Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
* Both assume that both sub-partitions are used and thus reaching max * Configurations supported: 1x32, 2x32, 1x64.
* bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit). * x64 ram modules can be used by combining the 2 32-bit channels into one.
* 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
* *
* 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 enum sdram_ids_erista
{ {
// LPDDR4 3200Mbps. // LPDDR4 3200Mbps.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C. LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, // Die-C. (2y-01).
// Custom hekate/L4T supported 8GB. 7 dram id can be easily applied in fuses.
LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, // XX: CH/CJ/CL.
}; };
enum sdram_ids_mariko enum sdram_ids_mariko
{ {
/*
* Nintendo Switch LPDRR4X generations:
* - 1x nm are 1st-gen
* - 1y nm are 2nd-gen
* - 1z/a nm are 3rd-gen
*/
// LPDDR4X 4266Mbps. // LPDDR4X 4266Mbps.
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01). LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01). LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01). LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
// LPDDR4X 3733Mbps. // LPDDR4X 3733Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 8 banks. 3733Mbps. LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E. LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 8 banks. 3733Mbps. LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E. LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
// LPDDR4X 4266Mbps. // LPDDR4X 4266Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps. LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03).
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03). LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03).
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps. LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03).
LPDDR4X_IOWA_4GB_SAMSUNG_1Z = 20, // 1z nm. 40% lower power usage. (1z-01). LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20, // Die-B. (1z-01). 40% lp.
LPDDR4X_HOAG_4GB_SAMSUNG_1Z = 21, // 1z nm. 40% lower power usage. (1z-01). LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
LPDDR4X_AULA_4GB_SAMSUNG_1Z = 22, // 1z nm. 40% lower power usage. (1z-01). LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22, // Die-B. (1z-01). 40% lp.
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03). 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_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. (1y-X03). 2nd gen.
LPDDR4X_UNK0_4GB_HYNIX_1A = 29, // 1a nm. 61% lower power usage. (1a-01). // Old naming scheme: H9HCNNNBKMCLXR-NEE
LPDDR4X_UNK1_4GB_HYNIX_1A = 30, // 1a nm. 61% lower power usage. (1a-01). LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
LPDDR4X_UNK2_4GB_HYNIX_1A = 31, // 1a nm. 61% lower power usage. (1a-01). LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
LPDDR4X_UNK0_4GB_MICRON_1A = 32, // 1a nm. 61% lower power usage. (1a-01). LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_UNK1_4GB_MICRON_1A = 33, // 1a nm. 61% lower power usage. (1a-01). LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_UNK2_4GB_MICRON_1A = 34, // 1a nm. 61% lower power usage. (1a-01). LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
}; };
enum sdram_codes_mariko enum sdram_codes_mariko
@@ -112,12 +117,11 @@ enum sdram_codes_mariko
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15. LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24. LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28. LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
LPDDR4X_4GB_SAMSUNG_1Z = 5, // DRAM IDs: 20, 21, 22. 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_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_NEE = 7, // DRAM IDs: 03, 05, 06.
LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
LPDDR4X_4GB_HYNIX_1A = 8, // DRAM IDs: 29, 30, 31. LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
LPDDR4X_4GB_MICRON_1A = 9, // DRAM IDs: 32, 33, 34.
}; };
void sdram_init(); void sdram_init();
+32 -56
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2020-2022 CTCaer * Copyright (c) 2020-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -434,9 +434,9 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.emc_dll_cfg0 = 0x1F13412F, .emc_dll_cfg0 = 0x1F13412F,
.emc_dll_cfg1 = 0x00010014, .emc_dll_cfg1 = 0x00010014,
.emc_pmc_scratch1 = 0x4FAFFFFF, .emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
.emc_pmc_scratch2 = 0x7FFFFFFF, .emc_pmc_scratch2 = 0x7FFFFFFF,
.emc_pmc_scratch3 = 0x4006D70B, .emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
.emc_pmacro_pad_cfg_ctrl = 0x00020000, .emc_pmacro_pad_cfg_ctrl = 0x00020000,
.emc_pmacro_vttgen_ctrl0 = 0x00030808, .emc_pmacro_vttgen_ctrl0 = 0x00030808,
@@ -489,8 +489,8 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
/* DRAM size information */ /* DRAM size information */
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks. .mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
.mc_emem_adr_cfg_dev0 = 0x00070302, // Rank 0 Density 512MB. .mc_emem_adr_cfg_dev0 = 0x00070302, // Chip 0 Density 512MB.
.mc_emem_adr_cfg_dev1 = 0x00070302, // Rank 1 Density 512MB. .mc_emem_adr_cfg_dev1 = 0x00070302, // Chip 1 Density 512MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400, .mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400, .mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800, .mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -499,7 +499,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory * Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes) * size (in KBytes)
*/ */
.mc_emem_cfg = 0x00001000, // 4GB total density. .mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */ /* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001, .mc_emem_arb_cfg = 0x08000001,
@@ -542,16 +542,18 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_video_protect_bom_adr_hi = 0x00000000, .mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 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. // AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4BAC343, .mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343. New: 0xE4FACB43. + TSEC, NVENC.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. // SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x00001ED3, .mc_video_protect_vpr_override1 = 0x0000FED3, // Default: 0x00001ED3. New: 0x0000FED3. + TSECB, TSEC1, TSECB1.
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_video_protect_gpu_override0 = 0x00000000,
.mc_video_protect_gpu_override1 = 0x00000000,
.mc_sec_carveout_bom = 0xFFF00000, .mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000, .mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000, .mc_sec_carveout_size_mb = 0x00000000,
.mc_video_protect_write_access = 0x00000000, .mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000, .mc_sec_carveout_protect_write_access = 0x00000000,
@@ -646,53 +648,27 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
.mc_mts_carveout_reg_ctrl = 0x00000000 .mc_mts_carveout_reg_ctrl = 0x00000000
}; };
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = { static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
// Hynix timing config. // Hynix timing config.
{ 0x0000000D, 0x10C / 4, DRAM_ID(1) }, // emc_r2w. { 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
{ 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra. { 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
{ 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width. { 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
{ 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode. { 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
{ 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // mc_emem_arb_timing_r2w. { 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
// Samsung 6GB density config. // Samsung 6GB density config.
{ 0x000C0302, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density. { 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
{ 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density. { 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
{ 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density. { 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
#ifdef CONFIG_SDRAM_COPPER_SUPPORT // Samsung 8GB density config.
// Copper prototype Samsung/Hynix/Micron timing configs. { 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
{ 0x0000003A, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh. { 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
{ 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh. { 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
{ 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w. { 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
{ 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra. { 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
{ 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width. { 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
{ 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden. { 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
{ 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
}; };
#undef DCFG_OFFSET_OF
+78 -73
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2022 CTCaer * Copyright (c) 2020-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -542,8 +542,8 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
/* DRAM size information */ /* DRAM size information */
.mc_emem_adr_cfg = 0x00000000, // 1 Rank. .mc_emem_adr_cfg = 0x00000000, // 1 Rank.
.mc_emem_adr_cfg_dev0 = 0x00080302, // Rank 0 Density 1024MB. .mc_emem_adr_cfg_dev0 = 0x00080302, // Chip 0 Density 1024MB.
.mc_emem_adr_cfg_dev1 = 0x00080302, // Rank 1 Density 1024MB. .mc_emem_adr_cfg_dev1 = 0x00080302, // Chip 1 Density 1024MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400, .mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400, .mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800, .mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -552,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory * Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes) * size (in KBytes)
*/ */
.mc_emem_cfg = 0x00001000, // 4GB total density. .mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */ /* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001, .mc_emem_arb_cfg = 0x08000001,
@@ -595,17 +595,18 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
.mc_video_protect_bom_adr_hi = 0x00000000, .mc_video_protect_bom_adr_hi = 0x00000000,
.mc_video_protect_size_mb = 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. // AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4BAC343, .mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B. // SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B and TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x06001ED3, .mc_video_protect_vpr_override1 = 0x0600FED3, // Default: 0x06001ED3.
.mc_video_protect_gpu_override0 = 0x00000000, .mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000000, .mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_sec_carveout_bom = 0xFFF00000, .mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000, .mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000, .mc_sec_carveout_size_mb = 0x00000000,
.mc_video_protect_write_access = 0x00000000, .mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000, .mc_sec_carveout_protect_write_access = 0x00000000,
@@ -708,100 +709,104 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ)) #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) | \ #define DRAM_CC_LPDDR4X_PUPD_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \ DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_DYN_SELF_CTRL (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \ #define DRAM_CC_LPDDR4X_DSR (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_QUSE_EINPUT (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \ #define DRAM_CC_LPDDR4X_QUSE (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \ DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_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_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A)) DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ #define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_SAMSUNG_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \ #define DRAM_CC_LPDDR4X_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL)) DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL))
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = { static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
// Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag. // Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag.
{ 0x35353535, 0x350 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_0. { 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
{ 0x35353535, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1. { 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
{ 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(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, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
{ 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. { 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
/*! Shared patched between DRAM Codes. */ /*! Shared patched between DRAM Codes. */
{ 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2. { 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0. { 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(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.
{ 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14. // Moved to default config.
{ 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control. // { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
// { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
{ 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse. { 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width. { 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
{ 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput.
{ 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration.
{ 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw. { 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
{ 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw. { 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
{ 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
{ 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
{ 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC. { 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
{ 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1. { 0x00000001, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(mc_emem_arb_timing_faw) },
{ 0x00000001, 0x134 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_adr_cfg. 2 Ranks. // Moved to default config.
{ 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw1. // { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
{ 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw2. // { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
{ 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw3.
{ 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw6. { 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
{ 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw8. { 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw9. { 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
{ 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw10. { 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
{ 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw12. { 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
{ 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw13. { 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
{ 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw14. { 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
{ 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw_extra. { 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
{ 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_dev_select. Both devices. { 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
{ 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_mrw_cmd. { 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
{ 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_init_dev1. { 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd4. { 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
{ 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd5. { 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
{ 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_adr_cfg. 2 Ranks. { 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
{ 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_cfg. 8GB total density. { 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
{ 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_timing_r2r. { 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
{ 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_da_turns. { 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
{ 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
{ 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
{ 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
}; };
#undef DCFG_OFFSET_OF
+1 -1
View File
@@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
u32 emc_r2p; u32 emc_r2p;
/* Specifies the value for EMC_W2P */ /* Specifies the value for EMC_W2P */
u32 emc_w2p; u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd; u32 emc_tppd;
u32 emc_trtm; u32 emc_trtm;
@@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
u32 emc_tr2ref; u32 emc_tr2ref;
u32 emc_ccdmw; u32 emc_ccdmw;
/* Specifies the value for EMC_RD_RCD */
u32 emc_rd_rcd; u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */ /* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd; u32 emc_wr_rcd;
+151 -79
View File
@@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -18,156 +18,228 @@
#include <string.h> #include <string.h>
#include <soc/bpmp.h>
#include <soc/ccplex.h> #include <soc/ccplex.h>
#include <soc/timer.h> #include <soc/timer.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <mem/mc_t210.h> #include <mem/mc_t210.h>
#include <mem/smmu.h> #include <mem/smmu.h>
#include <utils/aarch64_util.h> #include <memory_map.h>
bool smmu_used = false; /*! SMMU register defines */
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR; #define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
#define SMMU_ENABLE BIT(31)
#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
#define SMMU_TLB_RR_ARBITRATION BIT(28)
#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
#define SMMU_TLB_STATS_ENABLE BIT(31)
#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
#define SMUU_PTC_CACHE_ENABLE BIT(29)
#define SMUU_PTC_STATS_ENABLE BIT(31)
//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1; /*! Page table defines */
u8 smmu_payload[] __attribute__((aligned(16))) = { #define SMMU_4MB_REGION 0
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010 #define SMMU_PAGE_TABLE 1
#define SMMU_PDIR_COUNT 1024
#define SMMU_PTBL_COUNT 1024
#define SMMU_PAGE_SHIFT 12u
#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
#define SMMU_PDN_SHIFT 22u
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
static const u8 smmu_enable_payload[] = {
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1 0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1] 0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS 0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH 0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop 0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0 0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
0x00, 0x00, 0x00, 0x00, // 0x2C:
0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
0x00, 0x00, 0x00, 0x00 // 0x34:
}; };
void *page_alloc(u32 num) void *smmu_page_zalloc(u32 num)
{ {
u8 *res = _pageheap; void *page = smmu_heap;
_pageheap += SZ_PAGE * num; memset(page, 0, SZ_PAGE * num);
memset(res, 0, SZ_PAGE * num);
return res; smmu_heap += SZ_PAGE * num;
return page;
} }
u32 *smmu_alloc_pdir() static pde_t *_smmu_pdir_alloc()
{ {
u32 *pdir = (u32 *)page_alloc(1); pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn] = _PDE_VACANT(pdn); // Initialize pdes with no permissions.
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn].huge.page = pdn;
return pdir; return pdir;
} }
void smmu_flush_regs() static void _smmu_flush_regs()
{ {
(void)MC(MC_SMMU_PTB_DATA); (void)MC(MC_SMMU_PTB_DATA);
} }
void smmu_flush_all() void smmu_flush_all()
{ {
MC(MC_SMMU_PTC_FLUSH) = 0;
smmu_flush_regs();
// Flush the entire page table cache.
MC(MC_SMMU_PTC_FLUSH) = 0;
_smmu_flush_regs();
// Flush the entire table.
MC(MC_SMMU_TLB_FLUSH) = 0; MC(MC_SMMU_TLB_FLUSH) = 0;
smmu_flush_regs(); _smmu_flush_regs();
} }
void smmu_init(u32 secmon_base) void smmu_init()
{ {
MC(MC_SMMU_PTB_ASID) = 0; MC(MC_SMMU_PTB_ASID) = 0;
MC(MC_SMMU_PTB_DATA) = 0; MC(MC_SMMU_PTB_DATA) = 0;
MC(MC_SMMU_TLB_CONFIG) = 0x30000030; MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F; MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
MC(MC_SMMU_PTC_FLUSH) = 0; MC(MC_SMMU_PTC_FLUSH) = 0;
MC(MC_SMMU_TLB_FLUSH) = 0; MC(MC_SMMU_TLB_FLUSH) = 0;
// Set the secmon address
*(u32 *)(smmu_payload + 0x30) = secmon_base;
} }
void smmu_enable() void smmu_enable()
{ {
if (smmu_used) static bool enabled = false;
if (enabled)
return; return;
ccplex_boot_cpu0((u32)smmu_payload); // Launch payload on CCPLEX in order to set SMMU enable bit.
smmu_used = true; ccplex_boot_cpu0((u32)smmu_enable_payload, false);
msleep(150); msleep(100);
ccplex_powergate_cpu0();
smmu_flush_all(); smmu_flush_all();
enabled = true;
} }
bool smmu_is_used() void smmu_reset_heap()
{ {
return smmu_used; smmu_heap = (void *)SMMU_HEAP_ADDR;
} }
void smmu_exit() void *smmu_init_domain(u32 dev_base, u32 asid)
{ {
*(u32 *)(smmu_payload + 0x14) = _NOP(); void *ptb = _smmu_pdir_alloc();
}
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
{
u32 *pdir = smmu_alloc_pdir();
MC(MC_SMMU_PTB_ASID) = asid; MC(MC_SMMU_PTB_ASID) = asid;
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR); MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
smmu_flush_regs(); _smmu_flush_regs();
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid); // Use the same macro for both quad and single domains. Reserved bits are not set anyway.
smmu_flush_regs(); MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
_smmu_flush_regs();
return pdir; return ptb;
} }
u32 *smmu_get_pte(u32 *pdir, u32 iova) void smmu_deinit_domain(u32 dev_base, u32 asid)
{ {
u32 ptn = SMMU_ADDR_TO_PFN(iova); MC(MC_SMMU_PTB_ASID) = asid;
u32 pdn = SMMU_ADDR_TO_PDN(iova); MC(MC_SMMU_PTB_DATA) = 0;
u32 *ptbl; MC(dev_base) = 0;
_smmu_flush_regs();
}
if (pdir[pdn] != _PDE_VACANT(pdn)) void smmu_domain_bypass(u32 dev_base, bool bypass)
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT); {
if (bypass)
{
smmu_flush_all();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) &= ~SMMU_ENABLE;
}
else else
{ {
ptbl = (u32 *)page_alloc(1); bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) |= SMMU_ENABLE;
smmu_flush_all();
}
_smmu_flush_regs();
}
static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
{
u32 pdn = SMMU_ADDR_TO_PDN(iova);
pte_t *ptbl;
// Get 4MB page table or initialize one.
if (pdir[pdn].tbl.attr)
ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
else
{
// Allocate page table.
ptbl = (pte_t *)smmu_page_zalloc(1);
// Get address.
u32 addr = SMMU_PDN_TO_ADDR(pdn); u32 addr = SMMU_PDN_TO_ADDR(pdn);
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
ptbl[pn] = _PTE_VACANT(addr); // Initialize page table with no permissions.
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT); for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
// Set page table to the page directory.
pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
smmu_flush_all(); smmu_flush_all();
} }
return &ptbl[ptn % SMMU_PTBL_COUNT]; return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
} }
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr) void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
{ {
for (int i = 0; i < cnt; i++) // Map pages to page table entries. VA/PA should be aligned to 4KB.
for (u32 i = 0; i < pages; i++)
{ {
u32 *pte = smmu_get_pte(pdir, addr); pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
*pte = SMMU_ADDR_TO_PFN(page) | attr;
addr += SZ_PAGE; pte->page = SMMU_ADDR_TO_PFN(iopa);
page += SZ_PAGE; pte->attr = attr;
iova += SZ_PAGE;
iopa += SZ_PAGE;
} }
smmu_flush_all(); smmu_flush_all();
} }
u32 *smmu_init_for_tsec() void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
{ {
return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1); pde_t *pdir = (pde_t *)ptb;
}
void smmu_deinit_for_tsec() // Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
{ for (u32 i = 0; i < regions; i++)
MC(MC_SMMU_PTB_ASID) = 1; {
MC(MC_SMMU_PTB_DATA) = 0; u32 pdn = SMMU_ADDR_TO_PDN(iova);
MC(MC_SMMU_TSEC_ASID) = 0; pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
smmu_flush_regs(); pdir[pdn].huge.next = SMMU_4MB_REGION;
} pdir[pdn].huge.attr = attr;
iova += SZ_4M;
iopa += SZ_4M;
}
smmu_flush_all();
}
+49 -61
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -14,70 +15,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <assert.h>
#include <utils/types.h> #include <utils/types.h>
#define SMMU_HEAP_ADDR 0xA0000000
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_AVPC_ASID 0x23C #define MC_SMMU_AVPC_ASID 0x23C
#define MC_SMMU_TSEC_ASID 0x294 #define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define SMMU_PDE_NEXT_SHIFT 28 #define SMMU_NS BIT(0)
#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29 #define SMMU_WRITE BIT(1)
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30 #define SMMU_READ BIT(2)
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31 #define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
#define SMMU_PAGE_SHIFT 12
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
#define SMMU_PDIR_COUNT 1024
#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
#define SMMU_PTBL_COUNT 1024
#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
#define SMMU_PDIR_SHIFT 12
#define SMMU_PDE_SHIFT 12
#define SMMU_PTE_SHIFT 12
#define SMMU_PFN_MASK 0x000FFFFF
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
void *page_alloc(u32 num); typedef struct _pde_t {
u32 *smmu_alloc_pdir(); union {
void smmu_flush_regs(); union {
void smmu_flush_all(); struct {
void smmu_init(u32 secmon_base); u32 table:22;
void smmu_enable(); u32 rsvd:6;
bool smmu_is_used(); u32 next:1;
void smmu_exit(); u32 attr:3;
u32 *smmu_init_domain4(u32 dev_base, u32 asid); } tbl;
u32 *smmu_get_pte(u32 *pdir, u32 iova);
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr); struct {
u32 *smmu_init_for_tsec(); u32 rsvd_:10;
void smmu_deinit_for_tsec(); u32 page:12;
u32 rsvd:6;
u32 next:1;
u32 attr:3;
} huge;
};
u32 pde;
};
} pde_t;
typedef struct _pte_t {
u32 page:22;
u32 rsvd:7;
u32 attr:3;
} pte_t;
static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
void *smmu_page_zalloc(u32 num);
void smmu_flush_all();
void smmu_init();
void smmu_enable();
void smmu_reset_heap();
void *smmu_init_domain(u32 dev_base, u32 asid);
void smmu_deinit_domain(u32 dev_base, u32 asid);
void smmu_domain_bypass(u32 dev_base, bool bypass);
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);
+3 -1
View File
@@ -51,7 +51,9 @@
/* Stack theoretical max: 33MB */ /* Stack theoretical max: 33MB */
#define IPL_STACK_TOP 0x83100000 #define IPL_STACK_TOP 0x83100000
#define IPL_HEAP_START 0x84000000 #define IPL_HEAP_START 0x84000000
#define IPL_HEAP_SZ SZ_512M #define IPL_HEAP_SZ (SZ_512M - SZ_64M)
#define SMMU_HEAP_ADDR 0xA0000000
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */ /* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
// Virtual disk / Chainloader buffers. // Virtual disk / Chainloader buffers.
+23
View File
@@ -279,3 +279,26 @@ int max17050_fix_configuration()
return 0; return 0;
} }
void max17050_dump_regs(void *buf)
{
u16 *buff = (u16 *)buf;
// Unlock model table.
u16 unlock = 0x59;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
unlock = 0xC4;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
// Dump all battery fuel gauge registers.
for (u32 i = 0; i < 0x100; i++)
{
buff[i] = max17050_get_reg(i);
msleep(1);
}
// Lock model table.
unlock = 0;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
}
+4 -3
View File
@@ -130,8 +130,9 @@ enum MAX17050_reg {
MAX17050_VFSOC = 0xFF, MAX17050_VFSOC = 0xFF,
}; };
int max17050_get_property(enum MAX17050_reg reg, int *value); int max17050_get_property(enum MAX17050_reg reg, int *value);
int max17050_fix_configuration(); int max17050_fix_configuration();
u32 max17050_get_cached_batt_volt(); void max17050_dump_regs(void *buf);
u32 max17050_get_cached_batt_volt();
#endif /* __MAX17050_H_ */ #endif /* __MAX17050_H_ */
+3 -3
View File
@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
static const max77620_regulator_t _pmic_regulators[] = { 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 }} }, { "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
{ "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} }, { "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} }, { "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 }} }, { "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 }} }, { "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 }} },
@@ -103,7 +103,7 @@ static u8 _max77812_get_address()
return max77812_i2c_addr; return max77812_i2c_addr;
max77812_i2c_addr = max77812_i2c_addr =
!(FUSE(FUSE_RESERVED_ODM28_T210B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR; !(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
return max77812_i2c_addr; return max77812_i2c_addr;
} }
@@ -123,7 +123,7 @@ static u8 _max7762x_get_i2c_address(u32 id)
case REGULATOR_BC1: case REGULATOR_BC1:
{ {
u8 reg_addr = _max77812_get_address(); u8 reg_addr = _max77812_get_address();
if (id == REGULATOR_RAM1 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR) if (id == REGULATOR_RAM0 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR)
reg_addr = 0; reg_addr = 0;
return reg_addr; return reg_addr;
} }
+23 -2
View File
@@ -47,6 +47,27 @@
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv) * ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
*/ */
// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
/*
* OTP: T210 - T210B01:
* SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
* SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
* SD2: 1.35V 1.35V
* SD3: 1.8V 1.8V
* All powered off?
* LDO0: -- -- - Display
* LDO1: 1.05V 1.05V
* LDO2: -- -- - SD
* LDO3: 3.1V 3.1V - GC ASIC
* LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
* LDO5: 3.1V 3.1V
* LDO6: 2.8V 2.9V - Touch.
* LDO7: 1.05V 1.0V
* LDO8: 1.05V 1.0V
*/
/* /*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode * MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable * MAX77620_REG_GPIOx: 0x9 sets output and enable
@@ -69,9 +90,9 @@
#define REGULATOR_CPU0 13 // T210 CPU. #define REGULATOR_CPU0 13 // T210 CPU.
#define REGULATOR_GPU0 14 // T210 CPU. #define REGULATOR_GPU0 14 // T210 CPU.
#define REGULATOR_CPU1 15 // T210B01 CPU. #define REGULATOR_CPU1 15 // T210B01 CPU.
#define REGULATOR_RAM1 16 // T210B01 RAM for PHASE211. #define REGULATOR_RAM0 16 // T210B01 RAM for PHASE211.
//#define REGULATOR_GPU1 17 // T210B01 CPU. //#define REGULATOR_GPU1 17 // T210B01 CPU.
#define REGULATOR_MAX REGULATOR_RAM1 #define REGULATOR_MAX REGULATOR_RAM0
#define MAX77621_CPU_I2C_ADDR 0x1B #define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C #define MAX77621_GPU_I2C_ADDR 0x1C
+6 -6
View File
@@ -75,14 +75,14 @@
#define MAX77812_REG_GLB_CFG3 0x35 #define MAX77812_REG_GLB_CFG3 0x35
/*! Protected area and settings only for MAX77812_ES2_VERSION */ /*! Protected area and settings only for MAX77812_ES2_VERSION */
#define MAX77812_REG_GLB_CFG4 0x36 #define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
#define MAX77812_REG_GLB_CFG5 0x37 // HOS: 0x3E. Unmasked write. #define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
#define MAX77812_REG_GLB_CFG6 0x38 // HOS: 0x90. Unmasked write. #define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
#define MAX77812_REG_GLB_CFG7 0x39 #define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
#define MAX77812_REG_GLB_CFG8 0x3A // HOS: 0x3A. Unmasked write. #define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock. #define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
#define MAX77812_REG_MAX 0xFD #define MAX77812_REG_UNKNOWN 0xFE
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n) #define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
#define MAX77812_START_SLEW_RATE_MASK 0x07 #define MAX77812_START_SLEW_RATE_MASK 0x07
+17
View File
@@ -23,6 +23,8 @@
#include <soc/timer.h> #include <soc/timer.h>
#include <soc/t210.h> #include <soc/t210.h>
int epoch_offset = 0;
void max77620_rtc_prep_read() void max77620_rtc_prep_read()
{ {
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE); i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
@@ -154,6 +156,21 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
return epoch; return epoch;
} }
void max77620_rtc_get_time_adjusted(rtc_time_t *time)
{
max77620_rtc_get_time(time);
if (epoch_offset)
{
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
max77620_rtc_epoch_to_date(epoch, time);
}
}
void max77620_rtc_set_epoch_offset(int offset)
{
epoch_offset = offset;
}
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr) void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
{ {
max77620_rtc_stop_alarm(); max77620_rtc_stop_alarm();
+2
View File
@@ -109,6 +109,8 @@ typedef struct _rtc_reboot_reason_t
void max77620_rtc_prep_read(); void max77620_rtc_prep_read();
void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
void max77620_rtc_set_epoch_offset(int offset);
void max77620_rtc_stop_alarm(); void max77620_rtc_stop_alarm();
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time); 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);
+115 -78
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -182,7 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
if (!src || !dst) if (!src || !dst)
return 0; return 0;
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE); u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
@@ -281,6 +281,14 @@ void se_aes_iv_clear(u32 ks)
} }
} }
void se_aes_iv_updated_clear(u32 ks)
{
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
}
}
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
{ {
@@ -292,6 +300,26 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE); return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
} }
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{ {
if (enc) if (enc)
@@ -371,7 +399,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
tweak[i] = sec & 0xFF; tweak[i] = sec & 0xFF;
sec >>= 8; sec >>= 8;
} }
if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak)) if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
goto out; goto out;
// We are assuming a 0x10-aligned sector size in this implementation. // We are assuming a 0x10-aligned sector size in this implementation.
@@ -408,7 +436,7 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
tweak[i] = sec & 0xFF; tweak[i] = sec & 0xFF;
sec >>= 8; sec >>= 8;
} }
if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak)) if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak))
return 0; return 0;
} }
@@ -459,59 +487,21 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo
return 1; return 1;
} }
// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
{ {
int res = 0; u32 hash32[SE_SHA_256_SIZE / 4];
u8 *key = (u8 *)calloc(0x10, 1);
u8 *last_block = (u8 *)calloc(0x10, 1);
// generate derived key // Backup message left.
if (!se_aes_crypt_block_ecb(ks, 1, key, key)) if (msg_left)
goto out;
_gf256_mul_x(key);
if (src_size & 0xF)
_gf256_mul_x(key);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_iv_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4;
if (num_blocks > 1)
{ {
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2; msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size)) msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
goto out;
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
} }
if (src_size & 0xf) // Copy output hash.
{ for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf); hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
last_block[src_size & 0xf] = 0x80; memcpy(hash, hash32, SE_SHA_256_SIZE);
}
else if (src_size >= 0x10)
{
memcpy(last_block, src + src_size - 0x10, 0x10);
}
for (u32 i = 0; i < 0x10; i++)
last_block[i] ^= key[i];
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10);
u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (dst_size >> 2); i++)
dst32[i] = SE(SE_HASH_RESULT_REG + (i << 2));
out:;
free(key);
free(last_block);
return res;
} }
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot) int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
@@ -523,6 +513,17 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer. if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
return 0; return 0;
// Src size of 0 is not supported, so return null string sha256.
// if (!src_size)
// {
// const u8 null_hash[SE_SHA_256_SIZE] = {
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
// };
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
// return 1;
// }
// Setup config for SHA256. // Setup config for SHA256.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG) = sha_cfg; SE(SE_SHA_CONFIG_REG) = sha_cfg;
@@ -561,19 +562,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot); res = _se_execute(SE_OP_START, NULL, 0, src, src_size, is_oneshot);
if (is_oneshot) if (is_oneshot)
{ se_calc_sha256_get_hash(hash, msg_left);
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
return res; return res;
} }
@@ -585,20 +574,9 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
int se_calc_sha256_finalize(void *hash, u32 *msg_left) int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{ {
u32 hash32[SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize(); int res = _se_execute_finalize();
// Backup message left. se_calc_sha256_get_hash(hash, msg_left);
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
return res; return res;
} }
@@ -716,6 +694,65 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Decrypt context. // Decrypt context.
se_aes_key_clear(3); se_aes_key_clear(3);
se_aes_key_set(3, srk, SE_KEY_128_SIZE); se_aes_key_set(3, srk, SE_KEY_128_SIZE);
se_aes_crypt_cbc(3, CORE_DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
se_aes_key_clear(3); se_aes_key_clear(3);
} }
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
{
int res = 0;
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
// Generate sub key
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
goto out;
_gf256_mul_x(key);
if (src_size & 0xF)
_gf256_mul_x(key);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4;
if (num_blocks > 1)
{
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
goto out;
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
}
if (src_size & 0xf)
{
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
last_block[src_size & 0xf] = 0x80;
}
else if (src_size >= SE_AES_BLOCK_SIZE)
{
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
}
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
last_block[i] ^= key[i];
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
out:;
free(key);
free(last_block);
return res;
}
+3 -1
View File
@@ -30,7 +30,9 @@ void se_aes_iv_set(u32 ks, void *iv);
void se_aes_key_get(u32 ks, void *key, u32 size); void se_aes_key_get(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks); void se_aes_key_clear(u32 ks);
void se_aes_iv_clear(u32 ks); void se_aes_iv_clear(u32 ks);
void se_aes_iv_updated_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
@@ -38,11 +40,11 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *ds
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size); int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs); int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot); int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size); int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
int se_calc_sha256_finalize(void *hash, u32 *msg_left); int se_calc_sha256_finalize(void *hash, u32 *msg_left);
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size); int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
int se_gen_prng128(void *dst); int se_gen_prng128(void *dst);
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
#endif #endif
+3
View File
@@ -50,6 +50,9 @@
#define SE_RSA1536_DIGEST_SIZE 192 #define SE_RSA1536_DIGEST_SIZE 192
#define SE_RSA2048_DIGEST_SIZE 256 #define SE_RSA2048_DIGEST_SIZE 256
#define DECRYPT 0
#define ENCRYPT 1
/* SE register definitions */ /* SE register definitions */
#define SE_SE_SECURITY_REG 0x000 #define SE_SE_SECURITY_REG 0x000
#define SE_HARD_SETTING BIT(0) #define SE_HARD_SETTING BIT(0)
+47 -42
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -70,8 +70,9 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
int res = 0; int res = 0;
u8 *fwbuf = NULL; u8 *fwbuf = NULL;
u32 type = tsec_ctxt->type; u32 type = tsec_ctxt->type;
u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec; u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *pkg11_magic_off; u32 *pkg11_magic_off;
void *ptb;
bpmp_mmu_disable(); bpmp_mmu_disable();
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
@@ -145,64 +146,64 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (type == TSEC_FW_TYPE_EMU) if (type == TSEC_FW_TYPE_EMU)
{ {
// Init SMMU translation for TSEC. // Init SMMU translation for TSEC.
pdir = smmu_init_for_tsec(); ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
smmu_init(tsec_ctxt->secmon_base); smmu_init();
// Enable SMMU
if (!smmu_is_used()) // Enable SMMU.
smmu_enable(); smmu_enable();
// Clock reset controller. // Clock reset controller.
car = page_alloc(1); car = smmu_page_zalloc(1);
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE); memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2; car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE); smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
// Fuse driver. // Fuse driver.
fuse = page_alloc(1); fuse = smmu_page_zalloc(1);
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K); memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
fuse[0x82C / 4] = 0; fuse[0x82C / 4] = 0;
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE); smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
// Power management controller. // Power management controller.
pmc = page_alloc(1); pmc = smmu_page_zalloc(1);
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE); smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
// Flow control. // Flow control.
flowctrl = page_alloc(1); flowctrl = smmu_page_zalloc(1);
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE); smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
// Security engine. // Security engine.
se = page_alloc(1); se = smmu_page_zalloc(1);
memcpy(se, (void *)SE_BASE, SZ_PAGE); memcpy(se, (void *)SE_BASE, SZ_PAGE);
smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, SE_BASE, (u32)se, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Memory controller. // Memory controller.
mc = page_alloc(1); mc = smmu_page_zalloc(1);
memcpy(mc, (void *)MC_BASE, SZ_PAGE); memcpy(mc, (void *)MC_BASE, SZ_PAGE);
mc[MC_IRAM_BOM / 4] = 0; mc[MC_IRAM_BOM / 4] = 0;
mc[MC_IRAM_TOM / 4] = DRAM_START; mc[MC_IRAM_TOM / 4] = DRAM_START;
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); smmu_map(ptb, MC_BASE, (u32)mc, 1, SMMU_READ | SMMU_NS);
// IRAM // IRAM
iram = page_alloc(0x30); iram = smmu_page_zalloc(0x30);
memcpy(iram, tsec_ctxt->pkg1, 0x30000); memcpy(iram, tsec_ctxt->pkg1, 0x30000);
// PKG1.1 magic offset. // PKG1.1 magic offset.
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4)); pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Exception vectors // Exception vectors
evec = page_alloc(1); evec = smmu_page_zalloc(1);
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE); smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
} }
// Execute firmware. // Execute firmware.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA; HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
TSEC(TSEC_STATUS) = 0; TSEC(TSEC_MAILBOX1) = 0;
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1. TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
TSEC(TSEC_BOOTVEC) = 0; TSEC(TSEC_BOOTVEC) = 0;
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU; TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
if (type == TSEC_FW_TYPE_EMU) if (type == TSEC_FW_TYPE_EMU)
{ {
@@ -229,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (kidx != 8) if (kidx != 8)
{ {
res = -6; res = -6;
smmu_deinit_for_tsec(); smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
goto out_free; goto out_free;
} }
@@ -240,12 +241,12 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
memcpy(tsec_keys, &key, 0x20); memcpy(tsec_keys, &key, 0x20);
memcpy(tsec_ctxt->pkg1, iram, 0x30000); memcpy(tsec_ctxt->pkg1, iram, 0x30000);
smmu_deinit_for_tsec(); smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
// for (int i = 0; i < kidx; i++) // for (int i = 0; i < kidx; i++)
// gfx_printf("key %08X\n", key[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); // u32 errst = MC(MC_ERR_STATUS);
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR)); // gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
@@ -261,14 +262,18 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
res = -3; res = -3;
goto out_free; goto out_free;
} }
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while (!TSEC(TSEC_STATUS)) while (!TSEC(TSEC_MAILBOX1))
{
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
res = -4; res = -4;
goto out_free; goto out_free;
} }
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0) }
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
{ {
res = -5; res = -5;
goto out_free; goto out_free;
@@ -277,14 +282,14 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
// Fetch result. // Fetch result.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0; HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
u32 buf[4]; u32 buf[4];
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB); buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB); buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB); buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB); buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0; SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0; SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0; SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0; SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE); memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
} }
+1 -2
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -35,7 +35,6 @@ typedef struct _tsec_ctxt_t
u32 type; u32 type;
void *pkg1; void *pkg1;
u32 pkg11_off; u32 pkg11_off;
u32 secmon_base;
} tsec_ctxt_t; } tsec_ctxt_t;
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt); int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2023 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -17,8 +17,8 @@
#ifndef _TSEC_T210_H_ #ifndef _TSEC_T210_H_
#define _TSEC_T210_H_ #define _TSEC_T210_H_
#define TSEC_BOOTKEYVER 0x1040 #define TSEC_MAILBOX0 0x1040
#define TSEC_STATUS 0x1044 #define TSEC_MAILBOX1 0x1044
#define TSEC_ITFEN 0x1048 #define TSEC_ITFEN 0x1048
#define TSEC_ITFEN_CTXEN BIT(0) #define TSEC_ITFEN_CTXEN BIT(0)
#define TSEC_ITFEN_MTHDEN BIT(1) #define TSEC_ITFEN_MTHDEN BIT(1)
+11 -12
View File
@@ -76,7 +76,9 @@
#define ACTMON_HISTOGRAM_DATA_BASE 0x380 #define ACTMON_HISTOGRAM_DATA_BASE 0x380
#define ACTMON_HISTOGRAM_DATA_NUM 32 #define ACTMON_HISTOGRAM_DATA_NUM 32
#define ACTMON_FREQ 19200000 #define ACTMON_FREQ 19200000
#define ACTMON_PERIOD_MS 20
#define DEV_COUNT_WEIGHT 5
typedef struct _actmon_dev_reg_t typedef struct _actmon_dev_reg_t
{ {
@@ -91,11 +93,9 @@ typedef struct _actmon_dev_reg_t
vu32 avg_count; vu32 avg_count;
vu32 intr_status; vu32 intr_status;
vu32 ctrl2; vu32 ctrl2;
vu32 unk[5]; vu32 rsvd[5];
} actmon_dev_reg_t; } actmon_dev_reg_t;
u32 sample_period = 0;
void actmon_hist_enable(actmon_hist_src_t src) void actmon_hist_enable(actmon_hist_src_t src)
{ {
ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE; ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE;
@@ -120,10 +120,10 @@ void actmon_dev_enable(actmon_dev_t dev)
{ {
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
regs->init_avg = 0; regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
regs->count_weight = 5; regs->count_weight = DEV_COUNT_WEIGHT;
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC; regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC | ACTMON_DEV_CTRL_K_VAL(7); // 128 samples average.
} }
void actmon_dev_disable(actmon_dev_t dev) void actmon_dev_disable(actmon_dev_t dev)
@@ -138,7 +138,7 @@ u32 actmon_dev_get_load(actmon_dev_t dev)
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
// Get load-based sampling. 1 decimal point precision. // Get load-based sampling. 1 decimal point precision.
u32 load = regs->count / (ACTMON_FREQ / 1000); u32 load = regs->count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
return load; return load;
} }
@@ -148,7 +148,7 @@ u32 actmon_dev_get_load_avg(actmon_dev_t dev)
actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE));
// Get load-based sampling. 1 decimal point precision. // Get load-based sampling. 1 decimal point precision.
u32 avg_load = regs->avg_count / (ACTMON_FREQ / 1000); u32 avg_load = regs->avg_count * 100 / (ACTMON_FREQ / (ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT));
return avg_load; return avg_load;
} }
@@ -162,9 +162,8 @@ void actmon_init()
{ {
clock_enable_actmon(); clock_enable_actmon();
// Set period to 200ms. // Set period.
ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC; ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200);
} }
void actmon_end() void actmon_end()
+5 -5
View File
@@ -287,10 +287,10 @@ void bpmp_usleep(u32 us)
// Each iteration takes 1us. // Each iteration takes 1us.
while (us) while (us)
{ {
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us; delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
us -= delay; us -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
} }
} }
@@ -301,14 +301,14 @@ void bpmp_msleep(u32 ms)
// Iteration time is variable. ~200 - 1000us. // Iteration time is variable. ~200 - 1000us.
while (ms) while (ms)
{ {
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms; delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
ms -= delay; ms -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
} }
} }
void bpmp_halt() void bpmp_halt()
{ {
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
} }
+68 -13
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -27,7 +27,9 @@
#include <power/max77812.h> #include <power/max77812.h>
#include <utils/util.h> #include <utils/util.h>
void _ccplex_enable_power_t210() #define CCPLEX_FLOWCTRL_POWERGATING 0
static void _ccplex_enable_power_t210()
{ {
// Configure GPIO5 and enable output in order to power CPU pmic. // Configure GPIO5 and enable output in order to power CPU pmic.
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE); max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
@@ -37,19 +39,31 @@ void _ccplex_enable_power_t210()
// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL. // 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG); max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
// Set voltage and enable cores power. // Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000); max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
max7762x_regulator_enable(REGULATOR_CPU0, true); max7762x_regulator_enable(REGULATOR_CPU0, true);
} }
void _ccplex_enable_power_t210b01() static void _ccplex_enable_power_t210b01()
{ {
// Set voltage and enable cores power. // Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000); max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
max7762x_regulator_enable(REGULATOR_CPU1, true); max7762x_regulator_enable(REGULATOR_CPU1, true);
} }
void ccplex_boot_cpu0(u32 entry) static void _ccplex_disable_power()
{
// Disable cluster power.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
{
max7762x_regulator_enable(REGULATOR_CPU0, false);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
}
else
max7762x_regulator_enable(REGULATOR_CPU1, false);
}
void ccplex_boot_cpu0(u32 entry, bool lock)
{ {
// Set ACTIVE_CLUSER to FAST. // Set ACTIVE_CLUSER to FAST.
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW; FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
@@ -62,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
clock_enable_pllx(); clock_enable_pllx();
// Configure MSELECT source and enable clock to 102MHz. // 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_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
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. // Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ. CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000; CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
clock_enable_coresight(); clock_enable_coresight();
@@ -90,12 +104,15 @@ void ccplex_boot_cpu0(u32 entry)
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0; EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
// Set reset vector. // Set reset vector.
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN; SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
SB(SB_AA64_RESET_HIGH) = 0; SB(SB_AA64_RESET_HIGH) = 0;
// Non-secure reset vector write disable. // Non-secure reset vector write disable.
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS; if (lock)
(void)SB(SB_CSR); {
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
(void)SB(SB_CSR);
}
// Tighten up the security aperture. // Tighten up the security aperture.
// MC(MC_TZ_SECURITY_CTRL) = 1; // MC(MC_TZ_SECURITY_CTRL) = 1;
@@ -103,8 +120,46 @@ void ccplex_boot_cpu0(u32 entry)
// Clear MSELECT reset. // 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. // Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000; CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
// Clear CPU0 reset. // Clear CPU0 reset.
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset. // < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001; CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
}
void ccplex_powergate_cpu0()
{
#if CCPLEX_FLOWCTRL_POWERGATING
// Halt CPU0.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
// Powergate cluster via flow control without waiting for WFI.
FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
// Wait for the rail power off to finish.
while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
// Set CPU0 to waitevent.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
#endif
// Set CPU0 POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
// Set NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
// Set MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
// Disable CE0.
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
// Disable cluster 0 non-CPU.
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
// Disable CPU rail.
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
clock_disable_coresight();
// Clear out MSELECT and CPU clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
_ccplex_disable_power();
} }
+2 -1
View File
@@ -19,6 +19,7 @@
#include <utils/types.h> #include <utils/types.h>
void ccplex_boot_cpu0(u32 entry); void ccplex_boot_cpu0(u32 entry, bool lock);
void ccplex_powergate_cpu0();
#endif #endif
+47 -47
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -42,82 +42,82 @@ static const clock_osc_t _clock_osc_cnt[] = {
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */ /* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
static const clk_rst_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_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 } { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
}; };
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26. //I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
static const clk_rst_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_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 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, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
}; };
static clk_rst_t _clock_se = { 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. CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408MHz. Default: 408MHz. Max: 627.2 MHz.
}; };
static clk_rst_t _clock_tzram = { 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 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_host1x = { 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. CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408MHz.
}; };
static clk_rst_t _clock_tsec = { 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. CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204MHz. Max: 408MHz.
}; };
static clk_rst_t _clock_nvdec = { 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. CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2MHz.
}; };
static clk_rst_t _clock_nvjpg = { 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. CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
}; };
static clk_rst_t _clock_vic = { 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. CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8MHz.
}; };
static clk_rst_t _clock_sor_safe = { 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 CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_sor0 = { 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 CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_sor1 = { 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. CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204MHz.
}; };
static clk_rst_t _clock_kfuse = { 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 CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_cl_dvfs = { 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 CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_coresight = { 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. CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136MHz.
}; };
static clk_rst_t _clock_pwm = { 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. CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
}; };
static clk_rst_t _clock_sdmmc_legacy_tm = { 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 CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
}; };
static clk_rst_t _clock_apbdma = { 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. CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204MHz.
}; };
static clk_rst_t _clock_ahbdma = { 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 CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_actmon = { 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. CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2MHz.
}; };
static clk_rst_t _clock_extperiph1 = { 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 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
}; };
static clk_rst_t _clock_extperiph2 = { 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 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0MHz
}; };
void clock_enable(const clk_rst_t *clk) void clock_enable(const clk_rst_t *clk)
@@ -128,7 +128,7 @@ void clock_enable(const clk_rst_t *clk)
CLOCK(clk->enable) &= ~BIT(clk->index); CLOCK(clk->enable) &= ~BIT(clk->index);
// Configure clock source if required. // Configure clock source if required.
if (clk->source) if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29); CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
// Enable. // Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index); CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
usleep(2); usleep(2);
@@ -168,12 +168,12 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000; u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
if (baud == 3000000) if (baud == 3000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15; CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
else if (baud == 1000000) else if (baud == 1000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49; CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
else else
{ {
CLOCK(_clock_uart[idx].source) = clk_src_div | 2; CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
return 1; return 1;
} }
@@ -401,7 +401,7 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
// Set DISP1 clock source and parent clock. // Set DISP1 clock source and parent clock.
if (lowpower) if (lowpower)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = (2 << 29u) | CLK_SRC_DIV(1); // PLLD_OUT0.
// Set dividers and enable PLLD. // Set dividers and enable PLLD.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
@@ -715,38 +715,38 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
{ {
case 25000: case 25000:
*pclock = 24728; *pclock = 24728;
divisor = 31; // 16.5 div. divisor = CLK_SRC_DIV(16.5);
break; break;
case 26000: case 26000:
*pclock = 25500; *pclock = 25500;
divisor = 30; // 16 div. divisor = CLK_SRC_DIV(16);
break; break;
case 50000: case 50000:
*pclock = 48000; *pclock = 48000;
divisor = 15; // 8.5 div. divisor = CLK_SRC_DIV(8.5);
break; break;
case 52000: case 52000:
*pclock = 51000; *pclock = 51000;
divisor = 14; // 8 div. divisor = CLK_SRC_DIV(8);
break; break;
case 82000: case 82000:
*pclock = 81600; *pclock = 81600;
divisor = 8; // 5 div. divisor = CLK_SRC_DIV(5);
break; break;
case 100000: case 100000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT2; source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
*pclock = 99840; *pclock = 99840;
divisor = 2; // 2 div. divisor = CLK_SRC_DIV(2);
break; break;
case 164000: case 164000:
*pclock = 163200; *pclock = 163200;
divisor = 3; // 2.5 div. divisor = CLK_SRC_DIV(2.5);
break; break;
case 200000: case 200000:
@@ -762,14 +762,14 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
break; break;
} }
*pclock = 199680; *pclock = 199680;
divisor = 0; // 1 div. divisor = CLK_SRC_DIV(1);
break; break;
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
case 400000: case 400000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT0; source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
*pclock = 399360; *pclock = 399360;
divisor = 3; // 2.5 div divisor = CLK_SRC_DIV(2.5);
break; break;
#endif #endif
} }
@@ -785,7 +785,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
_clock_sdmmc_config_legacy_tm(); _clock_sdmmc_config_legacy_tm();
// Set SDMMC clock. // Set SDMMC clock.
u32 src_div = (source << 29) | divisor; u32 src_div = (source << 29u) | divisor;
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
+191 -94
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -198,6 +198,9 @@
#define UTMIPLL_LOCK BIT(31) #define UTMIPLL_LOCK BIT(31)
/*! Clock source */
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
/*! PTO_CLK_CNT */ /*! PTO_CLK_CNT */
#define PTO_REF_CLK_WIN_CFG_MASK 0xF #define PTO_REF_CLK_WIN_CFG_MASK 0xF
#define PTO_REF_CLK_WIN_CFG_16P 0xF #define PTO_REF_CLK_WIN_CFG_16P 0xF
@@ -227,138 +230,232 @@
/*! PTO IDs. */ /*! PTO IDs. */
typedef enum _clock_pto_id_t typedef enum _clock_pto_id_t
{ {
CLK_PTO_PCLK_SYS = 0x06, CLK_PTO_PCLK_SYS = 0x06,
CLK_PTO_HCLK_SYS = 0x07, 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_SPI1 = 0x17,
CLK_PTO_CCLK_G_DIV2 = 0x13, 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_SDMMC1 = 0x20,
CLK_PTO_SPI2 = 0x18, CLK_PTO_SDMMC2 = 0x21,
CLK_PTO_SPI3 = 0x19, CLK_PTO_SDMMC3 = 0x22,
CLK_PTO_SPI4 = 0x1A, CLK_PTO_SDMMC4 = 0x23,
CLK_PTO_MAUD = 0x1B, CLK_PTO_EMC = 0x24,
CLK_PTO_SCLK = 0x1C,
CLK_PTO_SDMMC1 = 0x20, CLK_PTO_DMIC3 = 0x2A,
CLK_PTO_SDMMC2 = 0x21, CLK_PTO_CCLK_LP = 0x2B,
CLK_PTO_SDMMC3 = 0x22, CLK_PTO_CCLK_LP_DIV2 = 0x2C,
CLK_PTO_SDMMC4 = 0x23,
CLK_PTO_EMC = 0x24,
CLK_PTO_CCLK_LP = 0x2B, CLK_PTO_MSELECT = 0x2F,
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
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_EQOS_AXI = 0x4C,
CLK_PTO_NVJPG = 0x3B, CLK_PTO_EQOS_PTP_REF = 0x4D,
CLK_PTO_TSEC = 0x3C, CLK_PTO_EQOS_TX = 0x4E,
CLK_PTO_TSECB = 0x3D, CLK_PTO_EQOS_RX = 0x4F,
CLK_PTO_SE = 0x3E,
CLK_PTO_DSIA_LP = 0x62, CLK_PTO_CILAB = 0x52,
CLK_PTO_CILCD = 0x53,
CLK_PTO_ISP = 0x64, CLK_PTO_CILEF = 0x55,
CLK_PTO_MC = 0x6A, CLK_PTO_PLLA1_PTO_OBS = 0x56,
CLK_PTO_PLLC4_PTO_OBS = 0x57,
CLK_PTO_ACTMON = 0x6B, CLK_PTO_PLLC2_PTO_OBS = 0x59,
CLK_PTO_CSITE = 0x6C, 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_MC = 0x6A,
CLK_PTO_SOC_THERM = 0x75,
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_HOST1X = 0x6F,
CLK_PTO_QSPI = 0x7D,
CLK_PTO_I2S1 = 0x80, CLK_PTO_QSPI_2X = 0x71,
CLK_PTO_I2S2 = 0x81, CLK_PTO_NVDEC = 0x72,
CLK_PTO_I2S3 = 0x82, CLK_PTO_NVJPG = 0x73,
CLK_PTO_I2S4 = 0x83, CLK_PTO_SE = 0x74,
CLK_PTO_I2S5 = 0x84, CLK_PTO_SOC_THERM = 0x75,
CLK_PTO_AHUB = 0x85,
CLK_PTO_APE = 0x86,
CLK_PTO_DVFS_SOC = 0x88, CLK_PTO_TSEC = 0x77,
CLK_PTO_DVFS_REF = 0x89, CLK_PTO_TSECB = 0x78,
CLK_PTO_VI = 0x79,
CLK_PTO_LA = 0x7A,
CLK_PTO_SCLK_SKIP = 0x7B,
CLK_PTO_SPDIF = 0x8F, CLK_PTO_ADSP_SKIP = 0x7C,
CLK_PTO_SPDIF_IN = 0x90, 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_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_EXTPERIPH1 = 0x9D,
CLK_PTO_I2C1 = 0x94, CLK_PTO_EXTPERIPH2 = 0x9E,
CLK_PTO_I2C2 = 0x95, CLK_PTO_EXTPERIPH3 = 0x9F,
CLK_PTO_I2C3 = 0x96, CLK_PTO_ENTROPY = 0xA0,
CLK_PTO_I2C4 = 0x97, CLK_PTO_UARTA = 0xA1,
CLK_PTO_I2C5 = 0x98, CLK_PTO_UARTB = 0xA2,
CLK_PTO_I2C6 = 0x99, CLK_PTO_UARTC = 0xA3,
CLK_PTO_I2C_SLOW = 0x9A, CLK_PTO_UARTD = 0xA4,
CLK_PTO_UARTAPE = 0x9B, 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_SOR0 = 0xC0,
CLK_PTO_EXTPERIPH2 = 0x9E, CLK_PTO_SOR1 = 0xC1,
CLK_PTO_HDMI = 0xC2,
CLK_PTO_ENTROPY = 0xA0, CLK_PTO_DISP2 = 0xC4,
CLK_PTO_UARTA = 0xA1, CLK_PTO_DISP1 = 0xC5,
CLK_PTO_UARTB = 0xA2,
CLK_PTO_UARTC = 0xA3,
CLK_PTO_UARTD = 0xA4,
CLK_PTO_OWR = 0xA5,
CLK_PTO_HDA2CODEC_2X = 0xA7, CLK_PTO_PLLD_OBS = 0xCA,
CLK_PTO_HDA = 0xA8, 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_USB3_L1_TXCLKREF = 0x129,
CLK_PTO_SOR1 = 0xC1, 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_XUSB_FS = 0x136,
CLK_PTO_DISP1 = 0xC5, 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_USB3_L2_TXCLKREF = 0x13C,
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
CLK_PTO_XUSB_FS = 0x136, CLK_PTO_USB_L4_RX = 0x13E,
CLK_PTO_XUSB_SS_HOST_DEV = 0x137, CLK_PTO_USB_L6_RX = 0x13F,
CLK_PTO_XUSB_CORE_HOST = 0x138,
CLK_PTO_XUSB_CORE_DEV = 0x139,
/* /*
* PLL need PTO enabled in MISC registers. * PLL need PTO enabled in MISC registers.
* Normal div is 2 so result is multiplied with it. * Normal div is 2 so result is multiplied with it.
*/ */
CLK_PTO_PLLC_DIV2 = 0x01, CLK_PTO_PLLC_DIV2 = 0x01,
CLK_PTO_PLLM_DIV2 = 0x02, CLK_PTO_PLLM_DIV2 = 0x02,
CLK_PTO_PLLP_DIV2 = 0x03, CLK_PTO_PLLP_DIV2 = 0x03,
CLK_PTO_PLLA_DIV2 = 0x04, CLK_PTO_PLLA_DIV2 = 0x04,
CLK_PTO_PLLX_DIV2 = 0x05, 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_PLLA1_DIV2 = 0x55,
CLK_PTO_PLLC2_DIV2 = 0x58, CLK_PTO_PLLC2_DIV2 = 0x58,
CLK_PTO_PLLC3_DIV2 = 0x5A, CLK_PTO_PLLC3_DIV2 = 0x5A,
CLK_PTO_PLLD_DIV2 = 0xCB, CLK_PTO_PLLD_DIV2 = 0xCB,
CLK_PTO_PLLD2_DIV2 = 0xCD, CLK_PTO_PLLD2_DIV2 = 0xCD,
CLK_PTO_PLLDP_DIV2 = 0xCF, 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; } clock_pto_id_t;
/* /*
+9 -12
View File
@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2 * Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2023 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -102,7 +102,7 @@ u32 fuse_read_dramid(bool raw_id)
if (tegra_t210) if (tegra_t210)
{ {
if (dramid > 6) if (dramid > 7)
dramid = 0; dramid = 0;
} }
else else
@@ -167,11 +167,8 @@ int fuse_set_sbk()
void fuse_wait_idle() void fuse_wait_idle()
{ {
u32 ctrl; while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
do ;
{
ctrl = FUSE(FUSE_CTRL);
} while (((ctrl >> 16) & 0x1f) != 4);
} }
u32 fuse_read(u32 addr) u32 fuse_read(u32 addr)
@@ -186,7 +183,7 @@ u32 fuse_read(u32 addr)
void fuse_read_array(u32 *words) void fuse_read_array(u32 *words)
{ {
u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ?
FUSE_ARRAY_WORDS_NUM_T210B01 : FUSE_ARRAY_WORDS_NUM; FUSE_ARRAY_WORDS_NUM_B01 : FUSE_ARRAY_WORDS_NUM;
for (u32 i = 0; i < array_size; i++) for (u32 i = 0; i < array_size; i++)
words[i] = fuse_read(i); words[i] = fuse_read(i);
@@ -325,9 +322,9 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
// Parse extra T210B01 fuses when the difference is reached. // Parse extra T210B01 fuses when the difference is reached.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 && if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) - word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32))) (FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
{ {
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1; word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
} }
} }
@@ -395,9 +392,9 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
// Parse extra T210B01 fuses when the difference is reached. // Parse extra T210B01 fuses when the difference is reached.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 && if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) - word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32))) (FUSE_ARRAY_WORDS_NUM_B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
{ {
word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1; word_addr = FUSE_ARRAY_WORDS_NUM_B01 - 1;
} }
} }
+254 -52
View File
@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2 * Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2023 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -23,67 +23,269 @@
#include <utils/types.h> #include <utils/types.h>
/*! Fuse registers. */ /*! Fuse registers. */
#define FUSE_CTRL 0x0 #define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4 #define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8 #define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC #define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10 #define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14 #define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18 #define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C #define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20 #define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24 #define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28 #define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C #define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30 #define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34 #define FUSE_PWR_GOOD_SW 0x34
#define FUSE_PRIV2RESHIFT 0x3C
#define FUSE_FUSETIME_RD0 0x40
#define FUSE_FUSETIME_RD1 0x44
#define FUSE_FUSETIME_RD2 0x48
#define FUSE_FUSETIME_RD3 0x4C
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
/*! Fuse Cached registers */ /*! Fuse Cached registers */
#define FUSE_SKU_INFO 0x110 #define FUSE_RESERVED_ODM8_B01 0x98
#define FUSE_CPU_SPEEDO_0_CALIB 0x114 #define FUSE_RESERVED_ODM9_B01 0x9C
#define FUSE_CPU_IDDQ_CALIB 0x118 #define FUSE_RESERVED_ODM10_B01 0xA0
#define FUSE_OPT_FT_REV 0x128 #define FUSE_RESERVED_ODM11_B01 0xA4
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C #define FUSE_RESERVED_ODM12_B01 0xA8
#define FUSE_CPU_SPEEDO_2_CALIB 0x130 #define FUSE_RESERVED_ODM13_B01 0xAC
#define FUSE_SOC_SPEEDO_0_CALIB 0x134 #define FUSE_RESERVED_ODM14_B01 0xB0
#define FUSE_SOC_SPEEDO_1_CALIB 0x138 #define FUSE_RESERVED_ODM15_B01 0xB4
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C #define FUSE_RESERVED_ODM16_B01 0xB8
#define FUSE_SOC_IDDQ_CALIB 0x140 #define FUSE_RESERVED_ODM17_B01 0xBC
#define FUSE_OPT_CP_REV 0x190 #define FUSE_RESERVED_ODM18_B01 0xC0
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c #define FUSE_RESERVED_ODM19_B01 0xC4
#define FUSE_PRIVATE_KEY0 0x1A4 #define FUSE_RESERVED_ODM20_B01 0xC8
#define FUSE_PRIVATE_KEY1 0x1A8 #define FUSE_RESERVED_ODM21_B01 0xCC
#define FUSE_PRIVATE_KEY2 0x1AC #define FUSE_KEK00_B01 0xD0
#define FUSE_PRIVATE_KEY3 0x1B0 #define FUSE_KEK01_B01 0xD4
#define FUSE_PRIVATE_KEY4 0x1B4 #define FUSE_KEK02_B01 0xD8
#define FUSE_RESERVED_SW 0x1C0 #define FUSE_KEK03_B01 0xDC
#define FUSE_USB_CALIB 0x1F0 #define FUSE_BEK00_B01 0xE0
#define FUSE_SKU_DIRECT_CONFIG 0x1F4 #define FUSE_BEK01_B01 0xE4
#define FUSE_OPT_VENDOR_CODE 0x200 #define FUSE_BEK02_B01 0xE8
#define FUSE_OPT_FAB_CODE 0x204 #define FUSE_BEK03_B01 0xEC
#define FUSE_OPT_LOT_CODE_0 0x208 #define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
#define FUSE_OPT_LOT_CODE_1 0x20C #define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
#define FUSE_OPT_WAFER_ID 0x210 #define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
#define FUSE_OPT_X_COORDINATE 0x214 #define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
#define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_OPT_OPS_RESERVED 0x220
#define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_USB_CALIB_EXT 0x350
#define FUSE_RESERVED_FIELD 0x354
#define FUSE_RESERVED_ODM28_T210B01 0x240 #define FUSE_PRODUCTION_MODE 0x100
#define FUSE_JTAG_SECUREID_VALID 0x104
#define FUSE_ODM_LOCK 0x108
#define FUSE_OPT_OPENGL_EN 0x10C
#define FUSE_SKU_INFO 0x110
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
#define FUSE_CPU_IDDQ_CALIB 0x118
#define FUSE_RESERVED_ODM22_B01 0x11C
#define FUSE_RESERVED_ODM23_B01 0x120
#define FUSE_RESERVED_ODM24_B01 0x124
#define FUSE_OPT_FT_REV 0x128
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
#define FUSE_SOC_IDDQ_CALIB 0x140
#define FUSE_RESERVED_ODM25_B01 0x144
#define FUSE_FA 0x148
#define FUSE_RESERVED_PRODUCTION 0x14C
#define FUSE_HDMI_LANE0_CALIB 0x150
#define FUSE_HDMI_LANE1_CALIB 0x154
#define FUSE_HDMI_LANE2_CALIB 0x158
#define FUSE_HDMI_LANE3_CALIB 0x15C
#define FUSE_ENCRYPTION_RATE 0x160
#define FUSE_PUBLIC_KEY0 0x164
#define FUSE_PUBLIC_KEY1 0x168
#define FUSE_PUBLIC_KEY2 0x16C
#define FUSE_PUBLIC_KEY3 0x170
#define FUSE_PUBLIC_KEY4 0x174
#define FUSE_PUBLIC_KEY5 0x178
#define FUSE_PUBLIC_KEY6 0x17C
#define FUSE_PUBLIC_KEY7 0x180
#define FUSE_TSENSOR1_CALIB 0x184
#define FUSE_TSENSOR2_CALIB 0x188
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
#define FUSE_OPT_CP_REV 0x190
#define FUSE_OPT_PFG 0x194
#define FUSE_TSENSOR0_CALIB 0x198
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
#define FUSE_SECURITY_MODE 0x1A0
#define FUSE_PRIVATE_KEY0 0x1A4
#define FUSE_PRIVATE_KEY1 0x1A8
#define FUSE_PRIVATE_KEY2 0x1AC
#define FUSE_PRIVATE_KEY3 0x1B0
#define FUSE_PRIVATE_KEY4 0x1B4
#define FUSE_ARM_JTAG_DIS 0x1B8
#define FUSE_BOOT_DEVICE_INFO 0x1BC
#define FUSE_RESERVED_SW 0x1C0
#define FUSE_OPT_VP9_DISABLE 0x1C4
#define FUSE_RESERVED_ODM0 0x1C8
#define FUSE_RESERVED_ODM1 0x1CC
#define FUSE_RESERVED_ODM2 0x1D0
#define FUSE_RESERVED_ODM3 0x1D4
#define FUSE_RESERVED_ODM4 0x1D8
#define FUSE_RESERVED_ODM5 0x1DC
#define FUSE_RESERVED_ODM6 0x1E0
#define FUSE_RESERVED_ODM7 0x1E4
#define FUSE_OBS_DIS 0x1E8
#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
#define FUSE_USB_CALIB 0x1F0
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
#define FUSE_PACKAGE_INFO 0x1FC
#define FUSE_OPT_VENDOR_CODE 0x200
#define FUSE_OPT_FAB_CODE 0x204
#define FUSE_OPT_LOT_CODE_0 0x208
#define FUSE_OPT_LOT_CODE_1 0x20C
#define FUSE_OPT_WAFER_ID 0x210
#define FUSE_OPT_X_COORDINATE 0x214
#define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_OPT_SEC_DEBUG_EN 0x21C
#define FUSE_OPT_OPS_RESERVED 0x220
#define FUSE_SATA_CALIB 0x224
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
#define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_TSENSOR3_CALIB 0x22C
#define FUSE_CLOCK_BONDOUT0 0x230
#define FUSE_CLOCK_BONDOUT1 0x234
#define FUSE_RESERVED_ODM26_B01 0x238
#define FUSE_RESERVED_ODM27_B01 0x23C
#define FUSE_RESERVED_ODM28_B01 0x240
#define FUSE_OPT_SAMPLE_TYPE 0x244
#define FUSE_OPT_SUBREVISION 0x248
#define FUSE_OPT_SW_RESERVED_0 0x24C
#define FUSE_OPT_SW_RESERVED_1 0x250
#define FUSE_TSENSOR4_CALIB 0x254
#define FUSE_TSENSOR5_CALIB 0x258
#define FUSE_TSENSOR6_CALIB 0x25C
#define FUSE_TSENSOR7_CALIB 0x260
#define FUSE_OPT_PRIV_SEC_DIS 0x264
#define FUSE_PKC_DISABLE 0x268
#define FUSE_BOOT_SECURITY_INFO_B01 0x268
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
#define FUSE_TSENSOR_COMMON 0x280
#define FUSE_OPT_CP_BIN 0x284
#define FUSE_OPT_GPU_DISABLE 0x288
#define FUSE_OPT_FT_BIN 0x28C
#define FUSE_OPT_DONE_MAP 0x290
#define FUSE_RESERVED_ODM29_B01 0x294
#define FUSE_APB2JTAG_DISABLE 0x298
#define FUSE_ODM_INFO 0x29C
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
#define FUSE_WOA_SKU_FLAG 0x2C0
#define FUSE_ECO_RESERVE_1 0x2C4
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
#define FUSE_PRODUCTION_MONTH 0x2CC
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
#define FUSE_TSENSOR9_CALIB 0x2D4
#define FUSE_VMIN_CALIBRATION 0x2DC
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
#define FUSE_SECURE_PROVISION_INDEX 0x2E8
#define FUSE_SECURE_PROVISION_INFO 0x2EC
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
#define FUSE_SPARE_ENDIS 0x2F4
#define FUSE_ECO_RESERVE_0 0x2F8
#define FUSE_RESERVED_CALIB0 0x304
#define FUSE_RESERVED_CALIB1 0x308
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
#define FUSE_OPT_CPU_DISABLE 0x314
#define FUSE_OPT_CPU_DISABLE_CP1 0x318
#define FUSE_TSENSOR10_CALIB 0x31C
#define FUSE_TSENSOR10_CALIB_AUX 0x320
#define FUSE_OPT_RAM_SVOP_DP 0x324
#define FUSE_OPT_RAM_SVOP_PDP 0x328
#define FUSE_OPT_RAM_SVOP_REG 0x32C
#define FUSE_OPT_RAM_SVOP_SP 0x330
#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
#define FUSE_OPT_ROM_SVOP_SP_B01 0x334
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
#define FUSE_USB_CALIB_EXT 0x350
#define FUSE_RESERVED_FIELD 0x354
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
#define FUSE_SPARE_BIT_0 0x380
//...
#define FUSE_SPARE_BIT_31 0x3FC
/*! Fuse commands. */ /*! Fuse commands. */
#define FUSE_READ 0x1 #define FUSE_IDLE 0x0
#define FUSE_WRITE 0x2 #define FUSE_READ 0x1
#define FUSE_SENSE 0x3 #define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3 #define FUSE_CMD_MASK 0x3
/*! Fuse status. */
#define FUSE_STATUS_RESET 0
#define FUSE_STATUS_POST_RESET 1
#define FUSE_STATUS_LOAD_ROW0 2
#define FUSE_STATUS_LOAD_ROW1 3
#define FUSE_STATUS_IDLE 4
#define FUSE_STATUS_READ_SETUP 5
#define FUSE_STATUS_READ_STROBE 6
#define FUSE_STATUS_SAMPLE_FUSES 7
#define FUSE_STATUS_READ_HOLD 8
#define FUSE_STATUS_FUSE_SRC_SETUP 9
#define FUSE_STATUS_WRITE_SETUP 10
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
#define FUSE_STATUS_WRITE_PROGRAM 12
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
#define FUSE_STATUS_FUSE_SRC_HOLD 14
#define FUSE_STATUS_LOAD_RIR 15
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
#define FUSE_STATUS_READ_DEASSERT_PD 17
/*! Fuse cache registers. */ /*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x)) #define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
#define FUSE_ARRAY_WORDS_NUM 192 #define FUSE_ARRAY_WORDS_NUM 192
#define FUSE_ARRAY_WORDS_NUM_T210B01 256 #define FUSE_ARRAY_WORDS_NUM_B01 256
enum enum
{ {
+9 -7
View File
@@ -85,7 +85,7 @@ static void _config_oscillators()
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1. 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_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_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_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
@@ -277,12 +277,12 @@ static void _config_regulators(bool tegra_t210)
// Disable low battery shutdown monitor. // Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false); max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power. // Disable SDMMC1 IO/Core power.
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
max7762x_regulator_enable(REGULATOR_LDO2, false); max7762x_regulator_enable(REGULATOR_LDO2, false);
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
sd_power_cycle_time_start = get_tmr_ms(); sd_power_cycle_time_start = get_tmr_ms();
// Disable LCD DVDD. // Disable LCD DVDD to make sure it's in a reset state.
max7762x_regulator_enable(REGULATOR_LDO0, false); 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_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
@@ -328,8 +328,10 @@ void hw_init()
// Bootrom stuff we skipped by going through rcm. // Bootrom stuff we skipped by going through rcm.
_config_se_brom(); _config_se_brom();
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11; //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. // Perform Memory Built-In Self Test WAR if T210.
if (tegra_t210) if (tegra_t210)
@@ -365,7 +367,7 @@ void hw_init()
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD); uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
#endif #endif
// Enable Dynamic Voltage and Frequency Scaling device clock. // Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
clock_enable_cl_dvfs(); clock_enable_cl_dvfs();
// Enable clocks to I2C1 and I2CPWR. // Enable clocks to I2C1 and I2CPWR.
+9 -14
View File
@@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include <soc/i2c.h> #include <soc/i2c.h>
#include <soc/t210.h>
#include <soc/timer.h> #include <soc/timer.h>
#define I2C_PACKET_PROT_I2C BIT(4) #define I2C_PACKET_PROT_I2C BIT(4)
@@ -81,14 +82,8 @@
#define MSTR_CONFIG_LOAD BIT(0) #define MSTR_CONFIG_LOAD BIT(0)
#define TIMEOUT_CONFIG_LOAD BIT(2) #define TIMEOUT_CONFIG_LOAD BIT(2)
static const u32 i2c_addrs[] = { /* I2C_1, 2, 3, 4, 5 and 6. */
0x7000C000, // I2C_1. static const u16 _i2c_base_offsets[6] = { 0x0, 0x400, 0x500, 0x700, 0x1000, 0x1100 };
0x7000C400, // I2C_2.
0x7000C500, // I2C_3.
0x7000C700, // I2C_4.
0x7000D000, // I2C_5.
0x7000D100 // I2C_6.
};
static void _i2c_load_cfg_wait(vu32 *base) static void _i2c_load_cfg_wait(vu32 *base)
{ {
@@ -108,7 +103,7 @@ static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
u32 tmp = 0; u32 tmp = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx]; vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and send mode. // Set device address and send mode.
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE; base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
@@ -154,7 +149,7 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
if (size > 8) if (size > 8)
return 0; return 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx]; vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and recv mode. // Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ; base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
@@ -198,7 +193,7 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
int res = 0; int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx]; vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts. // Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK | base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
@@ -270,7 +265,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
int res = 0; int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx]; vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts. // Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK | base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
@@ -352,7 +347,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
void i2c_init(u32 i2c_idx) void i2c_init(u32 i2c_idx)
{ {
vu32 *base = (vu32 *)i2c_addrs[i2c_idx]; vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2. base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE; base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
@@ -391,7 +386,7 @@ int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size) int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
{ {
u8 tmp[4]; u8 tmp[8];
if (size > 7) if (size > 7)
return 0; return 0;
+1 -1
View File
@@ -194,7 +194,7 @@ void irq_wait_event(u32 irq)
_irq_enable_source(irq); _irq_enable_source(irq);
// Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ. // Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ.
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
_irq_disable_source(irq); _irq_disable_source(irq);
_irq_ack_source(irq); _irq_ack_source(irq);
+1
View File
@@ -180,6 +180,7 @@
#define IRQ_EVENT_GPIO_A 162 #define IRQ_EVENT_GPIO_A 162
#define IRQ_EVENT_GPIO_B 163 #define IRQ_EVENT_GPIO_B 163
#define IRQ_EVENT_GPIO_C 164 #define IRQ_EVENT_GPIO_C 164
#define IRQ_EVENT_GPIO_D_T210B01 165
#define IRQ_FLOW_RSM_CPU 168 #define IRQ_FLOW_RSM_CPU 168
#define IRQ_FLOW_RSM_COP 169 #define IRQ_FLOW_RSM_COP 169
#define IRQ_TMR_SHARED 170 #define IRQ_TMR_SHARED 170
+9
View File
@@ -132,6 +132,9 @@
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10) #define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12) #define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14) #define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
#define APBDEV_PMC_FUSE_CONTROL 0x450
#define PMC_FUSE_CONTROL_PS18_LATCH_SET BIT(8)
#define PMC_FUSE_CONTROL_PS18_LATCH_CLR BIT(9)
#define APBDEV_PMC_IO_DPD3_REQ 0x45C #define APBDEV_PMC_IO_DPD3_REQ 0x45C
#define APBDEV_PMC_IO_DPD4_REQ 0x464 #define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4 #define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
@@ -177,6 +180,12 @@
#define PMC_LED_BREATHING_COUNTER_HZ 32768 #define PMC_LED_BREATHING_COUNTER_HZ 32768
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C #define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7 #define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
#define PMC_LED_BREATHING_FSM_STS_IDLE 0
#define PMC_LED_BREATHING_FSM_STS_UP_RAMP 1
#define PMC_LED_BREATHING_FSM_STS_PLATEAU 2
#define PMC_LED_BREATHING_FSM_STS_DOWN_RAMP 3
#define PMC_LED_BREATHING_FSM_STS_SHORT_LOW_PERIOD 4
#define PMC_LED_BREATHING_FSM_STS_LONG_LOW_PERIOD 5
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8 #define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0) #define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC #define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
+192 -141
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -20,125 +20,146 @@
#include <utils/types.h> #include <utils/types.h>
#define BOOTROM_BASE 0x100000 #define IROM_BASE 0x100000
#define IRAM_BASE 0x40000000 #define IRAM_BASE 0x40000000
#define HOST1X_BASE 0x50000000 #define HOST1X_BASE 0x50000000
#define BPMP_CACHE_BASE 0x50040000 #define BPMP_CACHE_BASE 0x50040000
#define DISPLAY_A_BASE 0x54200000 #define MSELECT_BASE 0x50060000
#define DSI_BASE 0x54300000 #define DPAUX1_BASE 0x54040000
#define VIC_BASE 0x54340000 #define TSEC2_BASE 0x54100000
#define NVDEC_BASE 0x54480000 #define DISPLAY_A_BASE 0x54200000
#define TSEC_BASE 0x54500000 #define DISPLAY_B_BASE 0x54240000
#define SOR1_BASE 0x54580000 #define DSI_BASE 0x54300000
#define MSELECT_BASE 0x50060000 #define VIC_BASE 0x54340000
#define ICTLR_BASE 0x60004000 #define NVJPG_BASE 0x54380000
#define TMR_BASE 0x60005000 #define NVDEC_BASE 0x54480000
#define CLOCK_BASE 0x60006000 #define NVENC_BASE 0x544C0000
#define FLOW_CTLR_BASE 0x60007000 #define TSEC_BASE 0x54500000
#define AHBDMA_BASE 0x60008000 #define SOR1_BASE 0x54580000
#define SYSREG_BASE 0x6000C000 #define GPU_BASE 0x57000000
#define SB_BASE (SYSREG_BASE + 0x200) #define GPU_USER_BASE 0x58000000
#define ACTMON_BASE 0x6000C800 #define RES_SEMAPH_BASE 0x60001000
#define GPIO_BASE 0x6000D000 #define ARB_SEMAPH_BASE 0x60002000
#define GPIO_1_BASE (GPIO_BASE) #define ARBPRI_BASE 0x60003000
#define GPIO_2_BASE (GPIO_BASE + 0x100) #define ICTLR_BASE 0x60004000
#define GPIO_3_BASE (GPIO_BASE + 0x200) #define TMR_BASE 0x60005000
#define GPIO_4_BASE (GPIO_BASE + 0x300) #define CLOCK_BASE 0x60006000
#define GPIO_5_BASE (GPIO_BASE + 0x400) #define FLOW_CTLR_BASE 0x60007000
#define GPIO_6_BASE (GPIO_BASE + 0x500) #define AHBDMA_BASE 0x60008000
#define GPIO_7_BASE (GPIO_BASE + 0x600) #define SYSREG_BASE 0x6000C000
#define GPIO_8_BASE (GPIO_BASE + 0x700) #define SB_BASE (SYSREG_BASE + 0x200)
#define EXCP_VEC_BASE 0x6000F000 #define ACTMON_BASE 0x6000C800
#define IPATCH_BASE 0x6001DC00 #define GPIO_BASE 0x6000D000
#define APBDMA_BASE 0x60020000 #define EXCP_VEC_BASE 0x6000F000
#define APB_MISC_BASE 0x70000000 #define IPATCH_BASE 0x6001DC00
#define PINMUX_AUX_BASE 0x70003000 #define APBDMA_BASE 0x60020000
#define UART_BASE 0x70006000 #define VGPIO_BASE 0x60024000
#define PWM_BASE 0x7000A000 #define APB_MISC_BASE 0x70000000
#define RTC_BASE 0x7000E000 #define PINMUX_AUX_BASE 0x70003000
#define PMC_BASE 0x7000E400 #define UART_BASE 0x70006000
#define SYSCTR0_BASE 0x700F0000 #define PWM_BASE 0x7000A000
#define FUSE_BASE 0x7000F800 #define I2C_BASE 0x7000C000
#define KFUSE_BASE 0x7000FC00 #define RTC_BASE 0x7000E000
#define SE_BASE 0x70012000 #define PMC_BASE 0x7000E400
#define MC_BASE 0x70019000 #define FUSE_BASE 0x7000F800
#define EMC_BASE 0x7001B000 #define KFUSE_BASE 0x7000FC00
#define EMC0_BASE 0x7001E000 #define SE_BASE 0x70012000
#define EMC1_BASE 0x7001F000 #define TSENSOR_BASE 0x70014000
#define XUSB_HOST_BASE 0x70090000 #define ATOMICS_BASE 0x70016000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define XUSB_PADCTL_BASE 0x7009F000 #define XUSB_PADCTL_BASE 0x7009F000
#define XUSB_DEV_BASE 0x700D0000 #define XUSB_DEV_BASE 0x700D0000
#define MIPI_CAL_BASE 0x700E3000 #define SDMMC_BASE 0x700B0000
#define CL_DVFS_BASE 0x70110000 #define SOC_THERM_BASE 0x700E2000
#define I2S_BASE 0x702D1000 #define MIPI_CAL_BASE 0x700E3000
#define ADMA_BASE 0x702E2000 #define SYSCTR0_BASE 0x700F0000
#define TZRAM_BASE 0x7C010000 #define SYSCTR1_BASE 0x70100000
#define CL_DVFS_BASE 0x70110000
#define APE_BASE 0x702C0000
#define AHUB_BASE 0x702D0000
#define AXBAR_BASE 0x702D0800
#define I2S_BASE 0x702D1000
#define ADMA_BASE 0x702E2000
#define SE2_BASE 0x70412000
#define SE_PKA1_BASE 0x70420000
#define TZRAM_BASE 0x7C010000
#define TZRAM_SIZE 0x10000 #define TZRAM_SIZE 0x10000
#define TZRAM_T210B01_SIZE 0x3C000 #define TZRAM_T210B01_SIZE 0x3C000
#define USB_BASE 0x7D000000 #define USB_BASE 0x7D000000
#define USB_OTG_BASE USB_BASE #define USB_OTG_BASE USB_BASE
#define USB1_BASE 0x7D004000 #define USB1_BASE 0x7D004000
#define EMEM_BASE 0x80000000
#define _REG(base, off) *(vu32 *)((base) + (off)) #define MMIO_REG32(base, off) *(vu32 *)((base) + (off))
#define HOST1X(off) _REG(HOST1X_BASE, off) #define HOST1X(off) MMIO_REG32(HOST1X_BASE, off)
#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off) #define BPMP_CACHE_CTRL(off) MMIO_REG32(BPMP_CACHE_BASE, off)
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off) #define MSELECT(off) MMIO_REG32(MSELECT_BASE, off)
#define DSI(off) _REG(DSI_BASE, off) #define DPAUX1(off) MMIO_REG32(DPAUX1_BASE, off)
#define VIC(off) _REG(VIC_BASE, off) #define TSEC2(off) MMIO_REG32(TSEC2_BASE, off)
#define NVDEC(off) _REG(NVDEC_BASE, off) #define DISPLAY_A(off) MMIO_REG32(DISPLAY_A_BASE, off)
#define TSEC(off) _REG(TSEC_BASE, off) #define DISPLAY_B(off) MMIO_REG32(DISPLAY_B_BASE, off)
#define SOR1(off) _REG(SOR1_BASE, off) #define DSI(off) MMIO_REG32(DSI_BASE, off)
#define MSELECT(off) _REG(MSELECT_BASE, off) #define VIC(off) MMIO_REG32(VIC_BASE, off)
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off) #define NVJPG(off) MMIO_REG32(NVJPG_BASE, off)
#define TMR(off) _REG(TMR_BASE, off) #define NVDEC(off) MMIO_REG32(NVDEC_BASE, off)
#define CLOCK(off) _REG(CLOCK_BASE, off) #define NVENC(off) MMIO_REG32(NVENC_BASE, off)
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off) #define TSEC(off) MMIO_REG32(TSEC_BASE, off)
#define SYSREG(off) _REG(SYSREG_BASE, off) #define SOR1(off) MMIO_REG32(SOR1_BASE, off)
#define AHB_GIZMO(off) _REG(SYSREG_BASE, off) #define GPU(off) MMIO_REG32(GPU_BASE, off)
#define SB(off) _REG(SB_BASE, off) #define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
#define ACTMON(off) _REG(ACTMON_BASE, off) #define ICTLR(cidx, off) MMIO_REG32(ICTLR_BASE + (0x100 * (cidx)), off)
#define GPIO(off) _REG(GPIO_BASE, off) #define TMR(off) MMIO_REG32(TMR_BASE, off)
#define GPIO_1(off) _REG(GPIO_1_BASE, off) #define CLOCK(off) MMIO_REG32(CLOCK_BASE, off)
#define GPIO_2(off) _REG(GPIO_2_BASE, off) #define FLOW_CTLR(off) MMIO_REG32(FLOW_CTLR_BASE, off)
#define GPIO_3(off) _REG(GPIO_3_BASE, off) #define AHBDMA(off) MMIO_REG32(AHBDMA_BASE, off)
#define GPIO_4(off) _REG(GPIO_4_BASE, off) #define SYSREG(off) MMIO_REG32(SYSREG_BASE, off)
#define GPIO_5(off) _REG(GPIO_5_BASE, off) #define AHB_GIZMO(off) MMIO_REG32(SYSREG_BASE, off)
#define GPIO_6(off) _REG(GPIO_6_BASE, off) #define SB(off) MMIO_REG32(SB_BASE, off)
#define GPIO_7(off) _REG(GPIO_7_BASE, off) #define ACTMON(off) MMIO_REG32(ACTMON_BASE, off)
#define GPIO_8(off) _REG(GPIO_8_BASE, off) #define GPIO(off) MMIO_REG32(GPIO_BASE, off)
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off) #define EXCP_VEC(off) MMIO_REG32(EXCP_VEC_BASE, off)
#define APB_MISC(off) _REG(APB_MISC_BASE, off) #define APBDMA(off) MMIO_REG32(APBDMA_BASE, off)
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off) #define VGPIO(off) MMIO_REG32(VGPIO_BASE, off)
#define PWM(off) _REG(PWM_BASE, off) #define APB_MISC(off) MMIO_REG32(APB_MISC_BASE, off)
#define RTC(off) _REG(RTC_BASE, off) #define PINMUX_AUX(off) MMIO_REG32(PINMUX_AUX_BASE, off)
#define PMC(off) _REG(PMC_BASE, off) #define PWM(off) MMIO_REG32(PWM_BASE, off)
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off) #define RTC(off) MMIO_REG32(RTC_BASE, off)
#define FUSE(off) _REG(FUSE_BASE, off) #define PMC(off) MMIO_REG32(PMC_BASE, off)
#define KFUSE(off) _REG(KFUSE_BASE, off) #define SYSCTR0(off) MMIO_REG32(SYSCTR0_BASE, off)
#define SE(off) _REG(SE_BASE, off) #define SYSCTR1(off) MMIO_REG32(SYSCTR1_BASE, off)
#define MC(off) _REG(MC_BASE, off) #define FUSE(off) MMIO_REG32(FUSE_BASE, off)
#define EMC(off) _REG(EMC_BASE, off) #define KFUSE(off) MMIO_REG32(KFUSE_BASE, off)
#define EMC_CH0(off) _REG(EMC0_BASE, off) #define SE(off) MMIO_REG32(SE_BASE, off)
#define EMC_CH1(off) _REG(EMC1_BASE, off) #define MC(off) MMIO_REG32(MC_BASE, off)
#define XUSB_HOST(off) _REG(XUSB_HOST_BASE, off) #define EMC(off) MMIO_REG32(EMC_BASE, off)
#define XUSB_PADCTL(off) _REG(XUSB_PADCTL_BASE, off) #define EMC_CH0(off) MMIO_REG32(EMC0_BASE, off)
#define XUSB_DEV(off) _REG(XUSB_DEV_BASE, off) #define EMC_CH1(off) MMIO_REG32(EMC1_BASE, off)
#define XUSB_DEV_XHCI(off) _REG(XUSB_DEV_BASE, off) #define XUSB_HOST(off) MMIO_REG32(XUSB_HOST_BASE, off)
#define XUSB_DEV_PCI(off) _REG(XUSB_DEV_BASE + 0x8000, off) #define XUSB_PADCTL(off) MMIO_REG32(XUSB_PADCTL_BASE, off)
#define XUSB_DEV_DEV(off) _REG(XUSB_DEV_BASE + 0x9000, off) #define XUSB_DEV(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off) #define XUSB_DEV_XHCI(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off) #define XUSB_DEV_PCI(off) MMIO_REG32(XUSB_DEV_BASE + 0x8000, off)
#define I2S(off) _REG(I2S_BASE, off) #define XUSB_DEV_DEV(off) MMIO_REG32(XUSB_DEV_BASE + 0x9000, off)
#define ADMA(off) _REG(ADMA_BASE, off) #define MIPI_CAL(off) MMIO_REG32(MIPI_CAL_BASE, off)
#define USB(off) _REG(USB_BASE, off) #define CL_DVFS(off) MMIO_REG32(CL_DVFS_BASE, off)
#define USB1(off) _REG(USB1_BASE, off) #define I2S(off) MMIO_REG32(I2S_BASE, off)
#define TEST_REG(off) _REG(0x0, off) #define ADMA(off) MMIO_REG32(ADMA_BASE, off)
#define SE2(off) MMIO_REG32(SE2_BASE, off)
#define SE_PKA1(off) MMIO_REG32(SE_PKA1_BASE, off)
#define USB(off) MMIO_REG32(USB_BASE, off)
#define USB1(off) MMIO_REG32(USB1_BASE, off)
#define TEST_REG(off) MMIO_REG32(0x0, off)
/* HOST1X registers. */ /* HOST1X v3 registers. */
#define HOST1X_CH0_SYNC_BASE 0x2100 #define HOST1X_CH0_SYNC_BASE 0x2100
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4) #define HOST1X_CH0_SYNC_SYNCPT_BASE (HOST1X_CH0_SYNC_BASE + 0xF80)
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200) #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. */ /*! EVP registers. */
#define EVP_CPU_RESET_VECTOR 0x100 #define EVP_CPU_RESET_VECTOR 0x100
@@ -204,6 +225,12 @@
#define GP_HIDREV_MAJOR_T210 0x1 #define GP_HIDREV_MAJOR_T210 0x1
#define GP_HIDREV_MAJOR_T210B01 0x2 #define GP_HIDREV_MAJOR_T210B01 0x2
#define APB_MISC_GP_ASDBGREG 0x810 #define APB_MISC_GP_ASDBGREG 0x810
#define APB_MISC_GP_TRANSACTOR_SCRATCH 0x864
#define APB_MISC_GP_AVP_TRANSACTOR_SCRATCH 0x880
#define APB_MISC_GP_CPU0_TRANSACTOR_SCRATCH 0x884
#define APB_MISC_GP_CPU1_TRANSACTOR_SCRATCH 0x888
#define APB_MISC_GP_CPU2_TRANSACTOR_SCRATCH 0x88C
#define APB_MISC_GP_CPU3_TRANSACTOR_SCRATCH 0x890
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4 #define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34 #define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98 #define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
@@ -223,10 +250,10 @@
#define SB_AA64_RESET_HIGH 0x34 #define SB_AA64_RESET_HIGH 0x34
/*! SOR registers. */ /*! SOR registers. */
#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8 #define SOR_DP_HDCP_BKSV_LSB 0x1E8
#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C #define SOR_TMDS_HDCP_BKSV_LSB 0x21C
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB 0x208 #define SOR_TMDS_HDCP_CN_MSB 0x208
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB 0x20C #define SOR_TMDS_HDCP_CN_LSB 0x20C
/*! RTC registers. */ /*! RTC registers. */
#define APBDEV_RTC_SECONDS 0x8 #define APBDEV_RTC_SECONDS 0x8
@@ -251,6 +278,12 @@
#define SYSCTR0_COUNTERID10 0xFF8 #define SYSCTR0_COUNTERID10 0xFF8
#define SYSCTR0_COUNTERID11 0xFFC #define SYSCTR0_COUNTERID11 0xFFC
/*! IPATCH registers. */
#define IPATCH_CAM_VALID 0x0
#define IPATCH_CAM_BASE 0x4
#define IPATCH_CAM(i) (IPATCH_CAM_BASE + (i) * 4)
#define IPATCH_CAM_ENTRIES 12
/*! I2S registers. */ /*! I2S registers. */
#define I2S1_CG 0x88 #define I2S1_CG 0x88
#define I2S1_CTRL 0xA0 #define I2S1_CTRL 0xA0
@@ -276,29 +309,47 @@
#define EMC_SEPT_RUN BIT(31) #define EMC_SEPT_RUN BIT(31)
/*! Flow controller registers. */ /*! Flow controller registers. */
#define FLOW_CTLR_HALT_COP_EVENTS 0x4 #define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define HALT_COP_GIC_IRQ BIT(9) #define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define HALT_COP_LIC_IRQ BIT(11) #define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define HALT_COP_SEC BIT(23) #define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define HALT_COP_MSEC BIT(24) #define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define HALT_COP_USEC BIT(25) #define HALT_GIC_IRQ BIT(9)
#define HALT_COP_JTAG BIT(28) #define HALT_LIC_IRQ BIT(11)
#define HALT_COP_WAIT_EVENT BIT(30) #define HALT_SEC BIT(23)
#define HALT_COP_STOP_UNTIL_IRQ BIT(31) #define HALT_MSEC BIT(24)
#define HALT_COP_MAX_CNT 0xFF #define HALT_USEC BIT(25)
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0 #define HALT_JTAG BIT(28)
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14 #define HALT_MODE_NONE (0 << 29u)
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C #define HALT_MODE_RUN_AND_INT (1 << 29u)
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24 #define HALT_MODE_WAITEVENT (2 << 29u)
#define FLOW_CTLR_CPU0_CSR 0x8 #define HALT_MODE_WAITEVENT_AND_INT (3 << 29u)
#define FLOW_CTLR_CPU1_CSR 0x18 #define HALT_MODE_STOP_UNTIL_IRQ (4 << 29u)
#define FLOW_CTLR_CPU2_CSR 0x20 #define HALT_MODE_STOP_UNTIL_IRQ_AND_INT (5 << 29u)
#define FLOW_CTLR_CPU3_CSR 0x28 #define HALT_MODE_STOP_UNTIL_EVENT_AND_IRQ (6 << 29u)
#define FLOW_CTLR_RAM_REPAIR 0x40 #define HALT_MAX_CNT 0xFF
#define RAM_REPAIR_REQ BIT(0) #define FLOW_CTLR_COP_CSR 0xC
#define RAM_REPAIR_STS BIT(1) #define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98 #define FLOW_CTLR_CPU1_CSR 0x18
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0) #define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define CSR_ENABLE BIT(0)
#define CSR_WAIT_WFI_NONE (0 << 8u)
#define CSR_WAIT_WFI_CPU0 (BIT(0) << 8u)
#define CSR_ENABLE_EXT_CPU_ONLY (0 << 12u)
#define CSR_ENABLE_EXT_CPU_NCPU (1 << 12u)
#define CSR_ENABLE_EXT_CPU_RAIL (2 << 12u)
#define CSR_EVENT_FLAG BIT(14)
#define CSR_INTR_FLAG BIT(15)
#define CSR_HALT BIT(22)
#define FLOW_CTLR_CPU_PWR_CSR 0x38
#define CPU_PWR_RAIL_STS_MASK (3 << 1u)
#define CPU_PWR_RAIL_OFF 0
#define FLOW_CTLR_RAM_REPAIR 0x40
#define RAM_REPAIR_REQ BIT(0)
#define RAM_REPAIR_STS BIT(1)
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
/* MSelect registers */ /* MSelect registers */
#define MSELECT_CONFIG 0x00 #define MSELECT_CONFIG 0x00
+6
View File
@@ -71,6 +71,12 @@ void usleep(u32 us)
#endif #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) void timer_usleep(u32 us)
{ {
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us; TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;
+2
View File
@@ -51,6 +51,8 @@ u32 get_tmr_ms();
u32 get_tmr_s(); u32 get_tmr_s();
void usleep(u32 us); void usleep(u32 us);
void msleep(u32 ms); void msleep(u32 ms);
#define ILOOP(is) ((is) / 3)
void isleep(u32 is);
void timer_usleep(u32 us); void timer_usleep(u32 us);
+10 -10
View File
@@ -21,11 +21,11 @@
#include <soc/t210.h> #include <soc/t210.h>
/* UART A, B, C, D and E. */ /* UART A, B, C, D and E. */
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 }; static const u16 _uart_base_offsets[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
void uart_init(u32 idx, u32 baud, u32 mode) void uart_init(u32 idx, u32 baud, u32 mode)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
// Make sure no data is being sent. // Make sure no data is being sent.
if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR))) if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR)))
@@ -70,7 +70,7 @@ void uart_init(u32 idx, u32 baud, u32 mode)
void uart_wait_xfer(u32 idx, u32 which) void uart_wait_xfer(u32 idx, u32 which)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (UART_TX_IDLE & which) if (UART_TX_IDLE & which)
{ {
while (!(uart->UART_LSR & UART_LSR_TMTY)) while (!(uart->UART_LSR & UART_LSR_TMTY))
@@ -85,7 +85,7 @@ void uart_wait_xfer(u32 idx, u32 which)
void uart_send(u32 idx, const u8 *buf, u32 len) void uart_send(u32 idx, const u8 *buf, u32 len)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
for (u32 i = 0; i != len; i++) for (u32 i = 0; i != len; i++)
{ {
@@ -97,7 +97,7 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
u32 uart_recv(u32 idx, u8 *buf, u32 len) u32 uart_recv(u32 idx, u8 *buf, u32 len)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
bool manual_mode = uart->UART_MCR & UART_MCR_RTS; bool manual_mode = uart->UART_MCR & UART_MCR_RTS;
u32 timeout = get_tmr_us() + 250; u32 timeout = get_tmr_us() + 250;
u32 i; u32 i;
@@ -127,7 +127,7 @@ out:
void uart_invert(u32 idx, bool enable, u32 invert_mask) void uart_invert(u32 idx, bool enable, u32 invert_mask)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (enable) if (enable)
uart->UART_IRDA_CSR |= invert_mask; uart->UART_IRDA_CSR |= invert_mask;
@@ -138,7 +138,7 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask)
void uart_set_mode(u32 idx, u32 mode) void uart_set_mode(u32 idx, u32 mode)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_MCR = mode; uart->UART_MCR = mode;
(void)uart->UART_SPR; (void)uart->UART_SPR;
@@ -146,7 +146,7 @@ void uart_set_mode(u32 idx, u32 mode)
u32 uart_get_IIR(u32 idx) u32 uart_get_IIR(u32 idx)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
u32 iir = uart->UART_IIR_FCR & UART_IIR_INT_MASK; u32 iir = uart->UART_IIR_FCR & UART_IIR_INT_MASK;
@@ -158,7 +158,7 @@ u32 uart_get_IIR(u32 idx)
void uart_set_IIR(u32 idx) void uart_set_IIR(u32 idx)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD; uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD;
(void)uart->UART_SPR; (void)uart->UART_SPR;
@@ -168,7 +168,7 @@ void uart_set_IIR(u32 idx)
void uart_empty_fifo(u32 idx, u32 which) void uart_empty_fifo(u32 idx, u32 which)
{ {
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_MCR = 0; uart->UART_MCR = 0;
(void)uart->UART_SPR; (void)uart->UART_SPR;
+3 -3
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -135,7 +135,7 @@ int emmc_set_partition(u32 partition) { return sdmmc_storage_set_mmc_partition(&
void emmc_gpt_parse(link_t *gpt) void emmc_gpt_parse(link_t *gpt)
{ {
gpt_t *gpt_buf = (gpt_t *)calloc(GPT_NUM_BLOCKS, EMMC_BLOCKSIZE); gpt_t *gpt_buf = (gpt_t *)zalloc(GPT_NUM_BLOCKS * EMMC_BLOCKSIZE);
#ifdef BDK_EMUMMC_ENABLE #ifdef BDK_EMUMMC_ENABLE
emummc_storage_read(GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf); emummc_storage_read(GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf);
@@ -149,7 +149,7 @@ void emmc_gpt_parse(link_t *gpt)
for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++) for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++)
{ {
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1); emmc_part_t *part = (emmc_part_t *)zalloc(sizeof(emmc_part_t));
if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba) if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba)
continue; continue;
+1 -1
View File
@@ -26,7 +26,7 @@
#define GPT_FIRST_LBA 1 #define GPT_FIRST_LBA 1
#define GPT_NUM_BLOCKS 33 #define GPT_NUM_BLOCKS 33
#define EMMC_BLOCKSIZE 512 #define EMMC_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum enum
{ {
+26 -26
View File
@@ -39,40 +39,40 @@ typedef struct _mbr_part_t
typedef struct _mbr_t typedef struct _mbr_t
{ {
u8 bootstrap[440]; /* 0x000 */ u8 bootstrap[440];
u32 signature; /* 0x1B8 */ u32 signature;
u16 copy_protected; /* 0x1BC */ u16 copy_protected;
mbr_part_t partitions[4]; /* 0x1BE */ mbr_part_t partitions[4];
u16 boot_signature; /* 0x1FE */ u16 boot_signature;
} __attribute__((packed)) mbr_t; } __attribute__((packed)) mbr_t;
typedef struct _gpt_entry_t typedef struct _gpt_entry_t
{ {
u8 type_guid[0x10]; /* 0x00 */ u8 type_guid[0x10];
u8 part_guid[0x10]; /* 0x10 */ u8 part_guid[0x10];
u64 lba_start; /* 0x20 */ u64 lba_start;
u64 lba_end; /* 0x28 */ u64 lba_end;
u64 attrs; /* 0x30 */ u64 attrs;
u16 name[36]; /* 0x38 */ u16 name[36];
} gpt_entry_t; } gpt_entry_t;
typedef struct _gpt_header_t typedef struct _gpt_header_t
{ {
u64 signature; // "EFI PART" /* 0x00 */ u64 signature; // "EFI PART"
u32 revision; /* 0x08 */ u32 revision;
u32 size; /* 0x0C */ u32 size;
u32 crc32; /* 0x10 */ u32 crc32;
u32 res1; /* 0x14 */ u32 res1;
u64 my_lba; /* 0x18 */ u64 my_lba;
u64 alt_lba; /* 0x20 */ u64 alt_lba;
u64 first_use_lba; /* 0x28 */ u64 first_use_lba;
u64 last_use_lba; /* 0x30 */ u64 last_use_lba;
u8 disk_guid[0x10]; /* 0x38 */ u8 disk_guid[0x10];
u64 part_ent_lba; /* 0x48 */ u64 part_ent_lba;
u32 num_part_ents; /* 0x50 */ u32 num_part_ents;
u32 part_ent_size; /* 0x54 */ u32 part_ent_size;
u32 part_ents_crc32; /* 0x58 */ u32 part_ents_crc32;
u8 res2[420]; // Used as first 3 partition entries backup for HOS. /* 0x5C */ u8 res2[420]; // Used as first 3 partition entries backup for HOS.
} gpt_header_t; } gpt_header_t;
typedef struct _gpt_t typedef struct _gpt_t
+3 -3
View File
@@ -91,7 +91,7 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush
} }
// Encrypt cluster. // Encrypt cluster.
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, CORE_ENCRYPT, cluster, tweak, true, sector_in_cluster, bis_cache->dma_buff, buff, count * EMMC_BLOCKSIZE)) if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, ENCRYPT, cluster, tweak, true, sector_in_cluster, bis_cache->dma_buff, buff, count * EMMC_BLOCKSIZE))
return 1; // Encryption error. return 1; // Encryption error.
// If not reading from cache, do a regular read and decrypt. // If not reading from cache, do a regular read and decrypt.
@@ -177,7 +177,7 @@ static int nx_emmc_bis_read_block_normal(u32 sector, u32 count, void *buff)
tweak_exp = sector_in_cluster; tweak_exp = sector_in_cluster;
// Maximum one cluster (1 XTS crypto block 16KB). // Maximum one cluster (1 XTS crypto block 16KB).
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, CORE_ENCRYPT, prev_cluster, tweak, regen_tweak, tweak_exp, buff, bis_cache->dma_buff, count * EMMC_BLOCKSIZE)) if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, prev_cluster, tweak, regen_tweak, tweak_exp, buff, bis_cache->dma_buff, count * EMMC_BLOCKSIZE))
return 1; // R/W error. return 1; // R/W error.
prev_sector = sector + count - 1; prev_sector = sector + count - 1;
@@ -220,7 +220,7 @@ static int nx_emmc_bis_read_block_cached(u32 sector, u32 count, void *buff)
return 1; // R/W error. return 1; // R/W error.
// Decrypt cluster. // Decrypt cluster.
if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, CORE_ENCRYPT, cluster, cache_tweak, true, 0, bis_cache->dma_buff, bis_cache->dma_buff, BIS_CLUSTER_SIZE)) if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, cluster, cache_tweak, true, 0, bis_cache->dma_buff, bis_cache->dma_buff, BIS_CLUSTER_SIZE))
return 1; // Decryption error. return 1; // Decryption error.
// Copy to cluster cache. // Copy to cluster cache.
+11 -7
View File
@@ -85,13 +85,13 @@ typedef struct _nx_emmc_cal0_t
u8 bd_mac[6]; u8 bd_mac[6];
u8 crc16_pad4[2]; u8 crc16_pad4[2];
u8 rsvd2[8]; u8 rsvd2[8];
u8 acc_offset[6]; u16 acc_offset[3];
u8 crc16_pad5[2]; u8 crc16_pad5[2];
u8 acc_scale[6]; u16 acc_scale[3];
u8 crc16_pad6[2]; u8 crc16_pad6[2];
u8 gyro_offset[6]; u16 gyro_offset[3];
u8 crc16_pad7[2]; u8 crc16_pad7[2];
u8 gyro_scale[6]; u16 gyro_scale[3];
u8 crc16_pad8[2]; u8 crc16_pad8[2];
char serial_number[0x18]; char serial_number[0x18];
u8 crc16_pad9[8]; u8 crc16_pad9[8];
@@ -213,11 +213,15 @@ typedef struct _nx_emmc_cal0_t
// 6.0.0 and up. // 6.0.0 and up.
u8 battery_ver; 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. // 9.0.0 and up.
u32 home_menu_scheme_model; u32 color_model;
u8 crc16_pad59[0xC]; u8 crc16_pad60[0xC];
// 10.0.0 and up. // 10.0.0 and up.
u8 console_6axis_sensor_mount_type; u8 console_6axis_sensor_mount_type;
+1 -1
View File
@@ -22,7 +22,7 @@
#include <storage/sdmmc_driver.h> #include <storage/sdmmc_driver.h>
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#define SD_BLOCKSIZE 512 #define SD_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum enum
{ {
+225 -53
View File
@@ -28,6 +28,7 @@
#include <memory_map.h> #include <memory_map.h>
#include <gfx_utils.h> #include <gfx_utils.h>
//#define SDMMC_DEBUG_PRINT_SD_REGS
//#define DPRINTF(...) gfx_printf(__VA_ARGS__) //#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...) #define DPRINTF(...)
@@ -184,7 +185,7 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0; reqbuf.is_auto_stop_trn = 0;
@@ -215,7 +216,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.num_sectors = num_sectors; reqbuf.num_sectors = num_sectors;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = is_write; reqbuf.is_write = is_write;
reqbuf.is_multi_block = 1; reqbuf.is_multi_block = 1;
reqbuf.is_auto_stop_trn = 1; reqbuf.is_auto_stop_trn = 1;
@@ -326,7 +327,7 @@ reinit_try:
out: out:
sct_off += blkcnt; sct_off += blkcnt;
sct_total -= blkcnt; sct_total -= blkcnt;
bbuf += 512 * blkcnt; bbuf += SDMMC_DAT_BLOCKSIZE * blkcnt;
} }
return 1; return 1;
@@ -338,13 +339,13 @@ int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, vo
if (mc_client_has_access(buf) && !((u32)buf % 8)) if (mc_client_has_access(buf) && !((u32)buf % 8))
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0); return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) if (num_sectors > (SDMMC_UP_BUF_SZ / SDMMC_DAT_BLOCKSIZE))
return 0; return 0;
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER; u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
if (_sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 0)) if (_sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 0))
{ {
memcpy(buf, tmp_buf, 512 * num_sectors); memcpy(buf, tmp_buf, SDMMC_DAT_BLOCKSIZE * num_sectors);
return 1; return 1;
} }
return 0; return 0;
@@ -356,11 +357,11 @@ int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v
if (mc_client_has_access(buf) && !((u32)buf % 8)) if (mc_client_has_access(buf) && !((u32)buf % 8))
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1); return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) if (num_sectors > (SDMMC_UP_BUF_SZ / SDMMC_DAT_BLOCKSIZE))
return 0; return 0;
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER; u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
memcpy(tmp_buf, buf, 512 * num_sectors); memcpy(tmp_buf, buf, SDMMC_DAT_BLOCKSIZE * num_sectors);
return _sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 1); return _sdmmc_storage_readwrite(storage, sector, num_sectors, tmp_buf, 1);
} }
@@ -519,7 +520,7 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 512; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@@ -708,9 +709,9 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_wid
return 0; return 0;
DPRINTF("[MMC] card selected\n"); DPRINTF("[MMC] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512)) if (!_sdmmc_storage_set_blocklen(storage, EMMC_BLOCKSIZE))
return 0; return 0;
DPRINTF("[MMC] set blocklen to 512\n"); DPRINTF("[MMC] set blocklen to EMMC_BLOCKSIZE\n");
// Check system specification version, only version 4.0 and later support below features. // Check system specification version, only version 4.0 and later support below features.
if (storage->csd.mmca_vsn < CSD_SPEC_VER_4) if (storage->csd.mmca_vsn < CSD_SPEC_VER_4)
@@ -780,6 +781,133 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0); return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
} }
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
void _sd_storage_debug_print_cid(u32 *raw_cid)
{
gfx_printf("Card Identification\n");
gfx_printf("MID: %02X\n", unstuff_bits(raw_cid, 120, 8));
gfx_printf("OID %04X\n", unstuff_bits(raw_cid, 104, 16));
gfx_printf("PNM: %02X %02X %02X %02X %02X\n",
unstuff_bits(raw_cid, 96, 8), unstuff_bits(raw_cid, 88, 8),
unstuff_bits(raw_cid, 80, 8), unstuff_bits(raw_cid, 72, 8),
unstuff_bits(raw_cid, 64, 8));
gfx_printf("PRV: %02X\n", unstuff_bits(raw_cid, 56, 8));
gfx_printf("PSN: %08X\n", unstuff_bits(raw_cid, 24, 32));
gfx_printf("MDT: %03X\n", unstuff_bits(raw_cid, 8, 12));
gfx_printf("--RSVD-- %X\n", unstuff_bits(raw_cid, 20, 4));
}
void _sd_storage_debug_print_csd(u32 *raw_csd)
{
gfx_printf("\n");
gfx_printf("\nCSD_STRUCTURE: %X\n", unstuff_bits(raw_csd, 126, 2));
gfx_printf("TAAC: %02X\n", unstuff_bits(raw_csd, 112, 8));
gfx_printf("NSAC: %02X\n", unstuff_bits(raw_csd, 104, 8));
gfx_printf("TRAN_SPEED: %02X\n", unstuff_bits(raw_csd, 96, 8));
gfx_printf("CCC: %03X\n", unstuff_bits(raw_csd, 84, 12));
gfx_printf("READ_BL_LEN: %X\n", unstuff_bits(raw_csd, 80, 4));
gfx_printf("READ_BL_PARTIAL: %X\n", unstuff_bits(raw_csd, 79, 1));
gfx_printf("WRITE_BLK_MISALIGN: %X\n", unstuff_bits(raw_csd, 78, 1));
gfx_printf("READ_BLK_MISALIGN: %X\n", unstuff_bits(raw_csd, 77, 1));
gfx_printf("DSR_IMP: %X\n", unstuff_bits(raw_csd, 76, 1));
gfx_printf("C_SIZE: %06X\n", unstuff_bits(raw_csd, 48, 22));
gfx_printf("ERASE_BLK_LEN: %X\n", unstuff_bits(raw_csd, 46, 1));
gfx_printf("SECTOR_SIZE: %02X\n", unstuff_bits(raw_csd, 39, 6));
gfx_printf("WP_GRP_SIZE: %02X\n", unstuff_bits(raw_csd, 32, 6));
gfx_printf("WP_GRP_ENABLE: %X\n", unstuff_bits(raw_csd, 31, 1));
gfx_printf("R2W_FACTOR: %X\n", unstuff_bits(raw_csd, 26, 3));
gfx_printf("WRITE_BL_LEN: %X\n", unstuff_bits(raw_csd, 22, 4));
gfx_printf("WRITE_BL_PARTIAL: %X\n", unstuff_bits(raw_csd, 21, 1));
gfx_printf("FILE_FORMAT_GRP: %X\n", unstuff_bits(raw_csd, 15, 1));
gfx_printf("COPY: %X\n", unstuff_bits(raw_csd, 14, 1));
gfx_printf("PERM_WRITE_PROTECT: %X\n", unstuff_bits(raw_csd, 13, 1));
gfx_printf("TMP_WRITE_PROTECT: %X\n", unstuff_bits(raw_csd, 12, 1));
gfx_printf("FILE_FORMAT: %X\n", unstuff_bits(raw_csd, 10, 2));
gfx_printf("--RSVD-- %02X %02X %X %X %02X %X\n",
unstuff_bits(raw_csd, 120, 6), unstuff_bits(raw_csd, 70, 6),
unstuff_bits(raw_csd, 47, 1), unstuff_bits(raw_csd, 29, 2),
unstuff_bits(raw_csd, 16, 5), unstuff_bits(raw_csd, 8, 2));
}
void _sd_storage_debug_print_scr(u32 *raw_scr)
{
u32 resp[4];
memcpy(&resp[2], raw_scr, 8);
gfx_printf("\n");
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(resp, 60, 4));
gfx_printf("SD_SPEC: %X\n", unstuff_bits(resp, 56, 4));
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(resp, 55, 1));
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(resp, 52, 3));
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(resp, 48, 4));
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(resp, 47, 1));
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(resp, 43, 4));
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(resp, 42, 1));
gfx_printf("SD_SPECX: %X\n", unstuff_bits(resp, 38, 4));
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(resp, 32, 4));
gfx_printf("VENDOR: %08X\n", unstuff_bits(resp, 0, 32));
gfx_printf("--RSVD-- %X\n", unstuff_bits(resp, 36, 2));
}
void _sd_storage_debug_print_ssr(u8 *raw_ssr)
{
u32 raw_ssr0[4]; // 511:384.
u32 raw_ssr1[4]; // 383:256.
u32 raw_ssr2[4]; // 255:128.
u32 raw_ssr3[4]; // 127:0.
memcpy(raw_ssr0, &raw_ssr[0], 16);
memcpy(raw_ssr1, &raw_ssr[16], 16);
memcpy(raw_ssr2, &raw_ssr[32], 16);
memcpy(raw_ssr3, &raw_ssr[48], 16);
gfx_printf("\nSD Status:\n");
gfx_printf("DAT_BUS_WIDTH: %X\n", unstuff_bits(raw_ssr0, 510 - 384, 2));
gfx_printf("SECURED_MODE: %X\n", unstuff_bits(raw_ssr0, 509 - 384, 1));
gfx_printf("SECURITY_FUNCTIONS: %02X\n", unstuff_bits(raw_ssr0, 502 - 384, 6));
gfx_printf("SD_CARD_TYPE: %04X\n", unstuff_bits(raw_ssr0, 480 - 384, 16));
gfx_printf("SZ_OF_PROTECTED_AREA: %08X\n", unstuff_bits(raw_ssr0, 448 - 384, 32));
gfx_printf("SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 440 - 384, 8));
gfx_printf("PERFORMANCE_MOVE: %02X\n", unstuff_bits(raw_ssr0, 432 - 384, 8));
gfx_printf("AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 428 - 384, 4));
gfx_printf("ERAZE_SIZE: %04X\n", unstuff_bits(raw_ssr0, 408 - 384, 16));
gfx_printf("ERASE_TIMEOUT: %02X\n", unstuff_bits(raw_ssr0, 402 - 384, 6));
gfx_printf("ERASE_OFFSET: %X\n", unstuff_bits(raw_ssr0, 400 - 384, 2));
gfx_printf("UHS_SPEED_GRADE: %X\n", unstuff_bits(raw_ssr0, 396 - 384, 4));
gfx_printf("UHS_AU_SIZE: %X\n", unstuff_bits(raw_ssr0, 392 - 384, 4));
gfx_printf("VIDEO_SPEED_CLASS: %02X\n", unstuff_bits(raw_ssr0, 384 - 384, 8));
gfx_printf("VSC_AU_SIZE: %03X\n", unstuff_bits(raw_ssr1, 368 - 256, 10));
gfx_printf("SUS_ADDR: %06X\n", unstuff_bits(raw_ssr1, 346 - 256, 22));
gfx_printf("APP_PERF_CLASS: %X\n", unstuff_bits(raw_ssr1, 336 - 256, 4));
gfx_printf("PERFORMANCE_ENHANCE: %02X\n", unstuff_bits(raw_ssr1, 328 - 256, 8));
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313 - 256, 1));
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312 - 256, 1));
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
unstuff_bits(raw_ssr0, 496 - 384, 6), unstuff_bits(raw_ssr0, 424 - 384, 4),
unstuff_bits(raw_ssr1, 378 - 256, 6), unstuff_bits(raw_ssr1, 340 - 256, 6),
unstuff_bits(raw_ssr1, 314 - 256, 14));
gfx_printf("VENDOR_1: %06X %08X\n",
unstuff_bits(raw_ssr1, 288 - 256, 24), unstuff_bits(raw_ssr1, 256 - 256, 32));
gfx_printf("VENDOR_2: %08X %08X %08X %08X\n",
unstuff_bits(raw_ssr2, 224 - 128, 32), unstuff_bits(raw_ssr2, 192 - 128, 32),
unstuff_bits(raw_ssr2, 160 - 128, 32), unstuff_bits(raw_ssr2, 128 - 128, 32));
gfx_printf("VENDOR_3: %08X %08X %08X %08X\n",
unstuff_bits(raw_ssr3, 96 - 0, 32), unstuff_bits(raw_ssr3, 64, 32),
unstuff_bits(raw_ssr3, 32 - 0, 32), unstuff_bits(raw_ssr3, 0, 32));
}
#endif
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc) static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
{ {
sdmmc_cmd_t cmdbuf; sdmmc_cmd_t cmdbuf;
@@ -910,6 +1038,10 @@ static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
memcpy(&resp[2], storage->raw_scr, 8); memcpy(&resp[2], storage->raw_scr, 8);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_scr((u32 *)storage->raw_scr);
#endif
storage->scr.sda_vsn = unstuff_bits(resp, 56, 4); storage->scr.sda_vsn = unstuff_bits(resp, 56, 4);
storage->scr.bus_widths = unstuff_bits(resp, 48, 4); storage->scr.bus_widths = unstuff_bits(resp, 48, 4);
@@ -958,7 +1090,7 @@ static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@@ -982,7 +1114,7 @@ static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@@ -1056,29 +1188,40 @@ int _sd_storage_set_driver_type(sdmmc_storage_t *storage, u32 driver, u8 *buf)
/* /*
* SD Card DDR200 (DDR208) support * SD Card DDR200 (DDR208) support
* *
* Proper procedure: * DLL Tuning (a) or Tuning Window (b) procedure:
* 1. Check that Vendor Specific Command System is supported. * 1. Check that Vendor Specific Command System is supported.
* Used as Enable DDR200 Bus. * Used as Enable DDR200 Bus.
* 2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6. * 2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6.
* Access Mode group is left to default 0 (SDR12). * Access Mode group is left to default 0 (SDR12).
* 3. Setup clock to 200 or 208 MHz. * 3. Setup clock to 200 or 208 MHz.
* 4. Set host to DDR bus mode that supports such high clocks. * 4a. Set host to DDR200/HS400 bus mode that enables DLL syncing.
* Some hosts have special mode, others use DDR50 and others HS400. * Actual implementation supported by all DDR200 cards.
* 5. Execute Tuning. * --
* 4b. Set host to DDR50 bus mode that supports such high clocks.
* Execute Manual Tuning.
* Limited to non-Sandisk cards.
* *
* The true validation that this value in Group 2 activates it, is that DDR50 bus * On Tegra SoCs, that can be done with DDR50 host mode.
* and clocks/timings work fully after that point. * That's because HS400 4-bit or HS400 generally, is not supported on SD SDMMC.
* 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.
* *
* On Tegra X1, that can be done with DDR50 host mode. * On the original implementation of DDR200 from Sandisk, a DLL mechanism,
* Tuning though can't be done automatically on any DDR mode. * like the one in eMMC HS400 is mandatory.
* So it needs to be done manually and selected tap will be applied from the biggest * So the card can start data signals whenever it wants, and the host should
* sampling window. * synchronize to the first DAT signal edge change.
* Every single other vendor that implemented that, always starts data transfers
* aligned to clock. That basically makes DDR200 in such SD cards a SDR104 but
* sampled on both edges. So effectively, it's an in-spec signal with DDR50,
* only that is clocked at 200MHz, instead of 50MHz.
* So the extra needed thing is using a tuning window, which is absent from the
* original implementation, since DDL syncing does not use that.
* *
* Finally, all that simply works, because the marketing materials for DDR200 are * On DLL tuning method expected cards, the tuning window is tiny.
* basically overstatements to sell the feature. DDR200 is simply SDR104 in DDR mode, * So check against a minimum of 8 taps window, to disallow DDR200.
* so sampling on rising and falling edge and with variable output data window.
* It can be supported by any host that is fast enough to support DDR at 200/208MHz
* and can do hw/sw tuning for finding the proper sampling window in that mode.
*/ */
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
static int _sd_storage_enable_DDR200(sdmmc_storage_t *storage, u8 *buf) static int _sd_storage_enable_DDR200(sdmmc_storage_t *storage, u8 *buf)
@@ -1150,20 +1293,37 @@ static int _sd_storage_set_card_bus_speed(sdmmc_storage_t *storage, u32 hs_type,
return 0; return 0;
} }
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf) int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fmodes)
{ {
if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4) if (!buf)
return 0; buf = (u8 *)SDMMC_UPPER_BUFFER;
if (!_sd_storage_switch_get(storage, buf)) if (!_sd_storage_switch_get(storage, buf))
return 0; return 0;
u8 access_mode = buf[13]; fmodes->access_mode = buf[13] | (buf[12] << 8);
u16 power_limit = buf[7] | buf[6] << 8; fmodes->cmd_system = buf[11] | (buf[10] << 8);
fmodes->driver_strength = buf[9] | (buf[8] << 8);
fmodes->power_limit = buf[7] | (buf[6] << 8);
return 1;
}
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
{
sd_func_modes_t fmodes;
if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)
return 0;
if (!sd_storage_get_fmodes(storage, buf, &fmodes))
return 0;
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
u16 cmd_system = buf[11] | buf[10] << 8; DPRINTF("[SD] access: %02X, power: %02X, cmd: %02X\n", fmodes.access_mode, fmodes.power_limit, fmodes.cmd_system);
#else
DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
#endif #endif
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
u32 hs_type = 0; u32 hs_type = 0;
switch (type) switch (type)
@@ -1171,11 +1331,11 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
case SDHCI_TIMING_UHS_DDR200: case SDHCI_TIMING_UHS_DDR200:
// Fall through if DDR200 is not supported. // Fall through if DDR200 is not supported.
if (cmd_system & SD_MODE_UHS_DDR200) if (fmodes.cmd_system & SD_MODE_UHS_DDR200)
{ {
DPRINTF("[SD] setting bus speed to DDR200\n"); DPRINTF("[SD] setting bus speed to DDR200\n");
storage->csd.busspeed = 200; storage->csd.busspeed = 200;
_sd_storage_set_power_limit(storage, power_limit, buf); _sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
return _sd_storage_enable_DDR200(storage, buf); return _sd_storage_enable_DDR200(storage, buf);
} }
#endif #endif
@@ -1183,7 +1343,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR104:
case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_SDR82:
// Fall through if not supported. // Fall through if not supported.
if (access_mode & SD_MODE_UHS_SDR104) if (fmodes.access_mode & SD_MODE_UHS_SDR104)
{ {
type = SDHCI_TIMING_UHS_SDR104; type = SDHCI_TIMING_UHS_SDR104;
hs_type = UHS_SDR104_BUS_SPEED; hs_type = UHS_SDR104_BUS_SPEED;
@@ -1201,7 +1361,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
} }
case SDHCI_TIMING_UHS_SDR50: case SDHCI_TIMING_UHS_SDR50:
if (access_mode & SD_MODE_UHS_SDR50) if (fmodes.access_mode & SD_MODE_UHS_SDR50)
{ {
type = SDHCI_TIMING_UHS_SDR50; type = SDHCI_TIMING_UHS_SDR50;
hs_type = UHS_SDR50_BUS_SPEED; hs_type = UHS_SDR50_BUS_SPEED;
@@ -1211,7 +1371,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
} }
/* /*
case SDHCI_TIMING_UHS_DDR50: case SDHCI_TIMING_UHS_DDR50:
if (access_mode & SD_MODE_UHS_DDR50) if (fmodes.access_mode & SD_MODE_UHS_DDR50)
{ {
type = SDHCI_TIMING_UHS_DDR50; type = SDHCI_TIMING_UHS_DDR50;
hs_type = UHS_DDR50_BUS_SPEED; hs_type = UHS_DDR50_BUS_SPEED;
@@ -1221,7 +1381,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
} }
*/ */
case SDHCI_TIMING_UHS_SDR25: case SDHCI_TIMING_UHS_SDR25:
if (access_mode & SD_MODE_UHS_SDR25) if (fmodes.access_mode & SD_MODE_UHS_SDR25)
{ {
type = SDHCI_TIMING_UHS_SDR25; type = SDHCI_TIMING_UHS_SDR25;
hs_type = UHS_SDR25_BUS_SPEED; hs_type = UHS_SDR25_BUS_SPEED;
@@ -1238,7 +1398,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
// Try to raise the power limit to let the card perform better. // Try to raise the power limit to let the card perform better.
if (hs_type != UHS_SDR25_BUS_SPEED) if (hs_type != UHS_SDR25_BUS_SPEED)
_sd_storage_set_power_limit(storage, power_limit, buf); _sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
// Setup and set selected card and bus speed. // Setup and set selected card and bus speed.
if (!_sd_storage_set_card_bus_speed(storage, hs_type, buf)) if (!_sd_storage_set_card_bus_speed(storage, hs_type, buf))
@@ -1258,17 +1418,17 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf) static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
{ {
if (!_sd_storage_switch_get(storage, buf)) sd_func_modes_t fmodes;
if (!sd_storage_get_fmodes(storage, buf, &fmodes))
return 0; return 0;
u8 access_mode = buf[13]; DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
u16 power_limit = buf[7] | buf[6] << 8;
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
// Try to raise the power limit to let the card perform better. // Try to raise the power limit to let the card perform better.
_sd_storage_set_power_limit(storage, power_limit, buf); _sd_storage_set_power_limit(storage, fmodes.power_limit, buf);
if (!(access_mode & SD_MODE_HIGH_SPEED)) if (!(fmodes.access_mode & SD_MODE_HIGH_SPEED))
return 1; return 1;
if (!_sd_storage_set_card_bus_speed(storage, HIGH_SPEED_BUS_SPEED, buf)) if (!_sd_storage_set_card_bus_speed(storage, HIGH_SPEED_BUS_SPEED, buf))
@@ -1327,6 +1487,10 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
memcpy(raw_ssr1, &storage->raw_ssr[0], 16); memcpy(raw_ssr1, &storage->raw_ssr[0], 16);
memcpy(raw_ssr2, &storage->raw_ssr[16], 16); memcpy(raw_ssr2, &storage->raw_ssr[16], 16);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_ssr(storage->raw_ssr);
#endif
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1; storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448 - 384, 32); storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448 - 384, 32);
@@ -1363,7 +1527,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 0; reqbuf.is_write = 0;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
@@ -1382,7 +1546,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1); sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
// Convert buffer to LE. // Convert buffer to LE.
for (int i = 0; i < 64; i += 4) for (int i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
{ {
storage->raw_ssr[i + 3] = buf[i]; storage->raw_ssr[i + 3] = buf[i];
storage->raw_ssr[i + 2] = buf[i + 1]; storage->raw_ssr[i + 2] = buf[i + 1];
@@ -1399,6 +1563,10 @@ static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
{ {
u32 *raw_cid = (u32 *)&(storage->raw_cid); u32 *raw_cid = (u32 *)&(storage->raw_cid);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_cid(raw_cid);
#endif
storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); storage->cid.manfid = unstuff_bits(raw_cid, 120, 8);
storage->cid.oemid = unstuff_bits(raw_cid, 104, 16); storage->cid.oemid = unstuff_bits(raw_cid, 104, 16);
storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8); storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);
@@ -1417,6 +1585,10 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
{ {
u32 *raw_csd = (u32 *)&(storage->raw_csd); u32 *raw_csd = (u32 *)&(storage->raw_csd);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_csd(raw_csd);
#endif
storage->csd.structure = unstuff_bits(raw_csd, 126, 2); storage->csd.structure = unstuff_bits(raw_csd, 126, 2);
storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12); storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12);
storage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4); storage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4);
@@ -1425,7 +1597,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
{ {
case 0: case 0:
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2); storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA 512B. storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA SDMMC_DAT_BLOCKSIZE.
break; break;
case 1: case 1:
@@ -1527,9 +1699,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
return 0; return 0;
DPRINTF("[SD] card selected\n"); DPRINTF("[SD] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512)) if (!_sdmmc_storage_set_blocklen(storage, SD_BLOCKSIZE))
return 0; return 0;
DPRINTF("[SD] set blocklen to 512\n"); DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
// Disconnect Card Detect resistor from DAT3. // Disconnect Card Detect resistor from DAT3.
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN)) if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
@@ -1604,7 +1776,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf; sdmmc_req_t reqbuf;
reqbuf.buf = buf; reqbuf.buf = buf;
reqbuf.blksize = 64; reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1; reqbuf.num_sectors = 1;
reqbuf.is_write = 1; reqbuf.is_write = 1;
reqbuf.is_multi_block = 0; reqbuf.is_multi_block = 0;
+13
View File
@@ -19,8 +19,12 @@
#define _SDMMC_H_ #define _SDMMC_H_
#include <utils/types.h> #include <utils/types.h>
#include <storage/sd_def.h>
#include <storage/sdmmc_driver.h> #include <storage/sdmmc_driver.h>
#define SDMMC_CMD_BLOCKSIZE 64
#define SDMMC_DAT_BLOCKSIZE 512
extern u32 sd_power_cycle_time_start; extern u32 sd_power_cycle_time_start;
typedef enum _sdmmc_type typedef enum _sdmmc_type
@@ -195,6 +199,14 @@ typedef struct _sdmmc_storage_t
sd_ssr_t ssr; sd_ssr_t ssr;
} sdmmc_storage_t; } sdmmc_storage_t;
typedef struct _sd_func_modes_t
{
u16 access_mode;
u16 cmd_system;
u16 driver_strength;
u16 power_limit;
} sd_func_modes_t;
int sdmmc_storage_end(sdmmc_storage_t *storage); int sdmmc_storage_end(sdmmc_storage_t *storage);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
@@ -209,6 +221,7 @@ 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 mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf);
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf); int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf);
int sd_storage_get_ssr(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); u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
+29 -32
View File
@@ -39,12 +39,7 @@
#endif #endif
/*! SCMMC controller base addresses. */ /*! SCMMC controller base addresses. */
static const u32 _sdmmc_bases[4] = { static const u16 _sdmmc_base_offsets[4] = { 0x0, 0x200, 0x400, 0x600 };
0x700B0000,
0x700B0200,
0x700B0400,
0x700B0600,
};
int sdmmc_get_io_power(sdmmc_t *sdmmc) int sdmmc_get_io_power(sdmmc_t *sdmmc)
{ {
@@ -214,12 +209,12 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
#ifdef ERROR_EXTRA_PRINTING #ifdef ERROR_EXTRA_PRINTING
// Check if Comp pad is open or short to ground. // 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. // 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; // Use 0x1F mask for all.
u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask; u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
if (!autocal_pu_status) if (!autocal_pu_status)
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
else if (autocal_pu_status == code_mask)
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1); 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 #endif
// In case auto calibration fails, we load suggested standard values. // In case auto calibration fails, we load suggested standard values.
@@ -344,6 +339,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
break; break;
case SDHCI_TIMING_MMC_HS400: 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; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
@@ -375,12 +371,10 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
clock_sdmmc_config_clock_source(&clock, sdmmc->id, clock); clock_sdmmc_config_clock_source(&clock, sdmmc->id, clock);
sdmmc->card_clock = (clock + divisor - 1) / divisor; sdmmc->card_clock = (clock + divisor - 1) / divisor;
//if divisor != 1 && divisor << 31 -> error // (divisor != 1) && (divisor & 1) -> error
u16 div_lo = divisor >> 1; u16 div_lo = divisor >> 1;
u16 div_hi = 0; u16 div_hi = div_lo >> 8;
if (div_lo > 0xFF)
div_hi = div_lo >> SDHCI_DIV_LO_SHIFT;
sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK)) | 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); (div_lo << SDHCI_DIV_LO_SHIFT) | (div_hi << SDHCI_DIV_HI_SHIFT);
@@ -593,7 +587,7 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
if (cmd->check_busy) if (cmd->check_busy)
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC; cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
else else
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC; cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
break; break;
case SDMMC_RSP_TYPE_2: case SDMMC_RSP_TYPE_2:
@@ -717,7 +711,6 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
{ {
best_tap = (tap_start + tap_end) / 2; best_tap = (tap_start + tap_end) / 2;
best_size = win_size + iter_end; best_size = win_size + iter_end;
} }
tap_start = INVALID_TAP; tap_start = INVALID_TAP;
@@ -726,8 +719,9 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
} }
} }
// Check if failed.
if (!best_tap) // Check if failed or window too small.
if (!best_tap || best_size < SAMPLING_WINDOW_SIZE_MIN)
return 0; return 0;
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
@@ -746,9 +740,12 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t
* SD Card DDR200 (DDR208) support * SD Card DDR200 (DDR208) support
* *
* On Tegra X1, that can be done with DDR50 host mode. * On Tegra X1, that can be done with DDR50 host mode.
* Tuning though can't be done automatically on any DDR 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 * So it needs to be done manually and selected tap will be applied from the biggest
* sampling window. * 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) static int sdmmc_tuning_execute_ddr200(sdmmc_t *sdmmc)
{ {
@@ -850,14 +847,14 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN; sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;
sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE; sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE;
// Enable 32bit addressing if used (sysad. if blkcnt it fallbacks to 16bit). // Enable 32/64bit addressing if used (sysad. if blkcnt it fallbacks to 16bit).
sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN; sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN;
if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT)) if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT))
return 0; return 0;
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN; sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK; 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. sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 14; // TMCLK * 2^27.
return 1; return 1;
@@ -1025,7 +1022,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
return result; 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) if (!req->blksize || !req->num_sectors)
return 0; return 0;
@@ -1042,10 +1039,10 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
sdmmc->regs->admaaddr = admaaddr; sdmmc->regs->admaaddr = admaaddr;
sdmmc->regs->admaaddr_hi = 0; 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->blksize = req->blksize | (7u << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
sdmmc->regs->blkcnt = blkcnt; sdmmc->regs->blkcnt = blkcnt;
if (blkcnt_out) if (blkcnt_out)
*blkcnt_out = blkcnt; *blkcnt_out = blkcnt;
@@ -1071,7 +1068,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
return 1; return 1;
} }
static int _sdmmc_update_dma(sdmmc_t *sdmmc) static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
{ {
u16 blkcnt = 0; u16 blkcnt = 0;
do do
@@ -1097,7 +1094,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
// Update DMA. // Update DMA.
sdmmc->regs->admaaddr = sdmmc->dma_addr_next; sdmmc->regs->admaaddr = sdmmc->dma_addr_next;
sdmmc->regs->admaaddr_hi = 0; sdmmc->regs->admaaddr_hi = 0;
sdmmc->dma_addr_next += 0x80000; sdmmc->dma_addr_next += SZ_512K;
} }
} }
@@ -1128,7 +1125,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
bool is_data_present = false; bool is_data_present = false;
if (req) if (req)
{ {
if (!_sdmmc_config_dma(sdmmc, &blkcnt, req)) if (!_sdmmc_config_sdma(sdmmc, &blkcnt, req))
{ {
#ifdef ERROR_EXTRA_PRINTING #ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC%d: DMA Wrong cfg!", sdmmc->id + 1); EPRINTFARGS("SDMMC%d: DMA Wrong cfg!", sdmmc->id + 1);
@@ -1172,7 +1169,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
} }
if (req && result) if (req && result)
{ {
result = _sdmmc_update_dma(sdmmc); result = _sdmmc_update_sdma(sdmmc);
#ifdef ERROR_EXTRA_PRINTING #ifdef ERROR_EXTRA_PRINTING
if (!result) if (!result)
EPRINTFARGS("SDMMC%d: DMA Update failed!", sdmmc->id + 1); EPRINTFARGS("SDMMC%d: DMA Update failed!", sdmmc->id + 1);
@@ -1369,7 +1366,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
u16 divisor; u16 divisor;
u8 vref_sel = 7; u8 vref_sel = 7;
const u8 trim_values_t210[4] = { 2, 8, 3, 8 }; const u8 trim_values_t210[4] = { 2, 8, 3, 8 };
const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 }; const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 };
const u8 *trim_values; const u8 *trim_values;
@@ -1378,7 +1375,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
memset(sdmmc, 0, sizeof(sdmmc_t)); memset(sdmmc, 0, sizeof(sdmmc_t));
sdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id]; sdmmc->regs = (t210_sdmmc_t *)(SDMMC_BASE + (u32)_sdmmc_base_offsets[id]);
sdmmc->id = id; sdmmc->id = id;
sdmmc->clock_stopped = 1; sdmmc->clock_stopped = 1;
sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01; sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
+5 -4
View File
@@ -23,9 +23,9 @@
/*! SDMMC controller IDs. */ /*! SDMMC controller IDs. */
#define SDMMC_1 0 // Version 4.00. #define SDMMC_1 0 // Version 4.00.
#define SDMMC_2 1 // Version 5.1. #define SDMMC_2 1 // Version 5.0 + SW CQE + Enhanced Strobe.
#define SDMMC_3 2 // Version 4.00. #define SDMMC_3 2 // Version 4.00.
#define SDMMC_4 3 // Version 5.1. #define SDMMC_4 3 // Version 5.0 + SW CQE + Enhanced Strobe.
/*! SDMMC power types. */ /*! SDMMC power types. */
#define SDMMC_POWER_OFF 0 #define SDMMC_POWER_OFF 0
@@ -273,8 +273,9 @@
/*! Helper for SWITCH command argument. */ /*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
#define HW_TAP_TUNING 0x100 #define HW_TAP_TUNING 0x100
#define INVALID_TAP 0x100 #define INVALID_TAP 0x100
#define SAMPLING_WINDOW_SIZE_MIN 8
/*! SDMMC controller context. */ /*! SDMMC controller context. */
typedef struct _sdmmc_t typedef struct _sdmmc_t
+26 -17
View File
@@ -56,16 +56,19 @@ typedef struct _gamepad_report_t
typedef struct _jc_cal_t typedef struct _jc_cal_t
{ {
bool cl_done; // 15ms * JC_CAL_MAX_STEPS = 240 ms.
bool cr_done; #define JC_CAL_MAX_STEPS 16
u16 clx_max; u32 cl_step;
u16 clx_min; u32 cr_step;
u16 cly_max;
u16 cly_min; u16 clx_max;
u16 crx_max; u16 clx_min;
u16 crx_min; u16 cly_max;
u16 cry_max; u16 cly_min;
u16 cry_min; u16 crx_max;
u16 crx_min;
u16 cry_max;
u16 cry_min;
} jc_cal_t; } jc_cal_t;
static jc_cal_t jc_cal_ctx; static jc_cal_t jc_cal_ctx;
@@ -74,34 +77,40 @@ static usb_ops_t usb_ops;
static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad) static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
{ {
// Calibrate left stick. // Calibrate left stick.
if (!jc_cal_ctx.cl_done) if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
{ {
if (jc_pad->conn_l if (jc_pad->conn_l
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400 && jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00) && jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
{ {
jc_cal_ctx.cl_step++;
jc_cal_ctx.clx_max = jc_pad->lstick_x + 0x72; jc_cal_ctx.clx_max = jc_pad->lstick_x + 0x72;
jc_cal_ctx.clx_min = jc_pad->lstick_x - 0x72; jc_cal_ctx.clx_min = jc_pad->lstick_x - 0x72;
jc_cal_ctx.cly_max = jc_pad->lstick_y + 0x72; jc_cal_ctx.cly_max = jc_pad->lstick_y + 0x72;
jc_cal_ctx.cly_min = jc_pad->lstick_y - 0x72; jc_cal_ctx.cly_min = jc_pad->lstick_y - 0x72;
jc_cal_ctx.cl_done = true;
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
return false;
} }
else else
return false; return false;
} }
// Calibrate right stick. // Calibrate right stick.
if (!jc_cal_ctx.cr_done) if (jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{ {
if (jc_pad->conn_r if (jc_pad->conn_r
&& jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400 && jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400
&& jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00) && jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00)
{ {
jc_cal_ctx.cr_step++;
jc_cal_ctx.crx_max = jc_pad->rstick_x + 0x72; jc_cal_ctx.crx_max = jc_pad->rstick_x + 0x72;
jc_cal_ctx.crx_min = jc_pad->rstick_x - 0x72; jc_cal_ctx.crx_min = jc_pad->rstick_x - 0x72;
jc_cal_ctx.cry_max = jc_pad->rstick_y + 0x72; jc_cal_ctx.cry_max = jc_pad->rstick_y + 0x72;
jc_cal_ctx.cry_min = jc_pad->rstick_y - 0x72; jc_cal_ctx.cry_min = jc_pad->rstick_y - 0x72;
jc_cal_ctx.cr_done = true;
if (jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
return false;
} }
else else
return false; return false;
@@ -122,7 +131,7 @@ static bool _jc_poll(gamepad_report_t *rpt)
if (jc_pad->l3 && jc_pad->home) if (jc_pad->l3 && jc_pad->home)
return true; return true;
if (!jc_cal_ctx.cl_done || !jc_cal_ctx.cr_done) if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS || jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{ {
if (!_jc_calibration(jc_pad)) if (!_jc_calibration(jc_pad))
return false; return false;
@@ -130,9 +139,9 @@ static bool _jc_poll(gamepad_report_t *rpt)
// Re-calibrate on disconnection. // Re-calibrate on disconnection.
if (!jc_pad->conn_l) if (!jc_pad->conn_l)
jc_cal_ctx.cl_done = false; jc_cal_ctx.cl_step = 0;
if (!jc_pad->conn_r) if (!jc_pad->conn_r)
jc_cal_ctx.cr_done = false; jc_cal_ctx.cr_step = 0;
// Calculate left analog stick. // Calculate left analog stick.
if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min) if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min)
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -30,8 +30,8 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
DIR dir; DIR dir;
FILINFO fno; FILINFO fno;
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256); char *dir_entries = (char *)zalloc(MAX_ENTRIES * 256);
char *temp = (char *)calloc(1, 256); char *temp = (char *)zalloc(256);
if (!pattern && !f_opendir(&dir, directory)) if (!pattern && !f_opendir(&dir, directory))
{ {
+3 -3
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer * Copyright (c) 2018-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -41,7 +41,7 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
// Calculate total allocation size. // Calculate total allocation size.
u32 len = name ? strlen(name) + 1 : 0; u32 len = name ? strlen(name) + 1 : 0;
char *buf = calloc(sizeof(ini_sec_t) + len, 1); char *buf = zalloc(sizeof(ini_sec_t) + len);
csec = (ini_sec_t *)buf; csec = (ini_sec_t *)buf;
csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name); csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name);
@@ -144,7 +144,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
// Calculate total allocation size. // Calculate total allocation size.
u32 klen = strlen(&lbuf[0]) + 1; u32 klen = strlen(&lbuf[0]) + 1;
u32 vlen = strlen(&lbuf[i + 1]) + 1; u32 vlen = strlen(&lbuf[i + 1]) + 1;
char *buf = calloc(sizeof(ini_kv_t) + klen + vlen, 1); char *buf = zalloc(sizeof(ini_kv_t) + klen + vlen);
ini_kv_t *kv = (ini_kv_t *)buf; ini_kv_t *kv = (ini_kv_t *)buf;
buf += sizeof(ini_kv_t); buf += sizeof(ini_kv_t);
+51 -7
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2022 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -39,7 +39,7 @@ static void _s_putn(u32 v, int base, char fill, int fcnt)
static const char digits[] = "0123456789ABCDEF"; static const char digits[] = "0123456789ABCDEF";
char *p; char *p;
char buf[65]; char buf[65]; // Number char size + leftover for padding.
int c = fcnt; int c = fcnt;
bool negative = false; bool negative = false;
@@ -93,44 +93,66 @@ void s_printf(char *out_buf, const char *fmt, ...)
fmt++; fmt++;
fill = 0; fill = 0;
fcnt = 0; fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{ {
fcnt = *fmt; fcnt = *fmt; // Padding size or padding type.
fmt++; fmt++;
if (*fmt >= '0' && *fmt <= '9') if (*fmt >= '0' && *fmt <= '9')
{ {
// Padding size exists. Previous char was type.
fill = fcnt; fill = fcnt;
fcnt = *fmt - '0'; fcnt = *fmt - '0';
fmt++; fmt++;
parse_padding_dec:
// Parse padding size extra digits.
if (*fmt >= '0' && *fmt <= '9')
{
fcnt = fcnt * 10 + *fmt - '0';
fmt++;
goto parse_padding_dec;
}
} }
else else
{ {
// No padding type, use space. (Max padding size is 9).
fill = ' '; fill = ' ';
fcnt -= '0'; fcnt -= '0';
} }
} }
switch (*fmt) switch (*fmt)
{ {
case 'c': case 'c':
_s_putc(va_arg(ap, u32)); char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break; break;
case 's': case 's':
_s_puts(va_arg(ap, char *)); _s_puts(va_arg(ap, char *));
break; break;
case 'd': case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt); _s_putn(va_arg(ap, u32), 10, fill, fcnt);
break; break;
case 'p': case 'p':
case 'P': case 'P':
case 'x': case 'x':
case 'X': case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt); _s_putn(va_arg(ap, u32), 16, fill, fcnt);
break; break;
case '%': case '%':
_s_putc('%'); _s_putc('%');
break; break;
case '\0': case '\0':
goto out; goto out;
default: default:
_s_putc('%'); _s_putc('%');
_s_putc(*fmt); _s_putc(*fmt);
@@ -160,44 +182,66 @@ void s_vprintf(char *out_buf, const char *fmt, va_list ap)
fmt++; fmt++;
fill = 0; fill = 0;
fcnt = 0; fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{ {
fcnt = *fmt; fcnt = *fmt; // Padding size or padding type.
fmt++; fmt++;
if (*fmt >= '0' && *fmt <= '9') if (*fmt >= '0' && *fmt <= '9')
{ {
// Padding size exists. Previous char was type.
fill = fcnt; fill = fcnt;
fcnt = *fmt - '0'; fcnt = *fmt - '0';
fmt++; fmt++;
parse_padding_dec:
// Parse padding size extra digits.
if (*fmt >= '0' && *fmt <= '9')
{
fcnt = fcnt * 10 + *fmt - '0';
fmt++;
goto parse_padding_dec;
}
} }
else else
{ {
// No padding type, use space. (Max padding size is 9).
fill = ' '; fill = ' ';
fcnt -= '0'; fcnt -= '0';
} }
} }
switch(*fmt)
switch (*fmt)
{ {
case 'c': case 'c':
_s_putc(va_arg(ap, u32)); char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break; break;
case 's': case 's':
_s_puts(va_arg(ap, char *)); _s_puts(va_arg(ap, char *));
break; break;
case 'd': case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt); _s_putn(va_arg(ap, u32), 10, fill, fcnt);
break; break;
case 'p': case 'p':
case 'P': case 'P':
case 'x': case 'x':
case 'X': case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt); _s_putn(va_arg(ap, u32), 16, fill, fcnt);
break; break;
case '%': case '%':
_s_putc('%'); _s_putc('%');
break; break;
case '\0': case '\0':
goto out; goto out;
default: default:
_s_putc('%'); _s_putc('%');
_s_putc(*fmt); _s_putc(*fmt);
Loaded 100 of 109 files, more files were not shown because too many files have changed in this diff. Show more