From: Sowjanya Komatineni <skomatineni@nvidia.com> To: thierry.reding@gmail.com, jonathanh@nvidia.com, talho@nvidia.com, skomatineni@nvidia.com, broonie@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, kyarlagadda@nvidia.com Cc: ldewangan@nvidia.com, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH V3 8/9] spi: tegra114: add support for HW CS timing Date: Mon, 15 Apr 2019 14:30:33 -0700 [thread overview] Message-ID: <1555363834-32155-9-git-send-email-skomatineni@nvidia.com> (raw) In-Reply-To: <1555363834-32155-1-git-send-email-skomatineni@nvidia.com> This patch implements set_cs_timing SPI controller method to allow SPI client driver to configure device specific SPI CS timings. Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> --- drivers/spi/spi-tegra114.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 732347d83366..8476a38cf4fb 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -95,8 +95,10 @@ (reg = (((val) & 0x1) << ((cs) * 8 + 5)) | \ ((reg) & ~(1 << ((cs) * 8 + 5)))) #define SPI_SET_CYCLES_BETWEEN_PACKETS(reg, cs, val) \ - (reg = (((val) & 0xF) << ((cs) * 8)) | \ - ((reg) & ~(0xF << ((cs) * 8)))) + (reg = (((val) & 0x1F) << ((cs) * 8)) | \ + ((reg) & ~(0x1F << ((cs) * 8)))) +#define MAX_SETUP_HOLD_CYCLES 16 +#define MAX_INACTIVE_CYCLES 32 #define SPI_TRANS_STATUS 0x010 #define SPI_BLK_CNT(val) (((val) >> 0) & 0xFFFF) @@ -206,6 +208,8 @@ struct tegra_spi_data { u32 command1_reg; u32 dma_control_reg; u32 def_command1_reg; + u32 spi_cs_timing1; + u32 spi_cs_timing2; struct completion xfer_completion; struct spi_transfer *curr_xfer; @@ -723,6 +727,43 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi, dma_release_channel(dma_chan); } +static void tegra_spi_set_hw_cs_timing(struct spi_device *spi, u8 setup_dly, + u8 hold_dly, u8 inactive_dly) +{ + struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); + u32 setup_hold; + u32 spi_cs_timing; + u32 inactive_cycles; + u8 cs_state; + + setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES); + hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES); + if (setup_dly && hold_dly) { + setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1); + spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1, + spi->chip_select, + setup_hold); + if (tspi->spi_cs_timing1 != spi_cs_timing) { + tspi->spi_cs_timing1 = spi_cs_timing; + tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING1); + } + } + + inactive_cycles = min_t(u8, inactive_dly, MAX_INACTIVE_CYCLES); + if (inactive_cycles) + inactive_cycles--; + cs_state = inactive_cycles ? 0 : 1; + spi_cs_timing = tspi->spi_cs_timing2; + SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + cs_state); + SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + inactive_cycles); + if (tspi->spi_cs_timing2 != spi_cs_timing) { + tspi->spi_cs_timing2 = spi_cs_timing; + tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING2); + } +} + static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, struct spi_transfer *t, bool is_first_of_msg, bool is_single_xfer) @@ -1232,6 +1273,7 @@ static int tegra_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->setup = tegra_spi_setup; master->transfer_one_message = tegra_spi_transfer_one_message; + master->set_cs_timing = tegra_spi_set_hw_cs_timing; master->num_chipselect = MAX_CHIP_SELECT; master->auto_runtime_pm = true; bus_num = of_alias_get_id(pdev->dev.of_node, "spi"); @@ -1307,6 +1349,8 @@ static int tegra_spi_probe(struct platform_device *pdev) reset_control_deassert(tspi->rst); tspi->def_command1_reg = SPI_M_S; tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); + tspi->spi_cs_timing1 = tegra_spi_readl(tspi, SPI_CS_TIMING1); + tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_CS_TIMING2); pm_runtime_put(&pdev->dev); ret = request_threaded_irq(tspi->irq, tegra_spi_isr, tegra_spi_isr_thread, IRQF_ONESHOT, -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Sowjanya Komatineni <skomatineni@nvidia.com> To: <thierry.reding@gmail.com>, <jonathanh@nvidia.com>, <talho@nvidia.com>, <skomatineni@nvidia.com>, <broonie@kernel.org>, <robh+dt@kernel.org>, <mark.rutland@arm.com>, <kyarlagadda@nvidia.com> Cc: <ldewangan@nvidia.com>, <linux-tegra@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <linux-spi@vger.kernel.org>, <devicetree@vger.kernel.org> Subject: [PATCH V3 8/9] spi: tegra114: add support for HW CS timing Date: Mon, 15 Apr 2019 14:30:33 -0700 [thread overview] Message-ID: <1555363834-32155-9-git-send-email-skomatineni@nvidia.com> (raw) In-Reply-To: <1555363834-32155-1-git-send-email-skomatineni@nvidia.com> This patch implements set_cs_timing SPI controller method to allow SPI client driver to configure device specific SPI CS timings. Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> --- drivers/spi/spi-tegra114.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 732347d83366..8476a38cf4fb 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -95,8 +95,10 @@ (reg = (((val) & 0x1) << ((cs) * 8 + 5)) | \ ((reg) & ~(1 << ((cs) * 8 + 5)))) #define SPI_SET_CYCLES_BETWEEN_PACKETS(reg, cs, val) \ - (reg = (((val) & 0xF) << ((cs) * 8)) | \ - ((reg) & ~(0xF << ((cs) * 8)))) + (reg = (((val) & 0x1F) << ((cs) * 8)) | \ + ((reg) & ~(0x1F << ((cs) * 8)))) +#define MAX_SETUP_HOLD_CYCLES 16 +#define MAX_INACTIVE_CYCLES 32 #define SPI_TRANS_STATUS 0x010 #define SPI_BLK_CNT(val) (((val) >> 0) & 0xFFFF) @@ -206,6 +208,8 @@ struct tegra_spi_data { u32 command1_reg; u32 dma_control_reg; u32 def_command1_reg; + u32 spi_cs_timing1; + u32 spi_cs_timing2; struct completion xfer_completion; struct spi_transfer *curr_xfer; @@ -723,6 +727,43 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi, dma_release_channel(dma_chan); } +static void tegra_spi_set_hw_cs_timing(struct spi_device *spi, u8 setup_dly, + u8 hold_dly, u8 inactive_dly) +{ + struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); + u32 setup_hold; + u32 spi_cs_timing; + u32 inactive_cycles; + u8 cs_state; + + setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES); + hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES); + if (setup_dly && hold_dly) { + setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1); + spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1, + spi->chip_select, + setup_hold); + if (tspi->spi_cs_timing1 != spi_cs_timing) { + tspi->spi_cs_timing1 = spi_cs_timing; + tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING1); + } + } + + inactive_cycles = min_t(u8, inactive_dly, MAX_INACTIVE_CYCLES); + if (inactive_cycles) + inactive_cycles--; + cs_state = inactive_cycles ? 0 : 1; + spi_cs_timing = tspi->spi_cs_timing2; + SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + cs_state); + SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + inactive_cycles); + if (tspi->spi_cs_timing2 != spi_cs_timing) { + tspi->spi_cs_timing2 = spi_cs_timing; + tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING2); + } +} + static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, struct spi_transfer *t, bool is_first_of_msg, bool is_single_xfer) @@ -1232,6 +1273,7 @@ static int tegra_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->setup = tegra_spi_setup; master->transfer_one_message = tegra_spi_transfer_one_message; + master->set_cs_timing = tegra_spi_set_hw_cs_timing; master->num_chipselect = MAX_CHIP_SELECT; master->auto_runtime_pm = true; bus_num = of_alias_get_id(pdev->dev.of_node, "spi"); @@ -1307,6 +1349,8 @@ static int tegra_spi_probe(struct platform_device *pdev) reset_control_deassert(tspi->rst); tspi->def_command1_reg = SPI_M_S; tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); + tspi->spi_cs_timing1 = tegra_spi_readl(tspi, SPI_CS_TIMING1); + tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_CS_TIMING2); pm_runtime_put(&pdev->dev); ret = request_threaded_irq(tspi->irq, tegra_spi_isr, tegra_spi_isr_thread, IRQF_ONESHOT, -- 2.7.4
next prev parent reply other threads:[~2019-04-15 21:30 UTC|newest] Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-15 21:30 [PATCH V3 0/9] bug fixes and more features to Tegra SPI Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-15 21:30 ` [PATCH V3 1/9] spi: tegra114: fix PIO transfer Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-16 16:32 ` Applied "spi: tegra114: fix PIO transfer" to the spi tree Mark Brown 2019-04-16 16:32 ` Mark Brown 2019-04-16 16:32 ` Mark Brown 2019-04-16 16:32 ` Mark Brown 2019-04-29 21:42 ` Sowjanya Komatineni 2019-05-02 2:42 ` Mark Brown 2019-04-15 21:30 ` [PATCH V3 2/9] spi: expand mode support Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-18 10:26 ` Applied "spi: expand mode support" to the spi tree Mark Brown 2019-04-18 10:26 ` Mark Brown 2019-04-18 10:26 ` Mark Brown 2019-04-18 10:26 ` Mark Brown 2019-05-02 2:19 ` Mark Brown 2019-05-02 2:19 ` Mark Brown 2019-05-02 2:19 ` Mark Brown 2019-05-02 2:19 ` Mark Brown 2019-04-15 21:30 ` [PATCH V3 3/9] spi: add SPI_LSBYTE_FIRST mode Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-19 15:22 ` Mark Brown 2019-04-27 0:32 ` Sowjanya Komatineni 2019-05-06 4:49 ` Mark Brown 2019-04-15 21:30 ` [PATCH V3 4/9] spi: tegra114: add support for Tegra SPI LSBYTE_FIRST Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-15 21:30 ` [PATCH V3 5/9] spi: export spi core function spi_set_cs Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-19 15:18 ` Mark Brown 2019-04-29 22:02 ` Sowjanya Komatineni 2019-05-06 4:44 ` Mark Brown 2019-05-10 18:53 ` Sowjanya Komatineni 2019-05-12 3:12 ` Mark Brown 2019-04-15 21:30 ` [PATCH V3 6/9] spi: tegra114: add support for gpio based CS Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-15 21:30 ` [PATCH V3 7/9] spi: tegra114: add support for hw based cs Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni [this message] 2019-04-15 21:30 ` [PATCH V3 8/9] spi: tegra114: add support for HW CS timing Sowjanya Komatineni 2019-04-15 21:30 ` [PATCH V3 9/9] spi: tegra114: add support for TX and RX trimmers Sowjanya Komatineni 2019-04-15 21:30 ` Sowjanya Komatineni
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1555363834-32155-9-git-send-email-skomatineni@nvidia.com \ --to=skomatineni@nvidia.com \ --cc=broonie@kernel.org \ --cc=devicetree@vger.kernel.org \ --cc=jonathanh@nvidia.com \ --cc=kyarlagadda@nvidia.com \ --cc=ldewangan@nvidia.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-spi@vger.kernel.org \ --cc=linux-tegra@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=robh+dt@kernel.org \ --cc=talho@nvidia.com \ --cc=thierry.reding@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.