cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sprd-efuse.c (10924B)


      1// SPDX-License-Identifier: GPL-2.0
      2// 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_device.h>
     11#include <linux/platform_device.h>
     12
     13#define SPRD_EFUSE_ENABLE		0x20
     14#define SPRD_EFUSE_ERR_FLAG		0x24
     15#define SPRD_EFUSE_ERR_CLR		0x28
     16#define SPRD_EFUSE_MAGIC_NUM		0x2c
     17#define SPRD_EFUSE_FW_CFG		0x50
     18#define SPRD_EFUSE_PW_SWT		0x54
     19#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		0x8810
     34
     35/* Block width (bytes) definitions */
     36#define SPRD_EFUSE_BLOCK_WIDTH		4
     37
     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 normal
     41 * block offset index and normal block numbers.
     42 */
     43#define SPRD_EFUSE_NORMAL_BLOCK_NUMS	24
     44#define SPRD_EFUSE_NORMAL_BLOCK_OFFSET	72
     45
     46/* Timeout (ms) for the trylock of hardware spinlocks */
     47#define SPRD_EFUSE_HWLOCK_TIMEOUT	5000
     48
     49/*
     50 * Since different Spreadtrum SoC chip can have different normal block numbers
     51 * and offset. And some SoC can support block double feature, which means
     52 * when reading or writing data to efuse memory, the controller can save double
     53 * 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 unique
     80 * efuse controller, so we need one hardware spinlock to synchronize between
     81 * 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	else
    113		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	else
    123		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	else
    138		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	else
    153		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	else
    165		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	else
    177		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	else
    189		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 to
    202	 * allow programming, and block other programming until we clear the
    203	 * 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 data
    210	 * 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 is
    218	 * 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 will
    261	 * 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 some
    279	 * 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 the
    341	 * whole block will be programmed. For this case, we should not allow
    342	 * this block to be programmed again by locking this block.
    343	 *
    344	 * If the block was programmed partially, we should allow this block to
    345	 * be programmed again.
    346	 */
    347	if (bytes < SPRD_EFUSE_BLOCK_WIDTH)
    348		lock = false;
    349	else
    350		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.reg_read = sprd_efuse_read;
    412	econfig.reg_write = sprd_efuse_write;
    413	econfig.priv = efuse;
    414	econfig.dev = &pdev->dev;
    415	nvmem = devm_nvmem_register(&pdev->dev, &econfig);
    416	if (IS_ERR(nvmem)) {
    417		dev_err(&pdev->dev, "failed to register nvmem\n");
    418		return PTR_ERR(nvmem);
    419	}
    420
    421	return 0;
    422}
    423
    424static const struct of_device_id sprd_efuse_of_match[] = {
    425	{ .compatible = "sprd,ums312-efuse", .data = &ums312_data },
    426	{ }
    427};
    428
    429static struct platform_driver sprd_efuse_driver = {
    430	.probe = sprd_efuse_probe,
    431	.driver = {
    432		.name = "sprd-efuse",
    433		.of_match_table = sprd_efuse_of_match,
    434	},
    435};
    436
    437module_platform_driver(sprd_efuse_driver);
    438
    439MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>");
    440MODULE_DESCRIPTION("Spreadtrum AP efuse driver");
    441MODULE_LICENSE("GPL v2");