Skip to content

Commit 89b37e4

Browse files
committed
spi-nand/spi-mem DTR support
Merge series from Miquel Raynal <miquel.raynal@bootlin.com>: Here is a (big) series supposed to bring DTR support in SPI-NAND.
2 parents 5e56618 + f000689 commit 89b37e4

17 files changed

+204
-40
lines changed

drivers/mtd/nand/spi/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,8 @@ spinand_select_op_variant(struct spinand_device *spinand,
12141214
if (ret)
12151215
break;
12161216

1217+
spi_mem_adjust_op_freq(spinand->spimem, &op);
1218+
12171219
if (!spi_mem_supports_op(spinand->spimem, &op))
12181220
break;
12191221

drivers/spi/spi-amd.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -298,19 +298,16 @@ static const struct amd_spi_freq amd_spi_freq[] = {
298298
{ AMD_SPI_MIN_HZ, F_800KHz, 0},
299299
};
300300

301-
static int amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
301+
static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
302302
{
303303
unsigned int i, spd7_val, alt_spd;
304304

305-
if (speed_hz < AMD_SPI_MIN_HZ)
306-
return -EINVAL;
307-
308305
for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
309306
if (speed_hz >= amd_spi_freq[i].speed_hz)
310307
break;
311308

312309
if (amd_spi->speed_hz == amd_spi_freq[i].speed_hz)
313-
return 0;
310+
return;
314311

315312
amd_spi->speed_hz = amd_spi_freq[i].speed_hz;
316313

@@ -329,8 +326,6 @@ static int amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
329326
amd_spi_setclear_reg32(amd_spi, AMD_SPI_SPEED_REG, spd7_val,
330327
AMD_SPI_SPD7_MASK);
331328
}
332-
333-
return 0;
334329
}
335330

336331
static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
@@ -479,6 +474,9 @@ static bool amd_spi_supports_op(struct spi_mem *mem,
479474
return false;
480475
}
481476

477+
if (op->max_freq < mem->spi->controller->min_speed_hz)
478+
return false;
479+
482480
return spi_mem_default_supports_op(mem, op);
483481
}
484482

