From patchwork Thu Jul 10 09:26:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lars-Peter Clausen X-Patchwork-Id: 4522361 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E3C249F26C for ; Thu, 10 Jul 2014 09:26:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1E81C2021B for ; Thu, 10 Jul 2014 09:26:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4942020200 for ; Thu, 10 Jul 2014 09:26:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752753AbaGJJ0f (ORCPT ); Thu, 10 Jul 2014 05:26:35 -0400 Received: from smtp-out-166.synserver.de ([212.40.185.166]:1056 "EHLO smtp-out-166.synserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752144AbaGJJ0e (ORCPT ); Thu, 10 Jul 2014 05:26:34 -0400 Received: (qmail 23771 invoked by uid 0); 10 Jul 2014 09:26:32 -0000 X-SynServer-TrustedSrc: 1 X-SynServer-AuthUser: lars@metafoo.de X-SynServer-PPID: 23655 Received: from p4fe63414.dip0.t-ipconnect.de (HELO lars-adi-laptop.analog.com) [79.230.52.20] by 217.119.54.73 with SMTP; 10 Jul 2014 09:26:31 -0000 From: Lars-Peter Clausen To: Mark Brown Cc: Harini Katakam , linux-spi@vger.kernel.org, Lars-Peter Clausen Subject: [PATCH 1/2] spi: cadence: Make sure that clock polarity changes are applied Date: Thu, 10 Jul 2014 11:26:28 +0200 Message-Id: <1404984389-12802-1-git-send-email-lars@metafoo.de> X-Mailer: git-send-email 1.8.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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); + } } /**