Skip to contentSkip to conversation

mtd: rawnand: loongson: Add Loongson-2K nand controller support

PATCH Applied Binbin Zhou 3 participants 12 messages Sep 4, 2025 – Sep 11, 2025

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v4 cover mtd: rawnand: loongson: Add Loongson-2K nand controller support

Hi all:

This patchset adds support for the Loongson-2K0500/Loongson-2K1000 NAND controllers, which are similar to the Loongson-1C NAND controller.

They support a maximum capacity of 16GB FLASH per chip, with a maximum page size of 8KB. The chip supports up to 4 chip selects and 4 RDY signals.

The key difference between the Loongson-2K NAND controllers is that the Loongson-2K1000 explicitly configures the DMA controller routing, while the Loongson-2K0500 defaults to using APBDMA0.

Summary of the patchset:
Ptach 1: Rename all prefixes from ls1x to loongson Patch 2: Add 6-byte NAND ID reading
Patch 3: Add chip select support
Patch 4-5: Add Loongson-2K0500 NAND controller support Patch 6-7: Add Loongson-2K1000 NAND controller support

Thanks.

-------
V4:
Patch (5/7):
- Split the flags variable into dma_bits;
- Chip selects set before requesting the DMA channel;
- '|' should be last character on the previous line.
Patch (7/7):
- Use devm_platform_ioremap_resource_byname();
- Add the dma_config() function pointer to replace the previous flags.

Link to V3:
https://lore.kernel.org/all/[email protected]/

V3:
Patch (1/7):
- Merge the first two rename patches;
Patch (3/7)
- Refact chip capacity calculation. Use a big switch-case

    for writesize, and sort the big switch-case by writesize;

- Drop the redundant 'nand_cs = 0x0';
Patch (6/7)
- Add Reviewed-by tag from Rob, thanks.

Link to V2:
https://lore.kernel.org/all/[email protected]/

V2:
Patch (5/8):
- Add Acked-by tag from Rob, thanks;
Patch (7/8):
- Update reg-names attribute description.

Link to V1:
https://lore.kernel.org/all/[email protected]/

Binbin Zhou (6):
mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson
mtd: rawnand: loongson: Add nand chip select support
dt-bindings: mtd: loongson,ls1b-nand-controller: Document the
Loongson-2K0500 NAND controller
mtd: rawnand: loongson: Add Loongson-2K0500 NAND controller support
dt-bindings: mtd: loongson,ls1b-nand-controller: Document the
Loongson-2K1000 NAND controller
mtd: rawnand: loongson: Add Loongson-2K1000 NAND controller support

Keguang Zhang (1):
mtd: rawnand: loongson: Add 6-byte NAND ID reading support

 .../mtd/loongson,ls1b-nand-controller.yaml    |   56 +-
 MAINTAINERS                                   |    2 +-
 drivers/mtd/nand/raw/Kconfig                  |    8 +-
 drivers/mtd/nand/raw/Makefile                 |    2 +-
 .../mtd/nand/raw/loongson-nand-controller.c   | 1024 +++++++++++++++++
 .../mtd/nand/raw/loongson1-nand-controller.c  |  836 --------------
 6 files changed, 1083 insertions(+), 845 deletions(-)
 create mode 100644 drivers/mtd/nand/raw/loongson-nand-controller.c
 delete mode 100644 drivers/mtd/nand/raw/loongson1-nand-controller.c

base-commit: c9f62564252c21d739a5003e9b2d6ad0828aa7bd

Signature · 1 line
2.47.3
#1 lore raw

PATCH v4 1/7 mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson

I am going to introduce the NAND controllers of the Loongson-2K series CPUs, which are similar to Loongson-1.

As preparation, rename all prefixes from Loongson1-specific to Loongson-generic.

No functional change intended.

---
 MAINTAINERS                                   |   2 +-
 drivers/mtd/nand/raw/Kconfig                  |   6 +-
 drivers/mtd/nand/raw/Makefile                 |   2 +-
 ...ontroller.c => loongson-nand-controller.c} | 337 +++++++++---------
 4 files changed, 177 insertions(+), 170 deletions(-)
 rename drivers/mtd/nand/raw/{loongson1-nand-controller.c => loongson-nand-controller.c} (61%)
