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:
commit
c5e7003aa8
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.) */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
237
drivers/spi/cadence_ospi_versal.c
Normal file
237
drivers/spi/cadence_ospi_versal.c
Normal 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);
|
||||
}
|
||||
}
|
@ -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)) {
|
||||
|
@ -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__ */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user