From patchwork Thu Apr 20 20:05:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philipp Tomsich X-Patchwork-Id: 752990 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3w88yf0gJNz9s75 for ; Fri, 21 Apr 2017 06:06:34 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id C313EC21C87; Thu, 20 Apr 2017 20:06:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 997B3C21C4C; Thu, 20 Apr 2017 20:06:21 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E715FC21C59; Thu, 20 Apr 2017 20:06:11 +0000 (UTC) Received: from mail.theobroma-systems.com (vegas.theobroma-systems.com [144.76.126.164]) by lists.denx.de (Postfix) with ESMTPS id 10629C21C82 for ; Thu, 20 Apr 2017 20:06:08 +0000 (UTC) Received: from [86.59.122.178] (port=55234 helo=android.lan) by mail.theobroma-systems.com with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1d1IL7-0002pz-Ox; Thu, 20 Apr 2017 22:06:05 +0200 From: Philipp Tomsich To: u-boot@lists.denx.de Date: Thu, 20 Apr 2017 22:05:50 +0200 Message-Id: <1492718755-14331-3-git-send-email-philipp.tomsich@theobroma-systems.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1492718755-14331-1-git-send-email-philipp.tomsich@theobroma-systems.com> References: <1492718755-14331-1-git-send-email-philipp.tomsich@theobroma-systems.com> Cc: Jacob Chen , Klaus Goger , Philipp Tomsich , Lin huang Subject: [U-Boot] [PATCH v4 2/7] rockchip: clk: rk3399: fix off-by one during rate calculation in i2c/spi_set_rate X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" For the RK3399, i2c_set_rate (and by extension: our spi_set_rate, which had been mindlessly following the template of the i2c_set_rate implementation) miscalculates the rate returned due to a off-by-one error resulting from the following sequence of events: 1. calculates 'src_div := src_freq / target_freq' 2. stores 'src_div - 1' into the register (the actual divider applied in hardware is biased by adding 1) 3. returns the result of the DIV_RATE(src_freq, src_div) macro, which expects the (decremented) divider from the hardware-register and implictly adds 1 (i.e. 'DIV_RATE(freq, div) := freq / (div + 1)') This can be observed with the SPI driver, which sets a rate of 99MHz based on the GPLL frequency of 594MHz: the hardware generates a clock of 99MHz (src_div is 6, the bitfield in the register correctly reads 5), but reports a frequency of 84MHz (594 / 7) on return. To fix, we have two options: * either we bias (i.e. "DIV_RATE(GPLL, src_div - 1)"), which doesn't make for a particularily nice read * we simply call the i2c/spi_get_rate function (introducing additional overhead for the additional register-read), which reads the divider from the register and then passes it through the DIV_RATE macro Given that this code is not time-critical, the more readable solution (i.e. calling the appropriate get_rate function) is implemented in this change. Signed-off-by: Philipp Tomsich Tested-by: Klaus Goger Acked-by: Simon Glass --- Changes in v4: None Changes in v3: None Changes in v2: - fixes an off-by-one for the RK3399 that cause the SPI module input clock to be misstated as 84MHz (even though it was running at 99MHz) drivers/clk/rockchip/clk_rk3399.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index da62757..ac658b9 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -606,7 +606,7 @@ static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) return -EINVAL; } - return DIV_TO_RATE(GPLL_HZ, src_clk_div); + return rk3399_i2c_get_clk(cru, clk_id); } /* @@ -695,8 +695,7 @@ static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz) ((src_clk_div << spiclk->div_shift) | (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift))); - - return DIV_TO_RATE(GPLL_HZ, src_clk_div); + return rk3399_spi_get_clk(cru, clk_id); } static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)