Skip to content

Commit 4cce023

Browse files
Amit Kumar Mahapatramichalsimek
authored andcommitted
mtd: spi-nor: Fix RX tuning failure for OSPI flashes connected in stacked mode
RX tuning failure was observed when two OSPI flashes connected in stacked were operating in DDR mode. In 'commit e246f0d ("mtd: spi-nor: Add stacked mode support for OSPI flash parts")' for stacked mode the RX tuning will get triggered only for one flash i.e., when the upper flash is set to OCTAL DDR mode, the RX truing is not triggered for the lower flash. The current implementation doesn't set the upper flash to DDR, it only sets the lower flash to DRR mode, as a result the RX tuning is never triggered and flash read/write failure are observed. Update spi_nor_set_octal_dtr() to set both the flashes to DDR mode and fix flash read/write failures. Segmentation error were observed while performing erase/read/write operation at the upper boundary of the upper flash. Updated die crossover logic in erase/read/write APIs to fix the issue.  Fixes: c376310 ("mtd: spi-nor: Add stacked memories support in spi-nor") Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>
1 parent 94de8a3 commit 4cce023

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

drivers/mtd/spi-nor/core.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,8 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
20962096
/*
20972097
* Flash cross over condition in stacked mode.
20982098
*/
2099-
if ((nor->flags & SNOR_F_HAS_STACKED) && (addr > sz - 1)) {
2099+
if ((nor->flags & SNOR_F_HAS_STACKED) && (addr > sz - 1) &&
2100+
(cur_cs_num != n_flash - 1)) {
21002101
cur_cs_num++;
21012102
params = spi_nor_get_params(nor, cur_cs_num);
21022103
sz += params->size;
@@ -2517,7 +2518,8 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
25172518
* Flash cross over condition in stacked mode.
25182519
*
25192520
*/
2520-
if ((nor->flags & SNOR_F_HAS_STACKED) && (from > sz - 1)) {
2521+
if ((nor->flags & SNOR_F_HAS_STACKED) && (from > sz - 1) &&
2522+
(cur_cs_num != n_flash - 1)) {
25212523
cur_cs_num++;
25222524
params = spi_nor_get_params(nor, cur_cs_num);
25232525
sz += params->size;
@@ -2705,7 +2707,8 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
27052707
/*
27062708
* Flash cross over condition in stacked mode.
27072709
*/
2708-
if ((nor->flags & SNOR_F_HAS_STACKED) && ((to + i) > sz - 1)) {
2710+
if ((nor->flags & SNOR_F_HAS_STACKED) && ((to + i) > sz - 1) &&
2711+
(cur_cs_num != n_flash - 1)) {
27092712
cur_cs_num++;
27102713
params = spi_nor_get_params(nor, cur_cs_num);
27112714
sz += params->size;
@@ -3776,7 +3779,7 @@ static int spi_nor_init_params(struct spi_nor *nor)
37763779
static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
37773780
{
37783781
struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
3779-
int ret;
3782+
int ret, idx, num_flash = 1;
37803783

37813784
if (!params->set_octal_dtr)
37823785
return 0;
@@ -3788,10 +3791,22 @@ static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
37883791
if (!(nor->flags & SNOR_F_IO_MODE_EN_VOLATILE))
37893792
return 0;
37903793

3791-
ret = params->set_octal_dtr(nor, enable);
3792-
if (ret)
3793-
return ret;
3794+
if (nor->flags & SNOR_F_HAS_STACKED)
3795+
num_flash = nor->num_flash;
3796+
3797+
for (idx = 0; idx < num_flash; idx++) {
3798+
params = spi_nor_get_params(nor, idx);
3799+
/*
3800+
* Select the appropriate CS index before
3801+
* issuing the command.
3802+
*/
3803+
nor->spimem->spi->cs_index_mask = 1 << idx;
3804+
ret = params->set_octal_dtr(nor, enable);
3805+
if (ret)
3806+
return ret;
3807+
}
37943808

3809+
nor->spimem->spi->cs_index_mask = 1;
37953810
if (enable)
37963811
nor->reg_proto = SNOR_PROTO_8_8_8_DTR;
37973812
else

0 commit comments

Comments
 (0)