From patchwork Fri Apr 3 20:39:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Brice X-Patchwork-Id: 6159931 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 D47109F350 for ; Fri, 3 Apr 2015 20:39:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E82A920396 for ; Fri, 3 Apr 2015 20:39:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DE3AF203AA for ; Fri, 3 Apr 2015 20:39:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752468AbbDCUjq (ORCPT ); Fri, 3 Apr 2015 16:39:46 -0400 Received: from p3plsmtpa08-09.prod.phx3.secureserver.net ([173.201.193.110]:54769 "EHLO p3plsmtpa08-09.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752091AbbDCUjp (ORCPT ); Fri, 3 Apr 2015 16:39:45 -0400 Received: from bricepc.corp.datasoft.com ([184.185.173.186]) by p3plsmtpa08-09.prod.phx3.secureserver.net with id BYfY1q00441flQ801YfklJ; Fri, 03 Apr 2015 13:39:45 -0700 From: Aaron Brice To: broonie@kernel.org Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, stefan@agner.ch, devicetree@vger.kernel.org Subject: [PATCH v3 1/3] spi: fsl-dspi: Fix clock rate scale values Date: Fri, 3 Apr 2015 13:39:29 -0700 Message-Id: <1428093571-20407-2-git-send-email-aaron.brice@datasoft.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1428093571-20407-1-git-send-email-aaron.brice@datasoft.com> References: <1428093571-20407-1-git-send-email-aaron.brice@datasoft.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, RCVD_IN_DNSWL_HI, T_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 Previous algorithm had an outer loop with the values {2,3,5,7} and an inner loop with {2,4,6,8,16,32,...,32768}, and would pick the first value over the required scaling value (where the total scale was the two numbers multiplied). Since the inner loop went up to 32768 it would always pick a value of 2 for PBR and a much higher than necessary value for BR. The desired scale factor was being divided by two I believe to compensate for the much higher scale factors (the divide by two not specified in the reference manual). Updated to check all values and find the smallest scale factor possible without going over the desired clock rate. Signed-off-by: Aaron Brice --- drivers/spi/spi-fsl-dspi.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index d1a3924..8213358 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -148,23 +148,32 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 }; - int temp, i = 0, j = 0; - - temp = clkrate / 2 / speed_hz; - - for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++) - for (j = 0; j < ARRAY_SIZE(brs); j++) { - if (pbr_tbl[i] * brs[j] >= temp) { - *pbr = i; - *br = j; - return; + int scale_needed, scale, minscale = INT_MAX; + int i, j; + + scale_needed = clkrate / speed_hz; + if (clkrate % speed_hz) + scale_needed++; + + for (i = 0; i < ARRAY_SIZE(brs); i++) + for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) { + scale = brs[i] * pbr_tbl[j]; + if (scale >= scale_needed) { + if (scale < minscale) { + minscale = scale; + *br = i; + *pbr = j; + } + break; } } - pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\ - ,we use the max prescaler value.\n", speed_hz, clkrate); - *pbr = ARRAY_SIZE(pbr_tbl) - 1; - *br = ARRAY_SIZE(brs) - 1; + if (minscale == INT_MAX) { + pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n", + speed_hz, clkrate); + *pbr = ARRAY_SIZE(pbr_tbl) - 1; + *br = ARRAY_SIZE(brs) - 1; + } } static int dspi_transfer_write(struct fsl_dspi *dspi)