Lines Matching +full:versal +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0+
5 * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
9 #include <asm/arch/clk.h>
13 #include <clk.h>
176 struct zynqmp_qspi_platdata *plat = bus->platdata; in zynqmp_qspi_ofdata_to_platdata()
180 plat->regs = (struct zynqmp_qspi_regs *)(devfdt_get_addr(bus) + in zynqmp_qspi_ofdata_to_platdata()
182 plat->dma_regs = (struct zynqmp_qspi_dma_regs *) in zynqmp_qspi_ofdata_to_platdata()
191 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_init_hw()
193 writel(GQSPI_GFIFO_SELECT, &regs->gqspisel); in zynqmp_qspi_init_hw()
194 writel(GQSPI_GFIFO_ALL_INT_MASK, &regs->idisr); in zynqmp_qspi_init_hw()
195 writel(GQSPI_FIFO_THRESHOLD, &regs->txftr); in zynqmp_qspi_init_hw()
196 writel(GQSPI_FIFO_THRESHOLD, &regs->rxftr); in zynqmp_qspi_init_hw()
197 writel(GQSPI_GFIFO_ALL_INT_MASK, &regs->isr); in zynqmp_qspi_init_hw()
199 config_reg = readl(&regs->confr); in zynqmp_qspi_init_hw()
205 writel(config_reg, &regs->confr); in zynqmp_qspi_init_hw()
207 writel(GQSPI_ENABLE_ENABLE_MASK, &regs->enbr); in zynqmp_qspi_init_hw()
223 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_fill_gen_fifo()
226 ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_GFEMTY_MASK, 1, in zynqmp_qspi_fill_gen_fifo()
231 writel(gqspi_fifo_reg, &regs->genfifo); in zynqmp_qspi_fill_gen_fifo()
254 struct zynqmp_qspi_platdata *plat = bus->platdata; in zynqmp_qspi_set_tapdelay()
256 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_set_tapdelay()
260 clk_rate = plat->frequency; in zynqmp_qspi_set_tapdelay()
274 lpbkdlyadj = readl(&regs->lpbkdly); in zynqmp_qspi_set_tapdelay()
276 datadlyadj = readl(&regs->gqspidlyadj); in zynqmp_qspi_set_tapdelay()
281 lpbkdlyadj = readl(&regs->lpbkdly); in zynqmp_qspi_set_tapdelay()
288 writel(lpbkdlyadj, &regs->lpbkdly); in zynqmp_qspi_set_tapdelay()
289 writel(datadlyadj, &regs->gqspidlyadj); in zynqmp_qspi_set_tapdelay()
294 struct zynqmp_qspi_platdata *plat = bus->platdata; in zynqmp_qspi_set_speed()
296 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_set_speed()
301 if (speed > plat->frequency) in zynqmp_qspi_set_speed()
302 speed = plat->frequency; in zynqmp_qspi_set_speed()
305 confr = readl(&regs->confr); in zynqmp_qspi_set_speed()
309 } else if (plat->speed_hz != speed) { in zynqmp_qspi_set_speed()
311 ((plat->frequency / in zynqmp_qspi_set_speed()
318 plat->speed_hz = plat->frequency / (2 << baud_rate_val); in zynqmp_qspi_set_speed()
322 writel(confr, &regs->confr); in zynqmp_qspi_set_speed()
325 debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz); in zynqmp_qspi_set_speed()
334 struct clk clk; in zynqmp_qspi_probe() local
340 priv->regs = plat->regs; in zynqmp_qspi_probe()
341 priv->dma_regs = plat->dma_regs; in zynqmp_qspi_probe()
343 ret = clk_get_by_index(bus, 0, &clk); in zynqmp_qspi_probe()
349 clock = clk_get_rate(&clk); in zynqmp_qspi_probe()
354 debug("%s: CLK %ld\n", __func__, clock); in zynqmp_qspi_probe()
356 ret = clk_enable(&clk); in zynqmp_qspi_probe()
357 if (ret && ret != -ENOSYS) { in zynqmp_qspi_probe()
361 plat->frequency = clock; in zynqmp_qspi_probe()
362 plat->speed_hz = plat->frequency / 2; in zynqmp_qspi_probe()
373 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_set_mode()
378 confr = readl(&regs->confr); in zynqmp_qspi_set_mode()
387 writel(confr, &regs->confr); in zynqmp_qspi_set_mode()
396 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_fill_tx_fifo()
397 u32 *buf = (u32 *)priv->tx_buf; in zynqmp_qspi_fill_tx_fifo()
400 debug("TxFIFO: 0x%x, size: 0x%x\n", readl(&regs->isr), in zynqmp_qspi_fill_tx_fifo()
404 ret = wait_for_bit_le32(&regs->isr, GQSPI_IXR_TXNFULL_MASK, 1, in zynqmp_qspi_fill_tx_fifo()
412 writel(*buf, &regs->txd0r); in zynqmp_qspi_fill_tx_fifo()
414 size -= 4; in zynqmp_qspi_fill_tx_fifo()
435 writel(data, &regs->txd0r); in zynqmp_qspi_fill_tx_fifo()
440 priv->tx_buf += len; in zynqmp_qspi_fill_tx_fifo()
449 while (priv->len) { in zynqmp_qspi_genfifo_cmd()
452 gen_fifo_cmd |= *(u8 *)priv->tx_buf; in zynqmp_qspi_genfifo_cmd()
454 priv->len--; in zynqmp_qspi_genfifo_cmd()
455 priv->tx_buf = (u8 *)priv->tx_buf + 1; in zynqmp_qspi_genfifo_cmd()
470 if (priv->len > 255) { in zynqmp_qspi_calc_exp()
471 if (priv->len & (1 << expval)) { in zynqmp_qspi_calc_exp()
475 priv->len -= (1 << expval); in zynqmp_qspi_calc_exp()
482 *gen_fifo_cmd |= (u8)priv->len; in zynqmp_qspi_calc_exp()
483 len = (u8)priv->len; in zynqmp_qspi_calc_exp()
484 priv->len = 0; in zynqmp_qspi_calc_exp()
502 while (priv->len) { in zynqmp_qspi_genfifo_fill_tx()
526 u32 actuallen = priv->len; in zynqmp_qspi_start_dma()
528 struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs; in zynqmp_qspi_start_dma()
530 writel((unsigned long)buf, &dma_regs->dmadst); in zynqmp_qspi_start_dma()
531 writel(roundup(priv->len, ARCH_DMA_MINALIGN), &dma_regs->dmasize); in zynqmp_qspi_start_dma()
532 writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); in zynqmp_qspi_start_dma()
534 size = roundup(priv->len, ARCH_DMA_MINALIGN); in zynqmp_qspi_start_dma()
537 while (priv->len) { in zynqmp_qspi_start_dma()
549 ret = wait_for_bit_le32(&dma_regs->dmaisr, GQSPI_DMA_DST_I_STS_DONE, in zynqmp_qspi_start_dma()
552 printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); in zynqmp_qspi_start_dma()
553 return -ETIMEDOUT; in zynqmp_qspi_start_dma()
556 writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); in zynqmp_qspi_start_dma()
559 (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, in zynqmp_qspi_start_dma()
562 if (buf != priv->rx_buf) in zynqmp_qspi_start_dma()
563 memcpy(priv->rx_buf, buf, actuallen); in zynqmp_qspi_start_dma()
572 u32 actuallen = priv->len; in zynqmp_qspi_genfifo_fill_rx()
584 if (!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) && in zynqmp_qspi_genfifo_fill_rx()
586 buf = (u32 *)priv->rx_buf; in zynqmp_qspi_genfifo_fill_rx()
590 ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, in zynqmp_qspi_genfifo_fill_rx()
600 if (priv->is_inst) { in zynqmp_qspi_start_transfer()
601 if (priv->tx_buf) in zynqmp_qspi_start_transfer()
604 return -EINVAL; in zynqmp_qspi_start_transfer()
606 if (priv->tx_buf) in zynqmp_qspi_start_transfer()
608 else if (priv->rx_buf) in zynqmp_qspi_start_transfer()
611 return -EINVAL; in zynqmp_qspi_start_transfer()
628 cs_change = priv->cs_change; in zynqmp_qspi_transfer()
630 if (!priv->tx_buf && !priv->rx_buf && priv->len) { in zynqmp_qspi_transfer()
631 status = -EINVAL; in zynqmp_qspi_transfer()
636 if (priv->len) { in zynqmp_qspi_transfer()
638 priv->is_inst = 0; in zynqmp_qspi_transfer()
654 struct udevice *bus = dev->parent; in zynqmp_qspi_claim_bus()
656 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_claim_bus()
658 writel(GQSPI_ENABLE_ENABLE_MASK, &regs->enbr); in zynqmp_qspi_claim_bus()
665 struct udevice *bus = dev->parent; in zynqmp_qspi_release_bus()
667 struct zynqmp_qspi_regs *regs = priv->regs; in zynqmp_qspi_release_bus()
669 writel(~GQSPI_ENABLE_ENABLE_MASK, &regs->enbr); in zynqmp_qspi_release_bus()
677 struct udevice *bus = dev->parent; in zynqmp_qspi_xfer()
684 priv->tx_buf = dout; in zynqmp_qspi_xfer()
685 priv->rx_buf = din; in zynqmp_qspi_xfer()
686 priv->len = bitlen / 8; in zynqmp_qspi_xfer()
693 priv->is_inst = 1; in zynqmp_qspi_xfer()
695 priv->is_inst = 0; in zynqmp_qspi_xfer()
698 priv->cs_change = 1; in zynqmp_qspi_xfer()
700 priv->cs_change = 0; in zynqmp_qspi_xfer()
716 { .compatible = "xlnx,zynqmp-qspi-1.0" },
717 { .compatible = "xlnx,versal-qspi-1.0" },