uplift bdk

Signed-off-by: Damien Zhao <zdm65477730@126.com>
This commit is contained in:
Damien Zhao
2024-04-13 12:27:17 +08:00
parent cf9ec7683b
commit 029b32f722
109 changed files with 58033 additions and 2060 deletions

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -42,6 +42,26 @@ static bool _nx_aula = false;
static void _display_panel_and_hw_end(bool no_panel_deinit);
void display_enable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) |= intr;
}
void display_disable_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) &= ~intr;
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
}
void display_wait_interrupt(u32 intr)
{
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = intr;
// Interrupts are masked. Poll status register for checking if fired.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & intr))
;
}
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
{
u32 end = get_tmr_us() + timeout;
@@ -64,22 +84,18 @@ static void _display_dsi_wait_vblank(bool enable)
if (enable)
{
// 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.
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
// Wait for vblank before starting the transfer.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
}
else
{
// Wait for vblank before resetting sync points.
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
;
display_wait_interrupt(DC_CMD_INT_FRAME_END_INT);
usleep(14);
// 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;
// Disable and clear vblank interrupt.
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
display_disable_interrupt(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_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_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
// Bring every IO rail out of deep power down.
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;

View File

@@ -732,9 +732,10 @@
* [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
* [20] 96 [0F]: InnoLux P062CCA-AZ3 (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] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [20] 99 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV]
* [30] 93 [0F]: AUO A062TAN00 (59.06A33.000)
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
@@ -786,13 +787,25 @@ enum
PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A055TAN01 = 0x1030,
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_backlight_pwm_init();
void display_end();
/*! Interrupt management. */
void display_enable_interrupt(u32 intr);
void display_disable_interrupt(u32 intr);
void display_wait_interrupt(u32 intr);
/*! Get/Set Display panel ID. */
u16 display_get_decoded_panel_id();
void display_set_decoded_panel_id(u32 id);

View File

@@ -38,7 +38,7 @@
/ 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) */
#if FF_USE_MKFS

View File

@@ -43,7 +43,9 @@
#define JC_HORI_INPUT_RPT 0x00
#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_HID_CONN 0x10
#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_m_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?
jc_hid_in_sixaxis_rpt_t sixaxis[15];
} jc_sio_hid_in_rpt_t;

View File

@@ -90,6 +90,16 @@ typedef struct _jc_gamepad_rpt_t
jc_bt_conn_t bt_conn_r;
} 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_deinit();
jc_gamepad_rpt_t *joycon_poll();

View File

@@ -39,7 +39,7 @@ static touch_panel_info_t _panels[] =
{ 1, 0, 1, 1, "GiS GGM6 B2X" },// 1.
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3.
{ 3, 1, 0, 0, "GiS 5.5\"" },// 4.
{ 4, 0, 0, 1, "Samsung BH2109" },// 5?
{ 4, 0, 0, 1, "Samsung TSP" },// 5?
{ -1, 1, 0, 1, "GiS VA 6.2\"" } // 2.
};

View File

@@ -107,7 +107,7 @@
**************************************/
#include <mem/heap.h> /* malloc, calloc, free */
#define ALLOC(s) malloc(s)
#define ALLOC_AND_ZERO(s) calloc(1,s)
#define ALLOC_AND_ZERO(s) zalloc(s)
#define FREEMEM free
#include <string.h> /* memset, memcpy */
#define MEM_INIT memset

View File

@@ -6333,6 +6333,8 @@ FRESULT f_mkfs (
LEAVE_MKFS(FR_OK);
}
#if FF_MULTI_PARTITION
/*-----------------------------------------------------------------------*/
/* Create Partition Table on the Physical Drive */
@@ -6444,16 +6446,16 @@ FRESULT f_fdisk_mod (
for (i = 0; i < 4; i++, p += SZ_PTE) {
p_sect = szt[i]; /* Number of sectors */
if (p_sect == 0)
if (p_sect == 0)
continue;
if (i == 0) { /* Exclude first 16MiB of sd */
s_hd = 1;
b_sect += 32768; p_sect -= 32768;
}
}
else
s_hd = 0;
b_cyl = b_sect / sz_cyl;
e_cyl = ((b_sect + p_sect) / sz_cyl) - 1; /* End cylinder */

57
bdk/libs/fatfs/ffsystem.c Normal file
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

View File

@@ -17,7 +17,7 @@
#ifndef LV_CONF_H
#define LV_CONF_H
#include <utils/types.h>
#include <soc/timer.h>
#include <memory_map.h>
/*===================
Dynamic memory
@@ -126,7 +126,7 @@
#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/
/*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_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 */
@@ -147,10 +147,10 @@
#define LV_COMPILER_VLA_SUPPORTED 1 /* 1: Variable length array is supported*/
/*HAL settings*/
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
#if LV_TICK_CUSTOM == 1
#define LV_TICK_CUSTOM_INCLUDE <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*/
@@ -296,6 +296,9 @@
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
#define USE_LV_MBOX 1
#if USE_LV_MBOX != 0
# define LV_MBOX_CLOSE_ANIM_TIME 200 /*ms*/
#endif
/*Text area (dependencies: lv_label, lv_page)*/
#define USE_LV_TA 1

View File

@@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
/*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
lv_obj_invalidate(last_top);
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
}
}

View File

@@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
lv_obj_invalidate(last_top);
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
}
/*Send a signal about the press*/

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

View File

@@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
#endif
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
#else
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
((uint32_t) c & 0xFF))
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
((uint32_t) (c) & 0xFF))
#endif
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
/**

View File

@@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
* @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list
* @param node pointer to a node
* @return head changed
*/
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
{
bool changed = ll_new_p->head != node;
lv_ll_rem(ll_ori_p, node);
/*Set node as head*/
@@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
ll_new_p->tail = node;
}
return changed;
}
/**

View File

@@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
* @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list
* @param node pointer to a node
* @return head changed
*/
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
/**
* Return with head node of the linked list

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -32,13 +32,16 @@
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
/**********************
* TYPEDEFS
**********************/
@@ -57,8 +60,9 @@ static lv_style_t def;
static lv_style_t sb;
/*Saved input parameters*/
static uint16_t _hue;
static uint16_t _hue;
static lv_font_t * _font;
uint32_t theme_bg_color;
/**********************
* MACROS
@@ -80,18 +84,17 @@ static void basic_init(void)
//def.image.opa = LV_OPA_COVER;
lv_style_copy(&bg, &def);
bg.body.main_color = COLOR_HOS_BG;
//bg.body.main_color = LV_COLOR_BLACK;
bg.body.main_color = COLOR_BG;
bg.body.grad_color = bg.body.main_color;
bg.body.radius = 0;
bg.body.empty = 1;
lv_style_copy(&panel, &def);
panel.body.radius = DEF_RADIUS;
panel.body.main_color = COLOR_HOS_BG;
panel.body.grad_color = COLOR_HOS_BG;
panel.body.main_color = COLOR_BG;
panel.body.grad_color = COLOR_BG;
panel.body.border.width = 1;
panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
panel.body.border.color = COLOR_LIGHT_BORDER;
panel.body.border.opa = LV_OPA_COVER;
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
panel.body.shadow.type = LV_SHADOW_BOTTOM;
@@ -129,7 +132,7 @@ static void btn_init(void)
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
lv_style_copy(&rel, &def);
rel.body.main_color = COLOR_HOS_BG_LIGHT;
rel.body.main_color = COLOR_BG_LIGHT;
rel.body.grad_color = rel.body.main_color;
rel.body.radius = 6;
rel.body.padding.hor = LV_DPI / 3;
@@ -139,7 +142,7 @@ static void btn_init(void)
rel.body.shadow.type = LV_SHADOW_BOTTOM;
rel.body.shadow.width = 6;
rel.body.border.width = 0;
rel.body.border.color = COLOR_HOS_BG_LIGHT;
rel.body.border.color = COLOR_BG_LIGHT;
rel.body.border.part = LV_BORDER_FULL;
//rel.text.color = COLOR_HOS_TXT_WHITE;
@@ -162,7 +165,7 @@ static void btn_init(void)
tgl_pr.body.shadow.width = 0;
lv_style_copy(&ina, &rel);
ina.body.main_color = COLOR_HOS_BG_DARK;
ina.body.main_color = COLOR_BG_DARK;
ina.body.grad_color = ina.body.main_color;
//ina.body.shadow.width = 0;
ina.text.color = LV_COLOR_HEX(0x888888);
@@ -207,7 +210,7 @@ static void img_init(void)
img_light.image.intense = LV_OPA_80;
lv_style_copy(&img_dark, &def);
img_dark.image.color = COLOR_HOS_BG_DARKER;
img_dark.image.color = COLOR_BG_DARKER;
img_dark.image.intense = LV_OPA_80;
@@ -250,7 +253,7 @@ static void bar_init(void)
static lv_style_t bar_bg, bar_indic;
lv_style_copy(&bar_bg, &def);
bar_bg.body.main_color = COLOR_HOS_LIGHT_BORDER;
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
bar_bg.body.grad_color = bar_bg.body.main_color;
bar_bg.body.radius = 3;
bar_bg.body.border.width = 0;
@@ -536,9 +539,9 @@ static void mbox_init(void)
static lv_style_t bg;
lv_style_copy(&bg, theme.panel);
bg.body.main_color = LV_COLOR_HEX(0x464646);
bg.body.main_color = COLOR_BG_LIGHTER;
bg.body.grad_color = bg.body.main_color;
bg.body.shadow.color = COLOR_HOS_BG;
bg.body.shadow.color = COLOR_BG;
bg.body.shadow.type = LV_SHADOW_FULL;
bg.body.shadow.width = 8;
@@ -628,7 +631,7 @@ static void list_init(void)
// pr.text.font = _font;
lv_style_copy(&tgl_rel, &pr);
tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
tgl_rel.body.main_color = COLOR_BG_LIGHT;
tgl_rel.body.grad_color = tgl_rel.body.main_color;
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
@@ -639,7 +642,7 @@ static void list_init(void)
tgl_pr.body.border.width = 0;
lv_style_copy(&ina, &pr);
ina.body.main_color = COLOR_HOS_BG_DARK;
ina.body.main_color = COLOR_BG_DARK;
ina.body.grad_color = ina.body.main_color;
theme.list.sb = &sb;
@@ -667,7 +670,7 @@ static void ddlist_init(void)
bg.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&sel, &bg);
sel.body.main_color = COLOR_HOS_BG_LIGHT;
sel.body.main_color = COLOR_BG_LIGHT;
sel.body.grad_color = sel.body.main_color;
theme.ddlist.bg = &bg;
@@ -713,7 +716,7 @@ static void tabview_init(void)
indic.body.opa = LV_OPA_0;
lv_style_copy(&btn_bg, &def);
btn_bg.body.main_color = COLOR_HOS_BG;
btn_bg.body.main_color = COLOR_BG;
btn_bg.body.grad_color = btn_bg.body.main_color;
btn_bg.body.radius = 0;
btn_bg.body.empty = 1;
@@ -734,7 +737,7 @@ static void tabview_init(void)
rel.text.font = _font;
lv_style_copy(&pr, &def);
pr.body.main_color = COLOR_HOS_BG_LIGHT;
pr.body.main_color = COLOR_BG_LIGHT;
pr.body.grad_color = pr.body.main_color;
pr.body.border.width = 0;
pr.body.empty = 0;
@@ -750,7 +753,7 @@ static void tabview_init(void)
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
lv_style_copy(&tgl_pr, &def);
tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
tgl_pr.body.main_color = COLOR_BG_LIGHT;
tgl_pr.body.grad_color = tgl_pr.body.main_color;
tgl_pr.body.border.width = 0;
tgl_pr.body.empty = 0;
@@ -797,7 +800,7 @@ static void win_init(void)
static lv_style_t header, rel, pr;
lv_style_copy(&header, &def);
header.body.main_color = COLOR_HOS_BG;
header.body.main_color = COLOR_BG;
header.body.grad_color = header.body.main_color;
header.body.radius = 0;
header.body.border.width = 0;
@@ -843,10 +846,11 @@ static void win_init(void)
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
{
if(font == NULL) font = LV_FONT_DEFAULT;
theme_bg_color = bg_color;
_hue = hue;
_font = font;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -35,6 +35,14 @@ extern "C" {
/*********************
* DEFINES
*********************/
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
#define COLOR_HOS_BG_BASE_BLACK 0x000000
#define COLOR_HOS_BG_DARKER 0x1B1B1B
#define COLOR_HOS_BG_DARK 0x222222
#define COLOR_HOS_BG 0x2D2D2D
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
/**********************
* TYPEDEFS
@@ -44,13 +52,15 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
extern uint32_t theme_bg_color;
/**
* Initialize the material theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
/**
* Get a pointer to the theme

View File

@@ -70,89 +70,89 @@ typedef struct {
allocation_table_header_t *header;
} 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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->prev = start_index;
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);
}
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);
}
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);
}
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));
}
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));
}

View File

@@ -48,7 +48,7 @@ typedef struct {
uint64_t _length;
} 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;
}

View File

@@ -39,7 +39,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#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));
block->buffer = malloc(ctx->block_size);
block->index = -1;

View File

@@ -57,15 +57,15 @@ typedef struct {
substorage base_storage;
} 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);
}
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));
}
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));
}

View File

@@ -28,12 +28,12 @@ typedef struct {
uint32_t high;
} 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->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);
}

View File

@@ -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);
}
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. */
uint64_t path1_len = strlen(path1), path2_len = strlen(path2);
if (path1_len == 0 || path2_len == 0)

View File

@@ -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. */
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));
se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt));
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;
const uint8_t *buf = (const uint8_t *)buffer;
for (uint64_t i = 0; i < count; i++) {

View File

@@ -39,6 +39,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdint.h>
typedef enum
{
VALIDITY_UNCHECKED = 0,
VALIDITY_INVALID,
VALIDITY_VALID
} validity_t;
typedef struct {
substorage hash_storage;
int integrity_check_level;

View File

@@ -71,11 +71,11 @@ typedef struct {
uint8_t *free_blocks;
} 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;
}
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;
}

View File

@@ -47,7 +47,7 @@ typedef struct {
bool _finished;
} 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;
}

View File

@@ -80,7 +80,7 @@ remap_segment_ctx_t *save_remap_storage_init_segments(remap_storage_ctx_t *ctx)
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);
if (segment_idx < ctx->header->map_segment_count) {
for (unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++) {

View File

@@ -89,11 +89,11 @@ typedef struct {
substorage base_storage;
} 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));
}
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);
}

View File

@@ -106,7 +106,7 @@ static bool save_process_header(save_ctx_t *ctx) {
uint8_t cmac[0x10] __attribute__((aligned(4)));
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) {
ctx->header_cmac_validity = VALIDITY_VALID;
} else {
@@ -298,7 +298,7 @@ void save_free_contexts(save_ctx_t *ctx) {
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 (!save_cached_storage_flush(ctx->core_data_ivfc_storage.data_level)) {
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_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)) {
EPRINTF("Failed to write save header!");

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

View File

@@ -42,6 +42,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#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 {
allocation_table_storage_ctx_t base_storage;
const char *path;
@@ -50,7 +59,7 @@ typedef struct {
open_mode_t mode;
} 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;
}

View File

@@ -41,7 +41,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <gfx_utils.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);
}

View File

@@ -49,20 +49,20 @@ typedef struct {
hierarchical_save_file_table_ctx_t file_table;
} 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);
}
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);
}
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);
*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;
}

View File

@@ -43,7 +43,7 @@ void save_fs_list_init(save_filesystem_list_ctx_t *ctx) {
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;
if (save_allocation_table_storage_read(&ctx->storage, &capacity, 4, 4) != 4) {
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;
}
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;
if (save_allocation_table_storage_read(&ctx->storage, &length, 0, 4) != 4) {
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;
}
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;
}
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;
}

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

View File