@@ -676,9 +674,7 @@ static int amd_spi_exec_mem_op(struct spi_mem *mem,
676674

677675
amd_spi = spi_controller_get_devdata(mem->spi->controller);
678676

679-
ret = amd_set_spi_freq(amd_spi, mem->spi->max_speed_hz);
680-
if (ret)
681-
return ret;
677+
amd_set_spi_freq(amd_spi, op->max_freq);
682678

683679
if (amd_spi->version == AMD_SPI_V2)
684680
amd_set_spi_addr_mode(amd_spi, op);
@@ -705,6 +701,10 @@ static const struct spi_controller_mem_ops amd_spi_mem_ops = {
705701
.supports_op = amd_spi_supports_op,
706702
};
707703

704+
static const struct spi_controller_mem_caps amd_spi_mem_caps = {
705+
.per_op_freq = true,
706+
};
707+
708708
static int amd_spi_host_transfer(struct spi_controller *host,
709709
struct spi_message *msg)
710710
{
@@ -782,6 +782,7 @@ static int amd_spi_probe(struct platform_device *pdev)
782782
host->setup = amd_spi_host_setup;
783783
host->transfer_one_message = amd_spi_host_transfer;
784784
host->mem_ops = &amd_spi_mem_ops;
785+
host->mem_caps = &amd_spi_mem_caps;
785786
host->max_transfer_size = amd_spi_max_transfer_size;
786787
host->max_message_size = amd_spi_max_transfer_size;
787788

drivers/spi/spi-amlogic-spifc-a1.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static int amlogic_spifc_a1_exec_op(struct spi_mem *mem,
259259
size_t data_size = op->data.nbytes;
260260
int ret;
261261

262-
ret = amlogic_spifc_a1_set_freq(spifc, mem->spi->max_speed_hz);
262+
ret = amlogic_spifc_a1_set_freq(spifc, op->max_freq);
263263
if (ret)
264264
return ret;
265265

@@ -320,6 +320,10 @@ static const struct spi_controller_mem_ops amlogic_spifc_a1_mem_ops = {
320320
.adjust_op_size = amlogic_spifc_a1_adjust_op_size,
321321
};
322322

323+
static const struct spi_controller_mem_caps amlogic_spifc_a1_mem_caps = {
324+
.per_op_freq = true,
325+
};
326+
323327
static int amlogic_spifc_a1_probe(struct platform_device *pdev)
324328
{
325329
struct spi_controller *ctrl;
@@ -356,6 +360,7 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
356360
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
357361
ctrl->auto_runtime_pm = true;
358362
ctrl->mem_ops = &amlogic_spifc_a1_mem_ops;
363+
ctrl->mem_caps = &amlogic_spifc_a1_mem_caps;
359364
ctrl->min_speed_hz = SPIFC_A1_MIN_HZ;
360365
ctrl->max_speed_hz = SPIFC_A1_MAX_HZ;
361366
ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL |

drivers/spi/spi-cadence-quadspi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
14331433
struct cqspi_flash_pdata *f_pdata;
14341434

14351435
f_pdata = &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)];
1436-
cqspi_configure(f_pdata, mem->spi->max_speed_hz);
1436+
cqspi_configure(f_pdata, op->max_freq);
14371437

14381438
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
14391439
/*
@@ -1682,6 +1682,7 @@ static const struct spi_controller_mem_ops cqspi_mem_ops = {
16821682

16831683
static const struct spi_controller_mem_caps cqspi_mem_caps = {
16841684
.dtr = true,
1685+
.per_op_freq = true,
16851686
};
16861687

16871688
static int cqspi_setup_flash(struct cqspi_st *cqspi)

drivers/spi/spi-dw-core.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
677677
* operation. Transmit-only mode is suitable for the rest of them.
678678
*/
679679
cfg.dfs = 8;
680-
cfg.freq = clamp(mem->spi->max_speed_hz, 0U, dws->max_mem_freq);
680+
cfg.freq = clamp(op->max_freq, 0U, dws->max_mem_freq);
681681
if (op->data.dir == SPI_MEM_DATA_IN) {
682682
cfg.tmode = DW_SPI_CTRLR0_TMOD_EPROMREAD;
683683
cfg.ndf = op->data.nbytes;
@@ -894,6 +894,10 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws)
894894
dw_writel(dws, DW_SPI_CS_OVERRIDE, 0xF);
895895
}
896896

897+
static const struct spi_controller_mem_caps dw_spi_mem_caps = {
898+
.per_op_freq = true,
899+
};
900+
897901
int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
898902
{
899903
struct spi_controller *host;
@@ -941,8 +945,10 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
941945
host->set_cs = dw_spi_set_cs;
942946
host->transfer_one = dw_spi_transfer_one;
943947
host->handle_err = dw_spi_handle_err;
944-
if (dws->mem_ops.exec_op)
948+
if (dws->mem_ops.exec_op) {
945949
host->mem_ops = &dws->mem_ops;
950+
host->mem_caps = &dw_spi_mem_caps;
951+
}
946952
host->max_speed_hz = dws->max_freq;
947953
host->flags = SPI_CONTROLLER_GPIO_SS;
948954
host->auto_runtime_pm = true;

drivers/spi/spi-fsl-qspi.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,10 @@ static void fsl_qspi_invalidate(struct fsl_qspi *q)
522522
qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
523523
}
524524

525-
static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi)
525+
static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi,
526+
const struct spi_mem_op *op)
526527
{
527-
unsigned long rate = spi->max_speed_hz;
528+
unsigned long rate = op->max_freq;
528529
int ret;
529530

530531
if (q->selected == spi_get_chipselect(spi, 0))
@@ -652,7 +653,7 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
652653
fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK |
653654
QUADSPI_SR_AHB_ACC_MASK), 10, 1000);
654655

655-
fsl_qspi_select_mem(q, mem->spi);
656+
fsl_qspi_select_mem(q, mem->spi, op);
656657

657658
if (needs_amba_base_offset(q))
658659
addr_offset = q->memmap_phy;
@@ -839,6 +840,10 @@ static const struct spi_controller_mem_ops fsl_qspi_mem_ops = {
839840
.get_name = fsl_qspi_get_name,
840841
};
841842

843+
static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
844+
.per_op_freq = true,
845+
};
846+
842847
static int fsl_qspi_probe(struct platform_device *pdev)
843848
{
844849
struct spi_controller *ctlr;
@@ -923,6 +928,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
923928
ctlr->bus_num = -1;
924929
ctlr->num_chipselect = 4;
925930
ctlr->mem_ops = &fsl_qspi_mem_ops;
931+
ctlr->mem_caps = &fsl_qspi_mem_caps;
926932

927933
fsl_qspi_default_setup(q);
928934

drivers/spi/spi-mem.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,16 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
187187
return false;
188188
}
189189

190+
if (op->max_freq && mem->spi->controller->min_speed_hz &&
191+
op->max_freq < mem->spi->controller->min_speed_hz)
192+
return false;
193+
194+
if (op->max_freq &&
195+
op->max_freq < mem->spi->max_speed_hz) {
196+
if (!spi_mem_controller_is_capable(ctlr, per_op_freq))
197+
return false;
198+
}
199+
190200
return spi_mem_check_buswidth(mem, op);
191201
}
192202
EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
@@ -364,6 +374,9 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
364374
u8 *tmpbuf;
365375
int ret;
366376

377+
/* Make sure the operation frequency is correct before going futher */
378+
spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op);
379+
367380
ret = spi_mem_check_op(op);
368381
if (ret)
369382
return ret;
@@ -410,6 +423,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
410423
xfers[xferpos].tx_buf = tmpbuf;
411424
xfers[xferpos].len = op->cmd.nbytes;
412425
xfers[xferpos].tx_nbits = op->cmd.buswidth;
426+
xfers[xferpos].speed_hz = op->max_freq;
413427
spi_message_add_tail(&xfers[xferpos], &msg);
414428
xferpos++;
415429
totalxferlen++;
@@ -424,6 +438,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
424438
xfers[xferpos].tx_buf = tmpbuf + 1;
425439
xfers[xferpos].len = op->addr.nbytes;
426440
xfers[xferpos].tx_nbits = op->addr.buswidth;
441+
xfers[xferpos].speed_hz = op->max_freq;
427442
spi_message_add_tail(&xfers[xferpos], &msg);
428443
xferpos++;
429444
totalxferlen += op->addr.nbytes;
@@ -435,6 +450,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
435450
xfers[xferpos].len = op->dummy.nbytes;
436451
xfers[xferpos].tx_nbits = op->dummy.buswidth;
437452
xfers[xferpos].dummy_data = 1;
453+
xfers[xferpos].speed_hz = op->max_freq;
438454
spi_message_add_tail(&xfers[xferpos], &msg);
439455
xferpos++;
440456
totalxferlen += op->dummy.nbytes;
@@ -450,6 +466,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
450466
}
451467

452468
xfers[xferpos].len = op->data.nbytes;
469+
xfers[xferpos].speed_hz = op->max_freq;
453470
spi_message_add_tail(&xfers[xferpos], &msg);
454471
xferpos++;
455472
totalxferlen += op->data.nbytes;
@@ -528,6 +545,23 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
528545
}
529546
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
530547

548+
/**
549+
* spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation to
550+
* match controller, PCB and chip limitations
551+
* @mem: the SPI memory
552+
* @op: the operation to adjust
553+
*
554+
* Some chips have per-op frequency limitations and must adapt the maximum
555+
* speed. This function allows SPI mem drivers to set @op->max_freq to the
556+
* maximum supported value.
557+
*/
558+
void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op)
559+
{
560+
if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz)
561+
op->max_freq = mem->spi->max_speed_hz;
562+
}
563+
EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
564+
531565
static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
532566
u64 offs, size_t len, void *buf)
533567
{

drivers/spi/spi-microchip-core-qspi.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ static irqreturn_t mchp_coreqspi_isr(int irq, void *dev_id)
265265
return ret;
266266
}
267267

