All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600
@ 2019-09-25 12:42 Cédric Le Goater
  2019-09-25 12:42 ` [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices Cédric Le Goater
                   ` (12 more replies)
  0 siblings, 13 replies; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Hello,

It is based on Brad Bishop series adding the Rainier system system.
The training is still experimental and optimistic. The algorithm might
need some more tuning when systems become available. Quad I/O support
is not implemented.

The Segment Register have a different layout on the AST2600 and the
AHB window of CS other than the first are closed. We will need support
from the firmware or the DT to activate multiple chips on the same
bus.

These driver extensions will not be pushed to mainline.

Thanks,

C.

Cédric Le Goater (13):
  ARM: dts: aspeed-g6: Add FMC and SPI devices
  ARM: dts: aspeed: rainier: Enable FMC and SPI devices
  ARM: dts: aspeed: rainier: Enable MAC0
  ARM: dts: ast2600-evb: Enable FMC and SPI devices
  mtd: spi-nor: Add support for w25q512jv
  mtd: spi-nor: aspeed: Introduce a field for the AHB physical address
  mtd: spi-nor: aspeed: Introduce segment operations
  mtd: spi-nor: aspeed: add initial support for ast2600
  mtd: spi-nor: aspeed: Check for disabled segments on the AST2600
  mtd: spi-nor: aspeed: Introduce training operations per platform
  mtd: spi-nor: aspeed: Introduce a HCLK mask for training
  mtd: spi-nor: aspeed: check upper freq limit when doing training
  mtd: spi-nor: aspeed: add support for AST2600 training

 drivers/mtd/spi-nor/aspeed-smc.c             | 283 ++++++++++++++++---
 drivers/mtd/spi-nor/spi-nor.c                |   2 +
 arch/arm/boot/dts/aspeed-ast2600-evb.dts     |  24 ++
 arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts |  38 +++
 arch/arm/boot/dts/aspeed-g6.dtsi             |  79 ++++++
 5 files changed, 385 insertions(+), 41 deletions(-)

-- 
2.21.0

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:27   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable " Cédric Le Goater
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/arm/boot/dts/aspeed-g6.dtsi | 79 ++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index b4991cbe1f36..e8c335416da8 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -80,6 +80,85 @@
 			    <0x40466000 0x2000>;
 			};
 
