/* * Copyright (C) 2014-2016, Toradex AG * * SPDX-License-Identifier: GPL-2.0+ */ /* * Helpers for i.MX OTP fusing during module production */ #include #include static int mfgr_fuse(void) { unsigned val, val6; fuse_sense(0, 5, &val); printf("Fuse 0, 5: %8x\n", val); fuse_sense(0, 6, &val6); printf("Fuse 0, 6: %8x\n", val6); fuse_sense(4, 3, &val); printf("Fuse 4, 3: %8x\n", val); fuse_sense(4, 2, &val); printf("Fuse 4, 2: %8x\n", val); if(val6 & 0x10) { puts("BT_FUSE_SEL already fused, will do nothing\n"); return CMD_RET_FAILURE; } /* boot cfg */ fuse_prog(0, 5, 0x00005072); /* BT_FUSE_SEL */ fuse_prog(0, 6, 0x00000010); return CMD_RET_SUCCESS; } int do_mfgr_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret; puts("Fusing...\n"); ret = mfgr_fuse(); if (ret == CMD_RET_SUCCESS) puts("done.\n"); else puts("failed.\n"); return ret; } int do_updt_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned val; int ret; int confirmed = argc >= 1 && !strcmp(argv[1], "-y"); /* can be used in scripts for command availability check */ if (argc >= 1 && !strcmp(argv[1], "-n")) return CMD_RET_SUCCESS; /* boot cfg */ fuse_sense(0, 5, &val); printf("Fuse 0, 5: %8x\n", val); if(val & 0x10) { puts("Fast boot mode already fused, no need to fuse\n"); return CMD_RET_SUCCESS; } if (!confirmed) { puts("Warning: Programming fuses is an irreversible operation!\n" " Updating to fast boot mode prevents easy\n" " downgrading to previous BSP versions.\n" "\nReally perform this fuse programming? \n"); if (!confirm_yesno()) return CMD_RET_FAILURE; } puts("Fusing fast boot mode...\n"); ret = fuse_prog(0, 5, 0x00005072); if (ret == CMD_RET_SUCCESS) puts("done.\n"); else puts("failed.\n"); return ret; } U_BOOT_CMD( mfgr_fuse, 1, 0, do_mfgr_fuse, "OTP fusing during module production", "" ); U_BOOT_CMD( updt_fuse, 2, 0, do_updt_fuse, "OTP fusing during module update", "updt_fuse [-n] [-y] - boot cfg fast boot mode fusing" );