Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * JZ4780 EFUSE Memory Support driver
0004  *
0005  * Copyright (c) 2017 PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
0006  * Copyright (c) 2020 H. Nikolaus Schaller <hns@goldelico.com>
0007  */
0008 
0009 /*
0010  * Currently supports JZ4780 efuse which has 8K programmable bit.
0011  * Efuse is separated into seven segments as below:
0012  *
0013  * -----------------------------------------------------------------------
0014  * | 64 bit | 128 bit | 128 bit | 3520 bit | 8 bit | 2296 bit | 2048 bit |
0015  * -----------------------------------------------------------------------
0016  *
0017  * The rom itself is accessed using a 9 bit address line and an 8 word wide bus
0018  * which reads/writes based on strobes. The strobe is configured in the config
0019  * register and is based on number of cycles of the bus clock.
0020  *
0021  * Driver supports read only as the writes are done in the Factory.
0022  */
0023 
0024 #include <linux/bitops.h>
0025 #include <linux/clk.h>
0026 #include <linux/module.h>
0027 #include <linux/nvmem-provider.h>
0028 #include <linux/of.h>
0029 #include <linux/platform_device.h>
0030 #include <linux/regmap.h>
0031 #include <linux/timer.h>
0032 
0033 #define JZ_EFUCTRL      (0x0)   /* Control Register */
0034 #define JZ_EFUCFG       (0x4)   /* Configure Register*/
0035 #define JZ_EFUSTATE     (0x8)   /* Status Register */
0036 #define JZ_EFUDATA(n)       (0xC + (n) * 4)
0037 
0038 /* We read 32 byte chunks to avoid complexity in the driver. */
0039 #define JZ_EFU_READ_SIZE 32
0040 
0041 #define EFUCTRL_ADDR_MASK   0x3FF
0042 #define EFUCTRL_ADDR_SHIFT  21
0043 #define EFUCTRL_LEN_MASK    0x1F
0044 #define EFUCTRL_LEN_SHIFT   16
0045 #define EFUCTRL_PG_EN       BIT(15)
0046 #define EFUCTRL_WR_EN       BIT(1)
0047 #define EFUCTRL_RD_EN       BIT(0)
0048 
0049 #define EFUCFG_INT_EN       BIT(31)
0050 #define EFUCFG_RD_ADJ_MASK  0xF
0051 #define EFUCFG_RD_ADJ_SHIFT 20
0052 #define EFUCFG_RD_STR_MASK  0xF
0053 #define EFUCFG_RD_STR_SHIFT 16
0054 #define EFUCFG_WR_ADJ_MASK  0xF
0055 #define EFUCFG_WR_ADJ_SHIFT 12
0056 #define EFUCFG_WR_STR_MASK  0xFFF
0057 #define EFUCFG_WR_STR_SHIFT 0
0058 
0059 #define EFUSTATE_WR_DONE    BIT(1)
0060 #define EFUSTATE_RD_DONE    BIT(0)
0061 
0062 struct jz4780_efuse {
0063     struct device *dev;
0064     struct regmap *map;
0065     struct clk *clk;
0066 };
0067 
0068 /* main entry point */
0069 static int jz4780_efuse_read(void *context, unsigned int offset,
0070                  void *val, size_t bytes)
0071 {
0072     struct jz4780_efuse *efuse = context;
0073 
0074     while (bytes > 0) {
0075         size_t start = offset & ~(JZ_EFU_READ_SIZE - 1);
0076         size_t chunk = min(bytes, (start + JZ_EFU_READ_SIZE)
0077                     - offset);
0078         char buf[JZ_EFU_READ_SIZE];
0079         unsigned int tmp;
0080         u32 ctrl;
0081         int ret;
0082 
0083         ctrl = (start << EFUCTRL_ADDR_SHIFT)
0084             | ((JZ_EFU_READ_SIZE - 1) << EFUCTRL_LEN_SHIFT)
0085             | EFUCTRL_RD_EN;
0086 
0087         regmap_update_bits(efuse->map, JZ_EFUCTRL,
0088                    (EFUCTRL_ADDR_MASK << EFUCTRL_ADDR_SHIFT) |
0089                    (EFUCTRL_LEN_MASK << EFUCTRL_LEN_SHIFT) |
0090                    EFUCTRL_PG_EN | EFUCTRL_WR_EN |
0091                    EFUCTRL_RD_EN,
0092                    ctrl);
0093 
0094         ret = regmap_read_poll_timeout(efuse->map, JZ_EFUSTATE,
0095                            tmp, tmp & EFUSTATE_RD_DONE,
0096                            1 * MSEC_PER_SEC,
0097                            50 * MSEC_PER_SEC);
0098         if (ret < 0) {
0099             dev_err(efuse->dev, "Time out while reading efuse data");
0100             return ret;
0101         }
0102 
0103         ret = regmap_bulk_read(efuse->map, JZ_EFUDATA(0),
0104                        buf, JZ_EFU_READ_SIZE / sizeof(u32));
0105         if (ret < 0)
0106             return ret;
0107 
0108         memcpy(val, &buf[offset - start], chunk);
0109 
0110         val += chunk;
0111         offset += chunk;
0112         bytes -= chunk;
0113     }
0114 
0115     return 0;
0116 }
0117 
0118 static struct nvmem_config jz4780_efuse_nvmem_config = {
0119     .name = "jz4780-efuse",
0120     .size = 1024,
0121     .word_size = 1,
0122     .stride = 1,
0123     .owner = THIS_MODULE,
0124     .reg_read = jz4780_efuse_read,
0125 };
0126 
0127 static const struct regmap_config jz4780_efuse_regmap_config = {
0128     .reg_bits = 32,
0129     .val_bits = 32,
0130     .reg_stride = 4,
0131     .max_register = JZ_EFUDATA(7),
0132 };
0133 
0134 static void clk_disable_unprepare_helper(void *clock)
0135 {
0136     clk_disable_unprepare(clock);
0137 }
0138 
0139 static int jz4780_efuse_probe(struct platform_device *pdev)
0140 {
0141     struct nvmem_device *nvmem;
0142     struct jz4780_efuse *efuse;
0143     struct nvmem_config cfg;
0144     unsigned long clk_rate;
0145     unsigned long rd_adj;
0146     unsigned long rd_strobe;
0147     struct device *dev = &pdev->dev;
0148     void __iomem *regs;
0149     int ret;
0150 
0151     efuse = devm_kzalloc(dev, sizeof(*efuse), GFP_KERNEL);
0152     if (!efuse)
0153         return -ENOMEM;
0154 
0155     regs = devm_platform_ioremap_resource(pdev, 0);
0156     if (IS_ERR(regs))
0157         return PTR_ERR(regs);
0158 
0159     efuse->map = devm_regmap_init_mmio(dev, regs,
0160                        &jz4780_efuse_regmap_config);
0161     if (IS_ERR(efuse->map))
0162         return PTR_ERR(efuse->map);
0163 
0164     efuse->clk = devm_clk_get(&pdev->dev, NULL);
0165     if (IS_ERR(efuse->clk))
0166         return PTR_ERR(efuse->clk);
0167 
0168     ret = clk_prepare_enable(efuse->clk);
0169     if (ret < 0)
0170         return ret;
0171 
0172     ret = devm_add_action_or_reset(&pdev->dev,
0173                        clk_disable_unprepare_helper,
0174                        efuse->clk);
0175     if (ret < 0)
0176         return ret;
0177 
0178     clk_rate = clk_get_rate(efuse->clk);
0179 
0180     efuse->dev = dev;
0181 
0182     /*
0183      * rd_adj and rd_strobe are 4 bit values
0184      * conditions:
0185      *   bus clk_period * (rd_adj + 1) > 6.5ns
0186      *   bus clk_period * (rd_adj + 5 + rd_strobe) > 35ns
0187      *   i.e. rd_adj >= 6.5ns / clk_period
0188      *   i.e. rd_strobe >= 35 ns / clk_period - 5 - rd_adj + 1
0189      * constants:
0190      *   1 / 6.5ns == 153846154 Hz
0191      *   1 / 35ns == 28571429 Hz
0192      */
0193 
0194     rd_adj = clk_rate / 153846154;
0195     rd_strobe = clk_rate / 28571429 - 5 - rd_adj + 1;
0196 
0197     if (rd_adj > EFUCFG_RD_ADJ_MASK ||
0198         rd_strobe > EFUCFG_RD_STR_MASK) {
0199         dev_err(&pdev->dev, "Cannot set clock configuration\n");
0200         return -EINVAL;
0201     }
0202 
0203     regmap_update_bits(efuse->map, JZ_EFUCFG,
0204                (EFUCFG_RD_ADJ_MASK << EFUCFG_RD_ADJ_SHIFT) |
0205                (EFUCFG_RD_STR_MASK << EFUCFG_RD_STR_SHIFT),
0206                (rd_adj << EFUCFG_RD_ADJ_SHIFT) |
0207                (rd_strobe << EFUCFG_RD_STR_SHIFT));
0208 
0209     cfg = jz4780_efuse_nvmem_config;
0210     cfg.dev = &pdev->dev;
0211     cfg.priv = efuse;
0212 
0213     nvmem = devm_nvmem_register(dev, &cfg);
0214 
0215     return PTR_ERR_OR_ZERO(nvmem);
0216 }
0217 
0218 static const struct of_device_id jz4780_efuse_match[] = {
0219     { .compatible = "ingenic,jz4780-efuse" },
0220     { /* sentinel */ },
0221 };
0222 MODULE_DEVICE_TABLE(of, jz4780_efuse_match);
0223 
0224 static struct platform_driver jz4780_efuse_driver = {
0225     .probe  = jz4780_efuse_probe,
0226     .driver = {
0227         .name = "jz4780-efuse",
0228         .of_match_table = jz4780_efuse_match,
0229     },
0230 };
0231 module_platform_driver(jz4780_efuse_driver);
0232 
0233 MODULE_AUTHOR("PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>");
0234 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
0235 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
0236 MODULE_DESCRIPTION("Ingenic JZ4780 efuse driver");
0237 MODULE_LICENSE("GPL v2");