+		fmc: spi@1e620000 {
+			reg = < 0x1e620000 0xc4
+				0x20000000 0x10000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2600-fmc";
+			clocks = <&syscon ASPEED_CLK_AHB>;
+			status = "disabled";
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+			flash@0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+			flash@1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+			flash@2 {
+				reg = < 2 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+		};
+
+		spi1: spi@1e630000 {
+			reg = < 0x1e630000 0xc4
+				0x30000000 0x10000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2600-spi";
+			clocks = <&syscon ASPEED_CLK_AHB>;
+			status = "disabled";
+			flash@0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+			flash@1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+		};
+
+		spi2: spi@1e631000 {
+			reg = < 0x1e631000 0xc4
+				0x50000000 0x10000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2600-spi";
+			clocks = <&syscon ASPEED_CLK_AHB>;
+			status = "disabled";
+			flash@0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+			flash@1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+			flash@2 {
+				reg = < 2 >;
+				compatible = "jedec,spi-nor";
+				spi-max-frequency = <50000000>;
+				status = "disabled";
+			};
+		};
+
 		mdio0: mdio@1e650000 {
 			compatible = "aspeed,ast2600-mdio";
 			reg = <0x1e650000 0x8>;
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable FMC and SPI devices
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
  2019-09-25 12:42 ` [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:34   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0 Cédric Le Goater
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts | 31 ++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
index 485c8732eec1..5e5bc78bdce4 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
@@ -444,3 +444,34 @@
 &ibt {
 	status = "okay";
 };
+
+&fmc {
+	status = "okay";
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+		spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout.dtsi"
+	};
+
+	flash@1 {
+		status = "okay";
+		m25p,fast-read;
+		label = "alt-bmc";
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "pnor";
+		spi-max-frequency = <100000000>;
+	};
+};
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
  2019-09-25 12:42 ` [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices Cédric Le Goater
  2019-09-25 12:42 ` [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable " Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:19   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices Cédric Le Goater
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
index 5e5bc78bdce4..713dc64064ad 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
@@ -475,3 +475,10 @@
 		spi-max-frequency = <100000000>;
 	};
 };
+
+&mac0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii1_default>;
+};
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (2 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0 Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:38   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv Cédric Le Goater
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/arm/boot/dts/aspeed-ast2600-evb.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
index da8c931c7295..7bcafb027afa 100644
--- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts
+++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
@@ -88,3 +88,27 @@
 &fsim0 {
 	status = "okay";
 };
+
+&fmc {
+	status = "okay";
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+		spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout.dtsi"
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "pnor";
+		spi-max-frequency = <100000000>;
+	};
+};
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (3 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:42   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address Cédric Le Goater
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/spi-nor.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0034e7751239..ff6b719fd267 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2151,6 +2151,8 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
 	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
 	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 	{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
 			SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
 
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (4 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  1:59   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations Cédric Le Goater
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

On the AST2600, we will use it to compute the address of the chip AHB
window from the Segment Register value. It also removes the need of
aspeed_smc_ahb_base_phy() helper.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 1cc89c965687..b3a128ada320 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -121,7 +121,8 @@ struct aspeed_smc_controller {
 	struct mutex mutex;			/* controller access mutex */
 	const struct aspeed_smc_info *info;	/* type info of controller */
 	void __iomem *regs;			/* controller registers */
-	void __iomem *ahb_base;			/* per-chip windows resource */
+	void __iomem *ahb_base;			/* per-chip window resource */
+	u32 ahb_base_phy;			/* phys addr of AHB window  */
 	u32 ahb_window_size;			/* full mapping window size */
 
 	unsigned long	clk_frequency;
@@ -533,21 +534,13 @@ static void __iomem *aspeed_smc_chip_base(struct aspeed_smc_chip *chip,
 	return controller->ahb_base + offset;
 }
 
-static u32 aspeed_smc_ahb_base_phy(struct aspeed_smc_controller *controller)
-{
-	u32 seg0_val = readl(SEGMENT_ADDR_REG(controller, 0));
-
-	return SEGMENT_ADDR_START(seg0_val);
-}
-
 static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 			    u32 size)
 {
 	struct aspeed_smc_controller *controller = chip->controller;
 	void __iomem *seg_reg;
-	u32 seg_oldval, seg_newval, ahb_base_phy, end;
-
-	ahb_base_phy = aspeed_smc_ahb_base_phy(controller);
+	u32 seg_oldval, seg_newval, end;
+	u32 ahb_base_phy = controller->ahb_base_phy;
 
 	seg_reg = SEGMENT_ADDR_REG(controller, cs);
 	seg_oldval = readl(seg_reg);
@@ -636,7 +629,7 @@ static u32 aspeed_smc_chip_set_segment(struct aspeed_smc_chip *chip)
 			 chip->cs, size >> 20);
 	}
 
-	ahb_base_phy = aspeed_smc_ahb_base_phy(controller);
+	ahb_base_phy = controller->ahb_base_phy;
 
 	/*
 	 * As a start address for the current segment, use the default
@@ -1154,6 +1147,7 @@ static int aspeed_smc_probe(struct platform_device *pdev)
 		return PTR_ERR(controller->regs);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	controller->ahb_base_phy = res->start;
 	controller->ahb_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(controller->ahb_base))
 		return PTR_ERR(controller->ahb_base);
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (5 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:00   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600 Cédric Le Goater
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

AST2600 will use a different encoding for the addresses defined in the
Segment Register.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 76 +++++++++++++++++++++++---------
 1 file changed, 56 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index b3a128ada320..4e768092a965 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -32,6 +32,7 @@ enum aspeed_smc_flash_type {
 };
 
 struct aspeed_smc_chip;
+struct aspeed_smc_controller;
 
 struct aspeed_smc_info {
 	u32 maxsize;		/* maximum size of chip window */
@@ -43,12 +44,22 @@ struct aspeed_smc_info {
 
 	void (*set_4b)(struct aspeed_smc_chip *chip);
 	int (*optimize_read)(struct aspeed_smc_chip *chip, u32 max_freq);
+	u32 (*segment_start)(struct aspeed_smc_controller *controller, u32 reg);
+	u32 (*segment_end)(struct aspeed_smc_controller *controller, u32 reg);
+	u32 (*segment_reg)(struct aspeed_smc_controller *controller,
+			   u32 start, u32 end);
 };
 
 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 int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 				     u32 max_freq);
+static u32 aspeed_smc_segment_start(
+	struct aspeed_smc_controller *controller, u32 reg);
+static u32 aspeed_smc_segment_end(
+	struct aspeed_smc_controller *controller, u32 reg);
+static u32 aspeed_smc_segment_reg(
+	struct aspeed_smc_controller *controller, u32 start, u32 end);
 
 static const struct aspeed_smc_info fmc_2400_info = {
 	.maxsize = 64 * 1024 * 1024,
@@ -59,6 +70,9 @@ static const struct aspeed_smc_info fmc_2400_info = {
 	.timing = 0x94,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.segment_start = aspeed_smc_segment_start,
+	.segment_end = aspeed_smc_segment_end,
+	.segment_reg = aspeed_smc_segment_reg,
 };
 
 static const struct aspeed_smc_info spi_2400_info = {
@@ -70,6 +84,7 @@ static const struct aspeed_smc_info spi_2400_info = {
 	.timing = 0x14,
 	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
 	.optimize_read = aspeed_smc_optimize_read,
+	/* No segment registers */
 };
 
 static const struct aspeed_smc_info fmc_2500_info = {
@@ -81,6 +96,9 @@ static const struct aspeed_smc_info fmc_2500_info = {
 	.timing = 0x94,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.segment_start = aspeed_smc_segment_start,
+	.segment_end = aspeed_smc_segment_end,
+	.segment_reg = aspeed_smc_segment_reg,
 };
 
 static const struct aspeed_smc_info spi_2500_info = {
@@ -92,6 +110,9 @@ static const struct aspeed_smc_info spi_2500_info = {
 	.timing = 0x94,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.segment_start = aspeed_smc_segment_start,
+	.segment_end = aspeed_smc_segment_end,
+	.segment_reg = aspeed_smc_segment_reg,
 };
 
 enum aspeed_smc_ctl_reg_value {
@@ -201,22 +222,33 @@ struct aspeed_smc_controller {
 	(CONTROL_AAF_MODE | CONTROL_CE_INACTIVE_MASK | CONTROL_CLK_DIV4 | \
 	 CONTROL_CLOCK_FREQ_SEL_MASK | CONTROL_LSB_FIRST | CONTROL_CLOCK_MODE_3)
 
-/*
- * The Segment Register uses a 8MB unit to encode the start address
- * and the end address of the mapping window of a flash SPI slave :
- *
- *        | byte 1 | byte 2 | byte 3 | byte 4 |
- *        +--------+--------+--------+--------+
- *        |  end   |  start |   0    |   0    |
- */
 #define SEGMENT_ADDR_REG0		0x30
-#define SEGMENT_ADDR_START(_r)		((((_r) >> 16) & 0xFF) << 23)
-#define SEGMENT_ADDR_END(_r)		((((_r) >> 24) & 0xFF) << 23)
-#define SEGMENT_ADDR_VALUE(start, end)					\
-	(((((start) >> 23) & 0xFF) << 16) | ((((end) >> 23) & 0xFF) << 24))
 #define SEGMENT_ADDR_REG(controller, cs)	\
 	((controller)->regs + SEGMENT_ADDR_REG0 + (cs) * 4)
 
+/*
+ * The Segment Registers of the AST2400 and AST2500 have a 8MB
+ * unit. The address range of a flash SPI slave is encoded with
+ * absolute addresses which should be part of the overall controller
+ * window.
+ */
+static u32 aspeed_smc_segment_start(
+	struct aspeed_smc_controller *controller, u32 reg)
+{
+	return ((reg >> 16) & 0xFF) << 23;
+}
+
+static u32 aspeed_smc_segment_end(
+	struct aspeed_smc_controller *controller, u32 reg)
+{
+	return ((reg >> 24) & 0xFF) << 23;
+}
+
+static u32 aspeed_smc_segment_reg(
+	struct aspeed_smc_controller *controller, u32 start, u32 end)
+{
+	return (((start >> 23) & 0xFF) << 16) | (((end >> 23) & 0xFF) << 24);
+}
 /*
  * Switch to turn off read optimisation if needed
  */
@@ -519,16 +551,19 @@ static void __iomem *aspeed_smc_chip_base(struct aspeed_smc_chip *chip,
 					  struct resource *res)
 {
 	struct aspeed_smc_controller *controller = chip->controller;
+	const struct aspeed_smc_info *info = controller->info;
 	u32 offset = 0;
 	u32 reg;
 
-	if (controller->info->nce > 1) {
+	if (info->nce > 1) {
 		reg = readl(SEGMENT_ADDR_REG(controller, chip->cs));
 
-		if (SEGMENT_ADDR_START(reg) >= SEGMENT_ADDR_END(reg))
+		if (info->segment_start(controller, reg) >=
+		    info->segment_end(controller, reg)) {
 			return NULL;
+		}
 
-		offset = SEGMENT_ADDR_START(reg) - res->start;
+		offset = info->segment_start(controller, reg) - res->start;
 	}
 
 	return controller->ahb_base + offset;
@@ -538,6 +573,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 			    u32 size)
 {
 	struct aspeed_smc_controller *controller = chip->controller;
+	const struct aspeed_smc_info *info = controller->info;
 	void __iomem *seg_reg;
 	u32 seg_oldval, seg_newval, end;
 	u32 ahb_base_phy = controller->ahb_base_phy;
@@ -551,7 +587,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 	 * previous segment
 	 */
 	if (!size)
-		size = SEGMENT_ADDR_END(seg_oldval) - start;
+		size = info->segment_end(controller, seg_oldval) - start;
 
 	/*
 	 * The segment cannot exceed the maximum window size of the
@@ -564,7 +600,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 	}
 
 	end = start + size;
-	seg_newval = SEGMENT_ADDR_VALUE(start, end);
+	seg_newval = info->segment_reg(controller, start, end);
 	writel(seg_newval, seg_reg);
 
 	/*
@@ -575,8 +611,8 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 	if (seg_newval != readl(seg_reg)) {
 		dev_err(chip->nor.dev, "CE%d window invalid", cs);
 		writel(seg_oldval, seg_reg);
-		start = SEGMENT_ADDR_START(seg_oldval);
-		end = SEGMENT_ADDR_END(seg_oldval);
+		start = info->segment_start(controller, seg_oldval);
+		end = info->segment_end(controller, seg_oldval);
 		size = end - start;
 	}
 
@@ -639,7 +675,7 @@ static u32 aspeed_smc_chip_set_segment(struct aspeed_smc_chip *chip)
 	if (chip->cs) {
 		u32 prev = readl(SEGMENT_ADDR_REG(controller, chip->cs - 1));
 
-		start = SEGMENT_ADDR_END(prev);
+		start = controller->info->segment_end(controller, prev);
 	} else {
 		start = ahb_base_phy;
 	}
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (6 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:00   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600 Cédric Le Goater
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

The Segment Registers of the AST2600 have a different encoding. A 1MB
unit is used and the address range of a flash SPI slave is encoded
with offsets in the overall controller window. The previous SoC
AST2400 and AST2500 used absolute addresses. Only bits [27:20] are
relevant and the end address is an upper bound limit.

SPI training yet to come.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 73 ++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 4e768092a965..6c5ecea21882 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -115,6 +115,39 @@ static const struct aspeed_smc_info spi_2500_info = {
 	.segment_reg = aspeed_smc_segment_reg,
 };
 
+static u32 aspeed_smc_segment_start_ast2600(
+	struct aspeed_smc_controller *controller, u32 reg);
+static u32 aspeed_smc_segment_end_ast2600(
+	struct aspeed_smc_controller *controller, u32 reg);
+static u32 aspeed_smc_segment_reg_ast2600(
+	struct aspeed_smc_controller *controller, u32 start, u32 end);
+
+static const struct aspeed_smc_info fmc_2600_info = {
+	.maxsize = 256 * 1024 * 1024,
+	.nce = 3,
+	.hastype = false, /* SPI Only */
+	.we0 = 16,
+	.ctl0 = 0x10,
+	.timing = 0x94,
+	.set_4b = aspeed_smc_chip_set_4b,
+	.segment_start = aspeed_smc_segment_start_ast2600,
+	.segment_end = aspeed_smc_segment_end_ast2600,
+	.segment_reg = aspeed_smc_segment_reg_ast2600,
+};
+
+static const struct aspeed_smc_info spi_2600_info = {
+	.maxsize = 256 * 1024 * 1024,
+	.nce = 2,
+	.hastype = false,
+	.we0 = 16,
+	.ctl0 = 0x10,
+	.timing = 0x94,
+	.set_4b = aspeed_smc_chip_set_4b,
+	.segment_start = aspeed_smc_segment_start_ast2600,
+	.segment_end = aspeed_smc_segment_end_ast2600,
+	.segment_reg = aspeed_smc_segment_reg_ast2600,
+};
+
 enum aspeed_smc_ctl_reg_value {
 	smc_base,		/* base value without mode for other commands */
 	smc_read,		/* command reg for (maybe fast) reads */
@@ -249,6 +282,44 @@ static u32 aspeed_smc_segment_reg(
 {
 	return (((start >> 23) & 0xFF) << 16) | (((end >> 23) & 0xFF) << 24);
 }
+
+/*
+ * The Segment Registers of the AST2600 have a 1MB unit. The address
+ * range of a flash SPI slave is encoded with offsets in the overall
+ * controller window. The previous SoC AST2400 and AST2500 used
+ * absolute addresses. Only bits [27:20] are relevant and the end
+ * address is an upper bound limit.
+ */
+
+#define AST2600_SEG_ADDR_MASK 0x0ff00000
+
+static u32 aspeed_smc_segment_start_ast2600(
+	struct aspeed_smc_controller *controller, u32 reg)
+{
+	uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
+
+	return controller->ahb_base_phy + start_offset;
+}
+
+static u32 aspeed_smc_segment_end_ast2600(
+	struct aspeed_smc_controller *controller, u32 reg)
+{
+	uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
+
+	/* segment is disabled */
+	if (!end_offset)
+		return controller->ahb_base_phy;
+
+	return controller->ahb_base_phy + end_offset + 0x100000;
+}
+
+static u32 aspeed_smc_segment_reg_ast2600(
+	struct aspeed_smc_controller *controller, u32 start, u32 end)
+{
+    return ((start & AST2600_SEG_ADDR_MASK) >> 16) |
+	    ((end - 1) & AST2600_SEG_ADDR_MASK);
+}
+
 /*
  * Switch to turn off read optimisation if needed
  */
@@ -536,6 +607,8 @@ static const struct of_device_id aspeed_smc_matches[] = {
 	{ .compatible = "aspeed,ast2400-spi", .data = &spi_2400_info },
 	{ .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
 	{ .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
+	{ .compatible = "aspeed,ast2600-fmc", .data = &fmc_2600_info },
+	{ .compatible = "aspeed,ast2600-spi", .data = &spi_2600_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, aspeed_smc_matches);
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (7 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600 Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:01   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform Cédric Le Goater
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

The segments can be disabled on the AST2600 (zero register value).
CS0 is open by default but not the other CS. This is closing the
access to the flash device in user mode and forbids scanning. For
multiple CS, we will need firmware or a DT property to reopen the
flash AHB window.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 6c5ecea21882..ea9b4a157677 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -659,8 +659,15 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 	 * size, but take into account the possible overlap with the
 	 * previous segment
 	 */
-	if (!size)
-		size = info->segment_end(controller, seg_oldval) - start;
+	if (!size) {
+		end = info->segment_end(controller, seg_oldval);
+
+		/*
+		 * Check for disabled segment (AST2600).
+		 */
+		if (end != ahb_base_phy)
+			size = end - start;
+	}
 
 	/*
 	 * The segment cannot exceed the maximum window size of the
@@ -689,8 +696,8 @@ static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
 		size = end - start;
 	}
 
-	dev_info(chip->nor.dev, "CE%d window [ 0x%.8x - 0x%.8x ] %dMB",
-		 cs, start, end, size >> 20);
+	dev_info(chip->nor.dev, "CE%d window [ 0x%.8x - 0x%.8x ] %dMB%s",
+		 cs, start, end, size >> 20, size ? "" : " (disabled)");
 
 	return size;
 }
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (8 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600 Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:03   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training Cédric Le Goater
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

The read timing compensation register is different on the AST2600 and
training will be slightly more complex.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index ea9b4a157677..768394068bd4 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -41,9 +41,13 @@ struct aspeed_smc_info {
 	u8 we0;			/* shift for write enable bit for CE0 */
 	u8 ctl0;		/* offset in regs of ctl for CE0 */
 	u8 timing;		/* offset in regs of timing */
+	u32 hdiv_max;           /* Max HCLK divisor on read timing reg */
 
 	void (*set_4b)(struct aspeed_smc_chip *chip);
 	int (*optimize_read)(struct aspeed_smc_chip *chip, u32 max_freq);
+	int (*calibrate)(struct aspeed_smc_chip *chip, u32 hdiv,
+			 const u8 *golden_buf, u8 *test_buf);
+
 	u32 (*segment_start)(struct aspeed_smc_controller *controller, u32 reg);
 	u32 (*segment_end)(struct aspeed_smc_controller *controller, u32 reg);
 	u32 (*segment_reg)(struct aspeed_smc_controller *controller,
@@ -54,6 +58,9 @@ 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 int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 				     u32 max_freq);
+static int aspeed_smc_calibrate_reads(struct aspeed_smc_chip *chip, u32 hdiv,
+			 const u8 *golden_buf, u8 *test_buf);
+
 static u32 aspeed_smc_segment_start(
 	struct aspeed_smc_controller *controller, u32 reg);
 static u32 aspeed_smc_segment_end(
@@ -68,8 +75,10 @@ static const struct aspeed_smc_info fmc_2400_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads,
 	.segment_start = aspeed_smc_segment_start,
 	.segment_end = aspeed_smc_segment_end,
 	.segment_reg = aspeed_smc_segment_reg,
@@ -82,8 +91,10 @@ static const struct aspeed_smc_info spi_2400_info = {
 	.we0 = 0,
 	.ctl0 = 0x04,
 	.timing = 0x14,
+	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
 	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads,
 	/* No segment registers */
 };
 
@@ -94,8 +105,10 @@ static const struct aspeed_smc_info fmc_2500_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads,
 	.segment_start = aspeed_smc_segment_start,
 	.segment_end = aspeed_smc_segment_end,
 	.segment_reg = aspeed_smc_segment_reg,
@@ -108,8 +121,10 @@ static const struct aspeed_smc_info spi_2500_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads,
 	.segment_start = aspeed_smc_segment_start,
 	.segment_end = aspeed_smc_segment_end,
 	.segment_reg = aspeed_smc_segment_reg,
@@ -984,7 +999,8 @@ static const uint32_t aspeed_smc_hclk_divs[] = {
 	0x6, /* HCLK/4 */
 	0xd, /* HCLK/5 */
 };
-#define ASPEED_SMC_HCLK_DIV(i) (aspeed_smc_hclk_divs[(i) - 1] << 8)
+#define ASPEED_SMC_HCLK_DIV(i) \
+	(aspeed_smc_hclk_divs[(i) - 1] << CONTROL_CLOCK_FREQ_SEL_SHIFT)
 
 static u32 aspeed_smc_default_read(struct aspeed_smc_chip *chip)
 {
@@ -1015,6 +1031,8 @@ static u32 aspeed_smc_default_read(struct aspeed_smc_chip *chip)
 static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 				     u32 max_freq)
 {
+	struct aspeed_smc_controller *controller = chip->controller;
+	const struct aspeed_smc_info *info = controller->info;
 	u8 *golden_buf, *test_buf;
 	int i, rc, best_div = -1;
 	u32 save_read_val = chip->ctl_val[smc_read];
@@ -1047,7 +1065,7 @@ static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 	}
 
 	/* Now we iterate the HCLK dividers until we find our breaking point */
-	for (i = ARRAY_SIZE(aspeed_smc_hclk_divs); i > 0; i--) {
+	for (i = ARRAY_SIZE(aspeed_smc_hclk_divs); i > info->hdiv_max - 1; i--) {
 		u32 tv, freq;
 
 		/* Compare timing to max */
@@ -1058,8 +1076,8 @@ static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 		/* Set the timing */
 		tv = chip->ctl_val[smc_read] | ASPEED_SMC_HCLK_DIV(i);
 		writel(tv, chip->ctl);
-		dev_dbg(chip->nor.dev, "Trying HCLK/%d...", i);
-		rc = aspeed_smc_calibrate_reads(chip, i, golden_buf, test_buf);
+		dev_dbg(chip->nor.dev, "Trying HCLK/%d [%08x] ...", i, tv);
+		rc = info->calibrate(chip, i, golden_buf, test_buf);
 		if (rc == 0)
 			best_div = i;
 	}
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (9 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:10   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training Cédric Le Goater
  2019-09-25 12:42 ` [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training Cédric Le Goater
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

The AST2600 handles more HCLK divisors than its predecessors.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 768394068bd4..c6a80fdf51ef 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -41,6 +41,7 @@ struct aspeed_smc_info {
 	u8 we0;			/* shift for write enable bit for CE0 */
 	u8 ctl0;		/* offset in regs of ctl for CE0 */
 	u8 timing;		/* offset in regs of timing */
+	u32 hclk_mask;          /* clock frequency mask in CEx Control reg */
 	u32 hdiv_max;           /* Max HCLK divisor on read timing reg */
 
 	void (*set_4b)(struct aspeed_smc_chip *chip);
@@ -75,6 +76,7 @@ static const struct aspeed_smc_info fmc_2400_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hclk_mask = 0xfffff0ff,
 	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
@@ -91,6 +93,7 @@ static const struct aspeed_smc_info spi_2400_info = {
 	.we0 = 0,
 	.ctl0 = 0x04,
 	.timing = 0x14,
+	.hclk_mask = 0xfffff0ff,
 	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
 	.optimize_read = aspeed_smc_optimize_read,
@@ -105,6 +108,7 @@ static const struct aspeed_smc_info fmc_2500_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hclk_mask = 0xfffff0ff,
 	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
@@ -121,6 +125,7 @@ static const struct aspeed_smc_info spi_2500_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hclk_mask = 0xfffff0ff,
 	.hdiv_max = 1,
 	.set_4b = aspeed_smc_chip_set_4b,
 	.optimize_read = aspeed_smc_optimize_read,
@@ -1053,7 +1058,7 @@ static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 	memcpy_fromio(golden_buf, chip->ahb_base, CALIBRATE_BUF_SIZE);
 
 	/* Establish our read mode with freq field set to 0 (HCLK/16) */
-	chip->ctl_val[smc_read] = save_read_val & 0xfffff0ff;
+	chip->ctl_val[smc_read] = save_read_val & info->hclk_mask;
 
 	/* Check if calibration data is suitable */
 	if (!aspeed_smc_check_calib_data(golden_buf, CALIBRATE_BUF_SIZE)) {
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (10 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:12   ` Andrew Jeffery
  2019-09-25 12:42 ` [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training Cédric Le Goater
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index c6a80fdf51ef..48164d819a37 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -1075,7 +1075,7 @@ static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 
 		/* Compare timing to max */
 		freq = ahb_freq / i;
-		if (freq >= max_freq)
+		if (freq > max_freq)
 			continue;
 
 		/* Set the timing */
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training
  2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
                   ` (11 preceding siblings ...)
  2019-09-25 12:42 ` [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training Cédric Le Goater
@ 2019-09-25 12:42 ` Cédric Le Goater
  2019-09-26  2:14   ` Andrew Jeffery
  12 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:42 UTC (permalink / raw)
  To: openbmc; +Cc: Joel Stanley, Andrew Jeffery, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 drivers/mtd/spi-nor/aspeed-smc.c | 68 ++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
index 48164d819a37..e9bc89755912 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -142,6 +142,9 @@ static u32 aspeed_smc_segment_end_ast2600(
 static u32 aspeed_smc_segment_reg_ast2600(
 	struct aspeed_smc_controller *controller, u32 start, u32 end);
 
+static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip *chip,
+	      u32 hdiv, const u8 *golden_buf, u8 *test_buf);
+
 static const struct aspeed_smc_info fmc_2600_info = {
 	.maxsize = 256 * 1024 * 1024,
 	.nce = 3,
@@ -149,7 +152,11 @@ static const struct aspeed_smc_info fmc_2600_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hclk_mask = 0xf0fff0ff,
+	.hdiv_max = 2,
 	.set_4b = aspeed_smc_chip_set_4b,
+	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads_ast2600,
 	.segment_start = aspeed_smc_segment_start_ast2600,
 	.segment_end = aspeed_smc_segment_end_ast2600,
 	.segment_reg = aspeed_smc_segment_reg_ast2600,
@@ -162,7 +169,11 @@ static const struct aspeed_smc_info spi_2600_info = {
 	.we0 = 16,
 	.ctl0 = 0x10,
 	.timing = 0x94,
+	.hclk_mask = 0xf0fff0ff,
+	.hdiv_max = 2,
 	.set_4b = aspeed_smc_chip_set_4b,
+	.optimize_read = aspeed_smc_optimize_read,
+	.calibrate = aspeed_smc_calibrate_reads_ast2600,
 	.segment_start = aspeed_smc_segment_start_ast2600,
 	.segment_end = aspeed_smc_segment_end_ast2600,
 	.segment_reg = aspeed_smc_segment_reg_ast2600,
@@ -1101,6 +1112,63 @@ static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
 	return 0;
 }
 
+#define TIMING_DELAY_DI         BIT(3)
+#define TIMING_DELAY_HCYCLE_MAX     5
+
+static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip *chip, u32 hdiv,
+					      const u8 *golden_buf, u8 *test_buf)
+{
+	struct aspeed_smc_controller *controller = chip->controller;
+	const struct aspeed_smc_info *info = controller->info;
+	int hcycle;
+	u32 shift = (hdiv - 2) << 3;
+	u32 mask = ~(0xfu << shift);
+	u32 fread_timing_val = 0;
+
+	for (hcycle = 0; hcycle <= TIMING_DELAY_HCYCLE_MAX; hcycle++) {
+		int delay_ns;
+		bool pass = false;
+
+		fread_timing_val &= mask;
+		fread_timing_val |= hcycle << shift;
+
+		/* no DI input delay first  */
+		writel(fread_timing_val, controller->regs + info->timing);
+		pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
+		dev_dbg(chip->nor.dev,
+			"  * [%08x] %d HCLK delay, DI delay none : %s",
+			fread_timing_val, hcycle, pass ? "PASS" : "FAIL");
+		if (pass)
+			return 0;
+
+		/* Add DI input delays  */
+		fread_timing_val &= mask;
+		fread_timing_val |= (TIMING_DELAY_DI | hcycle) << shift;
+
+		for (delay_ns = 0; delay_ns < 0x10; delay_ns++) {
+			fread_timing_val &= ~(0xf << (4 + shift));
+			fread_timing_val |= delay_ns << (4 + shift);
+
+			writel(fread_timing_val, controller->regs + info->timing);
+			pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
+			dev_dbg(chip->nor.dev,
+				"  * [%08x] %d HCLK delay, DI delay %d.%dns : %s",
+				fread_timing_val, hcycle, (delay_ns + 1)/2,
+				(delay_ns + 1) & 1 ? 5 : 5, pass ? "PASS" : "FAIL");
+			/*
+			 * TODO: This is optimistic. We should look
+			 * for a working interval and save the middle
+			 * value in the read timing register.
+			 */
+			if (pass)
+				return 0;
+		}
+	}
+
+	/* No good setting for this frequency */
+	return -1;
+}
+
 static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
 {
 	struct aspeed_smc_controller *controller = chip->controller;
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0
  2019-09-25 12:42 ` [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0 Cédric Le Goater
@ 2019-09-26  1:19   ` Andrew Jeffery
  2019-09-26  5:55     ` Cédric Le Goater
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:19 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts 
> b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> index 5e5bc78bdce4..713dc64064ad 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> @@ -475,3 +475,10 @@
>  		spi-max-frequency = <100000000>;
>  	};
>  };
> +
> +&mac0 {
> +	status = "okay";
> +
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rmii1_default>;

This looks like a shortcut to aid development under qemu?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices
  2019-09-25 12:42 ` [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices Cédric Le Goater
@ 2019-09-26  1:27   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:27 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  arch/arm/boot/dts/aspeed-g6.dtsi | 79 ++++++++++++++++++++++++++++++++
>  1 file changed, 79 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
> index b4991cbe1f36..e8c335416da8 100644
> --- a/arch/arm/boot/dts/aspeed-g6.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g6.dtsi
> @@ -80,6 +80,85 @@
>  			    <0x40466000 0x2000>;
>  			};
>  
> +		fmc: spi@1e620000 {
> +			reg = < 0x1e620000 0xc4
> +				0x20000000 0x10000000 >;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "aspeed,ast2600-fmc";
> +			clocks = <&syscon ASPEED_CLK_AHB>;
> +			status = "disabled";
> +			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> +			flash@0 {
> +				reg = < 0 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +			flash@1 {
> +				reg = < 1 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +			flash@2 {
> +				reg = < 2 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +		};
> +
> +		spi1: spi@1e630000 {
> +			reg = < 0x1e630000 0xc4
> +				0x30000000 0x10000000 >;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "aspeed,ast2600-spi";
> +			clocks = <&syscon ASPEED_CLK_AHB>;
> +			status = "disabled";
> +			flash@0 {
> +				reg = < 0 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +			flash@1 {
> +				reg = < 1 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +		};
> +
> +		spi2: spi@1e631000 {
> +			reg = < 0x1e631000 0xc4
> +				0x50000000 0x10000000 >;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "aspeed,ast2600-spi";
> +			clocks = <&syscon ASPEED_CLK_AHB>;
> +			status = "disabled";
> +			flash@0 {
> +				reg = < 0 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +			flash@1 {
> +				reg = < 1 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +			flash@2 {
> +				reg = < 2 >;
> +				compatible = "jedec,spi-nor";
> +				spi-max-frequency = <50000000>;
> +				status = "disabled";
> +			};
> +		};
> +
>  		mdio0: mdio@1e650000 {
>  			compatible = "aspeed,ast2600-mdio";
>  			reg = <0x1e650000 0x8>;
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable FMC and SPI devices
  2019-09-25 12:42 ` [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable " Cédric Le Goater
@ 2019-09-26  1:34   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:34 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Acked-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts | 31 ++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts 
> b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> index 485c8732eec1..5e5bc78bdce4 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
> @@ -444,3 +444,34 @@
>  &ibt {
>  	status = "okay";
>  };
> +
> +&fmc {
> +	status = "okay";
> +	flash@0 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "bmc";
> +		spi-max-frequency = <50000000>;
> +#include "openbmc-flash-layout.dtsi"
> +	};
> +
> +	flash@1 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "alt-bmc";
> +		spi-max-frequency = <50000000>;
> +	};
> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_spi1_default>;
> +
> +	flash@0 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "pnor";
> +		spi-max-frequency = <100000000>;
> +	};
> +};
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices
  2019-09-25 12:42 ` [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices Cédric Le Goater
@ 2019-09-26  1:38   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:38 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Acked-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  arch/arm/boot/dts/aspeed-ast2600-evb.dts | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts 
> b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
> index da8c931c7295..7bcafb027afa 100644
> --- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts
> +++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
> @@ -88,3 +88,27 @@
>  &fsim0 {
>  	status = "okay";
>  };
> +
> +&fmc {
> +	status = "okay";
> +	flash@0 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "bmc";
> +		spi-max-frequency = <50000000>;
> +#include "openbmc-flash-layout.dtsi"
> +	};
> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_spi1_default>;
> +
> +	flash@0 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "pnor";
> +		spi-max-frequency = <100000000>;
> +	};
> +};
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv
  2019-09-25 12:42 ` [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv Cédric Le Goater
@ 2019-09-26  1:42   ` Andrew Jeffery
  2019-09-26  3:53     ` Joel Stanley
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:42 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c 
> b/drivers/mtd/spi-nor/spi-nor.c
> index 0034e7751239..ff6b719fd267 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -2151,6 +2151,8 @@ static const struct flash_info spi_nor_ids[] = {
>  	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
>  	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
>  	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | 
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, SECT_4K | 
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
>  	{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
>  			SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
>  
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address
  2019-09-25 12:42 ` [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address Cédric Le Goater
@ 2019-09-26  1:59   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  1:59 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> On the AST2600, we will use it to compute the address of the chip AHB
> window from the Segment Register value. It also removes the need of
> aspeed_smc_ahb_base_phy() helper.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 18 ++++++------------
>  1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index 1cc89c965687..b3a128ada320 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -121,7 +121,8 @@ struct aspeed_smc_controller {
>  	struct mutex mutex;			/* controller access mutex */
>  	const struct aspeed_smc_info *info;	/* type info of controller */
>  	void __iomem *regs;			/* controller registers */
> -	void __iomem *ahb_base;			/* per-chip windows resource */
> +	void __iomem *ahb_base;			/* per-chip window resource */
> +	u32 ahb_base_phy;			/* phys addr of AHB window  */
>  	u32 ahb_window_size;			/* full mapping window size */
>  
>  	unsigned long	clk_frequency;
> @@ -533,21 +534,13 @@ static void __iomem *aspeed_smc_chip_base(struct 
> aspeed_smc_chip *chip,
>  	return controller->ahb_base + offset;
>  }
>  
> -static u32 aspeed_smc_ahb_base_phy(struct aspeed_smc_controller *controller)
> -{
> -	u32 seg0_val = readl(SEGMENT_ADDR_REG(controller, 0));
> -
> -	return SEGMENT_ADDR_START(seg0_val);
> -}
> -
>  static u32 chip_set_segment(struct aspeed_smc_chip *chip, u32 cs, u32 start,
>  			    u32 size)
>  {
>  	struct aspeed_smc_controller *controller = chip->controller;
>  	void __iomem *seg_reg;
> -	u32 seg_oldval, seg_newval, ahb_base_phy, end;
> -
> -	ahb_base_phy = aspeed_smc_ahb_base_phy(controller);
> +	u32 seg_oldval, seg_newval, end;
> +	u32 ahb_base_phy = controller->ahb_base_phy;
>  
>  	seg_reg = SEGMENT_ADDR_REG(controller, cs);
>  	seg_oldval = readl(seg_reg);
> @@ -636,7 +629,7 @@ static u32 aspeed_smc_chip_set_segment(struct 
> aspeed_smc_chip *chip)
>  			 chip->cs, size >> 20);
>  	}
>  
> -	ahb_base_phy = aspeed_smc_ahb_base_phy(controller);
> +	ahb_base_phy = controller->ahb_base_phy;
>  
>  	/*
>  	 * As a start address for the current segment, use the default
> @@ -1154,6 +1147,7 @@ static int aspeed_smc_probe(struct platform_device *pdev)
>  		return PTR_ERR(controller->regs);
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	controller->ahb_base_phy = res->start;
>  	controller->ahb_base = devm_ioremap_resource(dev, res);
>  	if (IS_ERR(controller->ahb_base))
>  		return PTR_ERR(controller->ahb_base);
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations
  2019-09-25 12:42 ` [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations Cédric Le Goater
@ 2019-09-26  2:00   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:00 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> AST2600 will use a different encoding for the addresses defined in the
> Segment Register.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 76 +++++++++++++++++++++++---------
>  1 file changed, 56 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index b3a128ada320..4e768092a965 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -32,6 +32,7 @@ enum aspeed_smc_flash_type {
>  };
>  
>  struct aspeed_smc_chip;
> +struct aspeed_smc_controller;
>  
>  struct aspeed_smc_info {
>  	u32 maxsize;		/* maximum size of chip window */
> @@ -43,12 +44,22 @@ struct aspeed_smc_info {
>  
>  	void (*set_4b)(struct aspeed_smc_chip *chip);
>  	int (*optimize_read)(struct aspeed_smc_chip *chip, u32 max_freq);
> +	u32 (*segment_start)(struct aspeed_smc_controller *controller, u32 reg);
> +	u32 (*segment_end)(struct aspeed_smc_controller *controller, u32 reg);
> +	u32 (*segment_reg)(struct aspeed_smc_controller *controller,
> +			   u32 start, u32 end);
>  };
>  
>  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 int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
>  				     u32 max_freq);
> +static u32 aspeed_smc_segment_start(
> +	struct aspeed_smc_controller *controller, u32 reg);
> +static u32 aspeed_smc_segment_end(
> +	struct aspeed_smc_controller *controller, u32 reg);
> +static u32 aspeed_smc_segment_reg(
> +	struct aspeed_smc_controller *controller, u32 start, u32 end);
>  
>  static const struct aspeed_smc_info fmc_2400_info = {
>  	.maxsize = 64 * 1024 * 1024,
> @@ -59,6 +70,9 @@ static const struct aspeed_smc_info fmc_2400_info = {
>  	.timing = 0x94,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.segment_start = aspeed_smc_segment_start,
> +	.segment_end = aspeed_smc_segment_end,
> +	.segment_reg = aspeed_smc_segment_reg,
>  };
>  
>  static const struct aspeed_smc_info spi_2400_info = {
> @@ -70,6 +84,7 @@ static const struct aspeed_smc_info spi_2400_info = {
>  	.timing = 0x14,
>  	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	/* No segment registers */
>  };
>  
>  static const struct aspeed_smc_info fmc_2500_info = {
> @@ -81,6 +96,9 @@ static const struct aspeed_smc_info fmc_2500_info = {
>  	.timing = 0x94,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.segment_start = aspeed_smc_segment_start,
> +	.segment_end = aspeed_smc_segment_end,
> +	.segment_reg = aspeed_smc_segment_reg,
>  };
>  
>  static const struct aspeed_smc_info spi_2500_info = {
> @@ -92,6 +110,9 @@ static const struct aspeed_smc_info spi_2500_info = {
>  	.timing = 0x94,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.segment_start = aspeed_smc_segment_start,
> +	.segment_end = aspeed_smc_segment_end,
> +	.segment_reg = aspeed_smc_segment_reg,
>  };
>  
>  enum aspeed_smc_ctl_reg_value {
> @@ -201,22 +222,33 @@ struct aspeed_smc_controller {
>  	(CONTROL_AAF_MODE | CONTROL_CE_INACTIVE_MASK | CONTROL_CLK_DIV4 | \
>  	 CONTROL_CLOCK_FREQ_SEL_MASK | CONTROL_LSB_FIRST | CONTROL_CLOCK_MODE_3)
>  
> -/*
> - * The Segment Register uses a 8MB unit to encode the start address
> - * and the end address of the mapping window of a flash SPI slave :
> - *
> - *        | byte 1 | byte 2 | byte 3 | byte 4 |
> - *        +--------+--------+--------+--------+
> - *        |  end   |  start |   0    |   0    |
> - */
>  #define SEGMENT_ADDR_REG0		0x30
> -#define SEGMENT_ADDR_START(_r)		((((_r) >> 16) & 0xFF) << 23)
> -#define SEGMENT_ADDR_END(_r)		((((_r) >> 24) & 0xFF) << 23)
> -#define SEGMENT_ADDR_VALUE(start, end)					\
> -	(((((start) >> 23) & 0xFF) << 16) | ((((end) >> 23) & 0xFF) << 24))
>  #define SEGMENT_ADDR_REG(controller, cs)	\
>  	((controller)->regs + SEGMENT_ADDR_REG0 + (cs) * 4)
>  
> +/*
> + * The Segment Registers of the AST2400 and AST2500 have a 8MB
> + * unit. The address range of a flash SPI slave is encoded with
> + * absolute addresses which should be part of the overall controller
> + * window.
> + */
> +static u32 aspeed_smc_segment_start(
> +	struct aspeed_smc_controller *controller, u32 reg)
> +{
> +	return ((reg >> 16) & 0xFF) << 23;
> +}
> +
> +static u32 aspeed_smc_segment_end(
> +	struct aspeed_smc_controller *controller, u32 reg)
> +{
> +	return ((reg >> 24) & 0xFF) << 23;
> +}
> +
> +static u32 aspeed_smc_segment_reg(
> +	struct aspeed_smc_controller *controller, u32 start, u32 end)
> +{
> +	return (((start >> 23) & 0xFF) << 16) | (((end >> 23) & 0xFF) << 24);
> +}
>  /*
>   * Switch to turn off read optimisation if needed
>   */
> @@ -519,16 +551,19 @@ static void __iomem *aspeed_smc_chip_base(struct 
> aspeed_smc_chip *chip,
>  					  struct resource *res)
>  {
>  	struct aspeed_smc_controller *controller = chip->controller;
> +	const struct aspeed_smc_info *info = controller->info;
>  	u32 offset = 0;
>  	u32 reg;
>  
> -	if (controller->info->nce > 1) {
> +	if (info->nce > 1) {
>  		reg = readl(SEGMENT_ADDR_REG(controller, chip->cs));
>  
> -		if (SEGMENT_ADDR_START(reg) >= SEGMENT_ADDR_END(reg))
> +		if (info->segment_start(controller, reg) >=
> +		    info->segment_end(controller, reg)) {
>  			return NULL;
> +		}
>  
> -		offset = SEGMENT_ADDR_START(reg) - res->start;
> +		offset = info->segment_start(controller, reg) - res->start;
>  	}
>  
>  	return controller->ahb_base + offset;
> @@ -538,6 +573,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  			    u32 size)
>  {
>  	struct aspeed_smc_controller *controller = chip->controller;
> +	const struct aspeed_smc_info *info = controller->info;
>  	void __iomem *seg_reg;
>  	u32 seg_oldval, seg_newval, end;
>  	u32 ahb_base_phy = controller->ahb_base_phy;
> @@ -551,7 +587,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  	 * previous segment
>  	 */
>  	if (!size)
> -		size = SEGMENT_ADDR_END(seg_oldval) - start;
> +		size = info->segment_end(controller, seg_oldval) - start;
>  
>  	/*
>  	 * The segment cannot exceed the maximum window size of the
> @@ -564,7 +600,7 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  	}
>  
>  	end = start + size;
> -	seg_newval = SEGMENT_ADDR_VALUE(start, end);
> +	seg_newval = info->segment_reg(controller, start, end);
>  	writel(seg_newval, seg_reg);
>  
>  	/*
> @@ -575,8 +611,8 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  	if (seg_newval != readl(seg_reg)) {
>  		dev_err(chip->nor.dev, "CE%d window invalid", cs);
>  		writel(seg_oldval, seg_reg);
> -		start = SEGMENT_ADDR_START(seg_oldval);
> -		end = SEGMENT_ADDR_END(seg_oldval);
> +		start = info->segment_start(controller, seg_oldval);
> +		end = info->segment_end(controller, seg_oldval);
>  		size = end - start;
>  	}
>  
> @@ -639,7 +675,7 @@ static u32 aspeed_smc_chip_set_segment(struct 
> aspeed_smc_chip *chip)
>  	if (chip->cs) {
>  		u32 prev = readl(SEGMENT_ADDR_REG(controller, chip->cs - 1));
>  
> -		start = SEGMENT_ADDR_END(prev);
> +		start = controller->info->segment_end(controller, prev);
>  	} else {
>  		start = ahb_base_phy;
>  	}
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600
  2019-09-25 12:42 ` [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600 Cédric Le Goater
@ 2019-09-26  2:00   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:00 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> The Segment Registers of the AST2600 have a different encoding. A 1MB
> unit is used and the address range of a flash SPI slave is encoded
> with offsets in the overall controller window. The previous SoC
> AST2400 and AST2500 used absolute addresses. Only bits [27:20] are
> relevant and the end address is an upper bound limit.
> 
> SPI training yet to come.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 73 ++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index 4e768092a965..6c5ecea21882 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -115,6 +115,39 @@ static const struct aspeed_smc_info spi_2500_info = {
>  	.segment_reg = aspeed_smc_segment_reg,
>  };
>  
> +static u32 aspeed_smc_segment_start_ast2600(
> +	struct aspeed_smc_controller *controller, u32 reg);
> +static u32 aspeed_smc_segment_end_ast2600(
> +	struct aspeed_smc_controller *controller, u32 reg);
> +static u32 aspeed_smc_segment_reg_ast2600(
> +	struct aspeed_smc_controller *controller, u32 start, u32 end);
> +
> +static const struct aspeed_smc_info fmc_2600_info = {
> +	.maxsize = 256 * 1024 * 1024,
> +	.nce = 3,
> +	.hastype = false, /* SPI Only */
> +	.we0 = 16,
> +	.ctl0 = 0x10,
> +	.timing = 0x94,
> +	.set_4b = aspeed_smc_chip_set_4b,
> +	.segment_start = aspeed_smc_segment_start_ast2600,
> +	.segment_end = aspeed_smc_segment_end_ast2600,
> +	.segment_reg = aspeed_smc_segment_reg_ast2600,
> +};
> +
> +static const struct aspeed_smc_info spi_2600_info = {
> +	.maxsize = 256 * 1024 * 1024,
> +	.nce = 2,
> +	.hastype = false,
> +	.we0 = 16,
> +	.ctl0 = 0x10,
> +	.timing = 0x94,
> +	.set_4b = aspeed_smc_chip_set_4b,
> +	.segment_start = aspeed_smc_segment_start_ast2600,
> +	.segment_end = aspeed_smc_segment_end_ast2600,
> +	.segment_reg = aspeed_smc_segment_reg_ast2600,
> +};
> +
>  enum aspeed_smc_ctl_reg_value {
>  	smc_base,		/* base value without mode for other commands */
>  	smc_read,		/* command reg for (maybe fast) reads */
> @@ -249,6 +282,44 @@ static u32 aspeed_smc_segment_reg(
>  {
>  	return (((start >> 23) & 0xFF) << 16) | (((end >> 23) & 0xFF) << 24);
>  }
> +
> +/*
> + * The Segment Registers of the AST2600 have a 1MB unit. The address
> + * range of a flash SPI slave is encoded with offsets in the overall
> + * controller window. The previous SoC AST2400 and AST2500 used
> + * absolute addresses. Only bits [27:20] are relevant and the end
> + * address is an upper bound limit.
> + */
> +
> +#define AST2600_SEG_ADDR_MASK 0x0ff00000
> +
> +static u32 aspeed_smc_segment_start_ast2600(
> +	struct aspeed_smc_controller *controller, u32 reg)
> +{
> +	uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
> +
> +	return controller->ahb_base_phy + start_offset;
> +}
> +
> +static u32 aspeed_smc_segment_end_ast2600(
> +	struct aspeed_smc_controller *controller, u32 reg)
> +{
> +	uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
> +
> +	/* segment is disabled */
> +	if (!end_offset)
> +		return controller->ahb_base_phy;
> +
> +	return controller->ahb_base_phy + end_offset + 0x100000;
> +}
> +
> +static u32 aspeed_smc_segment_reg_ast2600(
> +	struct aspeed_smc_controller *controller, u32 start, u32 end)
> +{
> +    return ((start & AST2600_SEG_ADDR_MASK) >> 16) |
> +	    ((end - 1) & AST2600_SEG_ADDR_MASK);
> +}
> +
>  /*
>   * Switch to turn off read optimisation if needed
>   */
> @@ -536,6 +607,8 @@ static const struct of_device_id aspeed_smc_matches[] = {
>  	{ .compatible = "aspeed,ast2400-spi", .data = &spi_2400_info },
>  	{ .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
>  	{ .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
> +	{ .compatible = "aspeed,ast2600-fmc", .data = &fmc_2600_info },
> +	{ .compatible = "aspeed,ast2600-spi", .data = &spi_2600_info },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, aspeed_smc_matches);
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600
  2019-09-25 12:42 ` [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600 Cédric Le Goater
@ 2019-09-26  2:01   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:01 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> The segments can be disabled on the AST2600 (zero register value).
> CS0 is open by default but not the other CS. This is closing the
> access to the flash device in user mode and forbids scanning. For
> multiple CS, we will need firmware or a DT property to reopen the
> flash AHB window.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c 
> b/drivers/mtd/spi-nor/aspeed-smc.c
> index 6c5ecea21882..ea9b4a157677 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -659,8 +659,15 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  	 * size, but take into account the possible overlap with the
>  	 * previous segment
>  	 */
> -	if (!size)
> -		size = info->segment_end(controller, seg_oldval) - start;
> +	if (!size) {
> +		end = info->segment_end(controller, seg_oldval);
> +
> +		/*
> +		 * Check for disabled segment (AST2600).
> +		 */
> +		if (end != ahb_base_phy)
> +			size = end - start;
> +	}
>  
>  	/*
>  	 * The segment cannot exceed the maximum window size of the
> @@ -689,8 +696,8 @@ static u32 chip_set_segment(struct aspeed_smc_chip 
> *chip, u32 cs, u32 start,
>  		size = end - start;
>  	}
>  
> -	dev_info(chip->nor.dev, "CE%d window [ 0x%.8x - 0x%.8x ] %dMB",
> -		 cs, start, end, size >> 20);
> +	dev_info(chip->nor.dev, "CE%d window [ 0x%.8x - 0x%.8x ] %dMB%s",
> +		 cs, start, end, size >> 20, size ? "" : " (disabled)");
>  
>  	return size;
>  }
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform
  2019-09-25 12:42 ` [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform Cédric Le Goater
@ 2019-09-26  2:03   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:03 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> The read timing compensation register is different on the AST2600 and
> training will be slightly more complex.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 26 ++++++++++++++++++++++----
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index ea9b4a157677..768394068bd4 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -41,9 +41,13 @@ struct aspeed_smc_info {
>  	u8 we0;			/* shift for write enable bit for CE0 */
>  	u8 ctl0;		/* offset in regs of ctl for CE0 */
>  	u8 timing;		/* offset in regs of timing */
> +	u32 hdiv_max;           /* Max HCLK divisor on read timing reg */
>  
>  	void (*set_4b)(struct aspeed_smc_chip *chip);
>  	int (*optimize_read)(struct aspeed_smc_chip *chip, u32 max_freq);
> +	int (*calibrate)(struct aspeed_smc_chip *chip, u32 hdiv,
> +			 const u8 *golden_buf, u8 *test_buf);
> +
>  	u32 (*segment_start)(struct aspeed_smc_controller *controller, u32 
> reg);
>  	u32 (*segment_end)(struct aspeed_smc_controller *controller, u32 reg);
>  	u32 (*segment_reg)(struct aspeed_smc_controller *controller,
> @@ -54,6 +58,9 @@ 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 int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
>  				     u32 max_freq);
> +static int aspeed_smc_calibrate_reads(struct aspeed_smc_chip *chip, 
> u32 hdiv,
> +			 const u8 *golden_buf, u8 *test_buf);
> +
>  static u32 aspeed_smc_segment_start(
>  	struct aspeed_smc_controller *controller, u32 reg);
>  static u32 aspeed_smc_segment_end(
> @@ -68,8 +75,10 @@ static const struct aspeed_smc_info fmc_2400_info = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads,
>  	.segment_start = aspeed_smc_segment_start,
>  	.segment_end = aspeed_smc_segment_end,
>  	.segment_reg = aspeed_smc_segment_reg,
> @@ -82,8 +91,10 @@ static const struct aspeed_smc_info spi_2400_info = {
>  	.we0 = 0,
>  	.ctl0 = 0x04,
>  	.timing = 0x14,
> +	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads,
>  	/* No segment registers */
>  };
>  
> @@ -94,8 +105,10 @@ static const struct aspeed_smc_info fmc_2500_info = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads,
>  	.segment_start = aspeed_smc_segment_start,
>  	.segment_end = aspeed_smc_segment_end,
>  	.segment_reg = aspeed_smc_segment_reg,
> @@ -108,8 +121,10 @@ static const struct aspeed_smc_info spi_2500_info = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads,
>  	.segment_start = aspeed_smc_segment_start,
>  	.segment_end = aspeed_smc_segment_end,
>  	.segment_reg = aspeed_smc_segment_reg,
> @@ -984,7 +999,8 @@ static const uint32_t aspeed_smc_hclk_divs[] = {
>  	0x6, /* HCLK/4 */
>  	0xd, /* HCLK/5 */
>  };
> -#define ASPEED_SMC_HCLK_DIV(i) (aspeed_smc_hclk_divs[(i) - 1] << 8)
> +#define ASPEED_SMC_HCLK_DIV(i) \
> +	(aspeed_smc_hclk_divs[(i) - 1] << CONTROL_CLOCK_FREQ_SEL_SHIFT)
>  
>  static u32 aspeed_smc_default_read(struct aspeed_smc_chip *chip)
>  {
> @@ -1015,6 +1031,8 @@ static u32 aspeed_smc_default_read(struct 
> aspeed_smc_chip *chip)
>  static int aspeed_smc_optimize_read(struct aspeed_smc_chip *chip,
>  				     u32 max_freq)
>  {
> +	struct aspeed_smc_controller *controller = chip->controller;
> +	const struct aspeed_smc_info *info = controller->info;
>  	u8 *golden_buf, *test_buf;
>  	int i, rc, best_div = -1;
>  	u32 save_read_val = chip->ctl_val[smc_read];
> @@ -1047,7 +1065,7 @@ static int aspeed_smc_optimize_read(struct 
> aspeed_smc_chip *chip,
>  	}
>  
>  	/* Now we iterate the HCLK dividers until we find our breaking point */
> -	for (i = ARRAY_SIZE(aspeed_smc_hclk_divs); i > 0; i--) {
> +	for (i = ARRAY_SIZE(aspeed_smc_hclk_divs); i > info->hdiv_max - 1; i--) {
>  		u32 tv, freq;
>  
>  		/* Compare timing to max */
> @@ -1058,8 +1076,8 @@ static int aspeed_smc_optimize_read(struct 
> aspeed_smc_chip *chip,
>  		/* Set the timing */
>  		tv = chip->ctl_val[smc_read] | ASPEED_SMC_HCLK_DIV(i);
>  		writel(tv, chip->ctl);
> -		dev_dbg(chip->nor.dev, "Trying HCLK/%d...", i);
> -		rc = aspeed_smc_calibrate_reads(chip, i, golden_buf, test_buf);
> +		dev_dbg(chip->nor.dev, "Trying HCLK/%d [%08x] ...", i, tv);
> +		rc = info->calibrate(chip, i, golden_buf, test_buf);
>  		if (rc == 0)
>  			best_div = i;
>  	}
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training
  2019-09-25 12:42 ` [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training Cédric Le Goater
@ 2019-09-26  2:10   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:10 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> The AST2600 handles more HCLK divisors than its predecessors.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index 768394068bd4..c6a80fdf51ef 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -41,6 +41,7 @@ struct aspeed_smc_info {
>  	u8 we0;			/* shift for write enable bit for CE0 */
>  	u8 ctl0;		/* offset in regs of ctl for CE0 */
>  	u8 timing;		/* offset in regs of timing */
> +	u32 hclk_mask;          /* clock frequency mask in CEx Control reg */
>  	u32 hdiv_max;           /* Max HCLK divisor on read timing reg */
>  
>  	void (*set_4b)(struct aspeed_smc_chip *chip);
> @@ -75,6 +76,7 @@ static const struct aspeed_smc_info fmc_2400_info = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hclk_mask = 0xfffff0ff,
>  	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> @@ -91,6 +93,7 @@ static const struct aspeed_smc_info spi_2400_info = {
>  	.we0 = 0,
>  	.ctl0 = 0x04,
>  	.timing = 0x14,
> +	.hclk_mask = 0xfffff0ff,
>  	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b_spi_2400,
>  	.optimize_read = aspeed_smc_optimize_read,
> @@ -105,6 +108,7 @@ static const struct aspeed_smc_info fmc_2500_info = 
> {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hclk_mask = 0xfffff0ff,
>  	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> @@ -121,6 +125,7 @@ static const struct aspeed_smc_info spi_2500_info = 
> {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hclk_mask = 0xfffff0ff,
>  	.hdiv_max = 1,
>  	.set_4b = aspeed_smc_chip_set_4b,
>  	.optimize_read = aspeed_smc_optimize_read,
> @@ -1053,7 +1058,7 @@ static int aspeed_smc_optimize_read(struct 
> aspeed_smc_chip *chip,
>  	memcpy_fromio(golden_buf, chip->ahb_base, CALIBRATE_BUF_SIZE);
>  
>  	/* Establish our read mode with freq field set to 0 (HCLK/16) */
> -	chip->ctl_val[smc_read] = save_read_val & 0xfffff0ff;
> +	chip->ctl_val[smc_read] = save_read_val & info->hclk_mask;
>  
>  	/* Check if calibration data is suitable */
>  	if (!aspeed_smc_check_calib_data(golden_buf, CALIBRATE_BUF_SIZE)) {
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training
  2019-09-25 12:42 ` [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training Cédric Le Goater
@ 2019-09-26  2:12   ` Andrew Jeffery
  0 siblings, 0 replies; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:12 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c 
> b/drivers/mtd/spi-nor/aspeed-smc.c
> index c6a80fdf51ef..48164d819a37 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -1075,7 +1075,7 @@ static int aspeed_smc_optimize_read(struct 
> aspeed_smc_chip *chip,
>  
>  		/* Compare timing to max */
>  		freq = ahb_freq / i;
> -		if (freq >= max_freq)
> +		if (freq > max_freq)
>  			continue;

Heh.

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

>  
>  		/* Set the timing */
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training
  2019-09-25 12:42 ` [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training Cédric Le Goater
@ 2019-09-26  2:14   ` Andrew Jeffery
  2019-09-26  6:59     ` Cédric Le Goater
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Jeffery @ 2019-09-26  2:14 UTC (permalink / raw)
  To: Cédric Le Goater, openbmc



On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:

Would prefer some description here, this patch gets complex. At least for me,
probably because I'm not familiar with the flash training routine.

> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  drivers/mtd/spi-nor/aspeed-smc.c | 68 ++++++++++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> index 48164d819a37..e9bc89755912 100644
> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> @@ -142,6 +142,9 @@ static u32 aspeed_smc_segment_end_ast2600(
>  static u32 aspeed_smc_segment_reg_ast2600(
>  	struct aspeed_smc_controller *controller, u32 start, u32 end);
>  
> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip 
> *chip,
> +	      u32 hdiv, const u8 *golden_buf, u8 *test_buf);
> +
>  static const struct aspeed_smc_info fmc_2600_info = {
>  	.maxsize = 256 * 1024 * 1024,
>  	.nce = 3,
> @@ -149,7 +152,11 @@ static const struct aspeed_smc_info fmc_2600_info 
> = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hclk_mask = 0xf0fff0ff,
> +	.hdiv_max = 2,
>  	.set_4b = aspeed_smc_chip_set_4b,
> +	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads_ast2600,
>  	.segment_start = aspeed_smc_segment_start_ast2600,
>  	.segment_end = aspeed_smc_segment_end_ast2600,
>  	.segment_reg = aspeed_smc_segment_reg_ast2600,
> @@ -162,7 +169,11 @@ static const struct aspeed_smc_info spi_2600_info 
> = {
>  	.we0 = 16,
>  	.ctl0 = 0x10,
>  	.timing = 0x94,
> +	.hclk_mask = 0xf0fff0ff,
> +	.hdiv_max = 2,
>  	.set_4b = aspeed_smc_chip_set_4b,
> +	.optimize_read = aspeed_smc_optimize_read,
> +	.calibrate = aspeed_smc_calibrate_reads_ast2600,
>  	.segment_start = aspeed_smc_segment_start_ast2600,
>  	.segment_end = aspeed_smc_segment_end_ast2600,
>  	.segment_reg = aspeed_smc_segment_reg_ast2600,
> @@ -1101,6 +1112,63 @@ static int aspeed_smc_optimize_read(struct 
> aspeed_smc_chip *chip,
>  	return 0;
>  }
>  
> +#define TIMING_DELAY_DI         BIT(3)
> +#define TIMING_DELAY_HCYCLE_MAX     5
> +
> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip 
> *chip, u32 hdiv,
> +					      const u8 *golden_buf, u8 *test_buf)
> +{
> +	struct aspeed_smc_controller *controller = chip->controller;
> +	const struct aspeed_smc_info *info = controller->info;
> +	int hcycle;
> +	u32 shift = (hdiv - 2) << 3;
> +	u32 mask = ~(0xfu << shift);
> +	u32 fread_timing_val = 0;
> +
> +	for (hcycle = 0; hcycle <= TIMING_DELAY_HCYCLE_MAX; hcycle++) {
> +		int delay_ns;
> +		bool pass = false;
> +
> +		fread_timing_val &= mask;
> +		fread_timing_val |= hcycle << shift;
> +
> +		/* no DI input delay first  */
> +		writel(fread_timing_val, controller->regs + info->timing);
> +		pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
> +		dev_dbg(chip->nor.dev,
> +			"  * [%08x] %d HCLK delay, DI delay none : %s",
> +			fread_timing_val, hcycle, pass ? "PASS" : "FAIL");
> +		if (pass)
> +			return 0;
> +
> +		/* Add DI input delays  */
> +		fread_timing_val &= mask;
> +		fread_timing_val |= (TIMING_DELAY_DI | hcycle) << shift;
> +
> +		for (delay_ns = 0; delay_ns < 0x10; delay_ns++) {
> +			fread_timing_val &= ~(0xf << (4 + shift));
> +			fread_timing_val |= delay_ns << (4 + shift);
> +
> +			writel(fread_timing_val, controller->regs + info->timing);
> +			pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
> +			dev_dbg(chip->nor.dev,
> +				"  * [%08x] %d HCLK delay, DI delay %d.%dns : %s",
> +				fread_timing_val, hcycle, (delay_ns + 1)/2,
> +				(delay_ns + 1) & 1 ? 5 : 5, pass ? "PASS" : "FAIL");
> +			/*
> +			 * TODO: This is optimistic. We should look
> +			 * for a working interval and save the middle
> +			 * value in the read timing register.
> +			 */
> +			if (pass)
> +				return 0;
> +		}
> +	}
> +
> +	/* No good setting for this frequency */
> +	return -1;
> +}
> +
>  static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
>  {
>  	struct aspeed_smc_controller *controller = chip->controller;
> -- 
> 2.21.0
> 
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv
  2019-09-26  1:42   ` Andrew Jeffery
@ 2019-09-26  3:53     ` Joel Stanley
  0 siblings, 0 replies; 31+ messages in thread
From: Joel Stanley @ 2019-09-26  3:53 UTC (permalink / raw)
  To: Andrew Jeffery; +Cc: Cédric Le Goater, OpenBMC Maillist

On Thu, 26 Sep 2019 at 01:42, Andrew Jeffery <andrew@aj.id.au> wrote:
>
>
>
> On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> > Signed-off-by: Cédric Le Goater <clg@kaod.org>
>
> Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

We should send this one upstream.


>
> > ---
> >  drivers/mtd/spi-nor/spi-nor.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > b/drivers/mtd/spi-nor/spi-nor.c
> > index 0034e7751239..ff6b719fd267 100644
> > --- a/drivers/mtd/spi-nor/spi-nor.c
> > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > @@ -2151,6 +2151,8 @@ static const struct flash_info spi_nor_ids[] = {
> >       { "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
> >       { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
> >       { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K |
> > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > +     { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024, SECT_4K |
> > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> > +                     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
> >       { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
> >                       SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
> >
> > --
> > 2.21.0
> >
> >

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0
  2019-09-26  1:19   ` Andrew Jeffery
@ 2019-09-26  5:55     ` Cédric Le Goater
  0 siblings, 0 replies; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-26  5:55 UTC (permalink / raw)
  To: Andrew Jeffery, openbmc; +Cc: Joel Stanley, Brad Bishop

On 26/09/2019 03:19, Andrew Jeffery wrote:
> 
> 
> On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts 
>> b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
>> index 5e5bc78bdce4..713dc64064ad 100644
>> --- a/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
>> +++ b/arch/arm/boot/dts/aspeed-bmc-opp-rainier.dts
>> @@ -475,3 +475,10 @@
>>  		spi-max-frequency = <100000000>;
>>  	};
>>  };
>> +
>> +&mac0 {
>> +	status = "okay";
>> +
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&pinctrl_rmii1_default>;
> 
> This looks like a shortcut to aid development under qemu?
> 

yes. I think Brad sent a new DTS update. We can drop this patch.

C.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training
  2019-09-26  2:14   ` Andrew Jeffery
@ 2019-09-26  6:59     ` Cédric Le Goater
  2019-09-26  7:04       ` Joel Stanley
  0 siblings, 1 reply; 31+ messages in thread
From: Cédric Le Goater @ 2019-09-26  6:59 UTC (permalink / raw)
  To: Andrew Jeffery, openbmc

On 26/09/2019 04:14, Andrew Jeffery wrote:
> 
> 
> On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> 
> Would prefer some description here, this patch gets complex. At least for me,
> probably because I'm not familiar with the flash training routine.

Joel, Could you please squeeze in this in the commit log ? I can resend
just that patch if you prefer, once you have pushed the series. This is 
just an optimization.

Thanks,

C.  


The training consists in finding the appropriate read timing delays for 
the HCLK dividers 2, 3, 4, and 5 and store the results in the Read Timing 
Compensation register. The previous SoC AST2500 and AST2400 were covering 
a broader HCLK range [ 1 - 5 ] because the AHB frequency was lower.

The algo first reads a golden buffer at low speed and then performs reads 
with different clocks and delay cycles settings to find a breaking point.
This selects the default clock frequency for the CEx control register.
The current settings are bit optimistic as we pick the first delay giving 
good results. A safer approach would be to determine an interval and 
choose the middle value. We might change the approach depending on the 
results on other systems.

Only CS0 is taken into account for the moment.

> 
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  drivers/mtd/spi-nor/aspeed-smc.c | 68 ++++++++++++++++++++++++++++++++
>>  1 file changed, 68 insertions(+)
>>
>> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
>> index 48164d819a37..e9bc89755912 100644
>> --- a/drivers/mtd/spi-nor/aspeed-smc.c
>> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
>> @@ -142,6 +142,9 @@ static u32 aspeed_smc_segment_end_ast2600(
>>  static u32 aspeed_smc_segment_reg_ast2600(
>>  	struct aspeed_smc_controller *controller, u32 start, u32 end);
>>  
>> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip 
>> *chip,
>> +	      u32 hdiv, const u8 *golden_buf, u8 *test_buf);
>> +
>>  static const struct aspeed_smc_info fmc_2600_info = {
>>  	.maxsize = 256 * 1024 * 1024,
>>  	.nce = 3,
>> @@ -149,7 +152,11 @@ static const struct aspeed_smc_info fmc_2600_info 
>> = {
>>  	.we0 = 16,
>>  	.ctl0 = 0x10,
>>  	.timing = 0x94,
>> +	.hclk_mask = 0xf0fff0ff,
>> +	.hdiv_max = 2,
>>  	.set_4b = aspeed_smc_chip_set_4b,
>> +	.optimize_read = aspeed_smc_optimize_read,
>> +	.calibrate = aspeed_smc_calibrate_reads_ast2600,
>>  	.segment_start = aspeed_smc_segment_start_ast2600,
>>  	.segment_end = aspeed_smc_segment_end_ast2600,
>>  	.segment_reg = aspeed_smc_segment_reg_ast2600,
>> @@ -162,7 +169,11 @@ static const struct aspeed_smc_info spi_2600_info 
>> = {
>>  	.we0 = 16,
>>  	.ctl0 = 0x10,
>>  	.timing = 0x94,
>> +	.hclk_mask = 0xf0fff0ff,
>> +	.hdiv_max = 2,
>>  	.set_4b = aspeed_smc_chip_set_4b,
>> +	.optimize_read = aspeed_smc_optimize_read,
>> +	.calibrate = aspeed_smc_calibrate_reads_ast2600,
>>  	.segment_start = aspeed_smc_segment_start_ast2600,
>>  	.segment_end = aspeed_smc_segment_end_ast2600,
>>  	.segment_reg = aspeed_smc_segment_reg_ast2600,
>> @@ -1101,6 +1112,63 @@ static int aspeed_smc_optimize_read(struct 
>> aspeed_smc_chip *chip,
>>  	return 0;
>>  }
>>  
>> +#define TIMING_DELAY_DI         BIT(3)
>> +#define TIMING_DELAY_HCYCLE_MAX     5
>> +
>> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip 
>> *chip, u32 hdiv,
>> +					      const u8 *golden_buf, u8 *test_buf)
>> +{
>> +	struct aspeed_smc_controller *controller = chip->controller;
>> +	const struct aspeed_smc_info *info = controller->info;
>> +	int hcycle;
>> +	u32 shift = (hdiv - 2) << 3;
>> +	u32 mask = ~(0xfu << shift);
>> +	u32 fread_timing_val = 0;
>> +
>> +	for (hcycle = 0; hcycle <= TIMING_DELAY_HCYCLE_MAX; hcycle++) {
>> +		int delay_ns;
>> +		bool pass = false;
>> +
>> +		fread_timing_val &= mask;
>> +		fread_timing_val |= hcycle << shift;
>> +
>> +		/* no DI input delay first  */
>> +		writel(fread_timing_val, controller->regs + info->timing);
>> +		pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
>> +		dev_dbg(chip->nor.dev,
>> +			"  * [%08x] %d HCLK delay, DI delay none : %s",
>> +			fread_timing_val, hcycle, pass ? "PASS" : "FAIL");
>> +		if (pass)
>> +			return 0;
>> +
>> +		/* Add DI input delays  */
>> +		fread_timing_val &= mask;
>> +		fread_timing_val |= (TIMING_DELAY_DI | hcycle) << shift;
>> +
>> +		for (delay_ns = 0; delay_ns < 0x10; delay_ns++) {
>> +			fread_timing_val &= ~(0xf << (4 + shift));
>> +			fread_timing_val |= delay_ns << (4 + shift);
>> +
>> +			writel(fread_timing_val, controller->regs + info->timing);
>> +			pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
>> +			dev_dbg(chip->nor.dev,
>> +				"  * [%08x] %d HCLK delay, DI delay %d.%dns : %s",
>> +				fread_timing_val, hcycle, (delay_ns + 1)/2,
>> +				(delay_ns + 1) & 1 ? 5 : 5, pass ? "PASS" : "FAIL");
>> +			/*
>> +			 * TODO: This is optimistic. We should look
>> +			 * for a working interval and save the middle
>> +			 * value in the read timing register.
>> +			 */
>> +			if (pass)
>> +				return 0;
>> +		}
>> +	}
>> +
>> +	/* No good setting for this frequency */
>> +	return -1;
>> +}
>> +
>>  static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
>>  {
>>  	struct aspeed_smc_controller *controller = chip->controller;
>> -- 
>> 2.21.0
>>
>>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training
  2019-09-26  6:59     ` Cédric Le Goater
@ 2019-09-26  7:04       ` Joel Stanley
  0 siblings, 0 replies; 31+ messages in thread
From: Joel Stanley @ 2019-09-26  7:04 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: Andrew Jeffery, OpenBMC Maillist

On Thu, 26 Sep 2019 at 06:59, Cédric Le Goater <clg@kaod.org> wrote:
>
> On 26/09/2019 04:14, Andrew Jeffery wrote:
> >
> >
> > On Wed, 25 Sep 2019, at 22:12, Cédric Le Goater wrote:
> >
> > Would prefer some description here, this patch gets complex. At least for me,
> > probably because I'm not familiar with the flash training routine.
>
> Joel, Could you please squeeze in this in the commit log ? I can resend
> just that patch if you prefer, once you have pushed the series. This is
> just an optimization.

Done.

>
> Thanks,
>
> C.
>
>
> The training consists in finding the appropriate read timing delays for
> the HCLK dividers 2, 3, 4, and 5 and store the results in the Read Timing
> Compensation register. The previous SoC AST2500 and AST2400 were covering
> a broader HCLK range [ 1 - 5 ] because the AHB frequency was lower.
>
> The algo first reads a golden buffer at low speed and then performs reads
> with different clocks and delay cycles settings to find a breaking point.
> This selects the default clock frequency for the CEx control register.
> The current settings are bit optimistic as we pick the first delay giving
> good results. A safer approach would be to determine an interval and
> choose the middle value. We might change the approach depending on the
> results on other systems.
>
> Only CS0 is taken into account for the moment.
>
> >
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> >> ---
> >>  drivers/mtd/spi-nor/aspeed-smc.c | 68 ++++++++++++++++++++++++++++++++
> >>  1 file changed, 68 insertions(+)
> >>
> >> diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
> >> index 48164d819a37..e9bc89755912 100644
> >> --- a/drivers/mtd/spi-nor/aspeed-smc.c
> >> +++ b/drivers/mtd/spi-nor/aspeed-smc.c
> >> @@ -142,6 +142,9 @@ static u32 aspeed_smc_segment_end_ast2600(
> >>  static u32 aspeed_smc_segment_reg_ast2600(
> >>      struct aspeed_smc_controller *controller, u32 start, u32 end);
> >>
> >> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip
> >> *chip,
> >> +          u32 hdiv, const u8 *golden_buf, u8 *test_buf);
> >> +
> >>  static const struct aspeed_smc_info fmc_2600_info = {
> >>      .maxsize = 256 * 1024 * 1024,
> >>      .nce = 3,
> >> @@ -149,7 +152,11 @@ static const struct aspeed_smc_info fmc_2600_info
> >> = {
> >>      .we0 = 16,
> >>      .ctl0 = 0x10,
> >>      .timing = 0x94,
> >> +    .hclk_mask = 0xf0fff0ff,
> >> +    .hdiv_max = 2,
> >>      .set_4b = aspeed_smc_chip_set_4b,
> >> +    .optimize_read = aspeed_smc_optimize_read,
> >> +    .calibrate = aspeed_smc_calibrate_reads_ast2600,
> >>      .segment_start = aspeed_smc_segment_start_ast2600,
> >>      .segment_end = aspeed_smc_segment_end_ast2600,
> >>      .segment_reg = aspeed_smc_segment_reg_ast2600,
> >> @@ -162,7 +169,11 @@ static const struct aspeed_smc_info spi_2600_info
> >> = {
> >>      .we0 = 16,
> >>      .ctl0 = 0x10,
> >>      .timing = 0x94,
> >> +    .hclk_mask = 0xf0fff0ff,
> >> +    .hdiv_max = 2,
> >>      .set_4b = aspeed_smc_chip_set_4b,
> >> +    .optimize_read = aspeed_smc_optimize_read,
> >> +    .calibrate = aspeed_smc_calibrate_reads_ast2600,
> >>      .segment_start = aspeed_smc_segment_start_ast2600,
> >>      .segment_end = aspeed_smc_segment_end_ast2600,
> >>      .segment_reg = aspeed_smc_segment_reg_ast2600,
> >> @@ -1101,6 +1112,63 @@ static int aspeed_smc_optimize_read(struct
> >> aspeed_smc_chip *chip,
> >>      return 0;
> >>  }
> >>
> >> +#define TIMING_DELAY_DI         BIT(3)
> >> +#define TIMING_DELAY_HCYCLE_MAX     5
> >> +
> >> +static int aspeed_smc_calibrate_reads_ast2600(struct aspeed_smc_chip
> >> *chip, u32 hdiv,
> >> +                                          const u8 *golden_buf, u8 *test_buf)
> >> +{
> >> +    struct aspeed_smc_controller *controller = chip->controller;
> >> +    const struct aspeed_smc_info *info = controller->info;
> >> +    int hcycle;
> >> +    u32 shift = (hdiv - 2) << 3;
> >> +    u32 mask = ~(0xfu << shift);
> >> +    u32 fread_timing_val = 0;
> >> +
> >> +    for (hcycle = 0; hcycle <= TIMING_DELAY_HCYCLE_MAX; hcycle++) {
> >> +            int delay_ns;
> >> +            bool pass = false;
> >> +
> >> +            fread_timing_val &= mask;
> >> +            fread_timing_val |= hcycle << shift;
> >> +
> >> +            /* no DI input delay first  */
> >> +            writel(fread_timing_val, controller->regs + info->timing);
> >> +            pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
> >> +            dev_dbg(chip->nor.dev,
> >> +                    "  * [%08x] %d HCLK delay, DI delay none : %s",
> >> +                    fread_timing_val, hcycle, pass ? "PASS" : "FAIL");
> >> +            if (pass)
> >> +                    return 0;
> >> +
> >> +            /* Add DI input delays  */
> >> +            fread_timing_val &= mask;
> >> +            fread_timing_val |= (TIMING_DELAY_DI | hcycle) << shift;
> >> +
> >> +            for (delay_ns = 0; delay_ns < 0x10; delay_ns++) {
> >> +                    fread_timing_val &= ~(0xf << (4 + shift));
> >> +                    fread_timing_val |= delay_ns << (4 + shift);
> >> +
> >> +                    writel(fread_timing_val, controller->regs + info->timing);
> >> +                    pass = aspeed_smc_check_reads(chip, golden_buf, test_buf);
> >> +                    dev_dbg(chip->nor.dev,
> >> +                            "  * [%08x] %d HCLK delay, DI delay %d.%dns : %s",
> >> +                            fread_timing_val, hcycle, (delay_ns + 1)/2,
> >> +                            (delay_ns + 1) & 1 ? 5 : 5, pass ? "PASS" : "FAIL");
> >> +                    /*
> >> +                     * TODO: This is optimistic. We should look
> >> +                     * for a working interval and save the middle
> >> +                     * value in the read timing register.
> >> +                     */
> >> +                    if (pass)
> >> +                            return 0;
> >> +            }
> >> +    }
> >> +
> >> +    /* No good setting for this frequency */
> >> +    return -1;
> >> +}
> >> +
> >>  static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
> >>  {
> >>      struct aspeed_smc_controller *controller = chip->controller;
> >> --
> >> 2.21.0
> >>
> >>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2019-09-26  7:05 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-25 12:42 [PATCH linux dev-5.3 00/13] mtd: spi-nor: aspeed: add support for ast2600 Cédric Le Goater
2019-09-25 12:42 ` [PATCH linux dev-5.3 01/13] ARM: dts: aspeed-g6: Add FMC and SPI devices Cédric Le Goater
2019-09-26  1:27   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 02/13] ARM: dts: aspeed: rainier: Enable " Cédric Le Goater
2019-09-26  1:34   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 03/13] ARM: dts: aspeed: rainier: Enable MAC0 Cédric Le Goater
2019-09-26  1:19   ` Andrew Jeffery
2019-09-26  5:55     ` Cédric Le Goater
2019-09-25 12:42 ` [PATCH linux dev-5.3 04/13] ARM: dts: ast2600-evb: Enable FMC and SPI devices Cédric Le Goater
2019-09-26  1:38   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 05/13] mtd: spi-nor: Add support for w25q512jv Cédric Le Goater
2019-09-26  1:42   ` Andrew Jeffery
2019-09-26  3:53     ` Joel Stanley
2019-09-25 12:42 ` [PATCH linux dev-5.3 06/13] mtd: spi-nor: aspeed: Introduce a field for the AHB physical address Cédric Le Goater
2019-09-26  1:59   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 07/13] mtd: spi-nor: aspeed: Introduce segment operations Cédric Le Goater
2019-09-26  2:00   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 08/13] mtd: spi-nor: aspeed: add initial support for ast2600 Cédric Le Goater
2019-09-26  2:00   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 09/13] mtd: spi-nor: aspeed: Check for disabled segments on the AST2600 Cédric Le Goater
2019-09-26  2:01   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 10/13] mtd: spi-nor: aspeed: Introduce training operations per platform Cédric Le Goater
2019-09-26  2:03   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 11/13] mtd: spi-nor: aspeed: Introduce a HCLK mask for training Cédric Le Goater
2019-09-26  2:10   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 12/13] mtd: spi-nor: aspeed: check upper freq limit when doing training Cédric Le Goater
2019-09-26  2:12   ` Andrew Jeffery
2019-09-25 12:42 ` [PATCH linux dev-5.3 13/13] mtd: spi-nor: aspeed: add support for AST2600 training Cédric Le Goater
2019-09-26  2:14   ` Andrew Jeffery
2019-09-26  6:59     ` Cédric Le Goater
2019-09-26  7:04       ` Joel Stanley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.