18747ec2eSVincent Shih // SPDX-License-Identifier: GPL-2.0
28747ec2eSVincent Shih
38747ec2eSVincent Shih /*
48747ec2eSVincent Shih * The OCOTP driver for Sunplus SP7021
58747ec2eSVincent Shih *
68747ec2eSVincent Shih * Copyright (C) 2019 Sunplus Technology Inc., All rights reserved.
78747ec2eSVincent Shih */
88747ec2eSVincent Shih
98747ec2eSVincent Shih #include <linux/bitfield.h>
108747ec2eSVincent Shih #include <linux/clk.h>
118747ec2eSVincent Shih #include <linux/delay.h>
128747ec2eSVincent Shih #include <linux/device.h>
138747ec2eSVincent Shih #include <linux/io.h>
148747ec2eSVincent Shih #include <linux/iopoll.h>
158747ec2eSVincent Shih #include <linux/module.h>
169bf75da0SRob Herring #include <linux/mod_devicetable.h>
178747ec2eSVincent Shih #include <linux/nvmem-provider.h>
188747ec2eSVincent Shih #include <linux/platform_device.h>
198747ec2eSVincent Shih
208747ec2eSVincent Shih /*
218747ec2eSVincent Shih * OTP memory
228747ec2eSVincent Shih * Each bank contains 4 words (32 bits).
238747ec2eSVincent Shih * Bank 0 starts at offset 0 from the base.
248747ec2eSVincent Shih */
258747ec2eSVincent Shih
268747ec2eSVincent Shih #define OTP_WORDS_PER_BANK 4
278747ec2eSVincent Shih #define OTP_WORD_SIZE sizeof(u32)
288747ec2eSVincent Shih #define OTP_BIT_ADDR_OF_BANK (8 * OTP_WORD_SIZE * OTP_WORDS_PER_BANK)
298747ec2eSVincent Shih #define QAC628_OTP_NUM_BANKS 8
308747ec2eSVincent Shih #define QAC628_OTP_SIZE (QAC628_OTP_NUM_BANKS * OTP_WORDS_PER_BANK * OTP_WORD_SIZE)
318747ec2eSVincent Shih #define OTP_READ_TIMEOUT_US 200000
328747ec2eSVincent Shih
338747ec2eSVincent Shih /* HB_GPIO */
348747ec2eSVincent Shih #define ADDRESS_8_DATA 0x20
358747ec2eSVincent Shih
368747ec2eSVincent Shih /* OTP_RX */
378747ec2eSVincent Shih #define OTP_CONTROL_2 0x48
388747ec2eSVincent Shih #define OTP_RD_PERIOD GENMASK(15, 8)
398747ec2eSVincent Shih #define OTP_RD_PERIOD_MASK ~GENMASK(15, 8)
408747ec2eSVincent Shih #define CPU_CLOCK FIELD_PREP(OTP_RD_PERIOD, 30)
418747ec2eSVincent Shih #define SEL_BAK_KEY2 BIT(5)
428747ec2eSVincent Shih #define SEL_BAK_KEY2_MASK ~BIT(5)
438747ec2eSVincent Shih #define SW_TRIM_EN BIT(4)
448747ec2eSVincent Shih #define SW_TRIM_EN_MASK ~BIT(4)
458747ec2eSVincent Shih #define SEL_BAK_KEY BIT(3)
468747ec2eSVincent Shih #define SEL_BAK_KEY_MASK ~BIT(3)
478747ec2eSVincent Shih #define OTP_READ BIT(2)
488747ec2eSVincent Shih #define OTP_LOAD_SECURE_DATA BIT(1)
498747ec2eSVincent Shih #define OTP_LOAD_SECURE_DATA_MASK ~BIT(1)
508747ec2eSVincent Shih #define OTP_DO_CRC BIT(0)
518747ec2eSVincent Shih #define OTP_DO_CRC_MASK ~BIT(0)
528747ec2eSVincent Shih #define OTP_STATUS 0x4c
538747ec2eSVincent Shih #define OTP_READ_DONE BIT(4)
548747ec2eSVincent Shih #define OTP_READ_DONE_MASK ~BIT(4)
558747ec2eSVincent Shih #define OTP_LOAD_SECURE_DONE_MASK ~BIT(2)
568747ec2eSVincent Shih #define OTP_READ_ADDRESS 0x50
578747ec2eSVincent Shih
588747ec2eSVincent Shih enum base_type {
598747ec2eSVincent Shih HB_GPIO,
608747ec2eSVincent Shih OTPRX,
618747ec2eSVincent Shih BASEMAX,
628747ec2eSVincent Shih };
638747ec2eSVincent Shih
648747ec2eSVincent Shih struct sp_ocotp_priv {
658747ec2eSVincent Shih struct device *dev;
668747ec2eSVincent Shih void __iomem *base[BASEMAX];
678747ec2eSVincent Shih struct clk *clk;
688747ec2eSVincent Shih };
698747ec2eSVincent Shih
708747ec2eSVincent Shih struct sp_ocotp_data {
718747ec2eSVincent Shih int size;
728747ec2eSVincent Shih };
738747ec2eSVincent Shih
741066f815SKrzysztof Kozlowski static const struct sp_ocotp_data sp_otp_v0 = {
758747ec2eSVincent Shih .size = QAC628_OTP_SIZE,
768747ec2eSVincent Shih };
778747ec2eSVincent Shih
sp_otp_read_real(struct sp_ocotp_priv * otp,int addr,char * value)788747ec2eSVincent Shih static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value)
798747ec2eSVincent Shih {
808747ec2eSVincent Shih unsigned int addr_data;
818747ec2eSVincent Shih unsigned int byte_shift;
828747ec2eSVincent Shih unsigned int status;
838747ec2eSVincent Shih int ret;
848747ec2eSVincent Shih
858747ec2eSVincent Shih addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
868747ec2eSVincent Shih addr_data = addr_data / OTP_WORD_SIZE;
878747ec2eSVincent Shih
888747ec2eSVincent Shih byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
898747ec2eSVincent Shih byte_shift = byte_shift % OTP_WORD_SIZE;
908747ec2eSVincent Shih
918747ec2eSVincent Shih addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
928747ec2eSVincent Shih addr = addr * OTP_BIT_ADDR_OF_BANK;
938747ec2eSVincent Shih
948747ec2eSVincent Shih writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK &
958747ec2eSVincent Shih OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS);
968747ec2eSVincent Shih writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS);
978747ec2eSVincent Shih writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ,
988747ec2eSVincent Shih otp->base[OTPRX] + OTP_CONTROL_2);
998747ec2eSVincent Shih writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK
1008747ec2eSVincent Shih & SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK,
1018747ec2eSVincent Shih otp->base[OTPRX] + OTP_CONTROL_2);
1028747ec2eSVincent Shih writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK,
1038747ec2eSVincent Shih otp->base[OTPRX] + OTP_CONTROL_2);
1048747ec2eSVincent Shih
1058747ec2eSVincent Shih ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status,
1068747ec2eSVincent Shih status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US);
1078747ec2eSVincent Shih
1088747ec2eSVincent Shih if (ret < 0)
1098747ec2eSVincent Shih return ret;
1108747ec2eSVincent Shih
1118747ec2eSVincent Shih *value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE)
1128747ec2eSVincent Shih >> (8 * byte_shift)) & 0xff;
1138747ec2eSVincent Shih
1148747ec2eSVincent Shih return ret;
1158747ec2eSVincent Shih }
1168747ec2eSVincent Shih
sp_ocotp_read(void * priv,unsigned int offset,void * value,size_t bytes)1178747ec2eSVincent Shih static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes)
1188747ec2eSVincent Shih {
1198747ec2eSVincent Shih struct sp_ocotp_priv *otp = priv;
1208747ec2eSVincent Shih unsigned int addr;
1218747ec2eSVincent Shih char *buf = value;
1228747ec2eSVincent Shih char val[4];
1238747ec2eSVincent Shih int ret;
1248747ec2eSVincent Shih
1258747ec2eSVincent Shih ret = clk_enable(otp->clk);
1268747ec2eSVincent Shih if (ret)
1278747ec2eSVincent Shih return ret;
1288747ec2eSVincent Shih
1298747ec2eSVincent Shih *buf = 0;
1308747ec2eSVincent Shih for (addr = offset; addr < (offset + bytes); addr++) {
1318747ec2eSVincent Shih ret = sp_otp_read_real(otp, addr, val);
1328747ec2eSVincent Shih if (ret < 0) {
1338747ec2eSVincent Shih dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr);
1348747ec2eSVincent Shih goto disable_clk;
1358747ec2eSVincent Shih }
1368747ec2eSVincent Shih
1378747ec2eSVincent Shih *buf++ = *val;
1388747ec2eSVincent Shih }
1398747ec2eSVincent Shih
1408747ec2eSVincent Shih disable_clk:
1418747ec2eSVincent Shih clk_disable(otp->clk);
1428747ec2eSVincent Shih
1438747ec2eSVincent Shih return ret;
1448747ec2eSVincent Shih }
1458747ec2eSVincent Shih
1468747ec2eSVincent Shih static struct nvmem_config sp_ocotp_nvmem_config = {
1478747ec2eSVincent Shih .name = "sp-ocotp",
148*26e2fe4cSRafał Miłecki .add_legacy_fixed_of_cells = true,
1498747ec2eSVincent Shih .read_only = true,
1508747ec2eSVincent Shih .word_size = 1,
1518747ec2eSVincent Shih .size = QAC628_OTP_SIZE,
1528747ec2eSVincent Shih .stride = 1,
1538747ec2eSVincent Shih .reg_read = sp_ocotp_read,
1548747ec2eSVincent Shih .owner = THIS_MODULE,
1558747ec2eSVincent Shih };
1568747ec2eSVincent Shih
sp_ocotp_probe(struct platform_device * pdev)1578747ec2eSVincent Shih static int sp_ocotp_probe(struct platform_device *pdev)
1588747ec2eSVincent Shih {
1598747ec2eSVincent Shih struct device *dev = &pdev->dev;
1608747ec2eSVincent Shih struct nvmem_device *nvmem;
1618747ec2eSVincent Shih struct sp_ocotp_priv *otp;
1628747ec2eSVincent Shih struct resource *res;
1638747ec2eSVincent Shih int ret;
1648747ec2eSVincent Shih
1658747ec2eSVincent Shih otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
1668747ec2eSVincent Shih if (!otp)
1678747ec2eSVincent Shih return -ENOMEM;
1688747ec2eSVincent Shih
1698747ec2eSVincent Shih otp->dev = dev;
1708747ec2eSVincent Shih
1718747ec2eSVincent Shih res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
1728747ec2eSVincent Shih otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
1738747ec2eSVincent Shih if (IS_ERR(otp->base[HB_GPIO]))
1748747ec2eSVincent Shih return PTR_ERR(otp->base[HB_GPIO]);
1758747ec2eSVincent Shih
1768747ec2eSVincent Shih res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
1778747ec2eSVincent Shih otp->base[OTPRX] = devm_ioremap_resource(dev, res);
1788747ec2eSVincent Shih if (IS_ERR(otp->base[OTPRX]))
1798747ec2eSVincent Shih return PTR_ERR(otp->base[OTPRX]);
1808747ec2eSVincent Shih
1818747ec2eSVincent Shih otp->clk = devm_clk_get(&pdev->dev, NULL);
1828747ec2eSVincent Shih if (IS_ERR(otp->clk))
1838747ec2eSVincent Shih return dev_err_probe(&pdev->dev, PTR_ERR(otp->clk),
1848747ec2eSVincent Shih "devm_clk_get fail\n");
1858747ec2eSVincent Shih
1868747ec2eSVincent Shih ret = clk_prepare(otp->clk);
1878747ec2eSVincent Shih if (ret < 0) {
1888747ec2eSVincent Shih dev_err(dev, "failed to prepare clk: %d\n", ret);
1898747ec2eSVincent Shih return ret;
1908747ec2eSVincent Shih }
1918747ec2eSVincent Shih
1928747ec2eSVincent Shih sp_ocotp_nvmem_config.priv = otp;
1938747ec2eSVincent Shih sp_ocotp_nvmem_config.dev = dev;
1948747ec2eSVincent Shih
1958747ec2eSVincent Shih nvmem = devm_nvmem_register(dev, &sp_ocotp_nvmem_config);
196095bb8baSYi Yingao if (IS_ERR(nvmem)) {
197095bb8baSYi Yingao ret = dev_err_probe(&pdev->dev, PTR_ERR(nvmem),
1988747ec2eSVincent Shih "register nvmem device fail\n");
199095bb8baSYi Yingao goto err;
200095bb8baSYi Yingao }
2018747ec2eSVincent Shih
2028747ec2eSVincent Shih platform_set_drvdata(pdev, nvmem);
2038747ec2eSVincent Shih
2048747ec2eSVincent Shih dev_dbg(dev, "banks:%d x wpb:%d x wsize:%d = %d",
2058747ec2eSVincent Shih (int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK,
2068747ec2eSVincent Shih (int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE);
2078747ec2eSVincent Shih
2088747ec2eSVincent Shih return 0;
209095bb8baSYi Yingao err:
210095bb8baSYi Yingao clk_unprepare(otp->clk);
211095bb8baSYi Yingao return ret;
2128747ec2eSVincent Shih }
2138747ec2eSVincent Shih
2148747ec2eSVincent Shih static const struct of_device_id sp_ocotp_dt_ids[] = {
2158747ec2eSVincent Shih { .compatible = "sunplus,sp7021-ocotp", .data = &sp_otp_v0 },
2168747ec2eSVincent Shih { }
2178747ec2eSVincent Shih };
2188747ec2eSVincent Shih MODULE_DEVICE_TABLE(of, sp_ocotp_dt_ids);
2198747ec2eSVincent Shih
2208747ec2eSVincent Shih static struct platform_driver sp_otp_driver = {
2218747ec2eSVincent Shih .probe = sp_ocotp_probe,
2228747ec2eSVincent Shih .driver = {
2238747ec2eSVincent Shih .name = "sunplus,sp7021-ocotp",
2248747ec2eSVincent Shih .of_match_table = sp_ocotp_dt_ids,
2258747ec2eSVincent Shih }
2268747ec2eSVincent Shih };
2278747ec2eSVincent Shih module_platform_driver(sp_otp_driver);
2288747ec2eSVincent Shih
2298747ec2eSVincent Shih MODULE_AUTHOR("Vincent Shih <vincent.sunplus@gmail.com>");
2308747ec2eSVincent Shih MODULE_DESCRIPTION("Sunplus On-Chip OTP driver");
2318747ec2eSVincent Shih MODULE_LICENSE("GPL");
2328747ec2eSVincent Shih
233