MAINTAINERS +1 -1
index fe168477caa4..470713cf4f8a 100644
@@ -16992,7 +16992,7 @@ F:	Documentation/devicetree/bindings/*/loongson,ls1*.yaml
 F:	arch/mips/include/asm/mach-loongson32/
 F:	arch/mips/loongson32/
 F:	drivers/*/*loongson1*
-F:	drivers/mtd/nand/raw/loongson1-nand-controller.c
+F:	drivers/mtd/nand/raw/loongson-nand-controller.c
 F:	drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
 F:	sound/soc/loongson/loongson1_ac97.c
 
drivers/mtd/nand/raw/Kconfig +3 -3
index f053806333c3..489f5c05cda9 100644
@@ -436,12 +436,12 @@ config MTD_NAND_NUVOTON_MA35
 	  Enables support for the NAND controller found on
 	  the Nuvoton MA35 series SoCs.
 
-config MTD_NAND_LOONGSON1
-	tristate "Loongson1 NAND controller"
+config MTD_NAND_LOONGSON
+	tristate "Loongson NAND controller"
 	depends on LOONGSON1_APB_DMA || COMPILE_TEST
 	select REGMAP_MMIO
 	help
-	  Enables support for NAND controller on Loongson1 SoCs.
+	  Enables support for NAND controller on Loongson family chips.
 
 comment "Misc"
 
drivers/mtd/nand/raw/Makefile +1 -1
index 363cd18eaf16..619760138d32 100644
@@ -58,7 +58,7 @@ obj-$(CONFIG_MTD_NAND_ROCKCHIP)		+= rockchip-nand-controller.o
 obj-$(CONFIG_MTD_NAND_PL35X)		+= pl35x-nand-controller.o
 obj-$(CONFIG_MTD_NAND_RENESAS)		+= renesas-nand-controller.o
 obj-$(CONFIG_MTD_NAND_NUVOTON_MA35)	+= nuvoton-ma35d1-nand-controller.o
-obj-$(CONFIG_MTD_NAND_LOONGSON1)	+= loongson1-nand-controller.o
+obj-$(CONFIG_MTD_NAND_LOONGSON)		+= loongson-nand-controller.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
drivers/mtd/nand/raw/loongson-nand-controller.c renamed from drivers/mtd/nand/raw/loongson1-nand-controller.c +172 -165

731 lines not on this page · raw message

Signature · 1 line
2.47.3
maintainer
#2 lore raw

Re: [PATCH v4 1/7] mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson

Hi Binbin,

Quoted 1 line · Binbin Zhou

I am going to introduce the NAND controllers of the Loongson-2K series

Please adopt a more global phrasing, like "In order to introduce" rather than the first singular person.

Quoted 9 lines

CPUs, which are similar to Loongson-1.

As preparation, rename all prefixes from Loongson1-specific to Loongson-generic.

No functional change intended.

---

Thanks,
Miquèl

maintainer
#3 lore raw

Re: [PATCH v4 1/7] mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson

Quoted 8 lines · Miquel Raynal

Hi Binbin,

Quoted 1 line · Binbin Zhou

I am going to introduce the NAND controllers of the Loongson-2K series

Please adopt a more global phrasing, like "In order to introduce" rather than the first singular person.

This will be a hint for next submission, the rest of the series looks good, so I'm taking it anyway, no need to resubmit.

Thanks,
Miquèl

#4 lore raw

PATCH v4 2/7 mtd: rawnand: loongson: Add 6-byte NAND ID reading support

In reply to Binbin Zhou

From: Keguang Zhang <[email protected]>

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.

---
 .../mtd/nand/raw/loongson-nand-controller.c   | 29 +++++++++++++++----
 1 file changed, 23 insertions(+), 6 deletions(-)
drivers/mtd/nand/raw/loongson-nand-controller.c +23 -6
index b5a7be0fcacc..97cd566420a8 100644
@@ -50,6 +50,9 @@
 #define LOONGSON_NAND_COL_ADDR_CYC	2U
 #define LOONGSON_NAND_MAX_ADDR_CYC	5U
 
