diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index cb7f77eb61f9..b5886af2dbe9 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -240,6 +240,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) { @@ -270,6 +287,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", @@ -324,8 +343,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; @@ -385,23 +402,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: @@ -1389,8 +1402,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; @@ -1401,10 +1412,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;