|
80 | 80 | #define MTK_NOR_REG_DMA_FADR 0x71c
|
81 | 81 | #define MTK_NOR_REG_DMA_DADR 0x720
|
82 | 82 | #define MTK_NOR_REG_DMA_END_DADR 0x724
|
| 83 | +#define MTK_NOR_REG_CG_DIS 0x728 |
| 84 | +#define MTK_NOR_SFC_SW_RST BIT(2) |
| 85 | + |
83 | 86 | #define MTK_NOR_REG_DMA_DADR_HB 0x738
|
84 | 87 | #define MTK_NOR_REG_DMA_END_DADR_HB 0x73c
|
85 | 88 |
|
@@ -147,6 +150,15 @@ static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk)
|
147 | 150 | return ret;
|
148 | 151 | }
|
149 | 152 |
|
| 153 | +static void mtk_nor_reset(struct mtk_nor *sp) |
| 154 | +{ |
| 155 | + mtk_nor_rmw(sp, MTK_NOR_REG_CG_DIS, 0, MTK_NOR_SFC_SW_RST); |
| 156 | + mb(); /* flush previous writes */ |
| 157 | + mtk_nor_rmw(sp, MTK_NOR_REG_CG_DIS, MTK_NOR_SFC_SW_RST, 0); |
| 158 | + mb(); /* flush previous writes */ |
| 159 | + writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); |
| 160 | +} |
| 161 | + |
150 | 162 | static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op)
|
151 | 163 | {
|
152 | 164 | u32 addr = op->addr.val;
|
@@ -609,7 +621,15 @@ static int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
|
609 | 621 | mtk_nor_set_addr(sp, op);
|
610 | 622 | return mtk_nor_read_pio(sp, op);
|
611 | 623 | } else {
|
612 |
| - return mtk_nor_read_dma(sp, op); |
| 624 | + ret = mtk_nor_read_dma(sp, op); |
| 625 | + if (unlikely(ret)) { |
| 626 | + /* Handle rare bus glitch */ |
| 627 | + mtk_nor_reset(sp); |
| 628 | + mtk_nor_setup_bus(sp, op); |
| 629 | + return mtk_nor_read_dma(sp, op); |
| 630 | + } |
| 631 | + |
| 632 | + return ret; |
613 | 633 | }
|
614 | 634 | }
|
615 | 635 |
|
|
0 commit comments