nvmem: rockchip-efuse: add optional property to get efuse size
[firefly-linux-kernel-4.4.55.git] / drivers / nvmem / rockchip-efuse.c
1 /*
2  * Rockchip eFuse Driver
3  *
4  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
5  * Author: Caesar Wang <wxt@rock-chips.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  */
16
17 #include <linux/clk.h>
18 #include <linux/delay.h>
19 #include <linux/device.h>
20 #include <linux/io.h>
21 #include <linux/module.h>
22 #include <linux/nvmem-provider.h>
23 #include <linux/slab.h>
24 #include <linux/of.h>
25 #include <linux/of_platform.h>
26 #include <linux/platform_device.h>
27 #include <linux/rockchip/rockchip_sip.h>
28
29 #define RK3288_A_SHIFT          6
30 #define RK3288_A_MASK           0x3ff
31 #define RK3288_PGENB            BIT(3)
32 #define RK3288_LOAD             BIT(2)
33 #define RK3288_STROBE           BIT(1)
34 #define RK3288_CSB              BIT(0)
35
36 #define RK3366_A_SHIFT          6
37 #define RK3366_A_MASK           0x3ff
38 #define RK3366_RDEN             BIT(2)
39 #define RK3366_AEN              BIT(1)
40
41 #define RK3399_A_SHIFT          16
42 #define RK3399_A_MASK           0x3ff
43 #define RK3399_NBYTES           4
44 #define RK3399_STROBSFTSEL      BIT(9)
45 #define RK3399_RSB              BIT(7)
46 #define RK3399_PD               BIT(5)
47 #define RK3399_PGENB            BIT(3)
48 #define RK3399_LOAD             BIT(2)
49 #define RK3399_STROBE           BIT(1)
50 #define RK3399_CSB              BIT(0)
51
52 #define REG_EFUSE_CTRL          0x0000
53 #define REG_EFUSE_DOUT          0x0004
54
55 struct rockchip_efuse_chip {
56         struct device *dev;
57         void __iomem *base;
58         struct clk *clk;
59         phys_addr_t phys;
60 };
61
62 static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
63                                       void *val, size_t bytes)
64 {
65         struct rockchip_efuse_chip *efuse = context;
66         u8 *buf = val;
67         int ret;
68
69         ret = clk_prepare_enable(efuse->clk);
70         if (ret < 0) {
71                 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
72                 return ret;
73         }
74
75         writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL);
76         udelay(1);
77         while (bytes--) {
78                 writel(readl(efuse->base + REG_EFUSE_CTRL) &
79                              (~(RK3288_A_MASK << RK3288_A_SHIFT)),
80                              efuse->base + REG_EFUSE_CTRL);
81                 writel(readl(efuse->base + REG_EFUSE_CTRL) |
82                              ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT),
83                              efuse->base + REG_EFUSE_CTRL);
84                 udelay(1);
85                 writel(readl(efuse->base + REG_EFUSE_CTRL) |
86                              RK3288_STROBE, efuse->base + REG_EFUSE_CTRL);
87                 udelay(1);
88                 *buf++ = readb(efuse->base + REG_EFUSE_DOUT);
89                 writel(readl(efuse->base + REG_EFUSE_CTRL) &
90                        (~RK3288_STROBE), efuse->base + REG_EFUSE_CTRL);
91                 udelay(1);
92         }
93
94         /* Switch to standby mode */
95         writel(RK3288_PGENB | RK3288_CSB, efuse->base + REG_EFUSE_CTRL);
96
97         clk_disable_unprepare(efuse->clk);
98
99         return 0;
100 }
101
102 static int rockchip_rk3288_efuse_secure_read(void *context,
103                                              unsigned int offset,
104                                              void *val, size_t bytes)
105 {
106         struct rockchip_efuse_chip *efuse = context;
107         u8 *buf = val;
108         u32 wr_val;
109         int ret;
110
111         ret = clk_prepare_enable(efuse->clk);
112         if (ret < 0) {
113                 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
114                 return ret;
115         }
116
117         sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
118                                  RK3288_LOAD | RK3288_PGENB);
119         udelay(1);
120         while (bytes--) {
121                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
122                          (~(RK3288_A_MASK << RK3288_A_SHIFT));
123                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
124                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
125                          ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT);
126                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
127                 udelay(1);
128                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
129                          RK3288_STROBE;
130                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
131                 udelay(1);
132                 *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
133                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
134                          (~RK3288_STROBE);
135                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
136                 udelay(1);
137         }
138
139         /* Switch to standby mode */
140         sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
141                                  RK3288_PGENB | RK3288_CSB);
142
143         clk_disable_unprepare(efuse->clk);
144
145         return 0;
146 }
147
148 static int rockchip_rk3366_efuse_read(void *context, unsigned int offset,
149                                       void *val, size_t bytes)
150 {
151         struct rockchip_efuse_chip *efuse = context;
152         u8 *buf = val;
153         int ret;
154
155         ret = clk_prepare_enable(efuse->clk);
156         if (ret < 0) {
157                 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
158                 return ret;
159         }
160
161         writel(RK3366_RDEN, efuse->base + REG_EFUSE_CTRL);
162         udelay(1);
163         while (bytes--) {
164                 writel(readl(efuse->base + REG_EFUSE_CTRL) &
165                        (~(RK3366_A_MASK << RK3366_A_SHIFT)),
166                        efuse->base + REG_EFUSE_CTRL);
167                 writel(readl(efuse->base + REG_EFUSE_CTRL) |
168                        ((offset++ & RK3366_A_MASK) << RK3366_A_SHIFT),
169                        efuse->base + REG_EFUSE_CTRL);
170                 udelay(1);
171                 writel(readl(efuse->base + REG_EFUSE_CTRL) |
172                        RK3366_AEN, efuse->base + REG_EFUSE_CTRL);
173                 udelay(1);
174                 *buf++ = readb(efuse->base + REG_EFUSE_DOUT);
175                 writel(readl(efuse->base + REG_EFUSE_CTRL) &
176                        (~RK3366_AEN), efuse->base + REG_EFUSE_CTRL);
177                 udelay(1);
178         }
179
180         writel(readl(efuse->base + REG_EFUSE_CTRL) &
181                (~RK3366_RDEN), efuse->base + REG_EFUSE_CTRL);
182
183         clk_disable_unprepare(efuse->clk);
184
185         return 0;
186 }
187
188 static int rockchip_rk3368_efuse_read(void *context, unsigned int offset,
189                                       void *val, size_t bytes)
190 {
191         struct rockchip_efuse_chip *efuse = context;
192         u8 *buf = val;
193         u32 wr_val;
194         int ret;
195
196         ret = clk_prepare_enable(efuse->clk);
197         if (ret < 0) {
198                 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
199                 return ret;
200         }
201
202         sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
203                                  RK3288_LOAD | RK3288_PGENB);
204         udelay(1);
205         while (bytes--) {
206                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
207                          (~(RK3288_A_MASK << RK3288_A_SHIFT));
208                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
209                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
210                          ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT);
211                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
212                 udelay(1);
213                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) |
214                          RK3288_STROBE;
215                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
216                 udelay(1);
217                 *buf++ = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_DOUT);
218                 wr_val = sip_smc_secure_reg_read(efuse->phys + REG_EFUSE_CTRL) &
219                          (~RK3288_STROBE);
220                 sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL, wr_val);
221                 udelay(1);
222         }
223
224         /* Switch to standby mode */
225         sip_smc_secure_reg_write(efuse->phys + REG_EFUSE_CTRL,
226                                  RK3288_PGENB | RK3288_CSB);
227
228         clk_disable_unprepare(efuse->clk);
229
230         return 0;
231 }
232
233 static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
234                                       void *val, size_t bytes)
235 {
236         struct rockchip_efuse_chip *efuse = context;
237         unsigned int addr_start, addr_end, addr_offset, addr_len;
238         u32 out_value;
239         u8 *buf;
240         int ret, i = 0;
241
242         ret = clk_prepare_enable(efuse->clk);
243         if (ret < 0) {
244                 dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
245                 return ret;
246         }
247
248         addr_start = rounddown(offset, RK3399_NBYTES) / RK3399_NBYTES;
249         addr_end = roundup(offset + bytes, RK3399_NBYTES) / RK3399_NBYTES;
250         addr_offset = offset % RK3399_NBYTES;
251         addr_len = addr_end - addr_start;
252
253         buf = kzalloc(sizeof(*buf) * addr_len * RK3399_NBYTES, GFP_KERNEL);
254         if (!buf) {
255                 clk_disable_unprepare(efuse->clk);
256                 return -ENOMEM;
257         }
258
259         writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
260                efuse->base + REG_EFUSE_CTRL);
261         udelay(1);
262         while (addr_len--) {
263                 writel(readl(efuse->base + REG_EFUSE_CTRL) | RK3399_STROBE |
264                        ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
265                        efuse->base + REG_EFUSE_CTRL);
266                 udelay(1);
267                 out_value = readl(efuse->base + REG_EFUSE_DOUT);
268                 writel(readl(efuse->base + REG_EFUSE_CTRL) & (~RK3399_STROBE),
269                        efuse->base + REG_EFUSE_CTRL);
270                 udelay(1);
271
272                 memcpy(&buf[i], &out_value, RK3399_NBYTES);
273                 i += RK3399_NBYTES;
274         }
275
276         /* Switch to standby mode */
277         writel(RK3399_PD | RK3399_CSB, efuse->base + REG_EFUSE_CTRL);
278
279         memcpy(val, buf + addr_offset, bytes);
280
281         kfree(buf);
282
283         clk_disable_unprepare(efuse->clk);
284
285         return 0;
286 }
287
288 static struct nvmem_config econfig = {
289         .name = "rockchip-efuse",
290         .owner = THIS_MODULE,
291         .stride = 1,
292         .word_size = 1,
293         .read_only = true,
294 };
295
296 static const struct of_device_id rockchip_efuse_match[] = {
297         /* deprecated but kept around for dts binding compatibility */
298         {
299                 .compatible = "rockchip,rockchip-efuse",
300                 .data = (void *)&rockchip_rk3288_efuse_read,
301         },
302         {
303                 .compatible = "rockchip,rk3066a-efuse",
304                 .data = (void *)&rockchip_rk3288_efuse_read,
305         },
306         {
307                 .compatible = "rockchip,rk3188-efuse",
308                 .data = (void *)&rockchip_rk3288_efuse_read,
309         },
310         {
311                 .compatible = "rockchip,rk3288-efuse",
312                 .data = (void *)&rockchip_rk3288_efuse_read,
313         },
314         {
315                 .compatible = "rockchip,rk3288-secure-efuse",
316                 .data = (void *)&rockchip_rk3288_efuse_secure_read,
317         },
318         {
319                 .compatible = "rockchip,rk3366-efuse",
320                 .data = (void *)&rockchip_rk3366_efuse_read,
321         },
322         {
323                 .compatible = "rockchip,rk3368-efuse",
324                 .data = (void *)&rockchip_rk3368_efuse_read,
325         },
326         {
327                 .compatible = "rockchip,rk3399-efuse",
328                 .data = (void *)&rockchip_rk3399_efuse_read,
329         },
330         { /* sentinel */},
331 };
332 MODULE_DEVICE_TABLE(of, rockchip_efuse_match);
333
334 static int __init rockchip_efuse_probe(struct platform_device *pdev)
335 {
336         struct resource *res;
337         struct nvmem_device *nvmem;
338         struct rockchip_efuse_chip *efuse;
339         const struct of_device_id *match;
340         struct device *dev = &pdev->dev;
341
342         match = of_match_device(dev->driver->of_match_table, dev);
343         if (!match || !match->data) {
344                 dev_err(dev, "failed to get match data\n");
345                 return -EINVAL;
346         }
347
348         efuse = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_efuse_chip),
349                              GFP_KERNEL);
350         if (!efuse)
351                 return -ENOMEM;
352
353         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
354         efuse->phys = res->start;
355         efuse->base = devm_ioremap_resource(&pdev->dev, res);
356         if (IS_ERR(efuse->base))
357                 return PTR_ERR(efuse->base);
358
359         efuse->clk = devm_clk_get(&pdev->dev, "pclk_efuse");
360         if (IS_ERR(efuse->clk))
361                 return PTR_ERR(efuse->clk);
362
363         efuse->dev = &pdev->dev;
364         if (of_property_read_u32_index(dev->of_node,
365                                        "rockchip,efuse-size",
366                                        0,
367                                        &econfig.size))
368                 econfig.size = resource_size(res);
369
370         econfig.reg_read = match->data;
371         econfig.priv = efuse;
372         econfig.dev = efuse->dev;
373         nvmem = nvmem_register(&econfig);
374         if (IS_ERR(nvmem))
375                 return PTR_ERR(nvmem);
376
377         platform_set_drvdata(pdev, nvmem);
378
379         return 0;
380 }
381
382 static int rockchip_efuse_remove(struct platform_device *pdev)
383 {
384         struct nvmem_device *nvmem = platform_get_drvdata(pdev);
385
386         return nvmem_unregister(nvmem);
387 }
388
389 static struct platform_driver rockchip_efuse_driver = {
390         .remove = rockchip_efuse_remove,
391         .driver = {
392                 .name = "rockchip-efuse",
393                 .of_match_table = rockchip_efuse_match,
394         },
395 };
396
397 static int __init rockchip_efuse_module_init(void)
398 {
399         return platform_driver_probe(&rockchip_efuse_driver,
400                                      rockchip_efuse_probe);
401 }
402
403 subsys_initcall(rockchip_efuse_module_init);
404
405 MODULE_DESCRIPTION("rockchip_efuse driver");
406 MODULE_LICENSE("GPL v2");