Lines Matching refs:op

163 static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op)
165 u32 addr = op->addr.val;
172 if (op->addr.nbytes == 4) {
180 static bool need_bounce(struct mtk_nor *sp, const struct spi_mem_op *op)
182 return ((uintptr_t)op->data.buf.in & MTK_NOR_DMA_ALIGN_MASK);
185 static bool mtk_nor_match_read(const struct spi_mem_op *op)
189 if (op->dummy.nbytes)
190 dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth;
192 if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) {
193 if (op->addr.buswidth == 1)
195 else if (op->addr.buswidth == 2)
197 else if (op->addr.buswidth == 4)
199 } else if ((op->addr.buswidth == 1) && (op->data.buswidth == 1)) {
200 if (op->cmd.opcode == 0x03)
202 else if (op->cmd.opcode == 0x0b)
208 static bool mtk_nor_match_prg(const struct spi_mem_op *op)
213 if ((op->cmd.buswidth > 1) || (op->addr.buswidth > 1) ||
214 (op->dummy.buswidth > 1) || (op->data.buswidth > 1))
217 tx_len = op->cmd.nbytes + op->addr.nbytes;
219 if (op->data.dir == SPI_MEM_DATA_OUT) {
221 tx_len += op->dummy.nbytes;
229 if ((!op->addr.nbytes) &&
230 (tx_len + op->data.nbytes > MTK_NOR_REG_PRGDATA_MAX + 1))
232 } else if (op->data.dir == SPI_MEM_DATA_IN) {
236 rx_len = op->data.nbytes;
237 prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes;
241 if (!op->addr.nbytes)
246 prg_len = tx_len + op->dummy.nbytes + rx_len;
250 prg_len = tx_len + op->dummy.nbytes;
257 static void mtk_nor_adj_prg_size(struct spi_mem_op *op)
261 tx_len = op->cmd.nbytes + op->addr.nbytes;
262 if (op->data.dir == SPI_MEM_DATA_OUT) {
263 tx_len += op->dummy.nbytes;
265 if (op->data.nbytes > tx_left)
266 op->data.nbytes = tx_left;
267 } else if (op->data.dir == SPI_MEM_DATA_IN) {
268 prg_left = MTK_NOR_PRG_CNT_MAX / 8 - tx_len - op->dummy.nbytes;
271 if (op->data.nbytes > prg_left)
272 op->data.nbytes = prg_left;
276 static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
280 if (!op->data.nbytes)
283 if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
284 if ((op->data.dir == SPI_MEM_DATA_IN) &&
285 mtk_nor_match_read(op)) {
287 if (op->data.nbytes > 0x400000)
288 op->data.nbytes = 0x400000;
290 if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
291 (op->data.nbytes < MTK_NOR_DMA_ALIGN))
292 op->data.nbytes = 1;
293 else if (!need_bounce(sp, op))
294 op->data.nbytes &= ~MTK_NOR_DMA_ALIGN_MASK;
295 else if (op->data.nbytes > MTK_NOR_BOUNCE_BUF_SIZE)
296 op->data.nbytes = MTK_NOR_BOUNCE_BUF_SIZE;
298 } else if (op->data.dir == SPI_MEM_DATA_OUT) {
299 if (op->data.nbytes >= MTK_NOR_PP_SIZE)
300 op->data.nbytes = MTK_NOR_PP_SIZE;
302 op->data.nbytes = 1;
307 mtk_nor_adj_prg_size(op);
312 const struct spi_mem_op *op)
314 if (!spi_mem_default_supports_op(mem, op))
317 if (op->cmd.buswidth != 1)
320 if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
321 switch (op->data.dir) {
323 if (mtk_nor_match_read(op))
327 if ((op->addr.buswidth == 1) &&
328 (op->dummy.nbytes == 0) &&
329 (op->data.buswidth == 1))
337 return mtk_nor_match_prg(op);
340 static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op)
344 if (op->addr.nbytes == 4)
347 if (op->data.buswidth == 4) {
349 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4));
350 if (op->addr.buswidth == 4)
352 } else if (op->data.buswidth == 2) {
354 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3));
355 if (op->addr.buswidth == 2)
358 if (op->cmd.opcode == 0x0b)
410 static int mtk_nor_read_bounce(struct mtk_nor *sp, const struct spi_mem_op *op)
415 if (op->data.nbytes & MTK_NOR_DMA_ALIGN_MASK)
416 rdlen = (op->data.nbytes + MTK_NOR_DMA_ALIGN) & ~MTK_NOR_DMA_ALIGN_MASK;
418 rdlen = op->data.nbytes;
420 ret = mtk_nor_dma_exec(sp, op->addr.val, rdlen, sp->buffer_dma);
423 memcpy(op->data.buf.in, sp->buffer, op->data.nbytes);
428 static int mtk_nor_read_dma(struct mtk_nor *sp, const struct spi_mem_op *op)
433 if (need_bounce(sp, op))
434 return mtk_nor_read_bounce(sp, op);
436 dma_addr = dma_map_single(sp->dev, op->data.buf.in,
437 op->data.nbytes, DMA_FROM_DEVICE);
442 ret = mtk_nor_dma_exec(sp, op->addr.val, op->data.nbytes, dma_addr);
444 dma_unmap_single(sp->dev, dma_addr, op->data.nbytes, DMA_FROM_DEVICE);
449 static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op)
451 u8 *buf = op->data.buf.in;
485 static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op)
487 const u8 *buf = op->data.buf.out;
495 for (i = 0; i < op->data.nbytes; i += 4) {
501 (op->data.nbytes + 5) * BITS_PER_BYTE);
505 const struct spi_mem_op *op)
507 const u8 *buf = op->data.buf.out;
517 static int mtk_nor_spi_mem_prg(struct mtk_nor *sp, const struct spi_mem_op *op)
526 tx_len = op->cmd.nbytes + op->addr.nbytes;
529 if (op->data.dir == SPI_MEM_DATA_OUT)
530 tx_len += op->dummy.nbytes + op->data.nbytes;
531 else if (op->data.dir == SPI_MEM_DATA_IN)
532 rx_len = op->data.nbytes;
534 prg_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes +
535 op->data.nbytes;
537 // an invalid op may reach here if the caller calls exec_op without
539 // spi-mem won't try this op again with generic spi transfers.
546 for (i = op->cmd.nbytes; i > 0; i--, reg_offset--) {
548 bufbyte = (op->cmd.opcode >> ((i - 1) * BITS_PER_BYTE)) & 0xff;
552 for (i = op->addr.nbytes; i > 0; i--, reg_offset--) {
554 bufbyte = (op->addr.val >> ((i - 1) * BITS_PER_BYTE)) & 0xff;
558 if (op->data.dir == SPI_MEM_DATA_OUT) {
559 for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) {
564 for (i = 0; i < op->data.nbytes; i++, reg_offset--) {
566 writeb(((const u8 *)(op->data.buf.out))[i], reg);
575 // trigger op
589 if (op->data.dir == SPI_MEM_DATA_IN) {
590 for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) {
592 ((u8 *)(op->data.buf.in))[i] = readb(reg);
599 static int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
604 if ((op->data.nbytes == 0) ||
605 ((op->addr.nbytes != 3) && (op->addr.nbytes != 4)))
606 return mtk_nor_spi_mem_prg(sp, op);
608 if (op->data.dir == SPI_MEM_DATA_OUT) {
609 mtk_nor_set_addr(sp, op);
610 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0);
611 if (op->data.nbytes == MTK_NOR_PP_SIZE)
612 return mtk_nor_pp_buffered(sp, op);
613 return mtk_nor_pp_unbuffered(sp, op);
616 if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) {
620 mtk_nor_setup_bus(sp, op);
621 if (op->data.nbytes == 1) {
622 mtk_nor_set_addr(sp, op);
623 return mtk_nor_read_pio(sp, op);
625 ret = mtk_nor_read_dma(sp, op);
629 mtk_nor_setup_bus(sp, op);
630 return mtk_nor_read_dma(sp, op);
637 return mtk_nor_spi_mem_prg(sp, op);