1*c3600e1fSPatrick Delaunay // SPDX-License-Identifier: GPL-2.0+ 2*c3600e1fSPatrick Delaunay /* 3*c3600e1fSPatrick Delaunay * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4*c3600e1fSPatrick Delaunay */ 5*c3600e1fSPatrick Delaunay 6*c3600e1fSPatrick Delaunay #include <common.h> 7*c3600e1fSPatrick Delaunay #include <command.h> 8*c3600e1fSPatrick Delaunay #include <misc.h> 9*c3600e1fSPatrick Delaunay #include <errno.h> 10*c3600e1fSPatrick Delaunay #include <dm/device.h> 11*c3600e1fSPatrick Delaunay #include <dm/uclass.h> 12*c3600e1fSPatrick Delaunay 13*c3600e1fSPatrick Delaunay #define STM32MP_OTP_BANK 0 14*c3600e1fSPatrick Delaunay 15*c3600e1fSPatrick Delaunay /* 16*c3600e1fSPatrick Delaunay * The 'fuse' command API 17*c3600e1fSPatrick Delaunay */ 18*c3600e1fSPatrick Delaunay int fuse_read(u32 bank, u32 word, u32 *val) 19*c3600e1fSPatrick Delaunay { 20*c3600e1fSPatrick Delaunay int ret = 0; 21*c3600e1fSPatrick Delaunay struct udevice *dev; 22*c3600e1fSPatrick Delaunay 23*c3600e1fSPatrick Delaunay switch (bank) { 24*c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK: 25*c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC, 26*c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec), 27*c3600e1fSPatrick Delaunay &dev); 28*c3600e1fSPatrick Delaunay if (ret) 29*c3600e1fSPatrick Delaunay return ret; 30*c3600e1fSPatrick Delaunay ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, 31*c3600e1fSPatrick Delaunay val, 4); 32*c3600e1fSPatrick Delaunay break; 33*c3600e1fSPatrick Delaunay 34*c3600e1fSPatrick Delaunay default: 35*c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); 36*c3600e1fSPatrick Delaunay ret = -EINVAL; 37*c3600e1fSPatrick Delaunay break; 38*c3600e1fSPatrick Delaunay } 39*c3600e1fSPatrick Delaunay 40*c3600e1fSPatrick Delaunay return ret; 41*c3600e1fSPatrick Delaunay } 42*c3600e1fSPatrick Delaunay 43*c3600e1fSPatrick Delaunay int fuse_prog(u32 bank, u32 word, u32 val) 44*c3600e1fSPatrick Delaunay { 45*c3600e1fSPatrick Delaunay struct udevice *dev; 46*c3600e1fSPatrick Delaunay int ret; 47*c3600e1fSPatrick Delaunay 48*c3600e1fSPatrick Delaunay switch (bank) { 49*c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK: 50*c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC, 51*c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec), 52*c3600e1fSPatrick Delaunay &dev); 53*c3600e1fSPatrick Delaunay if (ret) 54*c3600e1fSPatrick Delaunay return ret; 55*c3600e1fSPatrick Delaunay ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET, 56*c3600e1fSPatrick Delaunay &val, 4); 57*c3600e1fSPatrick Delaunay break; 58*c3600e1fSPatrick Delaunay 59*c3600e1fSPatrick Delaunay default: 60*c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); 61*c3600e1fSPatrick Delaunay ret = -EINVAL; 62*c3600e1fSPatrick Delaunay break; 63*c3600e1fSPatrick Delaunay } 64*c3600e1fSPatrick Delaunay 65*c3600e1fSPatrick Delaunay return ret; 66*c3600e1fSPatrick Delaunay } 67*c3600e1fSPatrick Delaunay 68*c3600e1fSPatrick Delaunay int fuse_sense(u32 bank, u32 word, u32 *val) 69*c3600e1fSPatrick Delaunay { 70*c3600e1fSPatrick Delaunay struct udevice *dev; 71*c3600e1fSPatrick Delaunay int ret; 72*c3600e1fSPatrick Delaunay 73*c3600e1fSPatrick Delaunay switch (bank) { 74*c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK: 75*c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC, 76*c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec), 77*c3600e1fSPatrick Delaunay &dev); 78*c3600e1fSPatrick Delaunay if (ret) 79*c3600e1fSPatrick Delaunay return ret; 80*c3600e1fSPatrick Delaunay ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4); 81*c3600e1fSPatrick Delaunay break; 82*c3600e1fSPatrick Delaunay 83*c3600e1fSPatrick Delaunay default: 84*c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); 85*c3600e1fSPatrick Delaunay ret = -EINVAL; 86*c3600e1fSPatrick Delaunay break; 87*c3600e1fSPatrick Delaunay } 88*c3600e1fSPatrick Delaunay 89*c3600e1fSPatrick Delaunay return ret; 90*c3600e1fSPatrick Delaunay } 91*c3600e1fSPatrick Delaunay 92*c3600e1fSPatrick Delaunay int fuse_override(u32 bank, u32 word, u32 val) 93*c3600e1fSPatrick Delaunay { 94*c3600e1fSPatrick Delaunay struct udevice *dev; 95*c3600e1fSPatrick Delaunay int ret; 96*c3600e1fSPatrick Delaunay 97*c3600e1fSPatrick Delaunay switch (bank) { 98*c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK: 99*c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC, 100*c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec), 101*c3600e1fSPatrick Delaunay &dev); 102*c3600e1fSPatrick Delaunay if (ret) 103*c3600e1fSPatrick Delaunay return ret; 104*c3600e1fSPatrick Delaunay ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, 105*c3600e1fSPatrick Delaunay &val, 4); 106*c3600e1fSPatrick Delaunay break; 107*c3600e1fSPatrick Delaunay 108*c3600e1fSPatrick Delaunay default: 109*c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", 110*c3600e1fSPatrick Delaunay __func__, bank); 111*c3600e1fSPatrick Delaunay ret = -EINVAL; 112*c3600e1fSPatrick Delaunay break; 113*c3600e1fSPatrick Delaunay } 114*c3600e1fSPatrick Delaunay 115*c3600e1fSPatrick Delaunay return ret; 116*c3600e1fSPatrick Delaunay } 117