Skip to content

Commit 51093cb

Browse files
Vladimir Zapolskiybroonie
Vladimir Zapolskiy
authored andcommitted
spi: sh-msiof: Simplify calculation of divisors for transfer rate
The change updates sh_msiof_spi_set_clk_regs() function by iterating over BRDV power values. Note that the change is a functional one, namely prescaler output x 1/1 set in BRDV bit field (0b111) for MSO division rate set to 2 is substituted by BRDV = 0b000 and BRPS = 0b0, in terms of written values to TSCR setting of 0x0107 is substituted by 0x0000, and for all input parameter cases this is the only functional change, which touches the controller. As a result of the rework the function is supposed to be slightly more efficient and more readable and maintainable in case of any further extensions. Signed-off-by: Vladimir Zapolskiy <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 3dbb3ee commit 51093cb

File tree

1 file changed

+35
-32
lines changed

1 file changed

+35
-32
lines changed

drivers/spi/spi-sh-msiof.c

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct sh_msiof_chipdata {
3939
u16 tx_fifo_size;
4040
u16 rx_fifo_size;
4141
u16 master_flags;
42-
u16 min_div;
42+
u16 min_div_pow;
4343
};
4444

4545
struct sh_msiof_spi_priv {
@@ -51,7 +51,7 @@ struct sh_msiof_spi_priv {
5151
struct completion done;
5252
unsigned int tx_fifo_size;
5353
unsigned int rx_fifo_size;
54-
unsigned int min_div;
54+
unsigned int min_div_pow;
5555
void *tx_dma_page;
5656
void *rx_dma_page;
5757
dma_addr_t tx_dma_addr;
@@ -249,43 +249,46 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
249249
return IRQ_HANDLED;
250250
}
251251

252-
static struct {
253-
unsigned short div;
254-
unsigned short brdv;
255-
} const sh_msiof_spi_div_table[] = {
256-
{ 1, SCR_BRDV_DIV_1 },
257-
{ 2, SCR_BRDV_DIV_2 },
258-
{ 4, SCR_BRDV_DIV_4 },
259-
{ 8, SCR_BRDV_DIV_8 },
260-
{ 16, SCR_BRDV_DIV_16 },
261-
{ 32, SCR_BRDV_DIV_32 },
252+
static const u32 sh_msiof_spi_div_array[] = {
253+
SCR_BRDV_DIV_1, SCR_BRDV_DIV_2, SCR_BRDV_DIV_4,
254+
SCR_BRDV_DIV_8, SCR_BRDV_DIV_16, SCR_BRDV_DIV_32,
262255
};
263256

264257
static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
265258
unsigned long parent_rate, u32 spi_hz)
266259
{
267-
unsigned long div = 1024;
260+
unsigned long div;
268261
u32 brps, scr;
269-
size_t k;
262+
unsigned int div_pow = p->min_div_pow;
270263

271-
if (!WARN_ON(!spi_hz || !parent_rate))
272-
div = DIV_ROUND_UP(parent_rate, spi_hz);
273-
274-
div = max_t(unsigned long, div, p->min_div);
264+
if (!spi_hz || !parent_rate) {
265+
WARN(1, "Invalid clock rate parameters %lu and %u\n",
266+
parent_rate, spi_hz);
267+
return;
268+
}
275269

276-
for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) {
277-
brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div);
270+
div = DIV_ROUND_UP(parent_rate, spi_hz);
271+
if (div <= 1024) {
278272
/* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
279-
if (sh_msiof_spi_div_table[k].div == 1 && brps > 2)
280-
continue;
281-
if (brps <= 32) /* max of brdv is 32 */
282-
break;
283-
}
273+
if (!div_pow && div <= 32 && div > 2)
274+
div_pow = 1;
275+
276+
if (div_pow)
277+
brps = (div + 1) >> div_pow;
278+
else
279+
brps = div;
284280

285-
k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_div_table) - 1);
286-
brps = min_t(int, brps, 32);
281+
for (; brps > 32; div_pow++)
282+
brps = (brps + 1) >> 1;
283+
} else {
284+
/* Set transfer rate composite divisor to 2^5 * 32 = 1024 */
285+
dev_err(&p->pdev->dev,
286+
"Requested SPI transfer rate %d is too low\n", spi_hz);
287+
div_pow = 5;
288+
brps = 32;
289+
}
287290

288-
scr = sh_msiof_spi_div_table[k].brdv | SCR_BRPS(brps);
291+
scr = sh_msiof_spi_div_array[div_pow] | SCR_BRPS(brps);
289292
sh_msiof_write(p, TSCR, scr);
290293
if (!(p->master->flags & SPI_MASTER_MUST_TX))
291294
sh_msiof_write(p, RSCR, scr);
@@ -1041,21 +1044,21 @@ static const struct sh_msiof_chipdata sh_data = {
10411044
.tx_fifo_size = 64,
10421045
.rx_fifo_size = 64,
10431046
.master_flags = 0,
1044-
.min_div = 1,
1047+
.min_div_pow = 0,
10451048
};
10461049

10471050
static const struct sh_msiof_chipdata rcar_gen2_data = {
10481051
.tx_fifo_size = 64,
10491052
.rx_fifo_size = 64,
10501053
.master_flags = SPI_MASTER_MUST_TX,
1051-
.min_div = 1,
1054+
.min_div_pow = 0,
10521055
};
10531056

10541057
static const struct sh_msiof_chipdata rcar_gen3_data = {
10551058
.tx_fifo_size = 64,
10561059
.rx_fifo_size = 64,
10571060
.master_flags = SPI_MASTER_MUST_TX,
1058-
.min_div = 2,
1061+
.min_div_pow = 1,
10591062
};
10601063

10611064
static const struct of_device_id sh_msiof_match[] = {
@@ -1319,7 +1322,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
13191322
platform_set_drvdata(pdev, p);
13201323
p->master = master;
13211324
p->info = info;
1322-
p->min_div = chipdata->min_div;
1325+
p->min_div_pow = chipdata->min_div_pow;
13231326

13241327
init_completion(&p->done);
13251328

0 commit comments

Comments
 (0)