Skip to content

Commit d8860f1

Browse files
tq-schiffermgregkh
authored andcommitted
spi: cadence-quadspi: fix protocol setup for non-1-1-X operations
[ Upstream commit 97e4827 ] cqspi_set_protocol() only set the data width, but ignored the command and address width (except for 8-8-8 DTR ops), leading to corruption of all transfers using 1-X-X or X-X-X ops. Fix by setting the other two widths as well. While we're at it, simplify the code a bit by replacing the CQSPI_INST_TYPE_* constants with ilog2(). Tested on a TI AM64x with a Macronix MX25U51245G QSPI flash with 1-4-4 read and write operations. Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com> Link: https://lore.kernel.org/r/20220331110819.133392-1-matthias.schiffer@ew.tq-group.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 6d48df7 commit d8860f1

File tree

1 file changed

+12
-34
lines changed

1 file changed

+12
-34
lines changed

drivers/spi/spi-cadence-quadspi.c

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/iopoll.h>
1919
#include <linux/jiffies.h>
2020
#include <linux/kernel.h>
21+
#include <linux/log2.h>
2122
#include <linux/module.h>
2223
#include <linux/of_device.h>
2324
#include <linux/of.h>
@@ -93,12 +94,6 @@ struct cqspi_driver_platdata {
9394
#define CQSPI_TIMEOUT_MS 500
9495
#define CQSPI_READ_TIMEOUT_MS 10
9596

96-
/* Instruction type */
97-
#define CQSPI_INST_TYPE_SINGLE 0
98-
#define CQSPI_INST_TYPE_DUAL 1
99-
#define CQSPI_INST_TYPE_QUAD 2
100-
#define CQSPI_INST_TYPE_OCTAL 3
101-
10297
#define CQSPI_DUMMY_CLKS_PER_BYTE 8
10398
#define CQSPI_DUMMY_BYTES_MAX 4
10499
#define CQSPI_DUMMY_CLKS_MAX 31
@@ -322,10 +317,6 @@ static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op, bool dtr)
322317
static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
323318
const struct spi_mem_op *op)
324319
{
325-
f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
326-
f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
327-
f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
328-
329320
/*
330321
* For an op to be DTR, cmd phase along with every other non-empty
331322
* phase should have dtr field set to 1. If an op phase has zero
@@ -335,52 +326,39 @@ static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
335326
(!op->addr.nbytes || op->addr.dtr) &&
336327
(!op->data.nbytes || op->data.dtr);
337328

338-
switch (op->data.buswidth) {
339-
case 0:
340-
break;
341-
case 1:
342-
f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
343-
break;
344-
case 2:
345-
f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
346-
break;
347-
case 4:
348-
f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
349-
break;
350-
case 8:
351-
f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
352-
break;
353-
default:
354-
return -EINVAL;
355-
}
329+
f_pdata->inst_width = 0;
330+
if (op->cmd.buswidth)
331+
f_pdata->inst_width = ilog2(op->cmd.buswidth);
332+
333+
f_pdata->addr_width = 0;
334+
if (op->addr.buswidth)
335+
f_pdata->addr_width = ilog2(op->addr.buswidth);
336+
337+
f_pdata->data_width = 0;
338+
if (op->data.buswidth)
339+
f_pdata->data_width = ilog2(op->data.buswidth);
356340

357341
/* Right now we only support 8-8-8 DTR mode. */
358342
if (f_pdata->dtr) {
359343
switch (op->cmd.buswidth) {
360344
case 0:
361-
break;
362345
case 8:
363-
f_pdata->inst_width = CQSPI_INST_TYPE_OCTAL;
364346
break;
365347
default:
366348
return -EINVAL;
367349
}
368350

369351
switch (op->addr.buswidth) {
370352
case 0:
371-
break;
372353
case 8:
373-
f_pdata->addr_width = CQSPI_INST_TYPE_OCTAL;
374354
break;
375355
default:
376356
return -EINVAL;
377357
}
378358

379359
switch (op->data.buswidth) {
380360
case 0:
381-
break;
382361
case 8:
383-
f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
384362
break;
385363
default:
386364
return -EINVAL;

0 commit comments

Comments
 (0)