* [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied @ 2014-07-10 9:26 Lars-Peter Clausen [not found] ` <1404984389-12802-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> 0 siblings, 1 reply; 5+ messages in thread From: Lars-Peter Clausen @ 2014-07-10 9:26 UTC (permalink / raw) To: Mark Brown Cc: Harini Katakam, linux-spi-u79uwXL29TY76Z2rM5mHXA, Lars-Peter Clausen It seems that the cadence SPI controller does not immediately change the clock polarity setting when writing the CR register. Instead the change is delayed until the next transfer starts. This happens after the chip select line has already been asserted. As a result the first transfer after a clock polarity change will generate spurious clock transitions which typically results in the SPI slave not being able to properly understand the message. Toggling the ER register seems to cause the SPI controller to apply the clock polarity changes, so implement this as a workaround to fix the issue. Signed-off-by: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> --- drivers/spi/spi-cadence.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 98b763b..03f4d5e 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) static void cdns_spi_config_clock_mode(struct spi_device *spi) { struct cdns_spi *xspi = spi_master_get_devdata(spi->master); - u32 ctrl_reg; + u32 ctrl_reg, new_ctrl_reg; - ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); + new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET); /* Set the SPI clock phase and clock polarity */ - ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); + new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK); if (spi->mode & SPI_CPHA) - ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; + new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK; if (spi->mode & SPI_CPOL) - ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; - - cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg); + new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK; + + if (new_ctrl_reg != ctrl_reg) { + /* + * Just writing the CR register does not seem to apply the clock + * setting changes. This is problematic when changing the clock + * polarity as it will cause the SPI slave to see spurious clock + * transitions. To workaround the issue toggle the ER register. + */ + cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, + CDNS_SPI_ER_DISABLE_MASK); + cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg); + cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, + CDNS_SPI_ER_ENABLE_MASK); + } } /** -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 5+ messages in thread
[parent not found: <1404984389-12802-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>]
* [PATCH 2/2] spi: cadence: Configure SPI clock in the prepare_message() callback [not found] ` <1404984389-12802-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> @ 2014-07-10 9:26 ` Lars-Peter Clausen [not found] ` <1404984389-12802-2-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> 2014-07-11 13:39 ` [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied Mark Brown 1 sibling, 1 reply; 5+ messages in thread From: Lars-Peter Clausen @ 2014-07-10 9:26 UTC (permalink / raw) To: Mark Brown Cc: Harini Katakam, linux-spi-u79uwXL29TY76Z2rM5mHXA, Lars-Peter Clausen Currently the cadence SPI driver does the SPI clock configuration (setup CPOL and CPHA) in the prepare_transfer_hardware() callback. The prepare_transfer_hardware() callback is only called though when the controller transitions from a idle state to a non-idle state. Such a transitions happens when the message queue goes from empty to non-empty. If multiple messages from different SPI slaves with different clock settings are in the message queue the clock settings will not be properly updated when switching from one slave device to another. Instead do the updating of the clock configuration in the prepare_message() callback which will be called for each individual message. Signed-off-by: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> --- drivers/spi/spi-cadence.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 03f4d5e..562ff83 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -382,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id) return status; } +static int cdns_prepare_message(struct spi_master *master, + struct spi_message *msg) +{ + cdns_spi_config_clock_mode(msg->spi); + return 0; +} /** * cdns_transfer_one - Initiates the SPI transfer @@ -428,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master) { struct cdns_spi *xspi = spi_master_get_devdata(master); - cdns_spi_config_clock_mode(master->cur_msg->spi); - cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET, CDNS_SPI_ER_ENABLE_MASK); @@ -544,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev) xspi->is_decoded_cs = 0; master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; + master->prepare_message = cdns_prepare_message; master->transfer_one = cdns_transfer_one; master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; master->set_cs = cdns_spi_chipselect; -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 5+ messages in thread
[parent not found: <1404984389-12802-2-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>]
* Re: [PATCH 2/2] spi: cadence: Configure SPI clock in the prepare_message() callback [not found] ` <1404984389-12802-2-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> @ 2014-07-10 10:43 ` Harini Katakam [not found] ` <CAFcVEC+yX7Zm2rq=XU0V8cs-vgxeLX5HsM=NySXwe9iEazC5eA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 5+ messages in thread From: Harini Katakam @ 2014-07-10 10:43 UTC (permalink / raw) To: Lars-Peter Clausen; +Cc: Mark Brown, linux-spi Hi, On Thu, Jul 10, 2014 at 2:56 PM, Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> wrote: > Currently the cadence SPI driver does the SPI clock configuration (setup CPOL > and CPHA) in the prepare_transfer_hardware() callback. The > prepare_transfer_hardware() callback is only called though when the controller > transitions from a idle state to a non-idle state. Such a transitions happens > when the message queue goes from empty to non-empty. If multiple messages from > different SPI slaves with different clock settings are in the message queue the > clock settings will not be properly updated when switching from one slave device > to another. Instead do the updating of the clock configuration in the > prepare_message() callback which will be called for each individual message. > Yes, the requirement from the controller is that CPOL/CPHA setting changes will not take effect when SPI is enabled. CPOL/CPHA setting is done in prepare_hardware before SPI is enabled. So this works. According to your patches I understand that you might change CPOL/CPHA for each message. Is this possible? Is this a requirement? Regards, Harini -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <CAFcVEC+yX7Zm2rq=XU0V8cs-vgxeLX5HsM=NySXwe9iEazC5eA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH 2/2] spi: cadence: Configure SPI clock in the prepare_message() callback [not found] ` <CAFcVEC+yX7Zm2rq=XU0V8cs-vgxeLX5HsM=NySXwe9iEazC5eA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2014-07-10 10:50 ` Lars-Peter Clausen 0 siblings, 0 replies; 5+ messages in thread From: Lars-Peter Clausen @ 2014-07-10 10:50 UTC (permalink / raw) To: Harini Katakam; +Cc: Mark Brown, linux-spi On 07/10/2014 12:43 PM, Harini Katakam wrote: > Hi, > > On Thu, Jul 10, 2014 at 2:56 PM, Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> wrote: >> Currently the cadence SPI driver does the SPI clock configuration (setup CPOL >> and CPHA) in the prepare_transfer_hardware() callback. The >> prepare_transfer_hardware() callback is only called though when the controller >> transitions from a idle state to a non-idle state. Such a transitions happens >> when the message queue goes from empty to non-empty. If multiple messages from >> different SPI slaves with different clock settings are in the message queue the >> clock settings will not be properly updated when switching from one slave device >> to another. Instead do the updating of the clock configuration in the >> prepare_message() callback which will be called for each individual message. >> > > Yes, the requirement from the controller is that CPOL/CPHA setting changes > will not take effect when SPI is enabled. CPOL/CPHA setting is done in > prepare_hardware > before SPI is enabled. So this works. > According to your patches I understand that you might change CPOL/CPHA for > each message. Is this possible? Is this a requirement? The message can be from different SPI devices, so yes this is a requirement. I'm seeing the issue in one of my setups. - Lars -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied [not found] ` <1404984389-12802-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> 2014-07-10 9:26 ` [PATCH 2/2] spi: cadence: Configure SPI clock in the prepare_message() callback Lars-Peter Clausen @ 2014-07-11 13:39 ` Mark Brown 1 sibling, 0 replies; 5+ messages in thread From: Mark Brown @ 2014-07-11 13:39 UTC (permalink / raw) To: Lars-Peter Clausen; +Cc: Harini Katakam, linux-spi-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 329 bytes --] On Thu, Jul 10, 2014 at 11:26:28AM +0200, Lars-Peter Clausen wrote: > It seems that the cadence SPI controller does not immediately change the clock > polarity setting when writing the CR register. Instead the change is delayed > until the next transfer starts. This happens after the chip select line has Applied both, thanks. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-07-11 13:39 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-10 9:26 [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied Lars-Peter Clausen [not found] ` <1404984389-12802-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> 2014-07-10 9:26 ` [PATCH 2/2] spi: cadence: Configure SPI clock in the prepare_message() callback Lars-Peter Clausen [not found] ` <1404984389-12802-2-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> 2014-07-10 10:43 ` Harini Katakam [not found] ` <CAFcVEC+yX7Zm2rq=XU0V8cs-vgxeLX5HsM=NySXwe9iEazC5eA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2014-07-10 10:50 ` Lars-Peter Clausen 2014-07-11 13:39 ` [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied Mark Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).