@@ -39,6 +39,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <utils/types.h>
#define DIV_ROUND_UP(a, b) ((a + b - 1) / b)
typedef struct {
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);
@@ -51,7 +53,7 @@ typedef struct {
void *ctx;
} 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->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);
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);
}
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);
}
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);
}
@@ -162,7 +164,7 @@ static const storage_vt hierarchical_duplex_storage_vt = {
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 &&
size >= 0 &&
size <= total_size &&

View File

@@ -698,6 +698,8 @@
typedef enum _emc_mr_t
{
MR0_FEAT = 0,
MR4_TEMP = 4,
MR5_MAN_ID = 5,
MR6_REV_ID1 = 6,
MR7_REV_ID2 = 7,
@@ -710,7 +712,7 @@ enum
EMC_CHAN1 = 1
};
typedef struct _emc_mr_data_t
typedef struct _emc_mr_chip_data_t
{
// Device 0.
u8 rank0_ch0;
@@ -719,6 +721,12 @@ typedef struct _emc_mr_data_t
// Device 1.
u8 rank1_ch0;
u8 rank1_ch1;
} emc_mr_chip_data_t;
typedef struct _emc_mr_data_t
{
emc_mr_chip_data_t chip0;
emc_mr_chip_data_t chip1;
} emc_mr_data_t;
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -159,6 +159,13 @@ void *calloc(u32 num, u32 size)
return res;
}
void *zalloc(u32 size)
{
void *res = (void *)_heap_alloc(size);
memset(res, 0, ALIGN(size, sizeof(hnode_t))); // Clear the aligned size.
return res;
}
void free(void *buf)
{
if (buf >= _heap.start)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -48,6 +48,7 @@ void heap_init(void *base);
void heap_set(heap_t *heap);
void *malloc(u32 size);
void *calloc(u32 num, u32 size);
void *zalloc(u32 size);
void free(void *buf);
void heap_monitor(heap_monitor_t *mon, bool print_node_stats);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -21,7 +21,7 @@
#include <soc/t210.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_SIZE_MB) = size1mb;
@@ -31,96 +31,47 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)
void mc_config_carveout()
{
// Enable ACR GSR3.
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MC(MC_VIDEO_PROTECT_BOM) = 0;
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
MC(MC_VIDEO_PROTECT_REG_CTRL) = 1;
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
// Configure TSEC carveout @ 0x90000000, 1MB.
//mc_config_tsec_carveout(0x90000000, 1, false);
mc_config_tsec_carveout(0, 0, true);
// Configure TZDRAM carveout @ 0x90000000, 1MB.
//mc_config_tzdram_carveout(0x90000000, 1, false);
mc_config_tzdram_carveout(0, 0, true);
MC(MC_MTS_CARVEOUT_BOM) = 0;
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MC(MC_MTS_CARVEOUT_ADR_HI) = 0;
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MC(MC_SECURITY_CARVEOUT1_BOM) = 0;
MC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MC(MC_SECURITY_CARVEOUT1_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_APERTURE_ID(0) |
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
MC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
MC(MC_SECURITY_CARVEOUT3_BOM) = 0;
MC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MC(MC_SECURITY_CARVEOUT4_BOM) = 0;
MC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT4_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_RD_NS |
SEC_CARVEOUT_CFG_WR_NS;
MC(MC_SECURITY_CARVEOUT5_BOM) = 0;
MC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
SEC_CARVEOUT_CFG_LOCKED |
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
SEC_CARVEOUT_CFG_RD_NS |
SEC_CARVEOUT_CFG_WR_NS;
}
void mc_enable_ahb_redirect()
@@ -157,12 +108,10 @@ bool mc_client_has_access(void *address)
void mc_enable()
{
// Reset EMC source to PLLP.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29);
// Enable memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29u);
// Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
// Clear clock resets for memory.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
usleep(5);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2014, NVIDIA Corporation.
* Copyright (c) 2018-2023, CTCaer
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -14,6 +15,22 @@
#ifndef _MC_T210_H_
#define _MC_T210_H_
/*! MC SMMU registers */
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
/*! MC General registers */
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
@@ -464,7 +481,7 @@
#define MC_UNTRANSLATED_REGION_CHECK 0x948
#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_DISPLAY0A BIT(1)
#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_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_VDEMBE BIT(3)
#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_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_VDETPM BIT(1)
#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4)
@@ -524,7 +541,7 @@
#define SEC_CARVEOUT_CA2_W_GPU BIT(25)
#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_SDMMCAA BIT(1)
#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2)
@@ -544,7 +561,7 @@
#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30)
#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_W_SE BIT(1)
#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2)

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
* under the terms and conditions of the GNU General Public License,
@@ -27,13 +27,18 @@
#include <soc/t210.h>
#include <utils/util.h>
#define TABLE_FREQ_KHZ_OFFSET 0x40
#define TABLE_LA_REGS_T210_OFFSET 0x1284
#define TABLE_LA_REGS_T210B01_OFFSET 0xFA4
#define LA_SDMMC1_INDEX 6
extern volatile nyx_storage_t *nyx_str;
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init()
{
u32 curr_ram_idx = 0;
u32 tbl_idx = 0;
minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
@@ -98,13 +103,13 @@ u32 minerva_init()
// Get current frequency
u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++)
{
if (current_emc_clk_src == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)
if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc)
break;
}
mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;
mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz;
mtc_cfg->rate_to = FREQ_204;
mtc_cfg->train_mode = OP_TRAIN;
minerva_cfg(mtc_cfg, NULL);
@@ -140,6 +145,27 @@ void minerva_change_freq(minerva_freq_t freq)
}
}
void minerva_sdmmc_la_program(void *table, bool t210b01)
{
u32 freq = *(u32 *)(table + TABLE_FREQ_KHZ_OFFSET);
u32 *la_scale_regs = (u32 *)(table + (t210b01 ? TABLE_LA_REGS_T210B01_OFFSET : TABLE_LA_REGS_T210_OFFSET));
// Adjust SDMMC1 latency allowance.
switch (freq)
{
case 204000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 50;
break;
case 408000:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 25;
break;
default:
la_scale_regs[LA_SDMMC1_INDEX] = (la_scale_regs[LA_SDMMC1_INDEX] & 0xFF0000) | 20;
break;
}
}
void minerva_prep_boot_freq()
{
if (!minerva_cfg)
@@ -157,23 +183,46 @@ void minerva_prep_boot_freq()
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)
return;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
// Program SDMMC LA regs.
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
// Add OC frequency.
if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600)
{
memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries],
&mtc_cfg->mtc_table[mtc_cfg->table_entries - 1],
sizeof(emc_table_t));
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
mtc_cfg->mtc_table[mtc_cfg->table_entries].opt_custom = opt_custom;
mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq;
mtc_cfg->table_entries++;
}
// Trim table.
int entries = 0;
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{
// Copy frequencies from 204/408/800 MHz and 1333+ MHz.
int rate = mtc_cfg->mtc_table[i].rate_khz;
if (rate == FREQ_204 ||
rate == FREQ_408 ||
rate == FREQ_800 ||
rate >= FREQ_1333)
{
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
entries++;
}
}
mtc_cfg->table_entries = entries;
// Set init frequency.
minerva_change_freq(FREQ_204);
@@ -181,35 +230,21 @@ void minerva_prep_boot_l4t(int oc_freq)
mtc_cfg->train_mode = OP_TRAIN;
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.
if (mtc_cfg->rate_to == FREQ_204 || mtc_cfg->rate_to == FREQ_800 || mtc_cfg->rate_to == FREQ_1600)
// Skip already trained frequencies and OC freq (Arachne handles it).
if (mtc_cfg->mtc_table[i].trained || mtc_cfg->rate_to == oc_freq)
continue;
// Train frequency.
mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz;
minerva_cfg(mtc_cfg, NULL);
}
// Do FSP WAR and scale to 800 MHz as boot freq.
bool fsp_opwr_disabled = !(EMC(EMC_MRW3) & 0xC0);
if (fsp_opwr_disabled)
minerva_change_freq(FREQ_666);
minerva_change_freq(FREQ_1333);
minerva_change_freq(FREQ_800);
// Trim table.
int entries = 0;
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
{
// Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above.
int rate = mtc_cfg->mtc_table[i].rate_khz;
if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600)
{
memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t));
entries++;
}
}
mtc_cfg->table_entries = entries;
// Do not let other mtc ops.
mtc_cfg->init_done = 0;
}

View File

@@ -53,16 +53,18 @@ enum train_mode_t
typedef enum
{
FREQ_204 = 204000,
FREQ_666 = 665600,
FREQ_408 = 408000,
FREQ_800 = 800000,
FREQ_1333 = 1331200,
FREQ_1600 = 1600000
} minerva_freq_t;
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init();
void minerva_change_freq(minerva_freq_t freq);
void minerva_sdmmc_la_program(void *table, bool t210b01);
void minerva_prep_boot_freq();
void minerva_prep_boot_l4t(int oc_freq);
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom);
void minerva_periodic_training();
emc_table_t *minerva_get_mtc_table();
int minerva_get_mtc_table_entries();

View File

@@ -481,7 +481,8 @@ typedef struct
u32 rate_khz;
u32 min_volt;
u32 gpu_min_volt;
char clock_src[32];
char clock_src[28];
u32 opt_custom;
u32 clk_src_emc;
u32 needs_training;
u32 training_pattern;

View File

@@ -42,8 +42,8 @@
typedef struct _sdram_vendor_patch_t
{
u32 val;
u32 offset:16;
u32 dramcf:16;
u32 offset:16;
} sdram_vendor_patch_t;
static const u8 dram_encoding_t210b01[] = {
@@ -67,21 +67,21 @@ static const u8 dram_encoding_t210b01[] = {
/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 20 */ LPDDR4X_4GB_SAMSUNG_1Z,
/* 21 */ LPDDR4X_4GB_SAMSUNG_1Z,
/* 22 */ LPDDR4X_4GB_SAMSUNG_1Z,
/* 20 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 21 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 22 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL,
/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL,
/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF,
/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL,
/* 29 */ LPDDR4X_4GB_HYNIX_1A,
/* 30 */ LPDDR4X_4GB_HYNIX_1A,
/* 31 */ LPDDR4X_4GB_HYNIX_1A,
/* 32 */ LPDDR4X_4GB_MICRON_1A,
/* 33 */ LPDDR4X_4GB_MICRON_1A,
/* 34 */ LPDDR4X_4GB_MICRON_1A,
/* 29 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 30 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 31 */ LPDDR4X_4GB_HYNIX_H54G46CYRBX267,
/* 32 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 33 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
/* 34 */ LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB,
};
#include "sdram_config.inl"
@@ -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 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.
for (u32 i = 0; i < 32; i++)
for (u32 i = 0; i < 16; i++)
{
(void)EMC(EMC_MRR);
usleep(1);
}
memset(&data, 0xFF, sizeof(emc_mr_data_t));
/*
* When a dram chip has only one rank, then the info from the 2 ranks differs.
* 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).
_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 (EMC(EMC_ADR_CFG) & 1)
if (dual_rank)
{
// Get Device 1 (Rank 1) info from both dram chips (channels).
_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);
}
else
{
data.rank1_ch0 = 0xFF;
data.rank1_ch1 = 0xFF;
// Ram module 0 info.
mrr = EMC_CH0(EMC_MRR);
data.chip0.rank1_ch0 = mrr & 0xFF;
data.chip0.rank1_ch1 = (mrr & 0xFF00 >> 8);
// Ram module 1 info.
if (dual_channel)
{
mrr = EMC_CH1(EMC_MRR);
data.chip1.rank1_ch0 = mrr & 0xFF;
data.chip1.rank1_ch1 = (mrr & 0xFF00 >> 8);
}
}
return data;
@@ -167,12 +188,12 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
{
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | (2 << 30u);
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
usleep(params->pmc_io_dpd4_req_wait);
@@ -209,7 +230,7 @@ break_nosleep:
if (params->emc_clock_source_dll)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
if (params->clear_clock2_mc1)
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_MC1); // Clear Reset to MC1.
// Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
@@ -233,7 +254,7 @@ break_nosleep:
// Program CMD mapping. Required before brick mapping, else
// we can't guarantee CK will be differential at all times.
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
@@ -246,7 +267,7 @@ break_nosleep:
EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
// Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
@@ -289,13 +310,13 @@ break_nosleep:
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
@@ -328,7 +349,7 @@ break_nosleep:
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_CFG_3) = params->emc_cfg3;
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
@@ -561,9 +582,11 @@ break_nosleep:
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
EMC(EMC_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@@ -616,7 +639,7 @@ break_nosleep:
}
// 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);
// 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;
// Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
@@ -717,7 +740,7 @@ break_nosleep:
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | BIT(1);
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
@@ -751,15 +774,15 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
// Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins.
PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000;
PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) | (2 << 30u);
usleep(params->pmc_io_dpd3_req_wait);
// 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);
// 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);
// 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_DBG) = params->emc_dbg;
EMC(EMC_QRST) = params->emc_qrst;
EMC(EMC_ISSUE_QRST) = 1;
EMC(EMC_ISSUE_QRST) = 0;
EMC(EMC_QSAFE) = params->emc_qsafe;
EMC(EMC_RDV) = params->emc_rdv;
EMC(EMC_RDV_MASK) = params->emc_rdv_mask;
@@ -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;
// 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);
// 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);
// Enable refresh.
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
EMC(EMC_REFCTRL) = params->emc_dev_select | BIT(31);
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
EMC(EMC_CFG) = params->emc_cfg;
@@ -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;
// 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.

View File

@@ -1,6 +1,6 @@
/*
* 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
* under the terms and conditions of the GNU General Public License,
@@ -23,81 +23,86 @@
/*
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
*
* Note: BWbits T210 = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
* BWbits T210B01 = Hz x ddr x bus width x channels = Hz x 2 x 64 x 2.
* Both assume that both sub-partitions are used and thus reaching max
* bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit).
* Retail Mariko use one sub-partition, in order to meet Erista perf.
*
* T210 T210B01
* 40.8 MHz: 0.61 1.22 GiB/s
* 68.0 MHz: 1.01 2.02 GiB/s
* 102.0 MHz: 1.52 3.04 GiB/s
* 204.0 MHz: 3.04 6.08 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
* 408.0 MHz: 6.08 12.16 GiB/s
* 665.6 MHz: 9.92 19.84 GiB/s
* 800.0 MHz: 11.92 23.84 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
* 1065.6 MHz: 15.89 31.78 GiB/s
* 1331.2 MHz: 19.84 39.68 GiB/s
* 1600.0 MHz: 23.84 47.68 GiB/s <-- Tegra X1/X1+ HOS Max Frequency
* 1862.4 MHz: 27.75 55.50 GiB/s <-- Tegra X1 Official Max Frequency
* 2131.2 MHz: 31.76 63.52 GiB/s <-- Tegra X1+ Official Max Frequency
* Note: Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2.
* Max BWbits = Hz x ddr x bus width x channels = Hz x 2 x 64 x 1.
* Configurations supported: 1x32, 2x32, 1x64.
* x64 ram modules can be used by combining the 2 32-bit channels into one.
*
* 204.0 MHz: 3.04 <-- Tegra X1/X1+ Init/SC7 Frequency
* 408.0 MHz: 6.08
* 665.6 MHz: 9.92
* 800.0 MHz: 11.92 <-- Tegra X1/X1+ Nvidia OS Boot Frequency
* 1065.6 MHz: 15.89
* 1331.2 MHz: 19.84
* 1600.0 MHz: 23.84
* 1862.4 MHz: 27.75 <-- Tegra X1 Official Max Frequency
* 2131.2 MHz: 31.76 <-- Tegra X1+ Official Max Frequency. Not all regs have support for > 2046 MHz.
*/
enum sdram_ids_erista
{
// LPDDR4 3200Mbps.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, // Die-B. (2y-01).
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, // Die-M. (2y-01).
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, // Die-C. (2y-01).
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
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
{
/*
* Nintendo Switch LPDRR4X generations:
* - 1x nm are 1st-gen
* - 1y nm are 2nd-gen
* - 1z/a nm are 3rd-gen
*/
// LPDDR4X 4266Mbps.
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01).
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Die-M. (1y-01).
LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Die-M. (1y-01).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Die-M. (1y-01).
// LPDDR4X 3733Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 8 banks. 3733Mbps.
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M.
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M.
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // 4266Mbps. Die-E.
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. (1x-03).
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. (1x-03).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11, // Die-E. (1x-03). D9WGB. 4266Mbps.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 8 banks. 3733Mbps.
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M.
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // 4266Mbps. Die-E.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. (1x-03).
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. (1x-03).
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15, // Die-E. (1x-03). D9WGB. 4266Mbps.
// LPDDR4X 4266Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_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_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_HOAG_4GB_SAMSUNG_1Z = 21, // 1z nm. 40% lower power usage. (1z-01).
LPDDR4X_AULA_4GB_SAMSUNG_1Z = 22, // 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_K4U6E3S4AB_MGCL = 21, // Die-B. (1z-01). 40% lp.
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_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_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // Die-F. (1y-01). D9XRR.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // Die-F. (1y-01). D9XRR.
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // Die-F. (1y-01). D9XRR.
LPDDR4X_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).
LPDDR4X_UNK1_4GB_HYNIX_1A = 30, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK2_4GB_HYNIX_1A = 31, // 1a nm. 61% lower power usage. (1a-01).
// Old naming scheme: H9HCNNNBKMCLXR-NEE
LPDDR4X_IOWA_4GB_HYNIX_H54G46CYRBX267 = 29, // Die-C. (1a-01). 61% lp.
LPDDR4X_HOAG_4GB_HYNIX_H54G46CYRBX267 = 30, // Die-C. (1a-01). 61% lp.
LPDDR4X_AULA_4GB_HYNIX_H54G46CYRBX267 = 31, // Die-C. (1a-01). 61% lp.
LPDDR4X_UNK0_4GB_MICRON_1A = 32, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK1_4GB_MICRON_1A = 33, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_UNK2_4GB_MICRON_1A = 34, // 1a nm. 61% lower power usage. (1a-01).
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33, // Die-B. (1a-01). D8BQM. 61% lp.
LPDDR4X_AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34, // Die-B. (1a-01). D8BQM. 61% lp.
};
enum sdram_codes_mariko
@@ -112,12 +117,11 @@ enum sdram_codes_mariko
LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15.
LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24.
LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28.
LPDDR4X_4GB_SAMSUNG_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_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06.
LPDDR4X_4GB_HYNIX_1A = 8, // DRAM IDs: 29, 30, 31.
LPDDR4X_4GB_MICRON_1A = 9, // DRAM IDs: 32, 33, 34.
LPDDR4X_4GB_HYNIX_H54G46CYRBX267 = 8, // DRAM IDs: 29, 30, 31.
LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB = 9, // DRAM IDs: 32, 33, 34.
};
void sdram_init();

View File

