From patchwork Mon Jun 15 15:49:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vaibhav Hiremath X-Patchwork-Id: 6610341 Return-Path: X-Original-To: patchwork-linux-arm@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 D89DAC0020 for ; Mon, 15 Jun 2015 16:03:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D5CE020270 for ; Mon, 15 Jun 2015 16:02:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C18EF20138 for ; Mon, 15 Jun 2015 16:02:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z4Wng-0004tu-Df; Mon, 15 Jun 2015 15:59:52 +0000 Received: from mail-pd0-f178.google.com ([209.85.192.178]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z4WiG-0000B0-Fx for linux-arm-kernel@lists.infradead.org; Mon, 15 Jun 2015 15:54:17 +0000 Received: by pdbki1 with SMTP id ki1so75752886pdb.1 for ; Mon, 15 Jun 2015 08:53:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LzA65CKlyMUG2iHYG+wujnY1s+u9hAA08DrJPZU0obM=; b=S4PV6o+6UQO4t17cw9H0DZRBvlgeCFxHAfD34IFsw9R2jWM0zgguJjRelc2YhYqma7 NauJ/ZmrDw8mXF1x29G/vHVr2WzlsHF4L/jUZ28m6xihqdjVN9b+Azbgl4TNoIueIoKL WC54MmDsVckGWKyJXvfcaRSdsX6u/+y+Jk4DPe6g6YcHjfsLaWAofTKUOyRQuyr4mEla vpwAVjl8/UC14pt+h3JgsdQPhfZVUeVtJQTu/1JYTQa8u21OadcAfRWGGQy2NUmUp2zT QDxi/aFkSXzB7A7zrZF/a70vLb2YuREg2BBK2M8xRoaXy4BIoSJyvACLW9sl9EcWvJ5V FLbA== X-Gm-Message-State: ALoCoQk1w3SORmZav673tH/aBDNYYzY+DuPSb7ivfKg04w+GvdxtITfoueBOG/KFgcGTvdt5BeXT X-Received: by 10.68.191.101 with SMTP id gx5mr50144514pbc.148.1434383634794; Mon, 15 Jun 2015 08:53:54 -0700 (PDT) Received: from localhost.localdomain ([202.62.77.106]) by mx.google.com with ESMTPSA id fs16sm12662484pdb.12.2015.06.15.08.53.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 15 Jun 2015 08:53:54 -0700 (PDT) From: Vaibhav Hiremath To: linux-i2c@vger.kernel.org Subject: [PATCH-V2 11/12] i2c: pxa: Add ILCR (tLow & tHigh) configuration support Date: Mon, 15 Jun 2015 21:19:58 +0530 Message-Id: <1434383399-2370-12-git-send-email-vaibhav.hiremath@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434383399-2370-1-git-send-email-vaibhav.hiremath@linaro.org> References: <1434383399-2370-1-git-send-email-vaibhav.hiremath@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150615_085416_590356_D34B8B58 X-CRM114-Status: GOOD ( 16.79 ) X-Spam-Score: -0.7 (/) Cc: wsa@the-dreams.de, Yi Zhang , Vaibhav Hiremath , "Jett.Zhou" , robert.jarzmik@free.fr, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 With addition of PXA910 family of devices, the TWSI module supports SCL clock adjustment using ILCR register. This patch enables the control and configuration of ICLR through DT properties, i2c-sclk-high-time-ns: SCLK high time (tHigh), for standard/fast/high speed mode i2c-sclk-low-time-ns: SCLK low time (tLow), for standard/fast/high speed mode Note that in case of standard and fast mod, the tLow and tHigh counters are same, and software will use tLow value. Signed-off-by: Vaibhav Hiremath Signed-off-by: Jett.Zhou Signed-off-by: Yi Zhang --- drivers/i2c/busses/i2c-pxa.c | 66 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 97f9c7c..03b70f8 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -195,6 +195,9 @@ struct pxa_i2c { unsigned long rate; bool highmode_enter; bool disable_after_xfer; + + unsigned int sclk_thigh_load_cnt; + unsigned int sclk_tlow_load_cnt; }; #define _IBMR(i2c) ((i2c)->reg_ibmr) @@ -507,6 +510,33 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode) #define i2c_pxa_set_slave(i2c, err) do { } while (0) #endif +static void i2c_pxa_do_sclk_adj(struct pxa_i2c *i2c) +{ + unsigned int reg_ilcr; + + reg_ilcr = readl(_ILCR(i2c)); + + /* For standard/fast mode tlow and thigh counters are same */ + if (i2c->sclk_tlow_load_cnt) { + unsigned int mask, shift; + + mask = i2c->high_mode ? ILCR_HLVL_MASK : + i2c->fast_mode ? ILCR_FLV_MASK : ILCR_SLV_MASK; + shift = i2c->high_mode ? ILCR_HLVL_SHIFT : + i2c->fast_mode ? ILCR_FLV_SHIFT : ILCR_SLV_SHIFT; + + reg_ilcr &= ~mask; + reg_ilcr |= i2c->sclk_tlow_load_cnt << shift; + } + + if (i2c->high_mode && i2c->sclk_thigh_load_cnt) { + reg_ilcr &= ~ILCR_HLVH_MASK; + reg_ilcr |= i2c->sclk_thigh_load_cnt << ILCR_HLVH_SHIFT; + } + + writel(reg_ilcr, _ILCR(i2c)); +} + static void i2c_pxa_reset(struct pxa_i2c *i2c) { pr_debug("Resetting I2C Controller Unit\n"); @@ -526,6 +556,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c) writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c)); writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c)); + i2c_pxa_do_sclk_adj(i2c); + #ifdef CONFIG_I2C_PXA_SLAVE dev_info(&i2c->adap.dev, "Enabling slave mode\n"); writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c)); @@ -1204,6 +1236,26 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, *i2c_types = (long)(of_id->data); + /* optional properties */ + if (of_device_is_compatible(np, "mrvl,mmp-twsi")) { + unsigned int tlow = 0, thigh = 0; + unsigned int clk_ns; + + /* clock time in nsec */ + clk_ns = 1000000 / (i2c->rate / 1000); + + of_property_read_u32(np, "i2c-sclk-high-time-ns", &thigh); + i2c->sclk_thigh_load_cnt = thigh / clk_ns; + + of_property_read_u32(np, "i2c-sclk-low-time-ns", &tlow); + i2c->sclk_tlow_load_cnt = tlow / clk_ns; + + /* For std/fast mode tlow & thigh have same bit-fields */ + if (!i2c->high_mode && + (i2c->sclk_tlow_load_cnt != i2c->sclk_thigh_load_cnt)) + dev_warn(&i2c->adap.dev, + "mismatch of tLow & tHigh values, using tLow\n"); + } return 0; } @@ -1253,6 +1305,14 @@ static int i2c_pxa_probe(struct platform_device *dev) return irq; } + i2c->clk = devm_clk_get(&dev->dev, NULL); + if (IS_ERR(i2c->clk)) { + dev_err(&dev->dev, "failed to get the clk\n"); + return PTR_ERR(i2c->clk); + } + + i2c->rate = clk_get_rate(i2c->clk); + /* Default adapter num to device id; i2c_pxa_probe_dt can override. */ i2c->adap.nr = dev->id; @@ -1270,12 +1330,6 @@ static int i2c_pxa_probe(struct platform_device *dev) strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name)); - i2c->clk = devm_clk_get(&dev->dev, NULL); - if (IS_ERR(i2c->clk)) { - dev_err(&dev->dev, "failed to get the clk\n"); - return PTR_ERR(i2c->clk); - } - i2c->reg_base = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(i2c->reg_base)) { dev_err(&dev->dev, "failed to map resource: %ld\n",