Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2018 Spreadtrum Communications Inc.
0003 
0004 #include <linux/hwspinlock.h>
0005 #include <linux/module.h>
0006 #include <linux/of.h>
0007 #include <linux/of_device.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/regmap.h>
0010 #include <linux/nvmem-provider.h>
0011 
0012 /* PMIC global registers definition */
0013 #define SC27XX_MODULE_EN        0xc08
0014 #define SC2730_MODULE_EN        0x1808
0015 #define SC27XX_EFUSE_EN         BIT(6)
0016 
0017 /* Efuse controller registers definition */
0018 #define SC27XX_EFUSE_GLB_CTRL       0x0
0019 #define SC27XX_EFUSE_DATA_RD        0x4
0020 #define SC27XX_EFUSE_DATA_WR        0x8
0021 #define SC27XX_EFUSE_BLOCK_INDEX    0xc
0022 #define SC27XX_EFUSE_MODE_CTRL      0x10
0023 #define SC27XX_EFUSE_STATUS     0x14
0024 #define SC27XX_EFUSE_WR_TIMING_CTRL 0x20
0025 #define SC27XX_EFUSE_RD_TIMING_CTRL 0x24
0026 #define SC27XX_EFUSE_EFUSE_DEB_CTRL 0x28
0027 
0028 /* Mask definition for SC27XX_EFUSE_BLOCK_INDEX register */
0029 #define SC27XX_EFUSE_BLOCK_MASK     GENMASK(4, 0)
0030 
0031 /* Bits definitions for SC27XX_EFUSE_MODE_CTRL register */
0032 #define SC27XX_EFUSE_PG_START       BIT(0)
0033 #define SC27XX_EFUSE_RD_START       BIT(1)
0034 #define SC27XX_EFUSE_CLR_RDDONE     BIT(2)
0035 
0036 /* Bits definitions for SC27XX_EFUSE_STATUS register */
0037 #define SC27XX_EFUSE_PGM_BUSY       BIT(0)
0038 #define SC27XX_EFUSE_READ_BUSY      BIT(1)
0039 #define SC27XX_EFUSE_STANDBY        BIT(2)
0040 #define SC27XX_EFUSE_GLOBAL_PROT    BIT(3)
0041 #define SC27XX_EFUSE_RD_DONE        BIT(4)
0042 
0043 /* Block number and block width (bytes) definitions */
0044 #define SC27XX_EFUSE_BLOCK_MAX      32
0045 #define SC27XX_EFUSE_BLOCK_WIDTH    2
0046 
0047 /* Timeout (ms) for the trylock of hardware spinlocks */
0048 #define SC27XX_EFUSE_HWLOCK_TIMEOUT 5000
0049 
0050 /* Timeout (us) of polling the status */
0051 #define SC27XX_EFUSE_POLL_TIMEOUT   3000000
0052 #define SC27XX_EFUSE_POLL_DELAY_US  10000
0053 
0054 /*
0055  * Since different PMICs of SC27xx series can have different
0056  * address , we should save address in the device data structure.
0057  */
0058 struct sc27xx_efuse_variant_data {
0059     u32 module_en;
0060 };
0061 
0062 struct sc27xx_efuse {
0063     struct device *dev;
0064     struct regmap *regmap;
0065     struct hwspinlock *hwlock;
0066     struct mutex mutex;
0067     u32 base;
0068     const struct sc27xx_efuse_variant_data *var_data;
0069 };
0070 
0071 static const struct sc27xx_efuse_variant_data sc2731_edata = {
0072     .module_en = SC27XX_MODULE_EN,
0073 };
0074 
0075 static const struct sc27xx_efuse_variant_data sc2730_edata = {
0076     .module_en = SC2730_MODULE_EN,
0077 };
0078 
0079 /*
0080  * On Spreadtrum platform, we have multi-subsystems will access the unique
0081  * efuse controller, so we need one hardware spinlock to synchronize between
0082  * the multiple subsystems.
0083  */
0084 static int sc27xx_efuse_lock(struct sc27xx_efuse *efuse)
0085 {
0086     int ret;
0087 
0088     mutex_lock(&efuse->mutex);
0089 
0090     ret = hwspin_lock_timeout_raw(efuse->hwlock,
0091                       SC27XX_EFUSE_HWLOCK_TIMEOUT);
0092     if (ret) {
0093         dev_err(efuse->dev, "timeout to get the hwspinlock\n");
0094         mutex_unlock(&efuse->mutex);
0095         return ret;
0096     }
0097 
0098     return 0;
0099 }
0100 
0101 static void sc27xx_efuse_unlock(struct sc27xx_efuse *efuse)
0102 {
0103     hwspin_unlock_raw(efuse->hwlock);
0104     mutex_unlock(&efuse->mutex);
0105 }
0106 
0107 static int sc27xx_efuse_poll_status(struct sc27xx_efuse *efuse, u32 bits)
0108 {
0109     int ret;
0110     u32 val;
0111 
0112     ret = regmap_read_poll_timeout(efuse->regmap,
0113                        efuse->base + SC27XX_EFUSE_STATUS,
0114                        val, (val & bits),
0115                        SC27XX_EFUSE_POLL_DELAY_US,
0116                        SC27XX_EFUSE_POLL_TIMEOUT);
0117     if (ret) {
0118         dev_err(efuse->dev, "timeout to update the efuse status\n");
0119         return ret;
0120     }
0121 
0122     return 0;
0123 }
0124 
0125 static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
0126 {
0127     struct sc27xx_efuse *efuse = context;
0128     u32 buf, blk_index = offset / SC27XX_EFUSE_BLOCK_WIDTH;
0129     u32 blk_offset = (offset % SC27XX_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE;
0130     int ret;
0131 
0132     if (blk_index > SC27XX_EFUSE_BLOCK_MAX ||
0133         bytes > SC27XX_EFUSE_BLOCK_WIDTH)
0134         return -EINVAL;
0135 
0136     ret = sc27xx_efuse_lock(efuse);
0137     if (ret)
0138         return ret;
0139 
0140     /* Enable the efuse controller. */
0141     ret = regmap_update_bits(efuse->regmap, efuse->var_data->module_en,
0142                  SC27XX_EFUSE_EN, SC27XX_EFUSE_EN);
0143     if (ret)
0144         goto unlock_efuse;
0145 
0146     /*
0147      * Before reading, we should ensure the efuse controller is in
0148      * standby state.
0149      */
0150     ret = sc27xx_efuse_poll_status(efuse, SC27XX_EFUSE_STANDBY);
0151     if (ret)
0152         goto disable_efuse;
0153 
0154     /* Set the block address to be read. */
0155     ret = regmap_write(efuse->regmap,
0156                efuse->base + SC27XX_EFUSE_BLOCK_INDEX,
0157                blk_index & SC27XX_EFUSE_BLOCK_MASK);
0158     if (ret)
0159         goto disable_efuse;
0160 
0161     /* Start reading process from efuse memory. */
0162     ret = regmap_update_bits(efuse->regmap,
0163                  efuse->base + SC27XX_EFUSE_MODE_CTRL,
0164                  SC27XX_EFUSE_RD_START,
0165                  SC27XX_EFUSE_RD_START);
0166     if (ret)
0167         goto disable_efuse;
0168 
0169     /*
0170      * Polling the read done status to make sure the reading process
0171      * is completed, that means the data can be read out now.
0172      */
0173     ret = sc27xx_efuse_poll_status(efuse, SC27XX_EFUSE_RD_DONE);
0174     if (ret)
0175         goto disable_efuse;
0176 
0177     /* Read data from efuse memory. */
0178     ret = regmap_read(efuse->regmap, efuse->base + SC27XX_EFUSE_DATA_RD,
0179               &buf);
0180     if (ret)
0181         goto disable_efuse;
0182 
0183     /* Clear the read done flag. */
0184     ret = regmap_update_bits(efuse->regmap,
0185                  efuse->base + SC27XX_EFUSE_MODE_CTRL,
0186                  SC27XX_EFUSE_CLR_RDDONE,
0187                  SC27XX_EFUSE_CLR_RDDONE);
0188 
0189 disable_efuse:
0190     /* Disable the efuse controller after reading. */
0191     regmap_update_bits(efuse->regmap, efuse->var_data->module_en, SC27XX_EFUSE_EN, 0);
0192 unlock_efuse:
0193     sc27xx_efuse_unlock(efuse);
0194 
0195     if (!ret) {
0196         buf >>= blk_offset;
0197         memcpy(val, &buf, bytes);
0198     }
0199 
0200     return ret;
0201 }
0202 
0203 static int sc27xx_efuse_probe(struct platform_device *pdev)
0204 {
0205     struct device_node *np = pdev->dev.of_node;
0206     struct nvmem_config econfig = { };
0207     struct nvmem_device *nvmem;
0208     struct sc27xx_efuse *efuse;
0209     int ret;
0210 
0211     efuse = devm_kzalloc(&pdev->dev, sizeof(*efuse), GFP_KERNEL);
0212     if (!efuse)
0213         return -ENOMEM;
0214 
0215     efuse->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0216     if (!efuse->regmap) {
0217         dev_err(&pdev->dev, "failed to get efuse regmap\n");
0218         return -ENODEV;
0219     }
0220 
0221     ret = of_property_read_u32(np, "reg", &efuse->base);
0222     if (ret) {
0223         dev_err(&pdev->dev, "failed to get efuse base address\n");
0224         return ret;
0225     }
0226 
0227     ret = of_hwspin_lock_get_id(np, 0);
0228     if (ret < 0) {
0229         dev_err(&pdev->dev, "failed to get hwspinlock id\n");
0230         return ret;
0231     }
0232 
0233     efuse->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret);
0234     if (!efuse->hwlock) {
0235         dev_err(&pdev->dev, "failed to request hwspinlock\n");
0236         return -ENXIO;
0237     }
0238 
0239     mutex_init(&efuse->mutex);
0240     efuse->dev = &pdev->dev;
0241     efuse->var_data = of_device_get_match_data(&pdev->dev);
0242 
0243     econfig.stride = 1;
0244     econfig.word_size = 1;
0245     econfig.read_only = true;
0246     econfig.name = "sc27xx-efuse";
0247     econfig.size = SC27XX_EFUSE_BLOCK_MAX * SC27XX_EFUSE_BLOCK_WIDTH;
0248     econfig.reg_read = sc27xx_efuse_read;
0249     econfig.priv = efuse;
0250     econfig.dev = &pdev->dev;
0251     nvmem = devm_nvmem_register(&pdev->dev, &econfig);
0252     if (IS_ERR(nvmem)) {
0253         dev_err(&pdev->dev, "failed to register nvmem config\n");
0254         return PTR_ERR(nvmem);
0255     }
0256 
0257     return 0;
0258 }
0259 
0260 static const struct of_device_id sc27xx_efuse_of_match[] = {
0261     { .compatible = "sprd,sc2731-efuse", .data = &sc2731_edata},
0262     { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
0263     { }
0264 };
0265 
0266 static struct platform_driver sc27xx_efuse_driver = {
0267     .probe = sc27xx_efuse_probe,
0268     .driver = {
0269         .name = "sc27xx-efuse",
0270         .of_match_table = sc27xx_efuse_of_match,
0271     },
0272 };
0273 
0274 module_platform_driver(sc27xx_efuse_driver);
0275 
0276 MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>");
0277 MODULE_DESCRIPTION("Spreadtrum SC27xx efuse driver");
0278 MODULE_LICENSE("GPL v2");