Răsfoiți Sursa

mtd: aspeed: add memory controllers for the Aspeed AST2400 SoC

This driver adds mtd support for the Aspeed AST2400 SoC static memory
controllers:

 * New Static Memory Controller (referred as FMC)
   . BMC firmware
   . AST2500 compatible register set
   . 5 chip select pins (CE0 ∼ CE4)
   . supports NOR flash, NAND flash and SPI flash memory.

 * SPI Flash Controller (SPI)
   . host Firmware
   . slightly different register set, between AST2500 and the legacy
     controller
   . supports SPI flash memory
   . 1 chip select pin (CE0)

The legacy static memory controller (referred as SMC) is not
supported, as well as types other than SPI.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Cédric Le Goater 8 ani în urmă
părinte
comite
e56beebbc7
2 a modificat fișierele cu 34 adăugiri și 1 ștergeri
  1. 1 1
      drivers/mtd/spi-nor/Kconfig
  2. 33 0
      drivers/mtd/spi-nor/aspeed-smc.c

+ 1 - 1
drivers/mtd/spi-nor/Kconfig

@@ -35,7 +35,7 @@ config SPI_ASPEED_SMC
 	depends on HAS_IOMEM && OF
 	depends on HAS_IOMEM && OF
 	help
 	help
 	  This enables support for the Firmware Memory controller (FMC)
 	  This enables support for the Firmware Memory controller (FMC)
-	  in the Aspeed AST2500 SoC when attached to SPI NOR chips,
+	  in the Aspeed AST2500/AST2400 SoCs when attached to SPI NOR chips,
 	  and support for the SPI flash memory controller (SPI) for
 	  and support for the SPI flash memory controller (SPI) for
 	  the host firmware. The implementation only supports SPI NOR.
 	  the host firmware. The implementation only supports SPI NOR.
 
 

+ 33 - 0
drivers/mtd/spi-nor/aspeed-smc.c

@@ -44,8 +44,27 @@ struct aspeed_smc_info {
 	void (*set_4b)(struct aspeed_smc_chip *chip);
 	void (*set_4b)(struct aspeed_smc_chip *chip);
 };
 };
 
 
+static void aspeed_smc_chip_set_4b_spi_2400(struct aspeed_smc_chip *chip);
 static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip);
 static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip);
 
 
+static const struct aspeed_smc_info fmc_2400_info = {
+	.maxsize = 64 * 1024 * 1024,
+	.nce = 5,
+	.hastype = true,
+	.we0 = 16,
+	.ctl0 = 0x10,
+	.set_4b = aspeed_smc_chip_set_4b,
+};
+
+static const struct aspeed_smc_info spi_2400_info = {
+	.maxsize = 64 * 1024 * 1024,
+	.nce = 1,
+	.hastype = false,
+	.we0 = 0,
+	.ctl0 = 0x04,
+	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
+};
+
 static const struct aspeed_smc_info fmc_2500_info = {
 static const struct aspeed_smc_info fmc_2500_info = {
 	.maxsize = 256 * 1024 * 1024,
 	.maxsize = 256 * 1024 * 1024,
 	.nce = 3,
 	.nce = 3,
@@ -135,6 +154,7 @@ struct aspeed_smc_controller {
 #define CONTROL_IO_DUMMY_HI		BIT(14)
 #define CONTROL_IO_DUMMY_HI		BIT(14)
 #define CONTROL_IO_DUMMY_HI_SHIFT	14
 #define CONTROL_IO_DUMMY_HI_SHIFT	14
 #define CONTROL_CLK_DIV4		BIT(13) /* others */
 #define CONTROL_CLK_DIV4		BIT(13) /* others */
+#define CONTROL_IO_ADDRESS_4B		BIT(13) /* AST2400 SPI */
 #define CONTROL_RW_MERGE		BIT(12)
 #define CONTROL_RW_MERGE		BIT(12)
 #define CONTROL_IO_DUMMY_LO_SHIFT	6
 #define CONTROL_IO_DUMMY_LO_SHIFT	6
 #define CONTROL_IO_DUMMY_LO		GENMASK(7, \
 #define CONTROL_IO_DUMMY_LO		GENMASK(7, \
@@ -397,6 +417,8 @@ static int aspeed_smc_remove(struct platform_device *dev)
 }
 }
 
 
 static const struct of_device_id aspeed_smc_matches[] = {
 static const struct of_device_id aspeed_smc_matches[] = {
+	{ .compatible = "aspeed,ast2400-fmc", .data = &fmc_2400_info },
+	{ .compatible = "aspeed,ast2400-spi", .data = &spi_2400_info },
 	{ .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
 	{ .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
 	{ .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
 	{ .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
 	{ }
 	{ }
@@ -470,6 +492,17 @@ static void aspeed_smc_chip_set_4b(struct aspeed_smc_chip *chip)
 	}
 	}
 }
 }
 
 
+/*
+ * The AST2400 SPI flash controller does not have a CE Control
+ * register. It uses the CE0 control register to set 4Byte mode at the
+ * controller level.
+ */
+static void aspeed_smc_chip_set_4b_spi_2400(struct aspeed_smc_chip *chip)
+{
+	chip->ctl_val[smc_base] |= CONTROL_IO_ADDRESS_4B;
+	chip->ctl_val[smc_read] |= CONTROL_IO_ADDRESS_4B;
+}
+
 static int aspeed_smc_chip_setup_init(struct aspeed_smc_chip *chip,
 static int aspeed_smc_chip_setup_init(struct aspeed_smc_chip *chip,
 				      struct resource *res)
 				      struct resource *res)
 {
 {