@@ -82,6 +82,7 @@ struct loongson_nand_data {
8282 unsigned int op_scope_field ;
8383 unsigned int hold_cycle ;
8484 unsigned int wait_cycle ;
85+ unsigned int nand_cs ;
8586 void (* set_addr )(struct loongson_nand_host * host , struct loongson_nand_op * op );
8687};
8788
@@ -90,6 +91,7 @@ struct loongson_nand_host {
9091 struct nand_chip chip ;
9192 struct nand_controller controller ;
9293 const struct loongson_nand_data * data ;
94+ unsigned int addr_cs_field ;
9395 void __iomem * reg_base ;
9496 struct regmap * regmap ;
9597 /* DMA Engine stuff */
@@ -215,6 +217,26 @@ static int loongson_nand_parse_instructions(struct nand_chip *chip, const struct
215217 return 0 ;
216218}
217219
220+ static void loongson_nand_set_addr_cs (struct loongson_nand_host * host )
221+ {
222+ struct nand_chip * chip = & host -> chip ;
223+ struct mtd_info * mtd = nand_to_mtd (chip );
224+
225+ if (!host -> data -> nand_cs )
226+ return ;
227+
228+ /*
229+ * The Manufacturer/Chip ID read operation precedes attach_chip, at which point
230+ * information such as NAND chip selection and capacity is unknown. As a
231+ * workaround, we use 128MB cellsize (2KB pagesize) as a fallback.
232+ */
233+ if (!mtd -> writesize )
234+ host -> addr_cs_field = GENMASK (17 , 16 );
235+
236+ regmap_update_bits (host -> regmap , LOONGSON_NAND_ADDR2 , host -> addr_cs_field ,
237+ host -> data -> nand_cs << __ffs (host -> addr_cs_field ));
238+ }
239+
218240static void ls1b_nand_set_addr (struct loongson_nand_host * host , struct loongson_nand_op * op )
219241{
220242 struct nand_chip * chip = & host -> chip ;
@@ -263,6 +285,8 @@ static void ls1c_nand_set_addr(struct loongson_nand_host *host, struct loongson_
263285 regmap_update_bits (host -> regmap , LOONGSON_NAND_ADDR2 , mask , val );
264286 }
265287 }
288+
289+ loongson_nand_set_addr_cs (host );
266290}
267291
268292static void loongson_nand_trigger_op (struct loongson_nand_host * host , struct loongson_nand_op * op )
@@ -603,42 +627,82 @@ static int loongson_nand_exec_op(struct nand_chip *chip, const struct nand_opera
603627 return nand_op_parser_exec_op (chip , & loongson_nand_op_parser , op , check_only );
604628}
605629
606- static int loongson_nand_attach_chip (struct nand_chip * chip )
630+ static int loongson_nand_get_chip_capacity (struct nand_chip * chip )
607631{
608632 struct loongson_nand_host * host = nand_get_controller_data (chip );
609633 u64 chipsize = nanddev_target_size (& chip -> base );
610- int cell_size = 0 ;
634+ struct mtd_info * mtd = nand_to_mtd ( chip ) ;
611635
612- switch (chipsize ) {
613- case SZ_128M :
614- cell_size = 0x0 ;
615- break ;
616- case SZ_256M :
617- cell_size = 0x1 ;
618- break ;
619- case SZ_512M :
620- cell_size = 0x2 ;
621- break ;
622- case SZ_1G :
623- cell_size = 0x3 ;
624- break ;
625- case SZ_2G :
626- cell_size = 0x4 ;
636+ switch (mtd -> writesize ) {
637+ case SZ_512 :
638+ switch (chipsize ) {
639+ case SZ_8M :
640+ host -> addr_cs_field = GENMASK (15 , 14 );
641+ return 0x9 ;
642+ case SZ_16M :
643+ host -> addr_cs_field = GENMASK (16 , 15 );
644+ return 0xa ;
645+ case SZ_32M :
646+ host -> addr_cs_field = GENMASK (17 , 16 );
647+ return 0xb ;
648+ case SZ_64M :
649+ host -> addr_cs_field = GENMASK (18 , 17 );
650+ return 0xc ;
651+ case SZ_128M :
652+ host -> addr_cs_field = GENMASK (19 , 18 );
653+ return 0xd ;
654+ }
627655 break ;
628- case SZ_4G :
629- cell_size = 0x5 ;
656+ case SZ_2K :
657+ switch (chipsize ) {
658+ case SZ_128M :
659+ host -> addr_cs_field = GENMASK (17 , 16 );
660+ return 0x0 ;
661+ case SZ_256M :
662+ host -> addr_cs_field = GENMASK (18 , 17 );
663+ return 0x1 ;
664+ case SZ_512M :
665+ host -> addr_cs_field = GENMASK (19 , 18 );
666+ return 0x2 ;
667+ case SZ_1G :
668+ host -> addr_cs_field = GENMASK (20 , 19 );
669+ return 0x3 ;
670+ }
630671 break ;
631- case SZ_8G :
632- cell_size = 0x6 ;
672+ case SZ_4K :
673+ if (chipsize == SZ_2G ) {
674+ host -> addr_cs_field = GENMASK (20 , 19 );
675+ return 0x4 ;
676+ }
633677 break ;
634- case SZ_16G :
635- cell_size = 0x7 ;
678+ case SZ_8K :
679+ switch (chipsize ) {
680+ case SZ_4G :
681+ host -> addr_cs_field = GENMASK (20 , 19 );
682+ return 0x5 ;
683+ case SZ_8G :
684+ host -> addr_cs_field = GENMASK (21 , 20 );
685+ return 0x6 ;
686+ case SZ_16G :
687+ host -> addr_cs_field = GENMASK (22 , 21 );
688+ return 0x7 ;
689+ }
636690 break ;
637- default :
638- dev_err (host -> dev , "unsupported chip size: %llu MB\n" , chipsize );
639- return - EINVAL ;
640691 }
641692
693+ dev_err (host -> dev , "Unsupported chip size: %llu MB with page size %u B\n" ,
694+ chipsize , mtd -> writesize );
695+ return - EINVAL ;
696+ }
697+
698+ static int loongson_nand_attach_chip (struct nand_chip * chip )
699+ {
700+ struct loongson_nand_host * host = nand_get_controller_data (chip );
701+ int cell_size = loongson_nand_get_chip_capacity (chip );
702+
703+ if (cell_size < 0 )
704+ return cell_size ;
705+
642706 switch (chip -> ecc .engine_type ) {
643707 case NAND_ECC_ENGINE_TYPE_NONE :
644708 break ;
0 commit comments