From patchwork Thu Apr 2 09:11:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 6145641 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 655F19F350 for ; Thu, 2 Apr 2015 09:21:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 84C1D20304 for ; Thu, 2 Apr 2015 09:21:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 96A1720382 for ; Thu, 2 Apr 2015 09:21:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752505AbbDBJVG (ORCPT ); Thu, 2 Apr 2015 05:21:06 -0400 Received: from gw02.mail.saunalahti.fi ([195.197.172.116]:34581 "EHLO gw02.mail.saunalahti.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752619AbbDBJVE (ORCPT ); Thu, 2 Apr 2015 05:21:04 -0400 Received: from localhost.localdomain (a91-152-110-231.elisa-laajakaista.fi [91.152.110.231]) by gw02.mail.saunalahti.fi (Postfix) with ESMTP id EBA054003A; Thu, 2 Apr 2015 12:11:46 +0300 (EEST) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.8/8.14.8) with ESMTP id t329C7nK028182; Thu, 2 Apr 2015 12:12:07 +0300 Received: (from andy@localhost) by localhost.localdomain (8.14.8/8.14.8/Submit) id t329C5RH028181; Thu, 2 Apr 2015 12:12:05 +0300 X-Authentication-Warning: localhost.localdomain: andy set sender to andy.shevchenko@gmail.com using -f From: Andy Shevchenko To: Aaron Brice , linux-spi@vger.kernel.org, Mark Brown Cc: Andy Shevchenko Subject: [PATCH v1 2/2][RFC] spi: fsl-dspi: use double baud rate in approximation Date: Thu, 2 Apr 2015 12:11:47 +0300 Message-Id: <1427965907-28125-3-git-send-email-andy.shevchenko@gmail.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1427965907-28125-1-git-send-email-andy.shevchenko@gmail.com> References: <1427965907-28125-1-git-send-email-andy.shevchenko@gmail.com> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham 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 The CTAR register has DBR bit which allows to double a baud rate, though it makes duty cycle deviate from 50/50. This patch tries to approximate better using DBR. It helps in case of highest possible baud rates. Signed-off-by: Andy Shevchenko --- drivers/spi/spi-fsl-dspi.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 31cdee5..92d387a 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -47,6 +47,7 @@ #define SPI_TCR 0x08 #define SPI_CTAR(x) (0x0c + (((x) & 0x3) * 4)) +#define SPI_CTAR_DBR(x) (((x) & 0x00000001) << 31) #define SPI_CTAR_FMSZ(x) (((x) & 0x0000000f) << 27) #define SPI_CTAR_CPOL(x) ((x) << 26) #define SPI_CTAR_CPHA(x) ((x) << 25) @@ -139,8 +140,8 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } -static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, - unsigned long clkrate) +static void hz_to_spi_baud(char *dbr, char *pbr, char *br, + int speed_hz, unsigned long clkrate) { /* Valid baud rate pre-scaler values */ int pbr_tbl[4] = {2, 3, 5, 7}; @@ -151,17 +152,21 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, 4096, 8192, 16384, 32768, }; unsigned long r = INT_MAX, tmp; - int i, j; - - for (i = 0; i < ARRAY_SIZE(brs); i++) - for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { - tmp = abs(clkrate / pbr_tbl[j] / brs[i] - speed_hz); - if (tmp >= r) - continue; - r = tmp; - *br = i; - *pbr = j; + int i, j, k; + + for (k = 0; k < 2; k++) { + for (i = 0; i < ARRAY_SIZE(brs); i++) { + for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { + tmp = abs(clkrate / pbr_tbl[j] / brs[i] - speed_hz); + if (tmp >= r) + continue; + r = tmp; + *br = i; + *pbr = j; + *dbr = k; + } } + } } static int dspi_transfer_write(struct fsl_dspi *dspi) @@ -342,7 +347,7 @@ static int dspi_setup(struct spi_device *spi) { struct chip_data *chip; struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); - unsigned char br = 0, pbr = 0, fmsz = 0; + unsigned char br = 0, pbr = 0, dbr = 0, fmsz = 0; if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { fmsz = spi->bits_per_word - 1; @@ -364,13 +369,14 @@ static int dspi_setup(struct spi_device *spi) chip->void_write_data = 0; - hz_to_spi_baud(&pbr, &br, + hz_to_spi_baud(&dbr, &pbr, &br, spi->max_speed_hz, clk_get_rate(dspi->clk)); chip->ctar_val = SPI_CTAR_FMSZ(fmsz) | SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0) | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0) | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0) + | SPI_CTAR_DBR(dbr) | SPI_CTAR_PBR(pbr) | SPI_CTAR_BR(br);