@@ -1,6 +1,6 @@
/*
* 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
* 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_cfg1 = 0x00010014,
.emc_pmc_scratch1 = 0x4FAFFFFF,
.emc_pmc_scratch1 = 0x4FAFFFFF, // APBDEV_PMC_IO_DPD3_REQ.
.emc_pmc_scratch2 = 0x7FFFFFFF,
.emc_pmc_scratch3 = 0x4006D70B,
.emc_pmc_scratch3 = 0x4006D70B, // APBDEV_PMC_DDR_CNTRL.
.emc_pmacro_pad_cfg_ctrl = 0x00020000,
.emc_pmacro_vttgen_ctrl0 = 0x00030808,
@@ -489,8 +489,8 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
/* DRAM size information */
.mc_emem_adr_cfg = 0x00000001, // 2 Ranks.
.mc_emem_adr_cfg_dev0 = 0x00070302, // Rank 0 Density 512MB.
.mc_emem_adr_cfg_dev1 = 0x00070302, // Rank 1 Density 512MB.
.mc_emem_adr_cfg_dev0 = 0x00070302, // Chip 0 Density 512MB.
.mc_emem_adr_cfg_dev1 = 0x00070302, // Chip 1 Density 512MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -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
* size (in KBytes)
*/
.mc_emem_cfg = 0x00001000, // 4GB total density.
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@@ -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_size_mb = 0x00000000,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
.mc_video_protect_vpr_override = 0xE4BAC343,
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR.
.mc_video_protect_vpr_override1 = 0x00001ED3,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343. New: 0xE4FACB43. + TSEC, NVENC.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x0000FED3, // Default: 0x00001ED3. New: 0x0000FED3. + TSECB, TSEC1, TSECB1.
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_video_protect_gpu_override0 = 0x00000000,
.mc_video_protect_gpu_override1 = 0x00000000,
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
.mc_video_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
};
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
// Hynix timing config.
{ 0x0000000D, 0x10C / 4, DRAM_ID(1) }, // emc_r2w.
{ 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra.
{ 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width.
{ 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode.
{ 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // mc_emem_arb_timing_r2w.
{ 0x0000000D, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_r2w) },
{ 0x00000001, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_extra) },
{ 0x80000000, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_puterm_width) },
{ 0x00000210, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(emc_pmacro_data_rx_term_mode) },
{ 0x00000005, DRAM_ID(LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE), DCFG_OFFSET_OF(mc_emem_arb_timing_r2w) },
// Samsung 6GB density config.
{ 0x000C0302, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density.
{ 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density.
{ 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 768MB Chip 0 density.
{ 0x000C0302, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 768MB Chip 1 density.
{ 0x00001800, DRAM_ID(LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH), DCFG_OFFSET_OF(mc_emem_cfg) }, // 6GB total density. Max 8GB.
#ifdef CONFIG_SDRAM_COPPER_SUPPORT
// Copper prototype Samsung/Hynix/Micron timing configs.
{ 0x0000003A, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh.
{ 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
{ 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w.
{ 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra.
{ 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width.
{ 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
{ 0x0000003B, 0x1C0 / 4, DRAM_ID(6) }, // emc_txsr.
{ 0x0000003B, 0x1C4 / 4, DRAM_ID(6) }, // emc_txsr_dll.
{ 0x00000003, 0x1DC / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable.
{ 0x00120015, 0x334 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4.
{ 0x00160012, 0x338 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5.
{ 0x00120015, 0x34C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4.
{ 0x00160012, 0x350 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5.
{ 0x002F0032, 0x354 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0.
{ 0x00310032, 0x358 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1.
{ 0x00360034, 0x35C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2.
{ 0x0033002F, 0x360 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3.
{ 0x00000006, 0x364 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4.
{ 0x002F0032, 0x36C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0.
{ 0x00310032, 0x370 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1.
{ 0x00360034, 0x374 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2.
{ 0x0033002F, 0x378 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3.
{ 0x00000006, 0x37C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4.
{ 0x00150015, 0x3A4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0.
{ 0x00120012, 0x3AC / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2.
{ 0x00160016, 0x3B0 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3.
{ 0x00000015, 0x3B4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
{ 0x00000012, 0x49C / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
{ 0x00000012, 0x4A0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
{ 0x00000210, 0x4F4 / 4, DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
{ 0x00000005, 0x5C0 / 4, DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
{ 0x00000007, 0x5C8 / 4, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
{ 0x72A30504, 0x5D4 / 4, DRAM_ID(6) }, // mc_emem_arb_misc0.
#endif
// Samsung 8GB density config.
{ 0x0000003A, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc) },
{ 0x0000001D, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_rfc_pb) },
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr) },
{ 0x0000003B, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(emc_txsr_dll) },
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev0) }, // 1024MB Chip 0 density.
{ 0x00080302, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_adr_cfg_dev1) }, // 1024MB Chip 1 density.
{ 0x00002000, DRAM_ID(LPDDR4_ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX), DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
};
#undef DCFG_OFFSET_OF

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2022 CTCaer
* Copyright (c) 2020-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -542,8 +542,8 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
/* DRAM size information */
.mc_emem_adr_cfg = 0x00000000, // 1 Rank.
.mc_emem_adr_cfg_dev0 = 0x00080302, // Rank 0 Density 1024MB.
.mc_emem_adr_cfg_dev1 = 0x00080302, // Rank 1 Density 1024MB.
.mc_emem_adr_cfg_dev0 = 0x00080302, // Chip 0 Density 1024MB.
.mc_emem_adr_cfg_dev1 = 0x00080302, // Chip 1 Density 1024MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@@ -552,7 +552,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
.mc_emem_cfg = 0x00001000, // 4GB total density.
.mc_emem_cfg = 0x00001000, // 4GB total density. Max 8GB.
/* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001,
@@ -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_size_mb = 0x00000000,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A.
.mc_video_protect_vpr_override = 0xE4BAC343,
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B.
.mc_video_protect_vpr_override1 = 0x06001ED3,
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. Plus TSEC, NVENC.
.mc_video_protect_vpr_override = 0xE4FACB43, // Default: 0xE4BAC343.
// SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B and TSECB, TSEC1, TSECB1.
.mc_video_protect_vpr_override1 = 0x0600FED3, // Default: 0x06001ED3.
.mc_video_protect_gpu_override0 = 0x00000000,
.mc_video_protect_gpu_override1 = 0x00000000,
.mc_video_protect_gpu_override0 = 0x2A800000, // Default: 0x00000000. Forced to 1 by HOS Secmon.
.mc_video_protect_gpu_override1 = 0x00000002, // Default: 0x00000000. Forced to 0 by HOS Secmon.
.mc_sec_carveout_bom = 0xFFF00000,
.mc_sec_carveout_adr_hi = 0x00000000,
.mc_sec_carveout_size_mb = 0x00000000,
.mc_video_protect_write_access = 0x00000000,
.mc_sec_carveout_protect_write_access = 0x00000000,
@@ -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_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_SAMSUNG_K4U6E3S4AA_MGCL) | \
DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_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_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_QUSE_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_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A))
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB))
#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \
DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \
DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z))
DRAM_CC(LPDDR4X_4GB_HYNIX_H54G46CYRBX267) | \
DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D1NP_046_WTB) | \
DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AB_MGCL))
#define DRAM_CC_LPDDR4X_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))
#define DCFG_OFFSET_OF(m) (OFFSET_OF(sdram_params_t210b01_t, m) / 4)
static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = {
// Samsung LPDDR4X 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, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1.
{ 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0.
{ 0x00100010, 0x400 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_1.
{ 0x00100010, 0x404 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_2.
{ 0x00100010, 0x408 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_3.
{ 0x00100010, 0x40C / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_0.
{ 0x00100010, 0x410 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_1.
{ 0x00100010, 0x414 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_2.
{ 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3.
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_0) },
{ 0x35353535, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_vref_dq_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_0) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_2) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank0_3) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_0) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_1) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_2) },
{ 0x00100010, DRAM_CC_LPDDR4X_PMACRO_IB, DCFG_OFFSET_OF(emc_pmacro_ib_ddll_long_dqs_rank1_3) },
/*! Shared patched between DRAM Codes. */
{ 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2.
{ 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0.
{ 0x2A800000, 0x6DC / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override0.
{ 0x00000002, 0x6E0 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override1.
//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are.
{ 0x05500000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_config2) },
{ 0xC9AFBCBC, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(emc_auto_cal_vref_sel0) },
{ 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14.
{ 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control.
// Moved to default config.
// { 0x2A800000, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override0) },
// { 0x00000002, DRAM_CC_LPDDR4X_PUPD_VPR, DCFG_OFFSET_OF(mc_video_protect_gpu_override1) },
{ 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse.
{ 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width.
{ 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput.
{ 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration.
{ 0x88161414, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x80000713, DRAM_CC_LPDDR4X_DSR, DCFG_OFFSET_OF(emc_dyn_self_ref_control) },
{ 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw.
{ 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw.
{ 0x00000006, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse) },
{ 0x00000005, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_quse_width) },
{ 0x00000003, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput) },
{ 0x0000000C, DRAM_CC_LPDDR4X_QUSE, DCFG_OFFSET_OF(emc_einput_duration) },
{ 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC.
{ 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1.
{ 0x00000008, DRAM_CC_LPDDR4X_FAW, DCFG_OFFSET_OF(emc_tfaw) },
{ 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.
{ 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw1.
{ 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw2.
{ 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw3.
{ 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw6.
{ 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw8.
{ 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw9.
{ 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw10.
{ 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw12.
{ 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw13.
{ 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw14.
{ 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw_extra.
{ 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_dev_select. Both devices.
{ 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_mrw_cmd.
{ 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_init_dev1.
{ 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd4.
{ 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd5.
{ 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_adr_cfg. 2 Ranks.
{ 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_cfg. 8GB total density.
{ 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_timing_r2r.
{ 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_da_turns.
// Moved to default config.
// { 0xE4FACB43, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override) }, // + TSEC, NVENC.
// { 0x0600FED3, DRAM_CC_LPDDR4X_VPR, DCFG_OFFSET_OF(mc_video_protect_vpr_override1) }, // + TSECB, TSEC1, TSECB1.
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_adr_cfg) }, // 2 Ranks.
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw1) },
{ 0x08020000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw2) },
{ 0x080D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw3) },
{ 0x08033131, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw6) },
{ 0x080B0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw8) },
{ 0x0C0E5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw9) },
{ 0x080C5D5D, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw10) },
{ 0x0C0D0808, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw12) },
{ 0x0C0D0000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw13) },
{ 0x08161414, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw14) },
{ 0x08010004, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_mrw_extra) },
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_dev_select) }, // Both devices.
{ 0x0051004F, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_mrw_cmd) },
{ 0x40000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_zcal_init_dev1) },
{ 0x00000000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd4) },
{ 0x00001000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(emc_pmacro_tx_pwrd5) },
{ 0x00000001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_adr_cfg) }, // 2 Ranks.
{ 0x00002000, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_cfg) }, // 8GB total density. Max 8GB.
{ 0x00000002, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_timing_r2r) },
{ 0x02020001, DRAM_CC_LPDDR4X_8GB, DCFG_OFFSET_OF(mc_emem_arb_da_turns) },
};
#undef DCFG_OFFSET_OF

View File

@@ -225,7 +225,6 @@ typedef struct _sdram_params_t210b01_t
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_trtm;
@@ -235,6 +234,7 @@ typedef struct _sdram_params_t210b01_t
u32 emc_tr2ref;
u32 emc_ccdmw;
/* Specifies the value for EMC_RD_RCD */
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* 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
* under the terms and conditions of the GNU General Public License,
@@ -18,156 +18,228 @@
#include <string.h>
#include <soc/bpmp.h>
#include <soc/ccplex.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <mem/mc_t210.h>
#include <mem/smmu.h>
#include <utils/aarch64_util.h>
#include <memory_map.h>
bool smmu_used = false;
u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;
/*! SMMU register defines */
#define SMMU_ASID(asid) (((asid) << 24u) | ((asid) << 16u) | ((asid) << 8u) | (asid))
#define SMMU_ENABLE BIT(31)
#define SMMU_TLB_ACTIVE_LINES(l) ((l) << 0u)
#define SMMU_TLB_RR_ARBITRATION BIT(28)
#define SMMU_TLB_HIT_UNDER_MISS BIT(29)
#define SMMU_TLB_STATS_ENABLE BIT(31)
#define SMUU_PTC_INDEX_MAP(m) ((m) << 0u)
#define SMUU_PTC_LINE_MASK(m) ((m) << 8u)
#define SMUU_PTC_REQ_LIMIT(l) ((l) << 24u)
#define SMUU_PTC_CACHE_ENABLE BIT(29)
#define SMUU_PTC_STATS_ENABLE BIT(31)
//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;
u8 smmu_payload[] __attribute__((aligned(16))) = {
0x41, 0x01, 0x00, 0x58, // 0x00: LDR X1, =0x70019010
/*! Page table defines */
#define SMMU_4MB_REGION 0
#define SMMU_PAGE_TABLE 1
#define SMMU_PDIR_COUNT 1024
#define SMMU_PTBL_COUNT 1024
#define SMMU_PAGE_SHIFT 12u
#define SMMU_PTN_SHIFT SMMU_PAGE_SHIFT
#define SMMU_PDN_SHIFT 22u
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> SMMU_PAGE_SHIFT)
#define SMMU_ADDR_TO_PTN(addr) ((addr) >> SMMU_PTN_SHIFT)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> SMMU_PDN_SHIFT)
#define SMMU_PTN_TO_ADDR(ptn) ((ptn) << SMMU_PTN_SHIFT)
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << SMMU_PDN_SHIFT)
#define SMMU_PTB(page, attr) (((attr) << 29u) | ((page) >> SMMU_PAGE_SHIFT))
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
static const u8 smmu_enable_payload[] = {
0xC1, 0x00, 0x00, 0x18, // 0x00: LDR W1, =0x70019010
0x20, 0x00, 0x80, 0xD2, // 0x04: MOV X0, #0x1
0x20, 0x00, 0x00, 0xB9, // 0x08: STR W0, [X1]
0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC IALLUIS
0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB ISH
0xFE, 0xFF, 0xFF, 0x17, // 0x14: B loop
0x00, 0x00, 0x80, 0xD2, // 0x18: MOV X0, #0x0
0x20, 0x00, 0x00, 0xB9, // 0x1C: STR W0, [X1]
0x80, 0x00, 0x00, 0x58, // 0x20: LDR X0, =0x4002B000
0x00, 0x00, 0x1F, 0xD6, // 0x28: BR X0
0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG
0x00, 0x00, 0x00, 0x00, // 0x2C:
0x00, 0x00, 0x00, 0x00, // 0x30: secmon address
0x00, 0x00, 0x00, 0x00 // 0x34:
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
};
void *page_alloc(u32 num)
void *smmu_page_zalloc(u32 num)
{
u8 *res = _pageheap;
_pageheap += SZ_PAGE * num;
memset(res, 0, SZ_PAGE * num);
return res;
void *page = smmu_heap;
memset(page, 0, SZ_PAGE * num);
smmu_heap += SZ_PAGE * num;
return page;
}
u32 *smmu_alloc_pdir()
static pde_t *_smmu_pdir_alloc()
{
u32 *pdir = (u32 *)page_alloc(1);
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn] = _PDE_VACANT(pdn);
pde_t *pdir = (pde_t *)smmu_page_zalloc(1);
// Initialize pdes with no permissions.
for (u32 pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn].huge.page = pdn;
return pdir;
}
void smmu_flush_regs()
static void _smmu_flush_regs()
{
(void)MC(MC_SMMU_PTB_DATA);
}
void smmu_flush_all()
{
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;
smmu_flush_regs();
_smmu_flush_regs();
}
void smmu_init(u32 secmon_base)
void smmu_init()
{
MC(MC_SMMU_PTB_ASID) = 0;
MC(MC_SMMU_PTB_DATA) = 0;
MC(MC_SMMU_TLB_CONFIG) = 0x30000030;
MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;
MC(MC_SMMU_TLB_CONFIG) = SMMU_TLB_HIT_UNDER_MISS | SMMU_TLB_RR_ARBITRATION | SMMU_TLB_ACTIVE_LINES(48);
MC(MC_SMMU_PTC_CONFIG) = SMUU_PTC_CACHE_ENABLE | SMUU_PTC_REQ_LIMIT(8) | SMUU_PTC_LINE_MASK(0xF) | SMUU_PTC_INDEX_MAP(0x3F);
MC(MC_SMMU_PTC_FLUSH) = 0;
MC(MC_SMMU_TLB_FLUSH) = 0;
// Set the secmon address
*(u32 *)(smmu_payload + 0x30) = secmon_base;
}
void smmu_enable()
{
if (smmu_used)
static bool enabled = false;
if (enabled)
return;
ccplex_boot_cpu0((u32)smmu_payload);
smmu_used = true;
msleep(150);
// Launch payload on CCPLEX in order to set SMMU enable bit.
ccplex_boot_cpu0((u32)smmu_enable_payload, false);
msleep(100);
ccplex_powergate_cpu0();
smmu_flush_all();
enabled = true;
}
bool smmu_is_used()
void smmu_reset_heap()
{
return smmu_used;
smmu_heap = (void *)SMMU_HEAP_ADDR;
}
void smmu_exit()
void *smmu_init_domain(u32 dev_base, u32 asid)
{
*(u32 *)(smmu_payload + 0x14) = _NOP();
}
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
{
u32 *pdir = smmu_alloc_pdir();
void *ptb = _smmu_pdir_alloc();
MC(MC_SMMU_PTB_ASID) = asid;
MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);
smmu_flush_regs();
MC(MC_SMMU_PTB_DATA) = SMMU_PTB((u32)ptb, SMMU_ATTR_ALL);
_smmu_flush_regs();
MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);
smmu_flush_regs();
// Use the same macro for both quad and single domains. Reserved bits are not set anyway.
MC(dev_base) = SMMU_ENABLE | SMMU_ASID(asid);
_smmu_flush_regs();
return pdir;
return ptb;
}
u32 *smmu_get_pte(u32 *pdir, u32 iova)
void smmu_deinit_domain(u32 dev_base, u32 asid)
{
u32 ptn = SMMU_ADDR_TO_PFN(iova);
u32 pdn = SMMU_ADDR_TO_PDN(iova);
u32 *ptbl;
MC(MC_SMMU_PTB_ASID) = asid;
MC(MC_SMMU_PTB_DATA) = 0;
MC(dev_base) = 0;
_smmu_flush_regs();
}
if (pdir[pdn] != _PDE_VACANT(pdn))
ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);
void smmu_domain_bypass(u32 dev_base, bool bypass)
{
if (bypass)
{
smmu_flush_all();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) &= ~SMMU_ENABLE;
}
else
{
ptbl = (u32 *)page_alloc(1);
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
MC(dev_base) |= SMMU_ENABLE;
smmu_flush_all();
}
_smmu_flush_regs();
}
static pte_t *_smmu_get_pte(pde_t *pdir, u32 iova)
{
u32 pdn = SMMU_ADDR_TO_PDN(iova);
pte_t *ptbl;
// Get 4MB page table or initialize one.
if (pdir[pdn].tbl.attr)
ptbl = (pte_t *)(SMMU_PTN_TO_ADDR(pdir[pdn].tbl.table));
else
{
// Allocate page table.
ptbl = (pte_t *)smmu_page_zalloc(1);
// Get address.
u32 addr = SMMU_PDN_TO_ADDR(pdn);
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)
ptbl[pn] = _PTE_VACANT(addr);
pdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);
// Initialize page table with no permissions.
for (u32 pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SZ_PAGE)
ptbl[pn].page = SMMU_ADDR_TO_PFN(addr);
// Set page table to the page directory.
pdir[pdn].tbl.table = SMMU_ADDR_TO_PTN((u32)ptbl);
pdir[pdn].tbl.next = SMMU_PAGE_TABLE;
pdir[pdn].tbl.attr = SMMU_ATTR_ALL;
smmu_flush_all();
}
return &ptbl[ptn % SMMU_PTBL_COUNT];
return &ptbl[SMMU_ADDR_TO_PTN(iova) % SMMU_PTBL_COUNT];
}
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr)
{
for (int i = 0; i < cnt; i++)
// Map pages to page table entries. VA/PA should be aligned to 4KB.
for (u32 i = 0; i < pages; i++)
{
u32 *pte = smmu_get_pte(pdir, addr);
*pte = SMMU_ADDR_TO_PFN(page) | attr;
addr += SZ_PAGE;
page += SZ_PAGE;
pte_t *pte = _smmu_get_pte((pde_t *)ptb, iova);
pte->page = SMMU_ADDR_TO_PFN(iopa);
pte->attr = attr;
iova += SZ_PAGE;
iopa += SZ_PAGE;
}
smmu_flush_all();
}
u32 *smmu_init_for_tsec()
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr)
{
return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);
}
pde_t *pdir = (pde_t *)ptb;
void smmu_deinit_for_tsec()
{
MC(MC_SMMU_PTB_ASID) = 1;
MC(MC_SMMU_PTB_DATA) = 0;
MC(MC_SMMU_TSEC_ASID) = 0;
smmu_flush_regs();
}
// Map 4MB regions to page directory entries. VA/PA should be aligned to 4MB.
for (u32 i = 0; i < regions; i++)
{
u32 pdn = SMMU_ADDR_TO_PDN(iova);
pdir[pdn].huge.page = SMMU_ADDR_TO_PDN(iopa);
pdir[pdn].huge.next = SMMU_4MB_REGION;
pdir[pdn].huge.attr = attr;
iova += SZ_4M;
iopa += SZ_4M;
}
smmu_flush_all();
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -14,70 +15,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <utils/types.h>
#define SMMU_HEAP_ADDR 0xA0000000
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_AVPC_ASID 0x23C
#define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define SMMU_PDE_NEXT_SHIFT 28
#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29
#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30
#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31
#define SMMU_PAGE_SHIFT 12
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
#define SMMU_PDIR_COUNT 1024
#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT)
#define SMMU_PTBL_COUNT 1024
#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT)
#define SMMU_PDIR_SHIFT 12
#define SMMU_PDE_SHIFT 12
#define SMMU_PTE_SHIFT 12
#define SMMU_PFN_MASK 0x000FFFFF
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)
#define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)
#define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)
#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
#define SMMU_NS BIT(0)
#define SMMU_WRITE BIT(1)
#define SMMU_READ BIT(2)
#define SMMU_ATTR_ALL (SMMU_READ | SMMU_WRITE | SMMU_NS)
void *page_alloc(u32 num);
u32 *smmu_alloc_pdir();
void smmu_flush_regs();
void smmu_flush_all();
void smmu_init(u32 secmon_base);
void smmu_enable();
bool smmu_is_used();
void smmu_exit();
u32 *smmu_init_domain4(u32 dev_base, u32 asid);
u32 *smmu_get_pte(u32 *pdir, u32 iova);
void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);
u32 *smmu_init_for_tsec();
void smmu_deinit_for_tsec();
typedef struct _pde_t {
union {
union {
struct {
u32 table:22;
u32 rsvd:6;
u32 next:1;
u32 attr:3;
} tbl;
struct {
u32 rsvd_:10;
u32 page:12;
u32 rsvd:6;
u32 next:1;
u32 attr:3;
} huge;
};
u32 pde;
};
} pde_t;
typedef struct _pte_t {
u32 page:22;
u32 rsvd:7;
u32 attr:3;
} pte_t;
static_assert(sizeof(pde_t) == sizeof(u32), "pde_t size is wrong!");
static_assert(sizeof(pte_t) == sizeof(u32), "pte_t size is wrong!");
void *smmu_page_zalloc(u32 num);
void smmu_flush_all();
void smmu_init();
void smmu_enable();
void smmu_reset_heap();
void *smmu_init_domain(u32 dev_base, u32 asid);
void smmu_deinit_domain(u32 dev_base, u32 asid);
void smmu_domain_bypass(u32 dev_base, bool bypass);
void smmu_map(void *ptb, u32 iova, u64 iopa, u32 pages, u32 attr);
void smmu_map_huge(void *ptb, u32 iova, u64 iopa, u32 regions, u32 attr);

View File

@@ -51,7 +51,9 @@
/* Stack theoretical max: 33MB */
#define IPL_STACK_TOP 0x83100000
#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 --- */
// Virtual disk / Chainloader buffers.

View File

@@ -279,3 +279,26 @@ int max17050_fix_configuration()
return 0;
}
void max17050_dump_regs(void *buf)
{
u16 *buff = (u16 *)buf;
// Unlock model table.
u16 unlock = 0x59;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
unlock = 0xC4;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
// Dump all battery fuel gauge registers.
for (u32 i = 0; i < 0x100; i++)
{
buff[i] = max17050_get_reg(i);
msleep(1);
}
// Lock model table.
unlock = 0;
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable1, (u8 *)&unlock, 2);
i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MODELEnable2, (u8 *)&unlock, 2);
}

View File

@@ -130,8 +130,9 @@ enum MAX17050_reg {
MAX17050_VFSOC = 0xFF,
};
int max17050_get_property(enum MAX17050_reg reg, int *value);
int max17050_fix_configuration();
u32 max17050_get_cached_batt_volt();
int max17050_get_property(enum MAX17050_reg reg, int *value);
int max17050_fix_configuration();
void max17050_dump_regs(void *buf);
u32 max17050_get_cached_batt_volt();
#endif /* __MAX17050_H_ */

View File

@@ -75,7 +75,7 @@ typedef struct _max77620_regulator_t
static const max77620_regulator_t _pmic_regulators[] = {
{ "sd0", 12500, 600000, 625000, 1400000, REGULATOR_SD, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, {{ MAX77620_REG_FPS_SD0, 1, 7, 1 }} },
{ "sd1", 12500, 600000, 1125000, 1250000, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd1", 12500, 600000, 1125000, 1237500, REGULATOR_SD, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, {{ MAX77620_REG_FPS_SD1, 0, 1, 5 }} },
{ "sd2", 12500, 600000, 1325000, 1350000, REGULATOR_SD, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD2, 1, 5, 2 }} },
{ "sd3", 12500, 600000, 1800000, 1800000, REGULATOR_SD, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, {{ MAX77620_REG_FPS_SD3, 0, 3, 3 }} },
{ "ldo0", 25000, 800000, 1200000, 1200000, REGULATOR_LDO, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO0, 3, 7, 0 }} },
@@ -103,7 +103,7 @@ static u8 _max77812_get_address()
return max77812_i2c_addr;
max77812_i2c_addr =
!(FUSE(FUSE_RESERVED_ODM28_T210B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
!(FUSE(FUSE_RESERVED_ODM28_B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
return max77812_i2c_addr;
}
@@ -123,7 +123,7 @@ static u8 _max7762x_get_i2c_address(u32 id)
case REGULATOR_BC1:
{
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;
return reg_addr;
}

View File

@@ -47,6 +47,27 @@
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
*/
// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
/*
* OTP: T210 - T210B01:
* SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
* SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
* SD2: 1.35V 1.35V
* SD3: 1.8V 1.8V
* All powered off?
* LDO0: -- -- - Display
* LDO1: 1.05V 1.05V
* LDO2: -- -- - SD
* LDO3: 3.1V 3.1V - GC ASIC
* LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
* LDO5: 3.1V 3.1V
* LDO6: 2.8V 2.9V - Touch.
* LDO7: 1.05V 1.0V
* LDO8: 1.05V 1.0V
*/
/*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable
@@ -69,9 +90,9 @@
#define REGULATOR_CPU0 13 // T210 CPU.
#define REGULATOR_GPU0 14 // T210 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_MAX REGULATOR_RAM1
#define REGULATOR_MAX REGULATOR_RAM0
#define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C

View File

@@ -75,14 +75,14 @@
#define MAX77812_REG_GLB_CFG3 0x35
/*! Protected area and settings only for MAX77812_ES2_VERSION */
#define MAX77812_REG_GLB_CFG4 0x36
#define MAX77812_REG_GLB_CFG5 0x37 // HOS: 0x3E. Unmasked write.
#define MAX77812_REG_GLB_CFG6 0x38 // HOS: 0x90. Unmasked write.
#define MAX77812_REG_GLB_CFG7 0x39
#define MAX77812_REG_GLB_CFG8 0x3A // HOS: 0x3A. Unmasked write.
#define MAX77812_REG_GLB_CFG4 0x36 // QS: 0xBB.
#define MAX77812_REG_GLB_CFG5 0x37 // QS: 0x39. ES2: Set to 0x3E.
#define MAX77812_REG_GLB_CFG6 0x38 // QS: 0x88. ES2: Set to 0x90.
#define MAX77812_REG_GLB_CFG7 0x39 // QS: 0x04.
#define MAX77812_REG_GLB_CFG8 0x3A // QS: 0x3A. ES2: Set to 0x3A.
#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock.
#define MAX77812_REG_MAX 0xFD
#define MAX77812_REG_UNKNOWN 0xFE
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
#define MAX77812_START_SLEW_RATE_MASK 0x07

View File

@@ -23,6 +23,8 @@
#include <soc/timer.h>
#include <soc/t210.h>
int epoch_offset = 0;
void max77620_rtc_prep_read()
{
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
@@ -154,6 +156,21 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
return epoch;
}
void max77620_rtc_get_time_adjusted(rtc_time_t *time)
{
max77620_rtc_get_time(time);
if (epoch_offset)
{
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
max77620_rtc_epoch_to_date(epoch, time);
}
}
void max77620_rtc_set_epoch_offset(int offset)
{
epoch_offset = offset;
}
void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr)
{
max77620_rtc_stop_alarm();

View File

@@ -109,6 +109,8 @@ typedef struct _rtc_reboot_reason_t
void max77620_rtc_prep_read();
void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_get_time_adjusted(rtc_time_t *time);
void max77620_rtc_set_epoch_offset(int offset);
void max77620_rtc_stop_alarm();
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -182,7 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
if (!src || !dst)
return 0;
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE);
u8 *block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
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)
{
@@ -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);
}
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
@@ -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;
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;
// 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;
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;
}
@@ -459,59 +487,21 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo
return 1;
}
// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
{
int res = 0;
u8 *key = (u8 *)calloc(0x10, 1);
u8 *last_block = (u8 *)calloc(0x10, 1);
u32 hash32[SE_SHA_256_SIZE / 4];
// generate derived key
if (!se_aes_crypt_block_ecb(ks, 1, key, key))
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)
// Backup message left.
if (msg_left)
{
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);
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
if (src_size & 0xf)
{
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
last_block[src_size & 0xf] = 0x80;
}
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;
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
@@ -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.
return 0;
// Src size of 0 is not supported, so return null string sha256.
// if (!src_size)
// {
// const u8 null_hash[SE_SHA_256_SIZE] = {
// 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
// 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
// };
// memcpy(hash, null_hash, SE_SHA_256_SIZE);
// return 1;
// }
// Setup config for SHA256.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG) = sha_cfg;
@@ -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);
if (is_oneshot)
{
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@@ -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)
{
u32 hash32[SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize();
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG);
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
memcpy(hash, hash32, SE_SHA_256_SIZE);
se_calc_sha256_get_hash(hash, msg_left);
return res;
}
@@ -716,6 +694,65 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Decrypt context.
se_aes_key_clear(3);
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);
}
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
{
int res = 0;
u8 *key = (u8 *)zalloc(SE_KEY_128_SIZE);
u8 *last_block = (u8 *)zalloc(SE_AES_BLOCK_SIZE);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
// Generate sub key
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
goto out;
_gf256_mul_x(key);
if (src_size & 0xF)
_gf256_mul_x(key);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4;
if (num_blocks > 1)
{
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
goto out;
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
}
if (src_size & 0xf)
{
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
last_block[src_size & 0xf] = 0x80;
}
else if (src_size >= SE_AES_BLOCK_SIZE)
{
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
}
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
last_block[i] ^= key[i];
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
out:;
free(key);
free(last_block);
return res;
}

View File

@@ -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_clear(u32 ks);
void se_aes_iv_clear(u32 ks);
void se_aes_iv_updated_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
@@ -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(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_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_oneshot(void *hash, const void *src, u32 src_size);
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_gen_prng128(void *dst);
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
#endif

View File

@@ -50,6 +50,9 @@
#define SE_RSA1536_DIGEST_SIZE 192
#define SE_RSA2048_DIGEST_SIZE 256
#define DECRYPT 0
#define ENCRYPT 1
/* SE register definitions */
#define SE_SE_SECURITY_REG 0x000
#define SE_HARD_SETTING BIT(0)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -70,8 +70,9 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
int res = 0;
u8 *fwbuf = NULL;
u32 type = tsec_ctxt->type;
u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec;
u32 *pkg11_magic_off;
void *ptb;
bpmp_mmu_disable();
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
@@ -145,64 +146,64 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (type == TSEC_FW_TYPE_EMU)
{
// Init SMMU translation for TSEC.
pdir = smmu_init_for_tsec();
smmu_init(tsec_ctxt->secmon_base);
// Enable SMMU
if (!smmu_is_used())
smmu_enable();
ptb = smmu_init_domain(MC_SMMU_TSEC_ASID, 1);
smmu_init();
// Enable SMMU.
smmu_enable();
// Clock reset controller.
car = page_alloc(1);
car = smmu_page_zalloc(1);
memcpy(car, (void *)CLOCK_BASE, SZ_PAGE);
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2;
smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE);
car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = CLK_SRC_DIV(2);
smmu_map(ptb, CLOCK_BASE, (u32)car, 1, SMMU_WRITE | SMMU_READ | SMMU_NS);
// Fuse driver.
fuse = page_alloc(1);
fuse = smmu_page_zalloc(1);
memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K);
fuse[0x82C / 4] = 0;
fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1;
smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE);
smmu_map(ptb, (FUSE_BASE - 0x800), (u32)fuse, 1, SMMU_READ | SMMU_NS);
// Power management controller.
pmc = page_alloc(1);
smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE);
pmc = smmu_page_zalloc(1);
smmu_map(ptb, RTC_BASE, (u32)pmc, 1, SMMU_READ | SMMU_NS);
// Flow control.
flowctrl = page_alloc(1);
smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE);
flowctrl = smmu_page_zalloc(1);
smmu_map(ptb, FLOW_CTLR_BASE, (u32)flowctrl, 1, SMMU_WRITE | SMMU_NS);
// Security engine.
se = page_alloc(1);
se = smmu_page_zalloc(1);
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.
mc = page_alloc(1);
mc = smmu_page_zalloc(1);
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
mc[MC_IRAM_BOM / 4] = 0;
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 = page_alloc(0x30);
iram = smmu_page_zalloc(0x30);
memcpy(iram, tsec_ctxt->pkg1, 0x30000);
// PKG1.1 magic offset.
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4));
smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE);
pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / sizeof(u32)));
smmu_map(ptb, 0x40010000, (u32)iram, 0x30, SMMU_READ | SMMU_WRITE | SMMU_NS);
// Exception vectors
evec = page_alloc(1);
smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE);
evec = smmu_page_zalloc(1);
smmu_map(ptb, EXCP_VEC_BASE, (u32)evec, 1, SMMU_READ | SMMU_WRITE | SMMU_NS);
}
// Execute firmware.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
TSEC(TSEC_STATUS) = 0;
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
TSEC(TSEC_BOOTVEC) = 0;
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
TSEC(TSEC_MAILBOX1) = 0;
TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
TSEC(TSEC_BOOTVEC) = 0;
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
if (type == TSEC_FW_TYPE_EMU)
{
@@ -229,7 +230,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
if (kidx != 8)
{
res = -6;
smmu_deinit_for_tsec();
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
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_ctxt->pkg1, iram, 0x30000);
smmu_deinit_for_tsec();
smmu_deinit_domain(MC_SMMU_TSEC_ASID, 1);
// for (int i = 0; i < kidx; i++)
// gfx_printf("key %08X\n", key[i]);
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
// u32 errst = MC(MC_ERR_STATUS);
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
@@ -261,14 +262,18 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
res = -3;
goto out_free;
}
u32 timeout = get_tmr_ms() + 2000;
while (!TSEC(TSEC_STATUS))
while (!TSEC(TSEC_MAILBOX1))
{
if (get_tmr_ms() > timeout)
{
res = -4;
goto out_free;
}
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
}
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
{
res = -5;
goto out_free;
@@ -277,14 +282,14 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
// Fetch result.
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
u32 buf[4];
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -35,7 +35,6 @@ typedef struct _tsec_ctxt_t
u32 type;
void *pkg1;
u32 pkg11_off;
u32 secmon_base;
} tsec_ctxt_t;
int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2023 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -17,8 +17,8 @@
#ifndef _TSEC_T210_H_
#define _TSEC_T210_H_
#define TSEC_BOOTKEYVER 0x1040
#define TSEC_STATUS 0x1044
#define TSEC_MAILBOX0 0x1040
#define TSEC_MAILBOX1 0x1044
#define TSEC_ITFEN 0x1048
#define TSEC_ITFEN_CTXEN BIT(0)
#define TSEC_ITFEN_MTHDEN BIT(1)

View File

@@ -76,7 +76,9 @@
#define ACTMON_HISTOGRAM_DATA_BASE 0x380
#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
{
@@ -91,11 +93,9 @@ typedef struct _actmon_dev_reg_t
vu32 avg_count;
vu32 intr_status;
vu32 ctrl2;
vu32 unk[5];
vu32 rsvd[5];
} actmon_dev_reg_t;
u32 sample_period = 0;
void actmon_hist_enable(actmon_hist_src_t src)
{
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));
regs->init_avg = 0;
regs->count_weight = 5;
regs->init_avg = ACTMON_FREQ * ACTMON_PERIOD_MS * DEV_COUNT_WEIGHT / 100;
regs->count_weight = DEV_COUNT_WEIGHT;
regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC;
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)
@@ -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));
// 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;
}
@@ -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));
// 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;
}
@@ -162,9 +162,8 @@ void actmon_init()
{
clock_enable_actmon();
// Set period to 200ms.
ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC;
ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200);
// Set period.
ACTMON(ACTMON_GLB_PERIOD_CTRL) = ACTMON_GLB_PERIOD_SAMPLE(ACTMON_PERIOD_MS);
}
void actmon_end()

