1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 10 #include "rkflash_api.h" 11 #include "rkflash_blk.h" 12 #include "rkflash_debug.h" 13 14 #ifdef CONFIG_RKSFC_NOR 15 16 #define IDB_ALIGN_64 128 /* 64 KB */ 17 #define IDB_ALIGN_32 64 /* 32 KB */ 18 19 static void P_RC4(u8 *buf, u16 len) 20 { 21 u8 S[256], K[256], temp; 22 u16 i, j, t, x; 23 u8 key[16] = {124, 78, 3, 4, 85, 5, 9, 7, 24 45, 44, 123, 56, 23, 13, 23, 17}; 25 26 j = 0; 27 for (i = 0; i < 256; i++) { 28 S[i] = (u8)i; 29 j &= 0x0f; 30 K[i] = key[j]; 31 j++; 32 } 33 34 j = 0; 35 for (i = 0; i < 256; i++) { 36 j = (j + S[i] + K[i]) % 256; 37 temp = S[i]; 38 S[i] = S[j]; 39 S[j] = temp; 40 } 41 42 i = 0; 43 j = 0; 44 for (x = 0; x < len; x++) { 45 i = (i + 1) % 256; 46 j = (j + S[i]) % 256; 47 temp = S[i]; 48 S[i] = S[j]; 49 S[j] = temp; 50 t = (S[i] + (S[j] % 256)) % 256; 51 buf[x] = buf[x] ^ S[t]; 52 } 53 } 54 55 int rksfc_nor_init(struct udevice *udev) 56 { 57 struct rkflash_info *priv = dev_get_priv(udev); 58 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 59 struct snor_info_packet *packet; 60 struct id_block_tag *idb_tag; 61 int ret; 62 63 ret = snor_init(p_dev); 64 if (ret == SFC_OK && p_dev->read_lines == DATA_LINES_X1) { 65 idb_tag = kzalloc(NOR_SECS_PAGE * 512, GFP_KERNEL); 66 if (!idb_tag) 67 return SFC_OK; 68 69 if (sfc_get_version() >= SFC_VER_4) 70 snor_read(p_dev, IDB_ALIGN_32, NOR_SECS_PAGE, 71 idb_tag); 72 else 73 snor_read(p_dev, IDB_ALIGN_64, NOR_SECS_PAGE, 74 idb_tag); 75 packet = (struct snor_info_packet *)&idb_tag->dev_param[0]; 76 if (idb_tag->id == IDB_BLOCK_TAG_ID) { 77 P_RC4((u8 *)idb_tag, sizeof(struct id_block_tag)); 78 snor_reinit_from_table_packet(p_dev, packet); 79 rkflash_print_error("snor reinit, ret= %d\n", ret); 80 } 81 kfree(idb_tag); 82 } 83 84 return ret; 85 } 86 87 u32 rksfc_nor_get_capacity(struct udevice *udev) 88 { 89 struct rkflash_info *priv = dev_get_priv(udev); 90 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 91 92 return snor_get_capacity(p_dev); 93 } 94 95 int rksfc_nor_read(struct udevice *udev, u32 sec, u32 n_sec, void *p_data) 96 { 97 u32 ret; 98 u32 offset, count = 0; 99 char *buf = (char *)p_data; 100 struct rkflash_info *priv = dev_get_priv(udev); 101 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 102 103 if (sec + n_sec - 1 < FLASH_VENDOR_PART_START || 104 sec > FLASH_VENDOR_PART_END) { 105 ret = snor_read(p_dev, sec, n_sec, p_data); 106 if (ret != n_sec) 107 return ret; 108 } else { 109 memset(p_data, 0, 512 * n_sec); 110 if (sec < FLASH_VENDOR_PART_START) { 111 count = FLASH_VENDOR_PART_START - sec; 112 buf = (char *)p_data; 113 ret = snor_read(p_dev, sec, count, buf); 114 if (ret != count) 115 return ret; 116 } 117 if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) { 118 count = sec + n_sec - 1 - FLASH_VENDOR_PART_END; 119 offset = FLASH_VENDOR_PART_END - sec + 1; 120 buf = (char *)p_data + offset * 512; 121 ret = snor_read(p_dev, 122 FLASH_VENDOR_PART_END + 1, 123 count, buf); 124 if (ret != count) 125 return ret; 126 } 127 } 128 129 return n_sec; 130 } 131 132 /* Workaround for GPT not aligned program */ 133 int rksfc_nor_simply_over_write(struct udevice *udev, 134 u32 sec, 135 u32 n_sec, 136 const void *p_data) 137 { 138 struct rkflash_info *priv = dev_get_priv(udev); 139 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 140 u8 *pbuf_temp; 141 u32 addr_aligned, offset, remain; 142 143 addr_aligned = sec / NOR_SECS_PAGE * NOR_SECS_PAGE; 144 offset = sec - addr_aligned; 145 remain = (offset + n_sec + NOR_SECS_PAGE - 1) / NOR_SECS_PAGE * NOR_SECS_PAGE; 146 147 pbuf_temp = malloc(remain * 512); 148 snor_read(p_dev, addr_aligned, remain, pbuf_temp); 149 memcpy(pbuf_temp + offset * 512, p_data, n_sec * 512); 150 snor_write(p_dev, addr_aligned, remain, pbuf_temp); 151 free(pbuf_temp); 152 153 return n_sec; 154 } 155 156 int rksfc_nor_write(struct udevice *udev, 157 u32 sec, 158 u32 n_sec, 159 const void *p_data) 160 { 161 u32 ret; 162 u32 offset, count = 0; 163 char *buf = (char *)p_data; 164 struct rkflash_info *priv = dev_get_priv(udev); 165 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 166 u32 sfc_nor_density = rksfc_nor_get_capacity(udev); 167 168 if (sec >= (sfc_nor_density - 33)) 169 return rksfc_nor_simply_over_write(udev, sec, n_sec, p_data); 170 171 if (sec + n_sec - 1 < FLASH_VENDOR_PART_START || 172 sec > FLASH_VENDOR_PART_END) { 173 ret = snor_write(p_dev, sec, n_sec, (void *)p_data); 174 if (ret != n_sec) 175 return ret; 176 } else { 177 if (sec < FLASH_VENDOR_PART_START) { 178 count = FLASH_VENDOR_PART_START - sec; 179 buf = (char *)p_data; 180 ret = snor_write(p_dev, sec, count, buf); 181 if (ret != count) 182 return ret; 183 } 184 if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) { 185 count = sec + n_sec - 1 - FLASH_VENDOR_PART_END; 186 offset = FLASH_VENDOR_PART_END - sec + 1; 187 buf = (char *)p_data + offset * 512; 188 ret = snor_write(p_dev, 189 FLASH_VENDOR_PART_END + 1, 190 count, buf); 191 if (ret != count) 192 return ret; 193 } 194 } 195 196 return n_sec; 197 } 198 199 int rksfc_nor_vendor_read(struct blk_desc *dev_desc, 200 u32 sec, 201 u32 n_sec, 202 void *p_data) 203 { 204 struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent); 205 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 206 207 return snor_read(p_dev, sec, n_sec, p_data); 208 } 209 210 int rksfc_nor_vendor_write(struct blk_desc *dev_desc, 211 u32 sec, 212 u32 n_sec, 213 void *p_data) 214 { 215 struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent); 216 struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 217 218 return snor_write(p_dev, sec, n_sec, p_data); 219 } 220 221 #endif 222 223 #ifdef CONFIG_RKSFC_NAND 224 int rksfc_nand_init(struct udevice *udev) 225 { 226 int ret; 227 228 ret = sfc_nand_init(); 229 if (ret) { 230 return ret; 231 } else { 232 sfc_nand_ftl_ops_init(); 233 234 return sftl_init(); 235 } 236 } 237 238 int rksfc_nand_read(struct udevice *udev, u32 index, u32 count, void *buf) 239 { 240 int ret; 241 242 ret = sftl_read(index, count, (u8 *)buf); 243 if (!ret) 244 return count; 245 else 246 return -EIO; 247 } 248 249 int rksfc_nand_write(struct udevice *udev, 250 u32 index, 251 u32 count, 252 const void *buf) 253 { 254 int ret; 255 256 ret = sftl_write(index, count, (u8 *)buf); 257 if (!ret) 258 return count; 259 else 260 return -EIO; 261 } 262 263 u32 rksfc_nand_get_density(struct udevice *udev) 264 { 265 return sftl_get_density(); 266 } 267 268 int rksfc_nand_vendor_read(struct blk_desc *dev_desc, 269 u32 sec, 270 u32 n_sec, 271 void *p_data) 272 { 273 int ret; 274 275 ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data); 276 if (!ret) 277 return n_sec; 278 else 279 return -EIO; 280 } 281 282 int rksfc_nand_vendor_write(struct blk_desc *dev_desc, 283 u32 sec, 284 u32 n_sec, 285 void *p_data) 286 { 287 int ret; 288 289 ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data); 290 if (!ret) 291 return n_sec; 292 else 293 return -EIO; 294 } 295 296 #endif 297 298 #ifdef CONFIG_RKNANDC_NAND 299 int rknand_flash_init(struct udevice *udev) 300 { 301 return sftl_init(); 302 } 303 304 int rknand_flash_read(struct udevice *udev, u32 index, u32 count, void *buf) 305 { 306 int ret; 307 308 ret = sftl_read(index, count, (u8 *)buf); 309 if (!ret) 310 return count; 311 else 312 return -EIO; 313 } 314 315 int rknand_flash_write(struct udevice *udev, 316 u32 index, 317 u32 count, 318 const void *buf) 319 { 320 int ret; 321 322 ret = sftl_write(index, count, (u8 *)buf); 323 if (!ret) 324 return count; 325 else 326 return -EIO; 327 } 328 329 u32 rknand_flash_get_density(struct udevice *udev) 330 { 331 return sftl_get_density(); 332 } 333 334 int rknand_flash_vendor_read(struct blk_desc *dev_desc, 335 u32 sec, 336 u32 n_sec, 337 void *p_data) 338 { 339 int ret; 340 341 ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data); 342 if (!ret) 343 return n_sec; 344 else 345 return -EIO; 346 } 347 348 int rknand_flash_vendor_write(struct blk_desc *dev_desc, 349 u32 sec, 350 u32 n_sec, 351 void *p_data) 352 { 353 int ret; 354 355 ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data); 356 if (!ret) 357 return n_sec; 358 else 359 return -EIO; 360 } 361 362 #endif 363