1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 #include <linux/compat.h> 7 #include <linux/delay.h> 8 #include <linux/kernel.h> 9 #include <linux/string.h> 10 11 #include "rkflash_debug.h" 12 #include "sfc_nor.h" 13 14 static struct flash_info spi_flash_tbl[] = { 15 /* GD25Q40B */ 16 { 0xc84013, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x05, 10, 9, 0 }, 17 /* GD25Q32B */ 18 { 0xc84016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 13, 9, 0 }, 19 /* GD25Q64B/C/E */ 20 { 0xc84017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 21 /* GD25Q127C and GD25Q128C/E */ 22 { 0xc84018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 23 /* GD25Q256B/C/D/E */ 24 { 0xc84019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1C, 16, 6, 0 }, 25 /* GD25Q512MC */ 26 { 0xc84020, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1C, 17, 6, 0 }, 27 /* GD25LQ64C */ 28 { 0xc86017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 }, 29 /* GD25LQ128 */ 30 { 0xc86018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 9, 0 }, 31 /* GD25LQ32E */ 32 { 0xc86016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 13, 9, 0 }, 33 /* GD25B512MEYIG */ 34 { 0xc8471A, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 17, 0, 0 }, 35 /* GD55B01GE */ 36 { 0xc8471B, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 18, 0, 0 }, 37 /* GD25LQ255E and GD25LQ256C */ 38 { 0xc86019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1D, 16, 9, 0 }, 39 /* GD25LB512MEYIG */ 40 { 0xc8671A, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 17, 0, 0 }, 41 42 /* W25Q32JV */ 43 { 0xef4016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 9, 0 }, 44 /* W25Q64JVSSIQ */ 45 { 0xef4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 46 /* W25Q128FV and W25Q128JV*/ 47 { 0xef4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 48 /* W25Q256F/J */ 49 { 0xef4019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0 }, 50 /* W25Q32JW */ 51 { 0xef6016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 9, 0 }, 52 /* W25Q64FWSSIG */ 53 { 0xef6017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 54 /* W25Q128JWSQ */ 55 { 0xef6018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 56 /* W25Q256JWEQ*/ 57 { 0xef6019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0 }, 58 /* W25Q128JVSIM */ 59 { 0xef7018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 60 /* W25Q256JVEM */ 61 { 0xef7019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x3C, 16, 9, 0 }, 62 63 /* MX25L3233FM2I-08G */ 64 { 0xc22016, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x0E, 13, 6, 0 }, 65 /* MX25L6433F */ 66 { 0xc22017, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x0E, 14, 6, 0 }, 67 /* MX25L12835E/F MX25L12833FMI-10G */ 68 { 0xc22018, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x0E, 15, 6, 0 }, 69 /* MX25L25635E/F MX25L25645G MX25L25645GMI-08G */ 70 { 0xc22019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1E, 16, 6, 0 }, 71 /* MX25L51245GMI */ 72 { 0xc2201a, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1E, 17, 6, 0 }, 73 /* MX25U51245G */ 74 { 0xc2253a, 128, 8, 0x0C, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1E, 17, 6, 0 }, 75 /* MX25U3232F */ 76 { 0xc22536, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0E, 13, 6, 0 }, 77 /* MX25U6432F */ 78 { 0xc22537, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0E, 14, 6, 0 }, 79 /* MX25U12832F */ 80 { 0xc22538, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0E, 15, 6, 0 }, 81 /* MX25U25645GZ4I-00 */ 82 { 0xc22539, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1E, 16, 6, 0 }, 83 84 /* XM25QH32C */ 85 { 0x204016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 9, 0 }, 86 /* XM25QH64C */ 87 { 0x204017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 88 /* XM25QH128C */ 89 { 0x204018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x05, 15, 9, 0 }, 90 /* XM25QH256C */ 91 { 0x204019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 9, 0 }, 92 /* XM25QH64B */ 93 { 0x206017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 6, 0 }, 94 /* XM25QH128B */ 95 { 0x206018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 6, 0 }, 96 /* XM25QH(QU)256B */ 97 { 0x206019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1D, 16, 6, 0 }, 98 /* XM25QH64A */ 99 { 0x207017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 }, 100 /* XM25QU128C */ 101 { 0x204118, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 102 /* XM25QU64C */ 103 { 0x204117, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 104 105 /* XT25F128A XM25QH128A */ 106 { 0x207018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 0, 0 }, 107 /* XT25F64BSSIGU-5 XT25F64F */ 108 { 0x0b4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 }, 109 /* XT25F128BSSIGU */ 110 { 0x0b4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 9, 0 }, 111 /* XT25F256BSFIGU */ 112 { 0x0b4019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 9, 0 }, 113 /* XT25F32BS XT25F32F */ 114 { 0x0b4016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 13, 9, 0 }, 115 /* XT25F16BS */ 116 { 0x0b4015, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 12, 9, 0 }, 117 /* XT25Q64D */ 118 { 0x0b6017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 119 /* XT25Q128D */ 120 { 0x0b6018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 121 122 /* EN25QH64A */ 123 { 0x1c7017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 }, 124 /* EN25QH128A */ 125 { 0x1c7018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 0, 0 }, 126 /* EN25QH32B */ 127 { 0x1c7016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 0, 0 }, 128 /* EN25S32A */ 129 { 0x1c3816, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 0, 0 }, 130 /* EN25S64A */ 131 { 0x1c3817, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 0, 0 }, 132 /* EN25QH256A */ 133 { 0x1c7019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 0, 0 }, 134 /* EN25QX256A */ 135 { 0x1c7119, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 0, 0 }, 136 137 /* P25Q64H */ 138 { 0x856017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 139 /* P25Q128H */ 140 { 0x856018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 141 /* P25Q16H-SUH-IT */ 142 { 0x856015, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 12, 9, 0 }, 143 /* P25Q32SL P25Q32SH-SSH-IT */ 144 { 0x856016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 13, 9, 0 }, 145 /* PY25Q64HA */ 146 { 0x852017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 147 /* PY25Q128H */ 148 { 0x852018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 149 /* PY25Q256H */ 150 { 0x852019, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 9, 0 }, 151 152 /* ZB25VQ64 */ 153 { 0x5e4017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 154 /* ZB25VQ128 */ 155 { 0x5e4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 156 /* ZB25LQ128 */ 157 { 0x5e5018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 158 159 /* BH25Q128AS */ 160 { 0x684018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 161 /* BH25Q64BS */ 162 { 0x684017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 163 164 /* FM25Q128A */ 165 { 0xA14018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 166 /* FM25Q64-SOB-T-G */ 167 { 0xA14017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 14, 9, 0 }, 168 169 /* FM25Q64A */ 170 { 0xf83217, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 }, 171 /* FM25M4AA */ 172 { 0xf84218, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 15, 9, 0 }, 173 /* FM25M64C */ 174 { 0xf84317, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0 }, 175 176 /* DS25M4AB-1AIB4 */ 177 { 0xe54218, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 178 179 /* GM25Q128A */ 180 { 0x1c4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0 }, 181 182 /* IS25LP512M */ 183 { 0x9D601A, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x3C, 17, 6, 0 }, 184 /* IS25WP512M */ 185 { 0x9D701A, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x3C, 17, 6, 0 }, 186 187 /* BY25Q256FSEIG */ 188 { 0x684919, 128, 8, 0x13, 0x12, 0x6C, 0x34, 0x21, 0xDC, 0x1C, 16, 9, 0 }, 189 190 /* NM25Q128EVB */ 191 { 0x522118, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 10, 0 }, 192 }; 193 194 static int snor_write_en(void) 195 { 196 int ret; 197 struct rk_sfc_op op; 198 199 op.sfcmd.d32 = 0; 200 op.sfcmd.b.cmd = CMD_WRITE_EN; 201 202 op.sfctrl.d32 = 0; 203 204 ret = sfc_request(&op, 0, NULL, 0); 205 206 return ret; 207 } 208 209 int snor_reset_device(void) 210 { 211 struct rk_sfc_op op; 212 213 op.sfcmd.d32 = 0; 214 op.sfcmd.b.cmd = CMD_ENABLE_RESER; 215 216 op.sfctrl.d32 = 0; 217 sfc_request(&op, 0, NULL, 0); 218 219 op.sfcmd.d32 = 0; 220 op.sfcmd.b.cmd = CMD_RESET_DEVICE; 221 222 op.sfctrl.d32 = 0; 223 sfc_request(&op, 0, NULL, 0); 224 /* tRST=30us , delay 1ms here */ 225 sfc_delay(1000); 226 227 return SFC_OK; 228 } 229 230 static int snor_enter_4byte_mode(void) 231 { 232 int ret; 233 struct rk_sfc_op op; 234 235 op.sfcmd.d32 = 0; 236 op.sfcmd.b.cmd = CMD_ENTER_4BYTE_MODE; 237 238 op.sfctrl.d32 = 0; 239 240 ret = sfc_request(&op, 0, NULL, 0); 241 return ret; 242 } 243 244 static int snor_read_status(u32 reg_index, u8 *status) 245 { 246 int ret; 247 struct rk_sfc_op op; 248 u8 read_stat_cmd[] = {CMD_READ_STATUS, 249 CMD_READ_STATUS2, CMD_READ_STATUS3}; 250 op.sfcmd.d32 = 0; 251 op.sfcmd.b.cmd = read_stat_cmd[reg_index]; 252 253 op.sfctrl.d32 = 0; 254 ret = sfc_request(&op, 0, status, 1); 255 256 return ret; 257 } 258 259 static int snor_wait_busy(int timeout) 260 { 261 int ret; 262 struct rk_sfc_op op; 263 int i; 264 u32 status; 265 266 op.sfcmd.d32 = 0; 267 op.sfcmd.b.cmd = CMD_READ_STATUS; 268 269 op.sfctrl.d32 = 0; 270 271 for (i = 0; i < timeout; i++) { 272 ret = sfc_request(&op, 0, &status, 1); 273 if (ret != SFC_OK) 274 return ret; 275 276 if ((status & 0x01) == 0) 277 return SFC_OK; 278 279 sfc_delay(1); 280 } 281 rkflash_print_error("%s error %x\n", __func__, timeout); 282 283 return SFC_BUSY_TIMEOUT; 284 } 285 286 static int snor_write_status2(u32 reg_index, u8 status) 287 { 288 int ret; 289 struct rk_sfc_op op; 290 u8 status2[2]; 291 292 status2[reg_index] = status; 293 if (reg_index == 0) 294 ret = snor_read_status(2, &status2[1]); 295 else 296 ret = snor_read_status(0, &status2[0]); 297 if (ret != SFC_OK) 298 return ret; 299 300 snor_write_en(); 301 302 op.sfcmd.d32 = 0; 303 op.sfcmd.b.cmd = CMD_WRITE_STATUS; 304 op.sfcmd.b.rw = SFC_WRITE; 305 306 op.sfctrl.d32 = 0; 307 308 ret = sfc_request(&op, 0, &status2[0], 2); 309 if (ret != SFC_OK) 310 return ret; 311 312 ret = snor_wait_busy(10000); /* 10ms */ 313 314 return ret; 315 } 316 317 static int snor_write_status1(u32 reg_index, u8 status) 318 { 319 int ret; 320 struct rk_sfc_op op; 321 u8 status2[2]; 322 u8 read_index; 323 324 status2[reg_index] = status; 325 read_index = (reg_index == 0) ? 1 : 0; 326 ret = snor_read_status(read_index, &status2[read_index]); 327 if (ret != SFC_OK) 328 return ret; 329 330 snor_write_en(); 331 332 op.sfcmd.d32 = 0; 333 op.sfcmd.b.cmd = CMD_WRITE_STATUS; 334 op.sfcmd.b.rw = SFC_WRITE; 335 336 op.sfctrl.d32 = 0; 337 338 ret = sfc_request(&op, 0, &status2[0], 2); 339 if (ret != SFC_OK) 340 return ret; 341 342 ret = snor_wait_busy(10000); /* 10ms */ 343 344 return ret; 345 } 346 347 static int snor_write_status(u32 reg_index, u8 status) 348 { 349 int ret; 350 struct rk_sfc_op op; 351 u8 write_stat_cmd[] = {CMD_WRITE_STATUS, 352 CMD_WRITE_STATUS2, CMD_WRITE_STATUS3}; 353 snor_write_en(); 354 op.sfcmd.d32 = 0; 355 op.sfcmd.b.cmd = write_stat_cmd[reg_index]; 356 op.sfcmd.b.rw = SFC_WRITE; 357 358 op.sfctrl.d32 = 0; 359 360 ret = sfc_request(&op, 0, &status, 1); 361 if (ret != SFC_OK) 362 return ret; 363 364 ret = snor_wait_busy(10000); /* 10ms */ 365 366 return ret; 367 } 368 369 int snor_erase(struct SFNOR_DEV *p_dev, 370 u32 addr, 371 enum NOR_ERASE_TYPE erase_type) 372 { 373 int ret; 374 struct rk_sfc_op op; 375 int timeout[] = {400, 2000, 40000}; /* ms */ 376 377 rkflash_print_dio("%s %x %x\n", __func__, addr, erase_type); 378 379 if (erase_type > ERASE_CHIP) 380 return SFC_PARAM_ERR; 381 382 op.sfcmd.d32 = 0; 383 if (erase_type == ERASE_BLOCK64K) 384 op.sfcmd.b.cmd = p_dev->blk_erase_cmd; 385 else if (erase_type == ERASE_SECTOR) 386 op.sfcmd.b.cmd = p_dev->sec_erase_cmd; 387 else 388 op.sfcmd.b.cmd = CMD_CHIP_ERASE; 389 390 op.sfcmd.b.addrbits = (erase_type != ERASE_CHIP) ? 391 SFC_ADDR_24BITS : SFC_ADDR_0BITS; 392 if (p_dev->addr_mode == ADDR_MODE_4BYTE && erase_type != ERASE_CHIP) 393 op.sfcmd.b.addrbits = SFC_ADDR_32BITS; 394 op.sfcmd.b.rw = SFC_WRITE; 395 396 op.sfctrl.d32 = 0; 397 398 snor_write_en(); 399 400 ret = sfc_request(&op, addr, NULL, 0); 401 if (ret != SFC_OK) 402 return ret; 403 404 ret = snor_wait_busy(timeout[erase_type] * 1000); 405 return ret; 406 } 407 408 int snor_prog_page(struct SFNOR_DEV *p_dev, 409 u32 addr, 410 void *p_data, 411 u32 size) 412 { 413 int ret; 414 struct rk_sfc_op op; 415 416 rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data)); 417 418 op.sfcmd.d32 = 0; 419 op.sfcmd.b.cmd = p_dev->prog_cmd; 420 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 421 op.sfcmd.b.rw = SFC_WRITE; 422 423 op.sfctrl.d32 = 0; 424 op.sfctrl.b.datalines = p_dev->prog_lines; 425 op.sfctrl.b.enbledma = 1; 426 op.sfctrl.b.addrlines = p_dev->prog_addr_lines; 427 428 if (p_dev->addr_mode == ADDR_MODE_4BYTE) 429 op.sfcmd.b.addrbits = SFC_ADDR_32BITS; 430 431 snor_write_en(); 432 433 ret = sfc_request(&op, addr, p_data, size); 434 if (ret != SFC_OK) 435 return ret; 436 437 ret = snor_wait_busy(10000); 438 439 return ret; 440 } 441 442 static int snor_prog(struct SFNOR_DEV *p_dev, u32 addr, void *p_data, u32 size) 443 { 444 int ret = SFC_OK; 445 u32 page_size, len; 446 u8 *p_buf = (u8 *)p_data; 447 448 page_size = NOR_PAGE_SIZE; 449 while (size) { 450 len = page_size < size ? page_size : size; 451 ret = snor_prog_page(p_dev, addr, p_buf, len); 452 if (ret != SFC_OK) 453 return ret; 454 455 size -= len; 456 addr += len; 457 p_buf += len; 458 } 459 460 return ret; 461 } 462 463 static int snor_enable_QE(struct SFNOR_DEV *p_dev) 464 { 465 int ret = SFC_OK; 466 int reg_index; 467 int bit_offset; 468 u8 status; 469 470 reg_index = p_dev->QE_bits >> 3; 471 bit_offset = p_dev->QE_bits & 0x7; 472 ret = snor_read_status(reg_index, &status); 473 if (ret != SFC_OK) 474 return ret; 475 476 if (status & (1 << bit_offset)) /* is QE bit set */ 477 return SFC_OK; 478 479 status |= (1 << bit_offset); 480 481 return p_dev->write_status(reg_index, status); 482 } 483 484 int snor_disable_QE(struct SFNOR_DEV *p_dev) 485 { 486 int ret = SFC_OK; 487 int reg_index; 488 int bit_offset; 489 u8 status; 490 491 reg_index = p_dev->QE_bits >> 3; 492 bit_offset = p_dev->QE_bits & 0x7; 493 ret = snor_read_status(reg_index, &status); 494 if (ret != SFC_OK) 495 return ret; 496 497 if (!(status & (1 << bit_offset))) 498 return SFC_OK; 499 500 status &= ~(1 << bit_offset); 501 502 return p_dev->write_status(reg_index, status); 503 } 504 505 int snor_read_data(struct SFNOR_DEV *p_dev, 506 u32 addr, 507 void *p_data, 508 u32 size) 509 { 510 int ret; 511 struct rk_sfc_op op; 512 513 op.sfcmd.d32 = 0; 514 op.sfcmd.b.cmd = p_dev->read_cmd; 515 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 516 517 op.sfctrl.d32 = 0; 518 op.sfctrl.b.datalines = p_dev->read_lines; 519 if (!(size & 0x3) && size >= 4) 520 op.sfctrl.b.enbledma = 1; 521 522 if (p_dev->read_cmd == CMD_FAST_READ_X1 || 523 p_dev->read_cmd == CMD_PAGE_FASTREAD4B || 524 p_dev->read_cmd == CMD_FAST_READ_X4 || 525 p_dev->read_cmd == CMD_FAST_READ_X2 || 526 p_dev->read_cmd == CMD_FAST_4READ_X4) { 527 op.sfcmd.b.dummybits = 8; 528 } else if (p_dev->read_cmd == CMD_FAST_READ_A4) { 529 op.sfcmd.b.addrbits = SFC_ADDR_32BITS; 530 addr = (addr << 8) | 0xFF; /* Set M[7:0] = 0xFF */ 531 op.sfcmd.b.dummybits = 4; 532 op.sfctrl.b.addrlines = SFC_4BITS_LINE; 533 } 534 535 if (p_dev->addr_mode == ADDR_MODE_4BYTE) 536 op.sfcmd.b.addrbits = SFC_ADDR_32BITS; 537 538 ret = sfc_request(&op, addr, p_data, size); 539 rkflash_print_dio("%s %x %x\n", __func__, addr, *(u32 *)(p_data)); 540 541 return ret; 542 } 543 544 int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) 545 { 546 int ret = SFC_OK; 547 u32 addr, size, len; 548 u8 *p_buf = (u8 *)p_data; 549 550 rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec); 551 552 if ((sec + n_sec) > p_dev->capacity) 553 return SFC_PARAM_ERR; 554 555 addr = sec << 9; 556 size = n_sec << 9; 557 while (size) { 558 len = size < p_dev->max_iosize ? size : p_dev->max_iosize; 559 ret = snor_read_data(p_dev, addr, p_buf, len); 560 if (ret != SFC_OK) { 561 rkflash_print_error("snor_read_data %x ret= %x\n", 562 addr >> 9, ret); 563 goto out; 564 } 565 566 size -= len; 567 addr += len; 568 p_buf += len; 569 } 570 out: 571 if (!ret) 572 ret = n_sec; 573 574 return ret; 575 } 576 577 int snor_write(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) 578 { 579 int ret = SFC_OK; 580 u32 len, blk_size, offset; 581 u8 *p_buf = (u8 *)p_data; 582 u32 total_sec = n_sec; 583 584 rkflash_print_dio("%s %x %x\n", __func__, sec, n_sec); 585 586 if ((sec + n_sec) > p_dev->capacity) 587 return SFC_PARAM_ERR; 588 589 while (n_sec) { 590 if (sec < 512 || sec >= p_dev->capacity - 512) 591 blk_size = 8; 592 else 593 blk_size = p_dev->blk_size; 594 595 offset = (sec & (blk_size - 1)); 596 if (!offset) { 597 ret = snor_erase(p_dev, sec << 9, (blk_size == 8) ? 598 ERASE_SECTOR : ERASE_BLOCK64K); 599 if (ret != SFC_OK) { 600 rkflash_print_error("snor_erase %x ret= %x\n", 601 sec, ret); 602 goto out; 603 } 604 } 605 len = (blk_size - offset) < n_sec ? 606 (blk_size - offset) : n_sec; 607 ret = snor_prog(p_dev, sec << 9, p_buf, len << 9); 608 if (ret != SFC_OK) { 609 rkflash_print_error("snor_prog %x ret= %x\n", sec, ret); 610 goto out; 611 } 612 n_sec -= len; 613 sec += len; 614 p_buf += len << 9; 615 } 616 out: 617 if (!ret) 618 ret = total_sec; 619 620 return ret; 621 } 622 623 int snor_read_id(u8 *data) 624 { 625 int ret; 626 struct rk_sfc_op op; 627 628 op.sfcmd.d32 = 0; 629 op.sfcmd.b.cmd = CMD_READ_JEDECID; 630 631 op.sfctrl.d32 = 0; 632 633 ret = sfc_request(&op, 0, data, 3); 634 635 return ret; 636 } 637 638 static int snor_read_parameter(u32 addr, u8 *data) 639 { 640 int ret; 641 struct rk_sfc_op op; 642 643 op.sfcmd.d32 = 0; 644 op.sfcmd.b.cmd = CMD_READ_PARAMETER; 645 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 646 op.sfcmd.b.dummybits = 8; 647 648 op.sfctrl.d32 = 0; 649 650 ret = sfc_request(&op, addr, data, 1); 651 652 return ret; 653 } 654 655 u32 snor_get_capacity(struct SFNOR_DEV *p_dev) 656 { 657 return p_dev->capacity; 658 } 659 660 static struct flash_info *snor_get_flash_info(u8 *flash_id) 661 { 662 u32 i; 663 u32 id = (flash_id[0] << 16) | (flash_id[1] << 8) | (flash_id[2] << 0); 664 665 for (i = 0; i < ARRAY_SIZE(spi_flash_tbl); i++) { 666 if (spi_flash_tbl[i].id == id) 667 return &spi_flash_tbl[i]; 668 } 669 return NULL; 670 } 671 672 /* Adjust flash info in ram base on parameter */ 673 static void *snor_flash_info_adjust(struct flash_info *spi_flash_info) 674 { 675 u32 addr; 676 u8 para_version; 677 678 if (spi_flash_info->id == 0xc84019) { 679 addr = 0x09; 680 snor_read_parameter(addr, ¶_version); 681 if (para_version == 0x06) { 682 spi_flash_info->QE_bits = 9; 683 spi_flash_info->prog_cmd_4 = 0x34; 684 } 685 } 686 return 0; 687 } 688 689 static int snor_parse_flash_table(struct SFNOR_DEV *p_dev, 690 struct flash_info *g_spi_flash_info) 691 { 692 int i, ret; 693 694 if (g_spi_flash_info) { 695 snor_flash_info_adjust(g_spi_flash_info); 696 p_dev->manufacturer = (g_spi_flash_info->id >> 16) & 0xFF; 697 p_dev->mem_type = (g_spi_flash_info->id >> 8) & 0xFF; 698 p_dev->capacity = 1 << g_spi_flash_info->density; 699 p_dev->blk_size = g_spi_flash_info->block_size; 700 p_dev->page_size = NOR_SECS_PAGE; 701 p_dev->read_cmd = g_spi_flash_info->read_cmd; 702 p_dev->prog_cmd = g_spi_flash_info->prog_cmd; 703 p_dev->sec_erase_cmd = g_spi_flash_info->sector_erase_cmd; 704 p_dev->blk_erase_cmd = g_spi_flash_info->block_erase_cmd; 705 p_dev->prog_lines = DATA_LINES_X1; 706 p_dev->read_lines = DATA_LINES_X1; 707 p_dev->QE_bits = g_spi_flash_info->QE_bits; 708 p_dev->addr_mode = ADDR_MODE_3BYTE; 709 710 i = g_spi_flash_info->feature & FEA_READ_STATUE_MASK; 711 if (i == 0) 712 p_dev->write_status = snor_write_status; 713 else if (i == 1) 714 p_dev->write_status = snor_write_status1; 715 else if (i == 2) 716 p_dev->write_status = snor_write_status2; 717 718 if (g_spi_flash_info->feature & FEA_4BIT_READ) { 719 ret = SFC_OK; 720 if (g_spi_flash_info->QE_bits) 721 ret = snor_enable_QE(p_dev); 722 if (ret == SFC_OK) { 723 p_dev->read_lines = DATA_LINES_X4; 724 p_dev->read_cmd = g_spi_flash_info->read_cmd_4; 725 } 726 } 727 if (g_spi_flash_info->feature & FEA_4BIT_PROG && 728 p_dev->read_lines == DATA_LINES_X4) { 729 p_dev->prog_lines = DATA_LINES_X4; 730 p_dev->prog_cmd = g_spi_flash_info->prog_cmd_4; 731 if ((p_dev->manufacturer == MID_MACRONIX) && 732 (p_dev->prog_cmd == CMD_PAGE_PROG_A4 || 733 p_dev->prog_cmd == CMD_PAGE_PROG_4PP)) 734 p_dev->prog_addr_lines = DATA_LINES_X4; 735 } 736 737 if (g_spi_flash_info->feature & FEA_4BYTE_ADDR) 738 p_dev->addr_mode = ADDR_MODE_4BYTE; 739 740 if ((g_spi_flash_info->feature & FEA_4BYTE_ADDR_MODE)) 741 snor_enter_4byte_mode(); 742 } 743 744 return SFC_OK; 745 } 746 747 int snor_init(struct SFNOR_DEV *p_dev) 748 { 749 struct flash_info *g_spi_flash_info; 750 u8 id_byte[5]; 751 752 if (!p_dev) 753 return SFC_PARAM_ERR; 754 755 memset((void *)p_dev, 0, sizeof(struct SFNOR_DEV)); 756 p_dev->max_iosize = sfc_get_max_iosize(); 757 758 snor_read_id(id_byte); 759 rkflash_print_error("sfc nor id: %x %x %x\n", 760 id_byte[0], id_byte[1], id_byte[2]); 761 if (0xFF == id_byte[0] || 0x00 == id_byte[0] || 0xFF == id_byte[1] || 0x00 == id_byte[1]) 762 return SFC_ERROR; 763 764 g_spi_flash_info = snor_get_flash_info(id_byte); 765 if (g_spi_flash_info) { 766 snor_parse_flash_table(p_dev, g_spi_flash_info); 767 } else { 768 pr_err("The device not support yet!\n"); 769 770 p_dev->manufacturer = id_byte[0]; 771 p_dev->mem_type = id_byte[1]; 772 p_dev->capacity = 1 << (id_byte[2] - 9); 773 p_dev->QE_bits = 0; 774 p_dev->blk_size = NOR_SECS_BLK; 775 p_dev->page_size = NOR_SECS_PAGE; 776 p_dev->read_cmd = CMD_READ_DATA; 777 p_dev->prog_cmd = CMD_PAGE_PROG; 778 p_dev->sec_erase_cmd = CMD_SECTOR_ERASE; 779 p_dev->blk_erase_cmd = CMD_BLOCK_ERASE; 780 p_dev->prog_lines = DATA_LINES_X1; 781 p_dev->prog_addr_lines = DATA_LINES_X1; 782 p_dev->read_lines = DATA_LINES_X1; 783 p_dev->write_status = snor_write_status; 784 snor_reset_device(); 785 } 786 787 rkflash_print_info("addr_mode: %x\n", p_dev->addr_mode); 788 rkflash_print_info("read_lines: %x\n", p_dev->read_lines); 789 rkflash_print_info("prog_lines: %x\n", p_dev->prog_lines); 790 rkflash_print_info("read_cmd: %x\n", p_dev->read_cmd); 791 rkflash_print_info("prog_cmd: %x\n", p_dev->prog_cmd); 792 rkflash_print_info("blk_erase_cmd: %x\n", p_dev->blk_erase_cmd); 793 rkflash_print_info("sec_erase_cmd: %x\n", p_dev->sec_erase_cmd); 794 rkflash_print_info("capacity: %x\n", p_dev->capacity); 795 796 return SFC_OK; 797 } 798 799 int snor_reinit_from_table_packet(struct SFNOR_DEV *p_dev, 800 struct snor_info_packet *packet) 801 { 802 struct flash_info g_spi_flash_info; 803 u8 id_byte[5]; 804 int ret; 805 806 if (!p_dev || packet->id != SNOR_INFO_PACKET_ID) 807 return SFC_PARAM_ERR; 808 809 snor_read_id(id_byte); 810 if (0xFF == id_byte[0] || 0x00 == id_byte[0]) 811 return SFC_ERROR; 812 813 g_spi_flash_info.id = id_byte[0] << 16 | id_byte[1] << 8 | id_byte[2]; 814 g_spi_flash_info.block_size = NOR_SECS_BLK; 815 g_spi_flash_info.sector_size = NOR_SECS_PAGE; 816 g_spi_flash_info.read_cmd = packet->read_cmd; 817 g_spi_flash_info.prog_cmd = packet->prog_cmd; 818 g_spi_flash_info.read_cmd_4 = packet->read_cmd_4; 819 g_spi_flash_info.prog_cmd_4 = packet->prog_cmd_4; 820 if (id_byte[2] >= 0x19) 821 g_spi_flash_info.read_cmd_4 = CMD_FAST_4READ_X4; 822 g_spi_flash_info.sector_erase_cmd = packet->sector_erase_cmd; 823 g_spi_flash_info.block_erase_cmd = packet->block_erase_cmd; 824 g_spi_flash_info.feature = packet->feature; 825 g_spi_flash_info.density = id_byte[2] - 9; 826 g_spi_flash_info.QE_bits = packet->QE_bits; 827 828 ret = snor_parse_flash_table(p_dev, &g_spi_flash_info); 829 830 return ret; 831 } 832 833