View File

@@ -287,10 +287,10 @@ void bpmp_usleep(u32 us)
// Each iteration takes 1us.
while (us)
{
delay = (us > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : us;
delay = (us > HALT_MAX_CNT) ? HALT_MAX_CNT : us;
us -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_USEC | delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_USEC | delay;
}
}
@@ -301,14 +301,14 @@ void bpmp_msleep(u32 ms)
// Iteration time is variable. ~200 - 1000us.
while (ms)
{
delay = (ms > HALT_COP_MAX_CNT) ? HALT_COP_MAX_CNT : ms;
delay = (ms > HALT_MAX_CNT) ? HALT_MAX_CNT : ms;
ms -= delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_MSEC | delay;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_MSEC | delay;
}
}
void bpmp_halt()
{
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_WAIT_EVENT | HALT_COP_JTAG;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_WAITEVENT | HALT_JTAG;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -27,7 +27,9 @@
#include <power/max77812.h>
#include <utils/util.h>
void _ccplex_enable_power_t210()
#define CCPLEX_FLOWCTRL_POWERGATING 0
static void _ccplex_enable_power_t210()
{
// Configure GPIO5 and enable output in order to power CPU pmic.
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_ENABLE);
@@ -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.
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_HOS_CFG);
// Set voltage and enable cores power.
// Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU0, 950000);
max7762x_regulator_enable(REGULATOR_CPU0, true);
}
void _ccplex_enable_power_t210b01()
static void _ccplex_enable_power_t210b01()
{
// Set voltage and enable cores power.
// Set voltage and enable cluster power.
max7762x_regulator_set_voltage(REGULATOR_CPU1, 800000);
max7762x_regulator_enable(REGULATOR_CPU1, true);
}
void ccplex_boot_cpu0(u32 entry)
static void _ccplex_disable_power()
{
// Disable cluster power.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
{
max7762x_regulator_enable(REGULATOR_CPU0, false);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 0);
}
else
max7762x_regulator_enable(REGULATOR_CPU1, false);
}
void ccplex_boot_cpu0(u32 entry, bool lock)
{
// Set ACTIVE_CLUSER to FAST.
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW;
@@ -62,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
clock_enable_pllx();
// Configure MSELECT source and enable clock to 102MHz.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (0 << 29) | CLK_SRC_DIV(4);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT);
// Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ.
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = BIT(31); // SUPER_CDIV_ENB.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
clock_enable_coresight();
@@ -90,12 +104,15 @@ void ccplex_boot_cpu0(u32 entry)
EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;
// Set reset vector.
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN;
SB(SB_AA64_RESET_HIGH) = 0;
// Non-secure reset vector write disable.
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
(void)SB(SB_CSR);
if (lock)
{
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
(void)SB(SB_CSR);
}
// Tighten up the security aperture.
// MC(MC_TZ_SECURITY_CTRL) = 1;
@@ -103,8 +120,46 @@ void ccplex_boot_cpu0(u32 entry)
// Clear MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
// Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(29); // CLR_NONCPURESET.
// Clear CPU0 reset.
// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
}
void ccplex_powergate_cpu0()
{
#if CCPLEX_FLOWCTRL_POWERGATING
// Halt CPU0.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
// Powergate cluster via flow control without waiting for WFI.
FLOW_CTLR(FLOW_CTLR_CPU0_CSR) = CSR_INTR_FLAG | CSR_EVENT_FLAG | CSR_ENABLE_EXT_CPU_RAIL | CSR_WAIT_WFI_NONE | CSR_ENABLE;
// Wait for the rail power off to finish.
while((FLOW_CTLR(FLOW_CTLR_CPU_PWR_CSR) & CPU_PWR_RAIL_STS_MASK) != CPU_PWR_RAIL_OFF);
// Set CPU0 to waitevent.
FLOW_CTLR(FLOW_CTLR_HALT_CPU0_EVENTS) = HALT_MODE_WAITEVENT;
#endif
// Set CPU0 POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(30) | BIT(24) | BIT(16) | BIT(0);
// Set NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET) = BIT(29);
// Set MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
// Disable CE0.
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
// Disable cluster 0 non-CPU.
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
// Disable CPU rail.
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
clock_disable_coresight();
// Clear out MSELECT and CPU clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_CLR) = BIT(CLK_V_MSELECT) | BIT(CLK_V_CPUG);
_ccplex_disable_power();
}

