Merge branch 'master' of https://github.com/CTCaer/hekate
All checks were successful
Build / Build (push) Successful in 26s
All checks were successful
Build / Build (push) Successful in 26s
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
# IPL Version.
|
# IPL Version.
|
||||||
BLVERSION_MAJOR := 6
|
BLVERSION_MAJOR := 6
|
||||||
BLVERSION_MINOR := 5
|
BLVERSION_MINOR := 5
|
||||||
BLVERSION_HOTFX := 2
|
BLVERSION_HOTFX := 3
|
||||||
BLVERSION_REL := 0
|
BLVERSION_REL := 0
|
||||||
|
|
||||||
# Nyx Version.
|
# Nyx Version.
|
||||||
NYXVERSION_MAJOR := 1
|
NYXVERSION_MAJOR := 1
|
||||||
NYXVERSION_MINOR := 9
|
NYXVERSION_MINOR := 9
|
||||||
NYXVERSION_HOTFX := 2
|
NYXVERSION_HOTFX := 3
|
||||||
NYXVERSION_REL := 0
|
NYXVERSION_REL := 0
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Header for MultiMediaCard (MMC)
|
* Header for MultiMediaCard (MMC)
|
||||||
*
|
*
|
||||||
* Copyright 2002 Hewlett-Packard Company
|
* Copyright 2002 Hewlett-Packard Company
|
||||||
* Copyright 2018-2021 CTCaer
|
* Copyright 2018-2026 CTCaer
|
||||||
*
|
*
|
||||||
* Use consistent with the GNU GPL is permitted,
|
* Use consistent with the GNU GPL is permitted,
|
||||||
* provided that this copyright notice is
|
* provided that this copyright notice is
|
||||||
@@ -44,14 +44,11 @@
|
|||||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
#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 */
|
/* class 2 */
|
||||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
#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_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* 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 */
|
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||||
|
|
||||||
/* class 3 */
|
/* class 3 */
|
||||||
@@ -63,11 +60,13 @@
|
|||||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||||
|
#define MMC_SET_TIME 49 /* adtc R1 */
|
||||||
|
|
||||||
/* class 6 */
|
/* class 6 */
|
||||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
#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_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||||
|
#define MMC_SEND_WR_PROTECT_TYPE 31 /* adtc [31:0] wpdata addr R1 */
|
||||||
|
|
||||||
/* class 5 */
|
/* class 5 */
|
||||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||||
@@ -85,18 +84,23 @@
|
|||||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||||
|
|
||||||
#define MMC_VENDOR_60_CMD 60 /* Vendor Defined */
|
/* class 10 */
|
||||||
#define MMC_VENDOR_61_CMD 61 /* Vendor Defined */
|
#define MMC_PROTOCOL_RD 53 /* adtc R1 */
|
||||||
#define MMC_VENDOR_62_CMD 62 /* Vendor Defined */
|
#define MMC_PROTOCOL_WR 54 /* adtc R1 */
|
||||||
#define MMC_VENDOR_63_CMD 63 /* Vendor Defined */
|
|
||||||
|
|
||||||
/* class 11 */
|
/* class 11 */
|
||||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
#define MMC_QUEUED_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
#define MMC_QUEUED_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id 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_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||||
|
|
||||||
|
/* class 12 */
|
||||||
|
#define MMC_VENDOR_CMD_60 60 /* Vendor Defined */
|
||||||
|
#define MMC_VENDOR_CMD_61 61 /* Vendor Defined */
|
||||||
|
#define MMC_VENDOR_CMD_62 62 /* Vendor Defined */
|
||||||
|
#define MMC_VENDOR_CMD_63 63 /* Vendor Defined */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMC_SWITCH argument format:
|
* MMC_SWITCH argument format:
|
||||||
*
|
*
|
||||||
@@ -163,36 +167,15 @@
|
|||||||
#define R1_STATE_PRG 7
|
#define R1_STATE_PRG 7
|
||||||
#define R1_STATE_DIS 8
|
#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
|
* OCR bits are mostly in host.h
|
||||||
*/
|
*/
|
||||||
#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */
|
#define MMC_OCR_VCCQ_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_OCR_VCCQ_20_26 (0x7F << 8) /* Card VDD voltage 2.0 ~ 2.6 */
|
||||||
#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */
|
#define MMC_OCR_VCCQ_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
|
||||||
#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */
|
#define MMC_OCR_HCS (2 << 29) /* Host Capacity status bit */
|
||||||
|
#define MMC_OCR_CCS MMC_OCR_HCS /* Card Capacity status bit */
|
||||||
|
#define MMC_OCR_BUSY (1 << 31) /* Card Power up status bit */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Card Command Classes (CCC)
|
* Card Command Classes (CCC)
|
||||||
@@ -342,23 +325,19 @@
|
|||||||
|
|
||||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
#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_52 (1<<1) /* Card can run at 52MHz */
|
||||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
|
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | EXT_CSD_CARD_TYPE_HS_52)
|
||||||
EXT_CSD_CARD_TYPE_HS_52)
|
|
||||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||||
/* DDR mode @1.8V or 3V I/O */
|
/* DDR mode @1.8V or 3V I/O */
|
||||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||||
/* DDR mode @1.2V I/O */
|
/* DDR mode @1.2V I/O */
|
||||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||||
| 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_8V (1<<4) /* Card can run at 200MHz */
|
||||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* 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 */
|
/* SDR mode @1.2V I/O */
|
||||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||||
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_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_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 | \
|
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||||
EXT_CSD_CARD_TYPE_HS400_1_2V)
|
|
||||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
#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_1 0 /* Card is in 1 bit mode */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||||
* Copyright (c) 2018-2025 CTCaer
|
* Copyright (c) 2018-2026 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,27 +16,52 @@
|
|||||||
/* This is basically the same command as for MMC with some quirks. */
|
/* This is basically the same command as for MMC with some quirks. */
|
||||||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||||
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
||||||
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
#define SD_VOLTAGE_SWITCH 11 /* ac R1 */
|
||||||
|
/* Class 1 */
|
||||||
|
#define SD_Q_MANAGEMENT 43 /* ac R1b */
|
||||||
|
#define SD_Q_TASK_INFO_A 44 /* ac R1 */
|
||||||
|
#define SD_Q_TASK_INFO_B 45 /* ac R1 */
|
||||||
|
#define SD_Q_RD_TASK 46 /* adtc R1 */
|
||||||
|
#define SD_Q_WR_TASK 47 /* adtc R1 */
|
||||||
/* Class 2 */
|
/* Class 2 */
|
||||||
#define SD_ADDR_EXT 22 /* ac [5:0] R1 */
|
#define SD_SEND_TUNING_BLOCK 19 /* ac R1b */
|
||||||
/* class 10 */
|
#define SD_SPEED_CLASS_CONTROL 20 /* ac [31:0] R1 */
|
||||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
#define SD_ADDRESS_EXTENSION 22 /* ac [5:0] UC ext addr R1 */
|
||||||
/* class 5 */
|
/* class 5 */
|
||||||
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
|
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
|
||||||
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
||||||
|
/* Class 9 */
|
||||||
|
#define SD_IO_SEND_OP_COND 5 /* bcr [31:0] OCR R4 */
|
||||||
|
#define SD_IO_RW_DIRECT 52 /* ac R5 */
|
||||||
|
#define SD_IO_RW_EXTENDED 53 /* adtc R5 */
|
||||||
|
/* class 10 */
|
||||||
|
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||||
|
#define SD_CMD_SYSTEM_34 34 /* cmd system defined */
|
||||||
|
#define SD_CMD_SYSTEM_35 35 /* cmd system defined */
|
||||||
|
#define SD_CMD_SYSTEM_36 36 /* cmd system defined */
|
||||||
|
#define SD_CMD_SYSTEM_37 37 /* cmd system defined */
|
||||||
|
#define SD_CMD_SYSTEM_50 50 /* cmd system defined */
|
||||||
|
#define SD_CMD_SYSTEM_57 57 /* cmd system defined */
|
||||||
/* class 11 */
|
/* class 11 */
|
||||||
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
|
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
|
||||||
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
|
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
|
||||||
|
#define SD_READ_EXTR_MULTI 58 /* adtc [31:0] R1 */
|
||||||
|
#define SD_WRITE_EXTR_MULTI 59 /* adtc [31:0] R1 */
|
||||||
|
#define SD_VENDOR_CMD_60 60 /* vendor defined */
|
||||||
|
#define SD_VENDOR_CMD_61 61 /* vendor defined */
|
||||||
|
#define SD_VENDOR_CMD_62 62 /* vendor defined */
|
||||||
|
#define SD_VENDOR_CMD_63 63 /* vendor defined */
|
||||||
|
|
||||||
/* Application commands */
|
/* Application commands */
|
||||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
||||||
#define SD_APP_SD_STATUS 13 /* adtc R1 */
|
#define SD_APP_SD_STATUS 13 /* adtc R1 */
|
||||||
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
|
#define SD_APP_SEND_NUM_WR_BLOCKS 22 /* adtc R1 */
|
||||||
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
|
#define SD_APP_SET_WR_BLK_ERASE_COUNT 23 /* ac R1 */
|
||||||
|
#define SD_APP_SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */
|
||||||
#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */
|
#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */
|
||||||
#define SD_APP_SEND_SCR 51 /* adtc R1 */
|
#define SD_APP_SEND_SCR 51 /* adtc R1 */
|
||||||
|
|
||||||
/* Application secure commands */
|
/* Application sd secure commands */
|
||||||
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
|
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
|
||||||
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
|
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
|
||||||
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
|
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
|
||||||
@@ -49,14 +74,33 @@
|
|||||||
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
|
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
|
||||||
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
|
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
|
||||||
|
|
||||||
|
/* ICR bit definitions */
|
||||||
|
#define SD_ICR_PATTERN 0xAA /* Check pattern */
|
||||||
|
#define SD_ICR_VHS_27_36 (1U << 8) /* VDD IO voltage 2.7 ~ 3.6 */
|
||||||
|
#define SD_ICR_VHS_170_195 (2U << 8) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only) */
|
||||||
|
#define SD_ICR_PCIE (1U << 12) /* PCIE availability */
|
||||||
|
#define SD_ICR_PCIE_12 (1U << 13) /* PCIE IO voltage 1.2 */
|
||||||
|
|
||||||
/* OCR bit definitions */
|
/* OCR bit definitions */
|
||||||
#define SD_OCR_VDD_18 (1U << 7) /* VDD voltage 1.8 */
|
#define SD_OCR_VDD_170_195 (1U << 7) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only or support) */
|
||||||
#define SD_VHS_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
|
#define SD_OCR_VDD_27_28 (1U << 15) /* VDD IO voltage 2.7 ~ 2.8 */
|
||||||
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD voltage 3.2 ~ 3.3 */
|
#define SD_OCR_VDD_28_29 (1U << 16) /* VDD IO voltage 2.8 ~ 2.9 */
|
||||||
|
#define SD_OCR_VDD_29_30 (1U << 17) /* VDD IO voltage 2.9 ~ 3.0 */
|
||||||
|
#define SD_OCR_VDD_30_31 (1U << 18) /* VDD IO voltage 3.0 ~ 3.1 */
|
||||||
|
#define SD_OCR_VDD_31_32 (1U << 19) /* VDD IO voltage 3.1 ~ 3.2 */
|
||||||
|
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD IO voltage 3.2 ~ 3.3 */
|
||||||
|
#define SD_OCR_VDD_33_34 (1U << 21) /* VDD IO voltage 3.3 ~ 3.4 */
|
||||||
|
#define SD_OCR_VDD_34_35 (1U << 22) /* VDD IO voltage 3.4 ~ 3.5 */
|
||||||
|
#define SD_OCR_VDD_35_36 (1U << 23) /* VDD IO voltage 3.5 ~ 3.6 */
|
||||||
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
|
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
|
||||||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
#define SD_OCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||||
#define SD_OCR_XPC (1U << 28) /* SDXC power control */
|
#define SD_OCR_HO2T (1U << 27) /* SDUC support */
|
||||||
#define SD_OCR_CCS (1U << 30) /* Card Capacity Status */
|
#define SD_OCR_CO2T SD_OCR_HO2T /* SDUC Status */
|
||||||
|
#define SD_OCR_XPC (1U << 28) /* SDXC power control - Max Performance */
|
||||||
|
#define SD_OCR_FB (1U << 29) /* eSD Fast Boot Support */
|
||||||
|
#define SD_OCR_UHSII (1U << 29) /* UHS-II Card Status */
|
||||||
|
#define SD_OCR_HCS (1U << 30) /* Host Capacity Support */
|
||||||
|
#define SD_OCR_CCS SD_OCR_HCS /* Card Capacity Status */
|
||||||
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
|
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -79,7 +79,17 @@ static int _sdmmc_storage_check_card_status(u32 res)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
|
static int _sdmmc_storage_check_cached_card_status(sdmmc_t *sdmmc)
|
||||||
|
{
|
||||||
|
u32 resp;
|
||||||
|
sdmmc_get_cached_rsp(sdmmc, &resp, SDMMC_RSP_TYPE_1);
|
||||||
|
if (_sdmmc_storage_check_card_status(resp))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sdmmc_storage_execute_cmd_ex_masked(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);
|
sdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);
|
||||||
@@ -97,10 +107,10 @@ static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *re
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
|
static int _sdmmc_storage_execute_cmd_ex_state(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
return _sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, cmd, arg, check_busy, expected_state, 0);
|
return _sdmmc_storage_execute_cmd_ex_masked(storage, &tmp, cmd, arg, check_busy, expected_state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)
|
static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)
|
||||||
@@ -125,7 +135,7 @@ static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage)
|
|||||||
|
|
||||||
static int _sdmmc_storage_select_card(sdmmc_storage_t *storage)
|
static int _sdmmc_storage_select_card(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, R1_SKIP_STATE_CHECK);
|
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SELECT_CARD, storage->rca << 16, 1, R1_SKIP_STATE_CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
|
static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
|
||||||
@@ -142,12 +152,12 @@ static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
|
|||||||
|
|
||||||
static int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)
|
static int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)
|
||||||
{
|
{
|
||||||
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);
|
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)
|
static int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)
|
||||||
{
|
{
|
||||||
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);
|
return _sdmmc_storage_execute_cmd_ex_masked(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
|
static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
|
||||||
@@ -156,11 +166,11 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
|
|||||||
return _sdmmc_storage_get_status(storage, &tmp, 0);
|
return _sdmmc_storage_get_status(storage, &tmp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
|
int sdmmc_storage_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_62_CMD, arg, SDMMC_RSP_TYPE_1, 1);
|
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_62, arg, SDMMC_RSP_TYPE_1, 1);
|
||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 resp;
|
u32 resp;
|
||||||
@@ -186,14 +196,14 @@ int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
|
|||||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
|
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
|
||||||
{
|
{
|
||||||
// Request health report.
|
// Request health report.
|
||||||
if (sdmmc_storage_execute_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT))
|
if (sdmmc_storage_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_req_t reqbuf;
|
sdmmc_req_t reqbuf;
|
||||||
|
|
||||||
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_63_CMD, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0.
|
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_63, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0.
|
||||||
|
|
||||||
reqbuf.buf = buf;
|
reqbuf.buf = buf;
|
||||||
reqbuf.num_sectors = 1;
|
reqbuf.num_sectors = 1;
|
||||||
@@ -202,16 +212,39 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
|
|||||||
reqbuf.is_multi_block = 0;
|
reqbuf.is_multi_block = 0;
|
||||||
reqbuf.is_auto_stop_trn = 0;
|
reqbuf.is_auto_stop_trn = 0;
|
||||||
|
|
||||||
u32 blkcnt_out;
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, &blkcnt_out))
|
|
||||||
{
|
{
|
||||||
sdmmc_stop_transmission(storage->sdmmc, &tmp);
|
|
||||||
_sdmmc_storage_get_status(storage, &tmp, 0);
|
_sdmmc_storage_get_status(storage, &tmp, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sdmmc_storage_gen_cmd(sdmmc_storage_t *storage, u32 arg, void *buf)
|
||||||
|
{
|
||||||
|
u32 tmp = 0;
|
||||||
|
sdmmc_cmd_t cmdbuf;
|
||||||
|
sdmmc_req_t reqbuf;
|
||||||
|
|
||||||
|
sdmmc_init_cmd(&cmdbuf, MMC_GEN_CMD, arg, SDMMC_RSP_TYPE_1, 0);
|
||||||
|
|
||||||
|
reqbuf.buf = buf;
|
||||||
|
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||||
|
reqbuf.num_sectors = 1;
|
||||||
|
reqbuf.is_write = !(arg & 1);
|
||||||
|
reqbuf.is_multi_block = 0;
|
||||||
|
reqbuf.is_auto_stop_trn = 0;
|
||||||
|
|
||||||
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
|
{
|
||||||
|
_sdmmc_storage_get_status(storage, &tmp, 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||||
@@ -241,11 +274,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
if (_sdmmc_storage_check_card_status(tmp))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdmmc_storage_end(sdmmc_storage_t *storage)
|
int sdmmc_storage_end(sdmmc_storage_t *storage)
|
||||||
@@ -401,7 +430,7 @@ int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v
|
|||||||
* MMC specific functions.
|
* MMC specific functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power)
|
static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *rocr, u32 power)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
|
|
||||||
@@ -409,11 +438,11 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
|||||||
switch (power)
|
switch (power)
|
||||||
{
|
{
|
||||||
case SDMMC_POWER_1_8:
|
case SDMMC_POWER_1_8:
|
||||||
arg = MMC_CARD_CCS | MMC_CARD_VDD_18;
|
arg = MMC_OCR_HCS | MMC_OCR_VCCQ_18;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDMMC_POWER_3_3:
|
case SDMMC_POWER_3_3:
|
||||||
arg = MMC_CARD_CCS | MMC_CARD_VDD_27_34;
|
arg = MMC_OCR_HCS | MMC_OCR_VCCQ_27_34;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -424,7 +453,7 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
|||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return sdmmc_get_cached_rsp(storage->sdmmc, pout, SDMMC_RSP_TYPE_3);
|
return sdmmc_get_cached_rsp(storage->sdmmc, rocr, SDMMC_RSP_TYPE_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
||||||
@@ -433,15 +462,15 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
u32 cond = 0;
|
u32 rocr = 0;
|
||||||
if (_mmc_storage_get_op_cond_inner(storage, &cond, power))
|
if (_mmc_storage_get_op_cond_inner(storage, &rocr, power))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check if power up is done.
|
// Check if power up is done.
|
||||||
if (cond & MMC_CARD_BUSY)
|
if (rocr & MMC_OCR_BUSY)
|
||||||
{
|
{
|
||||||
// Check if card is high capacity.
|
// Check if card is high capacity.
|
||||||
if (cond & MMC_CARD_CCS)
|
if (rocr & MMC_OCR_CCS)
|
||||||
storage->has_sector_access = 1;
|
storage->has_sector_access = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -457,7 +486,7 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
|||||||
|
|
||||||
static int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)
|
static int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, R1_SKIP_STATE_CHECK);
|
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, R1_SKIP_STATE_CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
|
static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
|
||||||
@@ -562,44 +591,14 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage)
|
|||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 tmp = 0;
|
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
_mmc_storage_parse_ext_csd(storage);
|
_mmc_storage_parse_ext_csd(storage);
|
||||||
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
}
|
|
||||||
|
|
||||||
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 address, u32 len, void *buf)
|
|
||||||
{
|
|
||||||
if (!(storage->scr.cmds & BIT(2)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
sdmmc_cmd_t cmdbuf;
|
|
||||||
|
|
||||||
u32 arg = fno << 27 | page << 18 | address << 9 | (len - 1);
|
|
||||||
|
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_READ_EXTR_SINGLE, arg, SDMMC_RSP_TYPE_1, 0);
|
|
||||||
|
|
||||||
sdmmc_req_t reqbuf;
|
|
||||||
reqbuf.buf = buf;
|
|
||||||
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
|
||||||
reqbuf.num_sectors = 1;
|
|
||||||
reqbuf.is_write = 0;
|
|
||||||
reqbuf.is_multi_block = 0;
|
|
||||||
reqbuf.is_auto_stop_trn = 0;
|
|
||||||
|
|
||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
u32 tmp = 0;
|
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)
|
static int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)
|
||||||
{
|
{
|
||||||
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, R1_SKIP_STATE_CHECK);
|
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SWITCH, arg, 1, R1_SKIP_STATE_CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
|
static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
|
||||||
@@ -828,18 +827,18 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
|
|||||||
static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmdbuf, sdmmc_req_t *req, u32 *blkcnt_out)
|
static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmdbuf, sdmmc_req_t *req, u32 *blkcnt_out)
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
if (_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
|
if (_sdmmc_storage_execute_cmd_ex_masked(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return sdmmc_execute_cmd(storage->sdmmc, cmdbuf, req, blkcnt_out);
|
return sdmmc_execute_cmd(storage->sdmmc, cmdbuf, req, blkcnt_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
|
static int _sd_storage_execute_app_cmd_tran(sdmmc_storage_t *storage, u32 cmd, u32 arg)
|
||||||
{
|
{
|
||||||
if (_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))
|
if (_sdmmc_storage_execute_cmd_ex_state(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
|
return _sdmmc_storage_execute_cmd_ex_state(storage, cmd, arg, 0, R1_STATE_TRAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||||
@@ -898,23 +897,23 @@ void _sd_storage_debug_print_csd(const u32 *raw_csd)
|
|||||||
|
|
||||||
void _sd_storage_debug_print_scr(const u32 *raw_scr)
|
void _sd_storage_debug_print_scr(const u32 *raw_scr)
|
||||||
{
|
{
|
||||||
u32 resp[4];
|
u32 scr[4];
|
||||||
memcpy(&resp[2], raw_scr, 8);
|
memcpy(&scr[2], raw_scr, 8);
|
||||||
|
|
||||||
gfx_printf("\n");
|
gfx_printf("\n");
|
||||||
|
|
||||||
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(resp, 60, 4));
|
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(scr, 60, 4));
|
||||||
gfx_printf("SD_SPEC: %X\n", unstuff_bits(resp, 56, 4));
|
gfx_printf("SD_SPEC: %X\n", unstuff_bits(scr, 56, 4));
|
||||||
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(resp, 55, 1));
|
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(scr, 55, 1));
|
||||||
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(resp, 52, 3));
|
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(scr, 52, 3));
|
||||||
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(resp, 48, 4));
|
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(scr, 48, 4));
|
||||||
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(resp, 47, 1));
|
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(scr, 47, 1));
|
||||||
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(resp, 43, 4));
|
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(scr, 43, 4));
|
||||||
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(resp, 42, 1));
|
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(scr, 42, 1));
|
||||||
gfx_printf("SD_SPECX: %X\n", unstuff_bits(resp, 38, 4));
|
gfx_printf("SD_SPECX: %X\n", unstuff_bits(scr, 38, 4));
|
||||||
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(resp, 32, 4));
|
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(scr, 32, 4));
|
||||||
gfx_printf("VENDOR: %08X\n", unstuff_bits(resp, 0, 32));
|
gfx_printf("VENDOR: %08X\n", unstuff_bits(scr, 0, 32));
|
||||||
gfx_printf("--RSVD-- %X\n", unstuff_bits(resp, 36, 2));
|
gfx_printf("--RSVD-- %X\n", unstuff_bits(scr, 36, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
||||||
@@ -952,11 +951,6 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
|||||||
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313, 1));
|
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313, 1));
|
||||||
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312, 1));
|
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312, 1));
|
||||||
|
|
||||||
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
|
|
||||||
unstuff_bits(raw_ssr0, 496, 6), unstuff_bits(raw_ssr0, 424, 4),
|
|
||||||
unstuff_bits(raw_ssr1, 378, 6), unstuff_bits(raw_ssr1, 340, 6),
|
|
||||||
unstuff_bits(raw_ssr1, 314, 14));
|
|
||||||
|
|
||||||
gfx_printf("VENDOR_1: %06X %08X\n",
|
gfx_printf("VENDOR_1: %06X %08X\n",
|
||||||
unstuff_bits(raw_ssr1, 288, 24), unstuff_bits(raw_ssr1, 256, 32));
|
unstuff_bits(raw_ssr1, 288, 24), unstuff_bits(raw_ssr1, 256, 32));
|
||||||
|
|
||||||
@@ -966,81 +960,174 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
|
|||||||
gfx_printf("VENDOR_3: %08X %08X %08X %08X\n",
|
gfx_printf("VENDOR_3: %08X %08X %08X %08X\n",
|
||||||
unstuff_bits(raw_ssr3, 96 - 0, 32), unstuff_bits(raw_ssr3, 64, 32),
|
unstuff_bits(raw_ssr3, 96 - 0, 32), unstuff_bits(raw_ssr3, 64, 32),
|
||||||
unstuff_bits(raw_ssr3, 32 - 0, 32), unstuff_bits(raw_ssr3, 0, 32));
|
unstuff_bits(raw_ssr3, 32 - 0, 32), unstuff_bits(raw_ssr3, 0, 32));
|
||||||
|
|
||||||
|
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
|
||||||
|
unstuff_bits(raw_ssr0, 496, 6), unstuff_bits(raw_ssr0, 424, 4),
|
||||||
|
unstuff_bits(raw_ssr1, 378, 6), unstuff_bits(raw_ssr1, 340, 6),
|
||||||
|
unstuff_bits(raw_ssr1, 314, 14));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
|
void sd_storage_get_vendor_info(sdmmc_storage_t *storage, sd_vendor_info_t *info)
|
||||||
|
{
|
||||||
|
// CID Reserved.
|
||||||
|
info->cid_rsvd = storage->cid.rsvd;
|
||||||
|
|
||||||
|
// CSD Reserved.
|
||||||
|
info->csd_rsvd8_9 = unstuff_bits((u32 *)storage->raw_csd, 8, 2);
|
||||||
|
info->csd_rsvd16_20 = unstuff_bits((u32 *)storage->raw_csd, 16, 5);
|
||||||
|
info->csd_rsvd29_30 = unstuff_bits((u32 *)storage->raw_csd, 29, 2);
|
||||||
|
info->csd_rsvd120_125 = unstuff_bits((u32 *)storage->raw_csd, 120, 6);
|
||||||
|
|
||||||
|
// SCR Vendor and Reserved.
|
||||||
|
u32 scr[4];
|
||||||
|
memcpy(&scr[2], storage->raw_scr, 8);
|
||||||
|
info->scr_vendor = storage->scr.vendor;
|
||||||
|
info->scr_rsvd = unstuff_bits(scr, 36, 2);
|
||||||
|
|
||||||
|
// SSR Vendor and Reserved.
|
||||||
|
u32 raw_ssr0[4]; // 511:384.
|
||||||
|
u32 raw_ssr1[4]; // 383:256.
|
||||||
|
u32 raw_ssr2[4]; // 255:128.
|
||||||
|
u32 raw_ssr3[4]; // 127:0.
|
||||||
|
memcpy(raw_ssr0, &storage->raw_ssr[0], 16);
|
||||||
|
memcpy(raw_ssr1, &storage->raw_ssr[16], 16);
|
||||||
|
memcpy(raw_ssr2, &storage->raw_ssr[32], 16);
|
||||||
|
memcpy(raw_ssr3, &storage->raw_ssr[48], 16);
|
||||||
|
info->ssr_vendor0_31 = unstuff_bits(raw_ssr3, 0, 32);
|
||||||
|
info->ssr_vendor32_63 = unstuff_bits(raw_ssr3, 32, 32);
|
||||||
|
info->ssr_vendor64_95 = unstuff_bits(raw_ssr3, 64, 32);
|
||||||
|
info->ssr_vendor96_127 = unstuff_bits(raw_ssr3, 96, 32);
|
||||||
|
info->ssr_vendor128_159 = unstuff_bits(raw_ssr2, 128, 32);
|
||||||
|
info->ssr_vendor160_191 = unstuff_bits(raw_ssr2, 160, 32);
|
||||||
|
info->ssr_vendor192_223 = unstuff_bits(raw_ssr2, 192, 32);
|
||||||
|
info->ssr_vendor224_255 = unstuff_bits(raw_ssr2, 224, 32);
|
||||||
|
info->ssr_vendor256_287 = unstuff_bits(raw_ssr1, 256, 32);
|
||||||
|
info->ssr_vendor288_311 = unstuff_bits(raw_ssr1, 288, 24);
|
||||||
|
|
||||||
|
info->ssr_rsvd314_327 = unstuff_bits(raw_ssr1, 314, 14);
|
||||||
|
info->ssr_rsvd340_345 = unstuff_bits(raw_ssr1, 340, 6);
|
||||||
|
info->ssr_rsvd378_383 = unstuff_bits(raw_ssr1, 378, 6);
|
||||||
|
info->ssr_rsvd424_427 = unstuff_bits(raw_ssr0, 424, 4);
|
||||||
|
info->ssr_rsvd496_501 = unstuff_bits(raw_ssr0, 496, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 address, u32 len, void *buf)
|
||||||
|
{
|
||||||
|
if (!(storage->scr.cmds & BIT(2)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sdmmc_cmd_t cmdbuf;
|
||||||
|
|
||||||
|
u32 arg = fno << 27 | page << 18 | address << 9 | (len - 1);
|
||||||
|
|
||||||
|
sdmmc_init_cmd(&cmdbuf, SD_READ_EXTR_SINGLE, arg, SDMMC_RSP_TYPE_1, 0);
|
||||||
|
|
||||||
|
sdmmc_req_t reqbuf;
|
||||||
|
reqbuf.buf = buf;
|
||||||
|
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
|
||||||
|
reqbuf.num_sectors = 1;
|
||||||
|
reqbuf.is_write = 0;
|
||||||
|
reqbuf.is_multi_block = 0;
|
||||||
|
reqbuf.is_auto_stop_trn = 0;
|
||||||
|
|
||||||
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sd_v1)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
u16 vhd_pattern = SD_VHS_27_36 | 0xAA;
|
u16 icr = SD_ICR_PCIE | SD_ICR_VHS_27_36 | SD_ICR_PATTERN;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_7, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, icr, SDMMC_RSP_TYPE_7, 0);
|
||||||
|
|
||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
{
|
{
|
||||||
// The SD Card is version 1.X (SDSC) if there is no response.
|
// The SD Card is version 1.XX if there is no response.
|
||||||
if (storage->sdmmc->error_sts == SDHCI_ERR_INT_CMD_TIMEOUT)
|
if (storage->sdmmc->error_sts == SDHCI_ERR_INT_CMD_TIMEOUT)
|
||||||
{
|
{
|
||||||
*is_sdsc = 1;
|
*is_sd_v1 = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Card version >= 2.0, parse results.
|
// For version >= 2.0, parse results.
|
||||||
u32 resp = 0;
|
u32 ricr = 0;
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_7);
|
sdmmc_get_cached_rsp(storage->sdmmc, &ricr, SDMMC_RSP_TYPE_7);
|
||||||
|
|
||||||
|
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||||
|
gfx_printf("ICR: %08X -> %08X\n", icr, ricr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Check if VHS was accepted and pattern was properly returned.
|
||||||
|
if ((ricr & 0xFFF) == (icr & 0xFFF))
|
||||||
|
{
|
||||||
|
storage->has_pcie = ricr & SD_ICR_PCIE;
|
||||||
|
|
||||||
// Check if VHD was accepted and pattern was properly returned.
|
|
||||||
if ((resp & 0xFFF) == vhd_pattern)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, bool is_sdsc, int bus_uhs_support)
|
static int _sd_storage_send_op_cond(sdmmc_storage_t *storage, u32 *rocr, u32 ocr, bool is_sd_v1)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
// Support for Current > 150mA.
|
|
||||||
u32 arg = !is_sdsc ? SD_OCR_XPC : 0;
|
|
||||||
// Support for handling block-addressed SDHC cards.
|
|
||||||
arg |= !is_sdsc ? SD_OCR_CCS : 0;
|
|
||||||
// Support for 1.8V signaling.
|
|
||||||
arg |= (bus_uhs_support && !is_sdsc) ? SD_OCR_S18R : 0;
|
|
||||||
// Support for 3.3V power supply (VDD1).
|
|
||||||
arg |= SD_OCR_VDD_32_33;
|
|
||||||
|
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_APP_SD_SEND_OP_COND, ocr, SDMMC_RSP_TYPE_3, 0);
|
||||||
|
|
||||||
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
|
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sd_v1 ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return sdmmc_get_cached_rsp(storage->sdmmc, cond, SDMMC_RSP_TYPE_3);
|
return sdmmc_get_cached_rsp(storage->sdmmc, rocr, SDMMC_RSP_TYPE_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support)
|
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sd_v1, int lv_support)
|
||||||
{
|
{
|
||||||
u32 timeout = get_tmr_ms() + 1500;
|
u32 timeout = get_tmr_ms() + 1500;
|
||||||
|
|
||||||
|
// Host in 3.3V power supply (VDD1).
|
||||||
|
u32 ocr = SD_OCR_VDD_32_33;
|
||||||
|
|
||||||
|
if (!is_sd_v1)
|
||||||
|
{
|
||||||
|
// Support for Current > 150mA.
|
||||||
|
ocr |= SD_OCR_XPC;
|
||||||
|
// Support for handling block-addressed SDHC/SDXC/SDUC cards.
|
||||||
|
ocr |= SD_OCR_HCS;
|
||||||
|
// Support and request 1.8V signaling.
|
||||||
|
ocr |= lv_support ? SD_OCR_S18R : 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
u32 cond = 0;
|
u32 rocr = 0;
|
||||||
if (_sd_storage_get_op_cond_once(storage, &cond, is_sdsc, bus_uhs_support))
|
if (_sd_storage_send_op_cond(storage, &rocr, ocr, is_sd_v1))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check if power up is done.
|
// Check if power up is done.
|
||||||
if (cond & SD_OCR_BUSY)
|
if (rocr & SD_OCR_BUSY)
|
||||||
{
|
{
|
||||||
DPRINTF("[SD] op cond: %08X, lv: %d\n", cond, bus_uhs_support);
|
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||||
|
gfx_printf("ROCR: %08X (%d)\n", rocr, lv_support);
|
||||||
|
#else
|
||||||
|
DPRINTF("[SD] rocr: %08X, lv: %d\n", rocr, lv_support);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check if card is high capacity.
|
// Check if card is higher capacity.
|
||||||
if (cond & SD_OCR_CCS)
|
if (rocr & SD_OCR_CCS)
|
||||||
storage->has_sector_access = 1;
|
storage->has_sector_access = 1; // Non-SDUC.
|
||||||
|
|
||||||
// Check if card supports 1.8V signaling.
|
// Check if card accepted 1.8V signaling.
|
||||||
if (cond & SD_ROCR_S18A && bus_uhs_support && !storage->is_low_voltage)
|
if (rocr & SD_OCR_S18A && lv_support)
|
||||||
{
|
{
|
||||||
// Switch to 1.8V signaling.
|
// Switch to 1.8V signaling.
|
||||||
if (!_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
|
if (!_sdmmc_storage_execute_cmd_ex_state(storage, SD_VOLTAGE_SWITCH, 0, 0, R1_STATE_READY))
|
||||||
{
|
{
|
||||||
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_UHS_SDR12))
|
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_UHS_SDR12))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1080,13 +1167,13 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
|||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
u32 resp = 0;
|
u32 rca = 0;
|
||||||
if (sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_6))
|
if (sdmmc_get_cached_rsp(storage->sdmmc, &rca, SDMMC_RSP_TYPE_6))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (resp >> 16)
|
if (rca >> 16)
|
||||||
{
|
{
|
||||||
storage->rca = resp >> 16;
|
storage->rca = rca >> 16;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1098,31 +1185,71 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 sd_storage_get_scr_sda_ver(sdmmc_storage_t *storage)
|
||||||
|
{
|
||||||
|
u8 version = 0;
|
||||||
|
|
||||||
|
u8 sda_spec = storage->scr.sda_vsn;
|
||||||
|
u8 sda_spec3 = storage->scr.sda_spec & 1;
|
||||||
|
u8 sda_spec4 = (storage->scr.sda_spec >> 1) & 1;
|
||||||
|
u8 sda_specx = storage->scr.sda_spec >> 4;
|
||||||
|
|
||||||
|
switch (sda_spec)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
version = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
version = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (!sda_spec3)
|
||||||
|
version = 2;
|
||||||
|
else if (!sda_spec4 && !sda_specx)
|
||||||
|
version = 3;
|
||||||
|
else
|
||||||
|
version = sda_specx + 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
|
static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
// unstuff_bits can parse only 4 u32
|
// unstuff_bits can parse only 4 u32
|
||||||
u32 resp[4];
|
u32 scr[4];
|
||||||
|
u8 sda_spec3 = 0;
|
||||||
|
u8 sda_spec4 = 0;
|
||||||
|
u8 sda_specx = 0;
|
||||||
|
|
||||||
memcpy(&resp[2], storage->raw_scr, 8);
|
memcpy(&scr[2], storage->raw_scr, 8);
|
||||||
|
|
||||||
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||||
_sd_storage_debug_print_scr((u32 *)storage->raw_scr);
|
_sd_storage_debug_print_scr((u32 *)storage->raw_scr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
storage->scr.sda_vsn = unstuff_bits(resp, 56, 4);
|
storage->scr.sda_vsn = unstuff_bits(scr, 56, 4);
|
||||||
storage->scr.bus_widths = unstuff_bits(resp, 48, 4);
|
storage->scr.bus_widths = unstuff_bits(scr, 48, 4);
|
||||||
|
|
||||||
// If v2.0 is supported, check if Physical Layer Spec v3.0 is supported.
|
// If v2.0 is supported, check if Physical Layer Spec v3.0 is supported.
|
||||||
if (storage->scr.sda_vsn == SCR_SPEC_VER_2)
|
if (storage->scr.sda_vsn == SCR_SPEC_VER_2)
|
||||||
storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);
|
sda_spec3 = unstuff_bits(scr, 47, 1);
|
||||||
if (storage->scr.sda_spec3)
|
if (sda_spec3)
|
||||||
{
|
{
|
||||||
u8 sda_spec4 = unstuff_bits(resp, 42, 1);
|
sda_spec4 = unstuff_bits(scr, 42, 1);
|
||||||
|
sda_specx = unstuff_bits(scr, 38, 4);
|
||||||
if (sda_spec4)
|
if (sda_spec4)
|
||||||
storage->scr.cmds = unstuff_bits(resp, 32, 4);
|
storage->scr.cmds = unstuff_bits(scr, 32, 4);
|
||||||
else
|
else
|
||||||
storage->scr.cmds = unstuff_bits(resp, 32, 2);
|
storage->scr.cmds = unstuff_bits(scr, 32, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage->scr.sda_spec = sda_spec3 | (sda_spec4 << 1) | (sda_specx << 4);
|
||||||
|
|
||||||
|
storage->scr.vendor = unstuff_bits(scr, 0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_storage_get_scr(sdmmc_storage_t *storage)
|
int sd_storage_get_scr(sdmmc_storage_t *storage)
|
||||||
@@ -1143,8 +1270,6 @@ int sd_storage_get_scr(sdmmc_storage_t *storage)
|
|||||||
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
|
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 tmp = 0;
|
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
//Prepare buffer for unstuff_bits
|
//Prepare buffer for unstuff_bits
|
||||||
for (u32 i = 0; i < 8; i += 4)
|
for (u32 i = 0; i < 8; i += 4)
|
||||||
{
|
{
|
||||||
@@ -1155,10 +1280,10 @@ int sd_storage_get_scr(sdmmc_storage_t *storage)
|
|||||||
}
|
}
|
||||||
_sd_storage_parse_scr(storage);
|
_sd_storage_parse_scr(storage);
|
||||||
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
|
static int _sd_storage_switch_get_all(sdmmc_storage_t *storage, void *buf)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);
|
||||||
@@ -1174,9 +1299,7 @@ static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
|
|||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 tmp = 0;
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg)
|
static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg)
|
||||||
@@ -1198,9 +1321,7 @@ static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int
|
|||||||
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 tmp = 0;
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limit, u8 *buf)
|
static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limit, u8 *buf)
|
||||||
@@ -1378,9 +1499,19 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
buf = (u8 *)SDMMC_ALT_DMA_BUFFER;
|
buf = (u8 *)SDMMC_ALT_DMA_BUFFER;
|
||||||
|
|
||||||
if (_sd_storage_switch_get(storage, buf))
|
if (_sd_storage_switch_get_all(storage, buf))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
|
||||||
|
gfx_printf("\nFMD: %04X %04X %04X %04X %04X %04X\n",
|
||||||
|
buf[13] | (buf[12] << 8),
|
||||||
|
buf[11] | (buf[10] << 8),
|
||||||
|
buf[9] | (buf[8] << 8),
|
||||||
|
buf[7] | (buf[6] << 8),
|
||||||
|
buf[5] | (buf[4] << 8),
|
||||||
|
buf[3] | (buf[2] << 8));
|
||||||
|
#endif
|
||||||
|
|
||||||
fmodes->access_mode = buf[13] | (buf[12] << 8);
|
fmodes->access_mode = buf[13] | (buf[12] << 8);
|
||||||
fmodes->cmd_system = buf[11] | (buf[10] << 8);
|
fmodes->cmd_system = buf[11] | (buf[10] << 8);
|
||||||
fmodes->driver_strength = buf[9] | (buf[8] << 8);
|
fmodes->driver_strength = buf[9] | (buf[8] << 8);
|
||||||
@@ -1389,7 +1520,7 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
|
static int _sd_storage_set_uhs_bus_speed(sdmmc_storage_t *storage, u32 type)
|
||||||
{
|
{
|
||||||
sd_func_modes_t fmodes;
|
sd_func_modes_t fmodes;
|
||||||
u8 *buf = storage->raw_ext_csd;
|
u8 *buf = storage->raw_ext_csd;
|
||||||
@@ -1490,14 +1621,14 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
|
|||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] after setup clock\n");
|
DPRINTF("[SD] after setup clock\n");
|
||||||
|
|
||||||
if (sdmmc_tuning_execute(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))
|
if (sdmmc_tuning_execute(storage->sdmmc, type, SD_SEND_TUNING_BLOCK))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] after tuning\n");
|
DPRINTF("[SD] after tuning\n");
|
||||||
|
|
||||||
return _sdmmc_storage_check_status(storage);
|
return _sdmmc_storage_check_status(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage)
|
static int _sd_storage_set_hs25_bus_speed(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
sd_func_modes_t fmodes;
|
sd_func_modes_t fmodes;
|
||||||
u8 *buf = storage->raw_ext_csd;
|
u8 *buf = storage->raw_ext_csd;
|
||||||
@@ -1520,6 +1651,64 @@ static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage)
|
|||||||
return sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_HS25);
|
return sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_HS25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sd_storage_get_ddr200_support(sdmmc_storage_t *storage)
|
||||||
|
{
|
||||||
|
// DDR200 CID reserved/SCR vendor (hex):
|
||||||
|
// Samsung 0x1B: A 00000000
|
||||||
|
// Longsys 0xAD: A 00000000
|
||||||
|
// Kowin 0x22: 7 33333039 33333039 SMART?
|
||||||
|
// Phison 0x27: 0 01196432 Byte2: DDR2XX (25 == DDR225)?
|
||||||
|
// Taishin 0x9F: 0 01006432
|
||||||
|
|
||||||
|
// Non-DDR200:
|
||||||
|
// Phison 0x27: 0 01000000
|
||||||
|
// Taishin 0x9F: 0 01000000
|
||||||
|
// Taishin 0x9F: 7 33333039 Supported but slow nand?
|
||||||
|
|
||||||
|
sd_func_modes_t fmodes = { 0 };
|
||||||
|
|
||||||
|
if (sd_storage_get_fmodes(storage, storage->raw_ext_csd, &fmodes))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Introduced first in 2018 via Sandisk Quickflow.
|
||||||
|
if (storage->cid.year < 2018)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// No DDR200 if no SDR104.
|
||||||
|
if (!(fmodes.access_mode & SD_MODE_UHS_SDR104))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Can't enter DDR200 mode without Vendor Command System mode.
|
||||||
|
if (!(fmodes.cmd_system & SD_CMD_SYSTEM_VND))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Assume no support if 4.10 and lower. (Should be < 6?)
|
||||||
|
if (sd_storage_get_scr_sda_ver(storage) < 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Sandisk.
|
||||||
|
if (storage->cid.manfid == 0x03)
|
||||||
|
{
|
||||||
|
// 0x80: DDR200, 0x85: DDR225, 0x86: DDR250? 0x87:DDR275?
|
||||||
|
if (storage->cid.prv >= 0x80)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CID Reserved bits.
|
||||||
|
if (storage->cid.rsvd == 0xA || // Samsung / Longsys.
|
||||||
|
storage->cid.rsvd == 0x7) // Taishin A / Kowin.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// SCR Vendor bits.
|
||||||
|
u32 scr_vnd = storage->scr.vendor & 0xFFFF;
|
||||||
|
if (scr_vnd == 0x6432) // Phison / Taishin B. "d2".
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage)
|
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
u32 au_size = storage->ssr.uhs_au_size;
|
u32 au_size = storage->ssr.uhs_au_size;
|
||||||
@@ -1706,9 +1895,6 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage)
|
|||||||
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
|
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
u32 tmp = 0;
|
|
||||||
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
|
|
||||||
|
|
||||||
// Convert buffer to LE.
|
// Convert buffer to LE.
|
||||||
for (u32 i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
|
for (u32 i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
|
||||||
{
|
{
|
||||||
@@ -1720,7 +1906,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage)
|
|||||||
|
|
||||||
_sd_storage_parse_ssr(storage);
|
_sd_storage_parse_ssr(storage);
|
||||||
|
|
||||||
return _sdmmc_storage_check_card_status(tmp);
|
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
|
static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
|
||||||
@@ -1741,6 +1927,7 @@ static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
|
|||||||
storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4);
|
storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4);
|
||||||
storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4);
|
storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4);
|
||||||
storage->cid.serial = unstuff_bits(raw_cid, 24, 32);
|
storage->cid.serial = unstuff_bits(raw_cid, 24, 32);
|
||||||
|
storage->cid.rsvd = unstuff_bits(raw_cid, 20, 4);
|
||||||
storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000;
|
storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000;
|
||||||
storage->cid.month = unstuff_bits(raw_cid, 8, 4);
|
storage->cid.month = unstuff_bits(raw_cid, 8, 4);
|
||||||
}
|
}
|
||||||
@@ -1778,7 +1965,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
|
|||||||
storage->sec_cnt = storage->csd.capacity;
|
storage->sec_cnt = storage->csd.capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _sdmmc_storage_get_bus_uhs_support(u32 bus_width, u32 type)
|
static bool _sd_storage_get_bus_uhs_support(u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -1806,9 +1993,8 @@ void sdmmc_storage_init_wait_sd()
|
|||||||
|
|
||||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
u32 tmp = 0;
|
bool is_sd_v1 = false;
|
||||||
bool is_sdsc = 0;
|
bool lv_support = _sd_storage_get_bus_uhs_support(bus_width, type);
|
||||||
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
|
|
||||||
|
|
||||||
DPRINTF("[SD]-[init: bus: %d, type: %d]\n", bus_width, type);
|
DPRINTF("[SD]-[init: bus: %d, type: %d]\n", bus_width, type);
|
||||||
|
|
||||||
@@ -1829,11 +2015,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] went to idle state\n");
|
DPRINTF("[SD] went to idle state\n");
|
||||||
|
|
||||||
if (_sd_storage_send_if_cond(storage, &is_sdsc))
|
if (_sd_storage_send_if_cond(storage, &is_sd_v1))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] after send if cond\n");
|
DPRINTF("[SD] sent if cond\n");
|
||||||
|
|
||||||
if (_sd_storage_get_op_cond(storage, is_sdsc, bus_uhs_support))
|
if (_sd_storage_get_op_cond(storage, is_sd_v1, lv_support))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] got op cond\n");
|
DPRINTF("[SD] got op cond\n");
|
||||||
|
|
||||||
@@ -1855,7 +2041,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||||||
{
|
{
|
||||||
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
|
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] after setup default clock\n");
|
DPRINTF("[SD] after setup default hs clock\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sdmmc_storage_select_card(storage))
|
if (_sdmmc_storage_select_card(storage))
|
||||||
@@ -1867,7 +2053,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||||||
DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
|
DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
|
||||||
|
|
||||||
// Disconnect Card Detect resistor from DAT3.
|
// Disconnect Card Detect resistor from DAT3.
|
||||||
if (_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
|
if (_sd_storage_execute_app_cmd_tran(storage, SD_APP_SET_CLR_CARD_DETECT, 0))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] cleared card detect\n");
|
DPRINTF("[SD] cleared card detect\n");
|
||||||
|
|
||||||
@@ -1878,7 +2064,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||||||
// If card supports a wider bus and if it's not SD Version 1.0 switch bus width.
|
// If card supports a wider bus and if it's not SD Version 1.0 switch bus width.
|
||||||
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & BIT(SD_BUS_WIDTH_4)) && storage->scr.sda_vsn)
|
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & BIT(SD_BUS_WIDTH_4)) && storage->scr.sda_vsn)
|
||||||
{
|
{
|
||||||
if (_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
|
if (_sd_storage_execute_app_cmd_tran(storage, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
|
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
|
||||||
@@ -1892,13 +2078,13 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
|
|||||||
|
|
||||||
if (storage->is_low_voltage)
|
if (storage->is_low_voltage)
|
||||||
{
|
{
|
||||||
if (_sd_storage_enable_uhs_low_volt(storage, type))
|
if (_sd_storage_set_uhs_bus_speed(storage, type))
|
||||||
return 1;
|
return 1;
|
||||||
DPRINTF("[SD] enabled UHS\n");
|
DPRINTF("[SD] enabled UHS\n");
|
||||||
}
|
}
|
||||||
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0.
|
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default HS speed and not SD Version 1.0.
|
||||||
{
|
{
|
||||||
if (_sd_storage_enable_hs_high_volt(storage))
|
if (_sd_storage_set_hs25_bus_speed(storage))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
DPRINTF("[SD] enabled HS\n");
|
DPRINTF("[SD] enabled HS\n");
|
||||||
@@ -1935,7 +2121,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
|||||||
{
|
{
|
||||||
u32 resp;
|
u32 resp;
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_60_CMD, 0, SDMMC_RSP_TYPE_1, 1);
|
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_60, 0, SDMMC_RSP_TYPE_1, 1);
|
||||||
|
|
||||||
sdmmc_req_t reqbuf;
|
sdmmc_req_t reqbuf;
|
||||||
reqbuf.buf = buf;
|
reqbuf.buf = buf;
|
||||||
@@ -1951,10 +2137,9 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_1))
|
if (_sdmmc_storage_check_cached_card_status(storage->sdmmc))
|
||||||
return 1;
|
|
||||||
if (_sdmmc_storage_check_card_status(resp))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return _sdmmc_storage_check_status(storage);
|
return _sdmmc_storage_check_status(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,15 +117,16 @@ typedef struct _mmc_sandisk_report_t
|
|||||||
|
|
||||||
typedef struct _mmc_cid
|
typedef struct _mmc_cid
|
||||||
{
|
{
|
||||||
u32 manfid;
|
u32 manfid; // SDA assigned.
|
||||||
u8 prod_name[8];
|
u8 prod_name[8];
|
||||||
u32 serial;
|
u32 serial;
|
||||||
u16 oemid;
|
u16 oemid; // SDA assigned.
|
||||||
u16 year;
|
u16 year;
|
||||||
u8 prv;
|
u8 prv;
|
||||||
u8 hwrev;
|
u8 hwrev;
|
||||||
u8 fwrev;
|
u8 fwrev;
|
||||||
u8 month;
|
u8 month;
|
||||||
|
u32 rsvd;
|
||||||
} mmc_cid_t;
|
} mmc_cid_t;
|
||||||
|
|
||||||
typedef struct _mmc_csd
|
typedef struct _mmc_csd
|
||||||
@@ -161,9 +162,10 @@ typedef struct _mmc_ext_csd
|
|||||||
typedef struct _sd_scr
|
typedef struct _sd_scr
|
||||||
{
|
{
|
||||||
u8 sda_vsn;
|
u8 sda_vsn;
|
||||||
u8 sda_spec3;
|
u8 sda_spec;
|
||||||
u8 bus_widths;
|
u8 bus_widths;
|
||||||
u8 cmds;
|
u8 cmds;
|
||||||
|
u32 vendor;
|
||||||
} sd_scr_t;
|
} sd_scr_t;
|
||||||
|
|
||||||
typedef struct _sd_ssr
|
typedef struct _sd_ssr
|
||||||
@@ -188,6 +190,46 @@ typedef struct _sd_ext_reg_t
|
|||||||
int valid;
|
int valid;
|
||||||
} sd_ext_reg_t;
|
} sd_ext_reg_t;
|
||||||
|
|
||||||
|
typedef struct _sd_func_modes_t
|
||||||
|
{
|
||||||
|
u16 access_mode;
|
||||||
|
u16 cmd_system;
|
||||||
|
u16 driver_strength;
|
||||||
|
u16 power_limit;
|
||||||
|
} sd_func_modes_t;
|
||||||
|
|
||||||
|
typedef struct _sd_vendor_info_t
|
||||||
|
{
|
||||||
|
// CID Reserved.
|
||||||
|
u8 cid_rsvd; // 4-bit.
|
||||||
|
|
||||||
|
// CSD Reserved.
|
||||||
|
u8 csd_rsvd8_9; // 2-bit.
|
||||||
|
u8 csd_rsvd16_20; // 5-bit.
|
||||||
|
u8 csd_rsvd29_30; // 2-bit.
|
||||||
|
u8 csd_rsvd120_125; // 6-bit.
|
||||||
|
|
||||||
|
u32 scr_vendor;
|
||||||
|
u8 scr_rsvd; // 2-bit.
|
||||||
|
|
||||||
|
u32 ssr_vendor0_31;
|
||||||
|
u32 ssr_vendor32_63;
|
||||||
|
u32 ssr_vendor64_95;
|
||||||
|
u32 ssr_vendor96_127;
|
||||||
|
u32 ssr_vendor128_159;
|
||||||
|
u32 ssr_vendor160_191;
|
||||||
|
u32 ssr_vendor192_223;
|
||||||
|
u32 ssr_vendor224_255;
|
||||||
|
u32 ssr_vendor256_287;
|
||||||
|
u32 ssr_vendor288_311; // 24-bit.
|
||||||
|
|
||||||
|
u16 ssr_rsvd314_327; // 14-bit.
|
||||||
|
u8 ssr_rsvd340_345; // 6-bit.
|
||||||
|
u8 ssr_rsvd378_383; // 6-bit.
|
||||||
|
u8 ssr_rsvd424_427; // 4-bit.
|
||||||
|
u8 ssr_rsvd496_501; // 6-bit.
|
||||||
|
} sd_vendor_info_t;
|
||||||
|
|
||||||
/*! SDMMC storage context. */
|
/*! SDMMC storage context. */
|
||||||
typedef struct _sdmmc_storage_t
|
typedef struct _sdmmc_storage_t
|
||||||
{
|
{
|
||||||
@@ -196,6 +238,7 @@ typedef struct _sdmmc_storage_t
|
|||||||
int initialized;
|
int initialized;
|
||||||
int is_low_voltage;
|
int is_low_voltage;
|
||||||
int has_sector_access;
|
int has_sector_access;
|
||||||
|
int has_pcie;
|
||||||
u32 rca;
|
u32 rca;
|
||||||
u32 sec_cnt;
|
u32 sec_cnt;
|
||||||
u32 partition;
|
u32 partition;
|
||||||
@@ -213,14 +256,6 @@ typedef struct _sdmmc_storage_t
|
|||||||
sd_ext_reg_t ser;
|
sd_ext_reg_t ser;
|
||||||
} sdmmc_storage_t;
|
} sdmmc_storage_t;
|
||||||
|
|
||||||
typedef struct _sd_func_modes_t
|
|
||||||
{
|
|
||||||
u16 access_mode;
|
|
||||||
u16 cmd_system;
|
|
||||||
u16 driver_strength;
|
|
||||||
u16 power_limit;
|
|
||||||
} sd_func_modes_t;
|
|
||||||
|
|
||||||
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
||||||
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||||
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||||
@@ -230,7 +265,8 @@ void sdmmc_storage_init_wait_sd();
|
|||||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type);
|
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type);
|
||||||
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
||||||
|
|
||||||
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
int sdmmc_storage_gen_cmd(sdmmc_storage_t *storage, u32 arg, void *buf);
|
||||||
|
int sdmmc_storage_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
|
||||||
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
|
||||||
|
|
||||||
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
|
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
|
||||||
@@ -238,10 +274,13 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
|
|||||||
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf);
|
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf);
|
||||||
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
|
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
|
||||||
int sd_storage_get_scr(sdmmc_storage_t *storage);
|
int sd_storage_get_scr(sdmmc_storage_t *storage);
|
||||||
|
u8 sd_storage_get_scr_sda_ver(sdmmc_storage_t *storage);
|
||||||
int sd_storage_get_ssr(sdmmc_storage_t *storage);
|
int sd_storage_get_ssr(sdmmc_storage_t *storage);
|
||||||
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
|
||||||
|
|
||||||
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf);
|
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf);
|
||||||
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf);
|
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf);
|
||||||
|
bool sd_storage_get_ddr200_support(sdmmc_storage_t *storage);
|
||||||
|
|
||||||
|
void sd_storage_get_vendor_info(sdmmc_storage_t *storage, sd_vendor_info_t *info);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -908,7 +908,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
|||||||
u16 norintsts = sdmmc->regs->norintsts;
|
u16 norintsts = sdmmc->regs->norintsts;
|
||||||
u16 errintsts = sdmmc->regs->errintsts;
|
u16 errintsts = sdmmc->regs->errintsts;
|
||||||
|
|
||||||
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
|
DPRINTF("norintsts %04X, errintsts %04X\n", norintsts, errintsts);
|
||||||
|
|
||||||
if (pout)
|
if (pout)
|
||||||
*pout = norintsts;
|
*pout = norintsts;
|
||||||
@@ -917,7 +917,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
|||||||
if (norintsts & SDHCI_INT_ERROR)
|
if (norintsts & SDHCI_INT_ERROR)
|
||||||
{
|
{
|
||||||
#ifdef ERROR_EXTRA_PRINTING
|
#ifdef ERROR_EXTRA_PRINTING
|
||||||
EPRINTFARGS("SDMMC%d: intsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
|
EPRINTFARGS("SDMMC%d: intsts %04X, errintsts %04X", sdmmc->id + 1, norintsts, errintsts);
|
||||||
#endif
|
#endif
|
||||||
sdmmc->error_sts = errintsts;
|
sdmmc->error_sts = errintsts;
|
||||||
sdmmc->regs->errintsts = errintsts;
|
sdmmc->regs->errintsts = errintsts;
|
||||||
@@ -1128,7 +1128,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||||||
if (_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
|
if (_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
|
||||||
{
|
{
|
||||||
#ifdef ERROR_EXTRA_PRINTING
|
#ifdef ERROR_EXTRA_PRINTING
|
||||||
EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type);
|
EPRINTFARGS("SDMMC%d: Wrong Response type %d!", sdmmc->id + 1, cmd->rsp_type);
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -968,4 +968,6 @@ static const kip1_id_t _kip_ids[] =
|
|||||||
{ "FS", "\x56\x25\x17\xA1\x92\xC3\xC8\xF0", _fs_patches_2100_exfat }, // FS 21.2.0 exFAT
|
{ "FS", "\x56\x25\x17\xA1\x92\xC3\xC8\xF0", _fs_patches_2100_exfat }, // FS 21.2.0 exFAT
|
||||||
{ "FS", "\xB7\xA2\x97\x39\xB7\xED\xDE\xFC", _fs_patches_2200 }, // FS 22.0.0
|
{ "FS", "\xB7\xA2\x97\x39\xB7\xED\xDE\xFC", _fs_patches_2200 }, // FS 22.0.0
|
||||||
{ "FS", "\xFB\x0B\x68\xDB\x24\x03\xD1\x19", _fs_patches_2200_exfat }, // FS 22.0.0 exFAT
|
{ "FS", "\xFB\x0B\x68\xDB\x24\x03\xD1\x19", _fs_patches_2200_exfat }, // FS 22.0.0 exFAT
|
||||||
|
{ "FS", "\x53\x6D\x93\x84\x69\xFE\x73\xBE", _fs_patches_2200 }, // FS 22.5.0
|
||||||
|
{ "FS", "\xD4\x45\x28\x29\x5B\x41\x92\xBA", _fs_patches_2200_exfat }, // FS 22.5.0 exFAT
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1426,7 +1426,7 @@ ment_t ment_top[] = {
|
|||||||
MDEF_END()
|
MDEF_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_t menu_top = { ment_top, "hekate v6.5.2", 0, 0 };
|
menu_t menu_top = { ment_top, "hekate v6.5.3", 0, 0 };
|
||||||
|
|
||||||
extern void pivot_stack(u32 stack_top);
|
extern void pivot_stack(u32 stack_top);
|
||||||
|
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ hw_info_t *hw_info = NULL;
|
|||||||
|
|
||||||
//! TODO: Limits assumed based on known samples.
|
//! TODO: Limits assumed based on known samples.
|
||||||
#define WAFER_20NM_X_MIN -9
|
#define WAFER_20NM_X_MIN -9
|
||||||
#define WAFER_20NM_X_MAX 15
|
#define WAFER_20NM_X_MAX 16
|
||||||
#define WAFER_20NM_Y_MIN 1
|
#define WAFER_20NM_Y_MIN 1
|
||||||
#define WAFER_20NM_Y_MAX 24
|
#define WAFER_20NM_Y_MAX 24
|
||||||
|
|
||||||
@@ -1618,8 +1618,171 @@ static lv_res_t _create_mbox_emmc_sandisk_report(lv_obj_t * btn)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
free(buf);
|
free(buf);
|
||||||
free (txt_buf);
|
free(txt_buf);
|
||||||
free (txt_buf2);
|
free(txt_buf2);
|
||||||
|
|
||||||
|
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
|
||||||
|
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
lv_obj_set_top(mbox, true);
|
||||||
|
|
||||||
|
return LV_RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_res_t _create_mbox_sd_vendor_info(lv_obj_t * btn)
|
||||||
|
{
|
||||||
|
lv_obj_t *dark_bg = lv_obj_create(lv_layer_top(), NULL);
|
||||||
|
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||||
|
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||||
|
|
||||||
|
static const char * mbox_btn_map[] = { "\251", "\222Close", "\251", "" };
|
||||||
|
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
|
||||||
|
lv_mbox_set_recolor_text(mbox, true);
|
||||||
|
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
|
||||||
|
|
||||||
|
lv_mbox_set_text(mbox, "#C7EA46 SD Vendor/Reserved Data#\nPlease wait..");
|
||||||
|
manual_system_maintenance(true);
|
||||||
|
|
||||||
|
u8 *buf = zalloc(EMMC_BLOCKSIZE);
|
||||||
|
char *txt_buf = (char *)malloc(SZ_32K);
|
||||||
|
char *txt_buf2 = (char *)malloc(SZ_32K);
|
||||||
|
txt_buf[0] = 0;
|
||||||
|
txt_buf2[0] = 0;
|
||||||
|
|
||||||
|
// Create SoC Info container.
|
||||||
|
lv_obj_t *h1 = lv_cont_create(mbox, NULL);
|
||||||
|
lv_cont_set_style(h1, &lv_style_transp_tight);
|
||||||
|
lv_cont_set_fit(h1, false, true);
|
||||||
|
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 4);
|
||||||
|
lv_obj_set_click(h1, false);
|
||||||
|
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
|
||||||
|
|
||||||
|
lv_obj_t * lb_desc = lv_label_create(h1, NULL);
|
||||||
|
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
|
||||||
|
lv_label_set_recolor(lb_desc, true);
|
||||||
|
lv_label_set_style(lb_desc, &monospace_text);
|
||||||
|
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 2);
|
||||||
|
|
||||||
|
lv_obj_t * lb_desc2 = lv_label_create(h1, NULL);
|
||||||
|
lv_label_set_long_mode(lb_desc2, LV_LABEL_LONG_BREAK);
|
||||||
|
lv_label_set_recolor(lb_desc2, true);
|
||||||
|
lv_label_set_style(lb_desc2, &monospace_text);
|
||||||
|
lv_obj_set_width(lb_desc2, LV_HOR_RES / 9 * 2);
|
||||||
|
lv_obj_align(lb_desc2, lb_desc, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
|
||||||
|
|
||||||
|
if (sd_mount())
|
||||||
|
{
|
||||||
|
lv_label_set_text(lb_desc, "#FFDD00 Failed to init SD!#");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_vendor_info_t sd_info;
|
||||||
|
sd_storage_get_vendor_info(&sd_storage, &sd_info);
|
||||||
|
|
||||||
|
s_printf(txt_buf,
|
||||||
|
"#00DDFF Vendor/Reserved Registers#\n"
|
||||||
|
"#FF8000 CID[023:020]:# %X\n\n"
|
||||||
|
|
||||||
|
"#FF8000 CSD[009:008]:# %X\n"
|
||||||
|
"#FF8000 CSD[020:016]:# %02X\n"
|
||||||
|
"#FF8000 CSD[030:029]:# %X\n"
|
||||||
|
"#FF8000 CSD[125:120]:# %02X\n"
|
||||||
|
|
||||||
|
"#FF8000 SCR Vendor:# %08X\n"
|
||||||
|
"#FF8000 SCR[037:036]:# %X\n\n"
|
||||||
|
|
||||||
|
"#FF8000 SSR[031:000]:# %08X\n"
|
||||||
|
"#FF8000 SSR[063:032]:# %08X\n"
|
||||||
|
"#FF8000 SSR[095:064]:# %08X\n"
|
||||||
|
"#FF8000 SSR[127:096]:# %08X\n"
|
||||||
|
"#FF8000 SSR[159:128]:# %08X\n"
|
||||||
|
"#FF8000 SSR[191:160]:# %08X\n"
|
||||||
|
"#FF8000 SSR[223:192]:# %08X\n"
|
||||||
|
"#FF8000 SSR[255:224]:# %08X\n"
|
||||||
|
"#FF8000 SSR[287:256]:# %08X\n"
|
||||||
|
"#FF8000 SSR[311:288]:# %06X",
|
||||||
|
sd_info.cid_rsvd,
|
||||||
|
|
||||||
|
sd_info.csd_rsvd8_9,
|
||||||
|
sd_info.csd_rsvd16_20,
|
||||||
|
sd_info.csd_rsvd29_30,
|
||||||
|
sd_info.csd_rsvd120_125,
|
||||||
|
|
||||||
|
sd_info.scr_vendor,
|
||||||
|
sd_info.scr_rsvd,
|
||||||
|
|
||||||
|
sd_info.ssr_vendor0_31,
|
||||||
|
sd_info.ssr_vendor32_63,
|
||||||
|
sd_info.ssr_vendor64_95,
|
||||||
|
sd_info.ssr_vendor96_127,
|
||||||
|
sd_info.ssr_vendor128_159,
|
||||||
|
sd_info.ssr_vendor160_191,
|
||||||
|
sd_info.ssr_vendor192_223,
|
||||||
|
sd_info.ssr_vendor224_255,
|
||||||
|
sd_info.ssr_vendor256_287,
|
||||||
|
sd_info.ssr_vendor288_311);
|
||||||
|
|
||||||
|
s_printf(txt_buf2,
|
||||||
|
"#FF8000 SSR[327:314]:# %04X\n"
|
||||||
|
"#FF8000 SSR[345:340]:# %02X\n"
|
||||||
|
"#FF8000 SSR[383:378]:# %02X\n"
|
||||||
|
"#FF8000 SSR[427:424]:# %X\n"
|
||||||
|
"#FF8000 SSR[501:496]:# %02X\n\n",
|
||||||
|
sd_info.ssr_rsvd314_327,
|
||||||
|
sd_info.ssr_rsvd340_345,
|
||||||
|
sd_info.ssr_rsvd378_383,
|
||||||
|
sd_info.ssr_rsvd424_427,
|
||||||
|
sd_info.ssr_rsvd496_501);
|
||||||
|
|
||||||
|
if (!sdmmc_storage_gen_cmd(&sd_storage, 0x00000001, buf))
|
||||||
|
{
|
||||||
|
const u32 health_rpt_args[] = {
|
||||||
|
0x00000001, // Sandisk.
|
||||||
|
0x11000001, // ATP.
|
||||||
|
0x110005F1, // AData.
|
||||||
|
0x110005F3,
|
||||||
|
0x110005F5,
|
||||||
|
0x110005F7,
|
||||||
|
0x110005F9, // Transcend.
|
||||||
|
0x110005FB, // Micron.
|
||||||
|
0x110005FD, // Innodisk.
|
||||||
|
0x110005FF,
|
||||||
|
|
||||||
|
(sd_storage.rca << 16) | 1,
|
||||||
|
(sd_storage.cid.oemid << 16) | 1, // 0x53420001: Swissbit.
|
||||||
|
|
||||||
|
// 0x00000010, // Apacer, 2-Step.
|
||||||
|
// 0x00000021,
|
||||||
|
};
|
||||||
|
|
||||||
|
strcpy(txt_buf2 + strlen(txt_buf2), "#00DDFF Health Report Data#");
|
||||||
|
|
||||||
|
for (u32 i = 0; i < ARRAY_SIZE(health_rpt_args); i++)
|
||||||
|
{
|
||||||
|
sdmmc_storage_gen_cmd(&sd_storage, health_rpt_args[i], buf);
|
||||||
|
u8 test = 0;
|
||||||
|
for (u32 i = 0; i < 512; i++)
|
||||||
|
test |= buf[i];
|
||||||
|
|
||||||
|
if (test)
|
||||||
|
s_printf(txt_buf2 + strlen(txt_buf2), "\n#FF8000 %08X:# Has data!", health_rpt_args[i]);
|
||||||
|
else
|
||||||
|
s_printf(txt_buf2 + strlen(txt_buf2), "\n#FF8000 %08X:# Empty", health_rpt_args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(txt_buf2 + strlen(txt_buf2), "#00DDFF Health Report Data#\n#FFDD00 Not supported!#");
|
||||||
|
|
||||||
|
lv_mbox_set_text(mbox, "#C7EA46 SD Vendor/Reserved Data#");
|
||||||
|
|
||||||
|
lv_label_set_text(lb_desc, txt_buf);
|
||||||
|
lv_label_set_text(lb_desc2, txt_buf2);
|
||||||
|
|
||||||
|
sd_unmount();
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(buf);
|
||||||
|
free(txt_buf);
|
||||||
|
free(txt_buf2);
|
||||||
|
|
||||||
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
|
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
|
||||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||||
@@ -2278,6 +2441,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
{
|
{
|
||||||
lv_obj_t *win = nyx_create_standard_window(SYMBOL_SD" microSD Card Info", NULL);
|
lv_obj_t *win = nyx_create_standard_window(SYMBOL_SD" microSD Card Info", NULL);
|
||||||
lv_win_add_btn(win, NULL, SYMBOL_SD" Benchmark", _create_mbox_sd_bench);
|
lv_win_add_btn(win, NULL, SYMBOL_SD" Benchmark", _create_mbox_sd_bench);
|
||||||
|
lv_win_add_btn(win, NULL, SYMBOL_FILE_ALT" Vendor Registers", _create_mbox_sd_vendor_info);
|
||||||
|
|
||||||
lv_obj_t *desc = lv_cont_create(win, NULL);
|
lv_obj_t *desc = lv_cont_create(win, NULL);
|
||||||
lv_obj_set_size(desc, LV_HOR_RES / 2 / 6 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
lv_obj_set_size(desc, LV_HOR_RES / 2 / 6 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
|
||||||
@@ -2301,7 +2465,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lv_label_set_text(lb_desc,
|
lv_label_set_text(lb_desc,
|
||||||
"#00DDFF Card ID:#\n"
|
"#00DDFF Card ID#\n"
|
||||||
"Vendor ID:\n"
|
"Vendor ID:\n"
|
||||||
"Model:\n"
|
"Model:\n"
|
||||||
"OEM ID:\n"
|
"OEM ID:\n"
|
||||||
@@ -2319,8 +2483,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
|
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
|
||||||
|
|
||||||
char *txt_buf = (char *)malloc(SZ_16K);
|
char *txt_buf = (char *)malloc(SZ_16K);
|
||||||
txt_buf[0] = '\n';
|
s_printf(txt_buf, "#00DDFF v%d.00#\n", sd_storage_get_scr_sda_ver(&sd_storage));
|
||||||
txt_buf[1] = 0;
|
|
||||||
|
|
||||||
// Identify manufacturer.
|
// Identify manufacturer.
|
||||||
switch (sd_storage.cid.manfid)
|
switch (sd_storage.cid.manfid)
|
||||||
@@ -2361,6 +2524,9 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
case 0x1D:
|
case 0x1D:
|
||||||
strcat(txt_buf, "AData ");
|
strcat(txt_buf, "AData ");
|
||||||
break;
|
break;
|
||||||
|
case 0x22:
|
||||||
|
strcat(txt_buf, "Kowin"); // #E: Digiera.
|
||||||
|
break;
|
||||||
case 0x27:
|
case 0x27:
|
||||||
strcat(txt_buf, "Phison ");
|
strcat(txt_buf, "Phison ");
|
||||||
break;
|
break;
|
||||||
@@ -2389,7 +2555,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
strcat(txt_buf, "Bongiovi ");
|
strcat(txt_buf, "Bongiovi ");
|
||||||
break;
|
break;
|
||||||
case 0x74:
|
case 0x74:
|
||||||
strcat(txt_buf, "Jiaelec ");
|
strcat(txt_buf, "Jiaelec "); // Transcend.
|
||||||
break;
|
break;
|
||||||
case 0x76:
|
case 0x76:
|
||||||
strcat(txt_buf, "Patriot ");
|
strcat(txt_buf, "Patriot ");
|
||||||
@@ -2413,7 +2579,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
strcat(txt_buf, "Taishin ");
|
strcat(txt_buf, "Taishin ");
|
||||||
break;
|
break;
|
||||||
case 0xAD:
|
case 0xAD:
|
||||||
strcat(txt_buf, "Longsys ");
|
strcat(txt_buf, "Longsys "); // Lexar/FORESEE.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcat(txt_buf, "Unknown ");
|
strcat(txt_buf, "Unknown ");
|
||||||
@@ -2423,13 +2589,38 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
// UHS-I max power limit is 400mA, no matter what the card says.
|
// UHS-I max power limit is 400mA, no matter what the card says.
|
||||||
u32 max_power_nominal = sd_storage.max_power > 400 ? 400 : sd_storage.max_power;
|
u32 max_power_nominal = sd_storage.max_power > 400 ? 400 : sd_storage.max_power;
|
||||||
|
|
||||||
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c (%04X)\n%X\n%X\n%08x\n%02d/%04d\n\n%d mW (%d mA)\n",
|
// Check for secret bits.
|
||||||
|
bool secret_bits = false;
|
||||||
|
sd_vendor_info_t sd_info = { 0 };
|
||||||
|
sd_storage_get_vendor_info(&sd_storage, &sd_info);
|
||||||
|
|
||||||
|
// Partially known bits.
|
||||||
|
if (sd_info.cid_rsvd && sd_info.cid_rsvd != 0x7 && sd_info.cid_rsvd != 0xA)
|
||||||
|
secret_bits = true;
|
||||||
|
if (sd_info.scr_vendor &&
|
||||||
|
sd_info.scr_vendor != 0x33333039 &&
|
||||||
|
sd_info.scr_vendor != 0x01196432 &&
|
||||||
|
sd_info.scr_vendor != 0x01006432 &&
|
||||||
|
sd_info.scr_vendor != 0x01000000)
|
||||||
|
secret_bits = true;
|
||||||
|
|
||||||
|
// Unknown bits.
|
||||||
|
sd_info.cid_rsvd = 0;
|
||||||
|
sd_info.scr_vendor = 0;
|
||||||
|
u8 *sd_info8 = (u8 *)&sd_info;
|
||||||
|
for (u32 i = 0; i < sizeof(sd_vendor_info_t); i++)
|
||||||
|
secret_bits |= !!sd_info8[i];
|
||||||
|
|
||||||
|
gfx_hexdump(0, sd_info8, sizeof(sd_vendor_info_t));
|
||||||
|
|
||||||
|
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c (%04X)\n%X\n%X\n%08x\n%02d/%04d\n%s\n%d mW (%d mA)\n",
|
||||||
sd_storage.cid.manfid,
|
sd_storage.cid.manfid,
|
||||||
sd_storage.cid.prod_name[0], sd_storage.cid.prod_name[1], sd_storage.cid.prod_name[2],
|
sd_storage.cid.prod_name[0], sd_storage.cid.prod_name[1], sd_storage.cid.prod_name[2],
|
||||||
sd_storage.cid.prod_name[3], sd_storage.cid.prod_name[4],
|
sd_storage.cid.prod_name[3], sd_storage.cid.prod_name[4],
|
||||||
(sd_storage.cid.oemid >> 8) & 0xFF, sd_storage.cid.oemid & 0xFF, sd_storage.cid.oemid,
|
(sd_storage.cid.oemid >> 8) & 0xFF, sd_storage.cid.oemid & 0xFF, sd_storage.cid.oemid,
|
||||||
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
|
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
|
||||||
sd_storage.cid.month, sd_storage.cid.year,
|
sd_storage.cid.month, sd_storage.cid.year,
|
||||||
|
secret_bits ? "#FF8000 Contact me#" : "",
|
||||||
max_power_nominal * 3600 / 1000, sd_storage.max_power);
|
max_power_nominal * 3600 / 1000, sd_storage.max_power);
|
||||||
|
|
||||||
switch (nyx_str->info.sd_init)
|
switch (nyx_str->info.sd_init)
|
||||||
@@ -2467,10 +2658,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
"Capacity (LBA):\n"
|
"Capacity (LBA):\n"
|
||||||
"Bus Width:\n"
|
"Bus Width:\n"
|
||||||
"Current Rate:\n"
|
"Current Rate:\n"
|
||||||
|
"Max Bus Speed:\n"
|
||||||
"Speed Class:\n"
|
"Speed Class:\n"
|
||||||
"UHS Classes:\n"
|
"UHS Classes:\n"
|
||||||
"Max Bus Speed:\n\n"
|
"Write Protect:\n"
|
||||||
"Write Protect:"
|
"Vendor Info:"
|
||||||
);
|
);
|
||||||
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
|
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
|
||||||
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 5 * 3, 0);
|
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 5 * 3, 0);
|
||||||
@@ -2483,15 +2675,15 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
char *wp_info;
|
char *wp_info;
|
||||||
switch (sd_storage.csd.write_protect)
|
switch (sd_storage.csd.write_protect)
|
||||||
{
|
{
|
||||||
|
case 0:
|
||||||
|
wp_info = "Inactive";
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
wp_info = "Temporary";
|
wp_info = "Temporary";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2 ... 3:
|
||||||
case 3:
|
|
||||||
wp_info = "Permanent";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
wp_info = "None";
|
wp_info = "Permanent";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2507,7 +2699,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
sd_storage_get_fmodes(&sd_storage, NULL, &fmodes);
|
sd_storage_get_fmodes(&sd_storage, NULL, &fmodes);
|
||||||
|
|
||||||
char *bus_speed;
|
char *bus_speed;
|
||||||
if (fmodes.cmd_system & SD_MODE_UHS_DDR200)
|
if (sd_storage_get_ddr200_support(&sd_storage))
|
||||||
bus_speed = "DDR200";
|
bus_speed = "DDR200";
|
||||||
else if (fmodes.access_mode & SD_MODE_UHS_SDR104)
|
else if (fmodes.access_mode & SD_MODE_UHS_SDR104)
|
||||||
bus_speed = "SDR104";
|
bus_speed = "SDR104";
|
||||||
@@ -2563,10 +2755,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
"%X (CP %X)\n"
|
"%X (CP %X)\n"
|
||||||
"%d\n"
|
"%d\n"
|
||||||
"%d MB/s (%d MHz)\n"
|
"%d MB/s (%d MHz)\n"
|
||||||
|
"%s%s\n"
|
||||||
"%d (AU: %d %s\n"
|
"%d (AU: %d %s\n"
|
||||||
"U%d V%d %sA%d%s\n"
|
"U%d V%d %sA%d%s\n"
|
||||||
"%s\n\n"
|
"%s\n"
|
||||||
"%s",
|
"%X %08X",
|
||||||
sd_storage.csd.structure + 1,
|
sd_storage.csd.structure + 1,
|
||||||
sd_storage.csd.cmdclass,
|
sd_storage.csd.cmdclass,
|
||||||
sd_storage.sec_cnt >> 11,
|
sd_storage.sec_cnt >> 11,
|
||||||
@@ -2574,10 +2767,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
|||||||
sd_storage.ssr.bus_width,
|
sd_storage.ssr.bus_width,
|
||||||
sd_storage.csd.busspeed,
|
sd_storage.csd.busspeed,
|
||||||
(sd_storage.csd.busspeed > 10) ? (sd_storage.csd.busspeed * 2) : 50,
|
(sd_storage.csd.busspeed > 10) ? (sd_storage.csd.busspeed * 2) : 50,
|
||||||
|
bus_speed, sd_storage.has_pcie ? " | SDE985" : "", // PCIe G3L1 (985 MB/s).
|
||||||
sd_storage.ssr.speed_class, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)",
|
sd_storage.ssr.speed_class, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)",
|
||||||
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, cpe ? cpe : "", sd_storage.ssr.app_class, cpe ? "#" : "",
|
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, cpe ? cpe : "", sd_storage.ssr.app_class, cpe ? "#" : "",
|
||||||
bus_speed,
|
wp_info,
|
||||||
wp_info);
|
sd_storage.cid.rsvd, sd_storage.scr.vendor);
|
||||||
|
|
||||||
lv_label_set_text(lb_val2, txt_buf);
|
lv_label_set_text(lb_val2, txt_buf);
|
||||||
|
|
||||||
@@ -2767,28 +2961,33 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
|
|||||||
value = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
|
value = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
|
||||||
u32 main_pmic_version = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID3) & 0xF;
|
u32 main_pmic_version = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID3) & 0xF;
|
||||||
|
|
||||||
|
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d%s\n",
|
||||||
|
main_pmic_version, main_pmic_version == 11 ? "" : "#FF8000 "SYMBOL_WARNING"#");
|
||||||
if (value == 0x35)
|
if (value == 0x35)
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\nErista OTP\n", main_pmic_version);
|
strcat(txt_buf, "Erista OTP\n");
|
||||||
else if (value == 0x53)
|
else if (value == 0x53)
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\nMariko OTP\n", main_pmic_version);
|
strcat(txt_buf, "Mariko OTP\n");
|
||||||
else
|
else
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\n#FF8000 Unknown OTP# (%02X)\n", main_pmic_version, value);
|
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown OTP# (%02X)\n", value);
|
||||||
|
|
||||||
// CPU/GPU/DRAM Pmic IC info.
|
// CPU/GPU/DRAM Pmic IC info.
|
||||||
u32 cpu_gpu_pmic_type = h_cfg.t210b01 ? (FUSE(FUSE_RESERVED_ODM28_B01) & 1) + 1 : 0;
|
u32 cpu_gpu_pmic_type = h_cfg.t210b01 ? (FUSE(FUSE_RESERVED_ODM28_B01) & 1) + 1 : 0;
|
||||||
|
u8 version;
|
||||||
switch (cpu_gpu_pmic_type)
|
switch (cpu_gpu_pmic_type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77621 v%d",
|
version = i2c_recv_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_REG_CHIPID1);
|
||||||
i2c_recv_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_REG_CHIPID1));
|
s_printf(txt_buf + strlen(txt_buf), "max77621 v%d%s",
|
||||||
|
version , version == 18 ? "" : "#FF8000 "SYMBOL_WARNING"#");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77812-2 v%d", // High power GPU. 2 Outputs, phases 3 1.
|
s_printf(txt_buf + strlen(txt_buf), "max77812-2 v%d", // High power GPU. 2 Outputs, phases 3 1.
|
||||||
i2c_recv_byte(I2C_5, MAX77812_PHASE31_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7);
|
i2c_recv_byte(I2C_5, MAX77812_PHASE31_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
s_printf(txt_buf + strlen(txt_buf), "max77812-3 v%d.0", // Low power GPU. 3 Outputs, phases 2 1 1.
|
version = i2c_recv_byte(I2C_5, MAX77812_PHASE211_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7;
|
||||||
i2c_recv_byte(I2C_5, MAX77812_PHASE211_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7);
|
s_printf(txt_buf + strlen(txt_buf), "max77812-3 v%d%s", // Low power GPU. 3 Outputs, phases 2 1 1.
|
||||||
|
version, version == 5 ? "" : "#FF8000 "SYMBOL_WARNING"#");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -968,7 +968,7 @@ static u32 _get_available_l4t_partition()
|
|||||||
|
|
||||||
// Search for a suitable partition.
|
// Search for a suitable partition.
|
||||||
u32 size_sct = 0;
|
u32 size_sct = 0;
|
||||||
if (!memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
|
if (!memcmp(&gpt->header.signature, "EFI PART", 8) && gpt->header.num_part_ents <= 128)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
|
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user