Controller can poll for wait state inserted by TPM device and handle it. Signed-off-by: Krishna Yarlagadda <kyarlagadda@xxxxxxxxxx> --- drivers/spi/spi-tegra210-quad.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index a2e225e8f7f0..ecf171bfcdce 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -142,6 +142,7 @@ #define QSPI_GLOBAL_CONFIG 0X1a4 #define QSPI_CMB_SEQ_EN BIT(0) +#define QSPI_TPM_WAIT_POLL_EN BIT(1) #define QSPI_CMB_SEQ_ADDR 0x1a8 #define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0) @@ -165,11 +166,13 @@ struct tegra_qspi_soc_data { bool has_dma; bool cmb_xfer_capable; bool cs_count; + bool has_wait_polling; }; struct tegra_qspi_client_data { int tx_clk_tap_delay; int rx_clk_tap_delay; + bool wait_polling; }; struct tegra_qspi { @@ -833,6 +836,11 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran else command1 |= QSPI_CONTROL_MODE_0; + if (tqspi->soc_data->cmb_xfer_capable) + command1 &= ~QSPI_CS_SW_HW; + else + command1 |= QSPI_CS_SW_HW; + if (spi->mode & SPI_CS_HIGH) command1 |= QSPI_CS_SW_VAL; else @@ -917,6 +925,7 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi, static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi) { + struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master); struct tegra_qspi_client_data *cdata; cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL); @@ -927,6 +936,11 @@ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_devic &cdata->tx_clk_tap_delay); device_property_read_u32(&spi->dev, "nvidia,rx-clk-tap-delay", &cdata->rx_clk_tap_delay); + if (tqspi->soc_data->has_wait_polling) + cdata->wait_polling = device_property_read_bool + (&spi->dev, + "nvidia,wait-polling"); + return cdata; } @@ -1049,6 +1063,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, bool is_first_msg = true; struct spi_transfer *xfer; struct spi_device *spi = msg->spi; + struct tegra_qspi_client_data *cdata = spi->controller_data; u8 transfer_phase = 0; u32 cmd1 = 0, dma_ctl = 0; int ret = 0; @@ -1059,6 +1074,10 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, /* Enable Combined sequence mode */ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); val |= QSPI_CMB_SEQ_EN; + if (cdata->wait_polling) + val |= QSPI_TPM_WAIT_POLL_EN; + else + val &= ~QSPI_TPM_WAIT_POLL_EN; tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); /* Process individual transfer list */ list_for_each_entry(xfer, &msg->transfers, transfer_list) { @@ -1158,6 +1177,8 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, transfer_phase++; } + ret = 0; + exit: msg->status = ret; @@ -1180,6 +1201,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, /* Disable Combined sequence mode */ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); val &= ~QSPI_CMB_SEQ_EN; + val &= ~QSPI_TPM_WAIT_POLL_EN; tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); list_for_each_entry(transfer, &msg->transfers, transfer_list) { struct spi_transfer *xfer = transfer; @@ -1439,24 +1461,28 @@ static struct tegra_qspi_soc_data tegra210_qspi_soc_data = { .has_dma = true, .cmb_xfer_capable = false, .cs_count = 1, + .has_wait_polling = false, }; static struct tegra_qspi_soc_data tegra186_qspi_soc_data = { .has_dma = true, .cmb_xfer_capable = true, .cs_count = 1, + .has_wait_polling = false, }; static struct tegra_qspi_soc_data tegra234_qspi_soc_data = { .has_dma = false, .cmb_xfer_capable = true, .cs_count = 1, + .has_wait_polling = true, }; static struct tegra_qspi_soc_data tegra_grace_qspi_soc_data = { .has_dma = false, .cmb_xfer_capable = true, .cs_count = 4, + .has_wait_polling = true, }; static const struct of_device_id tegra_qspi_of_match[] = { @@ -1509,6 +1535,7 @@ static int tegra_qspi_probe(struct platform_device *pdev) struct resource *r; int ret, qspi_irq; int bus_num; + u8 val = 0; master = devm_spi_alloc_master(&pdev->dev, sizeof(*tqspi)); if (!master) @@ -1585,6 +1612,10 @@ static int tegra_qspi_probe(struct platform_device *pdev) tqspi->spi_cs_timing1 = tegra_qspi_readl(tqspi, QSPI_CS_TIMING1); tqspi->spi_cs_timing2 = tegra_qspi_readl(tqspi, QSPI_CS_TIMING2); tqspi->def_command2_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND2); + val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); + val &= ~QSPI_CMB_SEQ_EN; + val &= ~QSPI_TPM_WAIT_POLL_EN; + tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); pm_runtime_put(&pdev->dev); -- 2.17.1