@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
57
bdk/libs/fatfs/ffsystem.c
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -546,8 +546,8 @@ static void obj_to_foreground(lv_obj_t * obj)
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -646,8 +646,8 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_t * par = lv_obj_get_parent(last_top);
|
||||
/*After list change it will be the new head*/
|
||||
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
|
||||
lv_obj_invalidate(last_top);
|
||||
if (lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top))
|
||||
lv_obj_invalidate(last_top); /*Only invalidate if not top*/
|
||||
}
|
||||
|
||||
/*Send a signal about the press*/
|
||||
|
||||
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
@@ -412,17 +412,17 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 // Concatenate into one 32-bit set.
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = (c | 0xFF000000)})
|
||||
#define LV_COLOR_HEX(c) ((lv_color_t){.full = ((c) | 0xFF000000)})
|
||||
#else
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
|
||||
((uint32_t) c & 0xFF))
|
||||
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)(c) >> 16) & 0xFF), \
|
||||
((uint32_t)((uint32_t)(c) >> 8) & 0xFF), \
|
||||
((uint32_t) (c) & 0xFF))
|
||||
#endif
|
||||
|
||||
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
|
||||
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
|
||||
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
|
||||
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE(((((c) >> 4) & 0xF0) | (((c) >> 8) & 0xF)), \
|
||||
((uint32_t)((c) & 0xF0) | (((c) & 0xF0) >> 4)), \
|
||||
((uint32_t)((c) & 0xF) | (((c) & 0xF) << 4)))
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -215,9 +215,12 @@ void lv_ll_clear(lv_ll_t * ll_p)
|
||||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
{
|
||||
bool changed = ll_new_p->head != node;
|
||||
|
||||
lv_ll_rem(ll_ori_p, node);
|
||||
|
||||
/*Set node as head*/
|
||||
@@ -232,6 +235,8 @@ void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node)
|
||||
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
|
||||
ll_new_p->tail = node;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -89,8 +89,9 @@ void lv_ll_clear(lv_ll_t * ll_p);
|
||||
* @param ll_ori_p pointer to the original (old) linked list
|
||||
* @param ll_new_p pointer to the new linked list
|
||||
* @param node pointer to a node
|
||||
* @return head changed
|
||||
*/
|
||||
void lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
bool lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node);
|
||||
|
||||
/**
|
||||
* Return with head node of the linked list
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -32,13 +32,16 @@
|
||||
#define COLOR_HOS_TEAL_LIGHT (lv_color_hsv_to_rgb(_hue, 100, 72)) // 0x00B78F
|
||||
#define COLOR_HOS_TEAL (lv_color_hsv_to_rgb(_hue, 100, 64)) // 0x00A273
|
||||
#define COLOR_HOS_ORANGE LV_COLOR_HEX(0xFF5500)
|
||||
#define COLOR_HOS_BG_DARKER LV_COLOR_HEX(0x1B1B1B)
|
||||
#define COLOR_HOS_BG_DARK LV_COLOR_HEX(0x222222)
|
||||
#define COLOR_HOS_BG LV_COLOR_HEX(0x2D2D2D)
|
||||
#define COLOR_HOS_BG_LIGHT LV_COLOR_HEX(0x3D3D3D)
|
||||
#define COLOR_HOS_LIGHT_BORDER LV_COLOR_HEX(0x4D4D4D)
|
||||
#define COLOR_HOS_TXT_WHITE LV_COLOR_HEX(0xFBFBFB)
|
||||
|
||||
#define COLOR_BG_DARKER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x121212) : 0x0B0B0B) // 0x1B1B1B.
|
||||
#define COLOR_BG_DARK LV_COLOR_HEX(theme_bg_color ? (theme_bg_color - 0x0B0B0B) : 0x121212) // 0x222222.
|
||||
#define COLOR_BG LV_COLOR_HEX(theme_bg_color) // 0x2D2D2D.
|
||||
#define COLOR_BG_LIGHT LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x101010) : 0x2D2D2D) // 0x3D3D3D.
|
||||
#define COLOR_BG_LIGHTER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x191919) : 0x363636) // 0x464646.
|
||||
#define COLOR_LIGHT_BORDER LV_COLOR_HEX(theme_bg_color ? (theme_bg_color + 0x202020) : 0x3D3D3D) // 0x4D4D4D.
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -57,8 +60,9 @@ static lv_style_t def;
|
||||
static lv_style_t sb;
|
||||
|
||||
/*Saved input parameters*/
|
||||
static uint16_t _hue;
|
||||
static uint16_t _hue;
|
||||
static lv_font_t * _font;
|
||||
uint32_t theme_bg_color;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -80,18 +84,17 @@ static void basic_init(void)
|
||||
//def.image.opa = LV_OPA_COVER;
|
||||
|
||||
lv_style_copy(&bg, &def);
|
||||
bg.body.main_color = COLOR_HOS_BG;
|
||||
//bg.body.main_color = LV_COLOR_BLACK;
|
||||
bg.body.main_color = COLOR_BG;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.radius = 0;
|
||||
bg.body.empty = 1;
|
||||
|
||||
lv_style_copy(&panel, &def);
|
||||
panel.body.radius = DEF_RADIUS;
|
||||
panel.body.main_color = COLOR_HOS_BG;
|
||||
panel.body.grad_color = COLOR_HOS_BG;
|
||||
panel.body.main_color = COLOR_BG;
|
||||
panel.body.grad_color = COLOR_BG;
|
||||
panel.body.border.width = 1;
|
||||
panel.body.border.color = COLOR_HOS_LIGHT_BORDER;
|
||||
panel.body.border.color = COLOR_LIGHT_BORDER;
|
||||
panel.body.border.opa = LV_OPA_COVER;
|
||||
panel.body.shadow.color = COLOR_SHADOW_LIGHT;
|
||||
panel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
@@ -129,7 +132,7 @@ static void btn_init(void)
|
||||
static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
||||
|
||||
lv_style_copy(&rel, &def);
|
||||
rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.main_color = COLOR_BG_LIGHT;
|
||||
rel.body.grad_color = rel.body.main_color;
|
||||
rel.body.radius = 6;
|
||||
rel.body.padding.hor = LV_DPI / 3;
|
||||
@@ -139,7 +142,7 @@ static void btn_init(void)
|
||||
rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
rel.body.shadow.width = 6;
|
||||
rel.body.border.width = 0;
|
||||
rel.body.border.color = COLOR_HOS_BG_LIGHT;
|
||||
rel.body.border.color = COLOR_BG_LIGHT;
|
||||
rel.body.border.part = LV_BORDER_FULL;
|
||||
//rel.text.color = COLOR_HOS_TXT_WHITE;
|
||||
|
||||
@@ -162,7 +165,7 @@ static void btn_init(void)
|
||||
tgl_pr.body.shadow.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &rel);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
//ina.body.shadow.width = 0;
|
||||
ina.text.color = LV_COLOR_HEX(0x888888);
|
||||
@@ -207,7 +210,7 @@ static void img_init(void)
|
||||
img_light.image.intense = LV_OPA_80;
|
||||
|
||||
lv_style_copy(&img_dark, &def);
|
||||
img_dark.image.color = COLOR_HOS_BG_DARKER;
|
||||
img_dark.image.color = COLOR_BG_DARKER;
|
||||
img_dark.image.intense = LV_OPA_80;
|
||||
|
||||
|
||||
@@ -250,7 +253,7 @@ static void bar_init(void)
|
||||
static lv_style_t bar_bg, bar_indic;
|
||||
|
||||
lv_style_copy(&bar_bg, &def);
|
||||
bar_bg.body.main_color = COLOR_HOS_LIGHT_BORDER;
|
||||
bar_bg.body.main_color = COLOR_LIGHT_BORDER;
|
||||
bar_bg.body.grad_color = bar_bg.body.main_color;
|
||||
bar_bg.body.radius = 3;
|
||||
bar_bg.body.border.width = 0;
|
||||
@@ -536,9 +539,9 @@ static void mbox_init(void)
|
||||
static lv_style_t bg;
|
||||
|
||||
lv_style_copy(&bg, theme.panel);
|
||||
bg.body.main_color = LV_COLOR_HEX(0x464646);
|
||||
bg.body.main_color = COLOR_BG_LIGHTER;
|
||||
bg.body.grad_color = bg.body.main_color;
|
||||
bg.body.shadow.color = COLOR_HOS_BG;
|
||||
bg.body.shadow.color = COLOR_BG;
|
||||
bg.body.shadow.type = LV_SHADOW_FULL;
|
||||
bg.body.shadow.width = 8;
|
||||
|
||||
@@ -628,7 +631,7 @@ static void list_init(void)
|
||||
// pr.text.font = _font;
|
||||
|
||||
lv_style_copy(&tgl_rel, &pr);
|
||||
tgl_rel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_rel.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_rel.body.grad_color = tgl_rel.body.main_color;
|
||||
//tgl_rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95);
|
||||
tgl_rel.text.color = COLOR_HOS_TEAL_LIGHTER;
|
||||
@@ -639,7 +642,7 @@ static void list_init(void)
|
||||
tgl_pr.body.border.width = 0;
|
||||
|
||||
lv_style_copy(&ina, &pr);
|
||||
ina.body.main_color = COLOR_HOS_BG_DARK;
|
||||
ina.body.main_color = COLOR_BG_DARK;
|
||||
ina.body.grad_color = ina.body.main_color;
|
||||
|
||||
theme.list.sb = &sb;
|
||||
@@ -667,7 +670,7 @@ static void ddlist_init(void)
|
||||
bg.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&sel, &bg);
|
||||
sel.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
sel.body.main_color = COLOR_BG_LIGHT;
|
||||
sel.body.grad_color = sel.body.main_color;
|
||||
|
||||
theme.ddlist.bg = &bg;
|
||||
@@ -713,7 +716,7 @@ static void tabview_init(void)
|
||||
indic.body.opa = LV_OPA_0;
|
||||
|
||||
lv_style_copy(&btn_bg, &def);
|
||||
btn_bg.body.main_color = COLOR_HOS_BG;
|
||||
btn_bg.body.main_color = COLOR_BG;
|
||||
btn_bg.body.grad_color = btn_bg.body.main_color;
|
||||
btn_bg.body.radius = 0;
|
||||
btn_bg.body.empty = 1;
|
||||
@@ -734,7 +737,7 @@ static void tabview_init(void)
|
||||
rel.text.font = _font;
|
||||
|
||||
lv_style_copy(&pr, &def);
|
||||
pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
pr.body.main_color = COLOR_BG_LIGHT;
|
||||
pr.body.grad_color = pr.body.main_color;
|
||||
pr.body.border.width = 0;
|
||||
pr.body.empty = 0;
|
||||
@@ -750,7 +753,7 @@ static void tabview_init(void)
|
||||
tgl_rel.text.color = COLOR_HOS_TURQUOISE;
|
||||
|
||||
lv_style_copy(&tgl_pr, &def);
|
||||
tgl_pr.body.main_color = COLOR_HOS_BG_LIGHT;
|
||||
tgl_pr.body.main_color = COLOR_BG_LIGHT;
|
||||
tgl_pr.body.grad_color = tgl_pr.body.main_color;
|
||||
tgl_pr.body.border.width = 0;
|
||||
tgl_pr.body.empty = 0;
|
||||
@@ -797,7 +800,7 @@ static void win_init(void)
|
||||
static lv_style_t header, rel, pr;
|
||||
|
||||
lv_style_copy(&header, &def);
|
||||
header.body.main_color = COLOR_HOS_BG;
|
||||
header.body.main_color = COLOR_BG;
|
||||
header.body.grad_color = header.body.main_color;
|
||||
header.body.radius = 0;
|
||||
header.body.border.width = 0;
|
||||
@@ -843,10 +846,11 @@ static void win_init(void)
|
||||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t * font)
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t * font)
|
||||
{
|
||||
if(font == NULL) font = LV_FONT_DEFAULT;
|
||||
|
||||
theme_bg_color = bg_color;
|
||||
_hue = hue;
|
||||
_font = font;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -35,6 +35,14 @@ extern "C" {
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define COLOR_HOS_BG_BASE_DEFAULT 0x1B1B1B
|
||||
#define COLOR_HOS_BG_BASE_BLACK 0x000000
|
||||
|
||||
#define COLOR_HOS_BG_DARKER 0x1B1B1B
|
||||
#define COLOR_HOS_BG_DARK 0x222222
|
||||
#define COLOR_HOS_BG 0x2D2D2D
|
||||
#define COLOR_HOS_BG_LIGHT 0x3D3D3D
|
||||
#define COLOR_HOS_LIGHT_BORDER 0x4D4D4D
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -44,13 +52,15 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
extern uint32_t theme_bg_color;
|
||||
|
||||
/**
|
||||
* Initialize the material theme
|
||||
* @param hue [0..360] hue value from HSV color space to define the theme's base color
|
||||
* @param font pointer to a font (NULL to use the default)
|
||||
* @return pointer to the initialized theme
|
||||
*/
|
||||
lv_theme_t * lv_theme_hekate_init(uint16_t hue, lv_font_t *font);
|
||||
lv_theme_t * lv_theme_hekate_init(uint32_t bg_color, uint16_t hue, lv_font_t *font);
|
||||
|
||||
/**
|
||||
* Get a pointer to the theme
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
101
bdk/mem/mc.c
101
bdk/mem/mc.c
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
111
bdk/mem/sdram.c
111
bdk/mem/sdram.c
@@ -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.
|
||||
|
||||
|
||||
114
bdk/mem/sdram.h
114
bdk/mem/sdram.h
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
230
bdk/mem/smmu.c
230
bdk/mem/smmu.c
@@ -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();
|
||||
}
|
||||
|
||||
110
bdk/mem/smmu.h
110
bdk/mem/smmu.h
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
193
bdk/sec/se.c
193
bdk/sec/se.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
285
bdk/soc/clock.h
285
bdk/soc/clock.h
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
306
bdk/soc/fuse.h
306
bdk/soc/fuse.h
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
333
bdk/soc/t210.h
333
bdk/soc/t210.h
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user