This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM625: Reading eFuse0 in Linux 6.18

Part Number: AM625

Hi,

I am trying to read the burn efuses (OTP) in an AM62x from Linux (A53 core).
But when I try I get only 0's out, while the mcu_plus_sdk_am62x_11_02_00_23 said otherwise (R5 core).
I should have enable though u-boot, that all cores are allowed to read from the efuse area. (0x4081)

What am I doing wrong? Should TI-SCI allow me to read the efuses?
boot_log_read_efuse.txt 0001-ti-efuse-Demo-read-efuse-and-fuse-status.patch.txt 0001-TI-SCI-allow-efuses-to-A53-core-for-AM62x.patch.txt 

From the mcu_plus_sdk I get:
OTP MMR 0: 0x4
OTP MMR 1: 0x0
OTP MMR 2: 0xaaaaaaaa
OTP MMR 3: 0xaaaaaaaa
OTP MMR 4: 0xaaaaaaaa
OTP MMR 5: 0x0
OTP MMR 6: 0x0
OTP MMR 7: 0x0
OTP MMR 8: 0x0
OTP MMR 9: 0x0
OTP MMR 10: 0x0
OTP MMR 11: 0x0
OTP MMR 12: 0x0
OTP MMR 13: 0x0
OTP MMR 14: 0x0
OTP MMR 15: 0x0
OTP MMR 16: 0x0
OTP MMR 17: 0x0
OTP MMR 18: 0x0
OTP MMR 19: 0x0
OTP MMR 20: 0x0
OTP MMR 21: 0x0
OTP MMR 22: 0x0
OTP MMR 23: 0x0
OTP MMR 24: 0x0
OTP MMR 25: 0x0
OTP MMR 26: 0x0
OTP MMR 27: 0x0
OTP MMR 28: 0x0
OTP MMR 29: 0x277700
OTP MMR 30: 0x38383838
OTP MMR 31: 0xebc80765

  • Hello,

    The following Extended OTP APIs can only be called from the Secure Hosts which are ATF/OPTEE on A53 core.

    software-dl.ti.com/.../extended_otp.html

  • After using optee-client and reading https://github.com/OP-TEE/optee_os/blob/master/core/pta/k3/otp.c#L52, I was able to make this C application for reading the efuses.

    #include <tee_client_api.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    
    #define PTA_K3_OTP_UUID { 0xacc50f40, 0x0613, 0x4abd, \
        { 0x8d, 0xfe, 0xa9, 0x64, 0xcb, 0x74, 0xeb, 0x69 } }
    
    #define TA_OTP_CMD_READ_MMR  0
    
    int main(int argc, char *argv[])
    {
        TEEC_Context ctx;
        TEEC_Session sess;
        TEEC_Operation op = { 0 };
        TEEC_UUID uuid = PTA_K3_OTP_UUID;
        TEEC_Result res;
        uint32_t origin;
        uint32_t mmr_index = 0; /* OTP row index to read */
    
        if (argc > 1)
            mmr_index = (uint32_t)strtoul(argv[1], NULL, 0);
    
        res = TEEC_InitializeContext(NULL, &ctx);
        if (res != TEEC_SUCCESS) {
            fprintf(stderr, "TEEC_InitializeContext failed: 0x%x\n", res);
            return 1;
        }
    
        /* Open session directly to the PTA (no TA binary needed on the filesystem) */
        res = TEEC_OpenSession(&ctx, &sess, &uuid,
                               TEEC_LOGIN_PUBLIC, NULL, NULL, &origin);
        if (res != TEEC_SUCCESS) {
            fprintf(stderr, "TEEC_OpenSession failed: 0x%x, origin 0x%x\n", res, origin);
            TEEC_FinalizeContext(&ctx);
            return 1;
        }
    
        op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
                                         TEEC_VALUE_OUTPUT,
                                         TEEC_NONE, TEEC_NONE);
        op.params[0].value.a = mmr_index;
    
        res = TEEC_InvokeCommand(&sess, TA_OTP_CMD_READ_MMR, &op, &origin);
        if (res != TEEC_SUCCESS) {
            fprintf(stderr, "TEEC_InvokeCommand failed: 0x%x, origin 0x%x\n", res, origin);
        } else {
            printf("OTP row[%u] = 0x%08x\n", mmr_index, op.params[1].value.a);
        }
    
        TEEC_CloseSession(&sess);
        TEEC_FinalizeContext(&ctx);
        return (res == TEEC_SUCCESS) ? 0 : 1;
    }