Lines Matching +full:quadspi +full:- +full:memory
1 // SPDX-License-Identifier: GPL-2.0
11 * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
24 #include <linux/spi/spi-mem.h>
68 #define QSPI_MR_NBBITS(n) ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
227 u32 value = readl_relaxed(aq->regs + offset); in atmel_qspi_read()
232 dev_vdbg(&aq->pdev->dev, "read 0x%08x from %s\n", value, in atmel_qspi_read()
244 dev_vdbg(&aq->pdev->dev, "write 0x%08x into %s\n", value, in atmel_qspi_write()
248 writel_relaxed(value, aq->regs + offset); in atmel_qspi_write()
254 if (op->cmd.buswidth != mode->cmd_buswidth) in atmel_qspi_is_compatible()
257 if (op->addr.nbytes && op->addr.buswidth != mode->addr_buswidth) in atmel_qspi_is_compatible()
260 if (op->data.nbytes && op->data.buswidth != mode->data_buswidth) in atmel_qspi_is_compatible()
274 return -ENOTSUPP; in atmel_qspi_find_mode()
287 if (op->addr.nbytes == 2 && op->cmd.buswidth != op->addr.buswidth && in atmel_qspi_supports_op()
288 op->dummy.nbytes == 0) in atmel_qspi_supports_op()
292 if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) in atmel_qspi_supports_op()
294 if (op->cmd.nbytes != 1) in atmel_qspi_supports_op()
308 icr = QSPI_ICR_INST(op->cmd.opcode); in atmel_qspi_set_cfg()
316 if (op->dummy.buswidth && op->dummy.nbytes) in atmel_qspi_set_cfg()
317 dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth; in atmel_qspi_set_cfg()
320 * The controller allows 24 and 32-bit addressing while NAND-flash in atmel_qspi_set_cfg()
321 * requires 16-bit long. Handling 8-bit long addresses is done using in atmel_qspi_set_cfg()
322 * the option field. For the 16-bit addresses, the workaround depends in atmel_qspi_set_cfg()
327 * use the same buswidth). The limitation is when the 16-bit address is in atmel_qspi_set_cfg()
331 if (op->addr.buswidth) { in atmel_qspi_set_cfg()
332 switch (op->addr.nbytes) { in atmel_qspi_set_cfg()
337 icr |= QSPI_ICR_OPT(op->addr.val & 0xff); in atmel_qspi_set_cfg()
340 if (dummy_cycles < 8 / op->addr.buswidth) { in atmel_qspi_set_cfg()
343 iar = (op->cmd.opcode << 16) | in atmel_qspi_set_cfg()
344 (op->addr.val & 0xffff); in atmel_qspi_set_cfg()
347 iar = (op->addr.val << 8) & 0xffffff; in atmel_qspi_set_cfg()
348 dummy_cycles -= 8 / op->addr.buswidth; in atmel_qspi_set_cfg()
353 iar = op->addr.val & 0xffffff; in atmel_qspi_set_cfg()
357 iar = op->addr.val & 0x7ffffff; in atmel_qspi_set_cfg()
360 return -ENOTSUPP; in atmel_qspi_set_cfg()
364 /* offset of the data access in the QSPI memory space */ in atmel_qspi_set_cfg()
372 if (op->data.nbytes) { in atmel_qspi_set_cfg()
375 if (op->addr.nbytes) in atmel_qspi_set_cfg()
381 * Serial Memory Mode (SMM). in atmel_qspi_set_cfg()
383 if (aq->mr != QSPI_MR_SMM) { in atmel_qspi_set_cfg()
385 aq->mr = QSPI_MR_SMM; in atmel_qspi_set_cfg()
391 if (aq->caps->has_ricr) { in atmel_qspi_set_cfg()
392 if (!op->addr.nbytes && op->data.dir == SPI_MEM_DATA_IN) in atmel_qspi_set_cfg()
397 if (op->data.dir == SPI_MEM_DATA_IN) in atmel_qspi_set_cfg()
403 if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) in atmel_qspi_set_cfg()
417 struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->master); in atmel_qspi_exec_op()
424 * when the flash memories overrun the controller's memory space. in atmel_qspi_exec_op()
426 if (op->addr.val + op->data.nbytes > aq->mmap_size) in atmel_qspi_exec_op()
427 return -ENOTSUPP; in atmel_qspi_exec_op()
434 if (op->data.nbytes) { in atmel_qspi_exec_op()
439 if (op->data.dir == SPI_MEM_DATA_IN) in atmel_qspi_exec_op()
440 memcpy_fromio(op->data.buf.in, aq->mem + offset, in atmel_qspi_exec_op()
441 op->data.nbytes); in atmel_qspi_exec_op()
443 memcpy_toio(aq->mem + offset, op->data.buf.out, in atmel_qspi_exec_op()
444 op->data.nbytes); in atmel_qspi_exec_op()
446 /* Release the chip-select */ in atmel_qspi_exec_op()
456 reinit_completion(&aq->cmd_completion); in atmel_qspi_exec_op()
457 aq->pending = sr & QSPI_SR_CMD_COMPLETED; in atmel_qspi_exec_op()
459 if (!wait_for_completion_timeout(&aq->cmd_completion, in atmel_qspi_exec_op()
461 err = -ETIMEDOUT; in atmel_qspi_exec_op()
469 return dev_name(spimem->spi->dev.parent); in atmel_qspi_get_name()
480 struct spi_controller *ctrl = spi->master; in atmel_qspi_setup()
485 if (ctrl->busy) in atmel_qspi_setup()
486 return -EBUSY; in atmel_qspi_setup()
488 if (!spi->max_speed_hz) in atmel_qspi_setup()
489 return -EINVAL; in atmel_qspi_setup()
491 src_rate = clk_get_rate(aq->pclk); in atmel_qspi_setup()
493 return -EINVAL; in atmel_qspi_setup()
496 scbr = DIV_ROUND_UP(src_rate, spi->max_speed_hz); in atmel_qspi_setup()
498 scbr--; in atmel_qspi_setup()
500 aq->scr = QSPI_SCR_SCBR(scbr); in atmel_qspi_setup()
501 atmel_qspi_write(aq->scr, aq, QSPI_SCR); in atmel_qspi_setup()
511 /* Set the QSPI controller by default in Serial Memory Mode */ in atmel_qspi_init()
513 aq->mr = QSPI_MR_SMM; in atmel_qspi_init()
531 aq->pending |= pending; in atmel_qspi_interrupt()
532 if ((aq->pending & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) in atmel_qspi_interrupt()
533 complete(&aq->cmd_completion); in atmel_qspi_interrupt()
545 ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*aq)); in atmel_qspi_probe()
547 return -ENOMEM; in atmel_qspi_probe()
549 ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; in atmel_qspi_probe()
550 ctrl->setup = atmel_qspi_setup; in atmel_qspi_probe()
551 ctrl->bus_num = -1; in atmel_qspi_probe()
552 ctrl->mem_ops = &atmel_qspi_mem_ops; in atmel_qspi_probe()
553 ctrl->num_chipselect = 1; in atmel_qspi_probe()
554 ctrl->dev.of_node = pdev->dev.of_node; in atmel_qspi_probe()
559 init_completion(&aq->cmd_completion); in atmel_qspi_probe()
560 aq->pdev = pdev; in atmel_qspi_probe()
564 aq->regs = devm_ioremap_resource(&pdev->dev, res); in atmel_qspi_probe()
565 if (IS_ERR(aq->regs)) { in atmel_qspi_probe()
566 dev_err(&pdev->dev, "missing registers\n"); in atmel_qspi_probe()
567 return PTR_ERR(aq->regs); in atmel_qspi_probe()
570 /* Map the AHB memory */ in atmel_qspi_probe()
572 aq->mem = devm_ioremap_resource(&pdev->dev, res); in atmel_qspi_probe()
573 if (IS_ERR(aq->mem)) { in atmel_qspi_probe()
574 dev_err(&pdev->dev, "missing AHB memory\n"); in atmel_qspi_probe()
575 return PTR_ERR(aq->mem); in atmel_qspi_probe()
578 aq->mmap_size = resource_size(res); in atmel_qspi_probe()
581 aq->pclk = devm_clk_get(&pdev->dev, "pclk"); in atmel_qspi_probe()
582 if (IS_ERR(aq->pclk)) in atmel_qspi_probe()
583 aq->pclk = devm_clk_get(&pdev->dev, NULL); in atmel_qspi_probe()
585 if (IS_ERR(aq->pclk)) { in atmel_qspi_probe()
586 dev_err(&pdev->dev, "missing peripheral clock\n"); in atmel_qspi_probe()
587 return PTR_ERR(aq->pclk); in atmel_qspi_probe()
591 err = clk_prepare_enable(aq->pclk); in atmel_qspi_probe()
593 dev_err(&pdev->dev, "failed to enable the peripheral clock\n"); in atmel_qspi_probe()
597 aq->caps = of_device_get_match_data(&pdev->dev); in atmel_qspi_probe()
598 if (!aq->caps) { in atmel_qspi_probe()
599 dev_err(&pdev->dev, "Could not retrieve QSPI caps\n"); in atmel_qspi_probe()
600 err = -EINVAL; in atmel_qspi_probe()
604 if (aq->caps->has_qspick) { in atmel_qspi_probe()
606 aq->qspick = devm_clk_get(&pdev->dev, "qspick"); in atmel_qspi_probe()
607 if (IS_ERR(aq->qspick)) { in atmel_qspi_probe()
608 dev_err(&pdev->dev, "missing system clock\n"); in atmel_qspi_probe()
609 err = PTR_ERR(aq->qspick); in atmel_qspi_probe()
614 err = clk_prepare_enable(aq->qspick); in atmel_qspi_probe()
616 dev_err(&pdev->dev, in atmel_qspi_probe()
628 err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt, in atmel_qspi_probe()
629 0, dev_name(&pdev->dev), aq); in atmel_qspi_probe()
642 clk_disable_unprepare(aq->qspick); in atmel_qspi_probe()
644 clk_disable_unprepare(aq->pclk); in atmel_qspi_probe()
656 clk_disable_unprepare(aq->qspick); in atmel_qspi_remove()
657 clk_disable_unprepare(aq->pclk); in atmel_qspi_remove()
666 clk_disable_unprepare(aq->qspick); in atmel_qspi_suspend()
667 clk_disable_unprepare(aq->pclk); in atmel_qspi_suspend()
677 clk_prepare_enable(aq->pclk); in atmel_qspi_resume()
678 clk_prepare_enable(aq->qspick); in atmel_qspi_resume()
682 atmel_qspi_write(aq->scr, aq, QSPI_SCR); in atmel_qspi_resume()
699 .compatible = "atmel,sama5d2-qspi",
703 .compatible = "microchip,sam9x60-qspi",