Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mtd: spinand: Add support for packed read data ODTR commands

Some devices stuff address bits in the double byte opcode (in place of
the repeated byte) in order to be able to increase the size of the
devices, without adding extra address bytes.

Create a flag to identify those devices. When the flag is set, use the
"packed" variant for the read data operation.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

+28 -3
+21 -3
drivers/mtd/nand/spi/core.c
··· 100 100 return op; 101 101 } 102 102 103 + static struct spi_mem_op 104 + spinand_fill_page_read_packed_op(struct spinand_device *spinand, u64 addr) 105 + { 106 + struct spi_mem_op op = spinand->op_templates->page_read; 107 + 108 + op.cmd.opcode |= addr >> 16; 109 + op.addr.val = addr & 0xFFFF; 110 + 111 + return op; 112 + } 113 + 103 114 struct spi_mem_op 104 115 spinand_fill_prog_exec_op(struct spinand_device *spinand, u64 addr) 105 116 { ··· 464 453 { 465 454 struct nand_device *nand = spinand_to_nand(spinand); 466 455 unsigned int row = nanddev_pos_to_row(nand, &req->pos); 467 - struct spi_mem_op op = SPINAND_OP(spinand, page_read, row); 456 + bool packed = spinand->flags & SPINAND_ODTR_PACKED_PAGE_READ; 457 + struct spi_mem_op op = packed ? 458 + SPINAND_OP(spinand, page_read_packed, row) : 459 + SPINAND_OP(spinand, page_read, row); 468 460 469 461 return spi_mem_exec_op(spinand->spimem, &op); 470 462 } ··· 1503 1489 if (!spi_mem_supports_op(spinand->spimem, &tmpl->blk_erase)) 1504 1490 return -EOPNOTSUPP; 1505 1491 1506 - tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_8D_8D_0_OP(0); 1507 - if (!spi_mem_supports_op(spinand->spimem, &tmpl->page_read)) 1492 + if (spinand->flags & SPINAND_ODTR_PACKED_PAGE_READ) 1493 + tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_PACKED_8D_8D_0_OP(0); 1494 + else 1495 + tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_8D_8D_0_OP(0); 1496 + if (!spi_mem_supports_op(spinand->spimem, &tmpl->page_read)) { 1508 1497 return -EOPNOTSUPP; 1498 + } 1509 1499 1510 1500 tmpl->prog_exec = (struct spi_mem_op)SPINAND_PROG_EXEC_8D_8D_0_OP(0); 1511 1501 if (!spi_mem_supports_op(spinand->spimem, &tmpl->prog_exec))
+7
include/linux/mtd/spinand.h
··· 290 290 SPI_MEM_OP_NO_DUMMY, \ 291 291 SPI_MEM_OP_NO_DATA) 292 292 293 + #define SPINAND_PAGE_READ_PACKED_8D_8D_0_OP(addr) \ 294 + SPI_MEM_OP(SPI_MEM_DTR_OP_PACKED_CMD(0x13, addr >> 16, 8), \ 295 + SPI_MEM_DTR_OP_ADDR(2, addr & 0xffff, 8), \ 296 + SPI_MEM_OP_NO_DUMMY, \ 297 + SPI_MEM_OP_NO_DATA) 298 + 293 299 #define SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(addr, ndummy, buf, len, freq) \ 294 300 SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x9d, 8), \ 295 301 SPI_MEM_DTR_OP_ADDR(2, addr, 8), \ ··· 489 483 #define SPINAND_HAS_PROG_PLANE_SELECT_BIT BIT(2) 490 484 #define SPINAND_HAS_READ_PLANE_SELECT_BIT BIT(3) 491 485 #define SPINAND_NO_RAW_ACCESS BIT(4) 486 + #define SPINAND_ODTR_PACKED_PAGE_READ BIT(5) 492 487 493 488 /** 494 489 * struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure