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