View File

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

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2023 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -42,82 +42,82 @@ static const clock_osc_t _clock_osc_cnt[] = {
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
static const clk_rst_t _clock_uart[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
};
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
static const clk_rst_t _clock_i2c[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, //20.4MHz -> 100KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, //81.6MHz -> 400KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } //20.4MHz -> 100KHz
};
static 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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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 = {
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)
@@ -128,7 +128,7 @@ void clock_enable(const clk_rst_t *clk)
CLOCK(clk->enable) &= ~BIT(clk->index);
// Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
// Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
usleep(2);
@@ -168,12 +168,12 @@ int clock_uart_use_src_div(u32 idx, u32 baud)
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
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)
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
{
CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
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.
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.
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:
*pclock = 24728;
divisor = 31; // 16.5 div.
divisor = CLK_SRC_DIV(16.5);
break;
case 26000:
*pclock = 25500;
divisor = 30; // 16 div.
divisor = CLK_SRC_DIV(16);
break;
case 50000:
*pclock = 48000;
divisor = 15; // 8.5 div.
divisor = CLK_SRC_DIV(8.5);
break;
case 52000:
*pclock = 51000;
divisor = 14; // 8 div.
divisor = CLK_SRC_DIV(8);
break;
case 82000:
*pclock = 81600;
divisor = 8; // 5 div.
divisor = CLK_SRC_DIV(5);
break;
case 100000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
*pclock = 99840;
divisor = 2; // 2 div.
divisor = CLK_SRC_DIV(2);
break;
case 164000:
*pclock = 163200;
divisor = 3; // 2.5 div.
divisor = CLK_SRC_DIV(2.5);
break;
case 200000:
@@ -762,14 +762,14 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
break;
}
*pclock = 199680;
divisor = 0; // 1 div.
divisor = CLK_SRC_DIV(1);
break;
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
case 400000:
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
*pclock = 399360;
divisor = 3; // 2.5 div
divisor = CLK_SRC_DIV(2.5);
break;
#endif
}
@@ -785,7 +785,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
_clock_sdmmc_config_legacy_tm();
// Set SDMMC clock.
u32 src_div = (source << 29) | divisor;
u32 src_div = (source << 29u) | divisor;
switch (id)
{
case SDMMC_1:

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -198,6 +198,9 @@
#define UTMIPLL_LOCK BIT(31)
/*! Clock source */
#define CLK_SRC_DIV(d) ((d) ? ((u32)(((d) - 1) * 2)) : 0)
/*! PTO_CLK_CNT */
#define PTO_REF_CLK_WIN_CFG_MASK 0xF
#define PTO_REF_CLK_WIN_CFG_16P 0xF
@@ -227,138 +230,232 @@
/*! PTO IDs. */
typedef enum _clock_pto_id_t
{
CLK_PTO_PCLK_SYS = 0x06,
CLK_PTO_HCLK_SYS = 0x07,
CLK_PTO_PCLK_SYS = 0x06,
CLK_PTO_HCLK_SYS = 0x07,
CLK_PTO_DMIC1 = 0x08,
CLK_PTO_DMIC2 = 0x09,
CLK_PTO_HDMI_SLOWCLK_DIV2 = 0x0A,
CLK_PTO_JTAG_REG = 0x0B,
CLK_PTO_UTMIP_240_A = 0x0C,
CLK_PTO_UTMIP_240_B = 0x0D,
CLK_PTO_UTMIP_240 = 0x0C,
CLK_PTO_CCLK_G = 0x12,
CLK_PTO_CCLK_G_DIV2 = 0x13,
CLK_PTO_MIPIBIF = 0x14,
CLK_PTO_CCLK_G = 0x12,
CLK_PTO_CCLK_G_DIV2 = 0x13,
CLK_PTO_SPI1 = 0x17,
CLK_PTO_SPI2 = 0x18,
CLK_PTO_SPI3 = 0x19,
CLK_PTO_SPI4 = 0x1A,
CLK_PTO_MAUD = 0x1B,
CLK_PTO_SCLK = 0x1C,
CLK_PTO_SPI1 = 0x17,
CLK_PTO_SPI2 = 0x18,
CLK_PTO_SPI3 = 0x19,
CLK_PTO_SPI4 = 0x1A,
CLK_PTO_MAUD = 0x1B,
CLK_PTO_SCLK = 0x1C,
CLK_PTO_SDMMC1 = 0x20,
CLK_PTO_SDMMC2 = 0x21,
CLK_PTO_SDMMC3 = 0x22,
CLK_PTO_SDMMC4 = 0x23,
CLK_PTO_EMC = 0x24,
CLK_PTO_SDMMC1 = 0x20,
CLK_PTO_SDMMC2 = 0x21,
CLK_PTO_SDMMC3 = 0x22,
CLK_PTO_SDMMC4 = 0x23,
CLK_PTO_EMC = 0x24,
CLK_PTO_DMIC3 = 0x2A,
CLK_PTO_CCLK_LP = 0x2B,
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
CLK_PTO_CCLK_LP = 0x2B,
CLK_PTO_CCLK_LP_DIV2 = 0x2C,
CLK_PTO_MSELECT = 0x2F,
CLK_PTO_MSELECT = 0x2F,
CLK_PTO_VI_SENSOR2 = 0x33,
CLK_PTO_VI_SENSOR = 0x34,
CLK_PTO_VIC = 0x35,
CLK_PTO_VIC_SKIP = 0x36,
CLK_PTO_ISP_SKIP = 0x37,
CLK_PTO_ISPB_SE2_SKIP = 0x38,
CLK_PTO_NVDEC_SKIP = 0x39,
CLK_PTO_NVENC_SKIP = 0x3A,
CLK_PTO_NVJPG_SKIP = 0x3B,
CLK_PTO_TSEC_SKIP = 0x3C,
CLK_PTO_TSECB_SKIP = 0x3D,
CLK_PTO_SE_SKIP = 0x3E,
CLK_PTO_VI_SKIP = 0x3F,
CLK_PTO_VIC = 0x36,
CLK_PTO_PLLX_OBS = 0x40,
CLK_PTO_PLLC_OBS = 0x41,
CLK_PTO_PLLM_OBS = 0x42,
CLK_PTO_PLLP_OBS = 0x43,
CLK_PTO_PLLA_OBS = 0x44,
CLK_PTO_PLLMB_OBS = 0x45,
CLK_PTO_SATA_OOB = 0x46,
CLK_PTO_NVDEC = 0x39,
CLK_PTO_FCPU_DVFS_DIV12_CPU = 0x48,
CLK_PTO_NVENC = 0x3A,
CLK_PTO_NVJPG = 0x3B,
CLK_PTO_TSEC = 0x3C,
CLK_PTO_TSECB = 0x3D,
CLK_PTO_SE = 0x3E,
CLK_PTO_EQOS_AXI = 0x4C,
CLK_PTO_EQOS_PTP_REF = 0x4D,
CLK_PTO_EQOS_TX = 0x4E,
CLK_PTO_EQOS_RX = 0x4F,
CLK_PTO_DSIA_LP = 0x62,
CLK_PTO_CILAB = 0x52,
CLK_PTO_CILCD = 0x53,
CLK_PTO_ISP = 0x64,
CLK_PTO_MC = 0x6A,
CLK_PTO_CILEF = 0x55,
CLK_PTO_PLLA1_PTO_OBS = 0x56,
CLK_PTO_PLLC4_PTO_OBS = 0x57,
CLK_PTO_ACTMON = 0x6B,
CLK_PTO_CSITE = 0x6C,
CLK_PTO_PLLC2_PTO_OBS = 0x59,
CLK_PTO_PLLC3_PTO_OBS = 0x5B,
CLK_PTO_HOST1X = 0x6F,
CLK_PTO_DSIA_LP = 0x62,
CLK_PTO_DSIB_LP = 0x63,
CLK_PTO_ISP = 0x64,
CLK_PTO_PEX_PAD = 0x65,
CLK_PTO_SE_2 = 0x74, // Same as CLK_PTO_SE.
CLK_PTO_SOC_THERM = 0x75,
CLK_PTO_MC = 0x6A,
CLK_PTO_TSEC_2 = 0x77, // Same as CLK_PTO_TSEC.
CLK_PTO_ACTMON = 0x6B,
CLK_PTO_CSITE = 0x6C,
CLK_PTO_VI_I2C = 0x6D,
CLK_PTO_ACLK = 0x7C,
CLK_PTO_QSPI = 0x7D,
CLK_PTO_HOST1X = 0x6F,
CLK_PTO_I2S1 = 0x80,
CLK_PTO_I2S2 = 0x81,
CLK_PTO_I2S3 = 0x82,
CLK_PTO_I2S4 = 0x83,
CLK_PTO_I2S5 = 0x84,
CLK_PTO_AHUB = 0x85,
CLK_PTO_APE = 0x86,
CLK_PTO_QSPI_2X = 0x71,
CLK_PTO_NVDEC = 0x72,
CLK_PTO_NVJPG = 0x73,
CLK_PTO_SE = 0x74,
CLK_PTO_SOC_THERM = 0x75,
CLK_PTO_DVFS_SOC = 0x88,
CLK_PTO_DVFS_REF = 0x89,
CLK_PTO_TSEC = 0x77,
CLK_PTO_TSECB = 0x78,
CLK_PTO_VI = 0x79,
CLK_PTO_LA = 0x7A,
CLK_PTO_SCLK_SKIP = 0x7B,
CLK_PTO_SPDIF = 0x8F,
CLK_PTO_SPDIF_IN = 0x90,
CLK_PTO_ADSP_SKIP = 0x7C,
CLK_PTO_QSPI = 0x7D,
CLK_PTO_SDMMC2_SHAPER = 0x7E,
CLK_PTO_SDMMC4_SHAPER = 0x7F,
CLK_PTO_I2S1 = 0x80,
CLK_PTO_I2S2 = 0x81,
CLK_PTO_I2S3 = 0x82,
CLK_PTO_I2S4 = 0x83,
CLK_PTO_I2S5 = 0x84,
CLK_PTO_AHUB = 0x85,
CLK_PTO_APE = 0x86,
CLK_PTO_DVFS_SOC = 0x88,
CLK_PTO_DVFS_REF = 0x89,
CLK_PTO_ADSP_CLK = 0x8A,
CLK_PTO_ADSP_DIV2_CLK = 0x8B,
CLK_PTO_SPDIF_OUT = 0x8F,
CLK_PTO_SPDIF_IN = 0x90,
CLK_PTO_UART_FST_MIPI_CAL = 0x91,
CLK_PTO_SYS2HSIO_SATA_CLK = 0x92,
CLK_PTO_PWM = 0x93,
CLK_PTO_I2C1 = 0x94,
CLK_PTO_I2C2 = 0x95,
CLK_PTO_I2C3 = 0x96,
CLK_PTO_I2C4 = 0x97,
CLK_PTO_I2C5 = 0x98,
CLK_PTO_I2C6 = 0x99,
CLK_PTO_I2C_SLOW = 0x9A,
CLK_PTO_UARTAPE = 0x9B,
CLK_PTO_PWM = 0x93,
CLK_PTO_I2C1 = 0x94,
CLK_PTO_I2C2 = 0x95,
CLK_PTO_I2C3 = 0x96,
CLK_PTO_I2C4 = 0x97,
CLK_PTO_I2C5 = 0x98,
CLK_PTO_I2C6 = 0x99,
CLK_PTO_I2C_SLOW = 0x9A,
CLK_PTO_UARTAPE = 0x9B,
CLK_PTO_EXTPERIPH1 = 0x9D,
CLK_PTO_EXTPERIPH2 = 0x9E,
CLK_PTO_EXTPERIPH3 = 0x9F,
CLK_PTO_ENTROPY = 0xA0,
CLK_PTO_UARTA = 0xA1,
CLK_PTO_UARTB = 0xA2,
CLK_PTO_UARTC = 0xA3,
CLK_PTO_UARTD = 0xA4,
CLK_PTO_OWR = 0xA5,
CLK_PTO_TSENSOR = 0xA6,
CLK_PTO_HDA2CODEC_2X = 0xA7,
CLK_PTO_HDA = 0xA8,
CLK_PTO_EMC_LATENCY = 0xA9,
CLK_PTO_EMC_DLL = 0xAA,
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
CLK_PTO_DBGAPB = 0xAC,
CLK_PTO_EXTPERIPH1 = 0x9D,
CLK_PTO_EXTPERIPH2 = 0x9E,
CLK_PTO_SOR0 = 0xC0,
CLK_PTO_SOR1 = 0xC1,
CLK_PTO_HDMI = 0xC2,
CLK_PTO_ENTROPY = 0xA0,
CLK_PTO_UARTA = 0xA1,
CLK_PTO_UARTB = 0xA2,
CLK_PTO_UARTC = 0xA3,
CLK_PTO_UARTD = 0xA4,
CLK_PTO_OWR = 0xA5,
CLK_PTO_DISP2 = 0xC4,
CLK_PTO_DISP1 = 0xC5,
CLK_PTO_HDA2CODEC_2X = 0xA7,
CLK_PTO_HDA = 0xA8,
CLK_PTO_PLLD_OBS = 0xCA,
CLK_PTO_PLLD2_PTO_OBS = 0xCC,
CLK_PTO_PLLDP_OBS = 0xCE,
CLK_PTO_PLLE_OBS = 0x10A,
CLK_PTO_PLLU_OBS = 0x10C,
CLK_PTO_PLLREFE_OBS = 0x10E,
CLK_PTO_SDMMC_LEGACY_TM = 0xAB,
CLK_PTO_XUSB_FALCON = 0x110,
CLK_PTO_XUSB_CLK480M_HSIC = 0x111,
CLK_PTO_USB_L0_RX = 0x112,
CLK_PTO_USB_L3_RX = 0x113,
CLK_PTO_USB_RX = 0x114,
CLK_PTO_USB3_L0_TXCLKREF = 0x115,
CLK_PTO_PEX_TXCLKREF_SWITCH_TMS = 0x116,
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP0 = 0x117,
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP1 = 0x118,
CLK_PTO_PEX_TXCLKREF_SWITCH_GRP2 = 0x119,
CLK_PTO_PEX_L4_RX = 0x11A,
CLK_PTO_PEX_TXCLKREF = 0x11B,
CLK_PTO_PEX_TXCLKREF_DIV2 = 0x11C,
CLK_PTO_PEX_TXCLKREF2 = 0x11D,
CLK_PTO_PEX_L0_RX = 0x11E,
CLK_PTO_PEX_L1_RX = 0x11F,
CLK_PTO_PEX_L2_RX = 0x120,
CLK_PTO_PEX_L3_RX = 0x121,
CLK_PTO_SATA_TXCLKREF = 0x122,
CLK_PTO_SATA_TXCLKREF_DIV2 = 0x123,
CLK_PTO_USB_L5_RX = 0x124,
CLK_PTO_SATA_TX = 0x125,
CLK_PTO_SATA_L0_RX = 0x126,
CLK_PTO_SOR0 = 0xC0,
CLK_PTO_SOR1 = 0xC1,
CLK_PTO_USB3_L1_TXCLKREF = 0x129,
CLK_PTO_USB3_L7_TXCLKREF = 0x12A,
CLK_PTO_USB3_L7_RX = 0x12B,
CLK_PTO_USB3_TX = 0x12C,
CLK_PTO_UTMIP_PLL_PAD = 0x12D,
CLK_PTO_DISP2 = 0xC4,
CLK_PTO_DISP1 = 0xC5,
CLK_PTO_XUSB_FS = 0x136,
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
CLK_PTO_XUSB_CORE_HOST = 0x138,
CLK_PTO_XUSB_CORE_DEV = 0x139,
CLK_PTO_XUSB_FALCON = 0x110,
CLK_PTO_XUSB_FS = 0x136,
CLK_PTO_XUSB_SS_HOST_DEV = 0x137,
CLK_PTO_XUSB_CORE_HOST = 0x138,
CLK_PTO_XUSB_CORE_DEV = 0x139,
CLK_PTO_USB3_L2_TXCLKREF = 0x13C,
CLK_PTO_USB3_L3_TXCLKREF = 0x13D,
CLK_PTO_USB_L4_RX = 0x13E,
CLK_PTO_USB_L6_RX = 0x13F,
/*
* PLL need PTO enabled in MISC registers.
* Normal div is 2 so result is multiplied with it.
*/
CLK_PTO_PLLC_DIV2 = 0x01,
CLK_PTO_PLLM_DIV2 = 0x02,
CLK_PTO_PLLP_DIV2 = 0x03,
CLK_PTO_PLLA_DIV2 = 0x04,
CLK_PTO_PLLX_DIV2 = 0x05,
CLK_PTO_PLLC_DIV2 = 0x01,
CLK_PTO_PLLM_DIV2 = 0x02,
CLK_PTO_PLLP_DIV2 = 0x03,
CLK_PTO_PLLA_DIV2 = 0x04,
CLK_PTO_PLLX_DIV2 = 0x05,
CLK_PTO_PLLMB_DIV2 = 0x25,
CLK_PTO_PLLMB_DIV2 = 0x25,
CLK_PTO_PLLC4_DIV2 = 0x51,
CLK_PTO_PLLC4_DIV2 = 0x51,
CLK_PTO_PLLA1_DIV2 = 0x55,
CLK_PTO_PLLC2_DIV2 = 0x58,
CLK_PTO_PLLC3_DIV2 = 0x5A,
CLK_PTO_PLLA1_DIV2 = 0x55,
CLK_PTO_PLLC2_DIV2 = 0x58,
CLK_PTO_PLLC3_DIV2 = 0x5A,
CLK_PTO_PLLD_DIV2 = 0xCB,
CLK_PTO_PLLD2_DIV2 = 0xCD,
CLK_PTO_PLLDP_DIV2 = 0xCF,
CLK_PTO_PLLD_DIV2 = 0xCB,
CLK_PTO_PLLD2_DIV2 = 0xCD,
CLK_PTO_PLLDP_DIV2 = 0xCF,
CLK_PTO_PLLU_DIV2 = 0x10D,
CLK_PTO_PLLE_DIV2 = 0x10B,
CLK_PTO_PLLREFE_DIV2 = 0x10F,
CLK_PTO_PLLU_DIV2 = 0x10D,
CLK_PTO_PLLREFE_DIV2 = 0x10F,
} clock_pto_id_t;
/*

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* 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
* 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 (dramid > 6)
if (dramid > 7)
dramid = 0;
}
else
@@ -167,11 +167,8 @@ int fuse_set_sbk()
void fuse_wait_idle()
{
u32 ctrl;
do
{
ctrl = FUSE(FUSE_CTRL);
} while (((ctrl >> 16) & 0x1f) != 4);
while (((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
;
}
u32 fuse_read(u32 addr)
@@ -186,7 +183,7 @@ u32 fuse_read(u32 addr)
void fuse_read_array(u32 *words)
{
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++)
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.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
(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.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 &&
word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) -
(FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32)))
(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;
}
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* 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
* under the terms and conditions of the GNU General Public License,
@@ -23,67 +23,269 @@
#include <utils/types.h>
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
#define FUSE_PRIV2RESHIFT 0x3C
#define FUSE_FUSETIME_RD0 0x40
#define FUSE_FUSETIME_RD1 0x44
#define FUSE_FUSETIME_RD2 0x48
#define FUSE_FUSETIME_RD3 0x4C
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
/*! Fuse Cached registers */
#define FUSE_SKU_INFO 0x110
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
#define FUSE_CPU_IDDQ_CALIB 0x118
#define FUSE_OPT_FT_REV 0x128
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
#define FUSE_SOC_IDDQ_CALIB 0x140
#define FUSE_OPT_CP_REV 0x190
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c
#define FUSE_PRIVATE_KEY0 0x1A4
#define FUSE_PRIVATE_KEY1 0x1A8
#define FUSE_PRIVATE_KEY2 0x1AC
#define FUSE_PRIVATE_KEY3 0x1B0
#define FUSE_PRIVATE_KEY4 0x1B4
#define FUSE_RESERVED_SW 0x1C0
#define FUSE_USB_CALIB 0x1F0
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
#define FUSE_OPT_VENDOR_CODE 0x200
#define FUSE_OPT_FAB_CODE 0x204
#define FUSE_OPT_LOT_CODE_0 0x208
#define FUSE_OPT_LOT_CODE_1 0x20C
#define FUSE_OPT_WAFER_ID 0x210
#define FUSE_OPT_X_COORDINATE 0x214
#define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_OPT_OPS_RESERVED 0x220
#define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_USB_CALIB_EXT 0x350
#define FUSE_RESERVED_FIELD 0x354
#define FUSE_RESERVED_ODM8_B01 0x98
#define FUSE_RESERVED_ODM9_B01 0x9C
#define FUSE_RESERVED_ODM10_B01 0xA0
#define FUSE_RESERVED_ODM11_B01 0xA4
#define FUSE_RESERVED_ODM12_B01 0xA8
#define FUSE_RESERVED_ODM13_B01 0xAC
#define FUSE_RESERVED_ODM14_B01 0xB0
#define FUSE_RESERVED_ODM15_B01 0xB4
#define FUSE_RESERVED_ODM16_B01 0xB8
#define FUSE_RESERVED_ODM17_B01 0xBC
#define FUSE_RESERVED_ODM18_B01 0xC0
#define FUSE_RESERVED_ODM19_B01 0xC4
#define FUSE_RESERVED_ODM20_B01 0xC8
#define FUSE_RESERVED_ODM21_B01 0xCC
#define FUSE_KEK00_B01 0xD0
#define FUSE_KEK01_B01 0xD4
#define FUSE_KEK02_B01 0xD8
#define FUSE_KEK03_B01 0xDC
#define FUSE_BEK00_B01 0xE0
#define FUSE_BEK01_B01 0xE4
#define FUSE_BEK02_B01 0xE8
#define FUSE_BEK03_B01 0xEC
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
#define FUSE_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. */
#define FUSE_READ 0x1
#define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_IDLE 0x0
#define FUSE_READ 0x1
#define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3
/*! Fuse status. */
#define FUSE_STATUS_RESET 0
#define FUSE_STATUS_POST_RESET 1
#define FUSE_STATUS_LOAD_ROW0 2
#define FUSE_STATUS_LOAD_ROW1 3
#define FUSE_STATUS_IDLE 4
#define FUSE_STATUS_READ_SETUP 5
#define FUSE_STATUS_READ_STROBE 6
#define FUSE_STATUS_SAMPLE_FUSES 7
#define FUSE_STATUS_READ_HOLD 8
#define FUSE_STATUS_FUSE_SRC_SETUP 9
#define FUSE_STATUS_WRITE_SETUP 10
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
#define FUSE_STATUS_WRITE_PROGRAM 12
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
#define FUSE_STATUS_FUSE_SRC_HOLD 14
#define FUSE_STATUS_LOAD_RIR 15
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
#define FUSE_STATUS_READ_DEASSERT_PD 17
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
#define FUSE_ARRAY_WORDS_NUM 192
#define FUSE_ARRAY_WORDS_NUM_T210B01 256
#define FUSE_ARRAY_WORDS_NUM 192
#define FUSE_ARRAY_WORDS_NUM_B01 256
enum
{

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_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
@@ -277,12 +277,12 @@ static void _config_regulators(bool tegra_t210)
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power.
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
// Disable SDMMC1 IO/Core power.
max7762x_regulator_enable(REGULATOR_LDO2, false);
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
sd_power_cycle_time_start = get_tmr_ms();
// Disable LCD DVDD.
// Disable LCD DVDD to make sure it's in a reset state.
max7762x_regulator_enable(REGULATOR_LDO0, false);
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.
_config_se_brom();
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
// Perform Memory Built-In Self Test WAR if T210.
if (tegra_t210)
@@ -365,7 +367,7 @@ void hw_init()
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
#endif
// Enable Dynamic Voltage and Frequency Scaling device clock.
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
clock_enable_cl_dvfs();
// Enable clocks to I2C1 and I2CPWR.

View File

@@ -18,6 +18,7 @@
#include <string.h>
#include <soc/i2c.h>
#include <soc/t210.h>
#include <soc/timer.h>
#define I2C_PACKET_PROT_I2C BIT(4)
@@ -81,14 +82,8 @@
#define MSTR_CONFIG_LOAD BIT(0)
#define TIMEOUT_CONFIG_LOAD BIT(2)
static const u32 i2c_addrs[] = {
0x7000C000, // I2C_1.
0x7000C400, // I2C_2.
0x7000C500, // I2C_3.
0x7000C700, // I2C_4.
0x7000D000, // I2C_5.
0x7000D100 // I2C_6.
};
/* I2C_1, 2, 3, 4, 5 and 6. */
static const u16 _i2c_base_offsets[6] = { 0x0, 0x400, 0x500, 0x700, 0x1000, 0x1100 };
static void _i2c_load_cfg_wait(vu32 *base)
{
@@ -108,7 +103,7 @@ static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
u32 tmp = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and send mode.
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
@@ -154,7 +149,7 @@ static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
if (size > 8)
return 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
@@ -198,7 +193,7 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
@@ -270,7 +265,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
@@ -352,7 +347,7 @@ static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
void i2c_init(u32 i2c_idx)
{
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
vu32 *base = (vu32 *)(I2C_BASE + (u32)_i2c_base_offsets[i2c_idx]);
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
@@ -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)
{
u8 tmp[4];
u8 tmp[8];
if (size > 7)
return 0;

View File

@@ -194,7 +194,7 @@ void irq_wait_event(u32 irq)
_irq_enable_source(irq);
// Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ.
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ;
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ;
_irq_disable_source(irq);
_irq_ack_source(irq);

View File

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

View File

@@ -132,6 +132,9 @@
#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10)
#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12)
#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14)
#define APBDEV_PMC_FUSE_CONTROL 0x450
#define PMC_FUSE_CONTROL_PS18_LATCH_SET BIT(8)
#define PMC_FUSE_CONTROL_PS18_LATCH_CLR BIT(9)
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
@@ -177,6 +180,12 @@
#define PMC_LED_BREATHING_COUNTER_HZ 32768
#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C
#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7
#define PMC_LED_BREATHING_FSM_STS_IDLE 0
#define PMC_LED_BREATHING_FSM_STS_UP_RAMP 1
#define PMC_LED_BREATHING_FSM_STS_PLATEAU 2
#define PMC_LED_BREATHING_FSM_STS_DOWN_RAMP 3
#define PMC_LED_BREATHING_FSM_STS_SHORT_LOW_PERIOD 4
#define PMC_LED_BREATHING_FSM_STS_LONG_LOW_PERIOD 5
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define PMC_TZRAM_PWR_CNTRL_SD BIT(0)
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2023 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -20,125 +20,146 @@
#include <utils/types.h>
#define BOOTROM_BASE 0x100000
#define IRAM_BASE 0x40000000
#define HOST1X_BASE 0x50000000
#define BPMP_CACHE_BASE 0x50040000
#define DISPLAY_A_BASE 0x54200000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define NVDEC_BASE 0x54480000
#define TSEC_BASE 0x54500000
#define SOR1_BASE 0x54580000
#define MSELECT_BASE 0x50060000
#define ICTLR_BASE 0x60004000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
#define FLOW_CTLR_BASE 0x60007000
#define AHBDMA_BASE 0x60008000
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define ACTMON_BASE 0x6000C800
#define GPIO_BASE 0x6000D000
#define GPIO_1_BASE (GPIO_BASE)
#define GPIO_2_BASE (GPIO_BASE + 0x100)
#define GPIO_3_BASE (GPIO_BASE + 0x200)
#define GPIO_4_BASE (GPIO_BASE + 0x300)
#define GPIO_5_BASE (GPIO_BASE + 0x400)
#define GPIO_6_BASE (GPIO_BASE + 0x500)
#define GPIO_7_BASE (GPIO_BASE + 0x600)
#define GPIO_8_BASE (GPIO_BASE + 0x700)
#define EXCP_VEC_BASE 0x6000F000
#define IPATCH_BASE 0x6001DC00
#define APBDMA_BASE 0x60020000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define PWM_BASE 0x7000A000
#define RTC_BASE 0x7000E000
#define PMC_BASE 0x7000E400
#define SYSCTR0_BASE 0x700F0000
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define IROM_BASE 0x100000
#define IRAM_BASE 0x40000000
#define HOST1X_BASE 0x50000000
#define BPMP_CACHE_BASE 0x50040000
#define MSELECT_BASE 0x50060000
#define DPAUX1_BASE 0x54040000
#define TSEC2_BASE 0x54100000
#define DISPLAY_A_BASE 0x54200000
#define DISPLAY_B_BASE 0x54240000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define NVJPG_BASE 0x54380000
#define NVDEC_BASE 0x54480000
#define NVENC_BASE 0x544C0000
#define TSEC_BASE 0x54500000
#define SOR1_BASE 0x54580000
#define GPU_BASE 0x57000000
#define GPU_USER_BASE 0x58000000
#define RES_SEMAPH_BASE 0x60001000
#define ARB_SEMAPH_BASE 0x60002000
#define ARBPRI_BASE 0x60003000
#define ICTLR_BASE 0x60004000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
#define FLOW_CTLR_BASE 0x60007000
#define AHBDMA_BASE 0x60008000
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define ACTMON_BASE 0x6000C800
#define GPIO_BASE 0x6000D000
#define EXCP_VEC_BASE 0x6000F000
#define IPATCH_BASE 0x6001DC00
#define APBDMA_BASE 0x60020000
#define VGPIO_BASE 0x60024000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define PWM_BASE 0x7000A000
#define I2C_BASE 0x7000C000
#define RTC_BASE 0x7000E000
#define PMC_BASE 0x7000E400
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define TSENSOR_BASE 0x70014000
#define ATOMICS_BASE 0x70016000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define XUSB_PADCTL_BASE 0x7009F000
#define XUSB_DEV_BASE 0x700D0000
#define MIPI_CAL_BASE 0x700E3000
#define CL_DVFS_BASE 0x70110000
#define I2S_BASE 0x702D1000
#define ADMA_BASE 0x702E2000
#define TZRAM_BASE 0x7C010000
#define XUSB_DEV_BASE 0x700D0000
#define SDMMC_BASE 0x700B0000
#define SOC_THERM_BASE 0x700E2000
#define MIPI_CAL_BASE 0x700E3000
#define SYSCTR0_BASE 0x700F0000
#define SYSCTR1_BASE 0x70100000
#define CL_DVFS_BASE 0x70110000
#define APE_BASE 0x702C0000
#define AHUB_BASE 0x702D0000
#define AXBAR_BASE 0x702D0800
#define I2S_BASE 0x702D1000
#define ADMA_BASE 0x702E2000
#define SE2_BASE 0x70412000
#define SE_PKA1_BASE 0x70420000
#define TZRAM_BASE 0x7C010000
#define TZRAM_SIZE 0x10000
#define TZRAM_T210B01_SIZE 0x3C000
#define USB_BASE 0x7D000000
#define USB_OTG_BASE USB_BASE
#define USB1_BASE 0x7D004000
#define USB_BASE 0x7D000000
#define USB_OTG_BASE USB_BASE
#define USB1_BASE 0x7D004000
#define EMEM_BASE 0x80000000
#define _REG(base, off) *(vu32 *)((base) + (off))
#define MMIO_REG32(base, off) *(vu32 *)((base) + (off))
#define HOST1X(off) _REG(HOST1X_BASE, off)
#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
#define DSI(off) _REG(DSI_BASE, off)
#define VIC(off) _REG(VIC_BASE, off)
#define NVDEC(off) _REG(NVDEC_BASE, off)
#define TSEC(off) _REG(TSEC_BASE, off)
#define SOR1(off) _REG(SOR1_BASE, off)
#define MSELECT(off) _REG(MSELECT_BASE, off)
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off)
#define TMR(off) _REG(TMR_BASE, off)
#define CLOCK(off) _REG(CLOCK_BASE, off)
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
#define SYSREG(off) _REG(SYSREG_BASE, off)
#define AHB_GIZMO(off) _REG(SYSREG_BASE, off)
#define SB(off) _REG(SB_BASE, off)
#define ACTMON(off) _REG(ACTMON_BASE, off)
#define GPIO(off) _REG(GPIO_BASE, off)
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
#define GPIO_3(off) _REG(GPIO_3_BASE, off)
#define GPIO_4(off) _REG(GPIO_4_BASE, off)
#define GPIO_5(off) _REG(GPIO_5_BASE, off)
#define GPIO_6(off) _REG(GPIO_6_BASE, off)
#define GPIO_7(off) _REG(GPIO_7_BASE, off)
#define GPIO_8(off) _REG(GPIO_8_BASE, off)
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
#define PWM(off) _REG(PWM_BASE, off)
#define RTC(off) _REG(RTC_BASE, off)
#define PMC(off) _REG(PMC_BASE, off)
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
#define FUSE(off) _REG(FUSE_BASE, off)
#define KFUSE(off) _REG(KFUSE_BASE, off)
#define SE(off) _REG(SE_BASE, off)
#define MC(off) _REG(MC_BASE, off)
#define EMC(off) _REG(EMC_BASE, off)
#define EMC_CH0(off) _REG(EMC0_BASE, off)
#define EMC_CH1(off) _REG(EMC1_BASE, off)
#define XUSB_HOST(off) _REG(XUSB_HOST_BASE, off)
#define XUSB_PADCTL(off) _REG(XUSB_PADCTL_BASE, off)
#define XUSB_DEV(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_XHCI(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_PCI(off) _REG(XUSB_DEV_BASE + 0x8000, off)
#define XUSB_DEV_DEV(off) _REG(XUSB_DEV_BASE + 0x9000, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)
#define I2S(off) _REG(I2S_BASE, off)
#define ADMA(off) _REG(ADMA_BASE, off)
#define USB(off) _REG(USB_BASE, off)
#define USB1(off) _REG(USB1_BASE, off)
#define TEST_REG(off) _REG(0x0, off)
#define HOST1X(off) MMIO_REG32(HOST1X_BASE, off)
#define BPMP_CACHE_CTRL(off) MMIO_REG32(BPMP_CACHE_BASE, off)
#define MSELECT(off) MMIO_REG32(MSELECT_BASE, off)
#define DPAUX1(off) MMIO_REG32(DPAUX1_BASE, off)
#define TSEC2(off) MMIO_REG32(TSEC2_BASE, off)
#define DISPLAY_A(off) MMIO_REG32(DISPLAY_A_BASE, off)
#define DISPLAY_B(off) MMIO_REG32(DISPLAY_B_BASE, off)
#define DSI(off) MMIO_REG32(DSI_BASE, off)
#define VIC(off) MMIO_REG32(VIC_BASE, off)
#define NVJPG(off) MMIO_REG32(NVJPG_BASE, off)
#define NVDEC(off) MMIO_REG32(NVDEC_BASE, off)
#define NVENC(off) MMIO_REG32(NVENC_BASE, off)
#define TSEC(off) MMIO_REG32(TSEC_BASE, off)
#define SOR1(off) MMIO_REG32(SOR1_BASE, off)
#define GPU(off) MMIO_REG32(GPU_BASE, off)
#define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
#define ICTLR(cidx, off) MMIO_REG32(ICTLR_BASE + (0x100 * (cidx)), off)
#define TMR(off) MMIO_REG32(TMR_BASE, off)
#define CLOCK(off) MMIO_REG32(CLOCK_BASE, off)
#define FLOW_CTLR(off) MMIO_REG32(FLOW_CTLR_BASE, off)
#define AHBDMA(off) MMIO_REG32(AHBDMA_BASE, off)
#define SYSREG(off) MMIO_REG32(SYSREG_BASE, off)
#define AHB_GIZMO(off) MMIO_REG32(SYSREG_BASE, off)
#define SB(off) MMIO_REG32(SB_BASE, off)
#define ACTMON(off) MMIO_REG32(ACTMON_BASE, off)
#define GPIO(off) MMIO_REG32(GPIO_BASE, off)
#define EXCP_VEC(off) MMIO_REG32(EXCP_VEC_BASE, off)
#define APBDMA(off) MMIO_REG32(APBDMA_BASE, off)
#define VGPIO(off) MMIO_REG32(VGPIO_BASE, off)
#define APB_MISC(off) MMIO_REG32(APB_MISC_BASE, off)
#define PINMUX_AUX(off) MMIO_REG32(PINMUX_AUX_BASE, off)
#define PWM(off) MMIO_REG32(PWM_BASE, off)
#define RTC(off) MMIO_REG32(RTC_BASE, off)
#define PMC(off) MMIO_REG32(PMC_BASE, off)
#define SYSCTR0(off) MMIO_REG32(SYSCTR0_BASE, off)
#define SYSCTR1(off) MMIO_REG32(SYSCTR1_BASE, off)
#define FUSE(off) MMIO_REG32(FUSE_BASE, off)
#define KFUSE(off) MMIO_REG32(KFUSE_BASE, off)
#define SE(off) MMIO_REG32(SE_BASE, off)
#define MC(off) MMIO_REG32(MC_BASE, off)
#define EMC(off) MMIO_REG32(EMC_BASE, off)
#define EMC_CH0(off) MMIO_REG32(EMC0_BASE, off)
#define EMC_CH1(off) MMIO_REG32(EMC1_BASE, off)
#define XUSB_HOST(off) MMIO_REG32(XUSB_HOST_BASE, off)
#define XUSB_PADCTL(off) MMIO_REG32(XUSB_PADCTL_BASE, off)
#define XUSB_DEV(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define XUSB_DEV_XHCI(off) MMIO_REG32(XUSB_DEV_BASE, off)
#define XUSB_DEV_PCI(off) MMIO_REG32(XUSB_DEV_BASE + 0x8000, off)
#define XUSB_DEV_DEV(off) MMIO_REG32(XUSB_DEV_BASE + 0x9000, off)
#define MIPI_CAL(off) MMIO_REG32(MIPI_CAL_BASE, off)
#define CL_DVFS(off) MMIO_REG32(CL_DVFS_BASE, off)
#define I2S(off) MMIO_REG32(I2S_BASE, off)
#define ADMA(off) MMIO_REG32(ADMA_BASE, off)
#define SE2(off) MMIO_REG32(SE2_BASE, off)
#define SE_PKA1(off) MMIO_REG32(SE_PKA1_BASE, off)
#define USB(off) MMIO_REG32(USB_BASE, off)
#define USB1(off) MMIO_REG32(USB1_BASE, off)
#define TEST_REG(off) MMIO_REG32(0x0, off)
/* HOST1X registers. */
#define HOST1X_CH0_SYNC_BASE 0x2100
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4)
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200)
/* HOST1X v3 registers. */
#define HOST1X_CH0_SYNC_BASE 0x2100
#define HOST1X_CH0_SYNC_SYNCPT_BASE (HOST1X_CH0_SYNC_BASE + 0xF80)
#define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x24)
#define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_SYNCPT_BASE + 0x280)
/*! EVP registers. */
#define EVP_CPU_RESET_VECTOR 0x100
@@ -204,6 +225,12 @@
#define GP_HIDREV_MAJOR_T210 0x1
#define GP_HIDREV_MAJOR_T210B01 0x2
#define APB_MISC_GP_ASDBGREG 0x810
#define APB_MISC_GP_TRANSACTOR_SCRATCH 0x864
#define APB_MISC_GP_AVP_TRANSACTOR_SCRATCH 0x880
#define APB_MISC_GP_CPU0_TRANSACTOR_SCRATCH 0x884
#define APB_MISC_GP_CPU1_TRANSACTOR_SCRATCH 0x888
#define APB_MISC_GP_CPU2_TRANSACTOR_SCRATCH 0x88C
#define APB_MISC_GP_CPU3_TRANSACTOR_SCRATCH 0x890
#define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
@@ -223,10 +250,10 @@
#define SB_AA64_RESET_HIGH 0x34
/*! SOR registers. */
#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8
#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB 0x208
#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB 0x20C
#define SOR_DP_HDCP_BKSV_LSB 0x1E8
#define SOR_TMDS_HDCP_BKSV_LSB 0x21C
#define SOR_TMDS_HDCP_CN_MSB 0x208
#define SOR_TMDS_HDCP_CN_LSB 0x20C
/*! RTC registers. */
#define APBDEV_RTC_SECONDS 0x8
@@ -251,6 +278,12 @@
#define SYSCTR0_COUNTERID10 0xFF8
#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. */
#define I2S1_CG 0x88
#define I2S1_CTRL 0xA0
@@ -276,29 +309,47 @@
#define EMC_SEPT_RUN BIT(31)
/*! Flow controller registers. */
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define HALT_COP_GIC_IRQ BIT(9)
#define HALT_COP_LIC_IRQ BIT(11)
#define HALT_COP_SEC BIT(23)
#define HALT_COP_MSEC BIT(24)
#define HALT_COP_USEC BIT(25)
#define HALT_COP_JTAG BIT(28)
#define HALT_COP_WAIT_EVENT BIT(30)
#define HALT_COP_STOP_UNTIL_IRQ BIT(31)
#define HALT_COP_MAX_CNT 0xFF
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_CPU1_CSR 0x18
#define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define FLOW_CTLR_RAM_REPAIR 0x40
#define 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)
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24
#define HALT_GIC_IRQ BIT(9)
#define HALT_LIC_IRQ BIT(11)
#define HALT_SEC BIT(23)
#define HALT_MSEC BIT(24)
#define HALT_USEC BIT(25)
#define HALT_JTAG BIT(28)
#define HALT_MODE_NONE (0 << 29u)
#define HALT_MODE_RUN_AND_INT (1 << 29u)
#define HALT_MODE_WAITEVENT (2 << 29u)
#define HALT_MODE_WAITEVENT_AND_INT (3 << 29u)
#define HALT_MODE_STOP_UNTIL_IRQ (4 << 29u)
#define HALT_MODE_STOP_UNTIL_IRQ_AND_INT (5 << 29u)
#define HALT_MODE_STOP_UNTIL_EVENT_AND_IRQ (6 << 29u)
#define HALT_MAX_CNT 0xFF
#define FLOW_CTLR_COP_CSR 0xC
#define FLOW_CTLR_CPU0_CSR 0x8
#define FLOW_CTLR_CPU1_CSR 0x18
#define FLOW_CTLR_CPU2_CSR 0x20
#define FLOW_CTLR_CPU3_CSR 0x28
#define CSR_ENABLE BIT(0)
#define CSR_WAIT_WFI_NONE (0 << 8u)
#define CSR_WAIT_WFI_CPU0 (BIT(0) << 8u)
#define CSR_ENABLE_EXT_CPU_ONLY (0 << 12u)
#define CSR_ENABLE_EXT_CPU_NCPU (1 << 12u)
#define CSR_ENABLE_EXT_CPU_RAIL (2 << 12u)
#define CSR_EVENT_FLAG BIT(14)
#define CSR_INTR_FLAG BIT(15)
#define CSR_HALT BIT(22)
#define FLOW_CTLR_CPU_PWR_CSR 0x38
#define CPU_PWR_RAIL_STS_MASK (3 << 1u)
#define CPU_PWR_RAIL_OFF 0
#define FLOW_CTLR_RAM_REPAIR 0x40
#define RAM_REPAIR_REQ BIT(0)
#define RAM_REPAIR_STS BIT(1)
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0)
/* MSelect registers */
#define MSELECT_CONFIG 0x00

