Skip to content

Commit 6c01ae1

Browse files
Kuwano-sanambarus
authored andcommitted
mtd: spi-nor: spansion: Rework cypress_nor_get_page_size() for multi-chip device support
For multi-chip devices, we can use 512B page only when the all dice are configured as 512B page size. The volatile register address is calculated by using the volatile register addresses retrieved from the SCCR tables and the (configuration) register offset. The location of cypress_nor_set_page_size() call is moved from post_bfpt_fixup() to post_sfdp_fixup(), because the number of dice and volatile register offset are parsed in the optional SCCR tables. Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com> Link: https://lore.kernel.org/r/6f8272f3e877dee392742d2c8401c4aed57e6d83.1680849425.git.Takahiro.Kuwano@infineon.com Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
1 parent 7ab8b81 commit 6c01ae1

1 file changed

Lines changed: 69 additions & 20 deletions

File tree

drivers/mtd/spi-nor/spansion.c

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,26 @@
1414
#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
1515
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
1616
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
17-
#define SPINOR_REG_CYPRESS_STR1V 0x00800000
18-
#define SPINOR_REG_CYPRESS_CFR1V 0x00800002
17+
#define SPINOR_REG_CYPRESS_VREG 0x00800000
18+
#define SPINOR_REG_CYPRESS_STR1 0x0
19+
#define SPINOR_REG_CYPRESS_STR1V \
20+
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
21+
#define SPINOR_REG_CYPRESS_CFR1 0x2
22+
#define SPINOR_REG_CYPRESS_CFR1V \
23+
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR1)
1924
#define SPINOR_REG_CYPRESS_CFR1_QUAD_EN BIT(1) /* Quad Enable */
20-
#define SPINOR_REG_CYPRESS_CFR2V 0x00800003
25+
#define SPINOR_REG_CYPRESS_CFR2 0x3
26+
#define SPINOR_REG_CYPRESS_CFR2V \
27+
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
2128
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
2229
#define SPINOR_REG_CYPRESS_CFR2_ADRBYT BIT(7)
23-
#define SPINOR_REG_CYPRESS_CFR3V 0x00800004
30+
#define SPINOR_REG_CYPRESS_CFR3 0x4
31+
#define SPINOR_REG_CYPRESS_CFR3V \
32+
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR3)
2433
#define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
25-
#define SPINOR_REG_CYPRESS_CFR5V 0x00800006
34+
#define SPINOR_REG_CYPRESS_CFR5 0x6
35+
#define SPINOR_REG_CYPRESS_CFR5V \
36+
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR5)
2637
#define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
2738
#define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
2839
#define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
@@ -301,17 +312,7 @@ static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
301312
return 0;
302313
}
303314

304-
/**
305-
* cypress_nor_get_page_size() - Get flash page size configuration.
306-
* @nor: pointer to a 'struct spi_nor'
307-
*
308-
* The BFPT table advertises a 512B or 256B page size depending on part but the
309-
* page size is actually configurable (with the default being 256B). Read from
310-
* CFR3V[4] and set the correct size.
311-
*
312-
* Return: 0 on success, -errno otherwise.
313-
*/
314-
static int cypress_nor_get_page_size(struct spi_nor *nor)
315+
static int cypress_nor_get_page_size_single_chip(struct spi_nor *nor)
315316
{
316317
struct spi_mem_op op =
317318
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
@@ -331,6 +332,54 @@ static int cypress_nor_get_page_size(struct spi_nor *nor)
331332
return 0;
332333
}
333334

335+
336+
static int cypress_nor_get_page_size_mcp(struct spi_nor *nor)
337+
{
338+
struct spi_mem_op op =
339+
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
340+
0, 0, nor->bouncebuf);
341+
struct spi_nor_flash_parameter *params = nor->params;
342+
int ret;
343+
u8 i;
344+
345+
/*
346+
* Use the minimum common page size configuration. Programming 256-byte
347+
* under 512-byte page size configuration is safe.
348+
*/
349+
params->page_size = 256;
350+
for (i = 0; i < params->n_dice; i++) {
351+
op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
352+
353+
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
354+
if (ret)
355+
return ret;
356+
357+
if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
358+
return 0;
359+
}
360+
361+
params->page_size = 512;
362+
363+
return 0;
364+
}
365+
366+
/**
367+
* cypress_nor_get_page_size() - Get flash page size configuration.
368+
* @nor: pointer to a 'struct spi_nor'
369+
*
370+
* The BFPT table advertises a 512B or 256B page size depending on part but the
371+
* page size is actually configurable (with the default being 256B). Read from
372+
* CFR3V[4] and set the correct size.
373+
*
374+
* Return: 0 on success, -errno otherwise.
375+
*/
376+
static int cypress_nor_get_page_size(struct spi_nor *nor)
377+
{
378+
if (nor->params->n_dice)
379+
return cypress_nor_get_page_size_mcp(nor);
380+
return cypress_nor_get_page_size_single_chip(nor);
381+
}
382+
334383
static void cypress_nor_ecc_init(struct spi_nor *nor)
335384
{
336385
/*
@@ -408,7 +457,7 @@ s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
408457
/* Replace Quad Enable with volatile version */
409458
nor->params->quad_enable = cypress_nor_quad_enable_volatile;
410459

411-
return cypress_nor_get_page_size(nor);
460+
return 0;
412461
}
413462

414463
static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
@@ -434,7 +483,7 @@ static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
434483
}
435484
}
436485

437-
return 0;
486+
return cypress_nor_get_page_size(nor);
438487
}
439488

440489
static void s25hx_t_late_init(struct spi_nor *nor)
@@ -494,7 +543,7 @@ static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
494543
*/
495544
nor->params->rdsr_addr_nbytes = 4;
496545

497-
return 0;
546+
return cypress_nor_get_page_size(nor);
498547
}
499548

500549
static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
@@ -507,7 +556,7 @@ static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
507556
if (ret)
508557
return ret;
509558

510-
return cypress_nor_get_page_size(nor);
559+
return 0;
511560
}
512561

513562
static void s28hx_t_late_init(struct spi_nor *nor)

0 commit comments

Comments
 (0)