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: 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>

authored by

Keguang Zhang and committed by
Miquel Raynal
fb1dd6b6 7a1e3a45

+23 -6
+23 -6
drivers/mtd/nand/raw/loongson-nand-controller.c
··· 50 50 #define LOONGSON_NAND_COL_ADDR_CYC 2U 51 51 #define LOONGSON_NAND_MAX_ADDR_CYC 5U 52 52 53 + #define LOONGSON_NAND_READ_ID_SLEEP_US 1000 54 + #define LOONGSON_NAND_READ_ID_TIMEOUT_US 5000 55 + 53 56 #define BITS_PER_WORD (4 * BITS_PER_BYTE) 54 57 55 58 struct loongson_nand_host; ··· 76 73 }; 77 74 78 75 struct loongson_nand_data { 76 + unsigned int max_id_cycle; 77 + unsigned int id_cycle_field; 79 78 unsigned int status_field; 80 79 unsigned int op_scope_field; 81 80 unsigned int hold_cycle; ··· 463 458 struct loongson_nand_op op = {}; 464 459 int i, ret; 465 460 union { 466 - char ids[5]; 461 + char ids[6]; 467 462 struct { 468 463 int idl; 469 - char idh; 464 + u16 idh; 470 465 }; 471 466 } nand_id; 472 467 ··· 474 469 if (ret) 475 470 return ret; 476 471 477 - nand_id.idl = readl(host->reg_base + LOONGSON_NAND_IDL); 478 - nand_id.idh = readb(host->reg_base + LOONGSON_NAND_IDH_STATUS); 472 + ret = regmap_read_poll_timeout(host->regmap, LOONGSON_NAND_IDL, nand_id.idl, nand_id.idl, 473 + LOONGSON_NAND_READ_ID_SLEEP_US, 474 + LOONGSON_NAND_READ_ID_TIMEOUT_US); 475 + if (ret) 476 + return ret; 479 477 480 - for (i = 0; i < min(sizeof(nand_id.ids), op.orig_len); i++) 481 - op.buf[i] = nand_id.ids[sizeof(nand_id.ids) - 1 - i]; 478 + nand_id.idh = readw(host->reg_base + LOONGSON_NAND_IDH_STATUS); 479 + 480 + for (i = 0; i < min(host->data->max_id_cycle, op.orig_len); i++) 481 + op.buf[i] = nand_id.ids[host->data->max_id_cycle - 1 - i]; 482 482 483 483 return ret; 484 484 } ··· 686 676 if (IS_ERR(host->regmap)) 687 677 return dev_err_probe(dev, PTR_ERR(host->regmap), "failed to init regmap\n"); 688 678 679 + if (host->data->id_cycle_field) 680 + regmap_update_bits(host->regmap, LOONGSON_NAND_PARAM, host->data->id_cycle_field, 681 + host->data->max_id_cycle << __ffs(host->data->id_cycle_field)); 682 + 689 683 chan = dma_request_chan(dev, "rxtx"); 690 684 if (IS_ERR(chan)) 691 685 return dev_err_probe(dev, PTR_ERR(chan), "failed to request DMA channel\n"); ··· 814 800 } 815 801 816 802 static const struct loongson_nand_data ls1b_nand_data = { 803 + .max_id_cycle = 5, 817 804 .status_field = GENMASK(15, 8), 818 805 .hold_cycle = 0x2, 819 806 .wait_cycle = 0xc, ··· 822 807 }; 823 808 824 809 static const struct loongson_nand_data ls1c_nand_data = { 810 + .max_id_cycle = 6, 811 + .id_cycle_field = GENMASK(14, 12), 825 812 .status_field = GENMASK(23, 16), 826 813 .op_scope_field = GENMASK(29, 16), 827 814 .hold_cycle = 0x2,