1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <asm/io.h> 8 #include <command.h> 9 #include <dm.h> 10 #include <linux/bitops.h> 11 #include <linux/delay.h> 12 #include <misc.h> 13 14 /* OTP Register Offsets */ 15 #define OTPC_SBPI_CTRL 0x0020 16 #define OTPC_SBPI_CMD_VALID_PRE 0x0024 17 #define OTPC_SBPI_CS_VALID_PRE 0x0028 18 #define OTPC_SBPI_STATUS 0x002C 19 #define OTPC_USER_CTRL 0x0100 20 #define OTPC_USER_ADDR 0x0104 21 #define OTPC_USER_ENABLE 0x0108 22 #define OTPC_USER_Q 0x0124 23 #define OTPC_INT_STATUS 0x0304 24 #define OTPC_SBPI_CMD0_OFFSET 0x1000 25 #define OTPC_SBPI_CMD1_OFFSET 0x1004 26 27 /* OTP Register bits and masks */ 28 #define OTPC_USER_ADDR_MASK GENMASK(31, 16) 29 #define OTPC_USE_USER BIT(0) 30 #define OTPC_USE_USER_MASK GENMASK(16, 16) 31 #define OTPC_USER_FSM_ENABLE BIT(0) 32 #define OTPC_USER_FSM_ENABLE_MASK GENMASK(16, 16) 33 #define OTPC_SBPI_DONE BIT(1) 34 #define OTPC_USER_DONE BIT(2) 35 36 #define SBPI_DAP_ADDR 0x02 37 #define SBPI_DAP_ADDR_SHIFT 8 38 #define SBPI_DAP_ADDR_MASK GENMASK(31, 24) 39 #define SBPI_CMD_VALID_MASK GENMASK(31, 16) 40 #define SBPI_DAP_CMD_WRF 0xC0 41 #define SBPI_DAP_REG_ECC 0x3A 42 #define SBPI_ECC_ENABLE 0x00 43 #define SBPI_ECC_DISABLE 0x09 44 #define SBPI_ENABLE BIT(0) 45 #define SBPI_ENABLE_MASK GENMASK(16, 16) 46 47 #define OTPC_TIMEOUT 10000 48 49 typedef int (*OTP_READ)(struct udevice *dev, int offset, void *buf, int size); 50 51 struct rockchip_otp_platdata { 52 void __iomem *base; 53 }; 54 55 static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp, 56 u32 flag) 57 { 58 int delay = OTPC_TIMEOUT; 59 60 while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) { 61 udelay(1); 62 delay--; 63 if (delay <= 0) { 64 printf("%s: wait init status timeout\n", __func__); 65 return -ETIMEDOUT; 66 } 67 } 68 69 /* clean int status */ 70 writel(flag, otp->base + OTPC_INT_STATUS); 71 72 return 0; 73 } 74 75 static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp, 76 bool enable) 77 { 78 int ret = 0; 79 80 writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT), 81 otp->base + OTPC_SBPI_CTRL); 82 83 writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE); 84 writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC, 85 otp->base + OTPC_SBPI_CMD0_OFFSET); 86 if (enable) 87 writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 88 else 89 writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 90 91 writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); 92 93 ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); 94 if (ret < 0) 95 printf("%s timeout during ecc_enable\n", __func__); 96 97 return ret; 98 } 99 100 static int rockchip_px30_otp_read(struct udevice *dev, int offset, 101 void *buf, int size) 102 { 103 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 104 u8 *buffer = buf; 105 int ret = 0; 106 107 ret = rockchip_otp_ecc_enable(otp, false); 108 if (ret < 0) { 109 printf("%s rockchip_otp_ecc_enable err\n", __func__); 110 return ret; 111 } 112 113 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 114 udelay(5); 115 while (size--) { 116 writel(offset++ | OTPC_USER_ADDR_MASK, 117 otp->base + OTPC_USER_ADDR); 118 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, 119 otp->base + OTPC_USER_ENABLE); 120 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); 121 if (ret < 0) { 122 printf("%s timeout during read setup\n", __func__); 123 goto read_end; 124 } 125 *buffer++ = readb(otp->base + OTPC_USER_Q); 126 } 127 128 read_end: 129 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 130 131 return ret; 132 } 133 134 static int rockchip_otp_read(struct udevice *dev, int offset, 135 void *buf, int size) 136 { 137 OTP_READ otp_read = NULL; 138 139 otp_read = (OTP_READ)dev_get_driver_data(dev); 140 if (!otp_read) 141 return -ENOSYS; 142 143 return (*otp_read)(dev, offset, buf, size); 144 } 145 146 static const struct misc_ops rockchip_otp_ops = { 147 .read = rockchip_otp_read, 148 }; 149 150 static int rockchip_otp_ofdata_to_platdata(struct udevice *dev) 151 { 152 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 153 154 otp->base = dev_read_addr_ptr(dev); 155 156 return 0; 157 } 158 159 static const struct udevice_id rockchip_otp_ids[] = { 160 { 161 .compatible = "rockchip,px30-otp", 162 .data = (ulong)&rockchip_px30_otp_read, 163 }, 164 { 165 .compatible = "rockchip,rk3308-otp", 166 .data = (ulong)&rockchip_px30_otp_read, 167 }, 168 {} 169 }; 170 171 U_BOOT_DRIVER(rockchip_otp) = { 172 .name = "rockchip_otp", 173 .id = UCLASS_MISC, 174 .of_match = rockchip_otp_ids, 175 .ops = &rockchip_otp_ops, 176 .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata, 177 .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata), 178 }; 179