View File

@@ -71,6 +71,12 @@ void usleep(u32 us)
#endif
}
// Instruction wait loop. Each loop is 3 cycles (SUBS+BGT). Usage: isleep(ILOOP(instr)). Base 408MHz: 7.35ns.
void __attribute__((target("arm"))) isleep(u32 is)
{
asm volatile( "0:" "SUBS %[is_cnt], #1;" "BGT 0b;" : [is_cnt] "+r" (is));
}
void timer_usleep(u32 us)
{
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;

View File

@@ -51,6 +51,8 @@ u32 get_tmr_ms();
u32 get_tmr_s();
void usleep(u32 us);
void msleep(u32 ms);
#define ILOOP(is) ((is) / 3)
void isleep(u32 is);
void timer_usleep(u32 us);

View File

@@ -21,11 +21,11 @@
#include <soc/t210.h>
/* UART A, B, C, D and E. */
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
static const u16 _uart_base_offsets[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
void uart_init(u32 idx, u32 baud, 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.
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)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (UART_TX_IDLE & which)
{
while (!(uart->UART_LSR & UART_LSR_TMTY))
@@ -85,7 +85,7 @@ void uart_wait_xfer(u32 idx, u32 which)
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++)
{
@@ -97,7 +97,7 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
u32 uart_recv(u32 idx, u8 *buf, u32 len)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
bool manual_mode = uart->UART_MCR & UART_MCR_RTS;
u32 timeout = get_tmr_us() + 250;
u32 i;
@@ -127,7 +127,7 @@ out:
void uart_invert(u32 idx, bool enable, u32 invert_mask)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
if (enable)
uart->UART_IRDA_CSR |= invert_mask;
@@ -138,7 +138,7 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask)
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;
(void)uart->UART_SPR;
@@ -146,7 +146,7 @@ void uart_set_mode(u32 idx, u32 mode)
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;
@@ -158,7 +158,7 @@ u32 uart_get_IIR(u32 idx)
void uart_set_IIR(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_IER_DLAB &= ~UART_IER_DLAB_IE_EORD;
(void)uart->UART_SPR;
@@ -168,7 +168,7 @@ void uart_set_IIR(u32 idx)
void uart_empty_fifo(u32 idx, u32 which)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
uart_t *uart = (uart_t *)(UART_BASE + (u32)_uart_base_offsets[idx]);
uart->UART_MCR = 0;
(void)uart->UART_SPR;

View File

@@ -1,6 +1,6 @@
/*
* 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
* 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)
{
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
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++)
{
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)
continue;

View File

@@ -26,7 +26,7 @@
#define GPT_FIRST_LBA 1
#define GPT_NUM_BLOCKS 33
#define EMMC_BLOCKSIZE 512
#define EMMC_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum
{

View File

@@ -39,40 +39,40 @@ typedef struct _mbr_part_t
typedef struct _mbr_t
{
u8 bootstrap[440];
u32 signature;
u16 copy_protected;
mbr_part_t partitions[4];
u16 boot_signature;
/* 0x000 */ u8 bootstrap[440];
/* 0x1B8 */ u32 signature;
/* 0x1BC */ u16 copy_protected;
/* 0x1BE */ mbr_part_t partitions[4];
/* 0x1FE */ u16 boot_signature;
} __attribute__((packed)) mbr_t;
typedef struct _gpt_entry_t
{
u8 type_guid[0x10];
u8 part_guid[0x10];
u64 lba_start;
u64 lba_end;
u64 attrs;
u16 name[36];
/* 0x00 */ u8 type_guid[0x10];
/* 0x10 */ u8 part_guid[0x10];
/* 0x20 */ u64 lba_start;
/* 0x28 */ u64 lba_end;
/* 0x30 */ u64 attrs;
/* 0x38 */ u16 name[36];
} gpt_entry_t;
typedef struct _gpt_header_t
{
u64 signature; // "EFI PART"
u32 revision;
u32 size;
u32 crc32;
u32 res1;
u64 my_lba;
u64 alt_lba;
u64 first_use_lba;
u64 last_use_lba;
u8 disk_guid[0x10];
u64 part_ent_lba;
u32 num_part_ents;
u32 part_ent_size;
u32 part_ents_crc32;
u8 res2[420]; // Used as first 3 partition entries backup for HOS.
/* 0x00 */ u64 signature; // "EFI PART"
/* 0x08 */ u32 revision;
/* 0x0C */ u32 size;
/* 0x10 */ u32 crc32;
/* 0x14 */ u32 res1;
/* 0x18 */ u64 my_lba;
/* 0x20 */ u64 alt_lba;
/* 0x28 */ u64 first_use_lba;
/* 0x30 */ u64 last_use_lba;
/* 0x38 */ u8 disk_guid[0x10];
/* 0x48 */ u64 part_ent_lba;
/* 0x50 */ u32 num_part_ents;
/* 0x54 */ u32 part_ent_size;
/* 0x58 */ u32 part_ents_crc32;
/* 0x5C */ u8 res2[420]; // Used as first 3 partition entries backup for HOS.
} gpt_header_t;
typedef struct _gpt_t

View File

@@ -91,7 +91,7 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush
}
// 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.
// 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;
// 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.
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.
// 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.
// Copy to cluster cache.

View File

@@ -85,13 +85,13 @@ typedef struct _nx_emmc_cal0_t
u8 bd_mac[6];
u8 crc16_pad4[2];
u8 rsvd2[8];
u8 acc_offset[6];
u16 acc_offset[3];
u8 crc16_pad5[2];
u8 acc_scale[6];
u16 acc_scale[3];
u8 crc16_pad6[2];
u8 gyro_offset[6];
u16 gyro_offset[3];
u8 crc16_pad7[2];
u8 gyro_scale[6];
u16 gyro_scale[3];
u8 crc16_pad8[2];
char serial_number[0x18];
u8 crc16_pad9[8];
@@ -213,11 +213,15 @@ typedef struct _nx_emmc_cal0_t
// 6.0.0 and up.
u8 battery_ver;
u8 crc16_pad58[0x1F];
u8 crc16_pad58[0xF];
// 10.0.0 and up.
u8 touch_ic_vendor_id;
u8 crc16_pad59[0xF];
// 9.0.0 and up.
u32 home_menu_scheme_model;
u8 crc16_pad59[0xC];
u32 color_model;
u8 crc16_pad60[0xC];
// 10.0.0 and up.
u8 console_6axis_sensor_mount_type;

View File

@@ -22,7 +22,7 @@
#include <storage/sdmmc_driver.h>
#include <libs/fatfs/ff.h>
#define SD_BLOCKSIZE 512
#define SD_BLOCKSIZE SDMMC_DAT_BLOCKSIZE
enum
{

View File

@@ -28,6 +28,7 @@
#include <memory_map.h>
#include <gfx_utils.h>
//#define SDMMC_DEBUG_PRINT_SD_REGS
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...)
@@ -184,7 +185,7 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
reqbuf.buf = buf;
reqbuf.num_sectors = 1;
reqbuf.blksize = 512;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 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.num_sectors = num_sectors;
reqbuf.blksize = 512;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.is_write = is_write;
reqbuf.is_multi_block = 1;
reqbuf.is_auto_stop_trn = 1;
@@ -326,7 +327,7 @@ reinit_try:
out:
sct_off += blkcnt;
sct_total -= blkcnt;
bbuf += 512 * blkcnt;
bbuf += SDMMC_DAT_BLOCKSIZE * blkcnt;
}
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))
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;
u8 *tmp_buf = (u8 *)SDMMC_UPPER_BUFFER;
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 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))
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;
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);
}
@@ -519,7 +520,7 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 512;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 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;
DPRINTF("[MMC] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512))
if (!_sdmmc_storage_set_blocklen(storage, EMMC_BLOCKSIZE))
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.
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);
}
#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)
{
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);
#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.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;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 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;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 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
*
* Proper procedure:
* DLL Tuning (a) or Tuning Window (b) procedure:
* 1. Check that Vendor Specific Command System is supported.
* Used as Enable DDR200 Bus.
* 2. Enable DDR200 bus mode via setting 14 to Group 2 via CMD6.
* Access Mode group is left to default 0 (SDR12).
* 3. Setup clock to 200 or 208 MHz.
* 4. Set host to DDR bus mode that supports such high clocks.
* Some hosts have special mode, others use DDR50 and others HS400.
* 5. Execute Tuning.
* 4a. Set host to DDR200/HS400 bus mode that enables DLL syncing.
* Actual implementation supported by all DDR200 cards.
* --
* 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
* and clocks/timings work fully after that point.
* On Tegra SoCs, that can be done with DDR50 host mode.
* 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.
* Tuning though can't be done automatically on any DDR mode.
* So it needs to be done manually and selected tap will be applied from the biggest
* sampling window.
* On the original implementation of DDR200 from Sandisk, a DLL mechanism,
* like the one in eMMC HS400 is mandatory.
* So the card can start data signals whenever it wants, and the host should
* 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
* basically overstatements to sell the feature. DDR200 is simply SDR104 in DDR mode,
* so sampling on rising and falling edge and with variable output data window.
* It can be supported by any host that is fast enough to support DDR at 200/208MHz
* and can do hw/sw tuning for finding the proper sampling window in that mode.
* On DLL tuning method expected cards, the tuning window is tiny.
* So check against a minimum of 8 taps window, to disallow DDR200.
*/
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
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;
}
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)
return 0;
if (!buf)
buf = (u8 *)SDMMC_UPPER_BUFFER;
if (!_sd_storage_switch_get(storage, buf))
return 0;
u8 access_mode = buf[13];
u16 power_limit = buf[7] | buf[6] << 8;
fmodes->access_mode = buf[13] | (buf[12] << 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
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
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
u32 hs_type = 0;
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
case SDHCI_TIMING_UHS_DDR200:
// 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");
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);
}
#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_SDR82:
// 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;
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:
if (access_mode & SD_MODE_UHS_SDR50)
if (fmodes.access_mode & SD_MODE_UHS_SDR50)
{
type = SDHCI_TIMING_UHS_SDR50;
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:
if (access_mode & SD_MODE_UHS_DDR50)
if (fmodes.access_mode & SD_MODE_UHS_DDR50)
{
type = SDHCI_TIMING_UHS_DDR50;
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:
if (access_mode & SD_MODE_UHS_SDR25)
if (fmodes.access_mode & SD_MODE_UHS_SDR25)
{
type = SDHCI_TIMING_UHS_SDR25;
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.
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.
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)
{
if (!_sd_storage_switch_get(storage, buf))
sd_func_modes_t fmodes;
if (!sd_storage_get_fmodes(storage, buf, &fmodes))
return 0;
u8 access_mode = buf[13];
u16 power_limit = buf[7] | buf[6] << 8;
DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit);
DPRINTF("[SD] access: %02X, power: %02X\n", fmodes.access_mode, fmodes.power_limit);
// Try to raise the power limit to let the card perform better.
_sd_storage_set_power_limit(storage, 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;
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_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.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;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 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);
// 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 + 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);
#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.oemid = unstuff_bits(raw_cid, 104, 16);
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);
#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.cmdclass = unstuff_bits(raw_csd, 84, 12);
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:
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;
case 1:
@@ -1527,9 +1699,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
return 0;
DPRINTF("[SD] card selected\n");
if (!_sdmmc_storage_set_blocklen(storage, 512))
if (!_sdmmc_storage_set_blocklen(storage, SD_BLOCKSIZE))
return 0;
DPRINTF("[SD] set blocklen to 512\n");
DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
// 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))
@@ -1604,7 +1776,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = 64;
reqbuf.blksize = SDMMC_CMD_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 1;
reqbuf.is_multi_block = 0;

View File

@@ -19,8 +19,12 @@
#define _SDMMC_H_
#include <utils/types.h>
#include <storage/sd_def.h>
#include <storage/sdmmc_driver.h>
#define SDMMC_CMD_BLOCKSIZE 64
#define SDMMC_DAT_BLOCKSIZE 512
extern u32 sd_power_cycle_time_start;
typedef enum _sdmmc_type
@@ -195,6 +199,14 @@ typedef struct _sdmmc_storage_t
sd_ssr_t ssr;
} 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_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);
@@ -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 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_ssr(sdmmc_storage_t *storage, u8 *buf);
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);

