@@ -24,7 +24,7 @@
|
||||
#include <input/als.h>
|
||||
#include <input/joycon.h>
|
||||
#include <input/touch.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/minerva.h>
|
||||
@@ -58,7 +58,7 @@
|
||||
#include <soc/uart.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/mmc_def.h>
|
||||
#include <storage/nx_emmc_bis.h>
|
||||
#include <storage/ramdisk.h>
|
||||
#include <storage/sd.h>
|
||||
@@ -72,6 +72,8 @@
|
||||
#include <utils/ini.h>
|
||||
#include <utils/list.h>
|
||||
#include <utils/sprintf.h>
|
||||
#include <utils/tegra_bct.h>
|
||||
#include <utils/tegra_bit.h>
|
||||
#include <utils/types.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "di.h"
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
@@ -132,7 +131,6 @@ static void _display_dsi_read_rx_fifo(u32 *data)
|
||||
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data)
|
||||
{
|
||||
int res = 0;
|
||||
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||
|
||||
// Drain RX FIFO.
|
||||
@@ -181,14 +179,13 @@ int display_dsi_read(u8 cmd, u32 len, void *data)
|
||||
|
||||
case ACK_ERROR_RES:
|
||||
default:
|
||||
res = 1;
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = 1;
|
||||
return 1;
|
||||
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_dsi_vblank_read(u8 cmd, u32 len, void *data)
|
||||
@@ -375,7 +372,7 @@ void display_init()
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = CLK_SRC_DIV(6); // Set PLLP_OUT and div 6 (68MHz).
|
||||
|
||||
// Bring every IO rail out of deep power down.
|
||||
// Bring every IO rail out of deep power down. (Though no rail bit is set.)
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
|
||||
@@ -414,9 +411,9 @@ void display_init()
|
||||
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
||||
}
|
||||
|
||||
// Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
|
||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||
// Set DISP1 clock source, parent clock and DSI/PCLK to command mode.
|
||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-BCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-BCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||
clock_enable_plld(3, 20, true, tegra_t210);
|
||||
|
||||
// Setup Display Interface initial window configuration.
|
||||
@@ -538,11 +535,11 @@ void display_init()
|
||||
// Unblank display.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||
|
||||
// Setup final dsi clock.
|
||||
// DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI): 234.0 MHz.
|
||||
// Switch to DSI HS mode.
|
||||
// DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI-BCLK): 234.0 MHz. (PCLK: 78 MHz)
|
||||
clock_enable_plld(1, 24, false, tegra_t210);
|
||||
|
||||
// Finalize DSI init packet sequence configuration.
|
||||
// Set HS PHY timing and finalize DSI packet sequence configuration.
|
||||
reg_write_array((u32 *)DSI_BASE, _di_dsi_seq_pkt_video_non_burst_no_eot_config, ARRAY_SIZE(_di_dsi_seq_pkt_video_non_burst_no_eot_config));
|
||||
|
||||
// Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate.
|
||||
@@ -700,9 +697,9 @@ static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||
// De-initialize video controller.
|
||||
reg_write_array((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, ARRAY_SIZE(_di_dc_video_disable_config));
|
||||
|
||||
// Set DISP1 clock source, parent clock and DSI/PCLK to low power mode.
|
||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||
// Set DISP1 clock source, parent clock and DSI/PCLK to command mode.
|
||||
// T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-BCLK): 50.0 MHz. (PCLK: 16.66 MHz)
|
||||
// T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-BCLK): 48.9 MHz. (PCLK: 16.30 MHz)
|
||||
clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210);
|
||||
|
||||
// Set timings for lowpower clocks.
|
||||
|
||||
@@ -730,7 +730,7 @@
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
#define MIPI_DCS_PRIV_SM_DISPLAY_ID 0xDD
|
||||
// LVL1 LVL2 LVL3 UNK0 UNK1
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK.
|
||||
#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Lock/Unlock: A5/5A. LVL1 group is normal registers.
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||
|
||||
@@ -842,8 +842,8 @@
|
||||
enum
|
||||
{
|
||||
PANEL_JDI_XXX062M = 0x10,
|
||||
PANEL_JDI_LAM062M109A = 0x0910,
|
||||
PANEL_JDI_LPM062M326A = 0x2610,
|
||||
PANEL_JDI_LAM062M109A = 0x0910, // SI.
|
||||
PANEL_JDI_LPM062M326A = 0x2610, // LTPS.
|
||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
@@ -851,12 +851,14 @@ enum
|
||||
PANEL_SHP_LQ055T1SW10 = 0x1040,
|
||||
PANEL_SAM_AMS699VC01 = 0x2050,
|
||||
|
||||
// Found on 6/2" clones. Unknown markings. Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F].
|
||||
// Found on 6/2" clones. Unknown markings. Clone of AUO A062TAN01.
|
||||
// Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F]. Sometimes reports [30] 94 [0F]. Both IDs have correct CRC16.
|
||||
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
|
||||
//0x0F40 [40] 94 [0F], 5.5" clone
|
||||
};
|
||||
|
||||
void display_init();
|
||||
|
||||
@@ -20,7 +20,7 @@ static const reg_cfg_t _di_dc_setup_win_config[] = {
|
||||
{DC_CMD_STATE_ACCESS, READ_MUX_ASSEMBLY | WRITE_MUX_ASSEMBLY},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL},
|
||||
{DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL | WIN_D_ACT_HCNTR_SEL},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
|
||||
@@ -197,7 +197,7 @@ static const reg_cfg_t _di_dsi_panel_init_config_jdi[] = {
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
// DSI packet config.
|
||||
// DSI HS packet config.
|
||||
static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
|
||||
@@ -211,6 +211,7 @@ static const reg_cfg_t _di_dsi_seq_pkt_video_non_burst_no_eot_config[] = {
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
|
||||
/* DSI packet sequence */
|
||||
{DSI_PKT_SEQ_0_LO, 0x40000208},
|
||||
{DSI_PKT_SEQ_2_LO, 0x40000308},
|
||||
{DSI_PKT_SEQ_4_LO, 0x40000308},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (FTM4CD60DA1BE/FTM4CD50TA1BE) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
|
||||
@@ -61,27 +61,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
#define SET_WRITE_PROTECT 6 /* Lock/Unlock media removal */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2025 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 @@
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/sd.h>
|
||||
#include <utils/util.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
@@ -6119,10 +6119,26 @@ FRESULT f_mkfs (
|
||||
for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */
|
||||
}
|
||||
n_clst = sz_vol / pau; /* Number of clusters */
|
||||
sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */
|
||||
sz_rsv = 32; /* Number of reserved sectors */
|
||||
while (1) {
|
||||
/* Do not account for reserved/root cluster on FAT size for better alignment. */
|
||||
sz_fat = (n_clst * 4 + ss - 1) / ss; /* FAT size [sector]. */
|
||||
sz_rsv = 2048; /* Number of reserved sectors. Use 1MB for better performance (for flash memory media) */
|
||||
sz_dir = 0; /* No static directory */
|
||||
if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||
|
||||
/* Align data base to erase block boundary (for flash memory media) */
|
||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||
b_fat += n; /* FAT32: Move FAT base */
|
||||
/* Make sure FAT base is aligned to reserved size for performance (PRF2SAFE min cluster alignment) */
|
||||
if ((b_fat & (sz_rsv - 1) || (n_fats == 2 && sz_fat & (sz_rsv - 1)))) {
|
||||
n_clst++; /* FAT size must always be bigger than real free size */
|
||||
continue;
|
||||
}
|
||||
sz_rsv += n;
|
||||
break;
|
||||
}
|
||||
} else { /* FAT volume */
|
||||
if (pau == 0) { /* au auto-selection */
|
||||
n = sz_vol / 0x1000; /* Volume size in unit of 4KS */
|
||||
@@ -6138,17 +6154,13 @@ FRESULT f_mkfs (
|
||||
sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */
|
||||
sz_rsv = 1; /* Number of reserved sectors */
|
||||
sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */
|
||||
}
|
||||
b_fat = b_vol + sz_rsv; /* FAT base */
|
||||
b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */
|
||||
|
||||
/* Align data base to erase block boundary (for flash memory media) */
|
||||
n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
n--; sz_rsv++; b_fat++; /* FAT: Expand FAT size */
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
@@ -6191,7 +6203,7 @@ FRESULT f_mkfs (
|
||||
/* Create FAT VBR */
|
||||
mem_set(buf, 0, ss);
|
||||
/* Boot jump code (x86), OEM name */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.8.0", 11);
|
||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||
@@ -6248,20 +6260,9 @@ FRESULT f_mkfs (
|
||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||
}
|
||||
|
||||
/* Create PRF2SAFE info */
|
||||
/* Clear PRF2SAFE info so PrFILE2 can recreate it and upgrade it if old */
|
||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||
mem_set(buf, 0, ss);
|
||||
st_dword(buf + 0, 0x32465250); /* Magic PRF2 */
|
||||
st_dword(buf + 4, 0x45464153); /* Magic SAFE */
|
||||
buf[16] = 0x64; /* Record type */
|
||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
||||
if (sz_vol < 0x1000000) {
|
||||
st_dword(buf + 36, 21 + 1); /* 22 Entries. */
|
||||
st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */
|
||||
} else {
|
||||
st_dword(buf + 36, 21 + 2); /* 23 Entries. */
|
||||
st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */
|
||||
}
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
}
|
||||
|
||||
@@ -6419,81 +6420,8 @@ FRESULT f_fdisk (
|
||||
#endif /* FF_MULTI_PARTITION */
|
||||
#endif /* FF_USE_MKFS && !FF_FS_READONLY */
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
FRESULT f_fdisk_mod (
|
||||
BYTE pdrv, /* Physical drive number */
|
||||
const DWORD* szt, /* Pointer to the size table for each partitions */
|
||||
void* work
|
||||
)
|
||||
{
|
||||
UINT i, n, sz_cyl, tot_cyl, e_cyl;
|
||||
BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
|
||||
DSTATUS stat;
|
||||
DWORD sz_disk, p_sect, b_cyl, b_sect;
|
||||
FRESULT res;
|
||||
|
||||
stat = disk_initialize(pdrv);
|
||||
if (stat & STA_NOINIT) return FR_NOT_READY;
|
||||
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
|
||||
sz_disk = sd_storage.csd.capacity;
|
||||
|
||||
if (!buf) return FR_NOT_ENOUGH_CORE;
|
||||
|
||||
/* Determine the CHS without any consideration of the drive geometry */
|
||||
for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
|
||||
if (n == 256) n--;
|
||||
e_hd = (BYTE)(n - 1);
|
||||
sz_cyl = 63 * n;
|
||||
tot_cyl = sz_disk / sz_cyl;
|
||||
|
||||
/* Create partition table */
|
||||
mem_set(buf, 0, 0x10000);
|
||||
p = buf + MBR_Table; b_cyl = 0, b_sect = 0;
|
||||
for (i = 0; i < 4; i++, p += SZ_PTE) {
|
||||
p_sect = szt[i]; /* Number of sectors */
|
||||
|
||||
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 */
|
||||
|
||||
if (e_cyl >= tot_cyl)
|
||||
LEAVE_MKFS(FR_INVALID_PARAMETER);
|
||||
|
||||
|
||||
/* Set partition table */
|
||||
p[1] = s_hd; /* Start head */
|
||||
p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1); /* Start sector */
|
||||
p[3] = (BYTE)b_cyl; /* Start cylinder */
|
||||
p[4] = 0x07; /* System type (temporary setting) */
|
||||
p[5] = e_hd; /* End head */
|
||||
p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */
|
||||
p[7] = (BYTE)e_cyl; /* End cylinder */
|
||||
st_dword(p + 8, b_sect); /* Start sector in LBA */
|
||||
st_dword(p + 12, p_sect); /* Number of sectors */
|
||||
/* Next partition */
|
||||
|
||||
for (u32 cursect = 0; cursect < 512; cursect++){
|
||||
disk_write(pdrv, buf + 0x4000, b_sect + (64 * cursect), 64);
|
||||
}
|
||||
|
||||
b_sect += p_sect;
|
||||
}
|
||||
st_word(p, 0xAA55); /* MBR signature (always at offset 510) */
|
||||
|
||||
/* Write it to the MBR */
|
||||
res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
|
||||
LEAVE_MKFS(res);
|
||||
}
|
||||
|
||||
#if FF_USE_STRFUNC
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3)
|
||||
|
||||
@@ -292,7 +292,6 @@ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_fdisk_mod (BYTE pdrv, const DWORD* szt, void* work); /* Modded version of f_fdisk that works:tm: */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/
|
||||
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */
|
||||
#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */
|
||||
#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/
|
||||
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix keyb /*Repeated trigger period in long press [ms] */
|
||||
#define LV_INDEV_LONG_PRESS_TIME 5000 /*Long press time in milliseconds*/
|
||||
#define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix lv_kb /*Repeated trigger period in long press [ms] */
|
||||
|
||||
/*Color settings*/
|
||||
#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/
|
||||
|
||||
@@ -316,6 +316,7 @@ static bool lv_task_exec(lv_task_t * lv_task_p)
|
||||
lv_task_p->last_run = lv_tick_get();
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
if (lv_task_p->task)
|
||||
lv_task_p->task(lv_task_p->param);
|
||||
|
||||
/*Delete if it was a one shot lv_task*/
|
||||
|
||||
@@ -41,6 +41,52 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 tmp1[0x40] = {0};
|
||||
u8 tmp2[0x40 + src_size];
|
||||
u8 tmp3[0x60] = {0};
|
||||
memset(tmp2, 0, 0x40 + src_size);
|
||||
|
||||
u8 *secret = (u8 *)tmp1;
|
||||
u8 *ipad = (u8 *)tmp2;
|
||||
u8 *opad = (u8 *)tmp3;
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
return res;
|
||||
}
|
||||
|
||||
void save_hierarchical_integrity_verification_storage_control_area_query_size(ivfc_size_set_t *out, const ivfc_storage_control_input_param_t *input_param, int32_t layer_count, uint64_t data_size) {
|
||||
int64_t level_size[IVFC_MAX_LEVEL + 1];
|
||||
int32_t level = layer_count - 1;
|
||||
|
||||
1528
bdk/mem/emc_t210.h
Normal file
1528
bdk/mem/emc_t210.h
Normal file
File diff suppressed because it is too large
Load Diff
82
bdk/mem/mc.c
82
bdk/mem/mc.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 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,56 +17,88 @@
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <mem/mc.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <soc/clock.h>
|
||||
|
||||
void mc_config_tzdram_carveout(u32 bom, u32 size1mb, bool lock)
|
||||
{
|
||||
MC(MC_SEC_CARVEOUT_BOM) = bom;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
|
||||
if (lock)
|
||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = 1;
|
||||
}
|
||||
#define HOS_WPR1_BASE 0x80020000
|
||||
|
||||
void mc_config_carveout()
|
||||
void mc_config_carveout_hos()
|
||||
{
|
||||
// Enable ACR GSR3.
|
||||
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
||||
// Enable ACR GSR3 and flush data to ram.
|
||||
*(u32 *)(HOS_WPR1_BASE + SZ_256K - sizeof(u32)) = ACR_GSC3_ENABLE_MAGIC;
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
// Set VPR CYA TRUSTED DEFAULT.
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = VPR_OVR0_CYA_TRUST_DEFAULT;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||
|
||||
// Disable VPR carveout.
|
||||
MC(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = VPR_CTRL_LOCKED;
|
||||
|
||||
// Configure TZDRAM carveout @ 0x90000000, 1MB.
|
||||
//mc_config_tzdram_carveout(0x90000000, 1, false);
|
||||
mc_config_tzdram_carveout(0, 0, true);
|
||||
// Disable TZDRAM carveout.
|
||||
MC(MC_SEC_CARVEOUT_BOM) = 0;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = 0;
|
||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = BIT(0);
|
||||
|
||||
// Disable CPU FW carveout.
|
||||
MC(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = BIT(0);
|
||||
|
||||
// Disable GEN1 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
||||
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;
|
||||
// Enable GEN2 carveout as WPR1.
|
||||
MC(MC_SECURITY_CARVEOUT2_BOM) = HOS_WPR1_BASE;
|
||||
MC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = SZ_256K / SZ_128K;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU | SEC_CARVEOUT_CA2_R_TSEC;
|
||||
MC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||
MC(MC_SECURITY_CARVEOUT2_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(2) |
|
||||
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
// Prepare GEN3 carveout as WPR2.
|
||||
MC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = SEC_CARVEOUT_CA2_R_GPU | SEC_CARVEOUT_CA2_W_GPU;
|
||||
MC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = SEC_CARVEOUT_CA4_R_GPU2 | SEC_CARVEOUT_CA4_W_GPU2;
|
||||
MC(MC_SECURITY_CARVEOUT3_CFG0) = SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
SEC_CARVEOUT_CFG_RD_NS |
|
||||
SEC_CARVEOUT_CFG_RD_SEC |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_RD_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_LS |
|
||||
SEC_CARVEOUT_CFG_WR_FALCON_HS |
|
||||
SEC_CARVEOUT_CFG_APERTURE_ID(3) |
|
||||
SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU |
|
||||
SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH;
|
||||
|
||||
// Disable GEN4 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
|
||||
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;
|
||||
|
||||
// Disable GEN5 carveout.
|
||||
MC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
|
||||
MC(MC_SECURITY_CARVEOUT5_CFG0) = SEC_CARVEOUT_CFG_TZ_SECURE |
|
||||
SEC_CARVEOUT_CFG_LOCKED |
|
||||
SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY |
|
||||
@@ -74,9 +106,10 @@ void mc_config_carveout()
|
||||
SEC_CARVEOUT_CFG_WR_NS;
|
||||
}
|
||||
|
||||
// SDMMC, TSEC, XUSB and probably more need it to access < DRAM_START.
|
||||
void mc_enable_ahb_redirect()
|
||||
{
|
||||
// Enable ARC_CLK_OVR_ON.
|
||||
// Bypass ARC clock gating.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19);
|
||||
//MC(MC_IRAM_REG_CTRL) &= ~BIT(0);
|
||||
MC(MC_IRAM_BOM) = IRAM_BASE;
|
||||
@@ -89,7 +122,7 @@ void mc_disable_ahb_redirect()
|
||||
MC(MC_IRAM_TOM) = 0;
|
||||
// Disable IRAM_CFG_WRITE_ACCESS (sticky).
|
||||
//MC(MC_IRAM_REG_CTRL) |= BIT(0);
|
||||
// Disable ARC_CLK_OVR_ON.
|
||||
// Set ARC clock gating to automatic.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19);
|
||||
}
|
||||
|
||||
@@ -109,6 +142,7 @@ void mc_enable()
|
||||
{
|
||||
// Reset EMC source to PLLP.
|
||||
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);
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
#include <mem/mc_t210.h>
|
||||
|
||||
void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);
|
||||
void mc_config_carveout();
|
||||
void mc_config_carveout_finalize();
|
||||
void mc_config_carveout_hos();
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_disable_ahb_redirect();
|
||||
bool mc_client_has_access(void *address);
|
||||
|
||||
1536
bdk/mem/mc_t210.h
1536
bdk/mem/mc_t210.h
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
#include "minerva.h"
|
||||
|
||||
#include <ianos/ianos.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
@@ -147,7 +147,6 @@ 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));
|
||||
|
||||
@@ -183,7 +182,7 @@ void minerva_prep_boot_freq()
|
||||
minerva_change_freq(FREQ_800);
|
||||
}
|
||||
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la)
|
||||
{
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
@@ -191,6 +190,7 @@ void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom)
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Program SDMMC LA regs.
|
||||
if (prg_sdmmc_la)
|
||||
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
|
||||
minerva_sdmmc_la_program(&mtc_cfg->mtc_table[i], false);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ 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(u32 oc_freq, u32 opt_custom);
|
||||
void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la);
|
||||
void minerva_periodic_training();
|
||||
emc_table_t *minerva_get_mtc_table();
|
||||
int minerva_get_mtc_table_entries();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <mem/mc.h>
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
#include <mem/sdram.h>
|
||||
#include <mem/sdram_param_t210.h>
|
||||
#include <mem/sdram_param_t210b01.h>
|
||||
@@ -260,7 +260,7 @@ static void _sdram_config_t210(const sdram_params_t210_t *params)
|
||||
|
||||
u32 pllm_div = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = pllm_div | PLL_BASE_ENABLE;
|
||||
|
||||
u32 wait_end = get_tmr_us() + 300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & BIT(27)))
|
||||
@@ -1012,26 +1012,26 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
|
||||
|
||||
// Program per bit pad macros.
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0) = params->emc_pmacro_perbit_rfu_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1) = params->emc_pmacro_perbit_rfu_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2) = params->emc_pmacro_perbit_rfu_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3) = params->emc_pmacro_perbit_rfu_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4) = params->emc_pmacro_perbit_rfu_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5) = params->emc_pmacro_perbit_rfu_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
||||
EMC(EMC_PMACRO_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl;
|
||||
EMC(EMC_PMACRO_CMD_PI_CTRL) = params->emc_pmacro_cmd_pi_ctrl;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0_B01) = params->emc_pmacro_perbit_fgcg_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1_B01) = params->emc_pmacro_perbit_fgcg_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2_B01) = params->emc_pmacro_perbit_fgcg_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3_B01) = params->emc_pmacro_perbit_fgcg_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4_B01) = params->emc_pmacro_perbit_fgcg_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5_B01) = params->emc_pmacro_perbit_fgcg_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0_B01) = params->emc_pmacro_perbit_rfu_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1_B01) = params->emc_pmacro_perbit_rfu_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2_B01) = params->emc_pmacro_perbit_rfu_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3_B01) = params->emc_pmacro_perbit_rfu_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4_B01) = params->emc_pmacro_perbit_rfu_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5_B01) = params->emc_pmacro_perbit_rfu_ctrl5;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0_B01) = params->emc_pmacro_perbit_rfu1_ctrl0;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1_B01) = params->emc_pmacro_perbit_rfu1_ctrl1;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2_B01) = params->emc_pmacro_perbit_rfu1_ctrl2;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3_B01) = params->emc_pmacro_perbit_rfu1_ctrl3;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4_B01) = params->emc_pmacro_perbit_rfu1_ctrl4;
|
||||
EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5_B01) = params->emc_pmacro_perbit_rfu1_ctrl5;
|
||||
EMC(EMC_PMACRO_DATA_PI_CTRL_B01) = params->emc_pmacro_data_pi_ctrl;
|
||||
EMC(EMC_PMACRO_CMD_PI_CTRL_B01) = params->emc_pmacro_cmd_pi_ctrl;
|
||||
|
||||
EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
|
||||
EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
|
||||
@@ -1220,7 +1220,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
if (params->emc_bct_spare8)
|
||||
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
||||
|
||||
EMC(EMC_AUTO_CAL_CONFIG9) = params->emc_auto_cal_config9;
|
||||
EMC(EMC_AUTO_CAL_CONFIG9_B01) = params->emc_auto_cal_config9;
|
||||
|
||||
// Program EMC timing configuration.
|
||||
EMC(EMC_CFG_2) = params->emc_cfg2;
|
||||
@@ -1240,11 +1240,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_RAS) = params->emc_ras;
|
||||
EMC(EMC_RP) = params->emc_rp;
|
||||
EMC(EMC_TPPD) = params->emc_tppd;
|
||||
EMC(EMC_CTT) = params->emc_trtm;
|
||||
EMC(EMC_FBIO_TWTM) = params->emc_twtm;
|
||||
EMC(EMC_FBIO_TRATM) = params->emc_tratm;
|
||||
EMC(EMC_FBIO_TWATM) = params->emc_twatm;
|
||||
EMC(EMC_FBIO_TR2REF) = params->emc_tr2ref;
|
||||
EMC(EMC_TRTM_B01) = params->emc_trtm;
|
||||
EMC(EMC_TWTM_B01) = params->emc_twtm;
|
||||
EMC(EMC_TRATM_B01) = params->emc_tratm;
|
||||
EMC(EMC_TWATM_B01) = params->emc_twatm;
|
||||
EMC(EMC_TR2REF_B01) = params->emc_tr2ref;
|
||||
EMC(EMC_R2R) = params->emc_r2r;
|
||||
EMC(EMC_W2W) = params->emc_w2w;
|
||||
EMC(EMC_R2W) = params->emc_r2w;
|
||||
@@ -1321,7 +1321,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
||||
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
||||
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
||||
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
||||
EMC(EMC_PMACRO_DSR_VTTGEN_CTRL_0_B01) = params->emc_pmacro_dsr_vttgen_ctrl0;
|
||||
|
||||
// Set pipe bypass enable bits before sending any DRAM commands.
|
||||
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
||||
@@ -1465,7 +1465,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
|
||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
||||
|
||||
// Set untranslated region requirements.
|
||||
MC(MC_UNTRANSLATED_REGION_CHECK) = params->mc_untranslated_region_check;
|
||||
MC(MC_UNTRANSLATED_REGION_CHECK_B01) = params->mc_untranslated_region_check;
|
||||
|
||||
// Lock carveouts per BCT cfg.
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef _SDRAM_H_
|
||||
#define _SDRAM_H_
|
||||
|
||||
#include <mem/emc.h>
|
||||
#include <mem/emc_t210.h>
|
||||
|
||||
/*
|
||||
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2025 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,
|
||||
@@ -538,18 +538,32 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
.mc_clken_override = 0x00008000,
|
||||
|
||||
.mc_stat_control = 0x00000000,
|
||||
|
||||
/* VPR carveout configuration */
|
||||
.mc_video_protect_bom = 0xFFF00000,
|
||||
.mc_video_protect_bom_adr_hi = 0x00000000,
|
||||
.mc_video_protect_size_mb = 0x00000000,
|
||||
|
||||
// AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. 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.
|
||||
// Disable access:
|
||||
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||
// Enable access:
|
||||
// DC, DCB, HDA, VIC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||
// Disable access:
|
||||
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus TSECB, TSEC1, TSECB1.
|
||||
// Enable access:
|
||||
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||
.mc_video_protect_vpr_override1 = 0x0000FED3, // Stock/Reset: 0x00001ED3. HOS 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.
|
||||
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||
|
||||
/* TZDRAM carveout configuration */
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
@@ -642,6 +656,7 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
|
||||
/* Specifies data for patched boot rom write */
|
||||
.boot_rom_patch_data = 0x00000000,
|
||||
|
||||
/* CPU FW carveout configuration */
|
||||
.mc_mts_carveout_bom = 0xFFF00000,
|
||||
.mc_mts_carveout_adr_hi = 0x00000000,
|
||||
.mc_mts_carveout_size_mb = 0x00000000,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2025 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,
|
||||
@@ -595,14 +595,26 @@ 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. 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.
|
||||
// Disable access:
|
||||
// AFI (PCIE), BPMP, HC (HOST1x), ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1 (WinT), SDMMC1/2/3. Plus TSEC, NVENC.
|
||||
// Enable access:
|
||||
// DC, DCB, HDA, VIC.
|
||||
.mc_video_protect_vpr_override = 0xE4FACB43, // Stock/Reset: 0xE4BAC343. HOS new: 0xE4FACB43. + TSEC, NVENC.
|
||||
// Disable access:
|
||||
// SDMMC4, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR, SE2, SE2B. Plus TSECB, TSEC1, TSECB1.
|
||||
// Enable access:
|
||||
// GPU, GPUB, NVDEC, NVJPG, NVDEC1.
|
||||
.mc_video_protect_vpr_override1 = 0x0600FED3, // Reset: 0x06001ED3. HOS new: 0x0600FED3. + 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.
|
||||
// VPR CYA. L4T override (set PD, SCC, SKED, L1 as UNTRUSTED).
|
||||
.mc_video_protect_gpu_override0 = VPR_OVR0_CYA_TRUST_GCC(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_RASTER(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_PE(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_TEX(VPR_TRUST_GRAPHICS) |
|
||||
VPR_OVR0_CYA_TRUST_OVERRIDE, // Stock: 0. HOS: VPR_OVR0_CYA_TRUST_DEFAULT.
|
||||
.mc_video_protect_gpu_override1 = VPR_OVR1_CYA_TRUST_PROP(VPR_TRUST_GRAPHICS), // Stock: 0. HOS: 0.
|
||||
|
||||
/* TZDRAM carveout configuration */
|
||||
.mc_sec_carveout_bom = 0xFFF00000,
|
||||
.mc_sec_carveout_adr_hi = 0x00000000,
|
||||
.mc_sec_carveout_size_mb = 0x00000000,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 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,
|
||||
@@ -54,10 +54,12 @@
|
||||
#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;
|
||||
#define SMMU_PAYLOAD_EN_SHIFT 4
|
||||
#define SMMU_PAYLOAD_EN_SET 0x20
|
||||
#define SMMU_PAYLOAD_EN_UNSET 0x00
|
||||
|
||||
// Enabling SMMU requires a TZ (EL3) secure write. MC(MC_SMMU_CONFIG) = 1;
|
||||
static const u8 smmu_enable_payload[] = {
|
||||
static 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]
|
||||
@@ -67,6 +69,9 @@ static const u8 smmu_enable_payload[] = {
|
||||
0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG
|
||||
};
|
||||
|
||||
static void *smmu_heap = (void *)SMMU_HEAP_ADDR;
|
||||
static bool smmu_enabled = false;
|
||||
|
||||
void *smmu_page_zalloc(u32 num)
|
||||
{
|
||||
void *page = smmu_heap;
|
||||
@@ -95,7 +100,6 @@ static void _smmu_flush_regs()
|
||||
|
||||
void smmu_flush_all()
|
||||
{
|
||||
|
||||
// Flush the entire page table cache.
|
||||
MC(MC_SMMU_PTC_FLUSH) = 0;
|
||||
_smmu_flush_regs();
|
||||
@@ -117,9 +121,7 @@ void smmu_init()
|
||||
|
||||
void smmu_enable()
|
||||
{
|
||||
static bool enabled = false;
|
||||
|
||||
if (enabled)
|
||||
if (smmu_enabled)
|
||||
return;
|
||||
|
||||
// Launch payload on CCPLEX in order to set SMMU enable bit.
|
||||
@@ -129,7 +131,31 @@ void smmu_enable()
|
||||
|
||||
smmu_flush_all();
|
||||
|
||||
enabled = true;
|
||||
smmu_enabled = true;
|
||||
}
|
||||
|
||||
void smmu_disable()
|
||||
{
|
||||
if (!smmu_enabled)
|
||||
return;
|
||||
|
||||
// Set payload to disable SMMU.
|
||||
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_UNSET;
|
||||
|
||||
smmu_flush_all();
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
// 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();
|
||||
|
||||
// Restore payload to SMMU enable.
|
||||
smmu_enable_payload[SMMU_PAYLOAD_EN_SHIFT] = SMMU_PAYLOAD_EN_SET;
|
||||
|
||||
smmu_enabled = false;
|
||||
}
|
||||
|
||||
void smmu_reset_heap()
|
||||
|
||||
@@ -63,6 +63,7 @@ void *smmu_page_zalloc(u32 num);
|
||||
void smmu_flush_all();
|
||||
void smmu_init();
|
||||
void smmu_enable();
|
||||
void smmu_disable();
|
||||
void smmu_reset_heap();
|
||||
void *smmu_init_domain(u32 dev_base, u32 asid);
|
||||
void smmu_deinit_domain(u32 dev_base, u32 asid);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -29,7 +29,6 @@
|
||||
#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon.
|
||||
|
||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||
|
||||
/* start.S / exception_handlers.S */
|
||||
#define SYS_STACK_TOP_INIT 0x4003FF00
|
||||
@@ -48,29 +47,27 @@
|
||||
#define NYX_SZ_MAX SZ_16M
|
||||
/* --- Gap: 0x82000000 - 0x82FFFFFF --- */
|
||||
|
||||
/* Stack theoretical max: 33MB */
|
||||
#define IPL_STACK_TOP 0x83100000
|
||||
#define IPL_HEAP_START 0x84000000
|
||||
#define IPL_HEAP_SZ (SZ_512M - SZ_64M)
|
||||
// Heap buffer.
|
||||
#define IPL_HEAP_START 0x82000000
|
||||
#define IPL_HEAP_SZ (SZ_256M)
|
||||
|
||||
#define SMMU_HEAP_ADDR 0xA0000000
|
||||
/* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */
|
||||
#define SMMU_HEAP_ADDR 0x92000000
|
||||
/* --- Gap: 1280MB 0x96000000 - 0xE4FFFFFF --- */
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
#define RAM_DISK_ADDR 0xA4000000
|
||||
#define RAM_DISK_SZ 0x41000000 // 1040MB.
|
||||
#define RAM_DISK2_SZ 0x21000000 // 528MB.
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xC5000000
|
||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||
#define NX_BIS_LOOKUP_ADDR 0xD6000000
|
||||
#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB.
|
||||
#define RAM_DISK_ADDR 0x95000000
|
||||
#define RAM_DISK_SZ 0x50000000 // 1280MB.
|
||||
|
||||
// L4T Kernel Panic Storage (PSTORE).
|
||||
#define PSTORE_ADDR 0xB0000000
|
||||
#define PSTORE_SZ SZ_2M
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xC7000000
|
||||
#define NX_BIS_CACHE_SZ 0x10020000 // 256MB.
|
||||
#define NX_BIS_LOOKUP_ADDR 0xD8000000
|
||||
#define NX_BIS_LOOKUP_SZ 0x8000000 // 128MB. 512GB eMMC partition max.
|
||||
|
||||
//#define DRAM_LIB_ADDR 0xE0000000
|
||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||
|
||||
@@ -78,7 +75,7 @@
|
||||
#define SDMMC_UPPER_BUFFER 0xE5000000
|
||||
#define SDMMC_UP_BUF_SZ SZ_128M
|
||||
|
||||
// Nyx buffers.
|
||||
// Nyx buffers. !Do not change!
|
||||
#define NYX_STORAGE_ADDR 0xED000000
|
||||
#define NYX_RES_ADDR 0xEE000000
|
||||
#define NYX_RES_SZ SZ_16M
|
||||
@@ -86,7 +83,6 @@
|
||||
// SDMMC DMA buffers 2
|
||||
#define SDXC_BUF_ALIGNED 0xEF000000
|
||||
#define MIXD_BUF_ALIGNED 0xF0000000
|
||||
#define TITLEKEY_BUF_ADR MIXD_BUF_ALIGNED
|
||||
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||
#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used.
|
||||
|
||||
@@ -96,7 +92,7 @@
|
||||
#define NYX_LV_MEM_ADR 0xF1400000
|
||||
#define NYX_LV_MEM_SZ 0x6600000 // 70MB.
|
||||
|
||||
// Framebuffer addresses.
|
||||
// Framebuffer addresses. !Do not change!
|
||||
#define IPL_FB_ADDRESS 0xF5A00000
|
||||
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
||||
#define LOG_FB_ADDRESS 0xF5E00000
|
||||
@@ -105,13 +101,6 @@
|
||||
#define NYX_FB2_ADDRESS 0xF6600000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
|
||||
/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */
|
||||
#define DRAM_MEM_HOLE_ADR 0xF6A00000
|
||||
#define NX_BIS_LOOKUP_ADR DRAM_MEM_HOLE_ADR
|
||||
#define DRAM_MEM_HOLE_SZ 0x8140000
|
||||
/* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */
|
||||
#define DRAM_START2 0xFEB40000
|
||||
|
||||
// USB buffers.
|
||||
#define USBD_ADDR 0xFEF00000
|
||||
#define USB_DESCRIPTOR_ADDR 0xFEF40000
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB-PD driver for Nintendo Switch's TI BM92T36
|
||||
*
|
||||
* Copyright (c) 2020-2023 CTCaer
|
||||
* Copyright (c) 2020-2025 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,
|
||||
@@ -54,6 +54,10 @@
|
||||
|
||||
#define STATUS1_INSERT BIT(7) // Cable inserted.
|
||||
|
||||
#define VER_36 0x36
|
||||
#define MAX_ROHM 0x4B5
|
||||
#define DEV_BM92T 0x3B0
|
||||
|
||||
typedef struct _pd_object_t {
|
||||
unsigned int amp:10;
|
||||
unsigned int volt:10;
|
||||
@@ -63,9 +67,29 @@ typedef struct _pd_object_t {
|
||||
|
||||
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
|
||||
{
|
||||
memset(buf, 0, size);
|
||||
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
|
||||
}
|
||||
|
||||
int bm92t36_get_version(u32 *value)
|
||||
{
|
||||
u8 buf[2];
|
||||
u16 version, man, dev;
|
||||
_bm92t36_read_reg(buf, 2, FW_TYPE_REG);
|
||||
version = (buf[0] << 4) | buf[1];
|
||||
_bm92t36_read_reg(buf, 2, MAN_ID_REG);
|
||||
man = (buf[1] << 8) | buf[0];
|
||||
_bm92t36_read_reg(buf, 2, DEV_ID_REG);
|
||||
dev = (buf[1] << 8) | buf[0];
|
||||
if (value)
|
||||
*value = (dev << 16) | version;
|
||||
|
||||
if (version == VER_36 && man == MAX_ROHM && dev == DEV_BM92T)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
{
|
||||
u8 buf[32];
|
||||
@@ -73,14 +97,12 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 2, STATUS1_REG);
|
||||
*inserted = (buf[0] & STATUS1_INSERT) ? true : false;
|
||||
}
|
||||
|
||||
if (usb_pd)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
_bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG);
|
||||
memcpy(pdos, &buf[1], 28);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct _usb_pd_objects_t
|
||||
usb_pd_object_t selected_pdo;
|
||||
} usb_pd_objects_t;
|
||||
|
||||
int bm92t36_get_version(u32 *value);
|
||||
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -25,6 +25,18 @@ static u8 bq24193_get_reg(u8 reg)
|
||||
return i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, reg);
|
||||
}
|
||||
|
||||
int bq24193_get_version(u32 *value)
|
||||
{
|
||||
u16 data = bq24193_get_reg(BQ24193_VendorPart);
|
||||
if (value)
|
||||
*value = data;
|
||||
|
||||
if (data == 0x2F)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef __BQ24193_H_
|
||||
#define __BQ24193_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
// REG 0 masks.
|
||||
@@ -114,6 +116,7 @@ enum BQ24193_reg_prop {
|
||||
BQ24193_ProductNumber, // REG A.
|
||||
};
|
||||
|
||||
int bq24193_get_version(u32 *value);
|
||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
||||
void bq24193_enable_charger();
|
||||
void bq24193_fake_battery_removal();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -60,6 +60,18 @@ static u16 max17050_get_reg(u8 reg)
|
||||
return data;
|
||||
}
|
||||
|
||||
int max17050_get_version(u32 *value)
|
||||
{
|
||||
u16 data = max17050_get_reg(MAX17050_DevName);
|
||||
if (value)
|
||||
*value = data;
|
||||
|
||||
if (data == 0x00AC)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
{
|
||||
u16 data;
|
||||
|
||||
@@ -130,6 +130,7 @@ enum MAX17050_reg {
|
||||
MAX17050_VFSOC = 0xFF,
|
||||
};
|
||||
|
||||
int max17050_get_version(u32 *value);
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||
int max17050_fix_configuration();
|
||||
void max17050_dump_regs(void *buf);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018-2022 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2019 shchmue
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
|
||||
bool auto_dst = false;
|
||||
int epoch_offset = 0;
|
||||
|
||||
void max77620_rtc_prep_read()
|
||||
@@ -39,20 +40,24 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
||||
|
||||
// Get control reg config.
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG);
|
||||
// TODO: Check for binary format also?
|
||||
// TODO: Make also sure it's binary format?
|
||||
|
||||
// Get time.
|
||||
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
|
||||
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG);
|
||||
u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG) & 0x1F;
|
||||
time->hour = hour & 0x1F;
|
||||
|
||||
if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK))
|
||||
time->hour = (time->hour & 0xF) + 12;
|
||||
if (!(val & MAX77620_RTC_24H))
|
||||
{
|
||||
time->hour = hour & 0xF;
|
||||
if (hour & MAX77620_RTC_HOUR_PM_MASK)
|
||||
time->hour += 12;
|
||||
}
|
||||
|
||||
// Get day of week. 1: Monday to 7: Sunday.
|
||||
time->weekday = 0;
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG);
|
||||
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG) & 0x7F;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
time->weekday++;
|
||||
@@ -62,8 +67,9 @@ void max77620_rtc_get_time(rtc_time_t *time)
|
||||
}
|
||||
|
||||
// Get date.
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
|
||||
time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DAY_REG) & 0x1F;
|
||||
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
|
||||
time->month++; // Normally minus 1, but everything else expects 1 as January.
|
||||
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
|
||||
}
|
||||
|
||||
@@ -126,7 +132,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
||||
time->day = day;
|
||||
|
||||
// Set weekday.
|
||||
time->weekday = 0; //! TODO.
|
||||
time->weekday = (day + 4) % 7;
|
||||
}
|
||||
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
||||
@@ -162,10 +168,21 @@ void max77620_rtc_get_time_adjusted(rtc_time_t *time)
|
||||
if (epoch_offset)
|
||||
{
|
||||
u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset);
|
||||
|
||||
// Adjust for DST between 28 march and 28 october. Good enough to cover all years as week info is not valid.
|
||||
u16 md = (time->month << 8) | time->day;
|
||||
if (auto_dst && md >= 0x31C && md < 0xA1C)
|
||||
epoch += 3600;
|
||||
|
||||
max77620_rtc_epoch_to_date(epoch, time);
|
||||
}
|
||||
}
|
||||
|
||||
void max77620_rtc_set_auto_dst(bool enable)
|
||||
{
|
||||
auto_dst = enable;
|
||||
}
|
||||
|
||||
void max77620_rtc_set_epoch_offset(int offset)
|
||||
{
|
||||
epoch_offset = offset;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define MAX77620_RTC_WEEKDAY_REG 0x0A
|
||||
#define MAX77620_RTC_MONTH_REG 0x0B
|
||||
#define MAX77620_RTC_YEAR_REG 0x0C
|
||||
#define MAX77620_RTC_DATE_REG 0x0D
|
||||
#define MAX77620_RTC_DAY_REG 0x0D
|
||||
|
||||
#define MAX77620_ALARM1_SEC_REG 0x0E
|
||||
#define MAX77620_ALARM1_MIN_REG 0x0F
|
||||
@@ -111,6 +111,7 @@ 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_set_auto_dst(bool enable);
|
||||
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);
|
||||
|
||||
115
bdk/sec/se.c
115
bdk/sec/se.c
@@ -32,9 +32,6 @@ typedef struct _se_ll_t
|
||||
vu32 size;
|
||||
} se_ll_t;
|
||||
|
||||
static u32 _se_rsa_mod_sizes[SE_RSA_KEYSLOT_COUNT];
|
||||
static u32 _se_rsa_exp_sizes[SE_RSA_KEYSLOT_COUNT];
|
||||
|
||||
se_ll_t ll_src, ll_dst;
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
|
||||
|
||||
@@ -214,66 +211,6 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||
SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
|
||||
}
|
||||
|
||||
// se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot
|
||||
void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size)
|
||||
{
|
||||
u32 *data = (u32 *)mod;
|
||||
for (u32 i = 0; i < mod_size / 4; i++)
|
||||
{
|
||||
SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i;
|
||||
SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[mod_size / 4 - i - 1]);
|
||||
}
|
||||
|
||||
data = (u32 *)exp;
|
||||
for (u32 i = 0; i < exp_size / 4; i++)
|
||||
{
|
||||
SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i;
|
||||
SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[exp_size / 4 - i - 1]);
|
||||
}
|
||||
|
||||
_se_rsa_mod_sizes[ks] = mod_size;
|
||||
_se_rsa_exp_sizes[ks] = exp_size;
|
||||
}
|
||||
|
||||
// se_rsa_key_clear() was derived from Atmosphère's clear_rsa_keyslot
|
||||
void se_rsa_key_clear(u32 ks)
|
||||
{
|
||||
for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++)
|
||||
{
|
||||
SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i;
|
||||
SE(SE_RSA_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++)
|
||||
{
|
||||
SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i;
|
||||
SE(SE_RSA_KEYTABLE_DATA_REG) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// se_rsa_exp_mod() was derived from Atmosphère's se_synchronous_exp_mod and se_get_exp_mod_output
|
||||
int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
int res;
|
||||
u8 stack_buf[SE_RSA2048_DIGEST_SIZE];
|
||||
|
||||
for (u32 i = 0; i < src_size; i++)
|
||||
stack_buf[i] = *((u8 *)src + src_size - i - 1);
|
||||
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RSA) | SE_CONFIG_DST(DST_RSAREG);
|
||||
SE(SE_RSA_CONFIG) = RSA_KEY_SLOT(ks);
|
||||
SE(SE_RSA_KEY_SIZE_REG) = (_se_rsa_mod_sizes[ks] >> 6) - 1;
|
||||
SE(SE_RSA_EXP_SIZE_REG) = _se_rsa_exp_sizes[ks] >> 2;
|
||||
|
||||
res = _se_execute_oneshot(SE_OP_START, NULL, 0, stack_buf, src_size);
|
||||
|
||||
// Copy output hash.
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
for (u32 i = 0; i < dst_size / 4; i++)
|
||||
dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT_REG + (i * 4)));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||
{
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
@@ -299,12 +236,6 @@ void se_aes_key_set(u32 ks, const void *key, u32 size)
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_key_partial_set(u32 ks, u32 index, u32 data)
|
||||
{
|
||||
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | index;
|
||||
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data;
|
||||
}
|
||||
|
||||
void se_aes_iv_set(u32 ks, const void *iv)
|
||||
{
|
||||
u32 data[SE_AES_IV_SIZE / 4];
|
||||
@@ -648,52 +579,6 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 tmp1[0x40] = {0};
|
||||
u8 tmp2[0x40 + src_size];
|
||||
u8 tmp3[0x60] = {0};
|
||||
memset(tmp2, 0, 0x40 + src_size);
|
||||
|
||||
u8 *secret = (u8 *)tmp1;
|
||||
u8 *ipad = (u8 *)tmp2;
|
||||
u8 *opad = (u8 *)tmp3;
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_gen_prng128(void *dst)
|
||||
{
|
||||
// Setup config for X931 PRNG.
|
||||
|
||||
@@ -22,15 +22,11 @@
|
||||
#include <utils/types.h>
|
||||
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags);
|
||||
void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size);
|
||||
void se_rsa_key_clear(u32 ks);
|
||||
int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags);
|
||||
u32 se_key_acc_ctrl_get(u32 ks);
|
||||
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
|
||||
void se_aes_key_set(u32 ks, const void *key, u32 size);
|
||||
void se_aes_iv_set(u32 ks, const void *iv);
|
||||
void se_aes_key_partial_set(u32 ks, u32 index, u32 data);
|
||||
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);
|
||||
@@ -47,7 +43,6 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_
|
||||
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);
|
||||
|
||||
|
||||
@@ -91,10 +91,10 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
{
|
||||
// Disable all CCPLEX core rails.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE1, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE2, DISABLE);
|
||||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE1, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE2, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE3, DISABLE);
|
||||
|
||||
// Enable AHB aperture and set it to full mmio.
|
||||
mc_enable_ahb_redirect();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -64,9 +64,13 @@ typedef enum
|
||||
BPMP_STATE_FIQ = BIT(3),
|
||||
} bpmp_state_t;
|
||||
|
||||
#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
#define BPMP_CLK_BIN0_BOOST BPMP_CLK_HYPER_BOOST
|
||||
#define BPMP_CLK_BIN1_BOOST BPMP_CLK_SUPER_BOOST
|
||||
#define BPMP_CLK_BIN2_BOOST BPMP_CLK_HIGH2_BOOST
|
||||
#define BPMP_CLK_BIN3_BOOST BPMP_CLK_HIGH_BOOST
|
||||
|
||||
#define BPMP_CLK_LOWER_BOOST BPMP_CLK_BIN1_BOOST
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_BIN0_BOOST
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply);
|
||||
|
||||
@@ -90,11 +90,11 @@ void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
|
||||
|
||||
// Enable CPU main rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, ENABLE);
|
||||
// Enable cluster 0 non-CPU rail.
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, ENABLE);
|
||||
// Enable CPU0 rail.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, ENABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, ENABLE);
|
||||
|
||||
// Request and wait for RAM repair. Needed for the Fast cluster.
|
||||
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ;
|
||||
@@ -115,7 +115,7 @@ void ccplex_boot_cpu0(u32 entry, bool lock)
|
||||
}
|
||||
|
||||
// Tighten up the security aperture.
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
// MC(MC_TZ_SECURITY_CTRL) = TZ_SEC_CTRL_CPU_STRICT_TZ_APERTURE_CHECK;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT);
|
||||
@@ -150,11 +150,11 @@ void ccplex_powergate_cpu0()
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_SET) = BIT(CLK_V_MSELECT);
|
||||
|
||||
// Disable CE0.
|
||||
pmc_enable_partition(POWER_RAIL_CE0, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CE0, DISABLE);
|
||||
// Disable cluster 0 non-CPU.
|
||||
pmc_enable_partition(POWER_RAIL_C0NC, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_C0NC, DISABLE);
|
||||
// Disable CPU rail.
|
||||
pmc_enable_partition(POWER_RAIL_CRAIL, DISABLE);
|
||||
pmc_domain_pwrgate_set(POWER_RAIL_CRAIL, DISABLE);
|
||||
|
||||
clock_disable_coresight();
|
||||
|
||||
|
||||
239
bdk/soc/clock.c
239
bdk/soc/clock.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 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,6 +23,14 @@
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sdmmc.h>
|
||||
|
||||
typedef struct _clk_rst_mgd_t
|
||||
{
|
||||
u16 reset;
|
||||
u16 enable;
|
||||
u16 source;
|
||||
u8 index;
|
||||
} clk_rst_mgd_t;
|
||||
|
||||
typedef struct _clock_osc_t
|
||||
{
|
||||
u32 freq;
|
||||
@@ -40,6 +48,15 @@ static const clock_osc_t _clock_osc_cnt[] = {
|
||||
{ 48000, 2836, 3023 }
|
||||
};
|
||||
|
||||
/* clk_rst_mgd_t: reset, enable, source, index */
|
||||
|
||||
static const clk_rst_mgd_t _clock_sdmmc[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1, CLK_L_SDMMC1 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2, CLK_L_SDMMC2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3, CLK_U_SDMMC3 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4, CLK_L_SDMMC4 },
|
||||
};
|
||||
|
||||
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clk_rst_t _clock_uart[] = {
|
||||
@@ -61,12 +78,12 @@ static const clk_rst_t _clock_i2c[] = {
|
||||
};
|
||||
|
||||
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, CLK_SRC_DIV(1) // 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) // 408 MHz. 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, CLK_SRC_DIV(1)
|
||||
};
|
||||
static clk_rst_t _clock_host1x = {
|
||||
static clk_rst_t _clock_host1x = { // Has idle divisor.
|
||||
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: 408 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_tsec = {
|
||||
@@ -78,11 +95,11 @@ static clk_rst_t _clock_nvdec = {
|
||||
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, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
|
||||
};
|
||||
static clk_rst_t _clock_vic = {
|
||||
static clk_rst_t _clock_vic = { // Has idle divisor.
|
||||
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.8 MHz.
|
||||
};
|
||||
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, CLK_SRC_DIV(1)
|
||||
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) // 24 MHz.
|
||||
};
|
||||
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, CLK_SRC_DIV(1)
|
||||
@@ -124,14 +141,14 @@ static clk_rst_t _clock_extperiph2 = {
|
||||
void clock_enable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->reset) |= BIT(clk->index);
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
// Configure clock source if required.
|
||||
if (clk->source)
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29u);
|
||||
CLOCK(clk->source) = (clk->clk_src << 29u) | clk->clk_div;
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->enable) |= BIT(clk->index);
|
||||
usleep(2);
|
||||
|
||||
// Take clock off reset.
|
||||
@@ -141,7 +158,7 @@ void clock_enable(const clk_rst_t *clk)
|
||||
void clock_disable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
CLOCK(clk->reset) |= BIT(clk->index);
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
}
|
||||
@@ -215,6 +232,9 @@ void clock_enable_tzram()
|
||||
void clock_enable_host1x()
|
||||
{
|
||||
clock_enable(&_clock_host1x);
|
||||
|
||||
// Set idle frequency to 81.6 MHz.
|
||||
// CLOCK(_clock_host1x.clk_src) |= CLK_SRC_DIV(5) << 8;
|
||||
}
|
||||
|
||||
void clock_disable_host1x()
|
||||
@@ -259,6 +279,9 @@ void clock_enable_vic()
|
||||
|
||||
clock_enable(&_clock_vic);
|
||||
|
||||
// Set idle frequency to 136 MHz.
|
||||
// CLOCK(_clock_vic.clk_src) |= CLK_SRC_DIV(3) << 8;
|
||||
|
||||
// Restore sys clock.
|
||||
bpmp_clk_rate_relaxed(false);
|
||||
}
|
||||
@@ -421,17 +444,23 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
|
||||
|
||||
// Set dividers and enable PLLD.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLL_BASE_ENABLE | PLL_BASE_LOCK | plld_div;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP.
|
||||
|
||||
// Set PLLD_SDM_DIN and enable PLLD to DSI pads.
|
||||
// Set PLLD_SDM_DIN and enable (T210) PLLD to DSI pads.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc;
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) & PLL_BASE_LOCK))
|
||||
;
|
||||
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
void clock_enable_pllx()
|
||||
{
|
||||
// Configure and enable PLLX if disabled.
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE.
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLL_BASE_ENABLE)) // PLLX_ENABLE.
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
||||
usleep(2);
|
||||
@@ -440,18 +469,20 @@ void clock_enable_pllx()
|
||||
const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz.
|
||||
|
||||
// Bypass dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | pllx_div_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_BYPASS | pllx_div_cfg;
|
||||
// Disable bypass
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg;
|
||||
// Set PLLX_LOCK_ENABLE.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN;
|
||||
// Enable PLLX.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | pllx_div_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLL_BASE_ENABLE | pllx_div_cfg;
|
||||
}
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK))
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLL_BASE_LOCK))
|
||||
;
|
||||
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
void clock_enable_pllc(u32 divn)
|
||||
@@ -459,7 +490,7 @@ void clock_enable_pllc(u32 divn)
|
||||
u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF;
|
||||
|
||||
// Check if already enabled and configured.
|
||||
if ((CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_ENABLE) && (pll_divn_curr == divn))
|
||||
if ((CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLL_BASE_ENABLE) && (pll_divn_curr == divn))
|
||||
return;
|
||||
|
||||
// Take PLLC out of reset and set basic misc parameters.
|
||||
@@ -468,7 +499,7 @@ void clock_enable_pllc(u32 divn)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) &= ~PLLC_MISC1_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
@@ -476,8 +507,8 @@ void clock_enable_pllc(u32 divn)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) = (divn << 10) | 4; // DIVM: 4, DIVP: 1.
|
||||
|
||||
// Enable PLLC and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLLCX_BASE_LOCK))
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLL_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) & PLL_BASE_LOCK))
|
||||
;
|
||||
|
||||
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
||||
@@ -493,7 +524,7 @@ void clock_disable_pllc()
|
||||
// Disable PLLC and PLLC_OUT1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM.
|
||||
usleep(10);
|
||||
@@ -515,7 +546,7 @@ static void _clock_enable_pllc4(u32 mask)
|
||||
//CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
|
||||
|
||||
// Disable PLL and IDDQ in case they are on.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLC4_BASE_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
@@ -523,8 +554,8 @@ static void _clock_enable_pllc4(u32 mask)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||
|
||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLLCX_BASE_LOCK))
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLL_BASE_ENABLE;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLL_BASE_LOCK))
|
||||
;
|
||||
|
||||
msleep(1); // Wait a bit for PLL to stabilize.
|
||||
@@ -542,7 +573,7 @@ static void _clock_disable_pllc4(u32 mask)
|
||||
|
||||
// Disable PLLC4.
|
||||
msleep(1); // Wait at least 1ms to prevent glitching.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLL_BASE_ENABLE;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLC4_BASE_IDDQ;
|
||||
usleep(10);
|
||||
|
||||
@@ -555,11 +586,11 @@ void clock_enable_pllu()
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= BIT(29); // Disable reference clock.
|
||||
u32 pllu_cfg = (CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & 0xFFE00000) | BIT(24) | (1 << 16) | (0x19 << 8) | 2;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLL_BASE_ENABLE; // Enable.
|
||||
|
||||
// Wait for PLL to stabilize.
|
||||
u32 timeout = get_tmr_us() + 1300;
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
|
||||
while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLL_BASE_LOCK)) // PLL_LOCK.
|
||||
if (get_tmr_us() > timeout)
|
||||
break;
|
||||
usleep(10);
|
||||
@@ -593,115 +624,50 @@ void clock_enable_utmipll()
|
||||
|
||||
static int _clock_sdmmc_is_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
return CLOCK(clk->reset) & BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->reset) |= BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||
}
|
||||
|
||||
static int _clock_sdmmc_is_enabled(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC1);
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC2);
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & BIT(CLK_U_SDMMC3);
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC4);
|
||||
}
|
||||
return 0;
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
return CLOCK(clk->enable) & BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->enable) |= BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC1);
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC2);
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_SDMMC3);
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC4);
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
|
||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
const clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
@@ -709,7 +675,7 @@ static void _clock_sdmmc_config_legacy_tm()
|
||||
typedef struct _clock_sdmmc_t
|
||||
{
|
||||
u32 clock;
|
||||
u32 real_clock;
|
||||
u32 pclock;
|
||||
} clock_sdmmc_t;
|
||||
|
||||
static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||
@@ -719,7 +685,7 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 clock)
|
||||
{
|
||||
u32 divisor = 0;
|
||||
u32 source = SDMMC_CLOCK_SRC_PLLP_OUT0;
|
||||
@@ -728,7 +694,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
return 0;
|
||||
|
||||
// Get IO clock divisor.
|
||||
switch (val)
|
||||
switch (clock)
|
||||
{
|
||||
case 25000:
|
||||
*pclock = 24728;
|
||||
@@ -775,7 +741,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // CLK RST divisor is ignored.
|
||||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
@@ -791,8 +757,8 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
#endif
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[id].clock = val;
|
||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
||||
_clock_sdmmc_table[id].clock = clock;
|
||||
_clock_sdmmc_table[id].pclock = *pclock;
|
||||
|
||||
// Enable PLLC4 if in use by any SDMMC.
|
||||
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||
@@ -802,40 +768,30 @@ 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 << 29u) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
|
||||
break;
|
||||
}
|
||||
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
|
||||
CLOCK(clk->source) = (source << 29u) | divisor;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val)
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock)
|
||||
{
|
||||
if (_clock_sdmmc_table[id].clock == val)
|
||||
if (_clock_sdmmc_table[id].clock == clock)
|
||||
{
|
||||
*pclock = _clock_sdmmc_table[id].real_clock;
|
||||
*pclock = _clock_sdmmc_table[id].pclock;
|
||||
}
|
||||
else
|
||||
{
|
||||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_config_clock_host(pclock, id, val);
|
||||
|
||||
_clock_sdmmc_config_clock_host(pclock, id, clock);
|
||||
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_set_enable(id);
|
||||
|
||||
// Commit changes.
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
}
|
||||
@@ -918,18 +874,17 @@ int clock_sdmmc_is_not_reset_and_enabled(u32 id)
|
||||
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
|
||||
}
|
||||
|
||||
void clock_sdmmc_enable(u32 id, u32 val)
|
||||
void clock_sdmmc_enable(u32 id, u32 clock)
|
||||
{
|
||||
u32 clock = 0;
|
||||
|
||||
if (_clock_sdmmc_is_enabled(id))
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
||||
_clock_sdmmc_config_clock_host(&clock, id, clock);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
|
||||
// // Commit changes and wait 100 cycles for reset and for clocks to stabilize.
|
||||
_clock_sdmmc_is_reset(id);
|
||||
// Wait 100 cycles for reset and for clocks to stabilize.
|
||||
usleep((100 * 1000 + clock - 1) / clock);
|
||||
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
|
||||
230
bdk/soc/clock.h
230
bdk/soc/clock.h
@@ -172,18 +172,14 @@
|
||||
#define CLK_NOT_USED 0x0
|
||||
|
||||
/*! PLL control and status bits */
|
||||
#define PLLX_BASE_LOCK BIT(27)
|
||||
#define PLLX_BASE_REF_DIS BIT(29)
|
||||
#define PLLX_BASE_ENABLE BIT(30)
|
||||
#define PLLX_BASE_BYPASS BIT(31)
|
||||
#define PLL_BASE_LOCK BIT(27)
|
||||
#define PLL_BASE_REF_DIS BIT(29)
|
||||
#define PLL_BASE_ENABLE BIT(30)
|
||||
#define PLL_BASE_BYPASS BIT(31)
|
||||
|
||||
#define PLLX_MISC_LOCK_EN BIT(18)
|
||||
#define PLLX_MISC3_IDDQ BIT(3)
|
||||
|
||||
#define PLLCX_BASE_LOCK BIT(27)
|
||||
#define PLLCX_BASE_REF_DIS BIT(29)
|
||||
#define PLLCX_BASE_ENABLE BIT(30)
|
||||
#define PLLCX_BASE_BYPASS BIT(31)
|
||||
|
||||
#define PLLA_OUT0_RSTN_CLR BIT(0)
|
||||
#define PLLA_OUT0_CLKEN BIT(1)
|
||||
#define PLLA_BASE_IDDQ BIT(25)
|
||||
@@ -473,38 +469,32 @@ typedef enum _clock_pto_id_t
|
||||
|
||||
enum CLK_L_DEV
|
||||
{
|
||||
CLK_L_CPU = 0, // Only reset. Deprecated.
|
||||
CLK_L_CPU = 0, // Deprecated.
|
||||
CLK_L_BPMP = 1, // Only reset.
|
||||
CLK_L_SYS = 2, // Only reset.
|
||||
CLK_L_ISPB = 3,
|
||||
CLK_L_RTC = 4,
|
||||
CLK_L_RTC = 4, // Only enable.
|
||||
CLK_L_TMR = 5,
|
||||
CLK_L_UARTA = 6,
|
||||
CLK_L_UARTB = 7,
|
||||
CLK_L_GPIO = 8,
|
||||
CLK_L_SDMMC2 = 9,
|
||||
CLK_L_SPDIF = 10,
|
||||
CLK_L_I2S2 = 11, // I2S1
|
||||
CLK_L_SPDIF = 10, // Only enable.
|
||||
CLK_L_I2S2 = 11, // Only enable.
|
||||
CLK_L_I2C1 = 12,
|
||||
CLK_L_NDFLASH = 13, // HIDDEN.
|
||||
CLK_L_SDMMC1 = 14,
|
||||
CLK_L_SDMMC4 = 15,
|
||||
CLK_L_TWC = 16, // HIDDEN.
|
||||
CLK_L_TWC = 16, // 3-Wire Controller. Deprecated.
|
||||
CLK_L_PWM = 17,
|
||||
CLK_L_I2S3 = 18,
|
||||
CLK_L_EPP = 19, // HIDDEN.
|
||||
CLK_L_I2S3 = 18, // Only enable.
|
||||
CLK_L_VI = 20,
|
||||
CLK_L_2D = 21, // HIDDEN.
|
||||
CLK_L_USBD = 22,
|
||||
CLK_L_ISP = 23,
|
||||
CLK_L_3D = 24, // HIDDEN.
|
||||
CLK_L_IDE = 25, // RESERVED.
|
||||
CLK_L_DISP2 = 26,
|
||||
CLK_L_DISP1 = 27,
|
||||
CLK_L_HOST1X = 28,
|
||||
CLK_L_VCP = 29, // HIDDEN.
|
||||
CLK_L_I2S1 = 30, // I2S0
|
||||
CLK_L_BPMP_CACHE_CTRL = 31, // CONTROLLER
|
||||
CLK_L_I2S1 = 30, // Only enable.
|
||||
CLK_L_BPMP_CACHE_CTRL = 31, // Controller.
|
||||
};
|
||||
|
||||
enum CLK_H_DEV
|
||||
@@ -512,70 +502,52 @@ enum CLK_H_DEV
|
||||
CLK_H_MEM = 0, // MC.
|
||||
CLK_H_AHBDMA = 1,
|
||||
CLK_H_APBDMA = 2,
|
||||
//CLK_H_ = 3,
|
||||
CLK_H_KBC = 4, // HIDDEN.
|
||||
CLK_H_STAT_MON = 5,
|
||||
CLK_H_PMC = 6,
|
||||
CLK_H_PMC = 6, // Only enable.
|
||||
CLK_H_FUSE = 7,
|
||||
CLK_H_KFUSE = 8,
|
||||
CLK_H_SPI1 = 9,
|
||||
CLK_H_SNOR = 10, // HIDDEN.
|
||||
CLK_H_JTAG2TBC = 11,
|
||||
CLK_H_SPI2 = 12,
|
||||
CLK_H_XIO = 13, // HIDDEN.
|
||||
CLK_H_XIO = 13, // Misc IO. Deprecated?
|
||||
CLK_H_SPI3 = 14,
|
||||
CLK_H_I2C5 = 15,
|
||||
CLK_H_DSI = 16,
|
||||
CLK_H_TVO = 17, // RESERVED.
|
||||
CLK_H_HSI = 18, // HIDDEN.
|
||||
CLK_H_HDMI = 19, // HIDDEN.
|
||||
CLK_H_CSI = 20,
|
||||
CLK_H_TVDAC = 21, // RESERVED.
|
||||
CLK_H_I2C2 = 22,
|
||||
CLK_H_UARTC = 23,
|
||||
CLK_H_MIPI_CAL = 24,
|
||||
CLK_H_EMC = 25,
|
||||
CLK_H_USB2 = 26,
|
||||
CLK_H_USB3 = 27, // HIDDEN.
|
||||
CLK_H_MPE = 28, // HIDDEN.
|
||||
CLK_H_VDE = 29, // HIDDEN.
|
||||
CLK_H_BSEA = 30, // HIDDEN.
|
||||
CLK_H_BSEV = 31,
|
||||
};
|
||||
|
||||
enum CLK_U_DEV
|
||||
{
|
||||
CLK_U_SPEEDO = 0, // RESERVED.
|
||||
//CLK_U_SPEEDO = 0, // RESERVED. Old speedo ring oscillator.
|
||||
CLK_U_UARTD = 1,
|
||||
CLK_U_UARTE = 2, // HIDDEN.
|
||||
CLK_U_I2C3 = 3,
|
||||
CLK_U_SPI4 = 4,
|
||||
CLK_U_SDMMC3 = 5,
|
||||
CLK_U_PCIE = 6,
|
||||
CLK_U_OWR = 7, // RESERVED.
|
||||
CLK_U_OWR = 7, // 1-Wire Controller. Deprecated.
|
||||
CLK_U_AFI = 8,
|
||||
CLK_U_CSITE = 9,
|
||||
CLK_U_PCIEXCLK = 10, // Only reset.
|
||||
CLK_U_BPMPUCQ = 11, // HIDDEN.
|
||||
CLK_U_LA = 12,
|
||||
CLK_U_TRACECLKIN = 13, // HIDDEN.
|
||||
CLK_U_LA = 12, // DFD.
|
||||
CLK_U_SOC_THERM = 14,
|
||||
CLK_U_DTV = 15,
|
||||
CLK_U_NAND_SPEED = 16, // HIDDEN.
|
||||
CLK_U_DTV = 15, // Deprecated.
|
||||
CLK_U_I2C_SLOW = 17,
|
||||
CLK_U_DSIB = 18,
|
||||
CLK_U_TSEC = 19,
|
||||
CLK_U_IRAMA = 20,
|
||||
CLK_U_IRAMB = 21,
|
||||
CLK_U_IRAMC = 22,
|
||||
CLK_U_IRAMA = 20, // Only enable.
|
||||
CLK_U_IRAMB = 21, // Only enable.
|
||||
CLK_U_IRAMC = 22, // Only enable.
|
||||
CLK_U_IRAMD = 23, // EMUCIF ON RESET
|
||||
CLK_U_BPMP_CACHE_RAM = 24,
|
||||
CLK_U_BPMP_CACHE_RAM = 24, // Only enable.
|
||||
CLK_U_XUSB_HOST = 25,
|
||||
CLK_U_CLK_M_DOUBLER = 26,
|
||||
CLK_U_MSENC = 27, // HIDDEN.
|
||||
CLK_U_SUS_OUT = 28,
|
||||
CLK_U_DEV2_OUT = 29,
|
||||
CLK_U_DEV1_OUT = 30,
|
||||
CLK_U_SUS_OUT = 28, // Only enable. VI MCLK. Deprecated?
|
||||
CLK_U_DEV2_OUT = 29, // Only enable. DAP MCLK. Deprecated?
|
||||
CLK_U_DEV1_OUT = 30, // Only enable. DAP MCLK. Deprecated?
|
||||
CLK_U_XUSB_DEV = 31,
|
||||
};
|
||||
|
||||
@@ -583,133 +555,109 @@ enum CLK_V_DEV
|
||||
{
|
||||
CLK_V_CPUG = 0,
|
||||
CLK_V_CPULP = 1, // Reserved.
|
||||
CLK_V_3D2 = 2, // HIDDEN.
|
||||
CLK_V_MSELECT = 3,
|
||||
CLK_V_TSENSOR = 4,
|
||||
CLK_V_I2S4 = 5,
|
||||
CLK_V_I2S5 = 6,
|
||||
CLK_V_TSENSOR = 4, // Only enable.
|
||||
CLK_V_I2S4 = 5, // Only enable.
|
||||
CLK_V_I2S5 = 6, // Only enable.
|
||||
CLK_V_I2C4 = 7,
|
||||
CLK_V_SPI5 = 8, // HIDDEN.
|
||||
CLK_V_SPI6 = 9, // HIDDEN.
|
||||
CLK_V_AHUB = 10, // AUDIO.
|
||||
CLK_V_APB2APE = 11, // APBIF.
|
||||
CLK_V_DAM0 = 12, // HIDDEN.
|
||||
CLK_V_DAM1 = 13, // HIDDEN.
|
||||
CLK_V_DAM2 = 14, // HIDDEN.
|
||||
CLK_V_AHUB = 10, // AUDIO. Only enable.
|
||||
CLK_V_APB2APE = 11, // APBIF. Only enable.
|
||||
CLK_V_HDA2CODEC_2X = 15,
|
||||
CLK_V_ATOMICS = 16,
|
||||
//CLK_V_ = 17,
|
||||
//CLK_V_ = 18,
|
||||
//CLK_V_ = 19,
|
||||
//CLK_V_ = 20,
|
||||
//CLK_V_ = 21,
|
||||
CLK_V_SPDIF_DOUBLER = 22,
|
||||
CLK_V_SPDIF_DOUBLER = 22, // Only enable.
|
||||
CLK_V_ACTMON = 23,
|
||||
CLK_V_EXTPERIPH1 = 24,
|
||||
CLK_V_EXTPERIPH2 = 25,
|
||||
CLK_V_EXTPERIPH3 = 26,
|
||||
CLK_V_SATA_OOB = 27,
|
||||
CLK_V_SATA = 28,
|
||||
CLK_V_SATA_OOB = 27, // Only on T210.
|
||||
CLK_V_SATA = 28, // Only on T210.
|
||||
CLK_V_HDA = 29,
|
||||
CLK_V_TZRAM = 30, // HIDDEN.
|
||||
CLK_V_SE = 31, // HIDDEN.
|
||||
CLK_V_TZRAM = 30,
|
||||
CLK_V_SE = 31,
|
||||
};
|
||||
|
||||
enum CLK_W_DEV
|
||||
{
|
||||
CLK_W_HDA2HDMICODEC = 0,
|
||||
CLK_W_RESERVED0 = 1, //satacoldrstn
|
||||
CLK_W_PCIERX0 = 2,
|
||||
CLK_W_PCIERX1 = 3,
|
||||
CLK_W_PCIERX2 = 4,
|
||||
CLK_W_PCIERX3 = 5,
|
||||
CLK_W_PCIERX4 = 6,
|
||||
CLK_W_PCIERX5 = 7,
|
||||
CLK_W_SATACOLD = 1, // Enable reserved. Unused.
|
||||
CLK_W_PCIERX0 = 2, // Reset reserved.
|
||||
CLK_W_PCIERX1 = 3, // Reset reserved.
|
||||
CLK_W_PCIERX2 = 4, // Reset reserved.
|
||||
CLK_W_PCIERX3 = 5, // Reset reserved.
|
||||
CLK_W_PCIERX4 = 6, // Reset reserved.
|
||||
CLK_W_PCIERX5 = 7, // Reset reserved.
|
||||
CLK_W_CEC = 8,
|
||||
CLK_W_PCIE2_IOBIST = 9,
|
||||
CLK_W_EMC_IOBIST = 10,
|
||||
CLK_W_HDMI_IOBIST = 11, // HIDDEN.
|
||||
CLK_W_SATA_IOBIST = 12,
|
||||
CLK_W_MIPI_IOBIST = 13,
|
||||
CLK_W_PCIE2_IOBIST = 9, // Reset reserved.
|
||||
CLK_W_EMC_IOBIST = 10, // Reset reserved.
|
||||
CLK_W_SATA_IOBIST = 12, // Reset reserved.
|
||||
CLK_W_MIPI_IOBIST = 13, // Reset reserved.
|
||||
CLK_W_XUSB_PADCTL = 14, // Only reset.
|
||||
CLK_W_XUSB = 15,
|
||||
CLK_W_CILAB = 16,
|
||||
CLK_W_CILCD = 17,
|
||||
CLK_W_CILEF = 18,
|
||||
CLK_W_DSIA_LP = 19,
|
||||
CLK_W_DSIB_LP = 20,
|
||||
CLK_W_XUSB = 15, // Only enable.
|
||||
CLK_W_CILAB = 16, // Only enable.
|
||||
CLK_W_CILCD = 17, // Only enable.
|
||||
CLK_W_CILEF = 18, // Only enable.
|
||||
CLK_W_DSIA_LP = 19, // Only enable.
|
||||
CLK_W_DSIB_LP = 20, // Only enable.
|
||||
CLK_W_ENTROPY = 21,
|
||||
CLK_W_DDS = 22, // HIDDEN.
|
||||
//CLK_W_ = 23,
|
||||
CLK_W_DP2 = 24, // HIDDEN.
|
||||
CLK_W_AMX0 = 25, // HIDDEN.
|
||||
CLK_W_ADX0 = 26, // HIDDEN.
|
||||
CLK_W_DVFS = 27,
|
||||
CLK_W_XUSB_SS = 28,
|
||||
CLK_W_EMC_LATENCY = 29,
|
||||
CLK_W_MC1 = 30,
|
||||
//CLK_W_ = 31,
|
||||
CLK_W_EMC_LATENCY = 29, // Only enable.
|
||||
CLK_W_MC1 = 30, // Only enable.
|
||||
};
|
||||
|
||||
enum CLK_X_DEV
|
||||
{
|
||||
CLK_X_SPARE = 0,
|
||||
CLK_X_DMIC1 = 1,
|
||||
CLK_X_DMIC2 = 2,
|
||||
CLK_X_ETR = 3,
|
||||
CLK_X_CAM_MCLK = 4,
|
||||
CLK_X_CAM_MCLK2 = 5,
|
||||
CLK_X_DMIC1 = 1, // Only enable.
|
||||
CLK_X_DMIC2 = 2, // Only enable.
|
||||
CLK_X_ETR = 3, // DFD.
|
||||
CLK_X_CAM_MCLK = 4, // Only enable.
|
||||
CLK_X_CAM_MCLK2 = 5, // Only enable.
|
||||
CLK_X_I2C6 = 6,
|
||||
CLK_X_MC_CAPA = 7, // MC DAISY CHAIN1
|
||||
CLK_X_MC_CBPA = 8, // MC DAISY CHAIN2
|
||||
CLK_X_MC_CPU = 9,
|
||||
CLK_X_MC_BBC = 10,
|
||||
CLK_X_VIM2_CLK = 11,
|
||||
//CLK_X_ = 12,
|
||||
CLK_X_MIPIBIF = 13, //RESERVED
|
||||
CLK_X_EMC_DLL = 14,
|
||||
//CLK_X_ = 15,
|
||||
CLK_X_HDMI_AUDIO = 16, // HIDDEN.
|
||||
CLK_X_UART_FST_MIPI_CAL = 17,
|
||||
CLK_X_MC_CAPA = 7, // MC Clients daisy chain 1. Only enable.
|
||||
CLK_X_MC_CBPA = 8, // MC Clients daisy chain 2. Only enable.
|
||||
CLK_X_MC_CPU = 9, // MC CPU. Only enable.
|
||||
CLK_X_MC_BBC = 10, // MC Backbone. Only enable.
|
||||
CLK_X_VIM2_CLK = 11, // Only enable.
|
||||
CLK_X_MIPIBIF = 13,
|
||||
CLK_X_EMC_DLL = 14, // Only enable.
|
||||
CLK_X_UART_FST_MIPI_CAL = 17, // Only enable.
|
||||
CLK_X_VIC = 18,
|
||||
//CLK_X_ = 19,
|
||||
CLK_X_ADX1 = 20, // HIDDEN.
|
||||
CLK_X_DPAUX = 21,
|
||||
CLK_X_SOR0 = 22,
|
||||
CLK_X_SOR1 = 23,
|
||||
CLK_X_GPU = 24,
|
||||
CLK_X_DBGAPB = 25,
|
||||
CLK_X_HPLL_ADSP = 26,
|
||||
CLK_X_PLLP_ADSP = 27,
|
||||
CLK_X_PLLA_ADSP = 28,
|
||||
CLK_X_PLLG_REF = 29,
|
||||
//CLK_X_ = 30,
|
||||
//CLK_X_ = 31,
|
||||
CLK_X_DBGAPB = 25, // Only enable.
|
||||
CLK_X_HPLL_ADSP = 26, // Only enable.
|
||||
CLK_X_PLLP_ADSP = 27, // Only enable.
|
||||
CLK_X_PLLA_ADSP = 28, // Only enable.
|
||||
CLK_X_PLLG_REF = 29, // Only enable.
|
||||
CLK_X_EQOS = 30, // T210B01 only.
|
||||
};
|
||||
|
||||
enum CLK_Y_DEV
|
||||
{
|
||||
CLK_Y_SPARE1 = 0,
|
||||
CLK_Y_SDMMC_LEGACY_TM = 1,
|
||||
CLK_Y_SDMMC_LEGACY_TM = 1, // Only enable.
|
||||
CLK_Y_NVDEC = 2,
|
||||
CLK_Y_NVJPG = 3,
|
||||
CLK_Y_AXIAP = 4,
|
||||
CLK_Y_DMIC3 = 5,
|
||||
CLK_Y_AXIAP = 4, // DFD.
|
||||
CLK_Y_DMIC3 = 5, // Only enable.
|
||||
CLK_Y_APE = 6,
|
||||
CLK_Y_ADSP = 7,
|
||||
CLK_Y_MC_CDPA = 8, // MC DAISY CHAIN4
|
||||
CLK_Y_MC_CCPA = 9, // MC DAISY CHAIN3
|
||||
CLK_Y_MAUD = 10,
|
||||
//CLK_Y_ = 11,
|
||||
CLK_Y_MC_CDPA = 8, // MC Clients daisy chain 4. Only enable.
|
||||
CLK_Y_MC_CCPA = 9, // MC Clients daisy chain 3. Only enable.
|
||||
CLK_Y_MAUD = 10, // Only enable.
|
||||
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
|
||||
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
|
||||
CLK_Y_TSECB = 14,
|
||||
CLK_Y_DPAUX1 = 15,
|
||||
CLK_Y_VI_I2C = 16,
|
||||
CLK_Y_HSIC_TRK = 17,
|
||||
CLK_Y_USB2_TRK = 18,
|
||||
CLK_Y_HSIC_TRK = 17, // Only enable.
|
||||
CLK_Y_USB2_TRK = 18, // Only enable.
|
||||
CLK_Y_QSPI = 19,
|
||||
CLK_Y_UARTAPE = 20,
|
||||
CLK_Y_UARTAPE = 20, // Only enable.
|
||||
CLK_Y_ADSPINTF = 21, // Only reset.
|
||||
CLK_Y_ADSPPERIPH = 22, // Only reset.
|
||||
CLK_Y_ADSPDBG = 23, // Only reset.
|
||||
@@ -717,10 +665,10 @@ enum CLK_Y_DEV
|
||||
CLK_Y_ADSPSCU = 25, // Only reset.
|
||||
CLK_Y_ADSPNEON = 26,
|
||||
CLK_Y_NVENC = 27,
|
||||
CLK_Y_IQC2 = 28,
|
||||
CLK_Y_IQC1 = 29,
|
||||
CLK_Y_SOR_SAFE = 30,
|
||||
CLK_Y_PLLP_OUT_CPU = 31,
|
||||
CLK_Y_IQC2 = 28, // Only enable. (Audio.)
|
||||
CLK_Y_IQC1 = 29, // Only enable. (Audio.)
|
||||
CLK_Y_SOR_SAFE = 30, // Only enable.
|
||||
CLK_Y_PLLP_OUT_CPU = 31, // Only enable.
|
||||
};
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
@@ -790,10 +738,10 @@ void clock_enable_pllu();
|
||||
void clock_disable_pllu();
|
||||
void clock_enable_utmipll();
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val);
|
||||
void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 clock);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_enable(u32 id, u32 clock);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
u32 clock_get_osc_freq();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <mem/heap.h>
|
||||
#include <sec/se.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
@@ -88,15 +89,6 @@ u32 fuse_read_odm_keygen_rev()
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 fuse_read_bootrom_rev()
|
||||
{
|
||||
u32 rev = FUSE(FUSE_SOC_SPEEDO_1_CALIB);
|
||||
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
|
||||
return rev;
|
||||
else
|
||||
return rev | (1 << 12);
|
||||
}
|
||||
|
||||
u32 fuse_read_dramid(bool raw_id)
|
||||
{
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
@@ -182,10 +174,30 @@ void fuse_wait_idle()
|
||||
;
|
||||
}
|
||||
|
||||
void fuse_sense()
|
||||
{
|
||||
clock_enable_fuse(false);
|
||||
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & (~FUSE_CMD_MASK)) | FUSE_SENSE;
|
||||
usleep(1);
|
||||
|
||||
fuse_wait_idle();
|
||||
|
||||
FUSE(FUSE_PRIV2INTFC) = FUSE_PRIV2INTFC_SKIP_RECORDS | FUSE_PRIV2INTFC_START_DATA;
|
||||
usleep(1);
|
||||
|
||||
while (!(FUSE(FUSE_CTRL) & BIT(30)) || ((FUSE(FUSE_CTRL) >> 16) & 0x1F) != FUSE_STATUS_IDLE)
|
||||
;
|
||||
|
||||
|
||||
clock_enable_fuse(true);
|
||||
}
|
||||
|
||||
u32 fuse_read(u32 addr)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = addr;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_CTRL) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
|
||||
fuse_wait_idle();
|
||||
|
||||
return FUSE(FUSE_RDATA);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 shuffle2
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019-2023 CTCaer
|
||||
* Copyright (c) 2019-2025 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,8 +32,12 @@
|
||||
#define FUSE_TIME_PGM1 0x18
|
||||
#define FUSE_TIME_PGM2 0x1C
|
||||
#define FUSE_PRIV2INTFC 0x20
|
||||
#define FUSE_PRIV2INTFC_START_DATA BIT(0)
|
||||
#define FUSE_PRIV2INTFC_SKIP_RECORDS BIT(1)
|
||||
#define FUSE_FUSEBYPASS 0x24
|
||||
#define FUSE_PRIVATEKEYDISABLE 0x28
|
||||
#define FUSE_PRIVKEY_DISABLE BIT(0)
|
||||
#define FUSE_PRIVKEY_TZ_STICKY_BIT BIT(4)
|
||||
#define FUSE_DISABLEREGPROGRAM 0x2C
|
||||
#define FUSE_WRITE_ACCESS_SW 0x30
|
||||
#define FUSE_PWR_GOOD_SW 0x34
|
||||
@@ -113,14 +117,14 @@
|
||||
#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_TSENSOR1_CALIB 0x184 // CPU1.
|
||||
#define FUSE_TSENSOR2_CALIB 0x188 // CPU2.
|
||||
|
||||
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
|
||||
|
||||
#define FUSE_OPT_CP_REV 0x190
|
||||
#define FUSE_OPT_CP_REV 0x190 // FUSE style revision - ATE. 0x101 0x100
|
||||
#define FUSE_OPT_PFG 0x194
|
||||
#define FUSE_TSENSOR0_CALIB 0x198
|
||||
#define FUSE_TSENSOR0_CALIB 0x198 // CPU0.
|
||||
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
|
||||
#define FUSE_SECURITY_MODE 0x1A0
|
||||
#define FUSE_PRIVATE_KEY0 0x1A4
|
||||
@@ -164,22 +168,22 @@
|
||||
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
|
||||
|
||||
#define FUSE_GPU_IDDQ_CALIB 0x228
|
||||
#define FUSE_TSENSOR3_CALIB 0x22C
|
||||
#define FUSE_TSENSOR3_CALIB 0x22C // CPU3.
|
||||
#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_RESERVED_ODM28_B01 0x240 // MAX77812 phase configuration.
|
||||
|
||||
#define FUSE_OPT_SAMPLE_TYPE 0x244
|
||||
#define FUSE_OPT_SUBREVISION 0x248
|
||||
#define FUSE_OPT_SUBREVISION 0x248 // "", "p", "q", "r". e.g: A01p.
|
||||
#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_TSENSOR4_CALIB 0x254 // GPU.
|
||||
#define FUSE_TSENSOR5_CALIB 0x258 // MEM0.
|
||||
#define FUSE_TSENSOR6_CALIB 0x25C // MEM1.
|
||||
#define FUSE_TSENSOR7_CALIB 0x260 // PLLX.
|
||||
#define FUSE_OPT_PRIV_SEC_DIS 0x264
|
||||
#define FUSE_PKC_DISABLE 0x268
|
||||
|
||||
@@ -199,7 +203,7 @@
|
||||
#define FUSE_RESERVED_ODM29_B01 0x294
|
||||
|
||||
#define FUSE_APB2JTAG_DISABLE 0x298
|
||||
#define FUSE_ODM_INFO 0x29C
|
||||
#define FUSE_ODM_INFO 0x29C // Debug features disable.
|
||||
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
|
||||
|
||||
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
|
||||
@@ -210,9 +214,12 @@
|
||||
#define FUSE_WOA_SKU_FLAG 0x2C0
|
||||
#define FUSE_ECO_RESERVE_1 0x2C4
|
||||
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
|
||||
#define FUSE_GPU_VPR_AUTO_FETCH_DIS BIT(0)
|
||||
#define FUSE_GPU_VPR_ENABLED BIT(1)
|
||||
#define FUSE_GPU_WPR_ENABLED BIT(2)
|
||||
#define FUSE_PRODUCTION_MONTH 0x2CC
|
||||
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
|
||||
#define FUSE_TSENSOR9_CALIB 0x2D4
|
||||
#define FUSE_TSENSOR9_CALIB 0x2D4 // AOTAG.
|
||||
#define FUSE_VMIN_CALIBRATION 0x2DC
|
||||
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
|
||||
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
|
||||
@@ -220,8 +227,8 @@
|
||||
#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_ECO_RESERVE_0 0x2F8 // AID.
|
||||
#define FUSE_RESERVED_CALIB0 0x304 // GPCPLL ADC Calibration.
|
||||
#define FUSE_RESERVED_CALIB1 0x308
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
|
||||
@@ -239,7 +246,7 @@
|
||||
#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_RAM_SVOP_SP_B01 0x334
|
||||
|
||||
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
|
||||
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
|
||||
@@ -248,7 +255,7 @@
|
||||
#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_RESERVED_FIELD 0x354 // RMA.
|
||||
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
|
||||
#define FUSE_SPARE_BIT_0 0x380
|
||||
//...
|
||||
@@ -304,12 +311,13 @@ enum
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
u32 fuse_read_odm_keygen_rev();
|
||||
u32 fuse_read_bootrom_rev();
|
||||
u32 fuse_read_dramid(bool raw_id);
|
||||
u32 fuse_read_hw_state();
|
||||
u32 fuse_read_hw_type();
|
||||
int fuse_set_sbk();
|
||||
void fuse_wait_idle();
|
||||
void fuse_sense();
|
||||
u32 fuse_read(u32 addr);
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
void fuse_read_array(u32 *words);
|
||||
|
||||
@@ -80,7 +80,7 @@ static void _config_oscillators()
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
|
||||
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
|
||||
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
|
||||
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
APB_MISC(APB_MISC_GP_ASDBGREG) = (APB_MISC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
|
||||
@@ -155,16 +155,34 @@ static void _config_pmc_scratch()
|
||||
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
|
||||
}
|
||||
|
||||
static void _mbist_workaround()
|
||||
static void _mbist_workaround_bl()
|
||||
{
|
||||
// Make sure Audio clocks are enabled before accessing I2S.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
/*
|
||||
* DFT MBIST HW Errata for T210.
|
||||
* RAM Data corruption observed when MBIST_EN from DFT (Tegra X1 Si Errata)
|
||||
*
|
||||
* The MBIST_EN signals from the DFT logic can impact the functional logic of
|
||||
* internal rams after power-on since they are driven by non-resetable flops.
|
||||
* That can be worked around by enabling and then disabling the related clocks.
|
||||
*
|
||||
* The bootrom patches, already handle the LVL2 SLCG war by enabling all clocks
|
||||
* and all LVL2 CLK overrides (power saving disable).
|
||||
* The Bootloader then handles the IP block SLCG part and also restores the
|
||||
* state for the clocks/lvl2 slcg.
|
||||
* After these, per domain MBIST WAR is needed every time a domain gets
|
||||
* unpowergated if it was previously powergated.
|
||||
*
|
||||
* Affected power domains: all except IRAM and CCPLEX.
|
||||
*/
|
||||
|
||||
// Set mux output to SOR1 clock switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
|
||||
// Enabled PLLD and set csi to PLLD for test pattern generation.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
|
||||
// Set mux output to SOR1 clock switch (for VI).
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) & ~BIT(14)) | BIT(15);
|
||||
// Enable PLLD and set csi to PLLD for test pattern generation (for VI).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= PLL_BASE_ENABLE | BIT(23);
|
||||
|
||||
// Make sure Audio clocks are enabled before accessing I2S.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||
|
||||
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
|
||||
@@ -172,56 +190,53 @@ static void _mbist_workaround()
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
usleep(2);
|
||||
|
||||
// I2S channels to master and disable SLCG.
|
||||
I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
|
||||
|
||||
// Set SLCG overrides.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
|
||||
// Set I2S to master to enable clocks and set SLCG overrides.
|
||||
for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||
{
|
||||
I2S(I2S_CTRL + (i2s_idx << 8u)) |= I2S_CTRL_MASTER_EN;
|
||||
I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_DISABLE;
|
||||
}
|
||||
// Set SLCG overrides for DISPA and VIC.
|
||||
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= BIT(2); // DSC_SLCG_OVERRIDE.
|
||||
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
|
||||
|
||||
// Wait a bit for MBIST_EN to get unstuck (1 cycle min).
|
||||
usleep(2);
|
||||
|
||||
// Reset SLCG to automatic mode.
|
||||
// for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
|
||||
// I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_ENABLE;
|
||||
// DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) &= ~BIT(2); // DSC_SLCG_OVERRIDE.
|
||||
// VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0;
|
||||
|
||||
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
|
||||
|
||||
// Enable specific clocks and disable all others.
|
||||
// Disable all unneeded clocks that were enabled in bootrom.
|
||||
// CLK L Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
|
||||
BIT(CLK_H_PMC) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = BIT(CLK_H_PMC) |
|
||||
BIT(CLK_H_FUSE);
|
||||
// CLK H Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
|
||||
BIT(CLK_L_RTC) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = BIT(CLK_L_RTC) |
|
||||
BIT(CLK_L_TMR) |
|
||||
BIT(CLK_L_GPIO) |
|
||||
BIT(CLK_L_BPMP_CACHE_CTRL);
|
||||
// CLK U Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
|
||||
BIT(CLK_U_CSITE) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = BIT(CLK_U_CSITE) |
|
||||
BIT(CLK_U_IRAMA) |
|
||||
BIT(CLK_U_IRAMB) |
|
||||
BIT(CLK_U_IRAMC) |
|
||||
BIT(CLK_U_IRAMD) |
|
||||
BIT(CLK_U_BPMP_CACHE_RAM);
|
||||
// CLK V Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
|
||||
BIT(CLK_V_MSELECT) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = BIT(CLK_V_MSELECT) |
|
||||
BIT(CLK_V_APB2APE) |
|
||||
BIT(CLK_V_SPDIF_DOUBLER) |
|
||||
BIT(CLK_V_SE);
|
||||
// CLK W Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
|
||||
BIT(CLK_W_PCIERX0) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = BIT(CLK_W_PCIERX0) |
|
||||
BIT(CLK_W_PCIERX1) |
|
||||
BIT(CLK_W_PCIERX2) |
|
||||
BIT(CLK_W_PCIERX3) |
|
||||
@@ -230,8 +245,7 @@ static void _mbist_workaround()
|
||||
BIT(CLK_W_ENTROPY) |
|
||||
BIT(CLK_W_MC1);
|
||||
// CLK X Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
|
||||
BIT(CLK_X_MC_CAPA) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = BIT(CLK_X_MC_CAPA) |
|
||||
BIT(CLK_X_MC_CBPA) |
|
||||
BIT(CLK_X_MC_CPU) |
|
||||
BIT(CLK_X_MC_BBC) |
|
||||
@@ -239,11 +253,10 @@ static void _mbist_workaround()
|
||||
BIT(CLK_X_DBGAPB) |
|
||||
BIT(CLK_X_PLLG_REF);
|
||||
// CLK Y Devices.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
|
||||
BIT(CLK_Y_MC_CDPA) |
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = BIT(CLK_Y_MC_CDPA) |
|
||||
BIT(CLK_Y_MC_CCPA);
|
||||
|
||||
// Disable clock gate overrides.
|
||||
// Reset clock gate overrides to automatic mode.
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
|
||||
@@ -252,10 +265,10 @@ static void _mbist_workaround()
|
||||
|
||||
// Set child clock sources.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= ~(BIT(15) | BIT(14)); // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
|
||||
}
|
||||
|
||||
static void _config_se_brom()
|
||||
@@ -266,6 +279,9 @@ static void _config_se_brom()
|
||||
// Try to set SBK from fuses. If patched, skip.
|
||||
fuse_set_sbk();
|
||||
|
||||
// Make SBK unreadable.
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = FUSE_PRIVKEY_TZ_STICKY_BIT | FUSE_PRIVKEY_DISABLE;
|
||||
|
||||
// Lock SSK (although it's not set and unused anyways).
|
||||
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
|
||||
|
||||
@@ -365,17 +381,16 @@ void hw_init()
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
|
||||
|
||||
// Bootrom stuff we skipped by going through rcm.
|
||||
// Bootrom stuff we might skipped by going through rcm.
|
||||
_config_se_brom();
|
||||
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
|
||||
|
||||
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
|
||||
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
|
||||
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
|
||||
|
||||
// Perform Memory Built-In Self Test WAR if T210.
|
||||
// Perform the bootloader part of the Memory Built-In Self Test WAR if T210.
|
||||
if (tegra_t210)
|
||||
_mbist_workaround();
|
||||
_mbist_workaround_bl();
|
||||
|
||||
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
|
||||
@@ -422,9 +437,10 @@ void hw_init()
|
||||
// Set BPMP/SCLK to PLLP_OUT (408MHz).
|
||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
|
||||
|
||||
// Power on T210B01 shadow TZRAM and lock the reg.
|
||||
// Disable T210B01 TZRAM power-gating and lock the reg.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
// This is not actually needed since it's done by bootrom. The read locks are extra.
|
||||
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
|
||||
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
|
||||
@@ -482,11 +498,11 @@ void hw_deinit(bool coreboot, u32 bl_magic)
|
||||
// Reset arbiter.
|
||||
hw_config_arbiter(true);
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to rerunning mbist war.
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
|
||||
}
|
||||
|
||||
// Do coreboot mitigations.
|
||||
|
||||
@@ -99,17 +99,26 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask)
|
||||
}
|
||||
}
|
||||
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable)
|
||||
/*
|
||||
* !TODO: Non CCPLEX power domains power gating/ungating.
|
||||
* Power gating: clock should be in reset if enabled and then
|
||||
* pmc_domain_pwrgate_set is run.
|
||||
* Power ungating: run pmc_domain_pwrgate_set, enable clocks and keep in
|
||||
* reset, remove clamping, remove reset, run mbist war if T210 and then clocks
|
||||
* can be disabled.
|
||||
*/
|
||||
|
||||
int pmc_domain_pwrgate_set(pmc_power_rail_t part, u32 enable)
|
||||
{
|
||||
u32 part_mask = BIT(part);
|
||||
u32 desired_state = enable << part;
|
||||
|
||||
// Check if the partition has the state we want.
|
||||
// Check if the power domain has the state we want.
|
||||
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
|
||||
return 1;
|
||||
|
||||
u32 i = 5001;
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
|
||||
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & PMC_PWRGATE_TOGGLE_START)
|
||||
{
|
||||
usleep(1);
|
||||
i--;
|
||||
@@ -118,7 +127,7 @@ int pmc_enable_partition(pmc_power_rail_t part, u32 enable)
|
||||
}
|
||||
|
||||
// Toggle power gating.
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
|
||||
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | PMC_PWRGATE_TOGGLE_START;
|
||||
|
||||
i = 5001;
|
||||
while (i > 0)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define PMC_CNTRL_SHUTDOWN_OE BIT(22)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define PMC_PWRGATE_TOGGLE_START BIT(8)
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define PMC_NO_IOPOWER_MEM BIT(7)
|
||||
@@ -154,6 +155,8 @@
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
#define PMC_NX_PANIC_SAFE_MODE 0x20
|
||||
#define PMC_NX_PANIC_BYPASS_FUSES 0x21
|
||||
#define APBDEV_PMC_SCRATCH201 0x844
|
||||
#define APBDEV_PMC_SCRATCH250 0x908
|
||||
#define APBDEV_PMC_SECURE_SCRATCH108 0xB08
|
||||
@@ -217,19 +220,14 @@ typedef enum _pmc_sec_lock_t
|
||||
typedef enum _pmc_power_rail_t
|
||||
{
|
||||
POWER_RAIL_CRAIL = 0,
|
||||
POWER_RAIL_3D0 = 1,
|
||||
POWER_RAIL_VENC = 2,
|
||||
POWER_RAIL_VE = 2,
|
||||
POWER_RAIL_PCIE = 3,
|
||||
POWER_RAIL_VDEC = 4,
|
||||
POWER_RAIL_L2C = 5,
|
||||
POWER_RAIL_MPE = 6,
|
||||
POWER_RAIL_HEG = 7,
|
||||
POWER_RAIL_NVENC = 6,
|
||||
POWER_RAIL_SATA = 8,
|
||||
POWER_RAIL_CE1 = 9,
|
||||
POWER_RAIL_CE2 = 10,
|
||||
POWER_RAIL_CE3 = 11,
|
||||
POWER_RAIL_CELP = 12,
|
||||
POWER_RAIL_3D1 = 13,
|
||||
POWER_RAIL_CE0 = 14,
|
||||
POWER_RAIL_C0NC = 15,
|
||||
POWER_RAIL_C1NC = 16,
|
||||
@@ -249,6 +247,6 @@ typedef enum _pmc_power_rail_t
|
||||
} pmc_power_rail_t;
|
||||
|
||||
void pmc_scratch_lock(pmc_sec_lock_t lock_mask);
|
||||
int pmc_enable_partition(pmc_power_rail_t part, u32 enable);
|
||||
int pmc_domain_pwrgate_set(pmc_power_rail_t part, u32 enable);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define SOR1_BASE 0x54580000
|
||||
#define GPU_BASE 0x57000000
|
||||
#define GPU_USER_BASE 0x58000000
|
||||
#define PG_BASE 0x60000000
|
||||
#define RES_SEMAPH_BASE 0x60001000
|
||||
#define ARB_SEMAPH_BASE 0x60002000
|
||||
#define ARB_PRI_BASE 0x60003000
|
||||
@@ -68,6 +69,8 @@
|
||||
#define ATOMICS_BASE 0x70016000
|
||||
#define MC_BASE 0x70019000
|
||||
#define EMC_BASE 0x7001B000
|
||||
#define MC0_BASE 0x7001C000
|
||||
#define MC1_BASE 0x7001D000
|
||||
#define EMC0_BASE 0x7001E000
|
||||
#define EMC1_BASE 0x7001F000
|
||||
#define XUSB_HOST_BASE 0x70090000
|
||||
@@ -114,6 +117,7 @@
|
||||
#define SOR1(off) MMIO_REG32(SOR1_BASE, off)
|
||||
#define GPU(off) MMIO_REG32(GPU_BASE, off)
|
||||
#define GPU_USER(off) MMIO_REG32(GPU_USER_BASE, off)
|
||||
#define PG(off) MMIO_REG32(PG_BASE, off)
|
||||
#define ARB_PRI(off) MMIO_REG32(ARB_PRI_BASE, off)
|
||||
#define ICTLR(cidx, off) MMIO_REG32(ICTLR_BASE + (0x100 * (cidx)), off)
|
||||
#define TMR(off) MMIO_REG32(TMR_BASE, off)
|
||||
@@ -140,6 +144,8 @@
|
||||
#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 MC_CH0(off) MMIO_REG32(MC0_BASE, off)
|
||||
#define MC_CH1(off) MMIO_REG32(MC1_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)
|
||||
@@ -297,8 +303,10 @@
|
||||
#define IPATCH_CAM_ENTRIES 12
|
||||
|
||||
/*! I2S registers. */
|
||||
#define I2S1_CG 0x88
|
||||
#define I2S1_CTRL 0xA0
|
||||
#define I2S_CG 0x88
|
||||
#define I2S_CTRL 0xA0
|
||||
#define I2S1_CG I2S_CG
|
||||
#define I2S1_CTRL I2S_CTRL
|
||||
#define I2S2_CG 0x188
|
||||
#define I2S2_CTRL 0x1A0
|
||||
#define I2S3_CG 0x288
|
||||
@@ -307,6 +315,7 @@
|
||||
#define I2S4_CTRL 0x3A0
|
||||
#define I2S5_CG 0x488
|
||||
#define I2S5_CTRL 0x4A0
|
||||
#define I2S_CG_SLCG_DISABLE 0
|
||||
#define I2S_CG_SLCG_ENABLE BIT(0)
|
||||
#define I2S_CTRL_MASTER_EN BIT(10)
|
||||
|
||||
@@ -318,7 +327,6 @@
|
||||
/*! Special registers. */
|
||||
#define EMC_SCRATCH0 0x324
|
||||
#define EMC_HEKA_UPD BIT(30)
|
||||
#define EMC_SEPT_RUN BIT(31)
|
||||
|
||||
/*! Flow controller registers. */
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS 0x4
|
||||
@@ -377,4 +385,12 @@
|
||||
#define NVDEC_SA_KEYSLOT_OTF 0x210C
|
||||
#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118
|
||||
#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C
|
||||
|
||||
/* PG registers */
|
||||
#define PG_UP_TAG 0x0 // Changes depending on what does the reg read request.
|
||||
#define TAG_PID_CCPLEX 0x55555555
|
||||
#define TAG_PID_BPMP 0xAAAAAAAA
|
||||
#define TAG_PID_COP2 0x99999999
|
||||
#define TAG_PID_OTHER 0xCCCCCCCC
|
||||
|
||||
#endif
|
||||
|
||||
454
bdk/storage/mmc_def.h
Normal file
454
bdk/storage/mmc_def.h
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
* Copyright 2018-2021 CTCaer
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Many thanks to Alessandro Rubini and Jonathan Corbet!
|
||||
*
|
||||
* Based strongly on code by:
|
||||
*
|
||||
* Author: Yong-iL Joh <tolkien@mizi.com>
|
||||
*
|
||||
* Author: Andrew Christian
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef MMC_H
|
||||
#define MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
#define MMC_GO_IDLE_STATE 0 /* bc */
|
||||
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
|
||||
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
|
||||
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
|
||||
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
|
||||
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
|
||||
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
|
||||
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
|
||||
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
|
||||
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
|
||||
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
|
||||
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
|
||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
||||
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
|
||||
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
|
||||
|
||||
/* class 2 */
|
||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
||||
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||
|
||||
/* class 3 */
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
|
||||
|
||||
/* class 4 */
|
||||
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||
|
||||
/* class 6 */
|
||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
||||
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE 38 /* ac R1b */
|
||||
|
||||
/* class 9 */
|
||||
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
|
||||
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
|
||||
|
||||
/* class 7 */
|
||||
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
|
||||
|
||||
/* class 8 */
|
||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||
|
||||
#define MMC_VENDOR_60_CMD 60 /* Vendor Defined */
|
||||
#define MMC_VENDOR_61_CMD 61 /* Vendor Defined */
|
||||
#define MMC_VENDOR_62_CMD 62 /* Vendor Defined */
|
||||
#define MMC_VENDOR_63_CMD 63 /* Vendor Defined */
|
||||
|
||||
/* class 11 */
|
||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
|
||||
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
* MMC status in R1, for native mode (SPI bits are different)
|
||||
* Type
|
||||
* e : error bit
|
||||
* s : status bit
|
||||
* r : detected and set for the actual command response
|
||||
* x : detected and set during command execution. the host must poll
|
||||
* the card by sending status command in order to read these bits.
|
||||
* Clear condition
|
||||
* a : according to the card state
|
||||
* b : always related to the previous command. Reception of a valid
|
||||
* command will clear it (with a delay of one command)
|
||||
* c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
|
||||
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
|
||||
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
|
||||
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
|
||||
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
|
||||
#define R1_CC_ERROR (1 << 20) /* erx, c */
|
||||
#define R1_ERROR (1 << 19) /* erx, c */
|
||||
#define R1_UNDERRUN (1 << 18) /* ex, c */
|
||||
#define R1_OVERRUN (1 << 17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) ((x) & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
#define R1_APP_CMD (1 << 5) /* sr, c */
|
||||
#define R1_SKIP_STATE_CHECK (1 << 4) /* Custom state to skip expected state check */
|
||||
#define R1_AKE_SEQ_ERROR (1 << 3)
|
||||
|
||||
/* R1_CURRENT_STATE 12:9 */
|
||||
#define R1_STATE(x) ((x) << 9)
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
#define R1_STATE_STBY 3
|
||||
#define R1_STATE_TRAN 4
|
||||
#define R1_STATE_DATA 5
|
||||
#define R1_STATE_RCV 6
|
||||
#define R1_STATE_PRG 7
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
#define R1_SPI_IDLE (1 << 0)
|
||||
#define R1_SPI_ERASE_RESET (1 << 1)
|
||||
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
|
||||
#define R1_SPI_COM_CRC (1 << 3)
|
||||
#define R1_SPI_ERASE_SEQ (1 << 4)
|
||||
#define R1_SPI_ADDRESS (1 << 5)
|
||||
#define R1_SPI_PARAMETER (1 << 6)
|
||||
/* R1 bit 7 is always zero */
|
||||
#define R2_SPI_CARD_LOCKED (1 << 8)
|
||||
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
|
||||
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
|
||||
#define R2_SPI_ERROR (1 << 10)
|
||||
#define R2_SPI_CC_ERROR (1 << 11)
|
||||
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
|
||||
#define R2_SPI_WP_VIOLATION (1 << 13)
|
||||
#define R2_SPI_ERASE_PARAM (1 << 14)
|
||||
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
|
||||
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */
|
||||
#define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
|
||||
#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */
|
||||
#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
|
||||
/* (CMD11) */
|
||||
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
|
||||
/* (CMD16,17,18) */
|
||||
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
|
||||
/* (CMD20) */
|
||||
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
|
||||
/* (CMD16,24,25,26,27) */
|
||||
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
|
||||
/* (CMD32,33,34,35,36,37,38,39) */
|
||||
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
|
||||
/* (CMD28,29,30) */
|
||||
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
|
||||
/* (CMD16,CMD42) */
|
||||
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
|
||||
/* (CMD55,56,57,ACMD*) */
|
||||
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
|
||||
/* (CMD5,39,40,52,53) */
|
||||
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
|
||||
/* (CMD6,34,35,36,37,50) */
|
||||
/* (11) Reserved */
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
|
||||
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
|
||||
|
||||
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
|
||||
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
|
||||
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
|
||||
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
|
||||
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
|
||||
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
|
||||
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
|
||||
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
|
||||
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
|
||||
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
|
||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||
#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */
|
||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||
#define EXT_CSD_BKOPS_EN 163 /* R/W */
|
||||
#define EXT_CSD_BKOPS_START 164 /* W */
|
||||
#define EXT_CSD_SANITIZE_START 165 /* W */
|
||||
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
|
||||
#define EXT_CSD_RPMB_MULT 168 /* RO */
|
||||
#define EXT_CSD_FW_CONFIG 169 /* R/W */
|
||||
#define EXT_CSD_BOOT_WP 173 /* R/W */
|
||||
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
|
||||
#define EXT_CSD_PART_CONFIG 179 /* R/W */
|
||||
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
|
||||
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
|
||||
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
|
||||
#define EXT_CSD_HS_TIMING 185 /* R/W */
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
#define EXT_CSD_REV 192 /* RO */
|
||||
#define EXT_CSD_STRUCTURE 194 /* RO */
|
||||
#define EXT_CSD_CARD_TYPE 196 /* RO */
|
||||
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
|
||||
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
|
||||
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
|
||||
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
|
||||
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
|
||||
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
|
||||
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
|
||||
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
|
||||
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
|
||||
#define EXT_CSD_BOOT_MULT 226 /* RO */
|
||||
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
|
||||
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
|
||||
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
|
||||
#define EXT_CSD_TRIM_MULT 232 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
|
||||
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
|
||||
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
|
||||
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
|
||||
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
|
||||
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
|
||||
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
|
||||
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
|
||||
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
|
||||
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
|
||||
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
|
||||
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
|
||||
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
|
||||
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
|
||||
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||
|
||||
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
|
||||
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||
|
||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
|
||||
|
||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
|
||||
EXT_CSD_CARD_TYPE_HS_52)
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.8V or 3V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
||||
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
|
||||
/* SDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
||||
|
||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
|
||||
|
||||
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
|
||||
#define EXT_CSD_TIMING_HS 1 /* High speed */
|
||||
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
|
||||
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
|
||||
|
||||
#define EXT_CSD_SEC_ER_EN (1<<0)
|
||||
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
|
||||
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
|
||||
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
|
||||
|
||||
#define EXT_CSD_RST_N_EN_MASK 0x3
|
||||
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
|
||||
|
||||
#define EXT_CSD_NO_POWER_NOTIFICATION 0
|
||||
#define EXT_CSD_POWER_ON 1
|
||||
#define EXT_CSD_POWER_OFF_SHORT 2
|
||||
#define EXT_CSD_POWER_OFF_LONG 3
|
||||
|
||||
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
|
||||
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
|
||||
|
||||
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS (1<<0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
|
||||
#define EXT_CSD_PACKED_FAILURE (1<<3)
|
||||
|
||||
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_OK 0x0
|
||||
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
|
||||
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
|
||||
#define EXT_CSD_BKOPS_CRITICAL 0x3
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
|
||||
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
|
||||
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
#define MMC_DISCARD_ARG 0x00000003
|
||||
#define MMC_SECURE_TRIM1_ARG 0x80000001
|
||||
#define MMC_SECURE_TRIM2_ARG 0x80008000
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
/*
|
||||
* Vendor definitions and structs
|
||||
*/
|
||||
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
|
||||
|
||||
#endif /* MMC_H */
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc.h>
|
||||
|
||||
#define NAND_PATROL_SECTOR 0xC20
|
||||
|
||||
typedef struct _nx_emmc_cal0_spk_t
|
||||
{
|
||||
u16 unk0;
|
||||
@@ -65,13 +67,18 @@ typedef struct _nx_emmc_cal0_spk_t
|
||||
|
||||
typedef struct _nx_emmc_cal0_t
|
||||
{
|
||||
// Header.
|
||||
u32 magic; // 'CAL0'.
|
||||
u32 version;
|
||||
u32 body_size;
|
||||
u16 model;
|
||||
u16 update_cnt;
|
||||
u8 pad_crc16_0[0x10];
|
||||
u8 pad_crc16_hdr[0x10];
|
||||
|
||||
// SHA256 for body.
|
||||
u8 body_sha256[0x20];
|
||||
|
||||
// Body.
|
||||
char cfg_id1[0x1E];
|
||||
u8 crc16_pad1[2];
|
||||
u8 rsvd0[0x20];
|
||||
@@ -225,6 +232,7 @@ typedef struct _nx_emmc_cal0_t
|
||||
|
||||
// 10.0.0 and up.
|
||||
u8 console_6axis_sensor_mount_type;
|
||||
u8 crc16_pad61[0xF];
|
||||
} __attribute__((packed)) nx_emmc_cal0_t;
|
||||
|
||||
int nx_emmc_bis_read(u32 sector, u32 count, void *buff);
|
||||
|
||||
@@ -44,7 +44,7 @@ int ram_disk_init(void *ram_fs, u32 ramdisk_size)
|
||||
disk_set_info(DRIVE_RAM, SET_SECTOR_COUNT, &ramdisk_size);
|
||||
|
||||
// Unmount ramdisk.
|
||||
f_mount(NULL, "ram:", 1);
|
||||
f_unmount("ram:");
|
||||
|
||||
// Format as exFAT w/ 32KB cluster with no MBR.
|
||||
res = f_mkfs("ram:", FM_EXFAT | FM_SFD, RAMDISK_CLUSTER_SZ, buf, 0x400000);
|
||||
|
||||
@@ -227,7 +227,7 @@ static void _sd_deinit(bool deinit)
|
||||
if (sd_init_done)
|
||||
{
|
||||
if (sd_mounted)
|
||||
f_mount(NULL, "0:", 1); // Volume 0 is SD.
|
||||
f_unmount("0:"); // Volume 0 is SD.
|
||||
|
||||
if (deinit)
|
||||
{
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
#include <soc/timer.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/mmc_def.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sd_def.h>
|
||||
#include <mem/mc.h>
|
||||
#include <memory_map.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
@@ -972,7 +971,7 @@ static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
|
||||
{
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
u16 vhd_pattern = SD_VHS_27_36 | 0xAA;
|
||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_7, 0);
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||
{
|
||||
// The SD Card is version 1.X (SDSC) if there is no response.
|
||||
@@ -987,7 +986,7 @@ static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
|
||||
|
||||
// For Card version >= 2.0, parse results.
|
||||
u32 resp = 0;
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_5);
|
||||
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_7);
|
||||
|
||||
// Check if VHD was accepted and pattern was properly returned.
|
||||
if ((resp & 0xFFF) == vhd_pattern)
|
||||
@@ -1070,7 +1069,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int b
|
||||
static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
||||
{
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_TYPE_4, 0);
|
||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_TYPE_6, 0);
|
||||
|
||||
u32 timeout = get_tmr_ms() + 1500;
|
||||
|
||||
@@ -1080,7 +1079,7 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
||||
break;
|
||||
|
||||
u32 resp = 0;
|
||||
if (!sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_4))
|
||||
if (!sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_6))
|
||||
break;
|
||||
|
||||
if (resp >> 16)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <storage/mmc.h>
|
||||
#include <storage/mmc_def.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <gfx_utils.h>
|
||||
#include <power/max7762x.h>
|
||||
@@ -115,7 +115,7 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
u32 tap_val = 0;
|
||||
|
||||
if (type == SDHCI_TIMING_MMC_HS400)
|
||||
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8);
|
||||
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & ~0x3F00) | (dqs_trim_val << 8);
|
||||
|
||||
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
|
||||
|
||||
@@ -129,7 +129,7 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
|
||||
else
|
||||
tap_val = sdmmc->t210b01 ? 11 : tap_values_t210[sdmmc->id];
|
||||
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
|
||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & ~0xFF0000) | (tap_val << 16);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -437,8 +437,8 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
{
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
rsp[0] = sdmmc->regs->rspreg[0];
|
||||
break;
|
||||
|
||||
@@ -470,8 +470,8 @@ int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
|
||||
{
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_3:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
rsp[0] = sdmmc->rsp[0];
|
||||
break;
|
||||
|
||||
@@ -560,8 +560,8 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, const sdmmc_cmd_t *cmd, bool is_data_
|
||||
break;
|
||||
|
||||
case SDMMC_RSP_TYPE_1:
|
||||
case SDMMC_RSP_TYPE_4:
|
||||
case SDMMC_RSP_TYPE_5:
|
||||
case SDMMC_RSP_TYPE_6:
|
||||
case SDMMC_RSP_TYPE_7:
|
||||
if (cmd->check_busy)
|
||||
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
|
||||
else
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#define SDMMC_RSP_TYPE_1 1
|
||||
#define SDMMC_RSP_TYPE_2 2
|
||||
#define SDMMC_RSP_TYPE_3 3
|
||||
#define SDMMC_RSP_TYPE_4 4
|
||||
#define SDMMC_RSP_TYPE_5 5
|
||||
#define SDMMC_RSP_TYPE_6 4
|
||||
#define SDMMC_RSP_TYPE_7 5
|
||||
|
||||
/*! SDMMC bus widths. */
|
||||
#define SDMMC_BUS_WIDTH_1 0
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <soc/t210.h>
|
||||
#include <thermal/tmp451.h>
|
||||
|
||||
// Remote Sensor.
|
||||
u16 tmp451_get_soc_temp(bool intenger)
|
||||
{
|
||||
u8 val;
|
||||
@@ -37,6 +38,7 @@ u16 tmp451_get_soc_temp(bool intenger)
|
||||
return temp;
|
||||
}
|
||||
|
||||
// Local Sensor.
|
||||
u16 tmp451_get_pcb_temp(bool intenger)
|
||||
{
|
||||
u8 val;
|
||||
@@ -72,7 +74,7 @@ void tmp451_init()
|
||||
i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_SOC_TMP_OFL_REG, 0x80); // + 0.5 oC.
|
||||
}
|
||||
|
||||
// Set conversion rate to 32/s and make a read to update the reg.
|
||||
// Set conversion rate to 31 ms and make a read to update the reg.
|
||||
i2c_send_byte(I2C_1, TMP451_I2C_ADDR, TMP451_CNV_RATE_REG, 9);
|
||||
tmp451_get_soc_temp(false);
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ typedef struct _usb_cfg_hid_descr_t
|
||||
usb_cfg_descr_t config;
|
||||
usb_inter_descr_t interface;
|
||||
usb_hid_descr_t hid;
|
||||
usb_ep_descr_t endpoint[2];
|
||||
usb_ep_descr_t endpoint[1];
|
||||
} __attribute__((packed)) usb_cfg_hid_descr_t;
|
||||
|
||||
typedef struct _usb_dev_bot_t
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -409,10 +409,10 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
|
||||
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
|
||||
.interface.bInterfaceNumber = 0,
|
||||
.interface.bAlternateSetting = 0,
|
||||
.interface.bNumEndpoints = 2,
|
||||
.interface.bNumEndpoints = 1,
|
||||
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
|
||||
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
|
||||
.interface.bInterfaceSubClass = 0x00, // No Subclass.
|
||||
.interface.bInterfaceProtocol = 0x00, // None.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
.hid.bLength = 9,
|
||||
@@ -430,14 +430,6 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
|
||||
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[0].wMaxPacketSize = 0x200,
|
||||
.endpoint[0].bInterval = 4, // 8ms on HS.
|
||||
|
||||
/* Endpoint descriptor structure EP1 OUT */
|
||||
.endpoint[1].bLength = 7,
|
||||
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
|
||||
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
|
||||
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[1].wMaxPacketSize = 0x200,
|
||||
.endpoint[1].bInterval = 4 // 8ms on HS.
|
||||
};
|
||||
|
||||
static u8 usb_vendor_string_descriptor_hid[22] =
|
||||
@@ -478,10 +470,10 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
|
||||
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
|
||||
.interface.bInterfaceNumber = 0,
|
||||
.interface.bAlternateSetting = 0,
|
||||
.interface.bNumEndpoints = 2,
|
||||
.interface.bNumEndpoints = 1,
|
||||
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
|
||||
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
|
||||
.interface.bInterfaceSubClass = 0x00, // No Subclass.
|
||||
.interface.bInterfaceProtocol = 0x00, // None.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
.hid.bLength = 9,
|
||||
@@ -499,14 +491,6 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
|
||||
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[0].wMaxPacketSize = 0x200,
|
||||
.endpoint[0].bInterval = 3, // 4ms on HS.
|
||||
|
||||
/* Endpoint descriptor structure EP1 OUT */
|
||||
.endpoint[1].bLength = 7,
|
||||
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
|
||||
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
|
||||
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[1].wMaxPacketSize = 0x200,
|
||||
.endpoint[1].bInterval = 3 // 4ms on HS.
|
||||
};
|
||||
|
||||
usb_desc_t usb_gadget_ums_descriptors =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB Gadget HID driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -80,6 +80,8 @@ enum {
|
||||
static jc_cal_t jc_cal_ctx;
|
||||
static usb_ops_t usb_ops;
|
||||
|
||||
static void *rpt_buffer = (u8 *)USB_EP_BULK_IN_BUF_ADDR;
|
||||
|
||||
static bool _jc_calibration(const jc_gamepad_rpt_t *jc_pad)
|
||||
{
|
||||
// Calibrate left stick.
|
||||
@@ -347,10 +349,10 @@ static bool _fts_touch_read(touchpad_report_t *rpt)
|
||||
|
||||
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
|
||||
{
|
||||
u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED_CMD);
|
||||
u8 status = usb_ops.usb_device_ep1_in_write(rpt_buffer, len, NULL, USB_XFER_SYNCED_CMD);
|
||||
if (status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#EP IN传输!");
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
if (usb_ops.usbd_flush_endpoint)
|
||||
usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN);
|
||||
}
|
||||
@@ -364,12 +366,12 @@ static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
|
||||
|
||||
static bool _hid_poll_jc(usb_ctxt_t *usbs)
|
||||
{
|
||||
int res = _jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
|
||||
int res = _jc_poll(rpt_buffer);
|
||||
if (res == INPUT_POLL_EXIT)
|
||||
return true;
|
||||
|
||||
// Send HID report.
|
||||
if (res == INPUT_POLL_HAS_PACKET)
|
||||
if (res == INPUT_POLL_HAS_PACKET || usbs->idle)
|
||||
if (_hid_transfer_start(usbs, sizeof(gamepad_report_t)))
|
||||
return true; // EP Error.
|
||||
|
||||
@@ -378,7 +380,7 @@ static bool _hid_poll_jc(usb_ctxt_t *usbs)
|
||||
|
||||
static bool _hid_poll_touch(usb_ctxt_t *usbs)
|
||||
{
|
||||
_fts_touch_read((touchpad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
|
||||
_fts_touch_read(rpt_buffer);
|
||||
|
||||
// Send HID report.
|
||||
if (_hid_transfer_start(usbs, sizeof(touchpad_report_t)))
|
||||
@@ -399,6 +401,10 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
else
|
||||
xusb_device_get_ops(&usb_ops);
|
||||
|
||||
// Always push packets by default.
|
||||
//! TODO: For now only per polling rate or on change is supported.
|
||||
usbs->idle = 1;
|
||||
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
{
|
||||
polling_time = 15000;
|
||||
@@ -410,7 +416,7 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
gadget_type = USB_GADGET_HID_TOUCHPAD;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB1已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB已启动");
|
||||
|
||||
if (usb_ops.usb_device_init())
|
||||
{
|
||||
@@ -418,24 +424,32 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#等待连接中");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#正在等待连接");
|
||||
|
||||
// Initialize Control Endpoint.
|
||||
if (usb_ops.usb_device_enumerate(gadget_type))
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#等待HID上报请求中");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#正在等待HID报告请求");
|
||||
|
||||
if (usb_ops.usb_device_class_send_hid_report())
|
||||
u32 rpt_size = usbs->type == USB_HID_GAMEPAD ? sizeof(gamepad_report_t) : sizeof(touchpad_report_t);
|
||||
if (usb_ops.usb_device_class_send_hid_report(rpt_buffer, rpt_size))
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID模拟已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID仿真已启动");
|
||||
|
||||
u32 timer_sys = get_tmr_ms() + 5000;
|
||||
while (true)
|
||||
{
|
||||
u32 timer = get_tmr_us();
|
||||
|
||||
// Check for suspended USB in case the cable was pulled.
|
||||
if (usb_ops.usb_device_get_suspended())
|
||||
break; // Disconnected.
|
||||
|
||||
// Handle control endpoint.
|
||||
usb_ops.usbd_handle_ep0_ctrl_setup(&usbs->idle);
|
||||
|
||||
// Parse input device.
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
{
|
||||
@@ -448,13 +462,6 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for suspended USB in case the cable was pulled.
|
||||
if (usb_ops.usb_device_get_suspended())
|
||||
break; // Disconnected.
|
||||
|
||||
// Handle control endpoint.
|
||||
usb_ops.usbd_handle_ep0_ctrl_setup();
|
||||
|
||||
// Wait max gadget timing.
|
||||
timer = get_tmr_us() - timer;
|
||||
if (timer < polling_time)
|
||||
@@ -467,11 +474,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
}
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID已结束");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID已结束");
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#超时或已取消");
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#超时或已被取消");
|
||||
res = 1;
|
||||
|
||||
exit:
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc_driver.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/sprintf.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include <memory_map.h>
|
||||
|
||||
@@ -287,7 +286,7 @@ static void raise_exception(usbd_gadget_ums_t *ums, enum ums_state new_state)
|
||||
|
||||
static void _handle_ep0_ctrl(usbd_gadget_ums_t *ums)
|
||||
{
|
||||
if (usb_ops.usbd_handle_ep0_ctrl_setup())
|
||||
if (usb_ops.usbd_handle_ep0_ctrl_setup(NULL))
|
||||
raise_exception(ums, UMS_STATE_PROTOCOL_RESET);
|
||||
}
|
||||
|
||||
@@ -328,11 +327,11 @@ static void _transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_in);
|
||||
}
|
||||
else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED)
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN缓冲区未对齐");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN缓冲区未对齐!");
|
||||
|
||||
if (sync_timeout)
|
||||
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
|
||||
@@ -345,11 +344,11 @@ static void _transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED)
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT缓冲区未对齐!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT缓冲区未对齐!");
|
||||
|
||||
if (sync_timeout)
|
||||
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
|
||||
@@ -364,7 +363,7 @@ static void _transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctx
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
|
||||
@@ -380,7 +379,7 @@ static void _transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_in);
|
||||
}
|
||||
|
||||
@@ -393,7 +392,7 @@ static void _transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
|
||||
@@ -463,7 +462,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
}
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#读取 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#读取超出范围!主机已通知。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -515,7 +514,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
// If an error occurred, report it and its position.
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# SDMMC读取!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC读取失败!");
|
||||
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -553,7 +552,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->lun.ro)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入 - 只读!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入受阻 - 只读模式! 已通知主机。");
|
||||
ums->lun.sense_data = SS_WRITE_PROTECTED;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -577,7 +576,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
// Check that starting LBA is not past the end sector offset.
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入超出范围! 已通知主机。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -599,7 +598,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (usb_lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#写入 - 超出最后扇区!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# 写入超过最后一个扇区!");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
ums->lun.sense_data_info = usb_lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -627,7 +626,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
|
||||
s_printf(txt_buf, "#FFDD00 错误:#写入 - 通讯失败 %d!", bulk_ctxt->bulk_out_status);
|
||||
s_printf(txt_buf, "#FFDD00 错误:#写入通信失败 %d!", bulk_ctxt->bulk_out_status);
|
||||
ums->set_text(ums->label, txt_buf);
|
||||
break;
|
||||
}
|
||||
@@ -665,7 +664,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
|
||||
// If an error occurred, report it and its position.
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC写入!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC写入失败!");
|
||||
ums->lun.sense_data = SS_WRITE_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -676,7 +675,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
|
||||
// Did the host decide to stop early?
|
||||
if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#空写入");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#空写入!");
|
||||
ums->short_packet_received = 1;
|
||||
break;
|
||||
}
|
||||
@@ -692,7 +691,7 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]);
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#校验 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#验证超出范围! 已通知主机。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -731,7 +730,7 @@ DPRINTF("File read %X @ %X\n", amount, lba_offset);
|
||||
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#文件检验!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#文件验证失败!");
|
||||
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -764,7 +763,7 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
switch (ums->lun.partition)
|
||||
{
|
||||
case 0:
|
||||
strcpy((char *)buf + strlen((char *)buf), "原始");
|
||||
strcpy((char *)buf + strlen((char *)buf), "RAW");
|
||||
break;
|
||||
case EMMC_GPP + 1:
|
||||
s_printf((char *)buf + strlen((char *)buf), "GPP");
|
||||
@@ -800,7 +799,7 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
switch (ums->lun.partition)
|
||||
{
|
||||
case 0:
|
||||
s_printf((char *)buf, "%s", "SD卡原始分区");
|
||||
s_printf((char *)buf, "%s", "SD RAW");
|
||||
break;
|
||||
case EMMC_GPP + 1:
|
||||
s_printf((char *)buf, "%s%s",
|
||||
@@ -1060,7 +1059,7 @@ static int _scsi_start_stop(usbd_gadget_ums_t *ums)
|
||||
// Check if we are allowed to unload the media.
|
||||
if (ums->lun.prevent_medium_removal)
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#卸载尝试已被阻止");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#尝试卸载被阻止");
|
||||
ums->lun.sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -1468,7 +1467,7 @@ static int _finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_set_ep_stall(bulk_ctxt->bulk_out);
|
||||
rc = _set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#方向不明。两端EP已暂停!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#方向未知。已停止两个端口!");
|
||||
} // Else do nothing.
|
||||
break;
|
||||
|
||||
@@ -1489,7 +1488,7 @@ static int _finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA);
|
||||
rc = _set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#数据残留。EP IN已停止!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#残留。已停止端口IN!");
|
||||
}
|
||||
else
|
||||
rc = _pad_with_zeros(ums, bulk_ctxt);
|
||||
@@ -1562,7 +1561,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
if (usb_ops.usb_device_get_port_in_sleep())
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#EP已休眠");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#端口休眠中");
|
||||
ums->timeouts += 14;
|
||||
}
|
||||
else if (!ums->xusb) // Timeout only on USB2.
|
||||
@@ -1581,7 +1580,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->lun.unmounted)
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#介质未挂载");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:# 介质已卸载");
|
||||
ums->timeouts++;
|
||||
if (!bulk_ctxt->bulk_out_status)
|
||||
ums->timeouts += 3;
|
||||
@@ -1633,7 +1632,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_set_ep_stall(bulk_ctxt->bulk_out);
|
||||
_set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#CBW未知 - 两端EP已停止!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#CBW未知 - 已停止两个端口!");
|
||||
}
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -1712,7 +1711,7 @@ static void _send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->phase_error)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#相位错误!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# 阶段性错误!");
|
||||
status = USB_STATUS_PHASE_ERROR;
|
||||
sd = SS_INVALID_COMMAND;
|
||||
}
|
||||
@@ -1826,7 +1825,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
xusb_device_get_ops(&usb_ops);
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#已启动USB");
|
||||
|
||||
if (usb_ops.usb_device_init())
|
||||
{
|
||||
@@ -1857,7 +1856,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
ums.set_text = usbs->set_text;
|
||||
ums.system_maintenance = usbs->system_maintenance;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#磁盘挂载中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#挂载磁盘");
|
||||
|
||||
// Initialize sdmmc.
|
||||
if (usbs->type == MMC_SD)
|
||||
@@ -1888,18 +1887,18 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
ums.lun.storage = &emmc_storage;
|
||||
}
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#连接等待中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#正在等待连接");
|
||||
|
||||
// Initialize Control Endpoint.
|
||||
if (usb_ops.usb_device_enumerate(USB_GADGET_UMS))
|
||||
goto usb_enum_error;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#LUN等待中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#正在等待LUN");
|
||||
|
||||
if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now.
|
||||
goto usb_enum_error;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#UMS已开启");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#已启动UMS");
|
||||
|
||||
// If partition sectors are not set get them from hardware.
|
||||
if (!ums.lun.num_sectors)
|
||||
@@ -1920,7 +1919,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
{
|
||||
// Check if we are allowed to unload the media.
|
||||
if (ums.lun.prevent_medium_removal)
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#卸载尝试已被阻止");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#尝试卸载被阻止");
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -1952,13 +1951,13 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
} while (ums.state != UMS_STATE_TERMINATED);
|
||||
|
||||
if (ums.lun.prevent_medium_removal)
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#磁盘已未安全弹出");
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#磁盘不安全弹出");
|
||||
else
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#磁盘已弹出");
|
||||
goto exit;
|
||||
|
||||
usb_enum_error:
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#超时或已取消!");
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#超时或取消!");
|
||||
res = 1;
|
||||
|
||||
exit:
|
||||
|
||||
193
bdk/usb/usbd.c
193
bdk/usb/usbd.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Enhanced USB Device (EDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -101,7 +101,11 @@ typedef struct _usbd_controller_t
|
||||
bool configuration_set;
|
||||
bool max_lun_set;
|
||||
bool bulk_reset_req;
|
||||
u32 intr_idle_rate;
|
||||
bool intr_idle_req;
|
||||
bool hid_report_sent;
|
||||
void *hid_rpt_buffer;
|
||||
u32 hid_rpt_size;
|
||||
u32 charger_detect;
|
||||
} usbd_controller_t;
|
||||
|
||||
@@ -881,7 +885,7 @@ int usbd_set_ep_stall(u32 endpoint, int ep_stall)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor, int *size, bool *ep_stall)
|
||||
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *desc, int *size, bool *ep_stall)
|
||||
{
|
||||
u8 _bRequest = usbd_otg->control_setup.bRequest;
|
||||
u16 _wIndex = usbd_otg->control_setup.wIndex;
|
||||
@@ -889,9 +893,9 @@ static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor,
|
||||
u16 _wLength = usbd_otg->control_setup.wLength;
|
||||
|
||||
bool valid_interface = _wIndex == usbd_otg->interface_num;
|
||||
bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0;
|
||||
bool valid_val = (_bRequest >= USB_REQUEST_BULK_GET_MAX_LUN) ? (!_wValue) : true;
|
||||
|
||||
if (!valid_interface || _wValue != 0 || _wLength != valid_len)
|
||||
if (!valid_interface || !valid_val)
|
||||
{
|
||||
*ep_stall = true;
|
||||
return;
|
||||
@@ -899,23 +903,51 @@ static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor,
|
||||
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_INTR_GET_REPORT:
|
||||
if (usbd_otg->hid_rpt_size != _wLength)
|
||||
break;
|
||||
|
||||
// _wValue unused as there's only one report type and id.
|
||||
*transmit_data = true;
|
||||
*size = usbd_otg->hid_rpt_size;
|
||||
memcpy(desc, usbd_otg->hid_rpt_buffer, usbd_otg->hid_rpt_size);
|
||||
return;
|
||||
|
||||
case USB_REQUEST_INTR_SET_IDLE:
|
||||
if (_wLength)
|
||||
break;
|
||||
|
||||
usbd_otg->intr_idle_rate = (_wValue & 0xFF) * 4 * 1000; // Only one interface so upper byte ignored.
|
||||
usbd_otg->intr_idle_req = true;
|
||||
_usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
return; // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_RESET:
|
||||
if (_wLength)
|
||||
break;
|
||||
|
||||
_usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
usbd_otg->bulk_reset_req = true;
|
||||
break; // DELAYED_STATUS;
|
||||
return; // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_GET_MAX_LUN:
|
||||
if (_wLength != 1)
|
||||
break;
|
||||
|
||||
*transmit_data = true;
|
||||
*size = 1;
|
||||
descriptor[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
|
||||
desc[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
|
||||
usbd_otg->max_lun_set = true;
|
||||
break;
|
||||
return;
|
||||
|
||||
default:
|
||||
*ep_stall = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor, int *size, bool *ep_stall)
|
||||
*ep_stall = true;
|
||||
}
|
||||
|
||||
static void _usbd_handle_get_descriptor(bool *transmit_data, void **desc, int *size, bool *ep_stall)
|
||||
{
|
||||
u8 descriptor_type = usbd_otg->control_setup.wValue >> 8;
|
||||
u8 descriptor_subtype = usbd_otg->control_setup.wValue & 0xFF;
|
||||
@@ -931,7 +963,7 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
|
||||
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
|
||||
*/
|
||||
*descriptor = usbd_otg->desc->dev;
|
||||
*desc = usbd_otg->desc->dev;
|
||||
*size = usbd_otg->desc->dev->bLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -941,13 +973,13 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
{
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x200; // No burst.
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -955,20 +987,22 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_otg->desc->cfg;
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
*descriptor = usbd_otg->desc->cfg;
|
||||
}
|
||||
*desc = usbd_otg->desc->cfg;
|
||||
*size = usbd_otg->desc->cfg->config.wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -976,23 +1010,23 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
switch (descriptor_subtype)
|
||||
{
|
||||
case 1:
|
||||
*descriptor = usbd_otg->desc->vendor;
|
||||
*desc = usbd_otg->desc->vendor;
|
||||
*size = usbd_otg->desc->vendor[0];
|
||||
break;
|
||||
case 2:
|
||||
*descriptor = usbd_otg->desc->product;
|
||||
*desc = usbd_otg->desc->product;
|
||||
*size = usbd_otg->desc->product[0];
|
||||
break;
|
||||
case 3:
|
||||
*descriptor = usbd_otg->desc->serial;
|
||||
*desc = usbd_otg->desc->serial;
|
||||
*size = usbd_otg->desc->serial[0];
|
||||
break;
|
||||
case 0xEE:
|
||||
*descriptor = usbd_otg->desc->ms_os;
|
||||
*desc = usbd_otg->desc->ms_os;
|
||||
*size = usbd_otg->desc->ms_os->bLength;
|
||||
break;
|
||||
default:
|
||||
*descriptor = usbd_otg->desc->lang_id;
|
||||
*desc = usbd_otg->desc->lang_id;
|
||||
*size = 4;
|
||||
break;
|
||||
}
|
||||
@@ -1002,7 +1036,7 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
if (!usbd_otg->desc->dev_qual)
|
||||
goto exit;
|
||||
usbd_otg->desc->dev_qual->bNumOtherConfigs = 1;
|
||||
*descriptor = usbd_otg->desc->dev_qual;
|
||||
*desc = usbd_otg->desc->dev_qual;
|
||||
*size = usbd_otg->desc->dev_qual->bLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -1011,22 +1045,22 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
goto exit;
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED)
|
||||
{
|
||||
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x200;
|
||||
}
|
||||
if ((usbd_otg->charger_detect & 1) && (usbd_otg->charger_detect & 2))
|
||||
usbd_otg->desc->cfg_other->config.bMaxPower = 500 / 2;
|
||||
*descriptor = usbd_otg->desc->cfg_other;
|
||||
*desc = usbd_otg->desc->cfg_other;
|
||||
*size = usbd_otg->desc->cfg_other->config.wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
|
||||
*descriptor = usbd_otg->desc->dev_bot;
|
||||
*desc = usbd_otg->desc->dev_bot;
|
||||
*size = usbd_otg->desc->dev_bot->wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -1086,7 +1120,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
bool ep_stall = false;
|
||||
bool transmit_data = false;
|
||||
|
||||
u8 *descriptor = (u8 *)USB_DESCRIPTOR_ADDR;
|
||||
u8 *desc = (u8 *)USB_DESCRIPTOR_ADDR;
|
||||
int size = 0;
|
||||
|
||||
u8 _bmRequestType = usbd_otg->control_setup.bmRequestType;
|
||||
@@ -1099,17 +1133,17 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
|
||||
switch (_bmRequestType)
|
||||
{
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x00.
|
||||
res = _usbd_handle_set_request(&ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x01.
|
||||
res = _usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
if (!res)
|
||||
usbd_otg->interface_num = _wValue;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x02.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_CLEAR_FEATURE:
|
||||
@@ -1153,25 +1187,25 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
memset(descriptor, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0x21.
|
||||
memset(desc, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x80.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
descriptor[0] = USB_STATUS_DEV_SELF_POWERED;
|
||||
descriptor[1] = 0; // No support for remove wake up.
|
||||
desc[0] = USB_STATUS_DEV_SELF_POWERED;
|
||||
desc[1] = 0; // No support for remove wake up.
|
||||
transmit_data = true;
|
||||
size = 2;
|
||||
break;
|
||||
case USB_REQUEST_GET_DESCRIPTOR:
|
||||
_usbd_handle_get_descriptor(&transmit_data, (void **)&descriptor, &size, &ep_stall);
|
||||
_usbd_handle_get_descriptor(&transmit_data, (void **)&desc, &size, &ep_stall);
|
||||
break;
|
||||
case USB_REQUEST_GET_CONFIGURATION:
|
||||
descriptor = (u8 *)&usbd_otg->config_num;
|
||||
desc = (u8 *)&usbd_otg->config_num;
|
||||
size = _wLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
@@ -1181,28 +1215,28 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x81.
|
||||
if (_bRequest == USB_REQUEST_GET_INTERFACE)
|
||||
{
|
||||
memset(descriptor, 0, _wLength);
|
||||
descriptor[0] = usbd_otg->interface_num;
|
||||
memset(desc, 0, _wLength);
|
||||
desc[0] = usbd_otg->interface_num;
|
||||
size = _wLength;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
memset(descriptor, 0, _wLength);
|
||||
memset(desc, 0, _wLength);
|
||||
size = _wLength;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget > USB_GADGET_UMS)
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
if (usbd_otg->gadget == USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
descriptor = (u8 *)&hid_report_descriptor_jc;
|
||||
desc = (u8 *)&hid_report_descriptor_jc;
|
||||
size = hid_report_descriptor_jc_size;
|
||||
}
|
||||
else // USB_GADGET_HID_TOUCHPAD
|
||||
{
|
||||
descriptor = (u8 *)&hid_report_descriptor_touch;
|
||||
desc = (u8 *)&hid_report_descriptor_touch;
|
||||
size = hid_report_descriptor_touch_size;
|
||||
}
|
||||
|
||||
@@ -1219,7 +1253,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
transmit_data = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x82.
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
int ep_req;
|
||||
@@ -1243,12 +1277,12 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
|
||||
size = _wLength;
|
||||
memset(descriptor, 0, size);
|
||||
memset(desc, 0, size);
|
||||
|
||||
if (_usbd_get_ep_status(ep_req) == USB_EP_STATUS_STALLED)
|
||||
descriptor[0] = USB_STATUS_EP_HALTED;
|
||||
desc[0] = USB_STATUS_EP_HALTED;
|
||||
else
|
||||
descriptor[0] = USB_STATUS_EP_OK;
|
||||
desc[0] = USB_STATUS_EP_OK;
|
||||
|
||||
transmit_data = true;
|
||||
}
|
||||
@@ -1256,24 +1290,24 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
memset(descriptor, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0xA1.
|
||||
memset(desc, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): // 0xC0.
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): // 0xC1.
|
||||
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
|
||||
{
|
||||
switch (_wIndex)
|
||||
{
|
||||
case USB_DESCRIPTOR_MS_COMPAT_ID:
|
||||
descriptor = (u8 *)usbd_otg->desc->ms_cid;
|
||||
desc = (u8 *)usbd_otg->desc->ms_cid;
|
||||
size = usbd_otg->desc->ms_cid->dLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES:
|
||||
descriptor = (u8 *)usbd_otg->desc->mx_ext;
|
||||
desc = (u8 *)usbd_otg->desc->mx_ext;
|
||||
size = usbd_otg->desc->mx_ext->dLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
@@ -1294,7 +1328,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
// Transmit data to HOST if any.
|
||||
if (transmit_data)
|
||||
{
|
||||
memcpy(usb_ep0_ctrl_buf, descriptor, size);
|
||||
memcpy(usb_ep0_ctrl_buf, desc, size);
|
||||
|
||||
if (_wLength < size)
|
||||
size = _wLength;
|
||||
@@ -1393,7 +1427,7 @@ int usb_device_enumerate(usb_gadget_type gadget)
|
||||
return _usbd_ep0_initialize();
|
||||
}
|
||||
|
||||
int usbd_handle_ep0_ctrl_setup()
|
||||
int usbd_handle_ep0_ctrl_setup(u32 *data)
|
||||
{
|
||||
// Acknowledge setup request for EP0 and copy its configuration.
|
||||
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
|
||||
@@ -1405,6 +1439,15 @@ int usbd_handle_ep0_ctrl_setup()
|
||||
memset(usb_ep0_ctrl_buf, 0, USB_TD_BUFFER_PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (usbd_otg->intr_idle_req)
|
||||
{
|
||||
if (data)
|
||||
*data = usbd_otg->intr_idle_rate;
|
||||
|
||||
usbd_otg->intr_idle_req = false;
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
// Only return error if bulk reset was requested.
|
||||
if (usbd_otg->bulk_reset_req)
|
||||
{
|
||||
@@ -1487,7 +1530,7 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
|
||||
break;
|
||||
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
}
|
||||
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
|
||||
|
||||
@@ -1536,7 +1579,7 @@ int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
|
||||
break;
|
||||
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
}
|
||||
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
|
||||
|
||||
@@ -1572,7 +1615,7 @@ int usb_device_class_send_max_lun(u8 max_lun)
|
||||
|
||||
while (!usbd_otg->max_lun_set)
|
||||
{
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
return USB_ERROR_USER_ABORT;
|
||||
}
|
||||
@@ -1580,15 +1623,19 @@ int usb_device_class_send_max_lun(u8 max_lun)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
int usb_device_class_send_hid_report()
|
||||
int usb_device_class_send_hid_report(void *rpt_buffer, u32 rpt_size)
|
||||
{
|
||||
// Set buffers.
|
||||
usbd_otg->hid_rpt_buffer = rpt_buffer;
|
||||
usbd_otg->hid_rpt_size = rpt_size;
|
||||
|
||||
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
|
||||
u32 timer = get_tmr_ms() + 10000;
|
||||
|
||||
// Wait for request and transfer start.
|
||||
while (!usbd_otg->hid_report_sent)
|
||||
{
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
return USB_ERROR_USER_ABORT;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2025 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,
|
||||
@@ -31,11 +31,11 @@
|
||||
#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE)
|
||||
|
||||
#define USB_XFER_START 0
|
||||
#define USB_XFER_SYNCED_ENUM 1000000
|
||||
#define USB_XFER_SYNCED_CMD 1000000
|
||||
#define USB_XFER_SYNCED_DATA 2000000
|
||||
#define USB_XFER_SYNCED_CLASS 5000000
|
||||
#define USB_XFER_SYNCED -1
|
||||
#define USB_XFER_SYNCED_ENUM 1000000 // ~2s.
|
||||
#define USB_XFER_SYNCED_CMD 1000000 // ~2s.
|
||||
#define USB_XFER_SYNCED_DATA 2000000 // ~4s.
|
||||
#define USB_XFER_SYNCED_CLASS 5000000 // ~10s.
|
||||
#define USB_XFER_SYNCED -1 // Max.
|
||||
|
||||
typedef enum _usb_hid_type
|
||||
{
|
||||
@@ -122,6 +122,9 @@ typedef enum {
|
||||
|
||||
USB_REQUEST_GET_MS_DESCRIPTOR = 0x99,
|
||||
|
||||
USB_REQUEST_INTR_GET_REPORT = 1,
|
||||
USB_REQUEST_INTR_SET_IDLE = 10,
|
||||
|
||||
USB_REQUEST_BULK_GET_MAX_LUN = 0xFE,
|
||||
USB_REQUEST_BULK_RESET = 0xFF
|
||||
} usb_standard_req_t;
|
||||
@@ -167,12 +170,13 @@ typedef struct _usb_ops_t
|
||||
{
|
||||
int (*usbd_flush_endpoint)(u32);
|
||||
int (*usbd_set_ep_stall)(u32, int);
|
||||
int (*usbd_handle_ep0_ctrl_setup)();
|
||||
int (*usbd_handle_ep0_ctrl_setup)(u32 *);
|
||||
void (*usbd_end)(bool, bool);
|
||||
int (*usb_device_init)();
|
||||
int (*usb_device_enumerate)(usb_gadget_type gadget);
|
||||
int (*usb_device_enumerate)(usb_gadget_type);
|
||||
|
||||
int (*usb_device_class_send_max_lun)(u8);
|
||||
int (*usb_device_class_send_hid_report)();
|
||||
int (*usb_device_class_send_hid_report)(void *, u32);
|
||||
|
||||
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, u32);
|
||||
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
|
||||
@@ -186,10 +190,17 @@ typedef struct _usb_ops_t
|
||||
typedef struct _usb_ctxt_t
|
||||
{
|
||||
u32 type;
|
||||
|
||||
// UMS.
|
||||
u32 partition;
|
||||
u32 offset;
|
||||
u32 sectors;
|
||||
u32 ro;
|
||||
|
||||
// HID.
|
||||
u32 idle;
|
||||
|
||||
// System.
|
||||
void (*system_maintenance)(bool);
|
||||
void *label;
|
||||
void (*set_text)(void *, const char *);
|
||||
|
||||
133
bdk/usb/xusbd.c
133
bdk/usb/xusbd.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* eXtensible USB Device driver (XDCI) for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2025 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,
|
||||
@@ -381,6 +381,10 @@ typedef struct _xusbd_controller_t
|
||||
|
||||
u8 max_lun;
|
||||
bool max_lun_set;
|
||||
void *hid_rpt_buffer;
|
||||
u32 hid_rpt_size;
|
||||
u32 intr_idle_rate;
|
||||
bool intr_idle_req;
|
||||
bool bulk_reset_req;
|
||||
} xusbd_controller_t;
|
||||
|
||||
@@ -1469,20 +1473,39 @@ static int _xusb_handle_get_class_request(const usb_ctrl_setup_t *ctrl_setup)
|
||||
u16 _wLength = ctrl_setup->wLength;
|
||||
|
||||
bool valid_interface = _wIndex == usbd_xotg->interface_num;
|
||||
bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0;
|
||||
bool valid_val = (_bRequest >= USB_REQUEST_BULK_GET_MAX_LUN) ? (!_wValue) : true;
|
||||
|
||||
if (!valid_interface || _wValue != 0 || _wLength != valid_len)
|
||||
if (!valid_interface || !valid_val)
|
||||
goto stall;
|
||||
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_INTR_GET_REPORT:
|
||||
if (usbd_xotg->hid_rpt_size != _wLength)
|
||||
goto stall;
|
||||
|
||||
// _wValue unused as there's only one report type and id.
|
||||
return _xusb_issue_data_trb(usbd_xotg->hid_rpt_buffer, usbd_xotg->hid_rpt_size, USB_DIR_IN);
|
||||
|
||||
case USB_REQUEST_INTR_SET_IDLE:
|
||||
if (_wLength)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->intr_idle_rate = (_wValue & 0xFF) * 4 * 1000; // Only one interface so upper byte ignored.
|
||||
usbd_xotg->intr_idle_req = true;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN); // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_RESET:
|
||||
if (_wLength)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->bulk_reset_req = true;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN); // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_GET_MAX_LUN:
|
||||
if (!usbd_xotg->max_lun_set)
|
||||
if (_wLength != 1 || !usbd_xotg->max_lun_set)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->device_state = XUSB_LUN_CONFIGURED_STS_WAIT;
|
||||
return _xusb_issue_data_trb(&usbd_xotg->max_lun, 1, USB_DIR_IN);
|
||||
}
|
||||
@@ -1495,7 +1518,7 @@ stall:
|
||||
static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
u32 size;
|
||||
void *descriptor;
|
||||
void *desc;
|
||||
|
||||
u32 wLength = ctrl_setup->wLength;
|
||||
|
||||
@@ -1513,7 +1536,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
|
||||
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
|
||||
*/
|
||||
descriptor = usbd_xotg->desc->dev;
|
||||
desc = usbd_xotg->desc->dev;
|
||||
size = usbd_xotg->desc->dev->bLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
@@ -1522,13 +1545,13 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200; // No burst.
|
||||
usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200; // No burst.
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg->endpoint[i].wMaxPacketSize = 0x200; // No burst.
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1536,43 +1559,45 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_xotg->desc->cfg;
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[i].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[i].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
descriptor = usbd_xotg->desc->cfg;
|
||||
}
|
||||
desc = usbd_xotg->desc->cfg;
|
||||
size = usbd_xotg->desc->cfg->config.wTotalLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
switch (descriptor_subtype)
|
||||
{
|
||||
case 1:
|
||||
descriptor = usbd_xotg->desc->vendor;
|
||||
desc = usbd_xotg->desc->vendor;
|
||||
size = usbd_xotg->desc->vendor[0];
|
||||
break;
|
||||
case 2:
|
||||
descriptor = usbd_xotg->desc->product;
|
||||
desc = usbd_xotg->desc->product;
|
||||
size = usbd_xotg->desc->product[0];
|
||||
break;
|
||||
case 3:
|
||||
descriptor = usbd_xotg->desc->serial;
|
||||
desc = usbd_xotg->desc->serial;
|
||||
size = usbd_xotg->desc->serial[0];
|
||||
break;
|
||||
case 0xEE:
|
||||
descriptor = usbd_xotg->desc->ms_os;
|
||||
desc = usbd_xotg->desc->ms_os;
|
||||
size = usbd_xotg->desc->ms_os->bLength;
|
||||
break;
|
||||
default:
|
||||
descriptor = usbd_xotg->desc->lang_id;
|
||||
desc = usbd_xotg->desc->lang_id;
|
||||
size = 4;
|
||||
break;
|
||||
}
|
||||
@@ -1584,7 +1609,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
usbd_xotg->desc->dev_qual->bNumOtherConfigs = 0;
|
||||
descriptor = usbd_xotg->desc->dev_qual;
|
||||
desc = usbd_xotg->desc->dev_qual;
|
||||
size = usbd_xotg->desc->dev_qual->bLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION:
|
||||
@@ -1595,19 +1620,19 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
}
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED)
|
||||
{
|
||||
usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x200;
|
||||
}
|
||||
descriptor = usbd_xotg->desc->cfg_other;
|
||||
desc = usbd_xotg->desc->cfg_other;
|
||||
size = usbd_xotg->desc->cfg_other->config.wTotalLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
|
||||
descriptor = usbd_xotg->desc->dev_bot;
|
||||
desc = usbd_xotg->desc->dev_bot;
|
||||
size = usbd_xotg->desc->dev_bot->wTotalLength;
|
||||
break;
|
||||
default:
|
||||
@@ -1618,7 +1643,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
if (wLength < size)
|
||||
size = wLength;
|
||||
|
||||
return _xusb_issue_data_trb(descriptor, size, USB_DIR_IN);
|
||||
return _xusb_issue_data_trb(desc, size, USB_DIR_IN);
|
||||
}
|
||||
|
||||
static void _xusb_handle_set_request_dev_address(const usb_ctrl_setup_t *ctrl_setup)
|
||||
@@ -1688,18 +1713,18 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
|
||||
switch (_bmRequestType)
|
||||
{
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x00.
|
||||
if (_bRequest == USB_REQUEST_SET_ADDRESS)
|
||||
_xusb_handle_set_request_dev_address(ctrl_setup);
|
||||
else if (_bRequest == USB_REQUEST_SET_CONFIGURATION)
|
||||
_xusb_handle_set_request_configuration(ctrl_setup);
|
||||
return USB_RES_OK; // What about others.
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x01.
|
||||
usbd_xotg->interface_num = _wValue;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN);
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x02.
|
||||
if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
if (_bRequest == USB_REQUEST_CLEAR_FEATURE || _bRequest == USB_REQUEST_SET_FEATURE)
|
||||
@@ -1735,10 +1760,10 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0x21.
|
||||
return _xusb_handle_get_class_request(ctrl_setup);
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x80.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
@@ -1760,7 +1785,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x81.
|
||||
if (_bRequest == USB_REQUEST_GET_INTERFACE)
|
||||
{
|
||||
desc = xusb_interface_descriptor;
|
||||
@@ -1774,7 +1799,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
size = sizeof(xusb_status_descriptor);
|
||||
transmit_data = true;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_xotg->gadget > USB_GADGET_UMS)
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_xotg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
if (usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
@@ -1793,7 +1818,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x82.
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
u32 ep = 0;
|
||||
@@ -1821,11 +1846,11 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0xA1.
|
||||
return _xusb_handle_get_class_request(ctrl_setup);
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): // 0xC0.
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): // 0xC1.
|
||||
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
|
||||
{
|
||||
switch (_wIndex)
|
||||
@@ -2017,12 +2042,24 @@ void xusb_end(bool reset_ep, bool only_controller)
|
||||
_xusb_device_power_down();
|
||||
}
|
||||
|
||||
int xusb_handle_ep0_ctrl_setup()
|
||||
int xusb_handle_ep0_ctrl_setup(u32 *data)
|
||||
{
|
||||
/*
|
||||
* EP0 Control handling is done by normal ep operation in XUSB.
|
||||
* Here we handle the bulk reset only.
|
||||
* Here we handle the interface only, except if HID.
|
||||
*/
|
||||
if (usbd_xotg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
_xusb_ep_operation(1);
|
||||
|
||||
if (usbd_xotg->intr_idle_req)
|
||||
{
|
||||
if (data)
|
||||
*data = usbd_xotg->intr_idle_rate;
|
||||
|
||||
usbd_xotg->intr_idle_req = false;
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
if (usbd_xotg->bulk_reset_req)
|
||||
{
|
||||
usbd_xotg->bulk_reset_req = false;
|
||||
@@ -2176,8 +2213,12 @@ bool xusb_device_class_send_max_lun(u8 max_lun)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool xusb_device_class_send_hid_report()
|
||||
bool xusb_device_class_send_hid_report(void *rpt_buffer, u32 rpt_size)
|
||||
{
|
||||
// Set buffers.
|
||||
usbd_xotg->hid_rpt_buffer = rpt_buffer;
|
||||
usbd_xotg->hid_rpt_size = rpt_size;
|
||||
|
||||
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
|
||||
u32 timer = get_tmr_ms() + 10000;
|
||||
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
#include <mem/heap.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, u32 flags)
|
||||
{
|
||||
int res = 0;
|
||||
u32 k = 0;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
bool show_hidden = !!(flags & DIR_SHOW_HIDDEN);
|
||||
bool show_dirs = !!(flags & DIR_SHOW_DIRS);
|
||||
bool ascii_order = !!(flags & DIR_ASCII_ORDER);
|
||||
|
||||
dirlist_t *dir_entries = (dirlist_t *)malloc(sizeof(dirlist_t));
|
||||
|
||||
@@ -43,11 +46,11 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
||||
if (res || !fno.fname[0])
|
||||
break;
|
||||
|
||||
bool curr_parse = parse_dirs ? (fno.fattrib & AM_DIR) : !(fno.fattrib & AM_DIR);
|
||||
bool curr_parse = show_dirs ? (fno.fattrib & AM_DIR) : !(fno.fattrib & AM_DIR);
|
||||
|
||||
if (curr_parse)
|
||||
{
|
||||
if ((fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
if ((fno.fname[0] != '.') && (show_hidden || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
strcpy(&dir_entries->data[k * 256], fno.fname);
|
||||
if (++k >= DIR_MAX_ENTRIES)
|
||||
@@ -61,7 +64,7 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (show_hidden || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
strcpy(&dir_entries->data[k * 256], fno.fname);
|
||||
if (++k >= DIR_MAX_ENTRIES)
|
||||
@@ -82,12 +85,15 @@ dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHidde
|
||||
// Terminate name list.
|
||||
dir_entries->name[k] = NULL;
|
||||
|
||||
// Choose list ordering.
|
||||
int (*strcmpex)(const char* str1, const char* str2) = ascii_order ? strcmp : strcasecmp;
|
||||
|
||||
// Reorder ini files Alphabetically.
|
||||
for (u32 i = 0; i < k - 1 ; i++)
|
||||
{
|
||||
for (u32 j = i + 1; j < k; j++)
|
||||
{
|
||||
if (strcasecmp(dir_entries->name[i], dir_entries->name[j]) > 0)
|
||||
if (strcmpex(dir_entries->name[i], dir_entries->name[j]) > 0)
|
||||
{
|
||||
char *tmp = dir_entries->name[i];
|
||||
dir_entries->name[i] = dir_entries->name[j];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2024 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -18,10 +18,14 @@
|
||||
|
||||
#define DIR_MAX_ENTRIES 64
|
||||
|
||||
#define DIR_SHOW_HIDDEN BIT(0)
|
||||
#define DIR_SHOW_DIRS BIT(1)
|
||||
#define DIR_ASCII_ORDER BIT(2)
|
||||
|
||||
typedef struct _dirlist_t
|
||||
{
|
||||
char *name[DIR_MAX_ENTRIES];
|
||||
char data[DIR_MAX_ENTRIES * 256];
|
||||
} dirlist_t;
|
||||
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs);
|
||||
dirlist_t *dirlist(const char *directory, const char *pattern, u32 flags);
|
||||
|
||||
@@ -70,7 +70,7 @@ int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
|
||||
// Get all ini filenames.
|
||||
if (is_dir)
|
||||
{
|
||||
filelist = dirlist(filename, "*.ini", false, false);
|
||||
filelist = dirlist(filename, "*.ini", DIR_ASCII_ORDER);
|
||||
if (!filelist)
|
||||
{
|
||||
free(filename);
|
||||
|
||||
256
bdk/utils/tegra_bct.h
Normal file
256
bdk/utils/tegra_bct.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEGRA_BCT_H
|
||||
#define TEGRA_BCT_H
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#include <mem/sdram_param_t210.h>
|
||||
#include <mem/sdram_param_t210b01.h>
|
||||
|
||||
#define BCT_IRAM_ADDRESS 0x40000100
|
||||
#define BCT_IRAM_ADDRESS_B01 0x40000464
|
||||
|
||||
#define BCT_BOOT_DEV_NONE 0
|
||||
#define BCT_BOOT_DEV_SPI 3
|
||||
#define BCT_BOOT_DEV_SDMMC 4
|
||||
#define BCT_BOOT_DEV_USB3 9
|
||||
#define BCT_BOOT_DEV_UART 11
|
||||
|
||||
// ECID is checked for the following.
|
||||
#define BCT_SEC_DBG_JTAG BIT(0)
|
||||
#define BCT_SEC_DBG_DEV BIT(1)
|
||||
#define BCT_SEC_DBG_SPNID BIT(2)
|
||||
#define BCT_SEC_DBG_SPID BIT(3)
|
||||
#define BCT_SEC_DBG_NID BIT(4) // ECID not checked for T210B01.
|
||||
#define BCT_SEC_DBG_DBG BIT(5) // ECID not checked for T210B01.
|
||||
|
||||
#define BCT_SDMMC_CFG_SDR25_SINGLE_PAGE 0
|
||||
#define BCT_SDMMC_CFG_SDR52_MULTI_PAGE 1
|
||||
#define BCT_SDMMC_CFG_SDR25_MULTI_PAGE 2
|
||||
#define BCT_SDMMC_CFG_DDR52_MULTI_PAGE 3
|
||||
#define BCT_SDMMC_CFG_DDR25_MULTI_PAGE 4
|
||||
|
||||
#define BCT_SPI_CFG_PIO_X1_20_4MHZ_SREAD 0
|
||||
#define BCT_SPI_CFG_PIO_X1_19_2MHZ_SREAD 1
|
||||
#define BCT_SPI_CFG_PIO_X4_51_0MHZ_QREAD 2
|
||||
|
||||
typedef struct _bct_bad_blocks_t
|
||||
{
|
||||
u32 used_entries; // For block table.
|
||||
u8 virtual_block_size_log2;
|
||||
u8 block_size_log2;
|
||||
u8 block_table[512]; // Each bit is a block (4096 blocks).
|
||||
|
||||
u8 padding[10];
|
||||
} bct_bad_blocks_t;
|
||||
|
||||
typedef struct _bct_sdmmc_dev_t210_t
|
||||
{
|
||||
u32 clk_div;
|
||||
u32 bus_width;
|
||||
u8 power_class_max;
|
||||
u8 multi_block_max;
|
||||
} bct_sdmmc_dev_t210_t;
|
||||
|
||||
typedef struct _bct_sdmmc_dev_t210b01_t
|
||||
{
|
||||
u8 sdmmc_config;
|
||||
u8 power_class_max;
|
||||
} bct_sdmmc_dev_t210b01_t;
|
||||
|
||||
typedef struct _bct_spi_dev_t210_t
|
||||
{
|
||||
u32 clk_src;
|
||||
u8 clk_div;
|
||||
u8 cmd_read_fast;
|
||||
u8 page_size; // 0: 2KB, 1: 16KB.
|
||||
} bct_spi_dev_t210_t;
|
||||
|
||||
typedef struct _bct_spi_dev_t210b01_t
|
||||
{
|
||||
u8 spi_config;
|
||||
} bct_spi_dev_t210b01_t;
|
||||
|
||||
typedef struct _bct_usb3_dev_t
|
||||
{
|
||||
u8 clk_div;
|
||||
u8 root_port;
|
||||
u8 page_size; // 0: 2KB, 1: 16KB.
|
||||
u8 oc_pin;
|
||||
u8 vbus_en;
|
||||
} bct_usb3_dev_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
bct_sdmmc_dev_t210_t sdmmc_params;
|
||||
bct_spi_dev_t210_t spi_params;
|
||||
bct_usb3_dev_t usb3_params;
|
||||
|
||||
u8 padding[64];
|
||||
} bct_boot_dev_t210_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
bct_sdmmc_dev_t210b01_t sdmmc_params;
|
||||
bct_spi_dev_t210b01_t spi_params;
|
||||
|
||||
u8 padding[64];
|
||||
} bct_boot_dev_t210b01_t;
|
||||
|
||||
typedef struct _bct_bootloader_t210_t
|
||||
{
|
||||
u32 version;
|
||||
u32 start_block;
|
||||
u32 start_page;
|
||||
|
||||
u32 length; // Should be bl size + 16 and aligned to 16.
|
||||
u32 load_addr;
|
||||
u32 entrypoint;
|
||||
u32 attributes; // ODM.
|
||||
|
||||
u8 aes_cmac_hash[16];
|
||||
u8 rsa_pss_signature[256];
|
||||
} bct_bootloader_t210_t;
|
||||
|
||||
typedef struct _bct_bootloader_t210b01_t
|
||||
{
|
||||
u32 start_block;
|
||||
u32 start_page;
|
||||
u32 version;
|
||||
u32 padding;
|
||||
} bct_bootloader_t210b01_t;
|
||||
|
||||
typedef struct _tegra_bct_t210_t
|
||||
{
|
||||
/* Unsigned section */
|
||||
bct_bad_blocks_t bad_block_table;
|
||||
|
||||
u8 rsa_modulus[256];
|
||||
u8 aes_cmac_hash[16];
|
||||
u8 rsa_pss_signature[256];
|
||||
|
||||
u32 secprov_aes_key_num_insecure;
|
||||
u8 secprov_aes_key[32];
|
||||
|
||||
u8 customer_data[204];
|
||||
|
||||
/* Signed section */
|
||||
u8 random_aes_block[16];
|
||||
|
||||
u32 ecid[4];
|
||||
|
||||
u32 data_version; // 0x210001.
|
||||
|
||||
u32 block_size_log2;
|
||||
u32 page_size_log2;
|
||||
u32 partition_size;
|
||||
|
||||
u32 boot_dev_params_num;
|
||||
u32 boot_dev_type;
|
||||
bct_boot_dev_t210_t boot_dev_params;
|
||||
|
||||
u32 dram_params_num;
|
||||
sdram_params_t210_t dram_params[4];
|
||||
|
||||
u32 bootloader_num;
|
||||
bct_bootloader_t210_t bootLoader[4];
|
||||
u32 bootloader_failback_en;
|
||||
|
||||
u32 sec_dbg_ctrl; // Copied to APBDEV_PMC_DEBUG_AUTHENTICATION. ECID checked.
|
||||
|
||||
u32 secprov_aes_key_num_secure;
|
||||
|
||||
u8 padding[20];
|
||||
} tegra_bct_t210_t;
|
||||
|
||||
typedef struct _tegra_bct_t210b01_t
|
||||
{
|
||||
/* Unsigned section */
|
||||
u32 rsa_key_size;
|
||||
u32 padding0[3];
|
||||
u8 rsa_modulus[256];
|
||||
u8 rsa_exponent[256];
|
||||
|
||||
u8 aes_cmac_hash[16];
|
||||
u8 rsa_pss_signature[256];
|
||||
|
||||
u8 secprov_aes_key[32];
|
||||
u32 secprov_aes_key_num_insecure;
|
||||
|
||||
u8 padding_unsigned[12];
|
||||
|
||||
u8 customer_data0[208];
|
||||
|
||||
/* Signed section */
|
||||
u8 random_aes_block0[16];
|
||||
|
||||
u32 boot_config0[4]; // Customer controlled features.
|
||||
|
||||
/// Unused space allocated for customer usage.
|
||||
u32 customer_data1_signed[16];
|
||||
|
||||
/* Encrypted section (optionally) */
|
||||
u8 random_aes_block1[16];
|
||||
|
||||
u32 ecid[4];
|
||||
|
||||
u32 data_version; // 0x210001.
|
||||
|
||||
u32 block_size_log2;
|
||||
u32 page_size_log2;
|
||||
u32 partition_size;
|
||||
|
||||
u32 boot_dev_params_num;
|
||||
u32 boot_dev_type;
|
||||
bct_boot_dev_t210b01_t boot_dev_params;
|
||||
|
||||
u32 dram_params_num;
|
||||
sdram_params_t210b01_t dram_params[4];
|
||||
|
||||
u32 bootloader_num;
|
||||
bct_bootloader_t210b01_t bootLoader[4];
|
||||
|
||||
u32 sec_dbg_ctrl; // Copied to APBDEV_PMC_DEBUG_AUTHENTICATION. ECID not checked.
|
||||
u32 sec_dbg_ctrl_ecid; // Copied to APBDEV_PMC_DEBUG_AUTHENTICATION. ECID checked.
|
||||
|
||||
u32 boot_config1[4]; // Customer controlled features. bit0 AON TZRAM powergating enable
|
||||
|
||||
u32 customer_data2_signed[16]; // u32[0]: bl attributes.
|
||||
|
||||
u32 secprov_aes_key_num_secure;
|
||||
|
||||
u8 padding_signed[388];
|
||||
} tegra_bct_t210b01_t;
|
||||
|
||||
typedef struct _bootLoader_hdr_t210b01_t
|
||||
{
|
||||
/* Unsigned section */
|
||||
u8 aes_cmac_hash[16];
|
||||
u8 rsa_pss_signature[256];
|
||||
|
||||
/* Signed section */
|
||||
u8 salt[16]; // random_aes_block.
|
||||
u8 bootLoader_sha256[16];
|
||||
u32 version;
|
||||
u32 length;
|
||||
u32 load_addr;
|
||||
u32 entrypoint;
|
||||
u8 padding[16];
|
||||
} bootLoader_hdr_t210b01_t;
|
||||
|
||||
#endif
|
||||
362
bdk/utils/tegra_bit.h
Normal file
362
bdk/utils/tegra_bit.h
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* 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,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEGRA_BIT_H
|
||||
#define TEGRA_BIT_H
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BIT_ADDRESS 0x40000000
|
||||
|
||||
#define BIT_BOOT_TYPE_NONE 0
|
||||
#define BIT_BOOT_TYPE_COLD 1
|
||||
#define BIT_BOOT_TYPE_RCM 2
|
||||
#define BIT_BOOT_TYPE_UART 3
|
||||
#define BIT_BOOT_TYPE_EXIT_RCM 4
|
||||
|
||||
#define BIT_READ_STATUS_NONE 0
|
||||
#define BIT_READ_STATUS_SUCCESS 1
|
||||
#define BIT_READ_STATUS_VALIDATION_ERROR 2
|
||||
#define BIT_READ_STATUS_HW_READ_ERROR 3
|
||||
|
||||
#define BIT_USB_CHARGE_DETECT_EN BIT(0)
|
||||
#define BIT_USB_CHARGE_LOW_BATT BIT(1)
|
||||
#define BIT_USB_CHARGE_CONNECTED BIT(2)
|
||||
#define BIT_USB_CHARGE_HI_CURRENT BIT(8)
|
||||
|
||||
// From T186 with some additions.
|
||||
enum
|
||||
{
|
||||
BIT_FLOW_STATUS_NONE = 0,
|
||||
BIT_FLOW_STATUS_IPATCHUNCORRECTED_ERROR = 1,
|
||||
BIT_FLOW_STATUS_IPATCHSUCCESS = 2,
|
||||
BIT_FLOW_STATUS_SETUPOSCCLK = 3,
|
||||
BIT_FLOW_STATUS_LOWBAT_NOTCHARGED = 4,
|
||||
BIT_FLOW_STATUS_LOWBAT_CHARGED = 5,
|
||||
BIT_FLOW_STATUS_PLLPENABLED = 6,
|
||||
BIT_FLOW_STATUS_MSSINITIALIZED = 7,
|
||||
BIT_FLOW_STATUS_FABRICINITIALIZED = 8,
|
||||
BIT_FLOW_STATUS_NONSECUREDISPATCHERENTRY = 9,
|
||||
BIT_FLOW_STATUS_NONSECUREDISPATCHEREXIT = 10,
|
||||
BIT_FLOW_STATUS_FAMODE = 11,
|
||||
BIT_FLOW_STATUS_PREPRODUCTIONMODEUART = 12,
|
||||
BIT_FLOW_STATUS_PRODUCTIONMODE = 13,
|
||||
BIT_FLOW_STATUS_ODMPRODUCTIONMODE = 14,
|
||||
BIT_FLOW_STATUS_DBGRCMMODE = 15,
|
||||
BIT_FLOW_STATUS_RECOVERYMODE = 16,
|
||||
BIT_FLOW_STATUS_SECUREDISPATCHERENTRY = 17,
|
||||
BIT_FLOW_STATUS_SECUREDISPATCHEREXIT = 18,
|
||||
BIT_FLOW_STATUS_RAMDUMPINIT = 19,
|
||||
BIT_FLOW_STATUS_RAMDUMPEXIT = 20,
|
||||
BIT_FLOW_STATUS_COLDBOOTENTRY = 21,
|
||||
BIT_FLOW_STATUS_COLDBOOTEXIT = 22,
|
||||
BIT_FLOW_STATUS_CBSETUPBOOTDEVICE = 23,
|
||||
BIT_FLOW_STATUS_CBBCTDONE = 24,
|
||||
BIT_FLOW_STATUS_MSSREGIONUNINITIALIZED = 25,
|
||||
BIT_FLOW_STATUS_MSSREGIONENABLEINITIALIZED = 26,
|
||||
BIT_FLOW_STATUS_CBMTSPREBOOTINIT = 27,
|
||||
BIT_FLOW_STATUS_CBREINITSUCCESS = 28,
|
||||
BIT_FLOW_STATUS_CBSDRAMINITSUCCESS = 29,
|
||||
BIT_FLOW_STATUS_CBPAYLOADSUCCESS = 30,
|
||||
BIT_FLOW_STATUS_RCMENTRY = 31,
|
||||
BIT_FLOW_STATUS_RCMEXIT = 32,
|
||||
BIT_FLOW_STATUS_SC7ENTRY = 33,
|
||||
BIT_FLOW_STATUS_SC7ACKWAYPOINT = 34,
|
||||
BIT_FLOW_STATUS_SC7DBELLERROR = 35,
|
||||
BIT_FLOW_STATUS_SC7EXIT = 36,
|
||||
BIT_FLOW_STATUS_SECUREBOOTENTRY = 37,
|
||||
BIT_FLOW_STATUS_SECUREBOOTEXIT = 38,
|
||||
BIT_FLOW_STATUS_DETECTEDWDTRESET = 39,
|
||||
BIT_FLOW_STATUS_DETECTEDAOTAG_SENSORRESET = 40,
|
||||
BIT_FLOW_STATUS_DETECTEDVFSENSORRESET = 41,
|
||||
BIT_FLOW_STATUS_DETECTEDSWMAINRESET = 42,
|
||||
BIT_FLOW_STATUS_DETECTEDHSMRESET = 43,
|
||||
BIT_FLOW_STATUS_DETECTEDCSITEDBGRESET = 44,
|
||||
BIT_FLOW_STATUS_DETECTEDSC7SPEWDT_0_RESET = 45,
|
||||
BIT_FLOW_STATUS_DETECTEDSC7SPEWDT_1_RESET = 46,
|
||||
BIT_FLOW_STATUS_DETECTEDSYSRESETN = 47,
|
||||
BIT_FLOW_STATUS_CRYPTOINITENTRY = 48,
|
||||
BIT_FLOW_STATUS_CRYPTOINITEXIT = 49,
|
||||
BIT_FLOW_STATUS_SECUREEXITSTART = 50
|
||||
};
|
||||
|
||||
typedef struct _bit_flow_log_t
|
||||
{
|
||||
u32 Init_time;
|
||||
u32 exit_time;
|
||||
u32 func_id;
|
||||
u32 func_status;
|
||||
} bit_flow_log_t;
|
||||
|
||||
typedef struct _bit_boot_sdmmc_status_t210_t
|
||||
{
|
||||
u8 fuses_bus_width;
|
||||
u8 fuses_voltage_range;
|
||||
u8 fuses_boo_mode_disable;
|
||||
u8 fuses_drd_mode;
|
||||
|
||||
u32 card_type;
|
||||
u32 voltage_range;
|
||||
u8 bus_width;
|
||||
u8 power_class;
|
||||
u8 auto_cal_status;
|
||||
u8 padding;
|
||||
u32 cid[4];
|
||||
|
||||
u32 pages_read;
|
||||
u32 crc_errors;
|
||||
u8 boot_from_boot_partition;
|
||||
u8 boot_mode_read_success;
|
||||
} bit_boot_sdmmc_status_t210_t;
|
||||
|
||||
typedef struct _bit_boot_sdmmc_status_t210b01_t
|
||||
{
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
u8 clk_en;
|
||||
u8 clk_rst_status;
|
||||
u8 clk_div_internal;
|
||||
u8 data_mode;
|
||||
|
||||
u8 fuses_bus_width;
|
||||
u8 fuses_drd_mode;
|
||||
u8 fuses_config;
|
||||
u8 fuses_read_mode;
|
||||
|
||||
u8 card_type;
|
||||
u32 voltage_range;
|
||||
u8 bus_width;
|
||||
u8 power_class;
|
||||
u8 auto_cal_status;
|
||||
u32 cid[4];
|
||||
|
||||
u32 pages_read;
|
||||
u32 crc_errors;
|
||||
u8 boot_from_boot_partition;
|
||||
|
||||
u32 time_init;
|
||||
u32 time_controller_init;
|
||||
u32 time_card_enumeration;
|
||||
u32 time_cmd1_op_cond;
|
||||
u32 time_cmd2_cid;
|
||||
u32 time_cmd9_csd;
|
||||
u32 time_transfer_mode;
|
||||
u32 time_cmd8_ext_csd;
|
||||
u32 time_power_class;
|
||||
u32 time_bus_width_and_partition;
|
||||
u32 time_read;
|
||||
|
||||
u32 payload_size;
|
||||
} bit_boot_sdmmc_status_t210b01_t;
|
||||
|
||||
typedef struct _bit_boot_spi_status_t210_t
|
||||
{
|
||||
u32 clk_src;
|
||||
u32 clk_div;
|
||||
u32 fast_read;
|
||||
|
||||
u32 pages_read;
|
||||
u32 last_block_read;
|
||||
u32 last_page_read;
|
||||
|
||||
u32 boot_status;
|
||||
u32 init_status;
|
||||
u32 read_status;
|
||||
u32 params_validated;
|
||||
} bit_boot_spi_status_t210_t;
|
||||
|
||||
typedef struct _bit_boot_spi_status_t210b01_t
|
||||
{
|
||||
u32 clk_en;
|
||||
u32 clk_rst_status;
|
||||
u32 mode;
|
||||
u32 bus_width;
|
||||
u32 clk_src;
|
||||
u32 clk_div;
|
||||
u32 fast_read;
|
||||
|
||||
u32 pages_read;
|
||||
u32 last_block_read;
|
||||
u32 last_page_read;
|
||||
|
||||
u32 boot_status;
|
||||
u32 init_status;
|
||||
u32 read_status;
|
||||
u32 params_validated;
|
||||
|
||||
u32 time_qspi_init;
|
||||
u32 time_read_time;
|
||||
|
||||
u32 payload_size;
|
||||
} bit_boot_spi_status_t210b01_t;
|
||||
|
||||
typedef struct _bit_boot_usb3_status_t
|
||||
{
|
||||
u8 port;
|
||||
u8 sense_key;
|
||||
u8 padding[2];
|
||||
u32 cur_csw_tag;
|
||||
u32 curr_cmd_csw_status;
|
||||
u32 curr_ep_xfer_failed_bytes;
|
||||
u32 periph_dev_type;
|
||||
u32 block_num;
|
||||
u32 last_logical_block_addr;
|
||||
u32 block_length;
|
||||
u32 usb3_ctxt;
|
||||
u32 init_res;
|
||||
u32 read_page_res;
|
||||
u32 xusb_driver_status;
|
||||
u32 dev_status;
|
||||
u32 ep_status;
|
||||
} bit_boot_usb3_status_t;
|
||||
|
||||
typedef union _bit_boot_secondary_dev_status_t210_t
|
||||
{
|
||||
bit_boot_sdmmc_status_t210_t sdmmc_status;
|
||||
bit_boot_spi_status_t210_t spi_status;
|
||||
bit_boot_usb3_status_t usb3_status;
|
||||
|
||||
u8 padding[60];
|
||||
} bit_boot_secondary_dev_status_t210_t;
|
||||
|
||||
typedef union _bit_boot_secondary_dev_status_t210b01_t
|
||||
{
|
||||
bit_boot_sdmmc_status_t210b01_t sdmmc_status;
|
||||
bit_boot_spi_status_t210b01_t spi_status;
|
||||
|
||||
u8 padding[256];
|
||||
} bit_boot_secondary_dev_status_t210b01_t;
|
||||
|
||||
typedef struct _bit_bl_state_t
|
||||
{
|
||||
u32 read_status;
|
||||
|
||||
u32 first_ecc_block;
|
||||
u32 first_ecc_page;
|
||||
u32 first_corrected_ecc_block;
|
||||
u32 first_corrected_ecc_page;
|
||||
u8 had_ecc_error;
|
||||
u8 had_crc_error;
|
||||
u8 had_corrected_ecc_error;
|
||||
u8 used_for_ecc_recovery;
|
||||
} bit_bl_state_t;
|
||||
|
||||
typedef struct _tegra_bit_t210_t
|
||||
{
|
||||
u32 brom_version;
|
||||
u32 data_version;
|
||||
u32 rcm_version;
|
||||
|
||||
u32 boot_type;
|
||||
|
||||
u32 primary_dev_type;
|
||||
u32 secondary_dev_type;
|
||||
|
||||
u32 boot_time_log_init;
|
||||
u32 boot_time_log_exit;
|
||||
u32 bct_read_tick_cnt;
|
||||
u32 bl_read_tick_cnt;
|
||||
|
||||
u32 osc_frequency;
|
||||
u8 dev_initialized;
|
||||
u8 dram_initialized;
|
||||
|
||||
u8 force_recovery_bit_cleared; // APBDEV_PMC_SCRATCH0.
|
||||
u8 failback_bit_cleared; // APBDEV_PMC_SCRATCH0.
|
||||
u8 failback_invoked;
|
||||
|
||||
u8 irom_patch_status; // bit0-3: hamming status, bit7: patches exist.
|
||||
|
||||
u8 bct_valid;
|
||||
u8 bct_status[9]; // Each bit is a block (72 blocks).
|
||||
u32 bct_last_journal_read;
|
||||
u32 bct_block;
|
||||
u32 bct_page;
|
||||
u32 bct_size;
|
||||
u32 bct_ptr;
|
||||
|
||||
bit_bl_state_t bl_state[4];
|
||||
|
||||
bit_boot_secondary_dev_status_t210_t secondary_dev_status;
|
||||
|
||||
u32 usb_charging_status;
|
||||
|
||||
u32 safe_start_addr; // Init: 0x400000F4 / UART: 0x40000100 / BL: 0x40002900.
|
||||
|
||||
u8 padding[12];
|
||||
} tegra_bit_t210_t;
|
||||
|
||||
typedef struct _tegra_bit_t210b01_t
|
||||
{
|
||||
u32 brom_version;
|
||||
u32 data_version;
|
||||
u32 rcm_version;
|
||||
|
||||
u32 boot_type;
|
||||
|
||||
u32 primary_dev_type;
|
||||
u32 secondary_dev_type;
|
||||
|
||||
u32 authentication_scheme;
|
||||
u32 encryption_enabled;
|
||||
|
||||
u32 brom_flow_tracker;
|
||||
|
||||
u32 reserved;
|
||||
u32 boot_time_log_exit;
|
||||
u32 setup_tick_cnt;
|
||||
u32 bct_read_tick_cnt;
|
||||
u32 bl_read_tick_cnt;
|
||||
|
||||
bit_flow_log_t boot_flow_log[40];
|
||||
|
||||
u32 osc_frequency;
|
||||
u8 dev_initialized;
|
||||
u8 dram_initialized;
|
||||
|
||||
u8 force_recovery_bit_cleared;
|
||||
u8 failback_bit_cleared;
|
||||
u8 failback_invoked;
|
||||
|
||||
u8 irom_patch_status; // bit0-3: hamming status, bit7: patches exist.
|
||||
|
||||
u8 bct_size_valid;
|
||||
u8 bct_size_status[9];
|
||||
u32 bct_size_last_journal_read;
|
||||
u32 bct_size_block;
|
||||
u32 bct_size_page;
|
||||
|
||||
u8 bct_valid;
|
||||
u8 bct_status[9];
|
||||
u8 padding[2];
|
||||
u32 bct_last_journal_read;
|
||||
u32 bct_block;
|
||||
u32 bct_page;
|
||||
u32 bct_size;
|
||||
u32 bct_ptr;
|
||||
|
||||
bit_bl_state_t bl_state[4];
|
||||
|
||||
bit_boot_secondary_dev_status_t210b01_t secondary_dev_status;
|
||||
|
||||
u32 usb_charging_status;
|
||||
|
||||
u8 pmu_boot_sel_read_error;
|
||||
|
||||
u32 safe_start_addr; // Init: 0x40000464 / UART: 0x40000464 / BL: 0x40002C64.
|
||||
} tegra_bit_t210b01_t;
|
||||
|
||||
#endif
|
||||
@@ -110,7 +110,6 @@ typedef unsigned long uptr;
|
||||
#define BOOT_CFG_FROM_LAUNCH BIT(1)
|
||||
#define BOOT_CFG_FROM_ID BIT(2)
|
||||
#define BOOT_CFG_TO_EMUMMC BIT(3)
|
||||
#define BOOT_CFG_SEPT_RUN BIT(7)
|
||||
|
||||
#define EXTRA_CFG_KEYS BIT(0)
|
||||
#define EXTRA_CFG_PAYLOAD BIT(1)
|
||||
|
||||
@@ -202,27 +202,6 @@ void reg_write_array(u32 *base, const reg_cfg_t *cfg, u32 num_cfg)
|
||||
base[cfg[i].idx] = cfg[i].val;
|
||||
}
|
||||
|
||||
u16 crc16_calc(const u8 *buf, u32 len)
|
||||
{
|
||||
const u8 *p, *q;
|
||||
u16 crc = 0x55aa;
|
||||
|
||||
static u16 table[16] = {
|
||||
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
|
||||
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
|
||||
};
|
||||
|
||||
q = buf + len;
|
||||
for (p = buf; p < q; p++)
|
||||
{
|
||||
u8 oct = *p;
|
||||
crc = (crc >> 4) ^ table[crc & 0xf] ^ table[(oct >> 0) & 0xf];
|
||||
crc = (crc >> 4) ^ table[crc & 0xf] ^ table[(oct >> 4) & 0xf];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
|
||||
{
|
||||
const u8 *p, *q;
|
||||
@@ -308,7 +287,7 @@ void power_set_state(power_state_t state)
|
||||
break;
|
||||
|
||||
case REBOOT_BYPASS_FUSES:
|
||||
panic(0x21); // Bypass fuse programming in package1.
|
||||
panic(PMC_NX_PANIC_BYPASS_FUSES); // Bypass fuse programming in package1.
|
||||
break;
|
||||
|
||||
case POWER_OFF:
|
||||
|
||||
@@ -51,12 +51,6 @@ typedef enum
|
||||
ERR_EXCEPTION = BIT(31),
|
||||
} hekate_errors_t;
|
||||
|
||||
typedef struct _cfg_op_t
|
||||
{
|
||||
u32 off;
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
typedef struct _reg_cfg_t
|
||||
{
|
||||
u32 idx;
|
||||
@@ -93,8 +87,6 @@ long strtol(const char *nptr, char **endptr, register int base);
|
||||
int atoi(const char *nptr);
|
||||
|
||||
void reg_write_array(u32 *base, const reg_cfg_t *cfg, u32 num_cfg);
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
u16 crc16_calc(const u8 *buf, u32 len);
|
||||
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
|
||||
|
||||
int qsort_compare_int(const void *a, const void *b);
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <utils/list.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define EMC_SEPT_RUN BIT(31)
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
void set_default_configuration()
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define BOOT_CFG_SEPT_RUN BIT(7)
|
||||
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
|
||||
#define WB_RST_ADDR 0x40010ED0
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#include "fs/fstypes.h"
|
||||
#include "fs/menus/filemenu.h"
|
||||
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||
#define IPL_STACK_TOP 0x83100000
|
||||
|
||||
hekate_config h_cfg;
|
||||
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
|
||||
|
||||
@@ -121,6 +121,120 @@ void DumpSysFw(){
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "../config.h"
|
||||
#include <libs/fatfs/diskio.h>
|
||||
#include <storage/emmc.h>
|
||||
#include "../storage/emummc.h"
|
||||
#include <storage/sd.h>
|
||||
#include <storage/nx_emmc_bis.h>
|
||||
|
||||
#define MBR_Table 446 /* MBR: Offset of partition table in the MBR */
|
||||
#define SZ_PTE 16 /* MBR: Size of a partition table entry */
|
||||
#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; }
|
||||
|
||||
|
||||
/* Fill memory block */
|
||||
static void mem_set (void* dst, int val, UINT cnt)
|
||||
{
|
||||
BYTE *d = (BYTE*)dst;
|
||||
|
||||
do {
|
||||
*d++ = (BYTE)val;
|
||||
} while (--cnt);
|
||||
}
|
||||
|
||||
static void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */
|
||||
{
|
||||
*ptr++ = (BYTE)val; val >>= 8;
|
||||
*ptr++ = (BYTE)val;
|
||||
}
|
||||
|
||||
static void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */
|
||||
{
|
||||
*ptr++ = (BYTE)val; val >>= 8;
|
||||
*ptr++ = (BYTE)val; val >>= 8;
|
||||
*ptr++ = (BYTE)val; val >>= 8;
|
||||
*ptr++ = (BYTE)val;
|
||||
}
|
||||
|
||||
FRESULT f_fdisk_mod (
|
||||
BYTE pdrv, /* Physical drive number */
|
||||
const DWORD* szt, /* Pointer to the size table for each partitions */
|
||||
void* work
|
||||
)
|
||||
{
|
||||
UINT i, n, sz_cyl, tot_cyl, e_cyl;
|
||||
BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
|
||||
DSTATUS stat;
|
||||
DWORD sz_disk, p_sect, b_cyl, b_sect;
|
||||
FRESULT res;
|
||||
|
||||
stat = disk_initialize(pdrv);
|
||||
if (stat & STA_NOINIT) return FR_NOT_READY;
|
||||
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
|
||||
sz_disk = sd_storage.csd.capacity;
|
||||
|
||||
if (!buf) return FR_NOT_ENOUGH_CORE;
|
||||
|
||||
/* Determine the CHS without any consideration of the drive geometry */
|
||||
for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
|
||||
if (n == 256) n--;
|
||||
e_hd = (BYTE)(n - 1);
|
||||
sz_cyl = 63 * n;
|
||||
tot_cyl = sz_disk / sz_cyl;
|
||||
|
||||
/* Create partition table */
|
||||
mem_set(buf, 0, 0x10000);
|
||||
p = buf + MBR_Table; b_cyl = 0, b_sect = 0;
|
||||
for (i = 0; i < 4; i++, p += SZ_PTE) {
|
||||
p_sect = szt[i]; /* Number of sectors */
|
||||
|
||||
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 */
|
||||
|
||||
if (e_cyl >= tot_cyl)
|
||||
LEAVE_MKFS(FR_INVALID_PARAMETER);
|
||||
|
||||
|
||||
/* Set partition table */
|
||||
p[1] = s_hd; /* Start head */
|
||||
p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1); /* Start sector */
|
||||
p[3] = (BYTE)b_cyl; /* Start cylinder */
|
||||
p[4] = 0x07; /* System type (temporary setting) */
|
||||
p[5] = e_hd; /* End head */
|
||||
p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */
|
||||
p[7] = (BYTE)e_cyl; /* End cylinder */
|
||||
st_dword(p + 8, b_sect); /* Start sector in LBA */
|
||||
st_dword(p + 12, p_sect); /* Number of sectors */
|
||||
/* Next partition */
|
||||
|
||||
for (u32 cursect = 0; cursect < 512; cursect++){
|
||||
disk_write(pdrv, buf + 0x4000, b_sect + (64 * cursect), 64);
|
||||
}
|
||||
|
||||
b_sect += p_sect;
|
||||
}
|
||||
st_word(p, 0xAA55); /* MBR signature (always at offset 510) */
|
||||
|
||||
/* Write it to the MBR */
|
||||
res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
|
||||
LEAVE_MKFS(res);
|
||||
}
|
||||
|
||||
|
||||
MenuEntry_t FatAndEmu[] = {
|
||||
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Back to main menu"},
|
||||
{.optionUnion = COLORTORGB(COLOR_GREEN), .name = "Fat32 + EmuMMC"},
|
||||
|
||||
Reference in New Issue
Block a user