Lines Matching +full:quad +full:- +full:core

1 // SPDX-License-Identifier: (GPL-2.0)
5 * Copyright (C) 2018-2022 Microchip Technology Inc. and its subsidiaries
22 #include <linux/spi/spi-mem.h>
103 * struct mchp_coreqspi - Defines qspi driver instance
128 u32 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_set_mode()
138 * 0: 2-bits (BSPI) in mchp_coreqspi_set_mode()
139 * 1: 4-bits (QSPI) in mchp_coreqspi_set_mode()
141 if (op->data.buswidth == 4 || op->data.buswidth == 2) { in mchp_coreqspi_set_mode()
143 if (op->cmd.buswidth == 1 && (op->addr.buswidth == 1 || op->addr.buswidth == 0)) in mchp_coreqspi_set_mode()
145 else if (op->cmd.buswidth == 1) in mchp_coreqspi_set_mode()
156 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_set_mode()
165 if (!qspi->rx_len) in mchp_coreqspi_read_op()
168 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_read_op()
171 * Read 4-bytes from the SPI FIFO in single transaction and then read in mchp_coreqspi_read_op()
175 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_read_op()
177 while (qspi->rx_len >= 4) { in mchp_coreqspi_read_op()
178 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) in mchp_coreqspi_read_op()
180 data = readl_relaxed(qspi->regs + REG_X4_RX_DATA); in mchp_coreqspi_read_op()
181 *(u32 *)qspi->rxbuf = data; in mchp_coreqspi_read_op()
182 qspi->rxbuf += 4; in mchp_coreqspi_read_op()
183 qspi->rx_len -= 4; in mchp_coreqspi_read_op()
187 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_read_op()
189 while (qspi->rx_len--) { in mchp_coreqspi_read_op()
190 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) in mchp_coreqspi_read_op()
192 data = readl_relaxed(qspi->regs + REG_RX_DATA); in mchp_coreqspi_read_op()
193 *qspi->rxbuf++ = (data & 0xFF); in mchp_coreqspi_read_op()
201 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_write_op()
203 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_write_op()
205 while (qspi->tx_len >= 4) { in mchp_coreqspi_write_op()
206 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) in mchp_coreqspi_write_op()
208 data = *(u32 *)qspi->txbuf; in mchp_coreqspi_write_op()
209 qspi->txbuf += 4; in mchp_coreqspi_write_op()
210 qspi->tx_len -= 4; in mchp_coreqspi_write_op()
211 writel_relaxed(data, qspi->regs + REG_X4_TX_DATA); in mchp_coreqspi_write_op()
215 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_write_op()
217 while (qspi->tx_len--) { in mchp_coreqspi_write_op()
218 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) in mchp_coreqspi_write_op()
220 data = *qspi->txbuf++; in mchp_coreqspi_write_op()
221 writel_relaxed(data, qspi->regs + REG_TX_DATA); in mchp_coreqspi_write_op()
229 qspi->rx_len = qspi->tx_len; in mchp_coreqspi_write_read_op()
231 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_write_read_op()
233 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_write_read_op()
235 while (qspi->tx_len >= 4) { in mchp_coreqspi_write_read_op()
236 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) in mchp_coreqspi_write_read_op()
239 data = qspi->txbuf ? *((u32 *)qspi->txbuf) : 0xaa; in mchp_coreqspi_write_read_op()
240 if (qspi->txbuf) in mchp_coreqspi_write_read_op()
241 qspi->txbuf += 4; in mchp_coreqspi_write_read_op()
242 qspi->tx_len -= 4; in mchp_coreqspi_write_read_op()
243 writel_relaxed(data, qspi->regs + REG_X4_TX_DATA); in mchp_coreqspi_write_read_op()
250 * has been filled and becomes non-full due to a transmission in mchp_coreqspi_write_read_op()
254 if (qspi->rx_len >= 4) { in mchp_coreqspi_write_read_op()
255 if (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXAVAILABLE) { in mchp_coreqspi_write_read_op()
256 data = readl_relaxed(qspi->regs + REG_X4_RX_DATA); in mchp_coreqspi_write_read_op()
257 *(u32 *)qspi->rxbuf = data; in mchp_coreqspi_write_read_op()
258 qspi->rxbuf += 4; in mchp_coreqspi_write_read_op()
259 qspi->rx_len -= 4; in mchp_coreqspi_write_read_op()
269 while (qspi->rx_len >= 4) { in mchp_coreqspi_write_read_op()
270 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) in mchp_coreqspi_write_read_op()
272 data = readl_relaxed(qspi->regs + REG_X4_RX_DATA); in mchp_coreqspi_write_read_op()
273 *(u32 *)qspi->rxbuf = data; in mchp_coreqspi_write_read_op()
274 qspi->rxbuf += 4; in mchp_coreqspi_write_read_op()
275 qspi->rx_len -= 4; in mchp_coreqspi_write_read_op()
284 if (!qspi->tx_len) in mchp_coreqspi_write_read_op()
288 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_write_read_op()
290 while (qspi->tx_len--) { in mchp_coreqspi_write_read_op()
291 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) in mchp_coreqspi_write_read_op()
293 data = qspi->txbuf ? *qspi->txbuf : 0xaa; in mchp_coreqspi_write_read_op()
294 qspi->txbuf++; in mchp_coreqspi_write_read_op()
295 writel_relaxed(data, qspi->regs + REG_TX_DATA); in mchp_coreqspi_write_read_op()
298 while (qspi->rx_len--) { in mchp_coreqspi_write_read_op()
299 while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) in mchp_coreqspi_write_read_op()
301 data = readl_relaxed(qspi->regs + REG_RX_DATA); in mchp_coreqspi_write_read_op()
302 *qspi->rxbuf++ = (data & 0xFF); in mchp_coreqspi_write_read_op()
312 writel_relaxed(mask, qspi->regs + REG_IEN); in mchp_coreqspi_enable_ints()
317 writel_relaxed(0, qspi->regs + REG_IEN); in mchp_coreqspi_disable_ints()
324 int intfield = readl_relaxed(qspi->regs + REG_STATUS) & STATUS_MASK; in mchp_coreqspi_isr()
330 writel_relaxed(IEN_TXDONE, qspi->regs + REG_STATUS); in mchp_coreqspi_isr()
335 writel_relaxed(IEN_RXAVAILABLE, qspi->regs + REG_STATUS); in mchp_coreqspi_isr()
341 writel_relaxed(IEN_RXDONE, qspi->regs + REG_STATUS); in mchp_coreqspi_isr()
342 complete(&qspi->data_completion); in mchp_coreqspi_isr()
355 clk_hz = clk_get_rate(qspi->clk); in mchp_coreqspi_setup_clock()
357 return -EINVAL; in mchp_coreqspi_setup_clock()
361 dev_err(&spi->dev, in mchp_coreqspi_setup_clock()
364 return -EINVAL; in mchp_coreqspi_setup_clock()
367 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_clock()
370 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_clock()
371 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_clock()
373 if ((spi->mode & SPI_CPOL) && (spi->mode & SPI_CPHA)) in mchp_coreqspi_setup_clock()
378 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_clock()
385 struct spi_controller *ctlr = spi_dev->controller; in mchp_coreqspi_setup_op()
387 u32 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_op()
391 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_setup_op()
401 cmd_bytes = op->cmd.nbytes + op->addr.nbytes; in mchp_coreqspi_config_op()
402 total_bytes = cmd_bytes + op->data.nbytes; in mchp_coreqspi_config_op()
409 * --------------------------------------------------------------------- in mchp_coreqspi_config_op()
413 * 1 | 1 | The SPI core will transmit a single byte | in mchp_coreqspi_config_op()
416 * 1 | 0 | The SPI core will transmit a single byte | in mchp_coreqspi_config_op()
419 * 10 | 4 | The SPI core will transmit 4 command | in mchp_coreqspi_config_op()
424 * 10 | 10 | The SPI core will transmit 10 command | in mchp_coreqspi_config_op()
426 * 10 | 0 | The SPI core will transmit 10 command | in mchp_coreqspi_config_op()
430 if (!(op->data.dir == SPI_MEM_DATA_IN)) in mchp_coreqspi_config_op()
434 writel_relaxed(frames, qspi->regs + REG_FRAMESUP); in mchp_coreqspi_config_op()
438 if (op->dummy.buswidth) in mchp_coreqspi_config_op()
439 idle_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth; in mchp_coreqspi_config_op()
442 ctrl = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_config_op()
448 writel_relaxed(frames, qspi->regs + REG_FRAMES); in mchp_coreqspi_config_op()
455 return readl_poll_timeout(qspi->regs + REG_STATUS, status, in mchp_coreqspi_wait_for_ready()
463 (mem->spi->controller); in mchp_coreqspi_exec_op()
464 u32 address = op->addr.val; in mchp_coreqspi_exec_op()
465 u8 opcode = op->cmd.opcode; in mchp_coreqspi_exec_op()
469 mutex_lock(&qspi->op_lock); in mchp_coreqspi_exec_op()
472 dev_err(&mem->spi->dev, "Timeout waiting on QSPI ready.\n"); in mchp_coreqspi_exec_op()
476 err = mchp_coreqspi_setup_clock(qspi, mem->spi, op->max_freq); in mchp_coreqspi_exec_op()
484 reinit_completion(&qspi->data_completion); in mchp_coreqspi_exec_op()
486 if (op->cmd.opcode) { in mchp_coreqspi_exec_op()
487 qspi->txbuf = &opcode; in mchp_coreqspi_exec_op()
488 qspi->rxbuf = NULL; in mchp_coreqspi_exec_op()
489 qspi->tx_len = op->cmd.nbytes; in mchp_coreqspi_exec_op()
490 qspi->rx_len = 0; in mchp_coreqspi_exec_op()
494 qspi->txbuf = &opaddr[0]; in mchp_coreqspi_exec_op()
495 if (op->addr.nbytes) { in mchp_coreqspi_exec_op()
496 for (i = 0; i < op->addr.nbytes; i++) in mchp_coreqspi_exec_op()
497 qspi->txbuf[i] = address >> (8 * (op->addr.nbytes - i - 1)); in mchp_coreqspi_exec_op()
499 qspi->rxbuf = NULL; in mchp_coreqspi_exec_op()
500 qspi->tx_len = op->addr.nbytes; in mchp_coreqspi_exec_op()
501 qspi->rx_len = 0; in mchp_coreqspi_exec_op()
505 if (op->data.nbytes) { in mchp_coreqspi_exec_op()
506 if (op->data.dir == SPI_MEM_DATA_OUT) { in mchp_coreqspi_exec_op()
507 qspi->txbuf = (u8 *)op->data.buf.out; in mchp_coreqspi_exec_op()
508 qspi->rxbuf = NULL; in mchp_coreqspi_exec_op()
509 qspi->rx_len = 0; in mchp_coreqspi_exec_op()
510 qspi->tx_len = op->data.nbytes; in mchp_coreqspi_exec_op()
513 qspi->txbuf = NULL; in mchp_coreqspi_exec_op()
514 qspi->rxbuf = (u8 *)op->data.buf.in; in mchp_coreqspi_exec_op()
515 qspi->rx_len = op->data.nbytes; in mchp_coreqspi_exec_op()
516 qspi->tx_len = 0; in mchp_coreqspi_exec_op()
522 if (!wait_for_completion_timeout(&qspi->data_completion, msecs_to_jiffies(1000))) in mchp_coreqspi_exec_op()
523 err = -ETIMEDOUT; in mchp_coreqspi_exec_op()
526 mutex_unlock(&qspi->op_lock); in mchp_coreqspi_exec_op()
537 if ((op->data.buswidth == 4 || op->data.buswidth == 2) && in mchp_coreqspi_supports_op()
538 (op->cmd.buswidth == 1 && (op->addr.buswidth == 1 || op->addr.buswidth == 0))) { in mchp_coreqspi_supports_op()
542 * quad lines. but it supports reading data on dual and in mchp_coreqspi_supports_op()
543 * quad lines with same configuration as command and in mchp_coreqspi_supports_op()
548 * Ex: 0x34h is Quad Load Program Data which is not in mchp_coreqspi_supports_op()
549 * supported. Then the spi-mem layer will iterate over in mchp_coreqspi_supports_op()
552 if (op->data.dir == SPI_MEM_DATA_OUT) in mchp_coreqspi_supports_op()
561 if (op->data.dir == SPI_MEM_DATA_OUT || op->data.dir == SPI_MEM_DATA_IN) { in mchp_coreqspi_adjust_op_size()
562 if (op->data.nbytes > MAX_DATA_CMD_LEN) in mchp_coreqspi_adjust_op_size()
563 op->data.nbytes = MAX_DATA_CMD_LEN; in mchp_coreqspi_adjust_op_size()
589 mutex_unlock(&qspi->op_lock); in mchp_coreqspi_unprepare_message()
601 bool quad = false, dual = false; in mchp_coreqspi_prepare_message() local
603 mutex_lock(&qspi->op_lock); in mchp_coreqspi_prepare_message()
606 mutex_unlock(&qspi->op_lock); in mchp_coreqspi_prepare_message()
607 dev_err(&ctlr->dev, "Timeout waiting on QSPI ready.\n"); in mchp_coreqspi_prepare_message()
611 ret = mchp_coreqspi_setup_clock(qspi, m->spi, m->spi->max_speed_hz); in mchp_coreqspi_prepare_message()
613 mutex_unlock(&qspi->op_lock); in mchp_coreqspi_prepare_message()
617 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_prepare_message()
619 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_prepare_message()
621 reinit_completion(&qspi->data_completion); in mchp_coreqspi_prepare_message()
623 list_for_each_entry(t, &m->transfers, transfer_list) { in mchp_coreqspi_prepare_message()
624 total_bytes += t->len; in mchp_coreqspi_prepare_message()
625 if (!cmd_bytes && !(t->tx_buf && t->rx_buf)) in mchp_coreqspi_prepare_message()
626 cmd_bytes = t->len; in mchp_coreqspi_prepare_message()
627 if (!t->rx_buf) in mchp_coreqspi_prepare_message()
629 if (t->tx_nbits == SPI_NBITS_QUAD || t->rx_nbits == SPI_NBITS_QUAD) in mchp_coreqspi_prepare_message()
630 quad = true; in mchp_coreqspi_prepare_message()
631 else if (t->tx_nbits == SPI_NBITS_DUAL || t->rx_nbits == SPI_NBITS_DUAL) in mchp_coreqspi_prepare_message()
635 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_prepare_message()
636 if (quad) { in mchp_coreqspi_prepare_message()
644 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_prepare_message()
647 writel_relaxed(frames, qspi->regs + REG_FRAMESUP); in mchp_coreqspi_prepare_message()
651 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_prepare_message()
656 writel_relaxed(frames, qspi->regs + REG_FRAMES); in mchp_coreqspi_prepare_message()
666 qspi->tx_len = t->len; in mchp_coreqspi_transfer_one()
668 if (t->tx_buf) in mchp_coreqspi_transfer_one()
669 qspi->txbuf = (u8 *)t->tx_buf; in mchp_coreqspi_transfer_one()
671 if (!t->rx_buf) { in mchp_coreqspi_transfer_one()
674 qspi->rxbuf = (u8 *)t->rx_buf; in mchp_coreqspi_transfer_one()
675 qspi->rx_len = t->len; in mchp_coreqspi_transfer_one()
686 struct device *dev = &pdev->dev; in mchp_coreqspi_probe()
687 struct device_node *np = dev->of_node; in mchp_coreqspi_probe()
690 ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*qspi)); in mchp_coreqspi_probe()
692 return -ENOMEM; in mchp_coreqspi_probe()
697 qspi->regs = devm_platform_ioremap_resource(pdev, 0); in mchp_coreqspi_probe()
698 if (IS_ERR(qspi->regs)) in mchp_coreqspi_probe()
699 return dev_err_probe(&pdev->dev, PTR_ERR(qspi->regs), in mchp_coreqspi_probe()
702 qspi->clk = devm_clk_get_enabled(&pdev->dev, NULL); in mchp_coreqspi_probe()
703 if (IS_ERR(qspi->clk)) in mchp_coreqspi_probe()
704 return dev_err_probe(&pdev->dev, PTR_ERR(qspi->clk), in mchp_coreqspi_probe()
707 init_completion(&qspi->data_completion); in mchp_coreqspi_probe()
708 mutex_init(&qspi->op_lock); in mchp_coreqspi_probe()
710 qspi->irq = platform_get_irq(pdev, 0); in mchp_coreqspi_probe()
711 if (qspi->irq < 0) in mchp_coreqspi_probe()
712 return qspi->irq; in mchp_coreqspi_probe()
714 ret = devm_request_irq(&pdev->dev, qspi->irq, mchp_coreqspi_isr, in mchp_coreqspi_probe()
715 IRQF_SHARED, pdev->name, qspi); in mchp_coreqspi_probe()
717 dev_err(&pdev->dev, "request_irq failed %d\n", ret); in mchp_coreqspi_probe()
721 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); in mchp_coreqspi_probe()
722 ctlr->mem_ops = &mchp_coreqspi_mem_ops; in mchp_coreqspi_probe()
723 ctlr->mem_caps = &mchp_coreqspi_mem_caps; in mchp_coreqspi_probe()
724 ctlr->setup = mchp_coreqspi_setup_op; in mchp_coreqspi_probe()
725 ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD | in mchp_coreqspi_probe()
727 ctlr->dev.of_node = np; in mchp_coreqspi_probe()
728 ctlr->min_speed_hz = clk_get_rate(qspi->clk) / 30; in mchp_coreqspi_probe()
729 ctlr->prepare_message = mchp_coreqspi_prepare_message; in mchp_coreqspi_probe()
730 ctlr->unprepare_message = mchp_coreqspi_unprepare_message; in mchp_coreqspi_probe()
731 ctlr->transfer_one = mchp_coreqspi_transfer_one; in mchp_coreqspi_probe()
732 ctlr->num_chipselect = 2; in mchp_coreqspi_probe()
733 ctlr->use_gpio_descriptors = true; in mchp_coreqspi_probe()
735 ret = devm_spi_register_controller(&pdev->dev, ctlr); in mchp_coreqspi_probe()
737 return dev_err_probe(&pdev->dev, ret, in mchp_coreqspi_probe()
746 u32 control = readl_relaxed(qspi->regs + REG_CONTROL); in mchp_coreqspi_remove()
750 writel_relaxed(control, qspi->regs + REG_CONTROL); in mchp_coreqspi_remove()
754 { .compatible = "microchip,coreqspi-rtl-v2" },