Lines Matching refs:op

162 static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op)  in mtk_nor_set_addr()  argument
164 u32 addr = op->addr.val; in mtk_nor_set_addr()
171 if (op->addr.nbytes == 4) { in mtk_nor_set_addr()
179 static bool need_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in need_bounce() argument
181 return ((uintptr_t)op->data.buf.in & MTK_NOR_DMA_ALIGN_MASK); in need_bounce()
184 static bool mtk_nor_match_read(const struct spi_mem_op *op) in mtk_nor_match_read() argument
188 if (op->dummy.nbytes) in mtk_nor_match_read()
189 dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth; in mtk_nor_match_read()
191 if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) { in mtk_nor_match_read()
192 if (op->addr.buswidth == 1) in mtk_nor_match_read()
194 else if (op->addr.buswidth == 2) in mtk_nor_match_read()
196 else if (op->addr.buswidth == 4) in mtk_nor_match_read()
198 } else if ((op->addr.buswidth == 1) && (op->data.buswidth == 1)) { in mtk_nor_match_read()
199 if (op->cmd.opcode == 0x03) in mtk_nor_match_read()
201 else if (op->cmd.opcode == 0x0b) in mtk_nor_match_read()
207 static bool mtk_nor_match_prg(const struct spi_mem_op *op) in mtk_nor_match_prg() argument
212 if ((op->cmd.buswidth > 1) || (op->addr.buswidth > 1) || in mtk_nor_match_prg()
213 (op->dummy.buswidth > 1) || (op->data.buswidth > 1)) in mtk_nor_match_prg()
216 tx_len = op->cmd.nbytes + op->addr.nbytes; in mtk_nor_match_prg()
218 if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_nor_match_prg()
220 tx_len += op->dummy.nbytes; in mtk_nor_match_prg()
228 if ((!op->addr.nbytes) && in mtk_nor_match_prg()
229 (tx_len + op->data.nbytes > MTK_NOR_REG_PRGDATA_MAX + 1)) in mtk_nor_match_prg()
231 } else if (op->data.dir == SPI_MEM_DATA_IN) { in mtk_nor_match_prg()
235 rx_len = op->data.nbytes; in mtk_nor_match_prg()
236 prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes; in mtk_nor_match_prg()
240 if (!op->addr.nbytes) in mtk_nor_match_prg()
245 prg_len = tx_len + op->dummy.nbytes + rx_len; in mtk_nor_match_prg()
249 prg_len = tx_len + op->dummy.nbytes; in mtk_nor_match_prg()
256 static void mtk_nor_adj_prg_size(struct spi_mem_op *op) in mtk_nor_adj_prg_size() argument
260 tx_len = op->cmd.nbytes + op->addr.nbytes; in mtk_nor_adj_prg_size()
261 if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_nor_adj_prg_size()
262 tx_len += op->dummy.nbytes; in mtk_nor_adj_prg_size()
264 if (op->data.nbytes > tx_left) in mtk_nor_adj_prg_size()
265 op->data.nbytes = tx_left; in mtk_nor_adj_prg_size()
266 } else if (op->data.dir == SPI_MEM_DATA_IN) { in mtk_nor_adj_prg_size()
267 prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes; in mtk_nor_adj_prg_size()
270 if (op->data.nbytes > prg_left) in mtk_nor_adj_prg_size()
271 op->data.nbytes = prg_left; in mtk_nor_adj_prg_size()
275 static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) in mtk_nor_adjust_op_size() argument
279 if (!op->data.nbytes) in mtk_nor_adjust_op_size()
282 if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { in mtk_nor_adjust_op_size()
283 if ((op->data.dir == SPI_MEM_DATA_IN) && in mtk_nor_adjust_op_size()
284 mtk_nor_match_read(op)) { in mtk_nor_adjust_op_size()
286 if (op->data.nbytes > 0x400000) in mtk_nor_adjust_op_size()
287 op->data.nbytes = 0x400000; in mtk_nor_adjust_op_size()
289 if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) || in mtk_nor_adjust_op_size()
290 (op->data.nbytes < MTK_NOR_DMA_ALIGN)) in mtk_nor_adjust_op_size()
291 op->data.nbytes = 1; in mtk_nor_adjust_op_size()
292 else if (!need_bounce(sp, op)) in mtk_nor_adjust_op_size()
293 op->data.nbytes &= ~MTK_NOR_DMA_ALIGN_MASK; in mtk_nor_adjust_op_size()
294 else if (op->data.nbytes > MTK_NOR_BOUNCE_BUF_SIZE) in mtk_nor_adjust_op_size()
295 op->data.nbytes = MTK_NOR_BOUNCE_BUF_SIZE; in mtk_nor_adjust_op_size()
297 } else if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_nor_adjust_op_size()
298 if (op->data.nbytes >= MTK_NOR_PP_SIZE) in mtk_nor_adjust_op_size()
299 op->data.nbytes = MTK_NOR_PP_SIZE; in mtk_nor_adjust_op_size()
301 op->data.nbytes = 1; in mtk_nor_adjust_op_size()
306 mtk_nor_adj_prg_size(op); in mtk_nor_adjust_op_size()
311 const struct spi_mem_op *op) in mtk_nor_supports_op() argument
313 if (!spi_mem_default_supports_op(mem, op)) in mtk_nor_supports_op()
316 if (op->cmd.buswidth != 1) in mtk_nor_supports_op()
319 if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { in mtk_nor_supports_op()
320 switch (op->data.dir) { in mtk_nor_supports_op()
322 if (mtk_nor_match_read(op)) in mtk_nor_supports_op()
326 if ((op->addr.buswidth == 1) && in mtk_nor_supports_op()
327 (op->dummy.nbytes == 0) && in mtk_nor_supports_op()
328 (op->data.buswidth == 1)) in mtk_nor_supports_op()
336 return mtk_nor_match_prg(op); in mtk_nor_supports_op()
339 static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_setup_bus() argument
343 if (op->addr.nbytes == 4) in mtk_nor_setup_bus()
346 if (op->data.buswidth == 4) { in mtk_nor_setup_bus()
348 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4)); in mtk_nor_setup_bus()
349 if (op->addr.buswidth == 4) in mtk_nor_setup_bus()
351 } else if (op->data.buswidth == 2) { in mtk_nor_setup_bus()
353 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3)); in mtk_nor_setup_bus()
354 if (op->addr.buswidth == 2) in mtk_nor_setup_bus()
357 if (op->cmd.opcode == 0x0b) in mtk_nor_setup_bus()
409 static int mtk_nor_read_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_bounce() argument
414 if (op->data.nbytes & MTK_NOR_DMA_ALIGN_MASK) in mtk_nor_read_bounce()
415 rdlen = (op->data.nbytes + MTK_NOR_DMA_ALIGN) & ~MTK_NOR_DMA_ALIGN_MASK; in mtk_nor_read_bounce()
417 rdlen = op->data.nbytes; in mtk_nor_read_bounce()
419 ret = mtk_nor_dma_exec(sp, op->addr.val, rdlen, sp->buffer_dma); in mtk_nor_read_bounce()
422 memcpy(op->data.buf.in, sp->buffer, op->data.nbytes); in mtk_nor_read_bounce()
427 static int mtk_nor_read_dma(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_dma() argument
432 if (need_bounce(sp, op)) in mtk_nor_read_dma()
433 return mtk_nor_read_bounce(sp, op); in mtk_nor_read_dma()
435 dma_addr = dma_map_single(sp->dev, op->data.buf.in, in mtk_nor_read_dma()
436 op->data.nbytes, DMA_FROM_DEVICE); in mtk_nor_read_dma()
441 ret = mtk_nor_dma_exec(sp, op->addr.val, op->data.nbytes, dma_addr); in mtk_nor_read_dma()
443 dma_unmap_single(sp->dev, dma_addr, op->data.nbytes, DMA_FROM_DEVICE); in mtk_nor_read_dma()
448 static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_pio() argument
450 u8 *buf = op->data.buf.in; in mtk_nor_read_pio()
484 static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_pp_buffered() argument
486 const u8 *buf = op->data.buf.out; in mtk_nor_pp_buffered()
494 for (i = 0; i < op->data.nbytes; i += 4) { in mtk_nor_pp_buffered()
500 (op->data.nbytes + 5) * BITS_PER_BYTE); in mtk_nor_pp_buffered()
504 const struct spi_mem_op *op) in mtk_nor_pp_unbuffered() argument
506 const u8 *buf = op->data.buf.out; in mtk_nor_pp_unbuffered()
516 static int mtk_nor_spi_mem_prg(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_spi_mem_prg() argument
525 tx_len = op->cmd.nbytes + op->addr.nbytes; in mtk_nor_spi_mem_prg()
528 if (op->data.dir == SPI_MEM_DATA_OUT) in mtk_nor_spi_mem_prg()
529 tx_len += op->dummy.nbytes + op->data.nbytes; in mtk_nor_spi_mem_prg()
530 else if (op->data.dir == SPI_MEM_DATA_IN) in mtk_nor_spi_mem_prg()
531 rx_len = op->data.nbytes; in mtk_nor_spi_mem_prg()
533 prg_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes + in mtk_nor_spi_mem_prg()
534 op->data.nbytes; in mtk_nor_spi_mem_prg()
545 for (i = op->cmd.nbytes; i > 0; i--, reg_offset--) { in mtk_nor_spi_mem_prg()
547 bufbyte = (op->cmd.opcode >> ((i - 1) * BITS_PER_BYTE)) & 0xff; in mtk_nor_spi_mem_prg()
551 for (i = op->addr.nbytes; i > 0; i--, reg_offset--) { in mtk_nor_spi_mem_prg()
553 bufbyte = (op->addr.val >> ((i - 1) * BITS_PER_BYTE)) & 0xff; in mtk_nor_spi_mem_prg()
557 if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_nor_spi_mem_prg()
558 for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) { in mtk_nor_spi_mem_prg()
563 for (i = 0; i < op->data.nbytes; i++, reg_offset--) { in mtk_nor_spi_mem_prg()
565 writeb(((const u8 *)(op->data.buf.out))[i], reg); in mtk_nor_spi_mem_prg()
588 if (op->data.dir == SPI_MEM_DATA_IN) { in mtk_nor_spi_mem_prg()
589 for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) { in mtk_nor_spi_mem_prg()
591 ((u8 *)(op->data.buf.in))[i] = readb(reg); in mtk_nor_spi_mem_prg()
598 static int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) in mtk_nor_exec_op() argument
603 if ((op->data.nbytes == 0) || in mtk_nor_exec_op()
604 ((op->addr.nbytes != 3) && (op->addr.nbytes != 4))) in mtk_nor_exec_op()
605 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()
607 if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_nor_exec_op()
608 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
609 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0); in mtk_nor_exec_op()
610 if (op->data.nbytes == MTK_NOR_PP_SIZE) in mtk_nor_exec_op()
611 return mtk_nor_pp_buffered(sp, op); in mtk_nor_exec_op()
612 return mtk_nor_pp_unbuffered(sp, op); in mtk_nor_exec_op()
615 if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) { in mtk_nor_exec_op()
619 mtk_nor_setup_bus(sp, op); in mtk_nor_exec_op()
620 if (op->data.nbytes == 1) { in mtk_nor_exec_op()
621 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
622 return mtk_nor_read_pio(sp, op); in mtk_nor_exec_op()
624 ret = mtk_nor_read_dma(sp, op); in mtk_nor_exec_op()
628 mtk_nor_setup_bus(sp, op); in mtk_nor_exec_op()
629 return mtk_nor_read_dma(sp, op); in mtk_nor_exec_op()
636 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()