0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
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)
0034 #define JZ_EFUCFG (0x4)
0035 #define JZ_EFUSTATE (0x8)
0036 #define JZ_EFUDATA(n) (0xC + (n) * 4)
0037
0038
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
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
0184
0185
0186
0187
0188
0189
0190
0191
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 { },
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");