@@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
1038
1038
return -1 ;
1039
1039
}
1040
1040
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
+
1041
1057
static void brcmnand_set_sector_size_1k (struct brcmnand_host * host , int val )
1042
1058
{
1043
1059
struct brcmnand_controller * ctrl = host -> ctrl ;
@@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
1055
1071
nand_writereg (ctrl , acc_control_offs , tmp );
1056
1072
}
1057
1073
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
+
1058
1111
/***********************************************************************
1059
1112
* CS_NAND_SELECT
1060
1113
***********************************************************************/
@@ -2625,19 +2678,37 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
2625
2678
nanddev_get_memorg (& chip -> base );
2626
2679
struct brcmnand_controller * ctrl = host -> ctrl ;
2627
2680
struct brcmnand_cfg * cfg = & host -> hwcfg ;
2628
- char msg [ 128 ] ;
2681
+ struct device_node * np = nand_get_flash_node ( chip ) ;
2629
2682
u32 offs , tmp , oob_sector ;
2683
+ bool use_strap = false;
2684
+ char msg [128 ];
2630
2685
int ret ;
2631
2686
2632
2687
memset (cfg , 0 , sizeof (* cfg ));
2688
+ use_strap = of_property_read_bool (np , "brcm,nand-ecc-use-strap" );
2633
2689
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" ,
2636
2704
& oob_sector );
2637
2705
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 );
2641
2712
} else {
2642
2713
cfg -> spare_area_size = oob_sector ;
2643
2714
}
0 commit comments