Versal QSPI/OSPI changes for v2022.10

- Add new flash types
 - Add cadence ospi driver for Xilinx Versal
 -----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCYr2hGQAKCRDKSWXLKUoM
 IabDAJ9oyJ+Z84pDMbegg3uiFp2hQZfx+wCfaX1PXklNCaHIcnnq3ZZAMV2SYds=
 =lU1M
 -----END PGP SIGNATURE-----

Merge tag 'versal-qspi-for-v2022.10' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze into next

Versal QSPI/OSPI changes for v2022.10

- Add new flash types
- Add cadence ospi driver for Xilinx Versal
This commit is contained in:
Tom Rini 2022-06-30 09:32:15 -04:00
commit c5e7003aa8
11 changed files with 547 additions and 155 deletions

View File

@ -640,6 +640,7 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/mach-versal/
F: drivers/net/xilinx_axi_mrmac.*
F: drivers/soc/soc_xilinx_versal.c
F: drivers/spi/cadence_ospi_versal.c
F: drivers/watchdog/xilinx_wwdt.c
N: (?<!uni)versal

View File

@ -58,6 +58,10 @@ struct rpu_regs {
#define VERSAL_CRP_BASEADDR 0xF1260000
#define VERSAL_SLCR_BASEADDR 0xF1060000
#define VERSAL_AXI_MUX_SEL (VERSAL_SLCR_BASEADDR + 0x504)
#define VERSAL_OSPI_LINEAR_MODE BIT(1)
struct crp_regs {
u32 reserved0[128];
u32 boot_mode_usr;
@ -82,3 +86,14 @@ struct crp_regs {
#define JTAG_MODE 0x00000000
#define BOOT_MODE_USE_ALT 0x100
#define BOOT_MODE_ALT_SHIFT 12
#define FLASH_RESET_GPIO 0xc
#define WPROT_CRP 0xF126001C
#define RST_GPIO 0xF1260318
#define WPROT_LPD_MIO 0xFF080728
#define WPROT_PMC_MIO 0xF1060828
#define BOOT_MODE_DIR 0xF1020204
#define BOOT_MODE_OUT 0xF1020208
#define MIO_PIN_12 0xF1060030
#define BANK0_OUTPUT 0xF1020040
#define BANK0_TRI 0xF1060200

View File

@ -106,6 +106,8 @@ CONFIG_XILINX_UARTLITE=y
CONFIG_SOC_XILINX_VERSAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_CADENCE_QSPI=y
CONFIG_CADENCE_OSPI_VERSAL=y
CONFIG_ZYNQ_SPI=y
CONFIG_USB=y
CONFIG_DM_USB_GADGET=y

View File

@ -82,6 +82,7 @@ const struct flash_info spi_nor_ids[] = {
/* EON -- en25xxx */
{ INFO("en25q32b", 0x1c3016, 0, 64 * 1024, 64, 0) },
{ INFO("en25q64", 0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("en25q128b", 0x1c3018, 0, 64 * 1024, 256, 0) },
{ INFO("en25qh128", 0x1c7018, 0, 64 * 1024, 256, 0) },
{ INFO("en25s64", 0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
#endif
@ -127,11 +128,17 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
INFO("gd25lx256e", 0xc86819, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES)
},
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
{ INFO("is25lq040b", 0x9d4013, 0, 64 * 1024, 8,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25lp008", 0x9d6014, 0, 64 * 1024, 16, SPI_NOR_QUAD_READ) },
{ INFO("is25lp016", 0x9d6015, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ) },
{ INFO("is25lp032", 0x9d6016, 0, 64 * 1024, 64, 0) },
{ INFO("is25lp064", 0x9d6017, 0, 64 * 1024, 128, 0) },
{ INFO("is25lp128", 0x9d6018, 0, 64 * 1024, 256,
@ -140,6 +147,10 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ) },
{ INFO("is25lp512", 0x9d601a, 0, 64 * 1024, 1024,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25lp01g", 0x9d601b, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp008", 0x9d7014, 0, 64 * 1024, 16, SPI_NOR_QUAD_READ) },
{ INFO("is25wp016", 0x9d7015, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ) },
{ INFO("is25wp032", 0x9d7016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp064", 0x9d7017, 0, 64 * 1024, 128,
@ -151,6 +162,10 @@ const struct flash_info spi_nor_ids[] = {
SPI_NOR_4B_OPCODES) },
{ INFO("is25wp512", 0x9d701a, 0, 64 * 1024, 1024,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp01g", 0x9d701b, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wx256", 0x9d5b19, 0, 128 * 1024, 256,
SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
/* Macronix */
@ -176,8 +191,11 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) },
{ INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25u51245f", 0xc2953a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u1g45g", 0xc2253b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u2g45g", 0xc2253c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("mx66l2g45g", 0xc2201c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("mx66uw2g345g", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
@ -208,8 +226,10 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("mt25qu02g", 0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("mt25ql02g", 0x20ba22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE | SPI_NOR_4B_OPCODES) },
#ifdef CONFIG_SPI_FLASH_MT35XU
{ INFO("mt35xl512aba", 0x2c5a1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) },
{ INFO("mt35xu512aba", 0x2c5b1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) },
#endif /* CONFIG_SPI_FLASH_MT35XU */
{ INFO6("mt35xu01g", 0x2c5b1b, 0x104100, 128 * 1024, 1024, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mt35xu02g", 0x2c5b1c, 0, 128 * 1024, 2048, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */
@ -225,6 +245,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("s25fl512s_256k", 0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
{ INFO("s25fl512s_64k", 0x010220, 0x4d01, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
{ INFO("s25fl512s_512k", 0x010220, 0x4f00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
{ INFO("s70fs01gs_256k", 0x010221, 0x4d00, 256 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, 0) },
{ INFO("s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, 0) },
{ INFO6("s25fl128s", 0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
@ -275,6 +296,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("sst25wf040", 0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) },
{ INFO("sst25wf080", 0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
{ INFO("sst26vf064b", 0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_SST26LOCK | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("sst26wf016b", 0xbf2641, 0, 64 * 1024, 32, SECT_4K) },
{ INFO("sst26wf016", 0xbf2651, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
{ INFO("sst26wf032", 0xbf2622, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
{ INFO("sst26wf064", 0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
@ -311,11 +333,19 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("w25q20bw", 0xef5012, 0, 64 * 1024, 4, SECT_4K) },
{ INFO("w25q20ew", 0xef6012, 0, 64 * 1024, 4, SECT_4K) },
{ INFO("w25q32", 0xef4016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{
INFO("w25q16dw", 0xef6015, 0, 64 * 1024, 32,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
},
{
INFO("w25q32dw", 0xef6016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
INFO("w25q16jv", 0xef7015, 0, 64 * 1024, 32,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
},
{
INFO("w25q32jv", 0xef7016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
@ -362,6 +392,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
INFO("w25q512jv", 0xef7119, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
@ -370,6 +405,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("w25q80", 0xef5014, 0, 64 * 1024, 16, SECT_4K) },
{ INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q32bv", 0xef4016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q128", 0xef4018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
@ -378,6 +414,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25h02jv", 0xef9022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_XMC
/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */

View File

@ -136,6 +136,14 @@ config CQSPI_REF_CLK
int "Cadence QSPI reference clock value in Hz"
depends on HAS_CQSPI_REF_CLK
config CADENCE_OSPI_VERSAL
bool "Configure Versal OSPI"
depends on ARCH_VERSAL && CADENCE_QSPI
imply DM_GPIO
help
This option is used to enable Versal OSPI DMA operations which
are used for ospi flash read using cadence qspi controller.
config CF_SPI
bool "ColdFire SPI driver"
help

View File

@ -7,6 +7,7 @@
ifdef CONFIG_$(SPL_TPL_)DM_SPI
obj-y += spi-uclass.o
obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o
obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
obj-$(CONFIG_SOFT_SPI) += soft_spi.o
obj-$(CONFIG_SPI_MEM) += spi-mem.o

View File

@ -0,0 +1,237 @@
// SPDX-License-Identifier: GPL-2.0
/*
* (C) Copyright 2018 Xilinx
*
* Cadence QSPI controller DMA operations
*/
#include <clk.h>
#include <common.h>
#include <memalign.h>
#include <wait_bit.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/cache.h>
#include <cpu_func.h>
#include <zynqmp_firmware.h>
#include <asm/arch/hardware.h>
#include "cadence_qspi.h"
#include <dt-bindings/power/xlnx-versal-power.h>
#define CMD_4BYTE_READ 0x13
#define CMD_4BYTE_FAST_READ 0x0C
int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
const struct spi_mem_op *op)
{
u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
n_rx = op->data.nbytes;
rxbuf = op->data.buf.in;
rx_rem = n_rx % 4;
bytes_to_dma = n_rx - rx_rem;
if (bytes_to_dma) {
cadence_qspi_apb_enable_linear_mode(false);
reg = readl(plat->regbase + CQSPI_REG_CONFIG);
reg |= CQSPI_REG_CONFIG_ENBL_DMA;
writel(reg, plat->regbase + CQSPI_REG_CONFIG);
writel(bytes_to_dma, plat->regbase + CQSPI_REG_INDIRECTRDBYTES);
writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
plat->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
writel(CQSPI_DFLT_DMA_PERIPH_CFG,
plat->regbase + CQSPI_REG_DMA_PERIPH_CFG);
writel((unsigned long)rxbuf, plat->regbase +
CQSPI_DMA_DST_ADDR_REG);
writel(plat->trigger_address, plat->regbase +
CQSPI_DMA_SRC_RD_ADDR_REG);
writel(bytes_to_dma, plat->regbase +
CQSPI_DMA_DST_SIZE_REG);
flush_dcache_range((unsigned long)rxbuf,
(unsigned long)rxbuf + bytes_to_dma);
writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
plat->regbase + CQSPI_DMA_DST_CTRL_REG);
/* Start the indirect read transfer */
writel(CQSPI_REG_INDIRECTRD_START, plat->regbase +
CQSPI_REG_INDIRECTRD);
/* Wait for dma to complete transfer */
ret = cadence_qspi_apb_wait_for_dma_cmplt(plat);
if (ret)
return ret;
/* Clear indirect completion status */
writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase +
CQSPI_REG_INDIRECTRD);
rxbuf += bytes_to_dma;
}
if (rx_rem) {
reg = readl(plat->regbase + CQSPI_REG_CONFIG);
reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
writel(reg, plat->regbase + CQSPI_REG_CONFIG);
reg = readl(plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
reg += bytes_to_dma;
writel(reg, plat->regbase + CQSPI_REG_CMDADDRESS);
addr_bytes = readl(plat->regbase + CQSPI_REG_SIZE) &
CQSPI_REG_SIZE_ADDRESS_MASK;
opcode = CMD_4BYTE_FAST_READ;
dummy_cycles = 8;
writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
plat->regbase + CQSPI_REG_RD_INSTR);
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
dummy_cycles = (readl(plat->regbase + CQSPI_REG_RD_INSTR) >>
CQSPI_REG_RD_INSTR_DUMMY_LSB) &
CQSPI_REG_RD_INSTR_DUMMY_MASK;
reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) <<
CQSPI_REG_CMDCTRL_DUMMY_LSB;
reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) <<
CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
ret = cadence_qspi_apb_exec_flash_cmd(plat->regbase, reg);
if (ret)
return ret;
data = readl(plat->regbase + CQSPI_REG_CMDREADDATALOWER);
memcpy(rxbuf, &data, rx_rem);
}
return 0;
}
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat)
{
u32 timeout = CQSPI_DMA_TIMEOUT;
while (!(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG) &
CQSPI_DMA_DST_I_STS_DONE) && timeout--)
udelay(1);
if (!timeout) {
printf("DMA timeout\n");
return -ETIMEDOUT;
}
writel(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG),
plat->regbase + CQSPI_DMA_DST_I_STS_REG);
return 0;
}
#if defined(CONFIG_DM_GPIO)
int cadence_spi_versal_flash_reset(struct udevice *dev)
{
struct gpio_desc gpio;
u32 reset_gpio;
int ret;
/* request gpio and set direction as output set to 1 */
ret = gpio_request_by_name(dev, "reset-gpios", 0, &gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
printf("%s: unable to reset ospi flash device", __func__);
return ret;
}
reset_gpio = PMIO_NODE_ID_BASE + gpio.offset;
/* Request for pin */
xilinx_pm_request(PM_PINCTRL_REQUEST, reset_gpio, 0, 0, 0, NULL);
/* Enable hysteresis in cmos receiver */
xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
PM_PINCTRL_CONFIG_SCHMITT_CMOS,
PM_PINCTRL_INPUT_TYPE_SCHMITT, 0, NULL);
/* Disable Tri-state */
xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
PM_PINCTRL_CONFIG_TRI_STATE,
PM_PINCTRL_TRI_STATE_DISABLE, 0, NULL);
udelay(1);
/* Set value 0 to pin */
dm_gpio_set_value(&gpio, 0);
udelay(1);
/* Set value 1 to pin */
dm_gpio_set_value(&gpio, 1);
udelay(1);
return 0;
}
#else
int cadence_spi_versal_flash_reset(struct udevice *dev)
{
/* CRP WPROT */
writel(0, WPROT_CRP);
/* GPIO Reset */
writel(0, RST_GPIO);
/* disable IOU write protection */
writel(0, WPROT_LPD_MIO);
/* set direction as output */
writel((readl(BOOT_MODE_DIR) | BIT(FLASH_RESET_GPIO)),
BOOT_MODE_POR_0);
/* Data output enable */
writel((readl(BOOT_MODE_OUT) | BIT(FLASH_RESET_GPIO)),
BOOT_MODE_POR_1);
/* IOU SLCR write enable */
writel(0, WPROT_PMC_MIO);
/* set MIO as GPIO */
writel(0x60, MIO_PIN_12);
/* Set value 1 to pin */
writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
udelay(10);
/* Disable Tri-state */
writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI);
udelay(1);
/* Set value 0 to pin */
writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
udelay(10);
/* Set value 1 to pin */
writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
udelay(10);
return 0;
}
#endif
void cadence_qspi_apb_enable_linear_mode(bool enable)
{
if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) {
if (enable)
/* ahb read mode */
xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
IOCTL_OSPI_MUX_SELECT,
PM_OSPI_MUX_SEL_LINEAR, 0, NULL);
else
/* DMA mode */
xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
IOCTL_OSPI_MUX_SELECT,
PM_OSPI_MUX_SEL_DMA, 0, NULL);
} else {
if (enable)
writel(readl(VERSAL_AXI_MUX_SEL) |
VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
else
writel(readl(VERSAL_AXI_MUX_SEL) &
~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
}
}

View File

@ -18,7 +18,9 @@
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/sizes.h>
#include <zynqmp_firmware.h>
#include "cadence_qspi.h"
#include <dt-bindings/power/xlnx-versal-power.h>
#define NSEC_PER_SEC 1000000000L
@ -27,6 +29,17 @@
#define CQSPI_READ 2
#define CQSPI_WRITE 3
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
const struct spi_mem_op *op)
{
return 0;
}
__weak int cadence_qspi_versal_flash_reset(struct udevice *dev)
{
return 0;
}
static int cadence_spi_write_speed(struct udevice *bus, uint hz)
{
struct cadence_spi_plat *plat = dev_get_plat(bus);
@ -138,7 +151,7 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz)
struct cadence_spi_priv *priv = dev_get_priv(bus);
int err;
if (hz > plat->max_hz)
if (!hz || hz > plat->max_hz)
hz = plat->max_hz;
/* Disable QSPI */
@ -185,6 +198,11 @@ static int cadence_spi_probe(struct udevice *bus)
priv->regbase = plat->regbase;
priv->ahbbase = plat->ahbbase;
if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE))
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
ZYNQMP_PM_REQUEST_ACK_NO, NULL);
if (plat->ref_clk_hz == 0) {
ret = clk_get_by_index(bus, 0, &clk);
if (ret) {
@ -214,6 +232,16 @@ static int cadence_spi_probe(struct udevice *bus)
plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz);
if (CONFIG_IS_ENABLED(ARCH_VERSAL)) {
/* Versal platform uses spi calibration to set read delay */
if (plat->read_delay >= 0)
plat->read_delay = -1;
/* Reset ospi flash device */
ret = cadence_qspi_versal_flash_reset(bus);
if (ret)
return ret;
}
return 0;
}
@ -288,8 +316,12 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
break;
case CQSPI_READ:
err = cadence_qspi_apb_read_setup(plat, op);
if (!err)
err = cadence_qspi_apb_read_execute(plat, op);
if (!err) {
if (plat->is_dma)
err = cadence_qspi_apb_dma_read(plat, op);
else
err = cadence_qspi_apb_read_execute(plat, op);
}
break;
case CQSPI_WRITE:
err = cadence_qspi_apb_write_setup(plat, op);
@ -342,6 +374,8 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
if (plat->ahbsize >= SZ_8M)
plat->use_dac_mode = true;
plat->is_dma = dev_read_bool(bus, "cdns,is-dma");
/* All other paramters are embedded in the child node */
subnode = dev_read_first_subnode(bus);
if (!ofnode_valid(subnode)) {

View File

@ -8,6 +8,8 @@
#define __CADENCE_QSPI_H__
#include <reset.h>
#include <linux/mtd/spi-nor.h>
#include <spi-mem.h>
#define CQSPI_IS_ADDR(cmd_len) (cmd_len > 1 ? 1 : 0)
@ -15,6 +17,186 @@
#define CQSPI_DECODER_MAX_CS 16
#define CQSPI_READ_CAPTURE_MAX_DELAY 16
#define CQSPI_REG_POLL_US 1 /* 1us */
#define CQSPI_REG_RETRY 10000
#define CQSPI_POLL_IDLE_RETRY 3
/* Transfer mode */
#define CQSPI_INST_TYPE_SINGLE 0
#define CQSPI_INST_TYPE_DUAL 1
#define CQSPI_INST_TYPE_QUAD 2
#define CQSPI_INST_TYPE_OCTAL 3
#define CQSPI_STIG_DATA_LEN_MAX 8
#define CQSPI_DUMMY_CLKS_PER_BYTE 8
#define CQSPI_DUMMY_BYTES_MAX 4
#define CQSPI_DUMMY_CLKS_MAX 31
/****************************************************************************
* Controller's configuration and status register (offset from QSPI_BASE)
****************************************************************************/
#define CQSPI_REG_CONFIG 0x00
#define CQSPI_REG_CONFIG_ENABLE BIT(0)
#define CQSPI_REG_CONFIG_CLK_POL BIT(1)
#define CQSPI_REG_CONFIG_CLK_PHA BIT(2)
#define CQSPI_REG_CONFIG_PHY_ENABLE_MASK BIT(3)
#define CQSPI_REG_CONFIG_DIRECT BIT(7)
#define CQSPI_REG_CONFIG_DECODE BIT(9)
#define CQSPI_REG_CONFIG_ENBL_DMA BIT(15)
#define CQSPI_REG_CONFIG_XIP_IMM BIT(18)
#define CQSPI_REG_CONFIG_DTR_PROT_EN_MASK BIT(24)
#define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10
#define CQSPI_REG_CONFIG_BAUD_LSB 19
#define CQSPI_REG_CONFIG_DTR_PROTO BIT(24)
#define CQSPI_REG_CONFIG_DUAL_OPCODE BIT(30)
#define CQSPI_REG_CONFIG_IDLE_LSB 31
#define CQSPI_REG_CONFIG_CHIPSELECT_MASK 0xF
#define CQSPI_REG_CONFIG_BAUD_MASK 0xF
#define CQSPI_REG_RD_INSTR 0x04
#define CQSPI_REG_RD_INSTR_OPCODE_LSB 0
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB 8
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB 12
#define CQSPI_REG_RD_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_RD_INSTR_MODE_EN_LSB 20
#define CQSPI_REG_RD_INSTR_DUMMY_LSB 24
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_MASK 0x3
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_MASK 0x3
#define CQSPI_REG_RD_INSTR_TYPE_DATA_MASK 0x3
#define CQSPI_REG_RD_INSTR_DUMMY_MASK 0x1F
#define CQSPI_REG_WR_INSTR 0x08
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
#define CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB 12
#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C
#define CQSPI_REG_DELAY_TSLCH_LSB 0
#define CQSPI_REG_DELAY_TCHSH_LSB 8
#define CQSPI_REG_DELAY_TSD2D_LSB 16
#define CQSPI_REG_DELAY_TSHSL_LSB 24
#define CQSPI_REG_DELAY_TSLCH_MASK 0xFF
#define CQSPI_REG_DELAY_TCHSH_MASK 0xFF
#define CQSPI_REG_DELAY_TSD2D_MASK 0xFF
#define CQSPI_REG_DELAY_TSHSL_MASK 0xFF
#define CQSPI_REG_RD_DATA_CAPTURE 0x10
#define CQSPI_REG_RD_DATA_CAPTURE_BYPASS BIT(0)
#define CQSPI_REG_READCAPTURE_DQS_ENABLE BIT(8)
#define CQSPI_REG_RD_DATA_CAPTURE_DELAY_LSB 1
#define CQSPI_REG_RD_DATA_CAPTURE_DELAY_MASK 0xF
#define CQSPI_REG_SIZE 0x14
#define CQSPI_REG_SIZE_ADDRESS_LSB 0
#define CQSPI_REG_SIZE_PAGE_LSB 4
#define CQSPI_REG_SIZE_BLOCK_LSB 16
#define CQSPI_REG_SIZE_ADDRESS_MASK 0xF
#define CQSPI_REG_SIZE_PAGE_MASK 0xFFF
#define CQSPI_REG_SIZE_BLOCK_MASK 0x3F
#define CQSPI_REG_SRAMPARTITION 0x18
#define CQSPI_REG_INDIRECTTRIGGER 0x1C
#define CQSPI_REG_REMAP 0x24
#define CQSPI_REG_MODE_BIT 0x28
#define CQSPI_REG_SDRAMLEVEL 0x2C
#define CQSPI_REG_SDRAMLEVEL_RD_LSB 0
#define CQSPI_REG_SDRAMLEVEL_WR_LSB 16
#define CQSPI_REG_SDRAMLEVEL_RD_MASK 0xFFFF
#define CQSPI_REG_SDRAMLEVEL_WR_MASK 0xFFFF
#define CQSPI_REG_WR_COMPLETION_CTRL 0x38
#define CQSPI_REG_WR_DISABLE_AUTO_POLL BIT(14)
#define CQSPI_REG_IRQSTATUS 0x40
#define CQSPI_REG_IRQMASK 0x44
#define CQSPI_REG_INDIRECTRD 0x60
#define CQSPI_REG_INDIRECTRD_START BIT(0)
#define CQSPI_REG_INDIRECTRD_CANCEL BIT(1)
#define CQSPI_REG_INDIRECTRD_INPROGRESS BIT(2)
#define CQSPI_REG_INDIRECTRD_DONE BIT(5)
#define CQSPI_REG_INDIRECTRDWATERMARK 0x64
#define CQSPI_REG_INDIRECTRDSTARTADDR 0x68
#define CQSPI_REG_INDIRECTRDBYTES 0x6C
#define CQSPI_REG_CMDCTRL 0x90
#define CQSPI_REG_CMDCTRL_EXECUTE BIT(0)
#define CQSPI_REG_CMDCTRL_INPROGRESS BIT(1)
#define CQSPI_REG_CMDCTRL_DUMMY_LSB 7
#define CQSPI_REG_CMDCTRL_WR_BYTES_LSB 12
#define CQSPI_REG_CMDCTRL_WR_EN_LSB 15
#define CQSPI_REG_CMDCTRL_ADD_BYTES_LSB 16
#define CQSPI_REG_CMDCTRL_ADDR_EN_LSB 19
#define CQSPI_REG_CMDCTRL_RD_BYTES_LSB 20
#define CQSPI_REG_CMDCTRL_RD_EN_LSB 23
#define CQSPI_REG_CMDCTRL_OPCODE_LSB 24
#define CQSPI_REG_CMDCTRL_DUMMY_MASK 0x1F
#define CQSPI_REG_CMDCTRL_WR_BYTES_MASK 0x7
#define CQSPI_REG_CMDCTRL_ADD_BYTES_MASK 0x3
#define CQSPI_REG_CMDCTRL_RD_BYTES_MASK 0x7
#define CQSPI_REG_CMDCTRL_OPCODE_MASK 0xFF
#define CQSPI_REG_INDIRECTWR 0x70
#define CQSPI_REG_INDIRECTWR_START BIT(0)
#define CQSPI_REG_INDIRECTWR_CANCEL BIT(1)
#define CQSPI_REG_INDIRECTWR_INPROGRESS BIT(2)
#define CQSPI_REG_INDIRECTWR_DONE BIT(5)
#define CQSPI_REG_INDIRECTWRWATERMARK 0x74
#define CQSPI_REG_INDIRECTWRSTARTADDR 0x78
#define CQSPI_REG_INDIRECTWRBYTES 0x7C
#define CQSPI_REG_CMDADDRESS 0x94
#define CQSPI_REG_CMDREADDATALOWER 0xA0
#define CQSPI_REG_CMDREADDATAUPPER 0xA4
#define CQSPI_REG_CMDWRITEDATALOWER 0xA8
#define CQSPI_REG_CMDWRITEDATAUPPER 0xAC
#define CQSPI_REG_OP_EXT_LOWER 0xE0
#define CQSPI_REG_OP_EXT_READ_LSB 24
#define CQSPI_REG_OP_EXT_WRITE_LSB 16
#define CQSPI_REG_OP_EXT_STIG_LSB 0
#define CQSPI_REG_PHY_CONFIG 0xB4
#define CQSPI_REG_PHY_CONFIG_RESET_FLD_MASK 0x40000000
#define CQSPI_DMA_DST_ADDR_REG 0x1800
#define CQSPI_DMA_DST_SIZE_REG 0x1804
#define CQSPI_DMA_DST_STS_REG 0x1808
#define CQSPI_DMA_DST_CTRL_REG 0x180C
#define CQSPI_DMA_DST_I_STS_REG 0x1814
#define CQSPI_DMA_DST_I_ENBL_REG 0x1818
#define CQSPI_DMA_DST_I_DISBL_REG 0x181C
#define CQSPI_DMA_DST_CTRL2_REG 0x1824
#define CQSPI_DMA_DST_ADDR_MSB_REG 0x1828
#define CQSPI_DMA_SRC_RD_ADDR_REG 0x1000
#define CQSPI_REG_DMA_PERIPH_CFG 0x20
#define CQSPI_REG_INDIR_TRIG_ADDR_RANGE 0x80
#define CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE 6
#define CQSPI_DFLT_DMA_PERIPH_CFG 0x602
#define CQSPI_DFLT_DST_CTRL_REG_VAL 0xF43FFA00
#define CQSPI_DMA_DST_I_STS_DONE BIT(1)
#define CQSPI_DMA_TIMEOUT 10000000
#define CQSPI_REG_IS_IDLE(base) \
((readl((base) + CQSPI_REG_CONFIG) >> \
CQSPI_REG_CONFIG_IDLE_LSB) & 0x1)
#define CQSPI_GET_RD_SRAM_LEVEL(reg_base) \
(((readl((reg_base) + CQSPI_REG_SDRAMLEVEL)) >> \
CQSPI_REG_SDRAMLEVEL_RD_LSB) & CQSPI_REG_SDRAMLEVEL_RD_MASK)
#define CQSPI_GET_WR_SRAM_LEVEL(reg_base) \
(((readl((reg_base) + CQSPI_REG_SDRAMLEVEL)) >> \
CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK)
struct cadence_spi_plat {
unsigned int ref_clk_hz;
unsigned int max_hz;
@ -42,6 +224,7 @@ struct cadence_spi_plat {
u8 addr_width;
u8 data_width;
bool dtr;
bool is_dma;
};
struct cadence_spi_priv {
@ -96,5 +279,11 @@ void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy);
void cadence_qspi_apb_readdata_capture(void *reg_base,
unsigned int bypass, unsigned int delay);
unsigned int cm_get_qspi_controller_clk_hz(void);
int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
const struct spi_mem_op *op);
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat);
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg);
int cadence_qspi_versal_flash_reset(struct udevice *dev);
void cadence_qspi_apb_enable_linear_mode(bool enable);
#endif /* __CADENCE_QSPI_H__ */

View File

@ -38,156 +38,10 @@
#include <malloc.h>
#include "cadence_qspi.h"
#define CQSPI_REG_POLL_US 1 /* 1us */
#define CQSPI_REG_RETRY 10000
#define CQSPI_POLL_IDLE_RETRY 3
/* Transfer mode */
#define CQSPI_INST_TYPE_SINGLE 0
#define CQSPI_INST_TYPE_DUAL 1
#define CQSPI_INST_TYPE_QUAD 2
#define CQSPI_INST_TYPE_OCTAL 3
#define CQSPI_STIG_DATA_LEN_MAX 8
#define CQSPI_DUMMY_CLKS_PER_BYTE 8
#define CQSPI_DUMMY_CLKS_MAX 31
/****************************************************************************
* Controller's configuration and status register (offset from QSPI_BASE)
****************************************************************************/
#define CQSPI_REG_CONFIG 0x00
#define CQSPI_REG_CONFIG_ENABLE BIT(0)
#define CQSPI_REG_CONFIG_CLK_POL BIT(1)
#define CQSPI_REG_CONFIG_CLK_PHA BIT(2)
#define CQSPI_REG_CONFIG_DIRECT BIT(7)
#define CQSPI_REG_CONFIG_DECODE BIT(9)
#define CQSPI_REG_CONFIG_XIP_IMM BIT(18)
#define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10
#define CQSPI_REG_CONFIG_BAUD_LSB 19
#define CQSPI_REG_CONFIG_DTR_PROTO BIT(24)
#define CQSPI_REG_CONFIG_DUAL_OPCODE BIT(30)
#define CQSPI_REG_CONFIG_IDLE_LSB 31
#define CQSPI_REG_CONFIG_CHIPSELECT_MASK 0xF
#define CQSPI_REG_CONFIG_BAUD_MASK 0xF
#define CQSPI_REG_RD_INSTR 0x04
#define CQSPI_REG_RD_INSTR_OPCODE_LSB 0
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB 8
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB 12
#define CQSPI_REG_RD_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_RD_INSTR_MODE_EN_LSB 20
#define CQSPI_REG_RD_INSTR_DUMMY_LSB 24
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_MASK 0x3
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_MASK 0x3
#define CQSPI_REG_RD_INSTR_TYPE_DATA_MASK 0x3
#define CQSPI_REG_RD_INSTR_DUMMY_MASK 0x1F
#define CQSPI_REG_WR_INSTR 0x08
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
#define CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB 12
#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C
#define CQSPI_REG_DELAY_TSLCH_LSB 0
#define CQSPI_REG_DELAY_TCHSH_LSB 8
#define CQSPI_REG_DELAY_TSD2D_LSB 16
#define CQSPI_REG_DELAY_TSHSL_LSB 24
#define CQSPI_REG_DELAY_TSLCH_MASK 0xFF
#define CQSPI_REG_DELAY_TCHSH_MASK 0xFF
#define CQSPI_REG_DELAY_TSD2D_MASK 0xFF
#define CQSPI_REG_DELAY_TSHSL_MASK 0xFF
#define CQSPI_REG_RD_DATA_CAPTURE 0x10
#define CQSPI_REG_RD_DATA_CAPTURE_BYPASS BIT(0)
#define CQSPI_REG_RD_DATA_CAPTURE_DELAY_LSB 1
#define CQSPI_REG_RD_DATA_CAPTURE_DELAY_MASK 0xF
#define CQSPI_REG_SIZE 0x14
#define CQSPI_REG_SIZE_ADDRESS_LSB 0
#define CQSPI_REG_SIZE_PAGE_LSB 4
#define CQSPI_REG_SIZE_BLOCK_LSB 16
#define CQSPI_REG_SIZE_ADDRESS_MASK 0xF
#define CQSPI_REG_SIZE_PAGE_MASK 0xFFF
#define CQSPI_REG_SIZE_BLOCK_MASK 0x3F
#define CQSPI_REG_SRAMPARTITION 0x18
#define CQSPI_REG_INDIRECTTRIGGER 0x1C
#define CQSPI_REG_REMAP 0x24
#define CQSPI_REG_MODE_BIT 0x28
#define CQSPI_REG_SDRAMLEVEL 0x2C
#define CQSPI_REG_SDRAMLEVEL_RD_LSB 0
#define CQSPI_REG_SDRAMLEVEL_WR_LSB 16
#define CQSPI_REG_SDRAMLEVEL_RD_MASK 0xFFFF
#define CQSPI_REG_SDRAMLEVEL_WR_MASK 0xFFFF
#define CQSPI_REG_WR_COMPLETION_CTRL 0x38
#define CQSPI_REG_WR_DISABLE_AUTO_POLL BIT(14)
#define CQSPI_REG_IRQSTATUS 0x40
#define CQSPI_REG_IRQMASK 0x44
#define CQSPI_REG_INDIRECTRD 0x60
#define CQSPI_REG_INDIRECTRD_START BIT(0)
#define CQSPI_REG_INDIRECTRD_CANCEL BIT(1)
#define CQSPI_REG_INDIRECTRD_INPROGRESS BIT(2)
#define CQSPI_REG_INDIRECTRD_DONE BIT(5)
#define CQSPI_REG_INDIRECTRDWATERMARK 0x64
#define CQSPI_REG_INDIRECTRDSTARTADDR 0x68
#define CQSPI_REG_INDIRECTRDBYTES 0x6C
#define CQSPI_REG_CMDCTRL 0x90
#define CQSPI_REG_CMDCTRL_EXECUTE BIT(0)
#define CQSPI_REG_CMDCTRL_INPROGRESS BIT(1)
#define CQSPI_REG_CMDCTRL_DUMMY_LSB 7
#define CQSPI_REG_CMDCTRL_WR_BYTES_LSB 12
#define CQSPI_REG_CMDCTRL_WR_EN_LSB 15
#define CQSPI_REG_CMDCTRL_ADD_BYTES_LSB 16
#define CQSPI_REG_CMDCTRL_ADDR_EN_LSB 19
#define CQSPI_REG_CMDCTRL_RD_BYTES_LSB 20
#define CQSPI_REG_CMDCTRL_RD_EN_LSB 23
#define CQSPI_REG_CMDCTRL_OPCODE_LSB 24
#define CQSPI_REG_CMDCTRL_DUMMY_MASK 0x1F
#define CQSPI_REG_CMDCTRL_WR_BYTES_MASK 0x7
#define CQSPI_REG_CMDCTRL_ADD_BYTES_MASK 0x3
#define CQSPI_REG_CMDCTRL_RD_BYTES_MASK 0x7
#define CQSPI_REG_CMDCTRL_OPCODE_MASK 0xFF
#define CQSPI_REG_INDIRECTWR 0x70
#define CQSPI_REG_INDIRECTWR_START BIT(0)
#define CQSPI_REG_INDIRECTWR_CANCEL BIT(1)
#define CQSPI_REG_INDIRECTWR_INPROGRESS BIT(2)
#define CQSPI_REG_INDIRECTWR_DONE BIT(5)
#define CQSPI_REG_INDIRECTWRWATERMARK 0x74
#define CQSPI_REG_INDIRECTWRSTARTADDR 0x78
#define CQSPI_REG_INDIRECTWRBYTES 0x7C
#define CQSPI_REG_CMDADDRESS 0x94
#define CQSPI_REG_CMDREADDATALOWER 0xA0
#define CQSPI_REG_CMDREADDATAUPPER 0xA4
#define CQSPI_REG_CMDWRITEDATALOWER 0xA8
#define CQSPI_REG_CMDWRITEDATAUPPER 0xAC
#define CQSPI_REG_OP_EXT_LOWER 0xE0
#define CQSPI_REG_OP_EXT_READ_LSB 24
#define CQSPI_REG_OP_EXT_WRITE_LSB 16
#define CQSPI_REG_OP_EXT_STIG_LSB 0
#define CQSPI_REG_IS_IDLE(base) \
((readl(base + CQSPI_REG_CONFIG) >> \
CQSPI_REG_CONFIG_IDLE_LSB) & 0x1)
#define CQSPI_GET_RD_SRAM_LEVEL(reg_base) \
(((readl(reg_base + CQSPI_REG_SDRAMLEVEL)) >> \
CQSPI_REG_SDRAMLEVEL_RD_LSB) & CQSPI_REG_SDRAMLEVEL_RD_MASK)
#define CQSPI_GET_WR_SRAM_LEVEL(reg_base) \
(((readl(reg_base + CQSPI_REG_SDRAMLEVEL)) >> \
CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK)
__weak void cadence_qspi_apb_enable_linear_mode(bool enable)
{
return;
}
void cadence_qspi_apb_controller_enable(void *reg_base)
{
@ -487,8 +341,7 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat)
cadence_qspi_apb_controller_enable(plat->regbase);
}
static int cadence_qspi_apb_exec_flash_cmd(void *reg_base,
unsigned int reg)
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
{
unsigned int retry = CQSPI_REG_RETRY;
@ -882,6 +735,9 @@ int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat,
void *buf = op->data.buf.in;
size_t len = op->data.nbytes;
if (CONFIG_IS_ENABLED(ARCH_VERSAL))
cadence_qspi_apb_enable_linear_mode(true);
if (plat->use_dac_mode && (from + len < plat->ahbsize)) {
if (len < 256 ||
dma_memcpy(buf, plat->ahbbase + from, len) < 0) {
@ -1049,6 +905,9 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat,
const void *buf = op->data.buf.out;
size_t len = op->data.nbytes;
if (CONFIG_IS_ENABLED(ARCH_VERSAL))
cadence_qspi_apb_enable_linear_mode(true);
/*
* Some flashes like the Cypress Semper flash expect a dummy 4-byte
* address (all 0s) with the read status register command in DTR mode.

View File

@ -160,6 +160,12 @@ enum dll_reset_type {
PM_DLL_RESET_PULSE = 2,
};
enum ospi_mux_select_type {
PM_OSPI_MUX_SEL_DMA,
PM_OSPI_MUX_SEL_LINEAR,
PM_OSPI_MUX_GET_MODE,
};
enum pm_query_id {
PM_QID_INVALID = 0,
PM_QID_CLOCK_GET_NAME = 1,
@ -427,6 +433,9 @@ enum pm_gem_config_type {
#define ZYNQMP_PM_VERSION_INVALID ~0
#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
#define PMIO_NODE_ID_BASE 0x1410801B
#define PMIO_NODE_ID_BASE 0x1410801B
/*
* Return payload size