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: 5636021 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 53A509F357 for ; Thu, 15 Jan 2015 01:50:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 67A1720173 for ; Thu, 15 Jan 2015 01:50:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6575E201C8 for ; Thu, 15 Jan 2015 01:50:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751314AbbAOBu1 (ORCPT ); Wed, 14 Jan 2015 20:50:27 -0500 Received: from mail-pd0-f181.google.com ([209.85.192.181]:34098 "EHLO mail-pd0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751353AbbAOBu1 (ORCPT ); Wed, 14 Jan 2015 20:50:27 -0500 Received: by mail-pd0-f181.google.com with SMTP id z10so1738639pdj.12 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=OI4XT9K/ffIWMBtQq3qBV27Hjg6yb8nPozvolErrUmZK9WnVmpszlQW7G7MiYEHcxw wiZ0QZ8e1tTIngfQ2t+iukfrlGBZBrIzJKaqbCXvdnhmuMwTxArlI1QIzNkH0YGAR32m 4A0F8DAobnWh2GZbLguXyGUXTvSRHzSO1i1SRfszfZm3ow9s6RnaVT6V/YXlFgAxqjee lwZMo6OfUHINsdNnEv/AzakBae9jDqIBb1Kj86IzgTzXl9qzUEnsp8OMgFACMzCchJQ8 zAtT9MFVofnJZ3i0ZG8jjQscyq8bFLZwxz+kWXjokflGlU55Q5Z9hUyyDbKaAmwJLyn0 uJXg== X-Gm-Message-State: ALoCoQktTvi3MA30xZyqoKAYgUA734CbKljlpTPY9ekE/Qa4BxWXHcfD3rM6nisKE+RXqoLVS7pX 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-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 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) { /*