mirror of
https://gitee.com/open-loongarch/linux-6.12.git
synced 2026-10-25 20:47:11 +08:00
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> Signed-off-by: maoxiaochuan <maoxiaochuan@loongson.cn>
This commit is contained in:
committed by
maoxiaochuan
parent
e1fc29b581
commit
bf3b61946c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user