From a15853d32aa67c1a855d7949040a414f3c117258 Mon Sep 17 00:00:00 2001 From: Ashish Kori Date: Thu, 12 Nov 2020 17:32:19 +0530 Subject: [PATCH] spi: spi-msm-geni: Configure DFS index and clk before doing set rate Currently we set rate before configure SPI DFS clk. Configure DFS clk before doing set rate to SE clk. This will allow us to enable correct parrent clk. Change-Id: Ifa193bce28937ed363eadeb1bdc2e4bcbacb210b Signed-off-by: Ashish Kori --- drivers/spi/spi-msm-geni.c | 39 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 632c493d19de..50bc8bbd22ee 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -239,6 +239,23 @@ static struct spi_master *get_spi_master(struct device *dev) return spi; } +static inline void spi_geni_clk_conf(struct spi_geni_master *mas, + int clk_div, int clk_idx) +{ + u32 clk_sel = 0; + u32 m_clk_cfg = 0; + + clk_sel |= (clk_idx & CLK_SEL_MSK); + m_clk_cfg |= ((clk_div << CLK_DIV_SHFT) | SER_CLK_EN); + geni_write_reg(clk_sel, mas->base, SE_GENI_CLK_SEL); + geni_write_reg(m_clk_cfg, mas->base, GENI_SER_M_CLK_CFG); + + /* + * Ensure Clk config completes before return. + */ + mb(); +} + static int get_spi_clk_cfg(u32 speed_hz, struct spi_geni_master *mas, int *clk_idx, int *clk_div) { @@ -269,6 +286,8 @@ static int get_spi_clk_cfg(u32 speed_hz, struct spi_geni_master *mas, dev_dbg(mas->dev, "%s: req %u resultant %lu sclk %lu, idx %d, div %d\n", __func__, speed_hz, res_freq, sclk_freq, *clk_idx, *clk_div); + spi_geni_clk_conf(mas, *clk_div, *clk_idx); + ret = clk_set_rate(rsc->se_clk, sclk_freq); if (ret) { dev_err(mas->dev, "%s: clk_set_rate failed %d\n", @@ -323,8 +342,6 @@ static int setup_fifo_params(struct spi_device *spi_slv, u32 cpha = geni_read_reg(mas->base, SE_SPI_CPHA); u32 demux_sel = 0; u32 demux_output_inv = 0; - u32 clk_sel = 0; - u32 m_clk_cfg = 0; int ret = 0; int idx; int div; @@ -384,23 +401,19 @@ static int setup_fifo_params(struct spi_device *spi_slv, goto setup_fifo_params_exit; } - clk_sel |= (idx & CLK_SEL_MSK); - m_clk_cfg |= ((div << CLK_DIV_SHFT) | SER_CLK_EN); spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word); geni_write_reg(loopback_cfg, mas->base, SE_SPI_LOOPBACK); geni_write_reg(demux_sel, mas->base, SE_SPI_DEMUX_SEL); geni_write_reg(cpha, mas->base, SE_SPI_CPHA); geni_write_reg(cpol, mas->base, SE_SPI_CPOL); geni_write_reg(demux_output_inv, mas->base, SE_SPI_DEMUX_OUTPUT_INV); - geni_write_reg(clk_sel, mas->base, SE_GENI_CLK_SEL); - geni_write_reg(m_clk_cfg, mas->base, GENI_SER_M_CLK_CFG); geni_write_reg(spi_delay_params, mas->base, SE_SPI_DELAY_COUNTERS); GENI_SE_DBG(mas->ipc, false, mas->dev, - "%s:Loopback%d demux_sel0x%x demux_op_inv 0x%x clk_cfg 0x%x\n", - __func__, loopback_cfg, demux_sel, demux_output_inv, m_clk_cfg); + "%s:Loopback%d demux_sel0x%x demux_op_inv 0x%x\n", + __func__, loopback_cfg, demux_sel, demux_output_inv); GENI_SE_DBG(mas->ipc, false, mas->dev, - "%s:clk_sel 0x%x cpol %d cpha %d delay 0x%x\n", __func__, - clk_sel, cpol, cpha, spi_delay_params); + "%s:cpol %d cpha %d delay 0x%x\n", __func__, + cpol, cpha, spi_delay_params); /* Ensure message level attributes are written before returning */ mb(); setup_fifo_params_exit: @@ -1388,8 +1401,6 @@ static int setup_fifo_xfer(struct spi_transfer *xfer, /* Speed and bits per word can be overridden per transfer */ if (xfer->speed_hz != mas->cur_speed_hz) { - u32 clk_sel = 0; - u32 m_clk_cfg = 0; int idx = 0; int div = 0; @@ -1400,10 +1411,6 @@ static int setup_fifo_xfer(struct spi_transfer *xfer, return ret; } mas->cur_speed_hz = xfer->speed_hz; - clk_sel |= (idx & CLK_SEL_MSK); - m_clk_cfg |= ((div << CLK_DIV_SHFT) | SER_CLK_EN); - geni_write_reg(clk_sel, mas->base, SE_GENI_CLK_SEL); - geni_write_reg(m_clk_cfg, mas->base, GENI_SER_M_CLK_CFG); } mas->tx_rem_bytes = 0;