Lines Matching +full:op +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
11 * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
25 #include <linux/spi/spi-mem.h>
29 #define QSPI_MR 0x0004 /* Mode Register */
44 #define QSPI_SMR 0x0040 /* Scrambling Mode Register */
47 #define QSPI_WPMR 0x00E4 /* Write Protection Mode Register */
59 /* Bitfields in QSPI_MR (Mode Register) */
69 #define QSPI_MR_NBBITS(n) ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
127 /* Bitfields in QSPI_SMR (Scrambling Mode Register) */
131 /* Bitfields in QSPI_WPMR (Write Protection Mode Register) */
167 int (*set_cfg)(struct atmel_qspi *aq, const struct spi_mem_op *op,
169 int (*transfer)(struct spi_mem *mem, const struct spi_mem_op *op,
241 u32 value = readl_relaxed(aq->regs + offset); in atmel_qspi_read()
246 dev_vdbg(&aq->pdev->dev, "read 0x%08x from %s\n", value, in atmel_qspi_read()
258 dev_vdbg(&aq->pdev->dev, "write 0x%08x into %s\n", value, in atmel_qspi_write()
262 writel_relaxed(value, aq->regs + offset); in atmel_qspi_write()
265 static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op, in atmel_qspi_is_compatible() argument
266 const struct atmel_qspi_mode *mode) in atmel_qspi_is_compatible() argument
268 if (op->cmd.buswidth != mode->cmd_buswidth) in atmel_qspi_is_compatible()
271 if (op->addr.nbytes && op->addr.buswidth != mode->addr_buswidth) in atmel_qspi_is_compatible()
274 if (op->data.nbytes && op->data.buswidth != mode->data_buswidth) in atmel_qspi_is_compatible()
280 static int atmel_qspi_find_mode(const struct spi_mem_op *op) in atmel_qspi_find_mode() argument
285 if (atmel_qspi_is_compatible(op, &atmel_qspi_modes[i])) in atmel_qspi_find_mode()
288 return -ENOTSUPP; in atmel_qspi_find_mode()
292 const struct spi_mem_op *op) in atmel_qspi_supports_op() argument
294 if (!spi_mem_default_supports_op(mem, op)) in atmel_qspi_supports_op()
297 if (atmel_qspi_find_mode(op) < 0) in atmel_qspi_supports_op()
301 if (op->addr.nbytes == 2 && op->cmd.buswidth != op->addr.buswidth && in atmel_qspi_supports_op()
302 op->dummy.nbytes == 0) in atmel_qspi_supports_op()
309 const struct spi_mem_op *op, u32 *offset) in atmel_qspi_set_cfg() argument
313 int mode; in atmel_qspi_set_cfg() local
316 icr = QSPI_ICR_INST(op->cmd.opcode); in atmel_qspi_set_cfg()
319 mode = atmel_qspi_find_mode(op); in atmel_qspi_set_cfg()
320 if (mode < 0) in atmel_qspi_set_cfg()
321 return mode; in atmel_qspi_set_cfg()
322 ifr |= atmel_qspi_modes[mode].config; in atmel_qspi_set_cfg()
324 if (op->dummy.nbytes) in atmel_qspi_set_cfg()
325 dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth; in atmel_qspi_set_cfg()
328 * The controller allows 24 and 32-bit addressing while NAND-flash in atmel_qspi_set_cfg()
329 * requires 16-bit long. Handling 8-bit long addresses is done using in atmel_qspi_set_cfg()
330 * the option field. For the 16-bit addresses, the workaround depends in atmel_qspi_set_cfg()
335 * use the same buswidth). The limitation is when the 16-bit address is in atmel_qspi_set_cfg()
339 if (op->addr.buswidth) { in atmel_qspi_set_cfg()
340 switch (op->addr.nbytes) { in atmel_qspi_set_cfg()
345 icr |= QSPI_ICR_OPT(op->addr.val & 0xff); in atmel_qspi_set_cfg()
348 if (dummy_cycles < 8 / op->addr.buswidth) { in atmel_qspi_set_cfg()
351 iar = (op->cmd.opcode << 16) | in atmel_qspi_set_cfg()
352 (op->addr.val & 0xffff); in atmel_qspi_set_cfg()
355 iar = (op->addr.val << 8) & 0xffffff; in atmel_qspi_set_cfg()
356 dummy_cycles -= 8 / op->addr.buswidth; in atmel_qspi_set_cfg()
361 iar = op->addr.val & 0xffffff; in atmel_qspi_set_cfg()
365 iar = op->addr.val & 0x7ffffff; in atmel_qspi_set_cfg()
368 return -ENOTSUPP; in atmel_qspi_set_cfg()
380 if (op->data.nbytes) { in atmel_qspi_set_cfg()
383 if (op->addr.nbytes) in atmel_qspi_set_cfg()
388 * If the QSPI controller is set in regular SPI mode, set it in in atmel_qspi_set_cfg()
389 * Serial Memory Mode (SMM). in atmel_qspi_set_cfg()
391 if (!(aq->mr & QSPI_MR_SMM)) { in atmel_qspi_set_cfg()
392 aq->mr |= QSPI_MR_SMM; in atmel_qspi_set_cfg()
393 atmel_qspi_write(aq->mr, aq, QSPI_MR); in atmel_qspi_set_cfg()
400 if (op->addr.nbytes && !op->data.nbytes) in atmel_qspi_set_cfg()
403 if (aq->caps->has_ricr) { in atmel_qspi_set_cfg()
404 if (op->data.dir == SPI_MEM_DATA_IN) in atmel_qspi_set_cfg()
409 if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) in atmel_qspi_set_cfg()
431 reinit_completion(&aq->cmd_completion); in atmel_qspi_wait_for_completion()
432 aq->pending = sr & irq_mask; in atmel_qspi_wait_for_completion()
433 aq->irq_mask = irq_mask; in atmel_qspi_wait_for_completion()
435 if (!wait_for_completion_timeout(&aq->cmd_completion, in atmel_qspi_wait_for_completion()
437 err = -ETIMEDOUT; in atmel_qspi_wait_for_completion()
444 const struct spi_mem_op *op, u32 offset) in atmel_qspi_transfer() argument
446 struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); in atmel_qspi_transfer()
449 if (!op->data.nbytes) in atmel_qspi_transfer()
457 if (op->data.dir == SPI_MEM_DATA_IN) { in atmel_qspi_transfer()
458 memcpy_fromio(op->data.buf.in, aq->mem + offset, in atmel_qspi_transfer()
459 op->data.nbytes); in atmel_qspi_transfer()
464 memcpy_toio(aq->mem + offset, op->data.buf.out, in atmel_qspi_transfer()
465 op->data.nbytes); in atmel_qspi_transfer()
471 /* Release the chip-select */ in atmel_qspi_transfer()
477 static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) in atmel_qspi_exec_op() argument
479 struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller); in atmel_qspi_exec_op()
485 * would be to add support for regular SPI mode and fall back to it in atmel_qspi_exec_op()
488 if (op->addr.val + op->data.nbytes > aq->mmap_size) in atmel_qspi_exec_op()
489 return -EOPNOTSUPP; in atmel_qspi_exec_op()
491 if (op->addr.nbytes > 4) in atmel_qspi_exec_op()
492 return -EOPNOTSUPP; in atmel_qspi_exec_op()
494 err = pm_runtime_resume_and_get(&aq->pdev->dev); in atmel_qspi_exec_op()
498 err = aq->ops->set_cfg(aq, op, &offset); in atmel_qspi_exec_op()
502 err = aq->ops->transfer(mem, op, offset); in atmel_qspi_exec_op()
505 pm_runtime_mark_last_busy(&aq->pdev->dev); in atmel_qspi_exec_op()
506 pm_runtime_put_autosuspend(&aq->pdev->dev); in atmel_qspi_exec_op()
512 return dev_name(spimem->spi->dev.parent); in atmel_qspi_get_name()
523 struct spi_controller *ctrl = spi->controller; in atmel_qspi_setup()
529 if (ctrl->busy) in atmel_qspi_setup()
530 return -EBUSY; in atmel_qspi_setup()
532 if (!spi->max_speed_hz) in atmel_qspi_setup()
533 return -EINVAL; in atmel_qspi_setup()
535 src_rate = clk_get_rate(aq->pclk); in atmel_qspi_setup()
537 return -EINVAL; in atmel_qspi_setup()
540 scbr = DIV_ROUND_UP(src_rate, spi->max_speed_hz); in atmel_qspi_setup()
542 scbr--; in atmel_qspi_setup()
544 ret = pm_runtime_resume_and_get(ctrl->dev.parent); in atmel_qspi_setup()
548 aq->scr &= ~QSPI_SCR_SCBR_MASK; in atmel_qspi_setup()
549 aq->scr |= QSPI_SCR_SCBR(scbr); in atmel_qspi_setup()
550 atmel_qspi_write(aq->scr, aq, QSPI_SCR); in atmel_qspi_setup()
552 pm_runtime_mark_last_busy(ctrl->dev.parent); in atmel_qspi_setup()
553 pm_runtime_put_autosuspend(ctrl->dev.parent); in atmel_qspi_setup()
560 struct spi_controller *ctrl = spi->controller; in atmel_qspi_set_cs_timing()
567 delay = spi_delay_to_ns(&spi->cs_setup, NULL); in atmel_qspi_set_cs_timing()
571 clk_rate = clk_get_rate(aq->pclk); in atmel_qspi_set_cs_timing()
573 return -EINVAL; in atmel_qspi_set_cs_timing()
578 ret = pm_runtime_resume_and_get(ctrl->dev.parent); in atmel_qspi_set_cs_timing()
582 aq->scr &= ~QSPI_SCR_DLYBS_MASK; in atmel_qspi_set_cs_timing()
583 aq->scr |= QSPI_SCR_DLYBS(cs_setup); in atmel_qspi_set_cs_timing()
584 atmel_qspi_write(aq->scr, aq, QSPI_SCR); in atmel_qspi_set_cs_timing()
586 pm_runtime_mark_last_busy(ctrl->dev.parent); in atmel_qspi_set_cs_timing()
587 pm_runtime_put_autosuspend(ctrl->dev.parent); in atmel_qspi_set_cs_timing()
597 /* Set the QSPI controller by default in Serial Memory Mode */ in atmel_qspi_init()
598 aq->mr |= QSPI_MR_SMM; in atmel_qspi_init()
599 atmel_qspi_write(aq->mr, aq, QSPI_MR); in atmel_qspi_init()
617 aq->pending |= pending; in atmel_qspi_interrupt()
618 if ((aq->pending & aq->irq_mask) == aq->irq_mask) in atmel_qspi_interrupt()
619 complete(&aq->cmd_completion); in atmel_qspi_interrupt()
636 ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*aq)); in atmel_qspi_probe()
638 return -ENOMEM; in atmel_qspi_probe()
640 ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; in atmel_qspi_probe()
641 ctrl->setup = atmel_qspi_setup; in atmel_qspi_probe()
642 ctrl->set_cs_timing = atmel_qspi_set_cs_timing; in atmel_qspi_probe()
643 ctrl->bus_num = -1; in atmel_qspi_probe()
644 ctrl->mem_ops = &atmel_qspi_mem_ops; in atmel_qspi_probe()
645 ctrl->num_chipselect = 1; in atmel_qspi_probe()
646 ctrl->dev.of_node = pdev->dev.of_node; in atmel_qspi_probe()
651 init_completion(&aq->cmd_completion); in atmel_qspi_probe()
652 aq->pdev = pdev; in atmel_qspi_probe()
653 aq->ops = &atmel_qspi_ops; in atmel_qspi_probe()
657 aq->regs = devm_ioremap_resource(&pdev->dev, res); in atmel_qspi_probe()
658 if (IS_ERR(aq->regs)) { in atmel_qspi_probe()
659 dev_err(&pdev->dev, "missing registers\n"); in atmel_qspi_probe()
660 return PTR_ERR(aq->regs); in atmel_qspi_probe()
665 aq->mem = devm_ioremap_resource(&pdev->dev, res); in atmel_qspi_probe()
666 if (IS_ERR(aq->mem)) { in atmel_qspi_probe()
667 dev_err(&pdev->dev, "missing AHB memory\n"); in atmel_qspi_probe()
668 return PTR_ERR(aq->mem); in atmel_qspi_probe()
671 aq->mmap_size = resource_size(res); in atmel_qspi_probe()
674 aq->pclk = devm_clk_get(&pdev->dev, "pclk"); in atmel_qspi_probe()
675 if (IS_ERR(aq->pclk)) in atmel_qspi_probe()
676 aq->pclk = devm_clk_get(&pdev->dev, NULL); in atmel_qspi_probe()
678 if (IS_ERR(aq->pclk)) { in atmel_qspi_probe()
679 dev_err(&pdev->dev, "missing peripheral clock\n"); in atmel_qspi_probe()
680 return PTR_ERR(aq->pclk); in atmel_qspi_probe()
684 err = clk_prepare_enable(aq->pclk); in atmel_qspi_probe()
686 dev_err(&pdev->dev, "failed to enable the peripheral clock\n"); in atmel_qspi_probe()
690 aq->caps = of_device_get_match_data(&pdev->dev); in atmel_qspi_probe()
691 if (!aq->caps) { in atmel_qspi_probe()
692 dev_err(&pdev->dev, "Could not retrieve QSPI caps\n"); in atmel_qspi_probe()
693 err = -EINVAL; in atmel_qspi_probe()
697 if (aq->caps->has_qspick) { in atmel_qspi_probe()
699 aq->qspick = devm_clk_get(&pdev->dev, "qspick"); in atmel_qspi_probe()
700 if (IS_ERR(aq->qspick)) { in atmel_qspi_probe()
701 dev_err(&pdev->dev, "missing system clock\n"); in atmel_qspi_probe()
702 err = PTR_ERR(aq->qspick); in atmel_qspi_probe()
707 err = clk_prepare_enable(aq->qspick); in atmel_qspi_probe()
709 dev_err(&pdev->dev, in atmel_qspi_probe()
721 err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt, in atmel_qspi_probe()
722 0, dev_name(&pdev->dev), aq); in atmel_qspi_probe()
726 pm_runtime_set_autosuspend_delay(&pdev->dev, 500); in atmel_qspi_probe()
727 pm_runtime_use_autosuspend(&pdev->dev); in atmel_qspi_probe()
728 pm_runtime_set_active(&pdev->dev); in atmel_qspi_probe()
729 pm_runtime_enable(&pdev->dev); in atmel_qspi_probe()
730 pm_runtime_get_noresume(&pdev->dev); in atmel_qspi_probe()
736 pm_runtime_put_noidle(&pdev->dev); in atmel_qspi_probe()
737 pm_runtime_disable(&pdev->dev); in atmel_qspi_probe()
738 pm_runtime_set_suspended(&pdev->dev); in atmel_qspi_probe()
739 pm_runtime_dont_use_autosuspend(&pdev->dev); in atmel_qspi_probe()
742 pm_runtime_mark_last_busy(&pdev->dev); in atmel_qspi_probe()
743 pm_runtime_put_autosuspend(&pdev->dev); in atmel_qspi_probe()
748 clk_disable_unprepare(aq->qspick); in atmel_qspi_probe()
750 clk_disable_unprepare(aq->pclk); in atmel_qspi_probe()
763 ret = pm_runtime_get_sync(&pdev->dev); in atmel_qspi_remove()
766 clk_disable(aq->qspick); in atmel_qspi_remove()
767 clk_disable(aq->pclk); in atmel_qspi_remove()
774 dev_warn(&pdev->dev, "Failed to resume device on remove\n"); in atmel_qspi_remove()
777 clk_unprepare(aq->qspick); in atmel_qspi_remove()
778 clk_unprepare(aq->pclk); in atmel_qspi_remove()
780 pm_runtime_disable(&pdev->dev); in atmel_qspi_remove()
781 pm_runtime_dont_use_autosuspend(&pdev->dev); in atmel_qspi_remove()
782 pm_runtime_put_noidle(&pdev->dev); in atmel_qspi_remove()
800 clk_unprepare(aq->qspick); in atmel_qspi_suspend()
801 clk_unprepare(aq->pclk); in atmel_qspi_suspend()
812 ret = clk_prepare(aq->pclk); in atmel_qspi_resume()
816 ret = clk_prepare(aq->qspick); in atmel_qspi_resume()
818 clk_unprepare(aq->pclk); in atmel_qspi_resume()
828 atmel_qspi_write(aq->scr, aq, QSPI_SCR); in atmel_qspi_resume()
841 clk_disable(aq->qspick); in atmel_qspi_runtime_suspend()
842 clk_disable(aq->pclk); in atmel_qspi_runtime_suspend()
853 ret = clk_enable(aq->pclk); in atmel_qspi_runtime_resume()
857 ret = clk_enable(aq->qspick); in atmel_qspi_runtime_resume()
859 clk_disable(aq->pclk); in atmel_qspi_runtime_resume()
879 .compatible = "atmel,sama5d2-qspi",
883 .compatible = "microchip,sam9x60-qspi",