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 <linux/bug.h> 9 #include <linux/delay.h> 10 11 #include "flash_com.h" 12 #include "rkflash_debug.h" 13 #include "rk_sftl.h" 14 #include "sfc.h" 15 #include "sfc_nand.h" 16 17 static u32 sfc_nand_get_ecc_status0(void); 18 static u32 sfc_nand_get_ecc_status1(void); 19 static u32 sfc_nand_get_ecc_status2(void); 20 static u32 sfc_nand_get_ecc_status3(void); 21 static u32 sfc_nand_get_ecc_status4(void); 22 static u32 sfc_nand_get_ecc_status5(void); 23 static u32 sfc_nand_get_ecc_status6(void); 24 static u32 sfc_nand_get_ecc_status7(void); 25 static u32 sfc_nand_get_ecc_status8(void); 26 static u32 sfc_nand_get_ecc_status9(void); 27 28 static struct nand_info spi_nand_tbl[] = { 29 /* TC58CVG0S0HxAIx */ 30 { 0x98, 0xC2, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 31 /* TC58CVG1S0HxAIx */ 32 { 0x98, 0xCB, 0x00, 4, 0x40, 2, 1024, 0x00, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 33 /* TC58CVG2S0HRAIJ */ 34 { 0x98, 0xED, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 0, { 0x04, 0x0C, 0x08, 0x10 }, &sfc_nand_get_ecc_status0 }, 35 /* TC58CVG1S3HRAIJ */ 36 { 0x98, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 37 /* TC58CVG0S3HRAIJ */ 38 { 0x98, 0xE2, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 39 40 /* MX35LF1GE4AB */ 41 { 0xC2, 0x12, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 42 /* MX35LF2GE4AB */ 43 { 0xC2, 0x22, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 44 /* MX35LF2GE4AD */ 45 { 0xC2, 0x26, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 46 /* MX35LF4GE4AD */ 47 { 0xC2, 0x37, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 }, 48 /* MX35UF1GE4AC */ 49 { 0xC2, 0x92, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 50 /* MX35UF2GE4AC */ 51 { 0xC2, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 52 /* MX35UF1GE4AD */ 53 { 0xC2, 0x96, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 54 /* MX35UF2GE4AD */ 55 { 0xC2, 0xA6, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 56 /* MX35UF4GE4AD */ 57 { 0xC2, 0xB7, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 }, 58 59 /* GD5F1GQ4UAYIG */ 60 { 0xC8, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 61 /* GD5F1GQ4RB9IGR */ 62 { 0xC8, 0xD1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 63 /* GD5F2GQ40BY2GR */ 64 { 0xC8, 0xD2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 65 /* GD5F1GQ5UEYIG */ 66 { 0xC8, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 67 /* GD5F2GQ5UEYIG */ 68 { 0xC8, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 69 /* GD5F1GQ4R */ 70 { 0xC8, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 71 /* GD5F4GQ6RExxG 1*4096 */ 72 { 0xC8, 0x45, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status2 }, 73 /* GD5F4GQ6UExxG 1*4096 */ 74 { 0xC8, 0x55, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status2 }, 75 /* GD5F1GQ4UExxH */ 76 { 0xC8, 0xD9, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 77 /* GD5F1GQ5REYIG Add 3rd code to distingush with F50L2G41KA */ 78 { 0xC8, 0x41, 0xC8, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 79 /* GD5F2GQ5REYIG */ 80 { 0xC8, 0x42, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 81 /* GD5F2GM7RxG */ 82 { 0xC8, 0x82, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 83 /* GD5F2GM7UxG */ 84 { 0xC8, 0x92, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 85 /* GD5F1GM7UxG */ 86 { 0xC8, 0x91, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 87 /* GD5F4GQ4UAYIG 1*4096 */ 88 { 0xC8, 0xF4, 0x00, 4, 0x40, 2, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 }, 89 /* GD5F1GM7REYIGR */ 90 { 0xC8, 0x81, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 91 /* GD5F4GM8UEYIGR */ 92 { 0xC8, 0x95, 0x00, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 93 94 /* W25N01GV */ 95 { 0xEF, 0xAA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 96 /* W25N02KVZEIR */ 97 { 0xEF, 0xAA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 }, 98 /* W25N04KVZEIR */ 99 { 0xEF, 0xAA, 0x23, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 0, { 0x04, 0x14, 0x24, 0x34 }, &sfc_nand_get_ecc_status0 }, 100 /* W25N01GW */ 101 { 0xEF, 0xBA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 102 /* W25N02KW */ 103 { 0xEF, 0xBA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 }, 104 /* W25N512GVEIG */ 105 { 0xEF, 0xAA, 0x20, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 106 /* W25N01KV */ 107 { 0xEF, 0xAE, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 108 109 /* HYF2GQ4UAACAE */ 110 { 0xC9, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 111 /* HYF1GQ4UDACAE */ 112 { 0xC9, 0x21, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 113 /* HYF1GQ4UPACAE */ 114 { 0xC9, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 115 /* HYF2GQ4UDACAE */ 116 { 0xC9, 0x22, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 117 /* HYF2GQ4UHCCAE */ 118 { 0xC9, 0x5A, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 119 /* HYF4GQ4UAACBE */ 120 { 0xC9, 0xD4, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0xE, 1, { 0x20, 0x40, 0x24, 0x44 }, &sfc_nand_get_ecc_status0 }, 121 /* HYF2GQ4IAACAE */ 122 { 0xC9, 0x82, 0x00, 4, 0x40, 1, 2048, 0x4C, 20, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 123 /* HYF1GQ4IDACAE */ 124 { 0xC9, 0x81, 0x00, 4, 0x40, 1, 1024, 0x4C, 20, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 125 126 /* FS35ND01G-S1 */ 127 { 0xCD, 0xB1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 128 /* FS35ND02G-S2 */ 129 { 0xCD, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x00, 19, 0x4, 0, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 130 /* FS35ND01G-S1Y2 */ 131 { 0xCD, 0xEA, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 132 /* FS35ND02G-S3Y2 */ 133 { 0xCD, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 134 /* FS35ND04G-S2Y2 1*4096 */ 135 { 0xCD, 0xEC, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 136 /* F35SQA001G */ 137 { 0xCD, 0x71, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 138 /* F35SQA002G */ 139 { 0xCD, 0x72, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 140 /* F35SQA512M */ 141 { 0xCD, 0x70, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 142 /* F35UQA512M */ 143 { 0xCD, 0x60, 0x00, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 144 /* F35UQA002G-WWT */ 145 { 0xCD, 0x62, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 146 /* F35UQA001G-WWT */ 147 { 0xCD, 0x61, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 148 149 /* DS35Q1GA-IB */ 150 { 0xE5, 0x71, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 151 /* DS35Q2GA-IB */ 152 { 0xE5, 0x72, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 153 /* DS35M1GA-1B */ 154 { 0xE5, 0x21, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 155 /* DS35M2GA-IB */ 156 { 0xE5, 0x22, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 157 /* DS35Q1GB-IB */ 158 { 0xE5, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 159 /* DS35Q2GB-IB */ 160 { 0xE5, 0xF2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 161 /* DS35Q4GM */ 162 { 0xE5, 0xF4, 0x00, 4, 0x40, 2, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 163 /* DS35M1GB-IB */ 164 { 0xE5, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 165 /* DS35Q12B-IB */ 166 { 0xE5, 0xF5, 0x00, 4, 0x40, 1, 512, 0x0C, 17, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 167 /* DS35M12B-IB */ 168 { 0xE5, 0xA5, 0x00, 4, 0x40, 1, 512, 0x0C, 17, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 169 /* DS35Q1GD-IB */ 170 { 0xE5, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 171 172 /* EM73C044VCC-H */ 173 { 0xD5, 0x22, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 174 /* EM73D044VCE-H */ 175 { 0xD5, 0x20, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 176 /* EM73E044SNA-G */ 177 { 0xD5, 0x03, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x28, 0x08, 0x2C }, &sfc_nand_get_ecc_status0 }, 178 /* EM73C044VCF-H */ 179 { 0xD5, 0x25, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 180 181 /* XT26G02A */ 182 { 0x0B, 0xE2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 183 /* XT26G01A */ 184 { 0x0B, 0xE1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 185 /* XT26G04A */ 186 { 0x0B, 0xE3, 0x00, 4, 0x80, 1, 2048, 0x4C, 20, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 187 /* XT26G01B */ 188 { 0x0B, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 189 /* XT26G02B */ 190 { 0x0B, 0xF2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 191 /* XT26G01C */ 192 { 0x0B, 0x11, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 }, 193 /* XT26G02C */ 194 { 0x0B, 0x12, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 }, 195 /* XT26G04C */ 196 { 0x0B, 0x13, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status7 }, 197 /* XT26G11C */ 198 { 0x0B, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 199 /* XT26Q02DWSIGA */ 200 { 0x0B, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 201 /* XT26Q01DWSIGA */ 202 { 0x0B, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 203 /* XT26Q04DWSIGA */ 204 { 0x0B, 0x53, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 }, 205 /* XT26G01DWSIGA */ 206 { 0x0B, 0x31, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 207 /* XT26G02DWSIGA */ 208 { 0x0B, 0x32, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 209 /* XT26G04DWSIGA */ 210 { 0x0B, 0x33, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status0 }, 211 212 /* MT29F2G01ABA, XT26G02E, F50L2G41XA */ 213 { 0x2C, 0x24, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 214 /* MT29F1G01ABA, F50L1G41XA */ 215 { 0x2C, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 216 217 /* FM25S01 */ 218 { 0xA1, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x00, 0x04, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 219 /* FM25S01A */ 220 { 0xA1, 0xE4, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 221 /* FM25S02A */ 222 { 0xA1, 0xE5, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 223 /* FM25LS01 */ 224 { 0xA1, 0xA5, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 225 /* FM25S01BI3 */ 226 { 0xA1, 0xD4, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 227 /* FM25G02BI3 */ 228 { 0xA1, 0xD2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 229 230 /* IS37SML01G1 */ 231 { 0xC8, 0x21, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x1, 0, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 232 /* F50L1G41LB */ 233 { 0xC8, 0x01, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 234 /* F50L2G41KA */ 235 { 0xC8, 0x41, 0x7F, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 236 237 /* UM19A1HISW */ 238 { 0xB0, 0x24, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 239 /* UM19A0HCSW */ 240 { 0xB0, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 241 /* UM19A0LCSW */ 242 { 0xB0, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 243 /* UM19A1LISW */ 244 { 0xB0, 0x25, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 245 246 /* ATO25D1GA */ 247 { 0x9B, 0x12, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x1, 1, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 248 /* BWJX08K-2Gb */ 249 { 0xBC, 0xB3, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x10, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 250 /* JS28U1GQSCAHG-83 */ 251 { 0xBF, 0x21, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 }, 252 /* SGM7000I-S24W1GH */ 253 { 0xEA, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 254 /* TX25G01 */ 255 { 0xA1, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 }, 256 257 /* S35ML01G3, ANV1GCP0CLG, HYF1GQ4UTXCAE, YX25G1E */ 258 { 0x01, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status9 }, 259 /* S35ML02G3, ANV2GCP0CLG, HYF2GQ4UTXCAE, YX25G2E */ 260 { 0x01, 0x25, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status9 }, 261 /* S35ML04G3 */ 262 { 0x01, 0x35, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 0, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status9 }, 263 264 /* GSS01GSAK1 */ 265 { 0x52, 0xBA, 0x13, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 266 /* GSS02GSAK1 */ 267 { 0x52, 0xBA, 0x23, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 268 269 /* XCSP2AAPK */ 270 { 0x8C, 0xA1, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 271 /* XCSP1AAPK */ 272 { 0x8C, 0x01, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 273 }; 274 275 static struct nand_info *p_nand_info; 276 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4]; 277 static struct SFNAND_DEV sfc_nand_dev; 278 279 static struct nand_info *sfc_nand_get_info(u8 *nand_id) 280 { 281 u32 i; 282 283 for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) { 284 if (spi_nand_tbl[i].id0 == nand_id[0] && 285 spi_nand_tbl[i].id1 == nand_id[1]) { 286 if (spi_nand_tbl[i].id2 && 287 spi_nand_tbl[i].id2 != nand_id[2]) 288 continue; 289 290 return &spi_nand_tbl[i]; 291 } 292 } 293 294 return NULL; 295 } 296 297 static int sfc_nand_write_en(void) 298 { 299 int ret; 300 struct rk_sfc_op op; 301 302 op.sfcmd.d32 = 0; 303 op.sfcmd.b.cmd = CMD_WRITE_EN; 304 305 op.sfctrl.d32 = 0; 306 307 ret = sfc_request(&op, 0, NULL, 0); 308 return ret; 309 } 310 311 static int sfc_nand_rw_preset(void) 312 { 313 int ret; 314 struct rk_sfc_op op; 315 316 op.sfcmd.d32 = 0; 317 op.sfcmd.b.cmd = 0xff; 318 op.sfcmd.b.cs = 2; 319 320 op.sfctrl.d32 = 0; 321 op.sfctrl.b.datalines = 2; 322 op.sfctrl.b.cmdlines = 2; 323 op.sfctrl.b.addrlines = 2; 324 325 ret = sfc_request(&op, 0, NULL, 0); 326 return ret; 327 } 328 329 static int sfc_nand_read_feature(u8 addr, u8 *data) 330 { 331 int ret; 332 struct rk_sfc_op op; 333 334 op.sfcmd.d32 = 0; 335 op.sfcmd.b.cmd = 0x0F; 336 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 337 338 op.sfctrl.d32 = 0; 339 op.sfctrl.b.addrbits = 8; 340 341 *data = 0; 342 343 ret = sfc_request(&op, addr, data, 1); 344 345 if (ret != SFC_OK) 346 return ret; 347 348 return SFC_OK; 349 } 350 351 static int sfc_nand_write_feature(u32 addr, u8 status) 352 { 353 int ret; 354 struct rk_sfc_op op; 355 356 sfc_nand_write_en(); 357 358 op.sfcmd.d32 = 0; 359 op.sfcmd.b.cmd = 0x1F; 360 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 361 op.sfcmd.b.rw = SFC_WRITE; 362 363 op.sfctrl.d32 = 0; 364 op.sfctrl.b.addrbits = 8; 365 366 ret = sfc_request(&op, addr, &status, 1); 367 368 if (ret != SFC_OK) 369 return ret; 370 371 return ret; 372 } 373 374 static int sfc_nand_wait_busy(u8 *data, int timeout) 375 { 376 int ret; 377 int i; 378 u8 status; 379 380 *data = 0; 381 382 for (i = 0; i < timeout; i++) { 383 ret = sfc_nand_read_feature(0xC0, &status); 384 385 if (ret != SFC_OK) 386 return ret; 387 388 *data = status; 389 390 if (!(status & (1 << 0))) 391 return SFC_OK; 392 393 sfc_delay(1); 394 } 395 396 return SFC_NAND_WAIT_TIME_OUT; 397 } 398 399 /* 400 * ecc default: 401 * ecc bits: 0xC0[4,5] 402 * 0b00, No bit errors were detected 403 * 0b01, Bit errors were detected and corrected. 404 * 0b10, Multiple bit errors were detected and not corrected. 405 * 0b11, Bits errors were detected and corrected, bit error count 406 * reach the bit flip detection threshold 407 */ 408 static u32 sfc_nand_get_ecc_status0(void) 409 { 410 u32 ret; 411 u32 i; 412 u8 ecc; 413 u8 status; 414 u32 timeout = 1000 * 1000; 415 416 for (i = 0; i < timeout; i++) { 417 ret = sfc_nand_read_feature(0xC0, &status); 418 419 if (ret != SFC_OK) 420 return SFC_NAND_ECC_ERROR; 421 422 if (!(status & (1 << 0))) 423 break; 424 425 sfc_delay(1); 426 } 427 428 ecc = (status >> 4) & 0x03; 429 430 if (ecc <= 1) 431 ret = SFC_NAND_ECC_OK; 432 else if (ecc == 2) 433 ret = (u32)SFC_NAND_ECC_ERROR; 434 else 435 ret = SFC_NAND_ECC_REFRESH; 436 437 return ret; 438 } 439 440 /* 441 * ecc spectial type1: 442 * ecc bits: 0xC0[4,5] 443 * 0b00, No bit errors were detected; 444 * 0b01, Bits errors were detected and corrected, bit error count 445 * may reach the bit flip detection threshold; 446 * 0b10, Multiple bit errors were detected and not corrected; 447 * 0b11, Reserved. 448 */ 449 static u32 sfc_nand_get_ecc_status1(void) 450 { 451 u32 ret; 452 u32 i; 453 u8 ecc; 454 u8 status; 455 u32 timeout = 1000 * 1000; 456 457 for (i = 0; i < timeout; i++) { 458 ret = sfc_nand_read_feature(0xC0, &status); 459 460 if (ret != SFC_OK) 461 return SFC_NAND_ECC_ERROR; 462 463 if (!(status & (1 << 0))) 464 break; 465 466 sfc_delay(1); 467 } 468 469 ecc = (status >> 4) & 0x03; 470 471 if (ecc == 0) 472 ret = SFC_NAND_ECC_OK; 473 else if (ecc == 1) 474 ret = SFC_NAND_ECC_REFRESH; 475 else 476 ret = (u32)SFC_NAND_ECC_ERROR; 477 478 return ret; 479 } 480 481 /* 482 * ecc spectial type2: 483 * ecc bits: 0xC0[4,5] 0xF0[4,5] 484 * [0b0000, 0b0011], No bit errors were detected; 485 * [0b0100, 0b0111], Bit errors were detected and corrected. Not 486 * reach Flipping Bits; 487 * [0b1000, 0b1011], Multiple bit errors were detected and 488 * not corrected. 489 * [0b1100, 0b1111], reserved. 490 */ 491 static u32 sfc_nand_get_ecc_status2(void) 492 { 493 u32 ret; 494 u32 i; 495 u8 ecc; 496 u8 status, status1; 497 u32 timeout = 1000 * 1000; 498 499 for (i = 0; i < timeout; i++) { 500 ret = sfc_nand_read_feature(0xC0, &status); 501 502 if (ret != SFC_OK) 503 return SFC_NAND_ECC_ERROR; 504 505 ret = sfc_nand_read_feature(0xF0, &status1); 506 507 if (ret != SFC_OK) 508 return SFC_NAND_ECC_ERROR; 509 510 if (!(status & (1 << 0))) 511 break; 512 513 sfc_delay(1); 514 } 515 516 ecc = (status >> 4) & 0x03; 517 ecc = (ecc << 2) | ((status1 >> 4) & 0x03); 518 519 if (ecc < 7) 520 ret = SFC_NAND_ECC_OK; 521 else if (ecc == 7) 522 ret = SFC_NAND_ECC_REFRESH; 523 else 524 ret = (u32)SFC_NAND_ECC_ERROR; 525 526 return ret; 527 } 528 529 /* 530 * ecc spectial type3: 531 * ecc bits: 0xC0[4,5] 0xF0[4,5] 532 * [0b0000, 0b0011], No bit errors were detected; 533 * [0b0100, 0b0111], Bit errors were detected and corrected. Not 534 * reach Flipping Bits; 535 * [0b1000, 0b1011], Multiple bit errors were detected and 536 * not corrected. 537 * [0b1100, 0b1111], Bit error count equals the bit flip 538 * detectio nthreshold 539 */ 540 static u32 sfc_nand_get_ecc_status3(void) 541 { 542 u32 ret; 543 u32 i; 544 u8 ecc; 545 u8 status, status1; 546 u32 timeout = 1000 * 1000; 547 548 for (i = 0; i < timeout; i++) { 549 ret = sfc_nand_read_feature(0xC0, &status); 550 551 if (ret != SFC_OK) 552 return SFC_NAND_ECC_ERROR; 553 554 ret = sfc_nand_read_feature(0xF0, &status1); 555 556 if (ret != SFC_OK) 557 return SFC_NAND_ECC_ERROR; 558 559 if (!(status & (1 << 0))) 560 break; 561 562 sfc_delay(1); 563 } 564 565 ecc = (status >> 4) & 0x03; 566 ecc = (ecc << 2) | ((status1 >> 4) & 0x03); 567 568 if (ecc < 7) 569 ret = SFC_NAND_ECC_OK; 570 else if (ecc == 7 || ecc >= 12) 571 ret = SFC_NAND_ECC_REFRESH; 572 else 573 ret = (u32)SFC_NAND_ECC_ERROR; 574 575 return ret; 576 } 577 578 /* 579 * ecc spectial type4: 580 * ecc bits: 0xC0[2,5] 581 * [0b0000], No bit errors were detected; 582 * [0b0001, 0b0111], Bit errors were detected and corrected. Not 583 * reach Flipping Bits; 584 * [0b1000], Multiple bit errors were detected and 585 * not corrected. 586 * [0b1100], Bit error count equals the bit flip 587 * detection threshold 588 * else, reserved 589 */ 590 static u32 sfc_nand_get_ecc_status4(void) 591 { 592 u32 ret; 593 u32 i; 594 u8 ecc; 595 u8 status; 596 u32 timeout = 1000 * 1000; 597 598 for (i = 0; i < timeout; i++) { 599 ret = sfc_nand_read_feature(0xC0, &status); 600 601 if (ret != SFC_OK) 602 return SFC_NAND_ECC_ERROR; 603 604 if (!(status & (1 << 0))) 605 break; 606 607 sfc_delay(1); 608 } 609 610 ecc = (status >> 2) & 0x0f; 611 612 if (ecc < 7) 613 ret = SFC_NAND_ECC_OK; 614 else if (ecc == 7 || ecc == 12) 615 ret = SFC_NAND_ECC_REFRESH; 616 else 617 ret = (u32)SFC_NAND_ECC_ERROR; 618 619 return ret; 620 } 621 622 /* 623 * ecc spectial type5: 624 * ecc bits: 0xC0[4,6] 625 * [0b000], No bit errors were detected; 626 * [0b001, 0b011], Bit errors were detected and corrected. Not 627 * reach Flipping Bits; 628 * [0b100], Bit error count equals the bit flip 629 * detection threshold 630 * [0b101, 0b110], Reserved; 631 * [0b111], Multiple bit errors were detected and 632 * not corrected. 633 */ 634 static u32 sfc_nand_get_ecc_status5(void) 635 { 636 u32 ret; 637 u32 i; 638 u8 ecc; 639 u8 status; 640 u32 timeout = 1000 * 1000; 641 642 for (i = 0; i < timeout; i++) { 643 ret = sfc_nand_read_feature(0xC0, &status); 644 645 if (ret != SFC_OK) 646 return SFC_NAND_ECC_ERROR; 647 648 if (!(status & (1 << 0))) 649 break; 650 651 sfc_delay(1); 652 } 653 654 ecc = (status >> 4) & 0x07; 655 656 if (ecc < 4) 657 ret = SFC_NAND_ECC_OK; 658 else if (ecc == 4) 659 ret = SFC_NAND_ECC_REFRESH; 660 else 661 ret = (u32)SFC_NAND_ECC_ERROR; 662 663 return ret; 664 } 665 666 /* 667 * ecc spectial type6: 668 * ecc bits: 0xC0[4,6] 669 * [0b000], No bit errors were detected; 670 * [0b001], 1-3 Bit errors were detected and corrected. Not 671 * reach Flipping Bits; 672 * [0b010], Multiple bit errors were detected and 673 * not corrected. 674 * [0b011], 4-6 Bit errors were detected and corrected. Not 675 * reach Flipping Bits; 676 * [0b101], Bit error count equals the bit flip 677 * detectionthreshold 678 * others, Reserved. 679 */ 680 static u32 sfc_nand_get_ecc_status6(void) 681 { 682 u32 ret; 683 u32 i; 684 u8 ecc; 685 u8 status; 686 u32 timeout = 1000 * 1000; 687 688 for (i = 0; i < timeout; i++) { 689 ret = sfc_nand_read_feature(0xC0, &status); 690 691 if (ret != SFC_OK) 692 return SFC_NAND_ECC_ERROR; 693 694 if (!(status & (1 << 0))) 695 break; 696 697 sfc_delay(1); 698 } 699 700 ecc = (status >> 4) & 0x07; 701 702 if (ecc == 0 || ecc == 1 || ecc == 3) 703 ret = SFC_NAND_ECC_OK; 704 else if (ecc == 5) 705 ret = SFC_NAND_ECC_REFRESH; 706 else 707 ret = (u32)SFC_NAND_ECC_ERROR; 708 709 return ret; 710 } 711 712 /* 713 * ecc spectial type7: 714 * ecc bits: 0xC0[4,7] 715 * [0b0000], No bit errors were detected; 716 * [0b0001, 0b0111], 1-7 Bit errors were detected and corrected. Not 717 * reach Flipping Bits; 718 * [0b1000], 8 Bit errors were detected and corrected. Bit error count 719 * equals the bit flip detectionthreshold; 720 * [0b1111], Bit errors greater than ECC capability(8 bits) and not corrected; 721 * others, Reserved. 722 */ 723 static u32 sfc_nand_get_ecc_status7(void) 724 { 725 u32 ret; 726 u32 i; 727 u8 ecc; 728 u8 status; 729 u32 timeout = 1000 * 1000; 730 731 for (i = 0; i < timeout; i++) { 732 ret = sfc_nand_read_feature(0xC0, &status); 733 734 if (ret != SFC_OK) 735 return SFC_NAND_ECC_ERROR; 736 737 if (!(status & (1 << 0))) 738 break; 739 740 sfc_delay(1); 741 } 742 743 ecc = (status >> 4) & 0xf; 744 745 if (ecc < 7) 746 ret = SFC_NAND_ECC_OK; 747 else if (ecc == 7 || ecc == 8) 748 ret = SFC_NAND_ECC_REFRESH; 749 else 750 ret = (u32)SFC_NAND_ECC_ERROR; 751 752 return ret; 753 } 754 755 /* 756 * ecc spectial type8: 757 * ecc bits: 0xC0[4,6] 758 * [0b000], No bit errors were detected; 759 * [0b001, 0b011], 1~3 Bit errors were detected and corrected. Not 760 * reach Flipping Bits; 761 * [0b100], Bit error count equals the bit flip 762 * detection threshold 763 * others, Reserved. 764 */ 765 static u32 sfc_nand_get_ecc_status8(void) 766 { 767 u32 ret; 768 u32 i; 769 u8 ecc; 770 u8 status; 771 u32 timeout = 1000 * 1000; 772 773 for (i = 0; i < timeout; i++) { 774 ret = sfc_nand_read_feature(0xC0, &status); 775 776 if (ret != SFC_OK) 777 return SFC_NAND_ECC_ERROR; 778 779 if (!(status & (1 << 0))) 780 break; 781 782 sfc_delay(1); 783 } 784 785 ecc = (status >> 4) & 0x07; 786 787 if (ecc < 4) 788 ret = SFC_NAND_ECC_OK; 789 else if (ecc == 4) 790 ret = SFC_NAND_ECC_REFRESH; 791 else 792 ret = (u32)SFC_NAND_ECC_ERROR; 793 794 return ret; 795 } 796 797 /* 798 * ecc spectial type9: 799 * ecc bits: 0xC0[4,5] 800 * 0b00, No bit errors were detected 801 * 0b01, 1-2Bit errors were detected and corrected. 802 * 0b10, 3-4Bit errors were detected and corrected. 803 * 0b11, 11 can be used as uncorrectable 804 */ 805 static u32 sfc_nand_get_ecc_status9(void) 806 { 807 u32 ret; 808 u32 i; 809 u8 ecc; 810 u8 status; 811 u32 timeout = 1000 * 1000; 812 813 for (i = 0; i < timeout; i++) { 814 ret = sfc_nand_read_feature(0xC0, &status); 815 816 if (ret != SFC_OK) 817 return SFC_NAND_ECC_ERROR; 818 819 if (!(status & (1 << 0))) 820 break; 821 822 sfc_delay(1); 823 } 824 825 ecc = (status >> 4) & 0x03; 826 827 if (ecc <= 1) 828 ret = SFC_NAND_ECC_OK; 829 else if (ecc == 2) 830 ret = SFC_NAND_ECC_REFRESH; 831 else 832 ret = (u32)SFC_NAND_ECC_ERROR; 833 834 return ret; 835 } 836 837 u32 sfc_nand_erase_block(u8 cs, u32 addr) 838 { 839 int ret; 840 struct rk_sfc_op op; 841 u8 status; 842 843 rkflash_print_dio("%s %x\n", __func__, addr); 844 op.sfcmd.d32 = 0; 845 op.sfcmd.b.cmd = 0xd8; 846 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 847 op.sfcmd.b.rw = SFC_WRITE; 848 849 op.sfctrl.d32 = 0; 850 851 sfc_nand_write_en(); 852 ret = sfc_request(&op, addr, NULL, 0); 853 854 if (ret != SFC_OK) 855 return ret; 856 857 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 858 859 if (status & (1 << 2)) 860 return SFC_NAND_PROG_ERASE_ERROR; 861 862 return ret; 863 } 864 865 static u32 sfc_nand_read_cache(u32 row, u32 *p_page_buf, u32 column, u32 len) 866 { 867 int ret; 868 u32 plane; 869 struct rk_sfc_op op; 870 871 op.sfcmd.d32 = 0; 872 op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; 873 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 874 op.sfcmd.b.dummybits = 8; 875 876 op.sfctrl.d32 = 0; 877 op.sfctrl.b.datalines = sfc_nand_dev.read_lines; 878 op.sfctrl.b.addrbits = 16; 879 880 plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0; 881 882 ret = sfc_request(&op, plane | column, p_page_buf, len); 883 if (ret != SFC_OK) 884 return SFC_NAND_HW_ERROR; 885 886 return ret; 887 } 888 889 u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) 890 { 891 int ret; 892 u32 plane; 893 struct rk_sfc_op op; 894 u8 status; 895 u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; 896 u32 data_area_size = SFC_NAND_SECTOR_SIZE * p_nand_info->sec_per_page; 897 898 rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]); 899 sfc_nand_write_en(); 900 901 if (sfc_nand_dev.prog_lines == DATA_LINES_X4 && 902 p_nand_info->feature & FEA_SOFT_QOP_BIT && 903 sfc_get_version() < SFC_VER_3) 904 sfc_nand_rw_preset(); 905 906 op.sfcmd.d32 = 0; 907 op.sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; 908 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 909 op.sfcmd.b.rw = SFC_WRITE; 910 911 op.sfctrl.d32 = 0; 912 op.sfctrl.b.datalines = sfc_nand_dev.prog_lines; 913 op.sfctrl.b.addrbits = 16; 914 plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0; 915 sfc_request(&op, plane, p_page_buf, page_size); 916 917 /* 918 * At the moment of power lost or dev running in harsh environment, flash 919 * maybe work in a unkonw state and result in bit flip, when this situation 920 * is detected by cache recheck, it's better to wait a second for a reliable 921 * hardware environment to avoid abnormal data written to flash array. 922 */ 923 if (p_nand_info->id0 == MID_GIGADEV) { 924 sfc_nand_read_cache(addr, (u32 *)sfc_nand_dev.recheck_buffer, 0, data_area_size); 925 if (memcmp(sfc_nand_dev.recheck_buffer, p_page_buf, data_area_size)) { 926 rkflash_print_error("%s %x cache bitflip\n", __func__, addr); 927 mdelay(1000); 928 sfc_request(&op, plane, p_page_buf, page_size); 929 } 930 } 931 932 op.sfcmd.d32 = 0; 933 op.sfcmd.b.cmd = 0x10; 934 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 935 op.sfcmd.b.rw = SFC_WRITE; 936 937 op.sfctrl.d32 = 0; 938 ret = sfc_request(&op, addr, p_page_buf, 0); 939 940 if (ret != SFC_OK) 941 return ret; 942 943 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 944 if (status & (1 << 3)) 945 return SFC_NAND_PROG_ERASE_ERROR; 946 947 return ret; 948 } 949 950 u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 951 { 952 int ret; 953 u32 sec_per_page = p_nand_info->sec_per_page; 954 u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; 955 struct nand_mega_area *meta = &p_nand_info->meta; 956 957 memcpy(gp_page_buf, p_data, data_size); 958 memset(&gp_page_buf[data_size / 4], 0xff, sec_per_page * 16); 959 gp_page_buf[(data_size + meta->off0) / 4] = p_spare[0]; 960 gp_page_buf[(data_size + meta->off1) / 4] = p_spare[1]; 961 962 if (sec_per_page == 8) { 963 gp_page_buf[(data_size + meta->off2) / 4] = p_spare[2]; 964 gp_page_buf[(data_size + meta->off3) / 4] = p_spare[3]; 965 } 966 967 ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf); 968 969 return ret; 970 } 971 972 u32 sfc_nand_read(u32 row, u32 *p_page_buf, u32 column, u32 len) 973 { 974 int ret; 975 u32 plane; 976 struct rk_sfc_op op; 977 u32 ecc_result; 978 u8 status; 979 980 op.sfcmd.d32 = 0; 981 op.sfcmd.b.cmd = 0x13; 982 op.sfcmd.b.rw = SFC_WRITE; 983 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 984 985 op.sfctrl.d32 = 0; 986 987 sfc_request(&op, row, p_page_buf, 0); 988 989 if (sfc_nand_dev.read_lines == DATA_LINES_X4 && 990 p_nand_info->feature & FEA_SOFT_QOP_BIT && 991 sfc_get_version() < SFC_VER_3) 992 sfc_nand_rw_preset(); 993 994 sfc_nand_wait_busy(&status, 1000 * 1000); 995 if (sfc_nand_dev.manufacturer == 0x01 && status) 996 sfc_nand_wait_busy(&status, 1000 * 1000); 997 998 ecc_result = p_nand_info->ecc_status(); 999 1000 op.sfcmd.d32 = 0; 1001 op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; 1002 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 1003 op.sfcmd.b.dummybits = 8; 1004 1005 op.sfctrl.d32 = 0; 1006 op.sfctrl.b.datalines = sfc_nand_dev.read_lines; 1007 op.sfctrl.b.addrbits = 16; 1008 1009 plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0; 1010 ret = sfc_request(&op, plane | column, p_page_buf, len); 1011 rkflash_print_dio("%s %x %x\n", __func__, row, p_page_buf[0]); 1012 1013 if (ret != SFC_OK) 1014 return SFC_NAND_HW_ERROR; 1015 1016 return ecc_result; 1017 } 1018 1019 u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf) 1020 { 1021 u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; 1022 1023 return sfc_nand_read(addr, p_page_buf, 0, page_size); 1024 } 1025 1026 u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 1027 { 1028 u32 ret; 1029 u32 sec_per_page = p_nand_info->sec_per_page; 1030 u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; 1031 struct nand_mega_area *meta = &p_nand_info->meta; 1032 1033 ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); 1034 memcpy(p_data, gp_page_buf, data_size); 1035 p_spare[0] = gp_page_buf[(data_size + meta->off0) / 4]; 1036 p_spare[1] = gp_page_buf[(data_size + meta->off1) / 4]; 1037 1038 if (p_nand_info->sec_per_page == 8) { 1039 p_spare[2] = gp_page_buf[(data_size + meta->off2) / 4]; 1040 p_spare[3] = gp_page_buf[(data_size + meta->off3) / 4]; 1041 } 1042 1043 if (ret == SFC_NAND_HW_ERROR) 1044 ret = SFC_NAND_ECC_ERROR; 1045 1046 if (ret != SFC_NAND_ECC_OK) { 1047 rkflash_print_error("%s[0x%x], ret=0x%x\n", __func__, addr, ret); 1048 1049 if (p_data) 1050 rkflash_print_hex("data:", p_data, 4, 8); 1051 1052 if (p_spare) 1053 rkflash_print_hex("spare:", p_spare, 4, 2); 1054 } 1055 1056 return ret; 1057 } 1058 1059 u32 sfc_nand_check_bad_block(u8 cs, u32 addr) 1060 { 1061 u32 ret; 1062 u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE; 1063 u32 marker = 0; 1064 1065 ret = sfc_nand_read(addr, &marker, data_size, 2); 1066 1067 /* unify with mtd framework */ 1068 if (ret == SFC_NAND_ECC_ERROR || (u16)marker != 0xffff) 1069 rkflash_print_error("%s page= %x ret= %x spare= %x\n", 1070 __func__, addr, ret, marker); 1071 1072 /* Original bad block */ 1073 if ((u16)marker != 0xffff) 1074 return true; 1075 1076 return false; 1077 } 1078 1079 u32 sfc_nand_mark_bad_block(u8 cs, u32 addr) 1080 { 1081 u32 ret; 1082 u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE; 1083 1084 ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); 1085 1086 if (ret) 1087 return SFC_NAND_HW_ERROR; 1088 1089 gp_page_buf[data_size / 4] = 0x0; 1090 ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf); 1091 1092 if (ret) 1093 return SFC_NAND_HW_ERROR; 1094 1095 return ret; 1096 } 1097 1098 int sfc_nand_read_id(u8 *data) 1099 { 1100 int ret; 1101 struct rk_sfc_op op; 1102 1103 op.sfcmd.d32 = 0; 1104 op.sfcmd.b.cmd = CMD_READ_JEDECID; 1105 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 1106 1107 op.sfctrl.d32 = 0; 1108 op.sfctrl.b.addrbits = 8; 1109 1110 ret = sfc_request(&op, 0, data, 3); 1111 1112 return ret; 1113 } 1114 1115 /* 1116 * Read the 1st page's 1st byte of a phy_blk 1117 * If not FF, it's bad blk 1118 */ 1119 static int sfc_nand_get_bad_block_list(u16 *table, u32 die) 1120 { 1121 u32 bad_cnt, page; 1122 u32 blk_per_die; 1123 u16 blk; 1124 1125 rkflash_print_info("%s\n", __func__); 1126 1127 bad_cnt = 0; 1128 blk_per_die = p_nand_info->plane_per_die * 1129 p_nand_info->blk_per_plane; 1130 1131 for (blk = 0; blk < blk_per_die; blk++) { 1132 page = (blk + blk_per_die * die) * 1133 p_nand_info->page_per_blk; 1134 1135 if (sfc_nand_check_bad_block(die, page)) { 1136 table[bad_cnt++] = blk; 1137 rkflash_print_error("die[%d], bad_blk[%d]\n", die, blk); 1138 } 1139 } 1140 1141 return (int)bad_cnt; 1142 } 1143 1144 void sfc_nand_ftl_ops_init(void) 1145 { 1146 /* para init */ 1147 g_nand_phy_info.nand_type = 1; 1148 g_nand_phy_info.die_num = 1; 1149 g_nand_phy_info.plane_per_die = p_nand_info->plane_per_die; 1150 g_nand_phy_info.blk_per_plane = p_nand_info->blk_per_plane; 1151 g_nand_phy_info.page_per_blk = p_nand_info->page_per_blk; 1152 g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk; 1153 g_nand_phy_info.byte_per_sec = SFC_NAND_SECTOR_SIZE; 1154 g_nand_phy_info.sec_per_page = p_nand_info->sec_per_page; 1155 g_nand_phy_info.sec_per_blk = p_nand_info->sec_per_page * 1156 p_nand_info->page_per_blk; 1157 g_nand_phy_info.reserved_blk = 8; 1158 g_nand_phy_info.blk_per_die = p_nand_info->plane_per_die * 1159 p_nand_info->blk_per_plane; 1160 g_nand_phy_info.ecc_bits = p_nand_info->max_ecc_bits; 1161 1162 /* driver register */ 1163 g_nand_ops.get_bad_blk_list = sfc_nand_get_bad_block_list; 1164 g_nand_ops.erase_blk = sfc_nand_erase_block; 1165 g_nand_ops.prog_page = sfc_nand_prog_page; 1166 g_nand_ops.read_page = sfc_nand_read_page; 1167 g_nand_ops.bch_sel = NULL; 1168 } 1169 1170 static int sfc_nand_enable_QE(void) 1171 { 1172 int ret = SFC_OK; 1173 u8 status; 1174 1175 ret = sfc_nand_read_feature(0xB0, &status); 1176 1177 if (ret != SFC_OK) 1178 return ret; 1179 1180 if (status & 1) /* is QE bit set */ 1181 return SFC_OK; 1182 1183 status |= 1; 1184 1185 return sfc_nand_write_feature(0xB0, status); 1186 } 1187 1188 u32 sfc_nand_init(void) 1189 { 1190 u8 status, id_byte[8]; 1191 1192 sfc_nand_read_id(id_byte); 1193 rkflash_print_error("sfc_nand id: %x %x %x\n", 1194 id_byte[0], id_byte[1], id_byte[2]); 1195 1196 if (id_byte[0] == 0xFF || id_byte[0] == 0x00) 1197 return (u32)FTL_NO_FLASH; 1198 1199 p_nand_info = sfc_nand_get_info(id_byte); 1200 1201 if (!p_nand_info) { 1202 pr_err("The device not support yet!\n"); 1203 1204 return (u32)FTL_UNSUPPORTED_FLASH; 1205 } 1206 1207 sfc_nand_dev.manufacturer = id_byte[0]; 1208 sfc_nand_dev.mem_type = id_byte[1]; 1209 sfc_nand_dev.capacity = p_nand_info->density; 1210 sfc_nand_dev.block_size = p_nand_info->page_per_blk * p_nand_info->sec_per_page; 1211 sfc_nand_dev.page_size = p_nand_info->sec_per_page; 1212 1213 /* disable block lock */ 1214 sfc_nand_write_feature(0xA0, 0); 1215 sfc_nand_dev.read_lines = DATA_LINES_X1; 1216 sfc_nand_dev.prog_lines = DATA_LINES_X1; 1217 sfc_nand_dev.page_read_cmd = 0x03; 1218 sfc_nand_dev.page_prog_cmd = 0x02; 1219 sfc_nand_dev.recheck_buffer = ftl_malloc(SFC_NAND_PAGE_MAX_SIZE); 1220 if (!sfc_nand_dev.recheck_buffer) { 1221 rkflash_print_error("%s recheck_buffer alloc failed\n", __func__); 1222 return -1; 1223 } 1224 1225 if (p_nand_info->feature & FEA_4BIT_READ) { 1226 if ((p_nand_info->has_qe_bits && sfc_nand_enable_QE() == SFC_OK) || 1227 !p_nand_info->has_qe_bits) { 1228 sfc_nand_dev.read_lines = DATA_LINES_X4; 1229 sfc_nand_dev.page_read_cmd = 0x6b; 1230 } 1231 } 1232 1233 if (p_nand_info->feature & FEA_4BIT_PROG && 1234 sfc_nand_dev.read_lines == DATA_LINES_X4) { 1235 sfc_nand_dev.prog_lines = DATA_LINES_X4; 1236 sfc_nand_dev.page_prog_cmd = 0x32; 1237 } 1238 1239 sfc_nand_read_feature(0xA0, &status); 1240 rkflash_print_info("sfc_nand A0 = 0x%x\n", status); 1241 sfc_nand_read_feature(0xB0, &status); 1242 rkflash_print_info("sfc_nand B0 = 0x%x\n", status); 1243 rkflash_print_info("read_lines = %x\n", sfc_nand_dev.read_lines); 1244 rkflash_print_info("prog_lines = %x\n", sfc_nand_dev.prog_lines); 1245 rkflash_print_info("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd); 1246 rkflash_print_info("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd); 1247 1248 return SFC_OK; 1249 } 1250 1251 void sfc_nand_deinit(void) 1252 { 1253 /* to-do */ 1254 kfree(sfc_nand_dev.recheck_buffer); 1255 } 1256 1257 struct SFNAND_DEV *sfc_nand_get_private_dev(void) 1258 { 1259 return &sfc_nand_dev; 1260 } 1261 1262