diff options
author | Brian Norris <computersforpeace@gmail.com> | 2012-09-24 23:40:50 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-09-29 10:57:38 -0400 |
commit | fc09bbc04ccd7f069c1928a0156968b888393833 (patch) | |
tree | 75d7b13a28849caf125cb7cdf82f291dff716907 /drivers/mtd | |
parent | 7e74c2d7141e8929049233e28c74cd089f6ae962 (diff) |
mtd: nand: split extended ID decoding into its own function
When detecting NAND parameters, the code gets a little ugly so that the
logic is obscured. Try to remedy that by moving code to separate functions
that have well-defined purposes.
This patch splits out the extended ID decode functionality, which handles
decoding the 3rd-8th ID bytes to determine NAND device parameters.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 122 |
1 files changed, 67 insertions, 55 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 16bb17f93997..e017af02da1c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2906,6 +2906,71 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
2906 | } | 2906 | } |
2907 | 2907 | ||
2908 | /* | 2908 | /* |
2909 | * Many new NAND share similar device ID codes, which represent the size of the | ||
2910 | * chip. The rest of the parameters must be decoded according to generic or | ||
2911 | * manufacturer-specific "extended ID" decoding patterns. | ||
2912 | */ | ||
2913 | static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, | ||
2914 | u8 id_data[8], int *busw) | ||
2915 | { | ||
2916 | int extid; | ||
2917 | /* The 3rd id byte holds MLC / multichip data */ | ||
2918 | chip->cellinfo = id_data[2]; | ||
2919 | /* The 4th id byte is the important one */ | ||
2920 | extid = id_data[3]; | ||
2921 | |||
2922 | /* | ||
2923 | * Field definitions are in the following datasheets: | ||
2924 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) | ||
2925 | * New style (6 byte ID): Samsung K9GBG08U0M (p.40) | ||
2926 | * | ||
2927 | * Check for wraparound + Samsung ID + nonzero 6th byte | ||
2928 | * to decide what to do. | ||
2929 | */ | ||
2930 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && | ||
2931 | id_data[0] == NAND_MFR_SAMSUNG && | ||
2932 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
2933 | id_data[5] != 0x00) { | ||
2934 | /* Calc pagesize */ | ||
2935 | mtd->writesize = 2048 << (extid & 0x03); | ||
2936 | extid >>= 2; | ||
2937 | /* Calc oobsize */ | ||
2938 | switch (extid & 0x03) { | ||
2939 | case 1: | ||
2940 | mtd->oobsize = 128; | ||
2941 | break; | ||
2942 | case 2: | ||
2943 | mtd->oobsize = 218; | ||
2944 | break; | ||
2945 | case 3: | ||
2946 | mtd->oobsize = 400; | ||
2947 | break; | ||
2948 | default: | ||
2949 | mtd->oobsize = 436; | ||
2950 | break; | ||
2951 | } | ||
2952 | extid >>= 2; | ||
2953 | /* Calc blocksize */ | ||
2954 | mtd->erasesize = (128 * 1024) << | ||
2955 | (((extid >> 1) & 0x04) | (extid & 0x03)); | ||
2956 | *busw = 0; | ||
2957 | } else { | ||
2958 | /* Calc pagesize */ | ||
2959 | mtd->writesize = 1024 << (extid & 0x03); | ||
2960 | extid >>= 2; | ||
2961 | /* Calc oobsize */ | ||
2962 | mtd->oobsize = (8 << (extid & 0x01)) * | ||
2963 | (mtd->writesize >> 9); | ||
2964 | extid >>= 2; | ||
2965 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | ||
2966 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | ||
2967 | extid >>= 2; | ||
2968 | /* Get buswidth information */ | ||
2969 | *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | ||
2970 | } | ||
2971 | } | ||
2972 | |||
2973 | /* | ||
2909 | * Set the bad block marker/indicator (BBM/BBI) patterns according to some | 2974 | * Set the bad block marker/indicator (BBM/BBI) patterns according to some |
2910 | * heuristic patterns using various detected parameters (e.g., manufacturer, | 2975 | * heuristic patterns using various detected parameters (e.g., manufacturer, |
2911 | * page size, cell-type information). | 2976 | * page size, cell-type information). |
@@ -3016,61 +3081,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3016 | /* Set the pagesize, oobsize, erasesize by the driver */ | 3081 | /* Set the pagesize, oobsize, erasesize by the driver */ |
3017 | busw = chip->init_size(mtd, chip, id_data); | 3082 | busw = chip->init_size(mtd, chip, id_data); |
3018 | } else if (!type->pagesize) { | 3083 | } else if (!type->pagesize) { |
3019 | int extid; | 3084 | /* Decode parameters from extended ID */ |
3020 | /* The 3rd id byte holds MLC / multichip data */ | 3085 | nand_decode_ext_id(mtd, chip, id_data, &busw); |
3021 | chip->cellinfo = id_data[2]; | ||
3022 | /* The 4th id byte is the important one */ | ||
3023 | extid = id_data[3]; | ||
3024 | |||
3025 | /* | ||
3026 | * Field definitions are in the following datasheets: | ||
3027 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) | ||
3028 | * New style (6 byte ID): Samsung K9GBG08U0M (p.40) | ||
3029 | * | ||
3030 | * Check for wraparound + Samsung ID + nonzero 6th byte | ||
3031 | * to decide what to do. | ||
3032 | */ | ||
3033 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && | ||
3034 | id_data[0] == NAND_MFR_SAMSUNG && | ||
3035 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
3036 | id_data[5] != 0x00) { | ||
3037 | /* Calc pagesize */ | ||
3038 | mtd->writesize = 2048 << (extid & 0x03); | ||
3039 | extid >>= 2; | ||
3040 | /* Calc oobsize */ | ||
3041 | switch (extid & 0x03) { | ||
3042 | case 1: | ||
3043 | mtd->oobsize = 128; | ||
3044 | break; | ||
3045 | case 2: | ||
3046 | mtd->oobsize = 218; | ||
3047 | break; | ||
3048 | case 3: | ||
3049 | mtd->oobsize = 400; | ||
3050 | break; | ||
3051 | default: | ||
3052 | mtd->oobsize = 436; | ||
3053 | break; | ||
3054 | } | ||
3055 | extid >>= 2; | ||
3056 | /* Calc blocksize */ | ||
3057 | mtd->erasesize = (128 * 1024) << | ||
3058 | (((extid >> 1) & 0x04) | (extid & 0x03)); | ||
3059 | busw = 0; | ||
3060 | } else { | ||
3061 | /* Calc pagesize */ | ||
3062 | mtd->writesize = 1024 << (extid & 0x03); | ||
3063 | extid >>= 2; | ||
3064 | /* Calc oobsize */ | ||
3065 | mtd->oobsize = (8 << (extid & 0x01)) * | ||
3066 | (mtd->writesize >> 9); | ||
3067 | extid >>= 2; | ||
3068 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | ||
3069 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | ||
3070 | extid >>= 2; | ||
3071 | /* Get buswidth information */ | ||
3072 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | ||
3073 | } | ||
3074 | } else { | 3086 | } else { |
3075 | /* | 3087 | /* |
3076 | * Old devices have chip data hardcoded in the device id table. | 3088 | * Old devices have chip data hardcoded in the device id table. |