View File

@@ -39,12 +39,7 @@
#endif
/*! SCMMC controller base addresses. */
static const u32 _sdmmc_bases[4] = {
0x700B0000,
0x700B0200,
0x700B0400,
0x700B0600,
};
static const u16 _sdmmc_base_offsets[4] = { 0x0, 0x200, 0x400, 0x600 };
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
// Check if Comp pad is open or short to ground.
// SDMMC1: CZ pads - T210/T210B01: 7-bit/5-bit. SDMMC2/4: LV_CZ pads - 5-bit.
u8 code_mask = (sdmmc->t210b01 || sdmmc->id != SDMMC_1) ? 0x1F : 0x7F;
u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask;
// Use 0x1F mask for all.
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
if (!autocal_pu_status)
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);
else if (autocal_pu_status == 0x1F)
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
#endif
// In case auto calibration fails, we load suggested standard values.
@@ -344,6 +339,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
break;
case SDHCI_TIMING_MMC_HS400:
// Non standard.
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break;
@@ -375,12 +371,10 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
clock_sdmmc_config_clock_source(&clock, sdmmc->id, clock);
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_hi = 0;
if (div_lo > 0xFF)
div_hi = div_lo >> SDHCI_DIV_LO_SHIFT;
u16 div_hi = div_lo >> 8;
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);
@@ -593,7 +587,7 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
if (cmd->check_busy)
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
else
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
break;
case SDMMC_RSP_TYPE_2:
@@ -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_size = win_size + iter_end;
}
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;
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
*
* 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
* 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)
{
@@ -850,14 +847,14 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;
sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE;
// Enable 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;
if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT))
return 0;
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK;
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK; // Use SDMA. Host V4 enabled so adma address regs in use.
sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 14; // TMCLK * 2^27.
return 1;
@@ -1025,7 +1022,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
return result;
}
static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
{
if (!req->blksize || !req->num_sectors)
return 0;
@@ -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_hi = 0;
sdmmc->dma_addr_next = (admaaddr + 0x80000) & 0xFFF80000;
sdmmc->dma_addr_next = ALIGN_DOWN((admaaddr + SZ_512K), SZ_512K);
sdmmc->regs->blksize = req->blksize | 0x7000; // DMA 512KB (Detects A18 carry out).
sdmmc->regs->blkcnt = blkcnt;
sdmmc->regs->blksize = req->blksize | (7u << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
sdmmc->regs->blkcnt = blkcnt;
if (blkcnt_out)
*blkcnt_out = blkcnt;
@@ -1071,7 +1068,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
return 1;
}
static int _sdmmc_update_dma(sdmmc_t *sdmmc)
static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
{
u16 blkcnt = 0;
do
@@ -1097,7 +1094,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
// Update DMA.
sdmmc->regs->admaaddr = sdmmc->dma_addr_next;
sdmmc->regs->admaaddr_hi = 0;
sdmmc->dma_addr_next += 0x80000;
sdmmc->dma_addr_next += SZ_512K;
}
}
@@ -1128,7 +1125,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
bool is_data_present = false;
if (req)
{
if (!_sdmmc_config_dma(sdmmc, &blkcnt, req))
if (!_sdmmc_config_sdma(sdmmc, &blkcnt, req))
{
#ifdef ERROR_EXTRA_PRINTING
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)
{
result = _sdmmc_update_dma(sdmmc);
result = _sdmmc_update_sdma(sdmmc);
#ifdef ERROR_EXTRA_PRINTING
if (!result)
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;
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;
@@ -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));
sdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id];
sdmmc->regs = (t210_sdmmc_t *)(SDMMC_BASE + (u32)_sdmmc_base_offsets[id]);
sdmmc->id = id;
sdmmc->clock_stopped = 1;
sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;