+#define LOONGSON_NAND_READ_ID_SLEEP_US		1000
+#define LOONGSON_NAND_READ_ID_TIMEOUT_US	5000
+
 #define BITS_PER_WORD			(4 * BITS_PER_BYTE)
 
 struct loongson_nand_host;
@@ -73,6 +76,8 @@ struct loongson_nand_op {
 };
 
 struct loongson_nand_data {
+	unsigned int max_id_cycle;
+	unsigned int id_cycle_field;
 	unsigned int status_field;
 	unsigned int op_scope_field;
 	unsigned int hold_cycle;
@@ -458,10 +463,10 @@ static int loongson_nand_read_id_type_exec(struct nand_chip *chip, const struct
 	struct loongson_nand_op op = {};
 	int i, ret;
 	union {
-		char ids[5];
+		char ids[6];
 		struct {
 			int idl;
-			char idh;
+			u16 idh;
 		};
 	} nand_id;
 
@@ -469,11 +474,16 @@ static int loongson_nand_read_id_type_exec(struct nand_chip *chip, const struct
 	if (ret)
 		return ret;
 
-	nand_id.idl = readl(host->reg_base + LOONGSON_NAND_IDL);
-	nand_id.idh = readb(host->reg_base + LOONGSON_NAND_IDH_STATUS);
+	ret = regmap_read_poll_timeout(host->regmap, LOONGSON_NAND_IDL, nand_id.idl, nand_id.idl,
+				       LOONGSON_NAND_READ_ID_SLEEP_US,
+				       LOONGSON_NAND_READ_ID_TIMEOUT_US);
+	if (ret)
+		return ret;
 
-	for (i = 0; i < min(sizeof(nand_id.ids), op.orig_len); i++)
-		op.buf[i] = nand_id.ids[sizeof(nand_id.ids) - 1 - i];
+	nand_id.idh = readw(host->reg_base + LOONGSON_NAND_IDH_STATUS);
+
+	for (i = 0; i < min(host->data->max_id_cycle, op.orig_len); i++)
+		op.buf[i] = nand_id.ids[host->data->max_id_cycle - 1 - i];
 
 	return ret;
 }
@@ -676,6 +686,10 @@ static int loongson_nand_controller_init(struct loongson_nand_host *host)
 	if (IS_ERR(host->regmap))
 		return dev_err_probe(dev, PTR_ERR(host->regmap), "failed to init regmap\n");
 
+	if (host->data->id_cycle_field)
+		regmap_update_bits(host->regmap, LOONGSON_NAND_PARAM, host->data->id_cycle_field,
+				   host->data->max_id_cycle << __ffs(host->data->id_cycle_field));
+
 	chan = dma_request_chan(dev, "rxtx");
 	if (IS_ERR(chan))
 		return dev_err_probe(dev, PTR_ERR(chan), "failed to request DMA channel\n");
@@ -800,6 +814,7 @@ static void loongson_nand_remove(struct platform_device *pdev)
 }
 
 static const struct loongson_nand_data ls1b_nand_data = {
+	.max_id_cycle = 5,
 	.status_field = GENMASK(15, 8),
 	.hold_cycle = 0x2,
 	.wait_cycle = 0xc,
@@ -807,6 +822,8 @@ static const struct loongson_nand_data ls1b_nand_data = {
 };
 
 static const struct loongson_nand_data ls1c_nand_data = {
+	.max_id_cycle = 6,
+	.id_cycle_field = GENMASK(14, 12),
 	.status_field = GENMASK(23, 16),
 	.op_scope_field = GENMASK(29, 16),
 	.hold_cycle = 0x2,
Signature · 1 line
2.47.3
#5 lore raw

PATCH v4 3/7 mtd: rawnand: loongson: Add nand chip select support

In reply to Binbin Zhou

The page address register describes the page address of the starting address for NAND read/write/erase operations.

According to the manual, it consists of two parts:

	{chip select, page number}

The chip select is fixed at 2 bits, and the page number is determined based on the actual capacity of the single-chip memory. Therefore we need to determine the chip select bits base on the page number.

For example, for a 1GB capacity chip (2K page size), it has 1M pages. Thus, [19:0] is used to represent the page number, and [21:20] represents the chip select.

---
 .../mtd/nand/raw/loongson-nand-controller.c   | 116 ++++++++++++++----
 1 file changed, 90 insertions(+), 26 deletions(-)
drivers/mtd/nand/raw/loongson-nand-controller.c +90 -26
index 97cd566420a8..1427dd6943a7 100644
@@ -82,6 +82,7 @@ struct loongson_nand_data {
 	unsigned int op_scope_field;
 	unsigned int hold_cycle;
 	unsigned int wait_cycle;
+	unsigned int nand_cs;
 	void (*set_addr)(struct loongson_nand_host *host, struct loongson_nand_op *op);
 };
 
@@ -90,6 +91,7 @@ struct loongson_nand_host {
 	struct nand_chip chip;
 	struct nand_controller controller;
 	const struct loongson_nand_data *data;
+	unsigned int addr_cs_field;
 	void __iomem *reg_base;
 	struct regmap *regmap;
 	/* DMA Engine stuff */
@@ -215,6 +217,26 @@ static int loongson_nand_parse_instructions(struct nand_chip *chip, const struct
 	return 0;
 }
 
+static void loongson_nand_set_addr_cs(struct loongson_nand_host *host)
+{
+	struct nand_chip *chip = &host->chip;
+	struct mtd_info *mtd = nand_to_mtd(chip);
+
+	if (!host->data->nand_cs)
+		return;
+
+	/*
+	 * The Manufacturer/Chip ID read operation precedes attach_chip, at which point
+	 * information such as NAND chip selection and capacity is unknown. As a
+	 * workaround, we use 128MB cellsize (2KB pagesize) as a fallback.
+	 */
+	if (!mtd->writesize)
+		host->addr_cs_field = GENMASK(17, 16);
+
+	regmap_update_bits(host->regmap, LOONGSON_NAND_ADDR2, host->addr_cs_field,
+			   host->data->nand_cs << __ffs(host->addr_cs_field));
+}
+
 static void ls1b_nand_set_addr(struct loongson_nand_host *host, struct loongson_nand_op *op)
 {
 	struct nand_chip *chip = &host->chip;
@@ -263,6 +285,8 @@ static void ls1c_nand_set_addr(struct loongson_nand_host *host, struct loongson_
 			regmap_update_bits(host->regmap, LOONGSON_NAND_ADDR2, mask, val);
 		}
 	}
+
+	loongson_nand_set_addr_cs(host);
 }
 
 static void loongson_nand_trigger_op(struct loongson_nand_host *host, struct loongson_nand_op *op)
@@ -603,42 +627,82 @@ static int loongson_nand_exec_op(struct nand_chip *chip, const struct nand_opera
 	return nand_op_parser_exec_op(chip, &loongson_nand_op_parser, op, check_only);
 }
 
-static int loongson_nand_attach_chip(struct nand_chip *chip)
+static int loongson_nand_get_chip_capacity(struct nand_chip *chip)
 {
 	struct loongson_nand_host *host = nand_get_controller_data(chip);
 	u64 chipsize = nanddev_target_size(&chip->base);
-	int cell_size = 0;
+	struct mtd_info *mtd = nand_to_mtd(chip);
 
-	switch (chipsize) {
-	case SZ_128M:
-		cell_size = 0x0;
-		break;
-	case SZ_256M:
-		cell_size = 0x1;
-		break;
-	case SZ_512M:
-		cell_size = 0x2;
-		break;
-	case SZ_1G:
-		cell_size = 0x3;
-		break;
-	case SZ_2G:
-		cell_size = 0x4;
+	switch (mtd->writesize) {
+	case SZ_512:
+		switch (chipsize) {
+		case SZ_8M:
+			host->addr_cs_field = GENMASK(15, 14);
+			return 0x9;
+		case SZ_16M:
+			host->addr_cs_field = GENMASK(16, 15);
+			return 0xa;
+		case SZ_32M:
+			host->addr_cs_field = GENMASK(17, 16);
+			return 0xb;
+		case SZ_64M:
+			host->addr_cs_field = GENMASK(18, 17);
+			return 0xc;
+		case SZ_128M:
+			host->addr_cs_field = GENMASK(19, 18);
+			return 0xd;
+		}
 		break;
-	case SZ_4G:
-		cell_size = 0x5;
+	case SZ_2K:
+		switch (chipsize) {
+		case SZ_128M:
+			host->addr_cs_field = GENMASK(17, 16);
+			return 0x0;
+		case SZ_256M:
+			host->addr_cs_field = GENMASK(18, 17);
+			return 0x1;
+		case SZ_512M:
+			host->addr_cs_field = GENMASK(19, 18);
+			return 0x2;
+		case SZ_1G:
+			host->addr_cs_field = GENMASK(20, 19);
+			return 0x3;
+		}
 		break;
-	case SZ_8G:
-		cell_size = 0x6;
+	case SZ_4K:
+		if (chipsize == SZ_2G) {
+			host->addr_cs_field = GENMASK(20, 19);
+			return 0x4;
+		}
 		break;
-	case SZ_16G:
-		cell_size = 0x7;
+	case SZ_8K:
+		switch (chipsize) {
+		case SZ_4G:
+			host->addr_cs_field = GENMASK(20, 19);
+			return 0x5;
+		case SZ_8G:
+			host->addr_cs_field = GENMASK(21, 20);
+			return 0x6;
+		case SZ_16G:
+			host->addr_cs_field = GENMASK(22, 21);
+			return 0x7;
+		}
 		break;
-	default:
-		dev_err(host->dev, "unsupported chip size: %llu MB\n", chipsize);
-		return -EINVAL;
 	}
 
+	dev_err(host->dev, "Unsupported chip size: %llu MB with page size %u B\n",
+		chipsize, mtd->writesize);
+	return -EINVAL;
+}
+
+static int loongson_nand_attach_chip(struct nand_chip *chip)
+{
+	struct loongson_nand_host *host = nand_get_controller_data(chip);
+	int cell_size = loongson_nand_get_chip_capacity(chip);
+
+	if (cell_size < 0)
+		return cell_size;
+
 	switch (chip->ecc.engine_type) {
 	case NAND_ECC_ENGINE_TYPE_NONE:
 		break;
Signature · 1 line
2.47.3
#6 lore raw

PATCH v4 4/7 dt-bindings: mtd: loongson,ls1b-nand-controller: Document the Loongson-2K0500 NAND controller

In reply to Binbin Zhou

Add new compatible for the Loongson-2K NAND controller used for Loongson-2K0500 SoC.

---
 .../bindings/mtd/loongson,ls1b-nand-controller.yaml         | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/mtd/loongson,ls1b-nand-controller.yaml +4 -2
index a09e92e416c4..4ec2b5d1e89d 100644
@@ -4,13 +4,14 @@
 $id: http://devicetree.org/schemas/mtd/loongson,ls1b-nand-controller.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Loongson-1 NAND Controller
+title: Loongson NAND Controller
 
 maintainers:
   - Keguang Zhang <[email protected]>
+  - Binbin Zhou <[email protected]>
 
 description:
-  The Loongson-1 NAND controller abstracts all supported operations,
+  The Loongson NAND controller abstracts all supported operations,
   meaning it does not support low-level access to raw NAND flash chips.
   Moreover, the controller is paired with the DMA engine to perform
   READ and PROGRAM functions.
@@ -24,6 +25,7 @@ properties:
       - enum:
           - loongson,ls1b-nand-controller
           - loongson,ls1c-nand-controller
+          - loongson,ls2k0500-nand-controller
       - items:
           - enum:
               - loongson,ls1a-nand-controller
Signature · 1 line
2.47.3
#7 lore raw

PATCH v4 5/7 mtd: rawnand: loongson: Add Loongson-2K0500 NAND controller support

In reply to Binbin Zhou

The Loongson-2K0500 NAND controller is similar to the Loongson-1C.

It supports a maximum capacity of 16GB FLASH per chip with a maximum page size of 8KB, and it supports up to 4 chip selects and 4 RDY signals.

Its DMA controller is defaulted to APBDMA0.

---
 drivers/mtd/nand/raw/Kconfig                  |  2 +-
 .../mtd/nand/raw/loongson-nand-controller.c   | 53 ++++++++++++++++++-
 2 files changed, 53 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/Kconfig +1 -1
index 489f5c05cda9..7408f34f0c68 100644
@@ -438,7 +438,7 @@ config MTD_NAND_NUVOTON_MA35
 
 config MTD_NAND_LOONGSON
 	tristate "Loongson NAND controller"
-	depends on LOONGSON1_APB_DMA || COMPILE_TEST
+	depends on LOONGSON1_APB_DMA || LOONGSON2_APB_DMA || COMPILE_TEST
 	select REGMAP_MMIO
 	help
 	  Enables support for NAND controller on Loongson family chips.
drivers/mtd/nand/raw/loongson-nand-controller.c +52 -1

112 lines not on this page · raw message

Signature · 1 line
2.47.3
#8 lore raw

PATCH v4 6/7 dt-bindings: mtd: loongson,ls1b-nand-controller: Document the Loongson-2K1000 NAND controller

In reply to Binbin Zhou

Add new compatible for the Loongson-2K NAND controller used for Loongson-2K1000 SoC.

---
 .../mtd/loongson,ls1b-nand-controller.yaml    | 50 ++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/mtd/loongson,ls1b-nand-controller.yaml +49 -1
index 4ec2b5d1e89d..cf85d0cede00 100644
@@ -26,18 +26,22 @@ properties:
           - loongson,ls1b-nand-controller
           - loongson,ls1c-nand-controller
           - loongson,ls2k0500-nand-controller
+          - loongson,ls2k1000-nand-controller
       - items:
           - enum:
               - loongson,ls1a-nand-controller
           - const: loongson,ls1b-nand-controller
 
   reg:
-    maxItems: 2
+    minItems: 2
+    maxItems: 3
 
   reg-names:
+    minItems: 2
     items:
       - const: nand
       - const: nand-dma
+      - const: dma-config
 
   dmas:
     maxItems: 1
@@ -54,6 +58,27 @@ required:
 
 unevaluatedProperties: false
 
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - loongson,ls2k1000-nand-controller
+
+then:
+  properties:
+    reg:
+      minItems: 3
+    reg-names:
+      minItems: 3
+
+else:
+  properties:
+    reg:
+      maxItems: 2
+    reg-names:
+      maxItems: 2
+
 examples:
   - |
     nand-controller@1fe78000 {
@@ -72,3 +97,26 @@ examples:
             nand-ecc-algo = "hamming";
         };
     };
+
+  - |
+    nand-controller@1fe26000 {
+        compatible = "loongson,ls2k1000-nand-controller";
+        reg = <0x1fe26000 0x24>,
+              <0x1fe26040 0x4>,
+              <0x1fe00438 0x8>;
+        reg-names = "nand", "nand-dma", "dma-config";
+        dmas = <&apbdma0 0>;
+        dma-names = "rxtx";
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        nand@0 {
+            reg = <0>;
+            label = "ls2k1000-nand";
+            nand-use-soft-ecc-engine;
+            nand-ecc-algo = "bch";
+            nand-ecc-strength = <8>;
+            nand-ecc-step-size = <512>;
+        };
+    };
Signature · 1 line
2.47.3
#9 lore raw

PATCH v4 7/7 mtd: rawnand: loongson: Add Loongson-2K1000 NAND controller support

In reply to Binbin Zhou

The Loongson-2K1000 NAND controller is also similar to the Loongson-1C.

It supports a maximum capacity of 16GB FLASH per chip with a maximum page size of 8KB, and it supports up to 4 chip selects and 4 RDY signals.

The key difference from the Loongson-2K0500 is that it requires explicit configuration of the DMA control route. Typically, it is configured as APBDMA0.

---
 .../mtd/nand/raw/loongson-nand-controller.c   | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
drivers/mtd/nand/raw/loongson-nand-controller.c +49 -0
index 427a0daf8c55..8490412d5be1 100644
@@ -74,6 +74,14 @@
 
 #define BITS_PER_WORD			(4 * BITS_PER_BYTE)
 
+/* Loongson-2K1000 NAND DMA routing register */
+#define LS2K1000_NAND_DMA_MASK         GENMASK(2, 0)
+#define LS2K1000_DMA0_CONF             0x0
+#define LS2K1000_DMA1_CONF             0x1
+#define LS2K1000_DMA2_CONF             0x2
+#define LS2K1000_DMA3_CONF             0x3
+#define LS2K1000_DMA4_CONF             0x4
+
 struct loongson_nand_host;
 
 struct loongson_nand_op {
@@ -103,6 +111,7 @@ struct loongson_nand_data {
 	unsigned int wait_cycle;
 	unsigned int nand_cs;
 	unsigned int dma_bits;
+	int (*dma_config)(struct device *dev);
 	void (*set_addr)(struct loongson_nand_host *host, struct loongson_nand_op *op);
 };
 
@@ -759,6 +768,23 @@ static void loongson_nand_controller_cleanup(struct loongson_nand_host *host)
 		dma_release_channel(host->dma_chan);
 }
 
+static int ls2k1000_nand_apbdma_config(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	void __iomem *regs;
+	int val;
+
+	regs = devm_platform_ioremap_resource_byname(pdev, "dma-config");
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	val = readl(regs);
+	val |= FIELD_PREP(LS2K1000_NAND_DMA_MASK, LS2K1000_DMA0_CONF);
+	writel(val, regs);
+
+	return 0;
+}
+
 static int loongson_nand_controller_init(struct loongson_nand_host *host)
 {
 	struct device *dev = host->dev;
@@ -787,6 +813,12 @@ static int loongson_nand_controller_init(struct loongson_nand_host *host)
 
 	regmap_write(host->regmap, LOONGSON_NAND_CS_RDY_MAP, val);
 
+	if (host->data->dma_config) {
+		ret = host->data->dma_config(dev);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to config DMA routing\n");
+	}
+
 	chan = dma_request_chan(dev, "rxtx");
 	if (IS_ERR(chan))
 		return dev_err_probe(dev, PTR_ERR(chan), "failed to request DMA channel\n");
@@ -941,6 +973,19 @@ static const struct loongson_nand_data ls2k0500_nand_data = {
 	.set_addr = ls1c_nand_set_addr,
 };
 
+static const struct loongson_nand_data ls2k1000_nand_data = {
+	.max_id_cycle = 6,
+	.id_cycle_field = GENMASK(14, 12),
+	.status_field = GENMASK(23, 16),
+	.op_scope_field = GENMASK(29, 16),
+	.hold_cycle = 0x4,
+	.wait_cycle = 0x12,
+	.nand_cs = 0x2,
+	.dma_bits = 64,
+	.dma_config = ls2k1000_nand_apbdma_config,
+	.set_addr = ls1c_nand_set_addr,
+};
+
 static const struct of_device_id loongson_nand_match[] = {
 	{
 		.compatible = "loongson,ls1b-nand-controller",
@@ -954,6 +999,10 @@ static const struct of_device_id loongson_nand_match[] = {
 		.compatible = "loongson,ls2k0500-nand-controller",
 		.data = &ls2k0500_nand_data,
 	},
+	{
+		.compatible = "loongson,ls2k1000-nand-controller",
+		.data = &ls2k1000_nand_data,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, loongson_nand_match);
Signature · 1 line
2.47.3
maintainer Applied
#10 lore raw
In reply to Binbin Zhou
Quoted 11 lines · Binbin Zhou

This patchset adds support for the Loongson-2K0500/Loongson-2K1000 NAND controllers, which are similar to the Loongson-1C NAND controller.

They support a maximum capacity of 16GB FLASH per chip, with a maximum page size of 8KB. The chip supports up to 4 chip selects and 4 RDY signals.

The key difference between the Loongson-2K NAND controllers is that the Loongson-2K1000 explicitly configures the DMA controller routing, while the Loongson-2K0500 defaults to using APBDMA0.

[...]

Applied to nand/next, thanks!

[1/7] mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson

      commit: 7a1e3a452a574ef337c4c2cd9202332a1ae9cd94
[2/7] mtd: rawnand: loongson: Add 6-byte NAND ID reading support
      commit: fb1dd6b6722b5187a4fa7385d0be60b28c0f9936
[3/7] mtd: rawnand: loongson: Add nand chip select support
      commit: 7ad5bdf88d7295c295a363a5daf481b283acedc2
[4/7] dt-bindings: mtd: loongson,ls1b-nand-controller: Document the Loongson-2K0500 NAND controller
      commit: 4a2bab7ccceb14b48e86794b87104248c75aa587
[5/7] mtd: rawnand: loongson: Add Loongson-2K0500 NAND controller support
      commit: e55bbdd4a4b654dfe8ee8649b3be1db82319d6c0
[6/7] dt-bindings: mtd: loongson,ls1b-nand-controller: Document the Loongson-2K1000 NAND controller
      commit: 0b1ae6480c3be58ad31afe757cbf1069ae072bb1
[7/7] mtd: rawnand: loongson: Add Loongson-2K1000 NAND controller support
      commit: 5808ae66f22e665c7131816e146548f2d7903ae1

Patche(s) should be available on mtd/linux.git and will be part of the next PR (provided that no robot complains by then).

Kind regards,
Miquèl

maintainer Reviewed-by Tested-by on the v4 series
#11 lore raw
In reply to Binbin Zhou

For the whole series:

Quoted 85 lines · Binbin Zhou

Hi all:

This patchset adds support for the Loongson-2K0500/Loongson-2K1000 NAND controllers, which are similar to the Loongson-1C NAND controller.

They support a maximum capacity of 16GB FLASH per chip, with a maximum page size of 8KB. The chip supports up to 4 chip selects and 4 RDY signals.

The key difference between the Loongson-2K NAND controllers is that the Loongson-2K1000 explicitly configures the DMA controller routing, while the Loongson-2K0500 defaults to using APBDMA0.

Summary of the patchset:
Ptach 1: Rename all prefixes from ls1x to loongson Patch 2: Add 6-byte NAND ID reading
Patch 3: Add chip select support
Patch 4-5: Add Loongson-2K0500 NAND controller support Patch 6-7: Add Loongson-2K1000 NAND controller support

Thanks.

-------
V4:
Patch (5/7):
- Split the flags variable into dma_bits;
- Chip selects set before requesting the DMA channel;
- '|' should be last character on the previous line.
Patch (7/7):
- Use devm_platform_ioremap_resource_byname();
- Add the dma_config() function pointer to replace the previous flags.

Link to V3:
https://lore.kernel.org/all/[email protected]/

V3:
Patch (1/7):
- Merge the first two rename patches;
Patch (3/7)
- Refact chip capacity calculation. Use a big switch-case

    for writesize, and sort the big switch-case by writesize;

- Drop the redundant 'nand_cs = 0x0';
Patch (6/7)
- Add Reviewed-by tag from Rob, thanks.

Link to V2:
https://lore.kernel.org/all/[email protected]/

V2:
Patch (5/8):
- Add Acked-by tag from Rob, thanks;
Patch (7/8):
- Update reg-names attribute description.

Link to V1:
https://lore.kernel.org/all/[email protected]/

Binbin Zhou (6):
mtd: rawnand: loongson1: Rename the prefix from ls1x to loongson
mtd: rawnand: loongson: Add nand chip select support
dt-bindings: mtd: loongson,ls1b-nand-controller: Document the
Loongson-2K0500 NAND controller
mtd: rawnand: loongson: Add Loongson-2K0500 NAND controller support
dt-bindings: mtd: loongson,ls1b-nand-controller: Document the
Loongson-2K1000 NAND controller
mtd: rawnand: loongson: Add Loongson-2K1000 NAND controller support

Keguang Zhang (1):
mtd: rawnand: loongson: Add 6-byte NAND ID reading support

 .../mtd/loongson,ls1b-nand-controller.yaml    |   56 +-
 MAINTAINERS                                   |    2 +-
 drivers/mtd/nand/raw/Kconfig                  |    8 +-
 drivers/mtd/nand/raw/Makefile                 |    2 +-
 .../mtd/nand/raw/loongson-nand-controller.c   | 1024 +++++++++++++++++
 .../mtd/nand/raw/loongson1-nand-controller.c  |  836 --------------
 6 files changed, 1083 insertions(+), 845 deletions(-)
 create mode 100644 drivers/mtd/nand/raw/loongson-nand-controller.c
 delete mode 100644 drivers/mtd/nand/raw/loongson1-nand-controller.c

base-commit: c9f62564252c21d739a5003e9b2d6ad0828aa7bd --
2.47.3

Signature · 3 lines
Best regards,

Keguang Zhang