Skip to content

Commit fb1dd6b

Browse files
kelvincheungmiquelraynal
authored andcommitted
mtd: rawnand: loongson: Add 6-byte NAND ID reading support
Loongson-1C and Loongson-2K SoCs support NAND flash chips with 6-byte ID. However, the current implementation only handles 5-byte ID which can lead to incorrect chip detection. Extend loongson_nand_read_id_type_exec() to support 6-byte NAND ID. Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent 7a1e3a4 commit fb1dd6b

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

drivers/mtd/nand/raw/loongson-nand-controller.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
#define LOONGSON_NAND_COL_ADDR_CYC 2U
5151
#define LOONGSON_NAND_MAX_ADDR_CYC 5U
5252

53+
#define LOONGSON_NAND_READ_ID_SLEEP_US 1000
54+
#define LOONGSON_NAND_READ_ID_TIMEOUT_US 5000
55+
5356
#define BITS_PER_WORD (4 * BITS_PER_BYTE)
5457

5558
struct loongson_nand_host;
@@ -73,6 +76,8 @@ struct loongson_nand_op {
7376
};
7477

7578
struct loongson_nand_data {
79+
unsigned int max_id_cycle;
80+
unsigned int id_cycle_field;
7681
unsigned int status_field;
7782
unsigned int op_scope_field;
7883
unsigned int hold_cycle;
@@ -458,22 +463,27 @@ static int loongson_nand_read_id_type_exec(struct nand_chip *chip, const struct
458463
struct loongson_nand_op op = {};
459464
int i, ret;
460465
union {
461-
char ids[5];
466+
char ids[6];
462467
struct {
463468
int idl;
464-
char idh;
469+
u16 idh;
465470
};
466471
} nand_id;
467472

468473
ret = loongson_nand_misc_type_exec(chip, subop, &op);
469474
if (ret)
470475
return ret;
471476

472-
nand_id.idl = readl(host->reg_base + LOONGSON_NAND_IDL);
473-
nand_id.idh = readb(host->reg_base + LOONGSON_NAND_IDH_STATUS);
477+
ret = regmap_read_poll_timeout(host->regmap, LOONGSON_NAND_IDL, nand_id.idl, nand_id.idl,
478+
LOONGSON_NAND_READ_ID_SLEEP_US,
479+
LOONGSON_NAND_READ_ID_TIMEOUT_US);
480+
if (ret)
481+
return ret;
474482

475-
for (i = 0; i < min(sizeof(nand_id.ids), op.orig_len); i++)
476-
op.buf[i] = nand_id.ids[sizeof(nand_id.ids) - 1 - i];
483+
nand_id.idh = readw(host->reg_base + LOONGSON_NAND_IDH_STATUS);
484+
485+
for (i = 0; i < min(host->data->max_id_cycle, op.orig_len); i++)
486+
op.buf[i] = nand_id.ids[host->data->max_id_cycle - 1 - i];
477487

478488
return ret;
479489
}
@@ -676,6 +686,10 @@ static int loongson_nand_controller_init(struct loongson_nand_host *host)
676686
if (IS_ERR(host->regmap))
677687
return dev_err_probe(dev, PTR_ERR(host->regmap), "failed to init regmap\n");
678688

689+
if (host->data->id_cycle_field)
690+
regmap_update_bits(host->regmap, LOONGSON_NAND_PARAM, host->data->id_cycle_field,
691+
host->data->max_id_cycle << __ffs(host->data->id_cycle_field));
692+
679693
chan = dma_request_chan(dev, "rxtx");
680694
if (IS_ERR(chan))
681695
return dev_err_probe(dev, PTR_ERR(chan), "failed to request DMA channel\n");
@@ -800,13 +814,16 @@ static void loongson_nand_remove(struct platform_device *pdev)
800814
}
801815

802816
static const struct loongson_nand_data ls1b_nand_data = {
817+
.max_id_cycle = 5,
803818
.status_field = GENMASK(15, 8),
804819
.hold_cycle = 0x2,
805820
.wait_cycle = 0xc,
806821
.set_addr = ls1b_nand_set_addr,
807822
};
808823

809824
static const struct loongson_nand_data ls1c_nand_data = {
825+
.max_id_cycle = 6,
826+
.id_cycle_field = GENMASK(14, 12),
810827
.status_field = GENMASK(23, 16),
811828
.op_scope_field = GENMASK(29, 16),
812829
.hold_cycle = 0x2,

0 commit comments

Comments
 (0)