View File

@@ -23,9 +23,9 @@
/*! SDMMC controller IDs. */
#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_4 3 // Version 5.1.
#define SDMMC_4 3 // Version 5.0 + SW CQE + Enhanced Strobe.
/*! SDMMC power types. */
#define SDMMC_POWER_OFF 0
@@ -273,8 +273,9 @@
/*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
#define HW_TAP_TUNING 0x100
#define INVALID_TAP 0x100
#define HW_TAP_TUNING 0x100
#define INVALID_TAP 0x100
#define SAMPLING_WINDOW_SIZE_MIN 8
/*! SDMMC controller context. */
typedef struct _sdmmc_t

View File

@@ -56,16 +56,19 @@ typedef struct _gamepad_report_t
typedef struct _jc_cal_t
{
bool cl_done;
bool cr_done;
u16 clx_max;
u16 clx_min;
u16 cly_max;
u16 cly_min;
u16 crx_max;
u16 crx_min;
u16 cry_max;
u16 cry_min;
// 15ms * JC_CAL_MAX_STEPS = 240 ms.
#define JC_CAL_MAX_STEPS 16
u32 cl_step;
u32 cr_step;
u16 clx_max;
u16 clx_min;
u16 cly_max;
u16 cly_min;
u16 crx_max;
u16 crx_min;
u16 cry_max;
u16 cry_min;
} jc_cal_t;
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)
{
// Calibrate left stick.
if (!jc_cal_ctx.cl_done)
if (jc_cal_ctx.cl_step != JC_CAL_MAX_STEPS)
{
if (jc_pad->conn_l
&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
&& 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_min = jc_pad->lstick_x - 0x72;
jc_cal_ctx.cly_max = 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
return false;
}
// Calibrate right stick.
if (!jc_cal_ctx.cr_done)
if (jc_cal_ctx.cr_step != JC_CAL_MAX_STEPS)
{
if (jc_pad->conn_r
&& jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400
&& 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_min = jc_pad->rstick_x - 0x72;
jc_cal_ctx.cry_max = 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
return false;
@@ -122,7 +131,7 @@ static bool _jc_poll(gamepad_report_t *rpt)
if (jc_pad->l3 && jc_pad->home)
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))
return false;
@@ -130,9 +139,9 @@ static bool _jc_poll(gamepad_report_t *rpt)
// Re-calibrate on disconnection.
if (!jc_pad->conn_l)
jc_cal_ctx.cl_done = false;
jc_cal_ctx.cl_step = 0;
if (!jc_pad->conn_r)
jc_cal_ctx.cr_done = false;
jc_cal_ctx.cr_step = 0;
// Calculate left analog stick.
if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min)

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
* 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;
FILINFO fno;
char *dir_entries = (char *)calloc(MAX_ENTRIES, 256);
char *temp = (char *)calloc(1, 256);
char *dir_entries = (char *)zalloc(MAX_ENTRIES * 256);
char *temp = (char *)zalloc(256);
if (!pattern && !f_opendir(&dir, directory))
{

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
* Copyright (c) 2018-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -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.
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->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.
u32 klen = strlen(&lbuf[0]) + 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;
buf += sizeof(ini_kv_t);

View File

@@ -1,6 +1,6 @@
/*
* 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
* 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";
char *p;
char buf[65];
char buf[65]; // Number char size + leftover for padding.
int c = fcnt;
bool negative = false;
@@ -93,44 +93,66 @@ void s_printf(char *out_buf, const char *fmt, ...)
fmt++;
fill = 0;
fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fcnt = *fmt; // Padding size or padding type.
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
// Padding size exists. Previous char was type.
fill = fcnt;
fcnt = *fmt - '0';
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
{
// No padding type, use space. (Max padding size is 9).
fill = ' ';
fcnt -= '0';
}
}
switch (*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);
@@ -160,44 +182,66 @@ void s_vprintf(char *out_buf, const char *fmt, va_list ap)
fmt++;
fill = 0;
fcnt = 0;
// Check for padding. Number or space based.
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fcnt = *fmt; // Padding size or padding type.
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
// Padding size exists. Previous char was type.
fill = fcnt;
fcnt = *fmt - '0';
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
{
// No padding type, use space. (Max padding size is 9).
fill = ' ';
fcnt -= '0';
}
}
switch(*fmt)
switch (*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
char c = va_arg(ap, u32);
if (c != '\0')
_s_putc(c);
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);

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