1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) Copyright 2018 Xilinx 4 * 5 * Cadence QSPI controller DMA operations 6 */ 7 8#include <clk.h> 9#include <common.h> 10#include <memalign.h> 11#include <wait_bit.h> 12#include <asm/io.h> 13#include <asm/gpio.h> 14#include <asm/cache.h> 15#include <cpu_func.h> 16#include <zynqmp_firmware.h> 17#include <asm/arch/hardware.h> 18#include "cadence_qspi.h" 19#include <dt-bindings/power/xlnx-versal-power.h> 20 21int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, 22 const struct spi_mem_op *op) 23{ 24 u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; 25 u8 opcode, addr_bytes, *rxbuf, dummy_cycles; 26 27 n_rx = op->data.nbytes; 28 rxbuf = op->data.buf.in; 29 rx_rem = n_rx % 4; 30 bytes_to_dma = n_rx - rx_rem; 31 32 if (bytes_to_dma) { 33 cadence_qspi_apb_enable_linear_mode(false); 34 reg = readl(priv->regbase + CQSPI_REG_CONFIG); 35 reg |= CQSPI_REG_CONFIG_ENBL_DMA; 36 writel(reg, priv->regbase + CQSPI_REG_CONFIG); 37 38 writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES); 39 40 writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE, 41 priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); 42 writel(CQSPI_DFLT_DMA_PERIPH_CFG, 43 priv->regbase + CQSPI_REG_DMA_PERIPH_CFG); 44 writel(lower_32_bits((unsigned long)rxbuf), priv->regbase + 45 CQSPI_DMA_DST_ADDR_REG); 46 writel(upper_32_bits((unsigned long)rxbuf), priv->regbase + 47 CQSPI_DMA_DST_ADDR_MSB_REG); 48 writel(priv->trigger_address, priv->regbase + 49 CQSPI_DMA_SRC_RD_ADDR_REG); 50 writel(bytes_to_dma, priv->regbase + 51 CQSPI_DMA_DST_SIZE_REG); 52 flush_dcache_range((unsigned long)rxbuf, 53 (unsigned long)rxbuf + bytes_to_dma); 54 writel(CQSPI_DFLT_DST_CTRL_REG_VAL, 55 priv->regbase + CQSPI_DMA_DST_CTRL_REG); 56 57 /* Start the indirect read transfer */ 58 writel(CQSPI_REG_INDIRECTRD_START, priv->regbase + 59 CQSPI_REG_INDIRECTRD); 60 /* Wait for dma to complete transfer */ 61 ret = cadence_qspi_apb_wait_for_dma_cmplt(priv); 62 if (ret) 63 return ret; 64 65 /* Clear indirect completion status */ 66 writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase + 67 CQSPI_REG_INDIRECTRD); 68 rxbuf += bytes_to_dma; 69 } 70 71 if (rx_rem) { 72 reg = readl(priv->regbase + CQSPI_REG_CONFIG); 73 reg &= ~CQSPI_REG_CONFIG_ENBL_DMA; 74 writel(reg, priv->regbase + CQSPI_REG_CONFIG); 75 76 reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); 77 reg += bytes_to_dma; 78 writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS); 79 80 addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) & 81 CQSPI_REG_SIZE_ADDRESS_MASK; 82 83 opcode = CMD_4BYTE_FAST_READ; 84 dummy_cycles = 8; 85 writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, 86 priv->regbase + CQSPI_REG_RD_INSTR); 87 88 reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; 89 reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB); 90 reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) << 91 CQSPI_REG_CMDCTRL_ADD_BYTES_LSB; 92 reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB); 93 dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >> 94 CQSPI_REG_RD_INSTR_DUMMY_LSB) & 95 CQSPI_REG_RD_INSTR_DUMMY_MASK; 96 reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) << 97 CQSPI_REG_CMDCTRL_DUMMY_LSB; 98 reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << 99 CQSPI_REG_CMDCTRL_RD_BYTES_LSB); 100 ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg); 101 if (ret) 102 return ret; 103 104 data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER); 105 memcpy(rxbuf, &data, rx_rem); 106 } 107 108 return 0; 109} 110 111int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv) 112{ 113 u32 timeout = CQSPI_DMA_TIMEOUT; 114 115 while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) & 116 CQSPI_DMA_DST_I_STS_DONE) && timeout--) 117 udelay(1); 118 119 if (!timeout) { 120 printf("DMA timeout\n"); 121 return -ETIMEDOUT; 122 } 123 124 writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG), 125 priv->regbase + CQSPI_DMA_DST_I_STS_REG); 126 return 0; 127} 128 129#if defined(CONFIG_DM_GPIO) 130int cadence_qspi_versal_flash_reset(struct udevice *dev) 131{ 132 struct gpio_desc gpio; 133 u32 reset_gpio; 134 int ret; 135 136 /* request gpio and set direction as output set to 1 */ 137 ret = gpio_request_by_name(dev, "reset-gpios", 0, &gpio, 138 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 139 if (ret) { 140 printf("%s: unable to reset ospi flash device", __func__); 141 return ret; 142 } 143 144 reset_gpio = PMIO_NODE_ID_BASE + gpio.offset; 145 146 /* Request for pin */ 147 xilinx_pm_request(PM_PINCTRL_REQUEST, reset_gpio, 0, 0, 0, NULL); 148 149 /* Enable hysteresis in cmos receiver */ 150 xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio, 151 PM_PINCTRL_CONFIG_SCHMITT_CMOS, 152 PM_PINCTRL_INPUT_TYPE_SCHMITT, 0, NULL); 153 154 /* Disable Tri-state */ 155 xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio, 156 PM_PINCTRL_CONFIG_TRI_STATE, 157 PM_PINCTRL_TRI_STATE_DISABLE, 0, NULL); 158 udelay(1); 159 160 /* Set value 0 to pin */ 161 dm_gpio_set_value(&gpio, 0); 162 udelay(1); 163 164 /* Set value 1 to pin */ 165 dm_gpio_set_value(&gpio, 1); 166 udelay(1); 167 168 return 0; 169} 170#else 171int cadence_qspi_versal_flash_reset(struct udevice *dev) 172{ 173 /* CRP WPROT */ 174 writel(0, WPROT_CRP); 175 /* GPIO Reset */ 176 writel(0, RST_GPIO); 177 178 /* disable IOU write protection */ 179 writel(0, WPROT_LPD_MIO); 180 181 /* set direction as output */ 182 writel((readl(BOOT_MODE_DIR) | BIT(FLASH_RESET_GPIO)), 183 BOOT_MODE_DIR); 184 185 /* Data output enable */ 186 writel((readl(BOOT_MODE_OUT) | BIT(FLASH_RESET_GPIO)), 187 BOOT_MODE_OUT); 188 189 /* IOU SLCR write enable */ 190 writel(0, WPROT_PMC_MIO); 191 192 /* set MIO as GPIO */ 193 writel(0x60, MIO_PIN_12); 194 195 /* Set value 1 to pin */ 196 writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT); 197 udelay(10); 198 199 /* Disable Tri-state */ 200 writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI); 201 udelay(1); 202 203 /* Set value 0 to pin */ 204 writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT); 205 udelay(10); 206 207 /* Set value 1 to pin */ 208 writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT); 209 udelay(10); 210 211 return 0; 212} 213#endif 214 215void cadence_qspi_apb_enable_linear_mode(bool enable) 216{ 217 if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) { 218 if (enable) 219 /* ahb read mode */ 220 xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI, 221 IOCTL_OSPI_MUX_SELECT, 222 PM_OSPI_MUX_SEL_LINEAR, 0, NULL); 223 else 224 /* DMA mode */ 225 xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI, 226 IOCTL_OSPI_MUX_SELECT, 227 PM_OSPI_MUX_SEL_DMA, 0, NULL); 228 } else { 229 if (enable) 230 writel(readl(VERSAL_AXI_MUX_SEL) | 231 VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); 232 else 233 writel(readl(VERSAL_AXI_MUX_SEL) & 234 ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); 235 } 236} 237