From patchwork Thu Jan 15 01:50:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nobuhiro Iwamatsu X-Patchwork-Id: 5636011 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 625F4C058D for ; Thu, 15 Jan 2015 01:50:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 64B43201C0 for ; Thu, 15 Jan 2015 01:50:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 707FD20173 for ; Thu, 15 Jan 2015 01:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751364AbbAOBu1 (ORCPT ); Wed, 14 Jan 2015 20:50:27 -0500 Received: from mail-pd0-f173.google.com ([209.85.192.173]:43031 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751314AbbAOBu0 (ORCPT ); Wed, 14 Jan 2015 20:50:26 -0500 Received: by mail-pd0-f173.google.com with SMTP id ft15so13226840pdb.4 for ; Wed, 14 Jan 2015 17:50:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=wBBcXeD+dD4k43oS+2sXODMmRVjo1azpLviZ/3z7RZM=; b=G7POGmG8mD63CgBJ0rhyXKGBQ01kvPwb9GZMvF/XehC94IufDT3lpDoTFPsdFSIF4L ewmJBogaumzoR/eB13l1aAbLGJ4PvpsOS9xKIYNvVI3nyg1OzvFleyQpjg4k4ne98T6B 0odVj2+is+fjWekaljNIj6hzbckQhmcduthFS41vSsaySOtOJFzObkw9GEII/MJJl97D ykfDOjL5oC3i+t8NgjjB1ZptJwumnfmbqe0snkb8cnnsMTWAIOiTK8jZAEgwLHTmtfTm 03Xy703CwdFtbI/M4Ttqu2AwdNNyrh4lwPgL0v1r0k6V5hOEjHYjFZ0njARgJ5T2P3rc vtTQ== X-Gm-Message-State: ALoCoQkVgmViIBXU0zCR6QuNAcIMiUvq1+1paeMnMWd7uI8iOP+uWrgnqsiwnIZY8jC5bmMExTdS X-Received: by 10.68.211.161 with SMTP id nd1mr10478354pbc.92.1421286626099; Wed, 14 Jan 2015 17:50:26 -0800 (PST) Received: from xps-iwamatsu.renesas.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPSA id qy3sm82240pbc.4.2015.01.14.17.50.22 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 14 Jan 2015 17:50:24 -0800 (PST) From: Nobuhiro Iwamatsu To: linux-spi@vger.kernel.org Cc: linux-sh@vger.kernel.org, sergei.shtylyov@cogentembedded.com, geert@glider.be, yoshihiro.shimoda.uh@renesas.com, Nobuhiro Iwamatsu Subject: [PATCH v2] spi: sh-msiof: Update calculation of frequency dividing Date: Thu, 15 Jan 2015 10:50:13 +0900 Message-Id: <1421286613-8240-1-git-send-email-nobuhiro.iwamatsu.yj@renesas.com> X-Mailer: git-send-email 2.1.3 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@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=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 sh-msiof of frequency dividing does not perform the calculation, driver have to manage setting value in the table. It is not possible to set frequency dividing value close to the actual data in this way. This changes from frequency dividing of table management to setting by calculation. This driver is able to set a value close to the actual data. Signed-off-by: Nobuhiro Iwamatsu --- V2: - use u32 instead of unsigned long. - Fix loop. - Use SCR_BRPS instead of hoard code shift. - Add check of div maximum value. drivers/spi/spi-sh-msiof.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 96a5fc0..545ffff 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -241,42 +241,41 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data) static struct { unsigned short div; - unsigned short scr; -} const sh_msiof_spi_clk_table[] = { - { 1, SCR_BRPS( 1) | SCR_BRDV_DIV_1 }, - { 2, SCR_BRPS( 1) | SCR_BRDV_DIV_2 }, - { 4, SCR_BRPS( 1) | SCR_BRDV_DIV_4 }, - { 8, SCR_BRPS( 1) | SCR_BRDV_DIV_8 }, - { 16, SCR_BRPS( 1) | SCR_BRDV_DIV_16 }, - { 32, SCR_BRPS( 1) | SCR_BRDV_DIV_32 }, - { 64, SCR_BRPS(32) | SCR_BRDV_DIV_2 }, - { 128, SCR_BRPS(32) | SCR_BRDV_DIV_4 }, - { 256, SCR_BRPS(32) | SCR_BRDV_DIV_8 }, - { 512, SCR_BRPS(32) | SCR_BRDV_DIV_16 }, - { 1024, SCR_BRPS(32) | SCR_BRDV_DIV_32 }, + unsigned short brdv; +} const sh_msiof_spi_div_table[] = { + { 1, SCR_BRDV_DIV_1 }, + { 2, SCR_BRDV_DIV_2 }, + { 4, SCR_BRDV_DIV_4 }, + { 8, SCR_BRDV_DIV_8 }, + { 16, SCR_BRDV_DIV_16 }, + { 32, SCR_BRDV_DIV_32 }, }; -static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, +static int sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, unsigned long parent_rate, u32 spi_hz) { unsigned long div = 1024; + u32 brps, scr; size_t k; if (!WARN_ON(!spi_hz || !parent_rate)) div = DIV_ROUND_UP(parent_rate, spi_hz); - /* TODO: make more fine grained */ + if (div > 1024) /* Max of divider is 1024 */ + return -EINVAL; - for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_clk_table); k++) { - if (sh_msiof_spi_clk_table[k].div >= div) + for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) { + brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div); + if (brps <= 32) /* max of brdv is 32 */ break; } - k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_clk_table) - 1); - - sh_msiof_write(p, TSCR, sh_msiof_spi_clk_table[k].scr); + scr = sh_msiof_spi_div_table[k].brdv | SCR_BRPS(brps); + sh_msiof_write(p, TSCR, scr); if (!(p->chipdata->master_flags & SPI_MASTER_MUST_TX)) - sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); + sh_msiof_write(p, RSCR, scr); + + return 0; } static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, @@ -804,7 +803,9 @@ static int sh_msiof_transfer_one(struct spi_master *master, int ret; /* setup clocks (clock already enabled in chipselect()) */ - sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz); + ret = sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz); + if (ret) + return ret; while (master->dma_tx && len > 15) { /*