268-
static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_device *spi)
268+
static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_device *spi,
269+
const struct spi_mem_op *op)
269270
{
270271
unsigned long clk_hz;
271272
u32 control, baud_rate_val = 0;
@@ -274,11 +275,11 @@ static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_devi
274275
if (!clk_hz)
275276
return -EINVAL;
276277

277-
baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * spi->max_speed_hz);
278+
baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq);
278279
if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER) {
279280
dev_err(&spi->dev,
280281
"could not configure the clock for spi clock %d Hz & system clock %ld Hz\n",
281-
spi->max_speed_hz, clk_hz);
282+
op->max_freq, clk_hz);
282283
return -EINVAL;
283284
}
284285

@@ -399,7 +400,7 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o
399400
if (err)
400401
goto error;
401402

402-
err = mchp_coreqspi_setup_clock(qspi, mem->spi);
403+
err = mchp_coreqspi_setup_clock(qspi, mem->spi, op);
403404
if (err)
404405
goto error;
405406

@@ -457,6 +458,10 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o
457458

458459
static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
459460
{
461+
struct mchp_coreqspi *qspi = spi_controller_get_devdata(mem->spi->controller);
462+
unsigned long clk_hz;
463+
u32 baud_rate_val;
464+
460465
if (!spi_mem_default_supports_op(mem, op))
461466
return false;
462467

@@ -479,6 +484,14 @@ static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_
479484
return false;
480485
}
481486

487+
clk_hz = clk_get_rate(qspi->clk);
488+
if (!clk_hz)
489+
return false;
490+
491+
baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq);
492+
if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER)
493+
return false;
494+
482495
return true;
483496
}
484497

@@ -498,6 +511,10 @@ static const struct spi_controller_mem_ops mchp_coreqspi_mem_ops = {
498511
.exec_op = mchp_coreqspi_exec_op,
499512
};
500513

514+
static const struct spi_controller_mem_caps mchp_coreqspi_mem_caps = {
515+
.per_op_freq = true,
516+
};
517+
501518
static int mchp_coreqspi_probe(struct platform_device *pdev)
502519
{
503520
struct spi_controller *ctlr;
@@ -540,6 +557,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
540557

541558
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
542559
ctlr->mem_ops = &mchp_coreqspi_mem_ops;
560+
ctlr->mem_caps = &mchp_coreqspi_mem_caps;
543561
ctlr->setup = mchp_coreqspi_setup_op;
544562
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
545563
SPI_TX_DUAL | SPI_TX_QUAD;

drivers/spi/spi-mt65xx.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
961961

962962
mtk_spi_reset(mdata);
963963
mtk_spi_hw_init(mem->spi->controller, mem->spi);
964-
mtk_spi_prepare_transfer(mem->spi->controller, mem->spi->max_speed_hz);
964+
mtk_spi_prepare_transfer(mem->spi->controller, op->max_freq);
965965

966966
reg_val = readl(mdata->base + SPI_CFG3_IPM_REG);
967967
/* opcode byte len */
@@ -1122,6 +1122,10 @@ static const struct spi_controller_mem_ops mtk_spi_mem_ops = {
11221122
.exec_op = mtk_spi_mem_exec_op,
11231123
};
11241124

1125+
static const struct spi_controller_mem_caps mtk_spi_mem_caps = {
1126+
.per_op_freq = true,
1127+
};
1128+
11251129
static int mtk_spi_probe(struct platform_device *pdev)
11261130
{
11271131
struct device *dev = &pdev->dev;
@@ -1160,6 +1164,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
11601164
if (mdata->dev_comp->ipm_design) {
11611165
mdata->dev = dev;
11621166
host->mem_ops = &mtk_spi_mem_ops;
1167+
host->mem_caps = &mtk_spi_mem_caps;
11631168
init_completion(&mdata->spimem_done);
11641169
}
11651170

0 commit comments

Comments
 (0)