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

authored by

Binbin Zhou and committed by
Miquel Raynal
5808ae66 0b1ae648

+49
+49
drivers/mtd/nand/raw/loongson-nand-controller.c
··· 74 74 75 75 #define BITS_PER_WORD (4 * BITS_PER_BYTE) 76 76 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 + 77 85 struct loongson_nand_host; 78 86 79 87 struct loongson_nand_op { ··· 111 103 unsigned int wait_cycle; 112 104 unsigned int nand_cs; 113 105 unsigned int dma_bits; 106 + int (*dma_config)(struct device *dev); 114 107 void (*set_addr)(struct loongson_nand_host *host, struct loongson_nand_op *op); 115 108 }; 116 109 ··· 768 759 dma_release_channel(host->dma_chan); 769 760 } 770 761 762 + static int ls2k1000_nand_apbdma_config(struct device *dev) 763 + { 764 + struct platform_device *pdev = to_platform_device(dev); 765 + void __iomem *regs; 766 + int val; 767 + 768 + regs = devm_platform_ioremap_resource_byname(pdev, "dma-config"); 769 + if (IS_ERR(regs)) 770 + return PTR_ERR(regs); 771 + 772 + val = readl(regs); 773 + val |= FIELD_PREP(LS2K1000_NAND_DMA_MASK, LS2K1000_DMA0_CONF); 774 + writel(val, regs); 775 + 776 + return 0; 777 + } 778 + 771 779 static int loongson_nand_controller_init(struct loongson_nand_host *host) 772 780 { 773 781 struct device *dev = host->dev; ··· 812 786 FIELD_PREP(LOONGSON_NAND_MAP_RDY3_SEL, LOONGSON_NAND_CS_RDY3); 813 787 814 788 regmap_write(host->regmap, LOONGSON_NAND_CS_RDY_MAP, val); 789 + 790 + if (host->data->dma_config) { 791 + ret = host->data->dma_config(dev); 792 + if (ret) 793 + return dev_err_probe(dev, ret, "failed to config DMA routing\n"); 794 + } 815 795 816 796 chan = dma_request_chan(dev, "rxtx"); 817 797 if (IS_ERR(chan)) ··· 973 941 .set_addr = ls1c_nand_set_addr, 974 942 }; 975 943 944 + static const struct loongson_nand_data ls2k1000_nand_data = { 945 + .max_id_cycle = 6, 946 + .id_cycle_field = GENMASK(14, 12), 947 + .status_field = GENMASK(23, 16), 948 + .op_scope_field = GENMASK(29, 16), 949 + .hold_cycle = 0x4, 950 + .wait_cycle = 0x12, 951 + .nand_cs = 0x2, 952 + .dma_bits = 64, 953 + .dma_config = ls2k1000_nand_apbdma_config, 954 + .set_addr = ls1c_nand_set_addr, 955 + }; 956 + 976 957 static const struct of_device_id loongson_nand_match[] = { 977 958 { 978 959 .compatible = "loongson,ls1b-nand-controller", ··· 998 953 { 999 954 .compatible = "loongson,ls2k0500-nand-controller", 1000 955 .data = &ls2k0500_nand_data, 956 + }, 957 + { 958 + .compatible = "loongson,ls2k1000-nand-controller", 959 + .data = &ls2k1000_nand_data, 1001 960 }, 1002 961 { /* sentinel */ } 1003 962 };