mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
spi: cadence_qspi: Enable apb linear mode for apb read & write operations
On versal platform, enable apb linear mode for apb read and write execute operations amd disable it when using dma reads. This is done by xilinx_pm_request() secure calls when CONFIG_ZYNQMP_FIRMWARE is enabled, else we use direct raw reads and writes in case of mini U-Boot. Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com> Link: https://lore.kernel.org/r/20220512100535.16364-5-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek <michal.simek@amd.com>
This commit is contained in:
parent
bf8dae5fcf
commit
248fe9f302
6 changed files with 54 additions and 0 deletions
|
@ -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;
|
||||
|
|
|
@ -33,6 +33,7 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
|||
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);
|
||||
|
@ -211,3 +212,26 @@ int cadence_spi_versal_flash_reset(struct udevice *dev)
|
|||
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
|
||||
|
||||
|
@ -196,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) {
|
||||
|
|
|
@ -284,5 +284,6 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
|||
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,6 +38,11 @@
|
|||
#include <malloc.h>
|
||||
#include "cadence_qspi.h"
|
||||
|
||||
__weak void cadence_qspi_apb_enable_linear_mode(bool enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void cadence_qspi_apb_controller_enable(void *reg_base)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
@ -730,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) {
|
||||
|
@ -897,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,7 @@ 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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue