@@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
10381038 return -1 ;
10391039}
10401040
1041+ static bool brcmnand_get_sector_size_1k (struct brcmnand_host * host )
1042+ {
1043+ struct brcmnand_controller * ctrl = host -> ctrl ;
1044+ int sector_size_bit = brcmnand_sector_1k_shift (ctrl );
1045+ u16 acc_control_offs = brcmnand_cs_offset (ctrl , host -> cs ,
1046+ BRCMNAND_CS_ACC_CONTROL );
1047+ u32 acc_control ;
1048+
1049+ if (sector_size_bit < 0 )
1050+ return false;
1051+
1052+ acc_control = nand_readreg (ctrl , acc_control_offs );
1053+
1054+ return ((acc_control & BIT (sector_size_bit )) != 0 );
1055+ }
1056+
10411057static void brcmnand_set_sector_size_1k (struct brcmnand_host * host , int val )
10421058{
10431059 struct brcmnand_controller * ctrl = host -> ctrl ;
@@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
10551071 nand_writereg (ctrl , acc_control_offs , tmp );
10561072}
10571073
1074+ static int brcmnand_get_spare_size (struct brcmnand_host * host )
1075+ {
1076+ struct brcmnand_controller * ctrl = host -> ctrl ;
1077+ u16 acc_control_offs = brcmnand_cs_offset (ctrl , host -> cs ,
1078+ BRCMNAND_CS_ACC_CONTROL );
1079+ u32 acc = nand_readreg (ctrl , acc_control_offs );
1080+
1081+ return (acc & brcmnand_spare_area_mask (ctrl ));
1082+ }
1083+
1084+ static void brcmnand_get_ecc_settings (struct brcmnand_host * host , struct nand_chip * chip )
1085+ {
1086+ struct brcmnand_controller * ctrl = host -> ctrl ;
1087+ u16 acc_control_offs = brcmnand_cs_offset (ctrl , host -> cs ,
1088+ BRCMNAND_CS_ACC_CONTROL );
1089+ bool sector_size_1k = brcmnand_get_sector_size_1k (host );
1090+ int spare_area_size , ecc_level ;
1091+ u32 acc ;
1092+
1093+ spare_area_size = brcmnand_get_spare_size (host );
1094+ acc = nand_readreg (ctrl , acc_control_offs );
1095+ ecc_level = (acc & brcmnand_ecc_level_mask (ctrl )) >> ctrl -> ecc_level_shift ;
1096+ if (sector_size_1k )
1097+ chip -> ecc .strength = ecc_level * 2 ;
1098+ else if (spare_area_size == 16 && ecc_level == 15 )
1099+ chip -> ecc .strength = 1 ; /* hamming */
1100+ else
1101+ chip -> ecc .strength = ecc_level ;
1102+
1103+ if (chip -> ecc .size == 0 ) {
1104+ if (sector_size_1k )
1105+ chip -> ecc .size = 1024 ;
1106+ else
1107+ chip -> ecc .size = 512 ;
1108+ }
1109+ }
1110+
10581111/***********************************************************************
10591112 * CS_NAND_SELECT
10601113 ***********************************************************************/
@@ -2625,19 +2678,37 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
26252678 nanddev_get_memorg (& chip -> base );
26262679 struct brcmnand_controller * ctrl = host -> ctrl ;
26272680 struct brcmnand_cfg * cfg = & host -> hwcfg ;
2628- char msg [ 128 ] ;
2681+ struct device_node * np = nand_get_flash_node ( chip ) ;
26292682 u32 offs , tmp , oob_sector ;
2683+ bool use_strap = false;
2684+ char msg [128 ];
26302685 int ret ;
26312686
26322687 memset (cfg , 0 , sizeof (* cfg ));
2688+ use_strap = of_property_read_bool (np , "brcm,nand-ecc-use-strap" );
26332689
2634- ret = of_property_read_u32 (nand_get_flash_node (chip ),
2635- "brcm,nand-oob-sector-size" ,
2690+ /*
2691+ * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out
2692+ * if both exist.
2693+ */
2694+ if (chip -> ecc .strength && use_strap ) {
2695+ dev_err (ctrl -> dev ,
2696+ "ECC strap and DT ECC configuration properties are mutually exclusive\n" );
2697+ return - EINVAL ;
2698+ }
2699+
2700+ if (use_strap )
2701+ brcmnand_get_ecc_settings (host , chip );
2702+
2703+ ret = of_property_read_u32 (np , "brcm,nand-oob-sector-size" ,
26362704 & oob_sector );
26372705 if (ret ) {
2638- /* Use detected size */
2639- cfg -> spare_area_size = mtd -> oobsize /
2640- (mtd -> writesize >> FC_SHIFT );
2706+ if (use_strap )
2707+ cfg -> spare_area_size = brcmnand_get_spare_size (host );
2708+ else
2709+ /* Use detected size */
2710+ cfg -> spare_area_size = mtd -> oobsize /
2711+ (mtd -> writesize >> FC_SHIFT );
26412712 } else {
26422713 cfg -> spare_area_size = oob_sector ;
26432714 }
0 commit comments