spi: cadence-qspi: Add disable STIG mode quikrs.
Adding quirk to disable STIG mode since cadence controller has issue for read/write using the STIG mode. STIG mode is enabled by default since 2023.04 for small read/write(<8bytes). Updated STIG mode reading from dev_get_driver_data by assigning to platdata struct before read quirks variable. The STIG mode is disabled for normal read case and enabled for QSPI Jedec ID read/write since it requires STIG read/write. Porting from linux implementation https://lore.kernel.org/all/20241204063338.296959-1-niravkumar .l.rabara@intel.com/T/ Signed-off-by: Boon Khai Ng <boon.khai.ng@altera.com> Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
This commit is contained in:
@@ -27,6 +27,9 @@
|
|||||||
#define CQSPI_READ 2
|
#define CQSPI_READ 2
|
||||||
#define CQSPI_WRITE 3
|
#define CQSPI_WRITE 3
|
||||||
|
|
||||||
|
/* Quirks */
|
||||||
|
#define CQSPI_DISABLE_STIG_MODE BIT(0)
|
||||||
|
|
||||||
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
@@ -222,6 +225,7 @@ static int cadence_spi_probe(struct udevice *bus)
|
|||||||
priv->tsd2d_ns = plat->tsd2d_ns;
|
priv->tsd2d_ns = plat->tsd2d_ns;
|
||||||
priv->tchsh_ns = plat->tchsh_ns;
|
priv->tchsh_ns = plat->tchsh_ns;
|
||||||
priv->tslch_ns = plat->tslch_ns;
|
priv->tslch_ns = plat->tslch_ns;
|
||||||
|
priv->quirks = plat->quirks;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
|
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
|
||||||
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
|
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
|
||||||
@@ -315,12 +319,16 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
|
|||||||
* which is unsupported on some flash devices during register
|
* which is unsupported on some flash devices during register
|
||||||
* reads, prefer STIG mode for such small reads.
|
* reads, prefer STIG mode for such small reads.
|
||||||
*/
|
*/
|
||||||
if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
|
if (!op->addr.nbytes ||
|
||||||
|
(op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX &&
|
||||||
|
!(priv->quirks & CQSPI_DISABLE_STIG_MODE)))
|
||||||
mode = CQSPI_STIG_READ;
|
mode = CQSPI_STIG_READ;
|
||||||
else
|
else
|
||||||
mode = CQSPI_READ;
|
mode = CQSPI_READ;
|
||||||
} else {
|
} else {
|
||||||
if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
|
if (!op->addr.nbytes || !op->data.buf.out ||
|
||||||
|
(op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX &&
|
||||||
|
!(priv->quirks & CQSPI_DISABLE_STIG_MODE)))
|
||||||
mode = CQSPI_STIG_WRITE;
|
mode = CQSPI_STIG_WRITE;
|
||||||
else
|
else
|
||||||
mode = CQSPI_WRITE;
|
mode = CQSPI_WRITE;
|
||||||
@@ -435,6 +443,10 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
|
|||||||
plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay",
|
plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay",
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
|
const struct cqspi_driver_platdata *drvdata =
|
||||||
|
(struct cqspi_driver_platdata *)dev_get_driver_data(bus);
|
||||||
|
plat->quirks = drvdata->quirks;
|
||||||
|
|
||||||
debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
|
debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
|
||||||
__func__, plat->regbase, plat->ahbbase, plat->max_hz,
|
__func__, plat->regbase, plat->ahbbase, plat->max_hz,
|
||||||
plat->page_size);
|
plat->page_size);
|
||||||
@@ -457,10 +469,21 @@ static const struct dm_spi_ops cadence_spi_ops = {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct cqspi_driver_platdata cdns_qspi = {
|
||||||
|
.quirks = CQSPI_DISABLE_STIG_MODE,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct udevice_id cadence_spi_ids[] = {
|
static const struct udevice_id cadence_spi_ids[] = {
|
||||||
{ .compatible = "cdns,qspi-nor" },
|
{
|
||||||
{ .compatible = "ti,am654-ospi" },
|
.compatible = "cdns,qspi-nor",
|
||||||
{ .compatible = "amd,versal2-ospi" },
|
.data = (ulong)&cdns_qspi,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "ti,am654-ospi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "amd,versal2-ospi"
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -222,6 +222,7 @@ struct cadence_spi_plat {
|
|||||||
u32 tsd2d_ns;
|
u32 tsd2d_ns;
|
||||||
u32 tchsh_ns;
|
u32 tchsh_ns;
|
||||||
u32 tslch_ns;
|
u32 tslch_ns;
|
||||||
|
u32 quirks;
|
||||||
|
|
||||||
bool is_dma;
|
bool is_dma;
|
||||||
};
|
};
|
||||||
@@ -253,6 +254,7 @@ struct cadence_spi_priv {
|
|||||||
u32 tsd2d_ns;
|
u32 tsd2d_ns;
|
||||||
u32 tchsh_ns;
|
u32 tchsh_ns;
|
||||||
u32 tslch_ns;
|
u32 tslch_ns;
|
||||||
|
u32 quirks;
|
||||||
u8 edge_mode;
|
u8 edge_mode;
|
||||||
u8 dll_mode;
|
u8 dll_mode;
|
||||||
bool extra_dummy;
|
bool extra_dummy;
|
||||||
@@ -268,6 +270,11 @@ struct cadence_spi_priv {
|
|||||||
bool dtr;
|
bool dtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cqspi_driver_platdata {
|
||||||
|
u32 hwcaps_mask;
|
||||||
|
u32 quirks;
|
||||||
|
};
|
||||||
|
|
||||||
/* Functions call declaration */
|
/* Functions call declaration */
|
||||||
void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv);
|
void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv);
|
||||||
void cadence_qspi_apb_controller_enable(void *reg_base_addr);
|
void cadence_qspi_apb_controller_enable(void *reg_base_addr);
|
||||||
|
Reference in New Issue
Block a user