rockchip-otp.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Rockchip OTP Driver
  4. *
  5. * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
  6. * Author: Finley Xiao <finley.xiao@rock-chips.com>
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/delay.h>
  10. #include <linux/device.h>
  11. #include <linux/io.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/module.h>
  14. #include <linux/nvmem-provider.h>
  15. #include <linux/reset.h>
  16. #include <linux/slab.h>
  17. #include <linux/of.h>
  18. #include <linux/of_platform.h>
  19. #include <linux/platform_device.h>
  20. /* OTP Register Offsets */
  21. #define OTPC_SBPI_CTRL 0x0020
  22. #define OTPC_SBPI_CMD_VALID_PRE 0x0024
  23. #define OTPC_SBPI_CS_VALID_PRE 0x0028
  24. #define OTPC_SBPI_STATUS 0x002C
  25. #define OTPC_USER_CTRL 0x0100
  26. #define OTPC_USER_ADDR 0x0104
  27. #define OTPC_USER_ENABLE 0x0108
  28. #define OTPC_USER_Q 0x0124
  29. #define OTPC_INT_STATUS 0x0304
  30. #define OTPC_SBPI_CMD0_OFFSET 0x1000
  31. #define OTPC_SBPI_CMD1_OFFSET 0x1004
  32. /* OTP Register bits and masks */
  33. #define OTPC_USER_ADDR_MASK GENMASK(31, 16)
  34. #define OTPC_USE_USER BIT(0)
  35. #define OTPC_USE_USER_MASK GENMASK(16, 16)
  36. #define OTPC_USER_FSM_ENABLE BIT(0)
  37. #define OTPC_USER_FSM_ENABLE_MASK GENMASK(16, 16)
  38. #define OTPC_SBPI_DONE BIT(1)
  39. #define OTPC_USER_DONE BIT(2)
  40. #define SBPI_DAP_ADDR 0x02
  41. #define SBPI_DAP_ADDR_SHIFT 8
  42. #define SBPI_DAP_ADDR_MASK GENMASK(31, 24)
  43. #define SBPI_CMD_VALID_MASK GENMASK(31, 16)
  44. #define SBPI_DAP_CMD_WRF 0xC0
  45. #define SBPI_DAP_REG_ECC 0x3A
  46. #define SBPI_ECC_ENABLE 0x00
  47. #define SBPI_ECC_DISABLE 0x09
  48. #define SBPI_ENABLE BIT(0)
  49. #define SBPI_ENABLE_MASK GENMASK(16, 16)
  50. #define OTPC_TIMEOUT 10000
  51. /* RK3588 Register */
  52. #define RK3588_OTPC_AUTO_CTRL 0x04
  53. #define RK3588_OTPC_AUTO_EN 0x08
  54. #define RK3588_OTPC_INT_ST 0x84
  55. #define RK3588_OTPC_DOUT0 0x20
  56. #define RK3588_NO_SECURE_OFFSET 0x300
  57. #define RK3588_NBYTES 4
  58. #define RK3588_BURST_NUM 1
  59. #define RK3588_BURST_SHIFT 8
  60. #define RK3588_ADDR_SHIFT 16
  61. #define RK3588_AUTO_EN BIT(0)
  62. #define RK3588_RD_DONE BIT(1)
  63. struct rockchip_data {
  64. int size;
  65. const char * const *clks;
  66. int num_clks;
  67. nvmem_reg_read_t reg_read;
  68. };
  69. struct rockchip_otp {
  70. struct device *dev;
  71. void __iomem *base;
  72. struct clk_bulk_data *clks;
  73. struct reset_control *rst;
  74. const struct rockchip_data *data;
  75. };
  76. static int rockchip_otp_reset(struct rockchip_otp *otp)
  77. {
  78. int ret;
  79. ret = reset_control_assert(otp->rst);
  80. if (ret) {
  81. dev_err(otp->dev, "failed to assert otp phy %d\n", ret);
  82. return ret;
  83. }
  84. udelay(2);
  85. ret = reset_control_deassert(otp->rst);
  86. if (ret) {
  87. dev_err(otp->dev, "failed to deassert otp phy %d\n", ret);
  88. return ret;
  89. }
  90. return 0;
  91. }
  92. static int rockchip_otp_wait_status(struct rockchip_otp *otp,
  93. unsigned int reg, u32 flag)
  94. {
  95. u32 status = 0;
  96. int ret;
  97. ret = readl_poll_timeout_atomic(otp->base + reg, status,
  98. (status & flag), 1, OTPC_TIMEOUT);
  99. if (ret)
  100. return ret;
  101. /* clean int status */
  102. writel(flag, otp->base + reg);
  103. return 0;
  104. }
  105. static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable)
  106. {
  107. int ret = 0;
  108. writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
  109. otp->base + OTPC_SBPI_CTRL);
  110. writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
  111. writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
  112. otp->base + OTPC_SBPI_CMD0_OFFSET);
  113. if (enable)
  114. writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
  115. else
  116. writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
  117. writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
  118. ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
  119. if (ret < 0)
  120. dev_err(otp->dev, "timeout during ecc_enable\n");
  121. return ret;
  122. }
  123. static int px30_otp_read(void *context, unsigned int offset,
  124. void *val, size_t bytes)
  125. {
  126. struct rockchip_otp *otp = context;
  127. u8 *buf = val;
  128. int ret;
  129. ret = rockchip_otp_reset(otp);
  130. if (ret) {
  131. dev_err(otp->dev, "failed to reset otp phy\n");
  132. return ret;
  133. }
  134. ret = rockchip_otp_ecc_enable(otp, false);
  135. if (ret < 0) {
  136. dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
  137. return ret;
  138. }
  139. writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
  140. udelay(5);
  141. while (bytes--) {
  142. writel(offset++ | OTPC_USER_ADDR_MASK,
  143. otp->base + OTPC_USER_ADDR);
  144. writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
  145. otp->base + OTPC_USER_ENABLE);
  146. ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
  147. if (ret < 0) {
  148. dev_err(otp->dev, "timeout during read setup\n");
  149. goto read_end;
  150. }
  151. *buf++ = readb(otp->base + OTPC_USER_Q);
  152. }
  153. read_end:
  154. writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
  155. return ret;
  156. }
  157. static int rk3588_otp_read(void *context, unsigned int offset,
  158. void *val, size_t bytes)
  159. {
  160. struct rockchip_otp *otp = context;
  161. unsigned int addr_start, addr_end, addr_len;
  162. int ret, i = 0;
  163. u32 data;
  164. u8 *buf;
  165. addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
  166. addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
  167. addr_len = addr_end - addr_start;
  168. addr_start += RK3588_NO_SECURE_OFFSET;
  169. buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
  170. if (!buf)
  171. return -ENOMEM;
  172. while (addr_len--) {
  173. writel((addr_start << RK3588_ADDR_SHIFT) |
  174. (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
  175. otp->base + RK3588_OTPC_AUTO_CTRL);
  176. writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
  177. ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
  178. RK3588_RD_DONE);
  179. if (ret < 0) {
  180. dev_err(otp->dev, "timeout during read setup\n");
  181. goto read_end;
  182. }
  183. data = readl(otp->base + RK3588_OTPC_DOUT0);
  184. memcpy(&buf[i], &data, RK3588_NBYTES);
  185. i += RK3588_NBYTES;
  186. addr_start++;
  187. }
  188. memcpy(val, buf + offset % RK3588_NBYTES, bytes);
  189. read_end:
  190. kfree(buf);
  191. return ret;
  192. }
  193. static int rockchip_otp_read(void *context, unsigned int offset,
  194. void *val, size_t bytes)
  195. {
  196. struct rockchip_otp *otp = context;
  197. int ret;
  198. if (!otp->data || !otp->data->reg_read)
  199. return -EINVAL;
  200. ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
  201. if (ret < 0) {
  202. dev_err(otp->dev, "failed to prepare/enable clks\n");
  203. return ret;
  204. }
  205. ret = otp->data->reg_read(context, offset, val, bytes);
  206. clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
  207. return ret;
  208. }
  209. static struct nvmem_config otp_config = {
  210. .name = "rockchip-otp",
  211. .owner = THIS_MODULE,
  212. .add_legacy_fixed_of_cells = true,
  213. .type = NVMEM_TYPE_OTP,
  214. .read_only = true,
  215. .stride = 1,
  216. .word_size = 1,
  217. .reg_read = rockchip_otp_read,
  218. };
  219. static const char * const px30_otp_clocks[] = {
  220. "otp", "apb_pclk", "phy",
  221. };
  222. static const struct rockchip_data px30_data = {
  223. .size = 0x40,
  224. .clks = px30_otp_clocks,
  225. .num_clks = ARRAY_SIZE(px30_otp_clocks),
  226. .reg_read = px30_otp_read,
  227. };
  228. static const char * const rk3588_otp_clocks[] = {
  229. "otp", "apb_pclk", "phy", "arb",
  230. };
  231. static const struct rockchip_data rk3588_data = {
  232. .size = 0x400,
  233. .clks = rk3588_otp_clocks,
  234. .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
  235. .reg_read = rk3588_otp_read,
  236. };
  237. static const struct of_device_id rockchip_otp_match[] = {
  238. {
  239. .compatible = "rockchip,px30-otp",
  240. .data = &px30_data,
  241. },
  242. {
  243. .compatible = "rockchip,rk3308-otp",
  244. .data = &px30_data,
  245. },
  246. {
  247. .compatible = "rockchip,rk3588-otp",
  248. .data = &rk3588_data,
  249. },
  250. { /* sentinel */ },
  251. };
  252. MODULE_DEVICE_TABLE(of, rockchip_otp_match);
  253. static int rockchip_otp_probe(struct platform_device *pdev)
  254. {
  255. struct device *dev = &pdev->dev;
  256. struct rockchip_otp *otp;
  257. const struct rockchip_data *data;
  258. struct nvmem_device *nvmem;
  259. int ret, i;
  260. data = of_device_get_match_data(dev);
  261. if (!data)
  262. return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
  263. otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
  264. GFP_KERNEL);
  265. if (!otp)
  266. return -ENOMEM;
  267. otp->data = data;
  268. otp->dev = dev;
  269. otp->base = devm_platform_ioremap_resource(pdev, 0);
  270. if (IS_ERR(otp->base))
  271. return dev_err_probe(dev, PTR_ERR(otp->base),
  272. "failed to ioremap resource\n");
  273. otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
  274. GFP_KERNEL);
  275. if (!otp->clks)
  276. return -ENOMEM;
  277. for (i = 0; i < data->num_clks; ++i)
  278. otp->clks[i].id = data->clks[i];
  279. ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
  280. if (ret)
  281. return dev_err_probe(dev, ret, "failed to get clocks\n");
  282. otp->rst = devm_reset_control_array_get_exclusive(dev);
  283. if (IS_ERR(otp->rst))
  284. return dev_err_probe(dev, PTR_ERR(otp->rst),
  285. "failed to get resets\n");
  286. otp_config.size = data->size;
  287. otp_config.priv = otp;
  288. otp_config.dev = dev;
  289. nvmem = devm_nvmem_register(dev, &otp_config);
  290. if (IS_ERR(nvmem))
  291. return dev_err_probe(dev, PTR_ERR(nvmem),
  292. "failed to register nvmem device\n");
  293. return 0;
  294. }
  295. static struct platform_driver rockchip_otp_driver = {
  296. .probe = rockchip_otp_probe,
  297. .driver = {
  298. .name = "rockchip-otp",
  299. .of_match_table = rockchip_otp_match,
  300. },
  301. };
  302. module_platform_driver(rockchip_otp_driver);
  303. MODULE_DESCRIPTION("Rockchip OTP driver");
  304. MODULE_LICENSE("GPL v2");