diff options
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 164 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 68 |
2 files changed, 202 insertions, 30 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 596ac848b46d..5b26fffc3534 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2787,14 +2787,46 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) | |||
2787 | } | 2787 | } |
2788 | 2788 | ||
2789 | /* | 2789 | /* |
2790 | * sanitize ONFI strings so we can safely print them | ||
2791 | */ | ||
2792 | static void sanitize_string(uint8_t *s, size_t len) | ||
2793 | { | ||
2794 | ssize_t i; | ||
2795 | |||
2796 | /* null terminate */ | ||
2797 | s[len - 1] = 0; | ||
2798 | |||
2799 | /* remove non printable chars */ | ||
2800 | for (i = 0; i < len - 1; i++) { | ||
2801 | if (s[i] < ' ' || s[i] > 127) | ||
2802 | s[i] = '?'; | ||
2803 | } | ||
2804 | |||
2805 | /* remove trailing spaces */ | ||
2806 | strim(s); | ||
2807 | } | ||
2808 | |||
2809 | static u16 onfi_crc16(u16 crc, u8 const *p, size_t len) | ||
2810 | { | ||
2811 | int i; | ||
2812 | while (len--) { | ||
2813 | crc ^= *p++ << 8; | ||
2814 | for (i = 0; i < 8; i++) | ||
2815 | crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); | ||
2816 | } | ||
2817 | |||
2818 | return crc; | ||
2819 | } | ||
2820 | |||
2821 | /* | ||
2790 | * Get the flash and manufacturer id and lookup if the type is supported | 2822 | * Get the flash and manufacturer id and lookup if the type is supported |
2791 | */ | 2823 | */ |
2792 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | 2824 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, |
2793 | struct nand_chip *chip, | 2825 | struct nand_chip *chip, |
2794 | int busw, int *maf_id, | 2826 | int busw, int *maf_id, int *dev_id, |
2795 | struct nand_flash_dev *type) | 2827 | struct nand_flash_dev *type) |
2796 | { | 2828 | { |
2797 | int i, dev_id, maf_idx; | 2829 | int i, maf_idx; |
2798 | u8 id_data[8]; | 2830 | u8 id_data[8]; |
2799 | 2831 | ||
2800 | /* Select the device */ | 2832 | /* Select the device */ |
@@ -2811,7 +2843,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2811 | 2843 | ||
2812 | /* Read manufacturer and device IDs */ | 2844 | /* Read manufacturer and device IDs */ |
2813 | *maf_id = chip->read_byte(mtd); | 2845 | *maf_id = chip->read_byte(mtd); |
2814 | dev_id = chip->read_byte(mtd); | 2846 | *dev_id = chip->read_byte(mtd); |
2815 | 2847 | ||
2816 | /* Try again to make sure, as some systems the bus-hold or other | 2848 | /* Try again to make sure, as some systems the bus-hold or other |
2817 | * interface concerns can cause random data which looks like a | 2849 | * interface concerns can cause random data which looks like a |
@@ -2821,15 +2853,13 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2821 | 2853 | ||
2822 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2854 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2823 | 2855 | ||
2824 | /* Read entire ID string */ | 2856 | for (i = 0; i < 2; i++) |
2825 | |||
2826 | for (i = 0; i < 8; i++) | ||
2827 | id_data[i] = chip->read_byte(mtd); | 2857 | id_data[i] = chip->read_byte(mtd); |
2828 | 2858 | ||
2829 | if (id_data[0] != *maf_id || id_data[1] != dev_id) { | 2859 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { |
2830 | printk(KERN_INFO "%s: second ID read did not match " | 2860 | printk(KERN_INFO "%s: second ID read did not match " |
2831 | "%02x,%02x against %02x,%02x\n", __func__, | 2861 | "%02x,%02x against %02x,%02x\n", __func__, |
2832 | *maf_id, dev_id, id_data[0], id_data[1]); | 2862 | *maf_id, *dev_id, id_data[0], id_data[1]); |
2833 | return ERR_PTR(-ENODEV); | 2863 | return ERR_PTR(-ENODEV); |
2834 | } | 2864 | } |
2835 | 2865 | ||
@@ -2837,9 +2867,81 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2837 | type = nand_flash_ids; | 2867 | type = nand_flash_ids; |
2838 | 2868 | ||
2839 | for (; type->name != NULL; type++) | 2869 | for (; type->name != NULL; type++) |
2840 | if (dev_id == type->id) | 2870 | if (*dev_id == type->id) |
2841 | break; | 2871 | break; |
2842 | 2872 | ||
2873 | chip->onfi_version = 0; | ||
2874 | if (!type->name || !type->pagesize) { | ||
2875 | /* try ONFI for unknow chip or LP */ | ||
2876 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); | ||
2877 | if (chip->read_byte(mtd) == 'O' && | ||
2878 | chip->read_byte(mtd) == 'N' && | ||
2879 | chip->read_byte(mtd) == 'F' && | ||
2880 | chip->read_byte(mtd) == 'I') { | ||
2881 | |||
2882 | struct nand_onfi_params *p = &chip->onfi_params; | ||
2883 | int i; | ||
2884 | |||
2885 | printk(KERN_INFO "ONFI flash detected\n"); | ||
2886 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); | ||
2887 | for (i = 0; i < 3; i++) { | ||
2888 | chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); | ||
2889 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == | ||
2890 | le16_to_cpu(p->crc)) | ||
2891 | { | ||
2892 | printk(KERN_INFO "ONFI param page %d valid\n", i); | ||
2893 | break; | ||
2894 | } | ||
2895 | } | ||
2896 | |||
2897 | if (i < 3) { | ||
2898 | /* check version */ | ||
2899 | int val = le16_to_cpu(p->revision); | ||
2900 | if (val == 1 || val > (1 << 4)) | ||
2901 | printk(KERN_INFO "%s: unsupported ONFI version: %d\n", | ||
2902 | __func__, val); | ||
2903 | else { | ||
2904 | if (val & (1 << 4)) | ||
2905 | chip->onfi_version = 22; | ||
2906 | else if (val & (1 << 3)) | ||
2907 | chip->onfi_version = 21; | ||
2908 | else if (val & (1 << 2)) | ||
2909 | chip->onfi_version = 20; | ||
2910 | else | ||
2911 | chip->onfi_version = 10; | ||
2912 | } | ||
2913 | } | ||
2914 | |||
2915 | if (chip->onfi_version) { | ||
2916 | sanitize_string(p->manufacturer, sizeof(p->manufacturer)); | ||
2917 | sanitize_string(p->model, sizeof(p->model)); | ||
2918 | if (!mtd->name) | ||
2919 | mtd->name = p->model; | ||
2920 | mtd->writesize = le32_to_cpu(p->byte_per_page); | ||
2921 | mtd->erasesize = le32_to_cpu(p->pages_per_block)*mtd->writesize; | ||
2922 | mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); | ||
2923 | chip->chipsize = le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; | ||
2924 | busw = 0; | ||
2925 | if (le16_to_cpu(p->features) & 1) | ||
2926 | busw = NAND_BUSWIDTH_16; | ||
2927 | |||
2928 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2929 | chip->options |= (NAND_NO_READRDY | | ||
2930 | NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; | ||
2931 | |||
2932 | goto ident_done; | ||
2933 | |||
2934 | } | ||
2935 | } | ||
2936 | } | ||
2937 | |||
2938 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | ||
2939 | |||
2940 | /* Read entire ID string */ | ||
2941 | |||
2942 | for (i = 0; i < 8; i++) | ||
2943 | id_data[i] = chip->read_byte(mtd); | ||
2944 | |||
2843 | if (!type->name) | 2945 | if (!type->name) |
2844 | return ERR_PTR(-ENODEV); | 2946 | return ERR_PTR(-ENODEV); |
2845 | 2947 | ||
@@ -2927,6 +3029,21 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2927 | mtd->erasesize <<= ((id_data[3] & 0x03) << 1); | 3029 | mtd->erasesize <<= ((id_data[3] & 0x03) << 1); |
2928 | } | 3030 | } |
2929 | } | 3031 | } |
3032 | /* Get chip options, preserve non chip based options */ | ||
3033 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
3034 | chip->options |= type->options & NAND_CHIPOPTIONS_MSK; | ||
3035 | |||
3036 | /* Check if chip is a not a samsung device. Do not clear the | ||
3037 | * options for chips which are not having an extended id. | ||
3038 | */ | ||
3039 | if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) | ||
3040 | chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
3041 | ident_done: | ||
3042 | |||
3043 | /* | ||
3044 | * Set chip as a default. Board drivers can override it, if necessary | ||
3045 | */ | ||
3046 | chip->options |= NAND_NO_AUTOINCR; | ||
2930 | 3047 | ||
2931 | /* Try to identify manufacturer */ | 3048 | /* Try to identify manufacturer */ |
2932 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { | 3049 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { |
@@ -2941,7 +3058,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2941 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { | 3058 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { |
2942 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 3059 | printk(KERN_INFO "NAND device: Manufacturer ID:" |
2943 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, | 3060 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, |
2944 | dev_id, nand_manuf_ids[maf_idx].name, mtd->name); | 3061 | *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); |
2945 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", | 3062 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", |
2946 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, | 3063 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, |
2947 | busw ? 16 : 8); | 3064 | busw ? 16 : 8); |
@@ -2966,21 +3083,6 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2966 | else | 3083 | else |
2967 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | 3084 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; |
2968 | 3085 | ||
2969 | /* Get chip options, preserve non chip based options */ | ||
2970 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2971 | chip->options |= type->options & NAND_CHIPOPTIONS_MSK; | ||
2972 | |||
2973 | /* | ||
2974 | * Set chip as a default. Board drivers can override it, if necessary | ||
2975 | */ | ||
2976 | chip->options |= NAND_NO_AUTOINCR; | ||
2977 | |||
2978 | /* Check if chip is a not a samsung device. Do not clear the | ||
2979 | * options for chips which are not having an extended id. | ||
2980 | */ | ||
2981 | if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) | ||
2982 | chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2983 | |||
2984 | /* | 3086 | /* |
2985 | * Bad block marker is stored in the last page of each block | 3087 | * Bad block marker is stored in the last page of each block |
2986 | * on Samsung and Hynix MLC devices; stored in first two pages | 3088 | * on Samsung and Hynix MLC devices; stored in first two pages |
@@ -3021,9 +3123,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3021 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) | 3123 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) |
3022 | chip->cmdfunc = nand_command_lp; | 3124 | chip->cmdfunc = nand_command_lp; |
3023 | 3125 | ||
3126 | /* TODO onfi flash name */ | ||
3024 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 3127 | printk(KERN_INFO "NAND device: Manufacturer ID:" |
3025 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, | 3128 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, |
3026 | nand_manuf_ids[maf_idx].name, type->name); | 3129 | nand_manuf_ids[maf_idx].name, |
3130 | chip->onfi_version ? type->name:chip->onfi_params.model); | ||
3027 | 3131 | ||
3028 | return type; | 3132 | return type; |
3029 | } | 3133 | } |
@@ -3042,7 +3146,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3042 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, | 3146 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, |
3043 | struct nand_flash_dev *table) | 3147 | struct nand_flash_dev *table) |
3044 | { | 3148 | { |
3045 | int i, busw, nand_maf_id; | 3149 | int i, busw, nand_maf_id, nand_dev_id; |
3046 | struct nand_chip *chip = mtd->priv; | 3150 | struct nand_chip *chip = mtd->priv; |
3047 | struct nand_flash_dev *type; | 3151 | struct nand_flash_dev *type; |
3048 | 3152 | ||
@@ -3052,7 +3156,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3052 | nand_set_defaults(chip, busw); | 3156 | nand_set_defaults(chip, busw); |
3053 | 3157 | ||
3054 | /* Read the flash type */ | 3158 | /* Read the flash type */ |
3055 | type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, table); | 3159 | type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table); |
3056 | 3160 | ||
3057 | if (IS_ERR(type)) { | 3161 | if (IS_ERR(type)) { |
3058 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) | 3162 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) |
@@ -3070,7 +3174,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3070 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 3174 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
3071 | /* Read manufacturer and device IDs */ | 3175 | /* Read manufacturer and device IDs */ |
3072 | if (nand_maf_id != chip->read_byte(mtd) || | 3176 | if (nand_maf_id != chip->read_byte(mtd) || |
3073 | type->id != chip->read_byte(mtd)) | 3177 | nand_dev_id != chip->read_byte(mtd)) |
3074 | break; | 3178 | break; |
3075 | } | 3179 | } |
3076 | if (i > 1) | 3180 | if (i > 1) |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 29656a3f9331..7666c42235c7 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -228,6 +228,69 @@ typedef enum { | |||
228 | /* Keep gcc happy */ | 228 | /* Keep gcc happy */ |
229 | struct nand_chip; | 229 | struct nand_chip; |
230 | 230 | ||
231 | struct nand_onfi_params { | ||
232 | /* rev info and features block */ | ||
233 | u8 sig[4]; /* 'O' 'N' 'F' 'I' */ | ||
234 | __le16 revision; | ||
235 | __le16 features; | ||
236 | __le16 opt_cmd; | ||
237 | u8 reserved[22]; | ||
238 | |||
239 | /* manufacturer information block */ | ||
240 | char manufacturer[12]; | ||
241 | char model[20]; | ||
242 | u8 jedec_id; | ||
243 | __le16 date_code; | ||
244 | u8 reserved2[13]; | ||
245 | |||
246 | /* memory organization block */ | ||
247 | __le32 byte_per_page; | ||
248 | __le16 spare_bytes_per_page; | ||
249 | __le32 data_bytes_per_ppage; | ||
250 | __le16 spare_bytes_per_ppage; | ||
251 | __le32 pages_per_block; | ||
252 | __le32 blocks_per_lun; | ||
253 | u8 lun_count; | ||
254 | u8 addr_cycles; | ||
255 | u8 bits_per_cell; | ||
256 | __le16 bb_per_lun; | ||
257 | __le16 block_endurance; | ||
258 | u8 guaranteed_good_blocks; | ||
259 | __le16 guaranteed_block_endurance; | ||
260 | u8 programs_per_page; | ||
261 | u8 ppage_attr; | ||
262 | u8 ecc_bits; | ||
263 | u8 interleaved_bits; | ||
264 | u8 interleaved_ops; | ||
265 | u8 reserved3[13]; | ||
266 | |||
267 | /* electrical parameter block */ | ||
268 | u8 io_pin_capacitance_max; | ||
269 | __le16 async_timing_mode; | ||
270 | __le16 program_cache_timing_mode; | ||
271 | __le16 t_prog; | ||
272 | __le16 t_bers; | ||
273 | __le16 t_r; | ||
274 | __le16 t_ccs; | ||
275 | __le16 src_sync_timing_mode; | ||
276 | __le16 src_ssync_features; | ||
277 | __le16 clk_pin_capacitance_typ; | ||
278 | __le16 io_pin_capacitance_typ; | ||
279 | __le16 input_pin_capacitance_typ; | ||
280 | u8 input_pin_capacitance_max; | ||
281 | u8 driver_strenght_support; | ||
282 | __le16 t_int_r; | ||
283 | __le16 t_ald; | ||
284 | u8 reserved4[7]; | ||
285 | |||
286 | /* vendor */ | ||
287 | u8 reserved5[90]; | ||
288 | |||
289 | __le16 crc; | ||
290 | } __attribute__((packed)); | ||
291 | |||
292 | #define ONFI_CRC_BASE 0x4F4E | ||
293 | |||
231 | /** | 294 | /** |
232 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices | 295 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices |
233 | * @lock: protection lock | 296 | * @lock: protection lock |
@@ -360,6 +423,8 @@ struct nand_buffers { | |||
360 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 | 423 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 |
361 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf | 424 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf |
362 | * @subpagesize: [INTERN] holds the subpagesize | 425 | * @subpagesize: [INTERN] holds the subpagesize |
426 | * @onfi_version: [INTERN] holds the chip ONFI version (BCD encoded), non 0 if ONFI supported | ||
427 | * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is supported, 0 otherwise | ||
363 | * @ecclayout: [REPLACEABLE] the default ecc placement scheme | 428 | * @ecclayout: [REPLACEABLE] the default ecc placement scheme |
364 | * @bbt: [INTERN] bad block table pointer | 429 | * @bbt: [INTERN] bad block table pointer |
365 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup | 430 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup |
@@ -412,6 +477,9 @@ struct nand_chip { | |||
412 | int badblockpos; | 477 | int badblockpos; |
413 | int badblockbits; | 478 | int badblockbits; |
414 | 479 | ||
480 | int onfi_version; | ||
481 | struct nand_onfi_params onfi_params; | ||
482 | |||
415 | flstate_t state; | 483 | flstate_t state; |
416 | 484 | ||
417 | uint8_t *oob_poi; | 485 | uint8_t *oob_poi; |