Skip to content

Commit 5808ae6

Browse files
AaronDotmiquelraynal
authored andcommitted
mtd: rawnand: loongson: Add Loongson-2K1000 NAND controller support
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. Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent 0b1ae64 commit 5808ae6

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@
7474

7575
#define BITS_PER_WORD (4 * BITS_PER_BYTE)
7676

77+
/* Loongson-2K1000 NAND DMA routing register */
78+
#define LS2K1000_NAND_DMA_MASK GENMASK(2, 0)
79+
#define LS2K1000_DMA0_CONF 0x0
80+
#define LS2K1000_DMA1_CONF 0x1
81+
#define LS2K1000_DMA2_CONF 0x2
82+
#define LS2K1000_DMA3_CONF 0x3
83+
#define LS2K1000_DMA4_CONF 0x4
84+
7785
struct loongson_nand_host;
7886

7987
struct loongson_nand_op {
@@ -103,6 +111,7 @@ struct loongson_nand_data {
103111
unsigned int wait_cycle;
104112
unsigned int nand_cs;
105113
unsigned int dma_bits;
114+
int (*dma_config)(struct device *dev);
106115
void (*set_addr)(struct loongson_nand_host *host, struct loongson_nand_op *op);
107116
};
108117

@@ -759,6 +768,23 @@ static void loongson_nand_controller_cleanup(struct loongson_nand_host *host)
759768
dma_release_channel(host->dma_chan);
760769
}
761770

771+
static int ls2k1000_nand_apbdma_config(struct device *dev)
772+
{
773+
struct platform_device *pdev = to_platform_device(dev);
774+
void __iomem *regs;
775+
int val;
776+
777+
regs = devm_platform_ioremap_resource_byname(pdev, "dma-config");
778+
if (IS_ERR(regs))
779+
return PTR_ERR(regs);
780+
781+
val = readl(regs);
782+
val |= FIELD_PREP(LS2K1000_NAND_DMA_MASK, LS2K1000_DMA0_CONF);
783+
writel(val, regs);
784+
785+
return 0;
786+
}
787+
762788
static int loongson_nand_controller_init(struct loongson_nand_host *host)
763789
{
764790
struct device *dev = host->dev;
@@ -787,6 +813,12 @@ static int loongson_nand_controller_init(struct loongson_nand_host *host)
787813

788814
regmap_write(host->regmap, LOONGSON_NAND_CS_RDY_MAP, val);
789815

816+
if (host->data->dma_config) {
817+
ret = host->data->dma_config(dev);
818+
if (ret)
819+
return dev_err_probe(dev, ret, "failed to config DMA routing\n");
820+
}
821+
790822
chan = dma_request_chan(dev, "rxtx");
791823
if (IS_ERR(chan))
792824
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 = {
941973
.set_addr = ls1c_nand_set_addr,
942974
};
943975

976+
static const struct loongson_nand_data ls2k1000_nand_data = {
977+
.max_id_cycle = 6,
978+
.id_cycle_field = GENMASK(14, 12),
979+
.status_field = GENMASK(23, 16),
980+
.op_scope_field = GENMASK(29, 16),
981+
.hold_cycle = 0x4,
982+
.wait_cycle = 0x12,
983+
.nand_cs = 0x2,
984+
.dma_bits = 64,
985+
.dma_config = ls2k1000_nand_apbdma_config,
986+
.set_addr = ls1c_nand_set_addr,
987+
};
988+
944989
static const struct of_device_id loongson_nand_match[] = {
945990
{
946991
.compatible = "loongson,ls1b-nand-controller",
@@ -954,6 +999,10 @@ static const struct of_device_id loongson_nand_match[] = {
954999
.compatible = "loongson,ls2k0500-nand-controller",
9551000
.data = &ls2k0500_nand_data,
9561001
},
1002+
{
1003+
.compatible = "loongson,ls2k1000-nand-controller",
1004+
.data = &ls2k1000_nand_data,
1005+
},
9571006
{ /* sentinel */ }
9581007
};
9591008
MODULE_DEVICE_TABLE(of, loongson_nand_match);

0 commit comments

Comments
 (0)