Skip to content

Commit

Permalink
spi: rspi: Use requested instead of maximum bit rate
Browse files Browse the repository at this point in the history
Currently, the RSPI driver always tries to use the maximum configured
bit rate for communicating with a slave device, even if the transfer(s)
in the current message specify a lower rate.

Use the mininum rate specified in the message instead.
Rename rspi_data.max_speed_hz accordingly.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20200608095940.30516-3-geert+renesas@glider.be
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Geert Uytterhoeven authored and Mark Brown committed Jun 9, 2020
1 parent 9ec8ade commit e0fe700
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions drivers/spi/spi-rspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@

struct rspi_data {
void __iomem *addr;
u32 max_speed_hz;
u32 speed_hz;
struct spi_controller *ctlr;
struct platform_device *pdev;
wait_queue_head_t wait;
Expand Down Expand Up @@ -258,8 +258,7 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);

/* Sets transfer bit rate */
spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk),
2 * rspi->max_speed_hz) - 1;
spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), 2 * rspi->speed_hz) - 1;
rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);

/* Disable dummy transmission, set 16-bit word access, 1 frame */
Expand Down Expand Up @@ -299,14 +298,14 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)

clksrc = clk_get_rate(rspi->clk);
while (div < 3) {
if (rspi->max_speed_hz >= clksrc/4) /* 4=(CLK/2)/2 */
if (rspi->speed_hz >= clksrc/4) /* 4=(CLK/2)/2 */
break;
div++;
clksrc /= 2;
}

/* Sets transfer bit rate */
spbr = DIV_ROUND_UP(clksrc, 2 * rspi->max_speed_hz) - 1;
spbr = DIV_ROUND_UP(clksrc, 2 * rspi->speed_hz) - 1;
rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
rspi->spcmd |= div << 2;

Expand Down Expand Up @@ -341,7 +340,7 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);

/* Sets transfer bit rate */
spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), 2 * rspi->max_speed_hz);
spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), 2 * rspi->speed_hz);
rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);

/* Disable dummy transmission, set byte access */
Expand Down Expand Up @@ -949,9 +948,24 @@ static int rspi_prepare_message(struct spi_controller *ctlr,
{
struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
struct spi_device *spi = msg->spi;
const struct spi_transfer *xfer;
int ret;

rspi->max_speed_hz = spi->max_speed_hz;
/*
* As the Bit Rate Register must not be changed while the device is
* active, all transfers in a message must use the same bit rate.
* In theory, the sequencer could be enabled, and each Command Register
* could divide the base bit rate by a different value.
* However, most RSPI variants do not have Transfer Data Length
* Multiplier Setting Registers, so each sequence step would be limited
* to a single word, making this feature unsuitable for large
* transfers, which would gain most from it.
*/
rspi->speed_hz = spi->max_speed_hz;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (xfer->speed_hz < rspi->speed_hz)
rspi->speed_hz = xfer->speed_hz;
}

rspi->spcmd = SPCMD_SSLKP;
if (spi->mode & SPI_CPOL)
Expand Down

0 comments on commit e0fe700

Please sign in to comment.