It was <2020-08-24 pon 15:21>, when Tomasz Figa wrote: > On Mon, Aug 24, 2020 at 3:17 PM Lukasz Stelmach wrote: >> >> It was <2020-08-22 sob 14:43>, when Krzysztof Kozlowski wrote: >> > On Fri, Aug 21, 2020 at 06:13:59PM +0200, Łukasz Stelmach wrote: >> >> cur_speed is used to calculate transfer timeout and needs to be >> >> set to the actual value of (half) the clock speed for precise >> >> calculations. >> > >> > If you need this only for timeout calculation just divide it in >> > s3c64xx_wait_for_dma(). >> >> I divide it here to keep the relationship between the value the variable >> holds and the one that is inside clk_* (See? It's multiplied 3 lines >> above). If you look around every single clk_get_rate() call in the file is >> divided by two. >> >> > Otherwise why only if (cmu) case is updated? >> >> You are righ I will update that too. >> >> However, I wonder if it is even possible that the value read from >> S3C64XX_SPI_CLK_CFG would be different than the one written to it? >> > > It is not possible for the register itself, but please see my other > reply, where I explained the integer rounding error which can happen > when calculating the value to write to the register. I don't have any board to test it and Marek says there is only one that doesn't use cmu *and* has an SPI device attached. Here is what I think should work for the !cmu case. --8<---------------cut here---------------start------------->8--- diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 18b89e53ceda..5ebb1caade4d 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -655,13 +655,18 @@ static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) return ret; sdd->cur_speed = clk_get_rate(sdd->src_clk) / 2; } else { + int src_clk_rate = clk_get_rate(sdd->src_clk); + int clk_val = (src_clk_rate / sdd->cur_speed / 2 - 1); + /* Configure Clock */ val = readl(regs + S3C64XX_SPI_CLK_CFG); val &= ~S3C64XX_SPI_PSR_MASK; - val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1) - & S3C64XX_SPI_PSR_MASK); + val |= (clk_val & S3C64XX_SPI_PSR_MASK); writel(val, regs + S3C64XX_SPI_CLK_CFG); + /* Keep the actual value */ + sdd->cur_speed = src_clk_rate / (2 * (clk_val + 1)); + /* Enable Clock */ val = readl(regs + S3C64XX_SPI_CLK_CFG); val |= S3C64XX_SPI_ENCLK_ENABLE; --8<---------------cut here---------------end--------------->8--- >> > You are also affecting here not only timeout but >> > s3c64xx_enable_datapath() which is not mentioned in commit log. In other >> > words, this looks wrong. >> >> Indeed, there is a reference too. I've corrected the message. >> > > Thanks! > > Best regards, > Tomasz > >> >> >> >> Cc: Tomasz Figa >> >> Signed-off-by: Łukasz Stelmach >> >> --- >> >> drivers/spi/spi-s3c64xx.c | 1 + >> >> 1 file changed, 1 insertion(+) >> >> >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> >> index 02de734b8ab1..89c162efe355 100644 >> >> --- a/drivers/spi/spi-s3c64xx.c >> >> +++ b/drivers/spi/spi-s3c64xx.c >> >> @@ -626,6 +626,7 @@ static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) >> >> ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); >> >> if (ret) >> >> return ret; >> >> + sdd->cur_speed = clk_get_rate(sdd->src_clk) / 2; >> >> } else { >> >> /* Configure Clock */ >> >> val = readl(regs + S3C64XX_SPI_CLK_CFG); >> >> -- >> >> 2.26.2 >> >> >> > >> > >> >> -- >> Łukasz Stelmach >> Samsung R&D Institute Poland >> Samsung Electronics > > -- Łukasz Stelmach Samsung R&D Institute Poland Samsung Electronics