@@ -65,6 +65,7 @@ module_param(wp_on, int, 0444);
6565#define CMD_PARAMETER_READ 0x0e
6666#define CMD_PARAMETER_CHANGE_COL 0x0f
6767#define CMD_LOW_LEVEL_OP 0x10
68+ #define CMD_NOT_SUPPORTED 0xff
6869
6970struct brcm_nand_dma_desc {
7071 u32 next_desc ;
@@ -199,6 +200,30 @@ static const u16 flash_dma_regs_v4[] = {
199200 [FLASH_DMA_CURRENT_DESC_EXT ] = 0x34 ,
200201};
201202
203+ /* Native command conversion for legacy controllers (< v5.0) */
204+ static const u8 native_cmd_conv [] = {
205+ [NAND_CMD_READ0 ] = CMD_NOT_SUPPORTED ,
206+ [NAND_CMD_READ1 ] = CMD_NOT_SUPPORTED ,
207+ [NAND_CMD_RNDOUT ] = CMD_PARAMETER_CHANGE_COL ,
208+ [NAND_CMD_PAGEPROG ] = CMD_NOT_SUPPORTED ,
209+ [NAND_CMD_READOOB ] = CMD_NOT_SUPPORTED ,
210+ [NAND_CMD_ERASE1 ] = CMD_BLOCK_ERASE ,
211+ [NAND_CMD_STATUS ] = CMD_NOT_SUPPORTED ,
212+ [NAND_CMD_SEQIN ] = CMD_NOT_SUPPORTED ,
213+ [NAND_CMD_RNDIN ] = CMD_NOT_SUPPORTED ,
214+ [NAND_CMD_READID ] = CMD_DEVICE_ID_READ ,
215+ [NAND_CMD_ERASE2 ] = CMD_NULL ,
216+ [NAND_CMD_PARAM ] = CMD_PARAMETER_READ ,
217+ [NAND_CMD_GET_FEATURES ] = CMD_NOT_SUPPORTED ,
218+ [NAND_CMD_SET_FEATURES ] = CMD_NOT_SUPPORTED ,
219+ [NAND_CMD_RESET ] = CMD_NOT_SUPPORTED ,
220+ [NAND_CMD_READSTART ] = CMD_NOT_SUPPORTED ,
221+ [NAND_CMD_READCACHESEQ ] = CMD_NOT_SUPPORTED ,
222+ [NAND_CMD_READCACHEEND ] = CMD_NOT_SUPPORTED ,
223+ [NAND_CMD_RNDOUTSTART ] = CMD_NULL ,
224+ [NAND_CMD_CACHEDPROG ] = CMD_NOT_SUPPORTED ,
225+ };
226+
202227/* Controller feature flags */
203228enum {
204229 BRCMNAND_HAS_1K_SECTORS = BIT (0 ),
@@ -237,6 +262,12 @@ struct brcmnand_controller {
237262 /* List of NAND hosts (one for each chip-select) */
238263 struct list_head host_list ;
239264
265+ /* Functions to be called from exec_op */
266+ int (* check_instr )(struct nand_chip * chip ,
267+ const struct nand_operation * op );
268+ int (* exec_instr )(struct nand_chip * chip ,
269+ const struct nand_operation * op );
270+
240271 /* EDU info, per-transaction */
241272 const u16 * edu_offsets ;
242273 void __iomem * edu_base ;
@@ -2478,18 +2509,190 @@ static int brcmnand_op_is_reset(const struct nand_operation *op)
24782509 return 0 ;
24792510}
24802511
2512+ static int brcmnand_check_instructions (struct nand_chip * chip ,
2513+ const struct nand_operation * op )
2514+ {
2515+ return 0 ;
2516+ }
2517+
2518+ static int brcmnand_exec_instructions (struct nand_chip * chip ,
2519+ const struct nand_operation * op )
2520+ {
2521+ struct brcmnand_host * host = nand_get_controller_data (chip );
2522+ unsigned int i ;
2523+ int ret = 0 ;
2524+
2525+ for (i = 0 ; i < op -> ninstrs ; i ++ ) {
2526+ ret = brcmnand_exec_instr (host , i , op );
2527+ if (ret )
2528+ break ;
2529+ }
2530+
2531+ return ret ;
2532+ }
2533+
2534+ static int brcmnand_check_instructions_legacy (struct nand_chip * chip ,
2535+ const struct nand_operation * op )
2536+ {
2537+ const struct nand_op_instr * instr ;
2538+ unsigned int i ;
2539+ u8 cmd ;
2540+
2541+ for (i = 0 ; i < op -> ninstrs ; i ++ ) {
2542+ instr = & op -> instrs [i ];
2543+
2544+ switch (instr -> type ) {
2545+ case NAND_OP_CMD_INSTR :
2546+ cmd = native_cmd_conv [instr -> ctx .cmd .opcode ];
2547+ if (cmd == CMD_NOT_SUPPORTED )
2548+ return - EOPNOTSUPP ;
2549+ break ;
2550+ case NAND_OP_ADDR_INSTR :
2551+ case NAND_OP_DATA_IN_INSTR :
2552+ case NAND_OP_WAITRDY_INSTR :
2553+ break ;
2554+ default :
2555+ return - EOPNOTSUPP ;
2556+ }
2557+ }
2558+
2559+ return 0 ;
2560+ }
2561+
2562+ static int brcmnand_exec_instructions_legacy (struct nand_chip * chip ,
2563+ const struct nand_operation * op )
2564+ {
2565+ struct mtd_info * mtd = nand_to_mtd (chip );
2566+ struct brcmnand_host * host = nand_get_controller_data (chip );
2567+ struct brcmnand_controller * ctrl = host -> ctrl ;
2568+ const struct nand_op_instr * instr ;
2569+ unsigned int i , j ;
2570+ u8 cmd = CMD_NULL , last_cmd = CMD_NULL ;
2571+ int ret = 0 ;
2572+ u64 last_addr ;
2573+
2574+ for (i = 0 ; i < op -> ninstrs ; i ++ ) {
2575+ instr = & op -> instrs [i ];
2576+
2577+ if (instr -> type == NAND_OP_CMD_INSTR ) {
2578+ cmd = native_cmd_conv [instr -> ctx .cmd .opcode ];
2579+ if (cmd == CMD_NOT_SUPPORTED ) {
2580+ dev_err (ctrl -> dev , "unsupported cmd=%d\n" ,
2581+ instr -> ctx .cmd .opcode );
2582+ ret = - EOPNOTSUPP ;
2583+ break ;
2584+ }
2585+ } else if (instr -> type == NAND_OP_ADDR_INSTR ) {
2586+ u64 addr = 0 ;
2587+
2588+ if (cmd == CMD_NULL )
2589+ continue ;
2590+
2591+ if (instr -> ctx .addr .naddrs > 8 ) {
2592+ dev_err (ctrl -> dev , "unsupported naddrs=%u\n" ,
2593+ instr -> ctx .addr .naddrs );
2594+ ret = - EOPNOTSUPP ;
2595+ break ;
2596+ }
2597+
2598+ for (j = 0 ; j < instr -> ctx .addr .naddrs ; j ++ )
2599+ addr |= (instr -> ctx .addr .addrs [j ]) << (j << 3 );
2600+
2601+ if (cmd == CMD_BLOCK_ERASE )
2602+ addr <<= chip -> page_shift ;
2603+ else if (cmd == CMD_PARAMETER_CHANGE_COL )
2604+ addr &= ~((u64 )(FC_BYTES - 1 ));
2605+
2606+ brcmnand_set_cmd_addr (mtd , addr );
2607+ brcmnand_send_cmd (host , cmd );
2608+ last_addr = addr ;
2609+ last_cmd = cmd ;
2610+ cmd = CMD_NULL ;
2611+ brcmnand_waitfunc (chip );
2612+
2613+ if (last_cmd == CMD_PARAMETER_READ ||
2614+ last_cmd == CMD_PARAMETER_CHANGE_COL ) {
2615+ /* Copy flash cache word-wise */
2616+ u32 * flash_cache = (u32 * )ctrl -> flash_cache ;
2617+
2618+ brcmnand_soc_data_bus_prepare (ctrl -> soc , true);
2619+
2620+ /*
2621+ * Must cache the FLASH_CACHE now, since changes in
2622+ * SECTOR_SIZE_1K may invalidate it
2623+ */
2624+ for (j = 0 ; j < FC_WORDS ; j ++ )
2625+ /*
2626+ * Flash cache is big endian for parameter pages, at
2627+ * least on STB SoCs
2628+ */
2629+ flash_cache [j ] = be32_to_cpu (brcmnand_read_fc (ctrl , j ));
2630+
2631+ brcmnand_soc_data_bus_unprepare (ctrl -> soc , true);
2632+ }
2633+ } else if (instr -> type == NAND_OP_DATA_IN_INSTR ) {
2634+ u8 * in = instr -> ctx .data .buf .in ;
2635+
2636+ if (last_cmd == CMD_DEVICE_ID_READ ) {
2637+ u32 val ;
2638+
2639+ if (instr -> ctx .data .len > 8 ) {
2640+ dev_err (ctrl -> dev , "unsupported len=%u\n" ,
2641+ instr -> ctx .data .len );
2642+ ret = - EOPNOTSUPP ;
2643+ break ;
2644+ }
2645+
2646+ for (j = 0 ; j < instr -> ctx .data .len ; j ++ ) {
2647+ if (j == 0 )
2648+ val = brcmnand_read_reg (ctrl , BRCMNAND_ID );
2649+ else if (j == 4 )
2650+ val = brcmnand_read_reg (ctrl , BRCMNAND_ID_EXT );
2651+
2652+ in [j ] = (val >> (24 - ((j % 4 ) << 3 ))) & 0xff ;
2653+ }
2654+ } else if (last_cmd == CMD_PARAMETER_READ ||
2655+ last_cmd == CMD_PARAMETER_CHANGE_COL ) {
2656+ u64 addr ;
2657+ u32 offs ;
2658+
2659+ for (j = 0 ; j < instr -> ctx .data .len ; j ++ ) {
2660+ addr = last_addr + j ;
2661+ offs = addr & (FC_BYTES - 1 );
2662+
2663+ if (j > 0 && offs == 0 )
2664+ nand_change_read_column_op (chip , addr , NULL , 0 ,
2665+ false);
2666+
2667+ in [j ] = ctrl -> flash_cache [offs ];
2668+ }
2669+ }
2670+ } else if (instr -> type == NAND_OP_WAITRDY_INSTR ) {
2671+ ret = bcmnand_ctrl_poll_status (host , NAND_CTRL_RDY , NAND_CTRL_RDY , 0 );
2672+ if (ret )
2673+ break ;
2674+ } else {
2675+ dev_err (ctrl -> dev , "unsupported instruction type: %d\n" , instr -> type );
2676+ ret = - EOPNOTSUPP ;
2677+ break ;
2678+ }
2679+ }
2680+
2681+ return ret ;
2682+ }
2683+
24812684static int brcmnand_exec_op (struct nand_chip * chip ,
24822685 const struct nand_operation * op ,
24832686 bool check_only )
24842687{
24852688 struct brcmnand_host * host = nand_get_controller_data (chip );
2689+ struct brcmnand_controller * ctrl = host -> ctrl ;
24862690 struct mtd_info * mtd = nand_to_mtd (chip );
24872691 u8 * status ;
2488- unsigned int i ;
24892692 int ret = 0 ;
24902693
24912694 if (check_only )
2492- return 0 ;
2695+ return ctrl -> check_instr ( chip , op ) ;
24932696
24942697 if (brcmnand_op_is_status (op )) {
24952698 status = op -> instrs [1 ].ctx .data .buf .in ;
@@ -2513,11 +2716,7 @@ static int brcmnand_exec_op(struct nand_chip *chip,
25132716 if (op -> deassert_wp )
25142717 brcmnand_wp (mtd , 0 );
25152718
2516- for (i = 0 ; i < op -> ninstrs ; i ++ ) {
2517- ret = brcmnand_exec_instr (host , i , op );
2518- if (ret )
2519- break ;
2520- }
2719+ ret = ctrl -> exec_instr (chip , op );
25212720
25222721 if (op -> deassert_wp )
25232722 brcmnand_wp (mtd , 1 );
@@ -3130,6 +3329,15 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
31303329 if (ret )
31313330 goto err ;
31323331
3332+ /* Only v5.0+ controllers have low level ops support */
3333+ if (ctrl -> nand_version >= 0x0500 ) {
3334+ ctrl -> check_instr = brcmnand_check_instructions ;
3335+ ctrl -> exec_instr = brcmnand_exec_instructions ;
3336+ } else {
3337+ ctrl -> check_instr = brcmnand_check_instructions_legacy ;
3338+ ctrl -> exec_instr = brcmnand_exec_instructions_legacy ;
3339+ }
3340+
31333341 /*
31343342 * Most chips have this cache at a fixed offset within 'nand' block.
31353343 * Some must specify this region separately.
0 commit comments