444 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2019 Spreadtrum Communications Inc.3 4#include <linux/clk.h>5#include <linux/delay.h>6#include <linux/hwspinlock.h>7#include <linux/io.h>8#include <linux/module.h>9#include <linux/nvmem-provider.h>10#include <linux/of.h>11#include <linux/platform_device.h>12 13#define SPRD_EFUSE_ENABLE 0x2014#define SPRD_EFUSE_ERR_FLAG 0x2415#define SPRD_EFUSE_ERR_CLR 0x2816#define SPRD_EFUSE_MAGIC_NUM 0x2c17#define SPRD_EFUSE_FW_CFG 0x5018#define SPRD_EFUSE_PW_SWT 0x5419#define SPRD_EFUSE_MEM(val) (0x1000 + ((val) << 2))20 21#define SPRD_EFUSE_VDD_EN BIT(0)22#define SPRD_EFUSE_AUTO_CHECK_EN BIT(1)23#define SPRD_EFUSE_DOUBLE_EN BIT(2)24#define SPRD_EFUSE_MARGIN_RD_EN BIT(3)25#define SPRD_EFUSE_LOCK_WR_EN BIT(4)26 27#define SPRD_EFUSE_ERR_CLR_MASK GENMASK(13, 0)28 29#define SPRD_EFUSE_ENK1_ON BIT(0)30#define SPRD_EFUSE_ENK2_ON BIT(1)31#define SPRD_EFUSE_PROG_EN BIT(2)32 33#define SPRD_EFUSE_MAGIC_NUMBER 0x881034 35/* Block width (bytes) definitions */36#define SPRD_EFUSE_BLOCK_WIDTH 437 38/*39 * The Spreadtrum AP efuse contains 2 parts: normal efuse and secure efuse,40 * and we can only access the normal efuse in kernel. So define the normal41 * block offset index and normal block numbers.42 */43#define SPRD_EFUSE_NORMAL_BLOCK_NUMS 2444#define SPRD_EFUSE_NORMAL_BLOCK_OFFSET 7245 46/* Timeout (ms) for the trylock of hardware spinlocks */47#define SPRD_EFUSE_HWLOCK_TIMEOUT 500048 49/*50 * Since different Spreadtrum SoC chip can have different normal block numbers51 * and offset. And some SoC can support block double feature, which means52 * when reading or writing data to efuse memory, the controller can save double53 * data in case one data become incorrect after a long period.54 *55 * Thus we should save them in the device data structure.56 */57struct sprd_efuse_variant_data {58 u32 blk_nums;59 u32 blk_offset;60 bool blk_double;61};62 63struct sprd_efuse {64 struct device *dev;65 struct clk *clk;66 struct hwspinlock *hwlock;67 struct mutex mutex;68 void __iomem *base;69 const struct sprd_efuse_variant_data *data;70};71 72static const struct sprd_efuse_variant_data ums312_data = {73 .blk_nums = SPRD_EFUSE_NORMAL_BLOCK_NUMS,74 .blk_offset = SPRD_EFUSE_NORMAL_BLOCK_OFFSET,75 .blk_double = false,76};77 78/*79 * On Spreadtrum platform, we have multi-subsystems will access the unique80 * efuse controller, so we need one hardware spinlock to synchronize between81 * the multiple subsystems.82 */83static int sprd_efuse_lock(struct sprd_efuse *efuse)84{85 int ret;86 87 mutex_lock(&efuse->mutex);88 89 ret = hwspin_lock_timeout_raw(efuse->hwlock,90 SPRD_EFUSE_HWLOCK_TIMEOUT);91 if (ret) {92 dev_err(efuse->dev, "timeout get the hwspinlock\n");93 mutex_unlock(&efuse->mutex);94 return ret;95 }96 97 return 0;98}99 100static void sprd_efuse_unlock(struct sprd_efuse *efuse)101{102 hwspin_unlock_raw(efuse->hwlock);103 mutex_unlock(&efuse->mutex);104}105 106static void sprd_efuse_set_prog_power(struct sprd_efuse *efuse, bool en)107{108 u32 val = readl(efuse->base + SPRD_EFUSE_PW_SWT);109 110 if (en)111 val &= ~SPRD_EFUSE_ENK2_ON;112 else113 val &= ~SPRD_EFUSE_ENK1_ON;114 115 writel(val, efuse->base + SPRD_EFUSE_PW_SWT);116 117 /* Open or close efuse power need wait 1000us to make power stable. */118 usleep_range(1000, 1200);119 120 if (en)121 val |= SPRD_EFUSE_ENK1_ON;122 else123 val |= SPRD_EFUSE_ENK2_ON;124 125 writel(val, efuse->base + SPRD_EFUSE_PW_SWT);126 127 /* Open or close efuse power need wait 1000us to make power stable. */128 usleep_range(1000, 1200);129}130 131static void sprd_efuse_set_read_power(struct sprd_efuse *efuse, bool en)132{133 u32 val = readl(efuse->base + SPRD_EFUSE_ENABLE);134 135 if (en)136 val |= SPRD_EFUSE_VDD_EN;137 else138 val &= ~SPRD_EFUSE_VDD_EN;139 140 writel(val, efuse->base + SPRD_EFUSE_ENABLE);141 142 /* Open or close efuse power need wait 1000us to make power stable. */143 usleep_range(1000, 1200);144}145 146static void sprd_efuse_set_prog_lock(struct sprd_efuse *efuse, bool en)147{148 u32 val = readl(efuse->base + SPRD_EFUSE_ENABLE);149 150 if (en)151 val |= SPRD_EFUSE_LOCK_WR_EN;152 else153 val &= ~SPRD_EFUSE_LOCK_WR_EN;154 155 writel(val, efuse->base + SPRD_EFUSE_ENABLE);156}157 158static void sprd_efuse_set_auto_check(struct sprd_efuse *efuse, bool en)159{160 u32 val = readl(efuse->base + SPRD_EFUSE_ENABLE);161 162 if (en)163 val |= SPRD_EFUSE_AUTO_CHECK_EN;164 else165 val &= ~SPRD_EFUSE_AUTO_CHECK_EN;166 167 writel(val, efuse->base + SPRD_EFUSE_ENABLE);168}169 170static void sprd_efuse_set_data_double(struct sprd_efuse *efuse, bool en)171{172 u32 val = readl(efuse->base + SPRD_EFUSE_ENABLE);173 174 if (en)175 val |= SPRD_EFUSE_DOUBLE_EN;176 else177 val &= ~SPRD_EFUSE_DOUBLE_EN;178 179 writel(val, efuse->base + SPRD_EFUSE_ENABLE);180}181 182static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en)183{184 u32 val = readl(efuse->base + SPRD_EFUSE_PW_SWT);185 186 if (en)187 val |= SPRD_EFUSE_PROG_EN;188 else189 val &= ~SPRD_EFUSE_PROG_EN;190 191 writel(val, efuse->base + SPRD_EFUSE_PW_SWT);192}193 194static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,195 bool lock, u32 *data)196{197 u32 status;198 int ret = 0;199 200 /*201 * We need set the correct magic number before writing the efuse to202 * allow programming, and block other programming until we clear the203 * magic number.204 */205 writel(SPRD_EFUSE_MAGIC_NUMBER,206 efuse->base + SPRD_EFUSE_MAGIC_NUM);207 208 /*209 * Power on the efuse, enable programme and enable double data210 * if asked.211 */212 sprd_efuse_set_prog_power(efuse, true);213 sprd_efuse_set_prog_en(efuse, true);214 sprd_efuse_set_data_double(efuse, doub);215 216 /*217 * Enable the auto-check function to validate if the programming is218 * successful.219 */220 if (lock)221 sprd_efuse_set_auto_check(efuse, true);222 223 writel(*data, efuse->base + SPRD_EFUSE_MEM(blk));224 225 /* Disable auto-check and data double after programming */226 if (lock)227 sprd_efuse_set_auto_check(efuse, false);228 sprd_efuse_set_data_double(efuse, false);229 230 /*231 * Check the efuse error status, if the programming is successful,232 * we should lock this efuse block to avoid programming again.233 */234 status = readl(efuse->base + SPRD_EFUSE_ERR_FLAG);235 if (status) {236 dev_err(efuse->dev,237 "write error status %u of block %d\n", status, blk);238 239 writel(SPRD_EFUSE_ERR_CLR_MASK,240 efuse->base + SPRD_EFUSE_ERR_CLR);241 ret = -EBUSY;242 } else if (lock) {243 sprd_efuse_set_prog_lock(efuse, lock);244 writel(0, efuse->base + SPRD_EFUSE_MEM(blk));245 sprd_efuse_set_prog_lock(efuse, false);246 }247 248 sprd_efuse_set_prog_power(efuse, false);249 writel(0, efuse->base + SPRD_EFUSE_MAGIC_NUM);250 251 return ret;252}253 254static int sprd_efuse_raw_read(struct sprd_efuse *efuse, int blk, u32 *val,255 bool doub)256{257 u32 status;258 259 /*260 * Need power on the efuse before reading data from efuse, and will261 * power off the efuse after reading process.262 */263 sprd_efuse_set_read_power(efuse, true);264 265 /* Enable double data if asked */266 sprd_efuse_set_data_double(efuse, doub);267 268 /* Start to read data from efuse block */269 *val = readl(efuse->base + SPRD_EFUSE_MEM(blk));270 271 /* Disable double data */272 sprd_efuse_set_data_double(efuse, false);273 274 /* Power off the efuse */275 sprd_efuse_set_read_power(efuse, false);276 277 /*278 * Check the efuse error status and clear them if there are some279 * errors occurred.280 */281 status = readl(efuse->base + SPRD_EFUSE_ERR_FLAG);282 if (status) {283 dev_err(efuse->dev,284 "read error status %d of block %d\n", status, blk);285 286 writel(SPRD_EFUSE_ERR_CLR_MASK,287 efuse->base + SPRD_EFUSE_ERR_CLR);288 return -EBUSY;289 }290 291 return 0;292}293 294static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)295{296 struct sprd_efuse *efuse = context;297 bool blk_double = efuse->data->blk_double;298 u32 index = offset / SPRD_EFUSE_BLOCK_WIDTH + efuse->data->blk_offset;299 u32 blk_offset = (offset % SPRD_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE;300 u32 data;301 int ret;302 303 ret = sprd_efuse_lock(efuse);304 if (ret)305 return ret;306 307 ret = clk_prepare_enable(efuse->clk);308 if (ret)309 goto unlock;310 311 ret = sprd_efuse_raw_read(efuse, index, &data, blk_double);312 if (!ret) {313 data >>= blk_offset;314 memcpy(val, &data, bytes);315 }316 317 clk_disable_unprepare(efuse->clk);318 319unlock:320 sprd_efuse_unlock(efuse);321 return ret;322}323 324static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)325{326 struct sprd_efuse *efuse = context;327 bool blk_double = efuse->data->blk_double;328 bool lock;329 int ret;330 331 ret = sprd_efuse_lock(efuse);332 if (ret)333 return ret;334 335 ret = clk_prepare_enable(efuse->clk);336 if (ret)337 goto unlock;338 339 /*340 * If the writing bytes are equal with the block width, which means the341 * whole block will be programmed. For this case, we should not allow342 * this block to be programmed again by locking this block.343 *344 * If the block was programmed partially, we should allow this block to345 * be programmed again.346 */347 if (bytes < SPRD_EFUSE_BLOCK_WIDTH)348 lock = false;349 else350 lock = true;351 352 ret = sprd_efuse_raw_prog(efuse, offset, blk_double, lock, val);353 354 clk_disable_unprepare(efuse->clk);355 356unlock:357 sprd_efuse_unlock(efuse);358 return ret;359}360 361static int sprd_efuse_probe(struct platform_device *pdev)362{363 struct device_node *np = pdev->dev.of_node;364 struct nvmem_device *nvmem;365 struct nvmem_config econfig = { };366 struct sprd_efuse *efuse;367 const struct sprd_efuse_variant_data *pdata;368 int ret;369 370 pdata = of_device_get_match_data(&pdev->dev);371 if (!pdata) {372 dev_err(&pdev->dev, "No matching driver data found\n");373 return -EINVAL;374 }375 376 efuse = devm_kzalloc(&pdev->dev, sizeof(*efuse), GFP_KERNEL);377 if (!efuse)378 return -ENOMEM;379 380 efuse->base = devm_platform_ioremap_resource(pdev, 0);381 if (IS_ERR(efuse->base))382 return PTR_ERR(efuse->base);383 384 ret = of_hwspin_lock_get_id(np, 0);385 if (ret < 0) {386 dev_err(&pdev->dev, "failed to get hwlock id\n");387 return ret;388 }389 390 efuse->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret);391 if (!efuse->hwlock) {392 dev_err(&pdev->dev, "failed to request hwlock\n");393 return -ENXIO;394 }395 396 efuse->clk = devm_clk_get(&pdev->dev, "enable");397 if (IS_ERR(efuse->clk)) {398 dev_err(&pdev->dev, "failed to get enable clock\n");399 return PTR_ERR(efuse->clk);400 }401 402 mutex_init(&efuse->mutex);403 efuse->dev = &pdev->dev;404 efuse->data = pdata;405 406 econfig.stride = 1;407 econfig.word_size = 1;408 econfig.read_only = false;409 econfig.name = "sprd-efuse";410 econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;411 econfig.add_legacy_fixed_of_cells = true;412 econfig.reg_read = sprd_efuse_read;413 econfig.reg_write = sprd_efuse_write;414 econfig.priv = efuse;415 econfig.dev = &pdev->dev;416 nvmem = devm_nvmem_register(&pdev->dev, &econfig);417 if (IS_ERR(nvmem)) {418 dev_err(&pdev->dev, "failed to register nvmem\n");419 return PTR_ERR(nvmem);420 }421 422 return 0;423}424 425static const struct of_device_id sprd_efuse_of_match[] = {426 { .compatible = "sprd,ums312-efuse", .data = &ums312_data },427 { }428};429MODULE_DEVICE_TABLE(of, sprd_efuse_of_match);430 431static struct platform_driver sprd_efuse_driver = {432 .probe = sprd_efuse_probe,433 .driver = {434 .name = "sprd-efuse",435 .of_match_table = sprd_efuse_of_match,436 },437};438 439module_platform_driver(sprd_efuse_driver);440 441MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>");442MODULE_DESCRIPTION("Spreadtrum AP efuse driver");443MODULE_LICENSE("GPL v2");444