Lines Matching +full:op +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
18 #include <linux/spi/spi-mem.h>
72 #define OP_CMD_BYTES(x) (((x) - 1) << 13)
181 ret = clk_prepare_enable(mxic->send_clk); in mxic_spi_clk_enable()
185 ret = clk_prepare_enable(mxic->send_dly_clk); in mxic_spi_clk_enable()
192 clk_disable_unprepare(mxic->send_clk); in mxic_spi_clk_enable()
199 clk_disable_unprepare(mxic->send_clk); in mxic_spi_clk_disable()
200 clk_disable_unprepare(mxic->send_dly_clk); in mxic_spi_clk_disable()
209 mxic->regs + IDLY_CODE(0)); in mxic_spi_set_input_delay_dqs()
214 mxic->regs + IDLY_CODE(1)); in mxic_spi_set_input_delay_dqs()
221 ret = clk_set_rate(mxic->send_clk, freq); in mxic_spi_clk_setup()
225 ret = clk_set_rate(mxic->send_dly_clk, freq); in mxic_spi_clk_setup()
236 * Phase degree = 360 * freq * output-delay in mxic_spi_clk_setup()
237 * where output-delay is a constant value 1 ns in FPGA. in mxic_spi_clk_setup()
243 ret = clk_set_phase(mxic->send_dly_clk, 9 * freq / 25000000); in mxic_spi_clk_setup()
254 if (mxic->cur_speed_hz == freq) in mxic_spi_set_freq()
266 mxic->cur_speed_hz = freq; in mxic_spi_set_freq()
273 writel(0, mxic->regs + DATA_STROB); in mxic_spi_hw_init()
274 writel(INT_STS_ALL, mxic->regs + INT_STS_EN); in mxic_spi_hw_init()
275 writel(0, mxic->regs + HC_EN); in mxic_spi_hw_init()
276 writel(0, mxic->regs + LRD_CFG); in mxic_spi_hw_init()
277 writel(0, mxic->regs + LRD_CTRL); in mxic_spi_hw_init()
280 mxic->regs + HC_CFG); in mxic_spi_hw_init()
289 unsigned int nbytes = len - pos; in mxic_spi_data_xfer()
300 ret = readl_poll_timeout(mxic->regs + INT_STS, sts, in mxic_spi_data_xfer()
305 writel(data, mxic->regs + TXD(nbytes % 4)); in mxic_spi_data_xfer()
308 ret = readl_poll_timeout(mxic->regs + INT_STS, sts, in mxic_spi_data_xfer()
314 ret = readl_poll_timeout(mxic->regs + INT_STS, sts, in mxic_spi_data_xfer()
320 data = readl(mxic->regs + RXD); in mxic_spi_data_xfer()
321 data >>= (8 * (4 - nbytes)); in mxic_spi_data_xfer()
323 WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); in mxic_spi_data_xfer()
325 readl(mxic->regs + RXD); in mxic_spi_data_xfer()
327 WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); in mxic_spi_data_xfer()
336 const struct spi_mem_op *op) in mxic_spi_mem_supports_op() argument
338 if (op->data.buswidth > 4 || op->addr.buswidth > 4 || in mxic_spi_mem_supports_op()
339 op->dummy.buswidth > 4 || op->cmd.buswidth > 4) in mxic_spi_mem_supports_op()
342 if (op->data.nbytes && op->dummy.nbytes && in mxic_spi_mem_supports_op()
343 op->data.buswidth != op->dummy.buswidth) in mxic_spi_mem_supports_op()
346 if (op->addr.nbytes > 7) in mxic_spi_mem_supports_op()
349 return spi_mem_default_supports_op(mem, op); in mxic_spi_mem_supports_op()
353 const struct spi_mem_op *op) in mxic_spi_mem_exec_op() argument
355 struct mxic_spi *mxic = spi_master_get_devdata(mem->spi->master); in mxic_spi_mem_exec_op()
359 u8 opcode = op->cmd.opcode; in mxic_spi_mem_exec_op()
361 ret = mxic_spi_set_freq(mxic, mem->spi->max_speed_hz); in mxic_spi_mem_exec_op()
365 if (mem->spi->mode & (SPI_TX_QUAD | SPI_RX_QUAD)) in mxic_spi_mem_exec_op()
367 else if (mem->spi->mode & (SPI_TX_DUAL | SPI_RX_DUAL)) in mxic_spi_mem_exec_op()
371 HC_CFG_TYPE(mem->spi->chip_select, HC_CFG_TYPE_SPI_NOR) | in mxic_spi_mem_exec_op()
372 HC_CFG_SLV_ACT(mem->spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1) | in mxic_spi_mem_exec_op()
374 mxic->regs + HC_CFG); in mxic_spi_mem_exec_op()
375 writel(HC_EN_BIT, mxic->regs + HC_EN); in mxic_spi_mem_exec_op()
377 ss_ctrl = OP_CMD_BYTES(1) | OP_CMD_BUSW(fls(op->cmd.buswidth) - 1); in mxic_spi_mem_exec_op()
379 if (op->addr.nbytes) in mxic_spi_mem_exec_op()
380 ss_ctrl |= OP_ADDR_BYTES(op->addr.nbytes) | in mxic_spi_mem_exec_op()
381 OP_ADDR_BUSW(fls(op->addr.buswidth) - 1); in mxic_spi_mem_exec_op()
383 if (op->dummy.nbytes) in mxic_spi_mem_exec_op()
384 ss_ctrl |= OP_DUMMY_CYC(op->dummy.nbytes); in mxic_spi_mem_exec_op()
386 if (op->data.nbytes) { in mxic_spi_mem_exec_op()
387 ss_ctrl |= OP_DATA_BUSW(fls(op->data.buswidth) - 1); in mxic_spi_mem_exec_op()
388 if (op->data.dir == SPI_MEM_DATA_IN) in mxic_spi_mem_exec_op()
392 writel(ss_ctrl, mxic->regs + SS_CTRL(mem->spi->chip_select)); in mxic_spi_mem_exec_op()
394 writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, in mxic_spi_mem_exec_op()
395 mxic->regs + HC_CFG); in mxic_spi_mem_exec_op()
401 for (i = 0; i < op->addr.nbytes; i++) in mxic_spi_mem_exec_op()
402 addr[i] = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); in mxic_spi_mem_exec_op()
404 ret = mxic_spi_data_xfer(mxic, addr, NULL, op->addr.nbytes); in mxic_spi_mem_exec_op()
408 ret = mxic_spi_data_xfer(mxic, NULL, NULL, op->dummy.nbytes); in mxic_spi_mem_exec_op()
413 op->data.dir == SPI_MEM_DATA_OUT ? in mxic_spi_mem_exec_op()
414 op->data.buf.out : NULL, in mxic_spi_mem_exec_op()
415 op->data.dir == SPI_MEM_DATA_IN ? in mxic_spi_mem_exec_op()
416 op->data.buf.in : NULL, in mxic_spi_mem_exec_op()
417 op->data.nbytes); in mxic_spi_mem_exec_op()
420 writel(readl(mxic->regs + HC_CFG) & ~HC_CFG_MAN_CS_ASSERT, in mxic_spi_mem_exec_op()
421 mxic->regs + HC_CFG); in mxic_spi_mem_exec_op()
422 writel(0, mxic->regs + HC_EN); in mxic_spi_mem_exec_op()
434 struct mxic_spi *mxic = spi_master_get_devdata(spi->master); in mxic_spi_set_cs()
437 writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_EN, in mxic_spi_set_cs()
438 mxic->regs + HC_CFG); in mxic_spi_set_cs()
439 writel(HC_EN_BIT, mxic->regs + HC_EN); in mxic_spi_set_cs()
440 writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT, in mxic_spi_set_cs()
441 mxic->regs + HC_CFG); in mxic_spi_set_cs()
443 writel(readl(mxic->regs + HC_CFG) & ~HC_CFG_MAN_CS_ASSERT, in mxic_spi_set_cs()
444 mxic->regs + HC_CFG); in mxic_spi_set_cs()
445 writel(0, mxic->regs + HC_EN); in mxic_spi_set_cs()
457 if (t->rx_buf && t->tx_buf) { in mxic_spi_transfer_one()
458 if (((spi->mode & SPI_TX_QUAD) && in mxic_spi_transfer_one()
459 !(spi->mode & SPI_RX_QUAD)) || in mxic_spi_transfer_one()
460 ((spi->mode & SPI_TX_DUAL) && in mxic_spi_transfer_one()
461 !(spi->mode & SPI_RX_DUAL))) in mxic_spi_transfer_one()
462 return -ENOTSUPP; in mxic_spi_transfer_one()
465 ret = mxic_spi_set_freq(mxic, t->speed_hz); in mxic_spi_transfer_one()
469 if (t->tx_buf) { in mxic_spi_transfer_one()
470 if (spi->mode & SPI_TX_QUAD) in mxic_spi_transfer_one()
472 else if (spi->mode & SPI_TX_DUAL) in mxic_spi_transfer_one()
474 } else if (t->rx_buf) { in mxic_spi_transfer_one()
475 if (spi->mode & SPI_RX_QUAD) in mxic_spi_transfer_one()
477 else if (spi->mode & SPI_RX_DUAL) in mxic_spi_transfer_one()
482 OP_DATA_BUSW(busw) | (t->rx_buf ? OP_READ : 0), in mxic_spi_transfer_one()
483 mxic->regs + SS_CTRL(0)); in mxic_spi_transfer_one()
485 ret = mxic_spi_data_xfer(mxic, t->tx_buf, t->rx_buf, t->len); in mxic_spi_transfer_one()
500 clk_disable_unprepare(mxic->ps_clk); in mxic_spi_runtime_suspend()
511 ret = clk_prepare_enable(mxic->ps_clk); in mxic_spi_runtime_resume()
532 master = devm_spi_alloc_master(&pdev->dev, sizeof(struct mxic_spi)); in mxic_spi_probe()
534 return -ENOMEM; in mxic_spi_probe()
540 master->dev.of_node = pdev->dev.of_node; in mxic_spi_probe()
542 mxic->ps_clk = devm_clk_get(&pdev->dev, "ps_clk"); in mxic_spi_probe()
543 if (IS_ERR(mxic->ps_clk)) in mxic_spi_probe()
544 return PTR_ERR(mxic->ps_clk); in mxic_spi_probe()
546 mxic->send_clk = devm_clk_get(&pdev->dev, "send_clk"); in mxic_spi_probe()
547 if (IS_ERR(mxic->send_clk)) in mxic_spi_probe()
548 return PTR_ERR(mxic->send_clk); in mxic_spi_probe()
550 mxic->send_dly_clk = devm_clk_get(&pdev->dev, "send_dly_clk"); in mxic_spi_probe()
551 if (IS_ERR(mxic->send_dly_clk)) in mxic_spi_probe()
552 return PTR_ERR(mxic->send_dly_clk); in mxic_spi_probe()
555 mxic->regs = devm_ioremap_resource(&pdev->dev, res); in mxic_spi_probe()
556 if (IS_ERR(mxic->regs)) in mxic_spi_probe()
557 return PTR_ERR(mxic->regs); in mxic_spi_probe()
559 pm_runtime_enable(&pdev->dev); in mxic_spi_probe()
560 master->auto_runtime_pm = true; in mxic_spi_probe()
562 master->num_chipselect = 1; in mxic_spi_probe()
563 master->mem_ops = &mxic_spi_mem_ops; in mxic_spi_probe()
565 master->set_cs = mxic_spi_set_cs; in mxic_spi_probe()
566 master->transfer_one = mxic_spi_transfer_one; in mxic_spi_probe()
567 master->bits_per_word_mask = SPI_BPW_MASK(8); in mxic_spi_probe()
568 master->mode_bits = SPI_CPOL | SPI_CPHA | in mxic_spi_probe()
576 dev_err(&pdev->dev, "spi_register_master failed\n"); in mxic_spi_probe()
577 pm_runtime_disable(&pdev->dev); in mxic_spi_probe()
587 pm_runtime_disable(&pdev->dev); in mxic_spi_remove()
594 { .compatible = "mxicy,mx25f0a-spi", },
603 .name = "mxic-spi",