diff options
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 164 |
1 files changed, 134 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) |