mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-22 20:06:40 +00:00
fusee/exo/sept: additional fixes
This commit is contained in:
parent
b89f0e45ec
commit
11ec6a6912
19 changed files with 158 additions and 121 deletions
|
@ -187,11 +187,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
||||||
*p_outvalue = INTERRUPT_ID_USER_SECURITY_ENGINE;
|
*p_outvalue = INTERRUPT_ID_USER_SECURITY_ENGINE;
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_VERSION:
|
case CONFIGITEM_VERSION:
|
||||||
/* Always returns maxver - 1 on hardware. */
|
*p_outvalue = fuse_get_expected_fuse_version(exosphere_get_target_firmware());
|
||||||
*p_outvalue = PACKAGE2_MAXVER_400_410 - 1;
|
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_HARDWARETYPE:
|
case CONFIGITEM_HARDWARETYPE:
|
||||||
*p_outvalue = fuse_get_hardware_type(mkey_get_revision());
|
*p_outvalue = fuse_get_hardware_type(exosphere_get_target_firmware());
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_ISRETAIL:
|
case CONFIGITEM_ISRETAIL:
|
||||||
*p_outvalue = fuse_get_retail_type();
|
*p_outvalue = fuse_get_retail_type();
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -36,7 +37,7 @@ void fuse_init(void) {
|
||||||
clkrst_enable_fuse_regs(true);
|
clkrst_enable_fuse_regs(true);
|
||||||
fuse_disable_private_key();
|
fuse_disable_private_key();
|
||||||
fuse_disable_programming();
|
fuse_disable_programming();
|
||||||
|
|
||||||
/* TODO: Should we allow this to be done later? */
|
/* TODO: Should we allow this to be done later? */
|
||||||
if (!g_has_checked_for_rcm_bug_patch) {
|
if (!g_has_checked_for_rcm_bug_patch) {
|
||||||
(void)(fuse_has_rcm_bug_patch());
|
(void)(fuse_has_rcm_bug_patch());
|
||||||
|
@ -127,7 +128,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
|
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -173,37 +174,38 @@ uint64_t fuse_get_device_id(void) {
|
||||||
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
} else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) {
|
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
@ -258,6 +260,31 @@ uint32_t fuse_get_5x_key_generation(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the fuse version expected for the firmware. */
|
||||||
|
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
|
||||||
|
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
|
||||||
|
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_COUNT) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
return expected_versions[target_firmware];
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for RCM bug patches. */
|
/* Check for RCM bug patches. */
|
||||||
bool fuse_has_rcm_bug_patch(void) {
|
bool fuse_has_rcm_bug_patch(void) {
|
||||||
/* Only check for RCM bug patch once, and cache our result. */
|
/* Only check for RCM bug patch once, and cache our result. */
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXOSPHERE_FUSE_H
|
#ifndef EXOSPHERE_FUSE_H
|
||||||
#define EXOSPHERE_FUSE_H
|
#define EXOSPHERE_FUSE_H
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
uint32_t fuse_get_5x_key_generation(void);
|
uint32_t fuse_get_5x_key_generation(void);
|
||||||
|
@ -228,4 +228,7 @@ uint32_t fuse_hw_read(uint32_t addr);
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||||
void fuse_hw_sense(void);
|
void fuse_hw_sense(void);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/lib src/display
|
SOURCES := src src/lib src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -79,7 +80,7 @@ void fuse_wait_idle(void) {
|
||||||
/* Read a fuse from the hardware array. */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
/* Write a fuse in the hardware array. */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
/* Sense the fuse hardware array into the shadow cache. */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -176,36 +177,36 @@ uint32_t fuse_get_dram_id(void) {
|
||||||
/* Derive the Device ID using values in the shadow cache. */
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
|
@ -214,7 +215,7 @@ uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -79,7 +80,7 @@ void fuse_wait_idle(void) {
|
||||||
/* Read a fuse from the hardware array. */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
/* Write a fuse in the hardware array. */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
/* Sense the fuse hardware array into the shadow cache. */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -176,36 +177,36 @@ uint32_t fuse_get_dram_id(void) {
|
||||||
/* Derive the Device ID using values in the shadow cache. */
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
|
@ -214,7 +215,7 @@ uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -79,7 +80,7 @@ void fuse_wait_idle(void) {
|
||||||
/* Read a fuse from the hardware array. */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
/* Write a fuse in the hardware array. */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
/* Sense the fuse hardware array into the shadow cache. */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -176,36 +177,36 @@ uint32_t fuse_get_dram_id(void) {
|
||||||
/* Derive the Device ID using values in the shadow cache. */
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
|
@ -214,7 +215,7 @@ uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
|
|
@ -32,3 +32,4 @@
|
||||||
|
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
|
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||||
|
#define ATMOSPHERE_TARGET_FIRMWARE_COUNT ((ATMOSPHERE_TARGET_FIRMWARE_MAX - ATMOSPHERE_TARGET_FIRMWARE_MIN) + 1)
|
|
@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -77,7 +78,7 @@ void fuse_wait_idle(void) {
|
||||||
/* Read a fuse from the hardware array. */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
/* Write a fuse in the hardware array. */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
/* Sense the fuse hardware array into the shadow cache. */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -174,36 +175,36 @@ uint32_t fuse_get_dram_id(void) {
|
||||||
/* Derive the Device ID using values in the shadow cache. */
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
|
@ -212,7 +213,7 @@ uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
@ -143,17 +143,19 @@ clean:
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
else
|
else
|
||||||
.PHONY: all $(OUTPUT).bin
|
.PHONY: all
|
||||||
|
|
||||||
DEPENDS := $(OFILES:.o=.d)
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all : $(OUTPUT).enc
|
all : $(OUTPUT)_01.enc
|
||||||
|
|
||||||
$(OUTPUT).enc : $(OUTPUT).bin
|
$(OUTPUT)_01.enc : $(OUTPUT)_00.enc
|
||||||
@python $(TOPDIR)/sept_sign.py $< $@
|
|
||||||
|
$(OUTPUT)_00.enc : $(OUTPUT).bin
|
||||||
|
@python $(TOPDIR)/sept_sign.py $(OUTPUT).bin $(OUTPUT).enc
|
||||||
@echo built ... $(notdir $@)
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
$(OUTPUT).bin : $(OUTPUT).elf
|
$(OUTPUT).bin : $(OUTPUT).elf
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "di.h"
|
#include "di.h"
|
||||||
|
@ -51,13 +51,13 @@ void display_init()
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
volatile tegra_car_t *car = car_get_regs();
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||||
|
|
||||||
/* Power on. */
|
/* Power on. */
|
||||||
uint8_t val = 0xD0;
|
uint8_t val = 0xD0;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
|
||||||
val = 0x09;
|
val = 0x09;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_GPIO7, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_GPIO7, &val, 1);
|
||||||
|
|
||||||
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
|
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
|
||||||
car->rst_dev_h_clr = 0x1010000;
|
car->rst_dev_h_clr = 0x1010000;
|
||||||
car->clk_enb_h_set = 0x1010000;
|
car->clk_enb_h_set = 0x1010000;
|
||||||
|
@ -78,31 +78,31 @@ void display_init()
|
||||||
pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
|
pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
|
||||||
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
|
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
|
||||||
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
|
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
|
||||||
|
|
||||||
/* Configure Backlight +-5V GPIOs. */
|
/* Configure Backlight +-5V GPIOs. */
|
||||||
gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
|
gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
|
||||||
gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
|
gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
|
||||||
gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
|
gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
|
||||||
gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
|
gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
|
||||||
|
|
||||||
/* Enable Backlight +5V. */
|
/* Enable Backlight +5V. */
|
||||||
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
|
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
/* Enable Backlight -5V. */
|
/* Enable Backlight -5V. */
|
||||||
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
|
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
/* Configure Backlight PWM, EN and RST GPIOs. */
|
/* Configure Backlight PWM, EN and RST GPIOs. */
|
||||||
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
|
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
|
||||||
gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
|
gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
|
||||||
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
|
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
|
||||||
gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
|
gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
|
||||||
gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
|
gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
|
||||||
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
|
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
|
||||||
|
|
||||||
/* Enable Backlight EN. */
|
/* Enable Backlight EN. */
|
||||||
gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
|
gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ void display_init()
|
||||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 60);
|
exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 60);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
/* Enable Backlight RST. */
|
/* Enable Backlight RST. */
|
||||||
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
|
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ void display_init()
|
||||||
udelay(5000);
|
udelay(5000);
|
||||||
|
|
||||||
_display_ver = MAKE_DSI_REG(DSI_RD_DATA);
|
_display_ver = MAKE_DSI_REG(DSI_RD_DATA);
|
||||||
|
|
||||||
if (_display_ver == 0x10)
|
if (_display_ver == 0x10)
|
||||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_4, 43);
|
exec_cfg((uint32_t *)DSI_BASE, _display_config_4, 43);
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ void display_init()
|
||||||
|
|
||||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_5, 21);
|
exec_cfg((uint32_t *)DSI_BASE, _display_config_5, 21);
|
||||||
exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
|
exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
|
||||||
|
|
||||||
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
|
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
|
||||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_7, 10);
|
exec_cfg((uint32_t *)DSI_BASE, _display_config_7, 10);
|
||||||
|
|
||||||
|
@ -176,10 +176,10 @@ void display_end()
|
||||||
{
|
{
|
||||||
volatile tegra_car_t *car = car_get_regs();
|
volatile tegra_car_t *car = car_get_regs();
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||||
|
|
||||||
/* Disable Backlight. */
|
/* Disable Backlight. */
|
||||||
display_backlight(false);
|
display_backlight(false);
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
|
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
|
||||||
MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
|
MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
|
||||||
|
|
||||||
|
@ -198,19 +198,19 @@ void display_end()
|
||||||
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
|
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
|
||||||
|
|
||||||
udelay(50000);
|
udelay(50000);
|
||||||
|
|
||||||
/* Disable Backlight RST. */
|
/* Disable Backlight RST. */
|
||||||
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
|
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
/* Disable Backlight -5V. */
|
/* Disable Backlight -5V. */
|
||||||
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
|
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
/* Disable Backlight +5V. */
|
/* Disable Backlight +5V. */
|
||||||
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
|
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
|
||||||
|
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
|
@ -222,10 +222,10 @@ void display_end()
|
||||||
|
|
||||||
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
|
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
|
||||||
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
|
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
|
||||||
|
|
||||||
/* Backlight PWM. */
|
/* Backlight PWM. */
|
||||||
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
|
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
|
||||||
|
|
||||||
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
|
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
|
||||||
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
|
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ uint32_t *display_init_framebuffer(void *address)
|
||||||
|
|
||||||
uint32_t *lfb_addr = (uint32_t *)address;
|
uint32_t *lfb_addr = (uint32_t *)address;
|
||||||
conf[19].val = (uint32_t)address;
|
conf[19].val = (uint32_t)address;
|
||||||
|
|
||||||
/* This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768). */
|
/* This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768). */
|
||||||
exec_cfg((uint32_t *)DI_BASE, conf, 32);
|
exec_cfg((uint32_t *)DI_BASE, conf, 32);
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
@ -79,7 +80,7 @@ void fuse_wait_idle(void) {
|
||||||
/* Read a fuse from the hardware array. */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
/* Write a fuse in the hardware array. */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
/* Sense the fuse hardware array into the shadow cache. */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ void fuse_hw_sense(void) {
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_FUSECTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
/* Wait for idle state. */
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -176,36 +177,36 @@ uint32_t fuse_get_dram_id(void) {
|
||||||
/* Derive the Device ID using values in the shadow cache. */
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache. */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Firmware from versions 1.0.0 to 3.0.2. */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
if (mkey_rev < 0x03) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
|
@ -214,7 +215,7 @@ uint32_t fuse_get_hardware_type(uint32_t mkey_rev) {
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
} else if ((mkey_rev >= 0x03) && (mkey_rev < 0x07)) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
hardware_type--;
|
hardware_type--;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(uint32_t mkey_rev);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue