diff options
author | Sukumar Ghorai <s-ghorai@ti.com> | 2011-01-28 05:12:09 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-02-17 18:32:55 -0500 |
commit | f040d33253b2daf6f305fc35fca2399047ced028 (patch) | |
tree | 09accb3434f740a07780f9b3df6a4020cff84cfb /drivers/mtd | |
parent | f3d73f362d689a1d044e77964864f0a8ea0217f3 (diff) |
omap3: nand: making ecc layout as compatible with romcode ecc
This patch overrides nand ecc layout and bad block descriptor (for 8-bit
device) to support hw ecc in romcode layout. So as to have in sync with ecc
layout throughout; i.e. x-loader, u-boot and kernel.
This enables to flash x-loader, u-boot, kernel, FS images from kernel itself
and compatiable with other tools.
This patch does not enables this feature by default and need to pass from
board file to enable for any board.
Signed-off-by: Vimal Singh <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/omap2.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d4a42e39380..4e33972ad17a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -98,6 +98,20 @@ | |||
98 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 98 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | /* oob info generated runtime depending on ecc algorithm and layout selected */ | ||
102 | static struct nand_ecclayout omap_oobinfo; | ||
103 | /* Define some generic bad / good block scan pattern which are used | ||
104 | * while scanning a device for factory marked good / bad blocks | ||
105 | */ | ||
106 | static uint8_t scan_ff_pattern[] = { 0xff }; | ||
107 | static struct nand_bbt_descr bb_descrip_flashbased = { | ||
108 | .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, | ||
109 | .offs = 0, | ||
110 | .len = 1, | ||
111 | .pattern = scan_ff_pattern, | ||
112 | }; | ||
113 | |||
114 | |||
101 | struct omap_nand_info { | 115 | struct omap_nand_info { |
102 | struct nand_hw_control controller; | 116 | struct nand_hw_control controller; |
103 | struct omap_nand_platform_data *pdata; | 117 | struct omap_nand_platform_data *pdata; |
@@ -914,6 +928,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
914 | struct omap_nand_info *info; | 928 | struct omap_nand_info *info; |
915 | struct omap_nand_platform_data *pdata; | 929 | struct omap_nand_platform_data *pdata; |
916 | int err; | 930 | int err; |
931 | int i, offset; | ||
917 | 932 | ||
918 | pdata = pdev->dev.platform_data; | 933 | pdata = pdev->dev.platform_data; |
919 | if (pdata == NULL) { | 934 | if (pdata == NULL) { |
@@ -1037,7 +1052,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1037 | /* selsect the ecc type */ | 1052 | /* selsect the ecc type */ |
1038 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) | 1053 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) |
1039 | info->nand.ecc.mode = NAND_ECC_SOFT; | 1054 | info->nand.ecc.mode = NAND_ECC_SOFT; |
1040 | else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { | 1055 | else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || |
1056 | (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { | ||
1041 | info->nand.ecc.bytes = 3; | 1057 | info->nand.ecc.bytes = 3; |
1042 | info->nand.ecc.size = 512; | 1058 | info->nand.ecc.size = 512; |
1043 | info->nand.ecc.calculate = omap_calculate_ecc; | 1059 | info->nand.ecc.calculate = omap_calculate_ecc; |
@@ -1057,6 +1073,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1057 | } | 1073 | } |
1058 | } | 1074 | } |
1059 | 1075 | ||
1076 | /* rom code layout */ | ||
1077 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { | ||
1078 | |||
1079 | if (info->nand.options & NAND_BUSWIDTH_16) | ||
1080 | offset = 2; | ||
1081 | else { | ||
1082 | offset = 1; | ||
1083 | info->nand.badblock_pattern = &bb_descrip_flashbased; | ||
1084 | } | ||
1085 | omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); | ||
1086 | for (i = 0; i < omap_oobinfo.eccbytes; i++) | ||
1087 | omap_oobinfo.eccpos[i] = i+offset; | ||
1088 | |||
1089 | omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; | ||
1090 | omap_oobinfo.oobfree->length = info->mtd.oobsize - | ||
1091 | (offset + omap_oobinfo.eccbytes); | ||
1092 | |||
1093 | info->nand.ecc.layout = &omap_oobinfo; | ||
1094 | } | ||
1060 | 1095 | ||
1061 | #ifdef CONFIG_MTD_PARTITIONS | 1096 | #ifdef CONFIG_MTD_PARTITIONS |
1062 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 1097 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |