From 196ed030ad058499f7763183b38e919398f6d168 Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 10:56:16 +0530 Subject: [PATCH 1/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit 22cec88da571 ("i2c: i2c-qcom-geni: Add lock and unlock tre support in I2C GSI mode")'. Change-Id: I1b92829cd04b379e48c34b09b5ab5ef4440ac0a8 Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index b95a7cf92a05..b7136a9fdf53 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -396,7 +396,7 @@ static struct msm_gpi_tre *setup_go_tre(int cmd, int cs, int rx_len, int flags, if (cmd == SPI_RX_ONLY) { eot = 0; chain = 0; - eob = 1; + eob = 0; } else { eot = 0; chain = 1; From 182605a3772100de3f85f9be12384e9aedb1e79e Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 11:31:00 +0530 Subject: [PATCH 2/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit f5bcbeb4a2a1 ("spi-geni-qcom: Add shared_ee dtsi property for spi driver")'. Change-Id: Ic64d6a6e358ba5fd1898eaacfb72586cdab9184a Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 106 ++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index b7136a9fdf53..53471261536a 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -147,7 +147,8 @@ struct spi_geni_master { int num_rx_eot; int num_xfers; void *ipc; - bool shared_se; + bool shared_se; /* GSI Mode */ + bool shared_ee; /* Dual EE use case */ bool dis_autosuspend; bool cmd_done; }; @@ -716,6 +717,32 @@ static int spi_geni_prepare_message(struct spi_master *spi, { int ret = 0; struct spi_geni_master *mas = spi_master_get_devdata(spi); + int count; + + if (mas->shared_ee) { + if (mas->setup) { + ret = pm_runtime_get_sync(mas->dev); + if (ret < 0) { + dev_err(mas->dev, + "%s:pm_runtime_get_sync failed %d\n", + __func__, ret); + pm_runtime_put_noidle(mas->dev); + goto exit_prepare_message; + } + ret = 0; + + if (mas->dis_autosuspend) { + count = + atomic_read(&mas->dev->power.usage_count); + if (count <= 0) + GENI_SE_ERR(mas->ipc, false, NULL, + "resume usage count mismatch:%d", + count); + } + } else { + mas->setup = true; + } + } mas->cur_xfer_mode = select_xfer_mode(spi, spi_msg); @@ -733,6 +760,7 @@ static int spi_geni_prepare_message(struct spi_master *spi, ret = setup_fifo_params(spi_msg->spi, spi); } +exit_prepare_message: return ret; } @@ -740,11 +768,27 @@ static int spi_geni_unprepare_message(struct spi_master *spi_mas, struct spi_message *spi_msg) { struct spi_geni_master *mas = spi_master_get_devdata(spi_mas); + int count = 0; mas->cur_speed_hz = 0; mas->cur_word_len = 0; if (mas->cur_xfer_mode == GSI_DMA) spi_geni_unmap_buf(mas, spi_msg); + + if (mas->shared_ee) { + if (mas->dis_autosuspend) { + pm_runtime_put_sync(mas->dev); + count = atomic_read(&mas->dev->power.usage_count); + if (count < 0) + GENI_SE_ERR(mas->ipc, false, NULL, + "suspend usage count mismatch:%d", + count); + } else { + pm_runtime_mark_last_busy(mas->dev); + pm_runtime_put_autosuspend(mas->dev); + } + } + return 0; } @@ -757,7 +801,7 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi) /* Adjust the IB based on the max speed of the slave in kHz.*/ rsc->ib = (max_speed * DEFAULT_BUS_WIDTH) / 1000; - if (mas->shared_se) { + if (mas->shared_se && !mas->shared_ee) { struct se_geni_rsc *rsc; int ret = 0; @@ -769,20 +813,23 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi) "%s: Error %d pinctrl_select_state\n", __func__, ret); } - ret = pm_runtime_get_sync(mas->dev); - if (ret < 0) { - dev_err(mas->dev, "%s:Error enabling SE resources %d\n", + if (!mas->setup || !mas->shared_ee) { + ret = pm_runtime_get_sync(mas->dev); + if (ret < 0) { + dev_err(mas->dev, + "%s:pm_runtime_get_sync failed %d\n", __func__, ret); - pm_runtime_put_noidle(mas->dev); - goto exit_prepare_transfer_hardware; - } else { + pm_runtime_put_noidle(mas->dev); + goto exit_prepare_transfer_hardware; + } ret = 0; - } - if (mas->dis_autosuspend) { - count = atomic_read(&mas->dev->power.usage_count); - if (count <= 0) - GENI_SE_ERR(mas->ipc, false, NULL, + + if (mas->dis_autosuspend) { + count = atomic_read(&mas->dev->power.usage_count); + if (count <= 0) + GENI_SE_ERR(mas->ipc, false, NULL, "resume usage count mismatch:%d", count); + } } if (unlikely(!mas->setup)) { int proto = get_se_proto(mas->base); @@ -856,7 +903,8 @@ setup_ipc: dev_info(mas->dev, "tx_fifo %d rx_fifo %d tx_width %d\n", mas->tx_fifo_depth, mas->rx_fifo_depth, mas->tx_fifo_width); - mas->setup = true; + if (!mas->shared_ee) + mas->setup = true; hw_ver = geni_se_qupv3_hw_version(mas->wrapper_dev, &major, &minor, &step); if (hw_ver) @@ -885,6 +933,9 @@ static int spi_geni_unprepare_transfer_hardware(struct spi_master *spi) struct spi_geni_master *mas = spi_master_get_devdata(spi); int count = 0; + if (mas->shared_ee) + return 0; + if (mas->shared_se) { struct se_geni_rsc *rsc; int ret = 0; @@ -1458,6 +1509,15 @@ static int spi_geni_probe(struct platform_device *pdev) geni_mas->dis_autosuspend = of_property_read_bool(pdev->dev.of_node, "qcom,disable-autosuspend"); + /* + * This property will be set when spi is being used from + * dual Execution Environments unlike shared_se flag + * which is set if SE is in GSI mode. + */ + geni_mas->shared_ee = + of_property_read_bool(pdev->dev.of_node, + "qcom,shared_ee"); + geni_mas->phys_addr = res->start; geni_mas->size = resource_size(res); geni_mas->base = devm_ioremap(&pdev->dev, res->start, @@ -1535,14 +1595,19 @@ static int spi_geni_runtime_suspend(struct device *dev) struct spi_master *spi = get_spi_master(dev); struct spi_geni_master *geni_mas = spi_master_get_devdata(spi); + if (geni_mas->shared_ee) + goto exit_rt_suspend; + if (geni_mas->shared_se) { ret = se_geni_clks_off(&geni_mas->spi_rsc); if (ret) GENI_SE_ERR(geni_mas->ipc, false, NULL, "%s: Error %d turning off clocks\n", __func__, ret); - } else { - ret = se_geni_resources_off(&geni_mas->spi_rsc); + return ret; } + +exit_rt_suspend: + ret = se_geni_resources_off(&geni_mas->spi_rsc); return ret; } @@ -1552,14 +1617,19 @@ static int spi_geni_runtime_resume(struct device *dev) struct spi_master *spi = get_spi_master(dev); struct spi_geni_master *geni_mas = spi_master_get_devdata(spi); + if (geni_mas->shared_ee) + goto exit_rt_resume; + if (geni_mas->shared_se) { ret = se_geni_clks_on(&geni_mas->spi_rsc); if (ret) GENI_SE_ERR(geni_mas->ipc, false, NULL, "%s: Error %d turning on clocks\n", __func__, ret); - } else { - ret = se_geni_resources_on(&geni_mas->spi_rsc); + return ret; } + +exit_rt_resume: + ret = se_geni_resources_on(&geni_mas->spi_rsc); return ret; } From ce64610d0eb88372908acdec25dfe5b7232c65bc Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 14:20:12 +0530 Subject: [PATCH 3/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit 185ecd35b11f ("spi: spi-geni-qcom: Reset the dma engine on failure")'. Change-Id: I3839d5bc773e7d7ea71ba6ff611f55f4869000f3 Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 53471261536a..2d13016dc500 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -1106,12 +1106,30 @@ static void handle_fifo_timeout(struct spi_geni_master *mas, "Failed to cancel/abort m_cmd\n"); } if (mas->cur_xfer_mode == SE_DMA) { - if (xfer->tx_buf) + if (xfer->tx_buf) { + reinit_completion(&mas->xfer_done); + writel_relaxed(1, mas->base + + SE_DMA_TX_FSM_RST); + timeout = + wait_for_completion_timeout(&mas->xfer_done, HZ); + if (!timeout) + dev_err(mas->dev, + "DMA TX RESET failed\n"); geni_se_tx_dma_unprep(mas->wrapper_dev, xfer->tx_dma, xfer->len); - if (xfer->rx_buf) + } + if (xfer->rx_buf) { + reinit_completion(&mas->xfer_done); + writel_relaxed(1, mas->base + + SE_DMA_RX_FSM_RST); + timeout = + wait_for_completion_timeout(&mas->xfer_done, HZ); + if (!timeout) + dev_err(mas->dev, + "DMA RX RESET failed\n"); geni_se_rx_dma_unprep(mas->wrapper_dev, - xfer->rx_dma, xfer->len); + xfer->rx_dma, xfer->len); + } } } From 67ec5c3b8f20604113213af0e1d2dca6e29ec613 Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 14:25:17 +0530 Subject: [PATCH 4/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit 64485a92b029 ("spi: spi-geni-qcom: Check for Rx DMA channel being null")'. Change-Id: I0dc30e38d0cbbab21d26eeab17b40b14017d48ff Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 2d13016dc500..30c6a9a7a5e4 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -860,6 +860,7 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi) dev_info(mas->dev, "Failed to get rx DMA ch %ld\n", PTR_ERR(mas->rx)); dma_release_channel(mas->tx); + goto setup_ipc; } mas->gsi = devm_kzalloc(mas->dev, (sizeof(struct spi_geni_gsi) * NUM_SPI_XFER), From e71111a9fa1d70f42ab151a87f2378e89034715c Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 14:32:42 +0530 Subject: [PATCH 5/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit 634968af3a1f ("spi: spi-geni-qcom: Allow flexible MISO sampling rate for SPI HLOS")'. Change-Id: I5061cec80875e5fad4d25b04977b8ce1281818fd Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 30c6a9a7a5e4..cebb104ba372 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -93,6 +93,16 @@ #define MAX_TX_SG (3) #define NUM_SPI_XFER (8) +/* SPI sampling registers */ +#define SE_GENI_CGC_CTRL (0x28) +#define SE_GENI_CFG_SEQ_START (0x84) +#define SE_GENI_CFG_REG108 (0x2B0) +#define SE_GENI_CFG_REG109 (0x2B4) +#define CPOL_CTRL_SHFT 1 +#define RX_IO_POS_FF_EN_SEL_SHFT 4 +#define RX_IO_EN2CORE_EN_DELAY_SHFT 8 +#define RX_SI_EN2IO_DELAY_SHFT 12 + struct gsi_desc_cb { struct spi_master *spi; struct spi_transfer *xfer; @@ -151,6 +161,8 @@ struct spi_geni_master { bool shared_ee; /* Dual EE use case */ bool dis_autosuspend; bool cmd_done; + bool set_miso_sampling; + u32 miso_sampling_ctrl_val; }; static struct spi_master *get_spi_master(struct device *dev) @@ -792,6 +804,56 @@ static int spi_geni_unprepare_message(struct spi_master *spi_mas, return 0; } +static void spi_geni_set_sampling_rate(struct spi_geni_master *mas, + unsigned int major, unsigned int minor) +{ + u32 cpol, cpha, cfg_reg108, cfg_reg109, cfg_seq_start; + + cpol = geni_read_reg(mas->base, SE_SPI_CPOL); + cpha = geni_read_reg(mas->base, SE_SPI_CPHA); + cfg_reg108 = geni_read_reg(mas->base, SE_GENI_CFG_REG108); + cfg_reg109 = geni_read_reg(mas->base, SE_GENI_CFG_REG109); + /* clear CPOL bit */ + cfg_reg108 &= ~(1 << CPOL_CTRL_SHFT); + + if (major == 1 && minor == 0) { + /* Write 1 to RX_SI_EN2IO_DELAY reg */ + cfg_reg108 &= ~(0x7 << RX_SI_EN2IO_DELAY_SHFT); + cfg_reg108 |= (1 << RX_SI_EN2IO_DELAY_SHFT); + /* Write 0 to RX_IO_POS_FF_EN_SEL reg */ + cfg_reg108 &= ~(1 << RX_IO_POS_FF_EN_SEL_SHFT); + } else if ((major < 2) || (major == 2 && minor < 5)) { + /* Write 0 to RX_IO_EN2CORE_EN_DELAY reg */ + cfg_reg108 &= ~(0x7 << RX_IO_EN2CORE_EN_DELAY_SHFT); + } else { + /* + * Write miso_sampling_ctrl_set to + * RX_IO_EN2CORE_EN_DELAY reg + */ + cfg_reg108 &= ~(0x7 << RX_IO_EN2CORE_EN_DELAY_SHFT); + cfg_reg108 |= (mas->miso_sampling_ctrl_val << + RX_IO_EN2CORE_EN_DELAY_SHFT); + } + + geni_write_reg(cfg_reg108, mas->base, SE_GENI_CFG_REG108); + + if (cpol == 0 && cpha == 0) + cfg_reg109 = 1; + else if (cpol == 1 && cpha == 0) + cfg_reg109 = 0; + geni_write_reg(cfg_reg109, mas->base, + SE_GENI_CFG_REG109); + if (!(major == 1 && minor == 0)) + geni_write_reg(1, mas->base, SE_GENI_CFG_SEQ_START); + cfg_reg108 = geni_read_reg(mas->base, SE_GENI_CFG_REG108); + cfg_reg109 = geni_read_reg(mas->base, SE_GENI_CFG_REG109); + cfg_seq_start = geni_read_reg(mas->base, SE_GENI_CFG_SEQ_START); + + GENI_SE_DBG(mas->ipc, false, mas->dev, + "%s cfg108: 0x%x cfg109: 0x%x cfg_seq_start: 0x%x\n", + __func__, cfg_reg108, cfg_reg109, cfg_seq_start); +} + static int spi_geni_prepare_transfer_hardware(struct spi_master *spi) { struct spi_geni_master *mas = spi_master_get_devdata(spi); @@ -918,6 +980,9 @@ setup_ipc: "%s:Major:%d Minor:%d step:%dos%d\n", __func__, major, minor, step, mas->oversampling); } + if (mas->set_miso_sampling) + spi_geni_set_sampling_rate(mas, major, minor); + mas->shared_se = (geni_read_reg(mas->base, GENI_IF_FIFO_DISABLE_RO) & FIFO_IF_DISABLE); @@ -1537,6 +1602,15 @@ static int spi_geni_probe(struct platform_device *pdev) of_property_read_bool(pdev->dev.of_node, "qcom,shared_ee"); + geni_mas->set_miso_sampling = of_property_read_bool(pdev->dev.of_node, + "qcom,set-miso-sampling"); + if (geni_mas->set_miso_sampling) { + if (!of_property_read_u32(pdev->dev.of_node, + "qcom,miso-sampling-ctrl-val", + &geni_mas->miso_sampling_ctrl_val)) + dev_info(&pdev->dev, "MISO_SAMPLING_SET: %d\n", + geni_mas->miso_sampling_ctrl_val); + } geni_mas->phys_addr = res->start; geni_mas->size = resource_size(res); geni_mas->base = devm_ioremap(&pdev->dev, res->start, From c5d86f08db125cadddf9afe03a791383da04926e Mon Sep 17 00:00:00 2001 From: Vipin Deep Kaur Date: Tue, 30 Jun 2020 14:46:44 +0530 Subject: [PATCH 6/6] spi: spi-msm-geni: Propagate missing change from 4.19 to 5.4 Propagate following change from 4.19 to 5.4 for SPI driver. 'commit 67192635d468 ("spi: spi-geni-qcom: Check for zero length transfer")'. Change-Id: I27bdd8b544ba1bdaa0a868d2260c4f76c156c215 Signed-off-by: Vipin Deep Kaur --- drivers/spi/spi-msm-geni.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index cebb104ba372..144f8567041c 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -1213,6 +1213,12 @@ static int spi_geni_transfer_one(struct spi_master *spi, return -EINVAL; } + /* Check for zero length transfer */ + if (xfer->len < 1) { + dev_err(mas->dev, "Zero length transfer\n"); + return -EINVAL; + } + if (mas->cur_xfer_mode != GSI_DMA) { reinit_completion(&mas->xfer_done); setup_fifo_xfer(xfer, mas, slv->mode, spi);