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