All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
@ 2017-01-04 19:46 Maxim Sloyko
  2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
                   ` (14 more replies)
  0 siblings, 15 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

This series adds minimal support for AST2500 part and eval board,
enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
Clock (very basic) and SDRAM MC drivers, all written from scratch,
using AST2500 datasheet. Aspeed's SDK was used only for reference.
Given very limited documentation provided by Aspeed, some parts of SDRAM
init sequence were basically rewritten to do the same thing that is done
in Aspeed SDK, without real understanding of what is going on.

The file layout closely follows the example of rk3288 chip and firefly-rk3288
board.

For the first round of reviews I'm mostly looking for a nod to add
mach-aspeed and arch-aspeed directories, as well as for feedback
on naming, file locations and overall approach.


Maxim Sloyko (12):
  aspeed: Add mach-aspeed directory and basic Kconfig
  aspeed: Add support for Watchdot Timer
  aspeed: Add Timer Support
  aspeed: Add sysreset driver
  aspeed/ast2500: Device Tree and bindings for some of the clocks
  aspeed/ast2500: Add Clock Driver
  aspeed/ast2500: Helper function to get access to SCU
  aspeed/ast2500: Add SDRAM MC driver
  aspeed/ast2500: Common board init functions for ast2500 based boards
  aspeed: Common configuration parameters for aspeed boards
  aspeed: Device Tree for ast2500 Eval Board
  aspeed: Configuration for ast2500 eval board

 arch/arm/Kconfig                                 |   7 +
 arch/arm/Makefile                                |   1 +
 arch/arm/dts/Makefile                            |   2 +
 arch/arm/dts/ast2500-evb.dts                     |  23 ++
 arch/arm/dts/ast2500.dtsi                        | 423 ++++++++++++++++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 108 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 133 +++++++
 arch/arm/include/asm/arch-aspeed/timer.h         |  54 +++
 arch/arm/include/asm/arch-aspeed/wdt.h           |  89 +++++
 arch/arm/mach-aspeed/Kconfig                     |  17 +
 arch/arm/mach-aspeed/Makefile                    |   8 +
 arch/arm/mach-aspeed/ast2500-board.c             |  74 ++++
 arch/arm/mach-aspeed/ast2500/Kconfig             |  13 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  31 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast_wdt.c                   |  44 +++
 board/aspeed/evb_ast2500/Kconfig                 |  12 +
 board/aspeed/evb_ast2500/Makefile                |   1 +
 board/aspeed/evb_ast2500/evb_ast2500.c           |   1 +
 configs/evb-ast2500_defconfig                    |  21 ++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 drivers/sysreset/Makefile                        |   1 +
 drivers/sysreset/sysreset_ast.c                  |  55 +++
 drivers/timer/Kconfig                            |   7 +
 drivers/timer/Makefile                           |   1 +
 drivers/timer/ast_timer.c                        |  96 +++++
 include/configs/aspeed-common.h                  |  84 +++++
 include/configs/evb_ast2500.h                    |  30 ++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 32 files changed, 2073 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c
 create mode 100644 include/configs/aspeed-common.h
 create mode 100644 include/configs/evb_ast2500.h
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

--
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-04 19:58   ` Rick Altherr
  2017-01-14 17:13   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer Maxim Sloyko
                   ` (13 subsequent siblings)
  14 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/Kconfig              |  7 +++++++
 arch/arm/Makefile             |  1 +
 arch/arm/mach-aspeed/Kconfig  | 15 +++++++++++++++
 arch/arm/mach-aspeed/Makefile |  8 ++++++++
 4 files changed, 31 insertions(+)
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 714dd8b514..135c544335 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
 	select OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 
+config ARCH_ASPEED
+	bool "Support Aspeed SoCs"
+	select OF_CONTROL
+	select DM
+
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm283x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 236debb452..cc73e1038e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ASPEED)		+= aspeed
 machine-$(CONFIG_ARCH_AT91)		+= at91
 machine-$(CONFIG_ARCH_BCM283X)		+= bcm283x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000000..43cdbeda84
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,15 @@
+if ARCH_ASPEED
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_SOC
+	default "aspeed"
+
+config ASPEED_AST2500
+	bool "Support Aspeed AST2500 SoC"
+	select CPU_ARM1176
+	help
+	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000000..8e276b4a9f
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2014 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-04 20:58   ` Tom Rini
  2017-01-14 17:13   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 03/12] aspeed: Add Timer Support Maxim Sloyko
                   ` (12 subsequent siblings)
  14 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

The driver is compatible with AST2400 and AST2500 watchdogs.
There is no uclass for Watchdog yet, so the driver does not follow
the driver model. It also uses fixed clock, so no clock driver
is needed.

# Conflicts:
#	arch/arm/mach-aspeed/Makefile

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/include/asm/arch-aspeed/wdt.h | 89 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-aspeed/Makefile          |  3 +-
 arch/arm/mach-aspeed/ast_wdt.c         | 44 +++++++++++++++++
 3 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c

diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
new file mode 100644
index 0000000000..32774b1a70
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_WDT_H
+#define _ASM_ARCH_WDT_H
+
+#define WDT_BASE			0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL		0x4755
+
+/* Control register */
+#define WDT_CTRL_RESET_MODE_SHIFT	5
+#define WDT_CTRL_RESET_MODE_MASK	3
+
+#define WDT_CTRL_EN			(1 << 0)
+#define WDT_CTRL_RESET			(1 << 1)
+#define WDT_CTRL_CLK1MHZ		(1 << 4)
+#define WDT_CTRL_2ND_BOOT		(1 << 7)
+
+/* Values for Reset Mode */
+#define WDT_CTRL_RESET_SOC		0
+#define WDT_CTRL_RESET_CHIP		1
+#define WDT_CTRL_RESET_CPU		2
+#define WDT_CTRL_RESET_MASK		3
+
+/* Reset Mask register */
+#define WDT_RESET_ARM			(1 << 0)
+#define WDT_RESET_COPROC		(1 << 1)
+#define WDT_RESET_SDRAM			(1 << 2)
+#define WDT_RESET_AHB			(1 << 3)
+#define WDT_RESET_I2C			(1 << 4)
+#define WDT_RESET_MAC1			(1 << 5)
+#define WDT_RESET_MAC2			(1 << 6)
+#define WDT_RESET_GCRT			(1 << 7)
+#define WDT_RESET_USB20			(1 << 8)
+#define WDT_RESET_USB11_HOST		(1 << 9)
+#define WDT_RESET_USB11_EHCI2		(1 << 10)
+#define WDT_RESET_VIDEO			(1 << 11)
+#define WDT_RESET_HAC			(1 << 12)
+#define WDT_RESET_LPC			(1 << 13)
+#define WDT_RESET_SDSDIO		(1 << 14)
+#define WDT_RESET_MIC			(1 << 15)
+#define WDT_RESET_CRT2C			(1 << 16)
+#define WDT_RESET_PWM			(1 << 17)
+#define WDT_RESET_PECI			(1 << 18)
+#define WDT_RESET_JTAG			(1 << 19)
+#define WDT_RESET_ADC			(1 << 20)
+#define WDT_RESET_GPIO			(1 << 21)
+#define WDT_RESET_MCTP			(1 << 22)
+#define WDT_RESET_XDMA			(1 << 23)
+#define WDT_RESET_SPI			(1 << 24)
+#define WDT_RESET_MISC			(1 << 25)
+
+#ifndef __ASSEMBLY__
+struct ast_wdt {
+	u32 counter_status;
+	u32 counter_reload_val;
+	u32 counter_restart;
+	u32 ctrl;
+	u32 timeout_status;
+	u32 clr_timeout_status;
+	u32 reset_width;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 reset_mask;
+#else
+	u32 reserved0;
+#endif
+};
+
+void wdt_stop(struct ast_wdt *wdt);
+void wdt_start(struct ast_wdt *wdt, u32 timeout);
+
+/**
+ * ast_get_wdt() - get a pointer to watchdog registers
+ *
+ * @wdt_number: 0-based WDT peripheral number
+ * @return pointer to registers or -ve error on error
+ */
+struct ast_wdt *ast_get_wdt(u8 wdt_number);
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 8e276b4a9f..a14b8f751d 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -1,8 +1,7 @@
 #
-# Copyright (c) 2014 Google, Inc
+# Copyright (c) 2016 Google, Inc
 #
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
new file mode 100644
index 0000000000..0b62abc455
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+/* Number of available watchdog timers */
+#ifdef CONFIG_ASPEED_AST2500
+#define WDT_MAX_NUM			2
+#else
+#define WDT_MAX_NUM			1
+#endif
+
+void wdt_stop(struct ast_wdt *wdt)
+{
+	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+}
+
+void wdt_start(struct ast_wdt *wdt, u32 timeout)
+{
+	writel(timeout, &wdt->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&wdt->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+}
+
+struct ast_wdt *ast_get_wdt(u8 wdt_number)
+{
+	if (wdt_number > WDT_MAX_NUM)
+		return ERR_PTR(-EINVAL);
+
+	return (struct ast_wdt *)(WDT_BASE +
+				  sizeof(struct ast_wdt) * wdt_number);
+}
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
  2017-01-04 19:46 ` [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-04 20:58   ` Tom Rini
  2017-01-14 17:13   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver Maxim Sloyko
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Add support for timer for Aspeed ast2400/ast2500 devices.
The driver actually controls several devices, but because all devices
share the same Control Register, it is somewhat difficult to completely
decouple them. Since only one timer is needed at the moment, this should
be OK.

The timer uses fixed clock, so does not rely on a clock driver.

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
 drivers/timer/Kconfig                    |  7 +++
 drivers/timer/Makefile                   |  1 +
 drivers/timer/ast_timer.c                | 96 ++++++++++++++++++++++++++++++++
 4 files changed, 158 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 drivers/timer/ast_timer.c

diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
new file mode 100644
index 0000000000..87c5b354ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/timer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_TIMER_H
+#define _ASM_ARCH_TIMER_H
+
+/* Each timer has 4 control bits in ctrl1 register.
+ * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
+ * such that timer X uses bits (4 * X - 4):(4 * X - 1)
+ * If the timer does not support PWM, bit 4 is reserved.
+ */
+#define AST_TMC_EN			(1 << 0)
+#define AST_TMC_1MHZ			(1 << 1)
+#define AST_TMC_OVFINTR			(1 << 2)
+#define AST_TMC_PWM			(1 << 3)
+
+/* Timers are counted from 1 in the datasheet. */
+#define AST_TMC_CTRL1_SHIFT(n)			(4 * ((n) - 1))
+
+#define AST_TMC_RATE  (1000*1000)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All timers share control registers, which makes it harder to make them
+ * separate devices. Since only one timer is needed@the moment, making
+ * it this just one device.
+ */
+
+struct ast_timer_counter {
+	u32 status;
+	u32 reload_val;
+	u32 match1;
+	u32 match2;
+};
+
+struct ast_timer {
+	struct ast_timer_counter timers1[3];
+	u32 ctrl1;
+	u32 ctrl2;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 ctrl3;
+	u32 ctrl1_clr;
+#else
+	u32 reserved[2];
+#endif
+	struct ast_timer_counter timers2[5];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_TIMER_H */
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index cb18f12fc9..9c5f98bb88 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -46,4 +46,11 @@ config OMAP_TIMER
 	help
 	  Select this to enable an timer for Omap devices.
 
+config AST_TIMER
+	bool "Aspeed ast2400/ast2500 timer support"
+	depends on TIMER
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable timer for Aspeed ast2400/ast2500 devices.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index f351fbb4e0..a4b1a486b0 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
new file mode 100644
index 0000000000..f644882f40
--- /dev/null
+++ b/drivers/timer/ast_timer.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define AST_TICK_TIMER  1
+#define AST_TMC_RELOAD_VAL  0xffffffff
+
+struct ast_timer_priv {
+	struct ast_timer *regs;
+};
+
+static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
+						       int n)
+{
+	if (n > 3)
+		return &timer->timers2[n - 4];
+	else
+		return &timer->timers1[n - 1];
+}
+
+static int ast_timer_probe(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
+
+	/*
+	 * Stop the timer. This will also load reload_val into
+	 * the status register.
+	 */
+	clrbits_le32(&priv->regs->ctrl1,
+		     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+	/* Start the timer from the fixed 1MHz clock. */
+	setbits_le32(&priv->regs->ctrl1,
+		     (AST_TMC_EN | AST_TMC_1MHZ) <<
+		     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+
+	uc_priv->clock_rate = AST_TMC_RATE;
+
+	return 0;
+}
+
+static int ast_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+
+	*count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
+
+	return 0;
+}
+
+static int ast_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = (struct ast_timer *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static const struct timer_ops ast_timer_ops = {
+	.get_count = ast_timer_get_count,
+};
+
+static const struct udevice_id ast_timer_ids[] = {
+	{ .compatible = "aspeed,ast2500-timer" },
+	{ .compatible = "aspeed,ast2400-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(sandbox_timer) = {
+	.name = "ast_timer",
+	.id = UCLASS_TIMER,
+	.of_match = ast_timer_ids,
+	.probe = ast_timer_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_timer_priv),
+	.ofdata_to_platdata = ast_timer_ofdata_to_platdata,
+	.ops = &ast_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (2 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 03/12] aspeed: Add Timer Support Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks Maxim Sloyko
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

The driver uses watchdog timer to do resets and particular
watchdog device to use is hardcoded (0)

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 drivers/sysreset/Makefile       |  1 +
 drivers/sysreset/sysreset_ast.c | 55 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 drivers/sysreset/sysreset_ast.c

diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index fa75cc52de..37638a8eea 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
new file mode 100644
index 0000000000..a0ab12851d
--- /dev/null
+++ b/drivers/sysreset/sysreset_ast.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+/* Number of Watchdog Timer ticks before reset */
+#define AST_WDT_RESET_TIMEOUT	10
+#define AST_WDT_FOR_RESET	0
+
+static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
+	u32 reset_mode = 0;
+
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		reset_mode = WDT_CTRL_RESET_CPU;
+		break;
+	case SYSRESET_COLD:
+		reset_mode = WDT_CTRL_RESET_CHIP;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	/* Clear reset mode bits */
+	clrsetbits_le32(&wdt->ctrl,
+			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
+			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
+	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops ast_sysreset = {
+	.request	= ast_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_ast) = {
+	.name	= "ast_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &ast_sysreset,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (3 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-04 20:58   ` Tom Rini
  2017-01-04 19:46 ` [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver Maxim Sloyko
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/ast2500-scu.h |  29 +++
 2 files changed, 452 insertions(+)
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
new file mode 100644
index 0000000000..1a2a3f7ee3
--- /dev/null
+++ b/arch/arm/dts/ast2500.dtsi
@@ -0,0 +1,423 @@
+/* This device tree is copied from
+ * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
+ */
+
+#include <dt-bindings/clock/ast2500-scu.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Aspeed BMC";
+	compatible = "aspeed,ast2500";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&vic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,arm1176jzf-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	scu: clock-controller at 1e6e2000 {
+		compatible = "aspeed,ast2500-scu";
+		reg = <0x1e6e2000 0x1000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	sdrammc: sdrammc at 1e6e0000 {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-sdrammc";
+		reg = <0x1e6e0000 0x174
+			0x1e6e0200 0x1d4 >;
+		clocks = <&scu PLL_MPLL>;
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		u-boot,dm-pre-reloc;
+
+		fmc: flash-controller at 1e620000 {
+			reg = < 0x1e620000 0xc4
+				0x20000000 0x10000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2500-fmc";
+			status = "disabled";
+			aspeed,fmc-has-dma;
+			interrupts = <19>;
+			flash at 0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+			flash at 1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+			flash at 2 {
+				reg = < 2 >;
+				compatible = "jedec,spi-nor";
+				// compatible = "cfi,flash", "jedec,flash";
+				status = "disabled";
+			};
+		};
+
+		spi1: flash-controller at 1e630000 {
+			reg = < 0x1e630000 0xc4
+				0x30000000 0x08000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2500-smc";
+			status = "disabled";
+			flash at 0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+			flash at 1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+		};
+
+		spi2: flash-controller at 1e631000 {
+			reg = < 0x1e631000 0xc4
+				0x38000000 0x08000000 >;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "aspeed,ast2500-smc";
+			status = "disabled";
+			flash at 0 {
+				reg = < 0 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+			flash at 1 {
+				reg = < 1 >;
+				compatible = "jedec,spi-nor";
+				status = "disabled";
+			};
+		};
+
+		vic: interrupt-controller at 1e6c0080 {
+			compatible = "aspeed,ast2400-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			valid-sources = <0xfefff7ff 0x0807ffff>;
+			reg = <0x1e6c0080 0x80>;
+		};
+
+		mac0: ethernet at 1e660000 {
+			compatible = "faraday,ftgmac100";
+			reg = <0x1e660000 0x180>;
+			interrupts = <2>;
+			no-hw-checksum;
+			status = "disabled";
+		};
+
+		mac1: ethernet at 1e680000 {
+			compatible = "faraday,ftgmac100";
+			reg = <0x1e680000 0x180>;
+			interrupts = <3>;
+			no-hw-checksum;
+			status = "disabled";
+		};
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			u-boot,dm-pre-reloc;
+
+			syscon: syscon at 1e6e2000 {
+				compatible = "aspeed,g5-scu", "syscon", "simple-mfd";
+				reg = <0x1e6e2000 0x1a8>;
+			};
+
+			sram at 1e720000 {
+				compatible = "mmio-sram";
+				reg = <0x1e720000 0x9000>;	// 36K
+			};
+
+			gpio: gpio at 1e780000 {
+				#gpio-cells = <2>;
+				gpio-controller;
+				compatible = "aspeed,ast2500-gpio";
+				reg = <0x1e780000 0x1000>;
+				interrupts = <20>;
+			};
+
+			timer: timer at 1e782000 {
+				compatible = "aspeed,ast2500-timer";
+				u-boot,dm-pre-reloc;
+				reg = <0x1e782000 0x90>;
+			};
+
+			ibt: ibt at 1e789140 {
+				compatible = "aspeed,bt-host";
+				reg = <0x1e789140 0x18>;
+				interrupts = <8>;
+			};
+
+			wdt1: wdt at 1e785000 {
+				compatible = "aspeed,ast2500-wdt";
+				reg = <0x1e785000 0x1c>;
+			};
+
+			wdt2: wdt at 1e785020 {
+				compatible = "aspeed,ast2500-wdt";
+				reg = <0x1e785020 0x1c>;
+				status = "disabled";
+			};
+
+			wdt3: wdt at 1e785040 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785074 0x1c>;
+				status = "disabled";
+			};
+
+			uart1: serial at 1e783000 {
+				compatible = "ns16550a";
+				reg = <0x1e783000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <9>;
+				clocks = <&scu PCLK_UART1>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart2: serial at 1e78d000 {
+				compatible = "ns16550a";
+				reg = <0x1e78d000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <32>;
+				clocks = <&scu PCLK_UART2>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart3: serial at 1e78e000 {
+				compatible = "ns16550a";
+				reg = <0x1e78e000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <33>;
+				clocks = <&scu PCLK_UART3>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart4: serial at 1e78f000 {
+				compatible = "ns16550a";
+				reg = <0x1e78f000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <34>;
+				clocks = <&scu PCLK_UART4>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart5: serial at 1e784000 {
+				compatible = "ns16550a";
+				reg = <0x1e784000 0x1000>;
+				interrupts = <10>;
+				reg-shift = <2>;
+				clocks = <&scu PCLK_UART5>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			vuart: vuart at 1e787000 {
+				compatible = "aspeed,vuart";
+				reg = <0x1e787000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <8>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			i2c: i2c at 1e78a000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				#interrupt-cells = <1>;
+
+				compatible = "aspeed,ast2400-i2c-controller";
+				reg = <0x1e78a000 0x40>;
+				ranges = <0 0x1e78a000 0x1000>;
+				interrupts = <12>;
+				clock-ranges;
+				interrupt-controller;
+
+				i2c0: i2c-bus at 40 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x40 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <0>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <0>;
+					interrupt-parent = <&i2c>;
+				};
+
+				i2c1: i2c-bus at 80 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x80 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <1>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <1>;
+				};
+
+				i2c2: i2c-bus at c0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0xC0 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <2>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <2>;
+				};
+
+				i2c3: i2c-bus at 100 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x100 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <3>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <3>;
+				};
+
+				i2c4: i2c-bus at 140 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x140 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <4>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <4>;
+				};
+
+				i2c5: i2c-bus at 180 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x180 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <5>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <5>;
+				};
+
+				i2c6: i2c-bus at 1c0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x1C0 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <6>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <6>;
+				};
+
+				i2c7: i2c-bus at 300 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x300 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <7>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <7>;
+				};
+
+				i2c8: i2c-bus at 340 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x340 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <8>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <8>;
+				};
+
+				i2c9: i2c-bus at 380 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x380 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <9>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <9>;
+				};
+
+				i2c10: i2c-bus at 3c0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x3c0 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <10>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <10>;
+				};
+
+				i2c11: i2c-bus at 400 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x400 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <11>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <11>;
+				};
+
+				i2c12: i2c-bus at 440 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x440 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <12>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <12>;
+				};
+
+				i2c13: i2c-bus at 480 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x480 0x40>;
+					compatible = "aspeed,ast2400-i2c-bus";
+					bus = <13>;
+					clock-frequency = <100000>;
+					status = "disabled";
+					interrupts = <13>;
+				};
+
+			};
+
+		};
+	};
+};
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
new file mode 100644
index 0000000000..ca58b12943
--- /dev/null
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Core Clocks */
+#define PLL_HPLL	1
+#define PLL_DPLL	2
+#define PLL_D2PLL	3
+#define PLL_MPLL	4
+#define ARMCLK		5
+
+
+/* Bus Clocks, derived from core clocks */
+#define BCLK_PCLK	101
+#define BCLK_LHCLK	102
+#define BCLK_MACCLK	103
+#define BCLK_SDCLK	104
+#define BCLK_ARMCLK	105
+
+#define MCLK_DDR	201
+
+/* Special clocks */
+#define PCLK_UART1	501
+#define PCLK_UART2	502
+#define PCLK_UART3	503
+#define PCLK_UART4	504
+#define PCLK_UART5	505
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (4 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU Maxim Sloyko
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

This driver is ast2500 specific and is not compatible with earlier
versions of this chip. The differences are not that large, but they are
in somewhat random places, so making it compatible with ast2400 is not
worth the effort at the moment.

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 108 +++++++++++
 drivers/clk/Makefile                           |   2 +
 drivers/clk/aspeed/Makefile                    |   7 +
 drivers/clk/aspeed/clk_ast2500.c               | 255 +++++++++++++++++++++++++
 4 files changed, 372 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c

diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
new file mode 100644
index 0000000000..febff9d2d3
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -0,0 +1,108 @@
+#ifndef _ASM_ARCH_SCU_AST2500_H
+#define _ASM_ARCH_SCU_AST2500_H
+
+#define SCU_UNLOCK_VALUE		0x1688a8a8
+
+#define SCU_HWSTRAP_VGAMEM_MASK		3
+#define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_DDR4		(1 << 24)
+#define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
+
+#define SCU_MPLL_DENUM_SHIFT		0
+#define SCU_MPLL_DENUM_MASK		0x1f
+#define SCU_MPLL_NUM_SHIFT		5
+#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_POST_SHIFT		13
+#define SCU_MPLL_POST_MASK		0x3f
+
+#define SCU_HPLL_DENUM_SHIFT		0
+#define SCU_HPLL_DENUM_MASK		0x1f
+#define SCU_HPLL_NUM_SHIFT		5
+#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_POST_SHIFT		13
+#define SCU_HPLL_POST_MASK		0x3f
+
+#define SCU_MISC2_UARTCLK_SHIFT		24
+
+#define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_clk_priv {
+	struct ast2500_scu *scu;
+};
+
+struct ast2500_scu {
+	u32 protection_key;
+	u32 sysreset_ctrl1;
+	u32 clk_sel1;
+	u32 clk_stop_ctrl1;
+	u32 freq_counter_ctrl;
+	u32 freq_counter_cmp;
+	u32 intr_ctrl;
+	u32 d2_pll_param;
+	u32 m_pll_param;
+	u32 h_pll_param;
+	u32 d_pll_param;
+	u32 misc_ctrl1;
+	u32 pci_config[3];
+	u32 sysreset_status;
+	u32 vga_handshake[2];
+	u32 mac_clk_delay;
+	u32 misc_ctrl2;
+	u32 vga_scratch[8];
+	u32 hwstrap;
+	u32 rng_ctrl;
+	u32 rng_data;
+	u32 rev_id;
+	u32 pinmux_ctrl[6];
+	u32 reserved0;
+	u32 extrst_sel;
+	u32 pinmux_ctrl1[4];
+	u32 reserved1[2];
+	u32 mac_clk_delay_100M;
+	u32 mac_clk_delay_10M;
+	u32 wakeup_enable;
+	u32 wakeup_control;
+	u32 reserved2[3];
+	u32 sysreset_ctrl2;
+	u32 clk_sel2;
+	u32 clk_stop_ctrl2;
+	u32 freerun_counter;
+	u32 freerun_counter_ext;
+	u32 clk_duty_meas_ctrl;
+	u32 clk_duty_meas_res;
+	u32 reserved3[4];
+	/* The next registers are not key protected */
+	struct ast2500_cpu2 {
+		u32 ctrl;
+		u32 base_addr[9];
+		u32 cache_ctrl;
+	} cpu2;
+	u32 reserved4;
+	u32 d_pll_ext_param[3];
+	u32 d2_pll_ext_param[3];
+	u32 mh_pll_ext_param;
+	u32 reserved5;
+	u32 chip_id[2];
+	u32 reserved6[2];
+	u32 uart_clk_ctrl;
+	u32 reserved7[7];
+	u32 pcie_config;
+	u32 mmio_decode;
+	u32 reloc_ctrl_decode[2];
+	u32 mailbox_addr;
+	u32 shared_sram_decode[2];
+	u32 bmc_rev_id;
+	u32 reserved8;
+	u32 bmc_device_id;
+	u32 reserved9[13];
+	u32 clk_duty_sel;
+};
+
+int ast_get_clk(struct udevice **devp);
+void *ast_get_scu(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 40a5e8cae8..625513789c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
new file mode 100644
index 0000000000..65d1cd6e29
--- /dev/null
+++ b/drivers/clk/aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
new file mode 100644
index 0000000000..c888a6d35b
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ */
+
+/*
+ * Get the rate of the M-PLL clock from input clock frequency and
+ * the value of the M-PLL Parameter Register.
+ */
+static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
+{
+	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
+	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
+			& SCU_MPLL_DENUM_MASK;
+	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
+			& SCU_MPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+/*
+ * Get the rate of the H-PLL clock from input clock frequency and
+ * the value of the H-PLL Parameter Register.
+ */
+static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
+{
+	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
+	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
+			& SCU_HPLL_DENUM_MASK;
+	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
+			& SCU_HPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+static ulong ast2500_get_clkin(struct ast2500_scu *scu)
+{
+	return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
+			? 25*1000*1000 : 24*1000*1000;
+}
+
+static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart)
+{
+	/*
+	 * ast2500 datasheet is very confusing when it comes to UART clocks,
+	 * especially when CLKIN = 25 MHz. The settings are in
+	 * different registers and it is unclear how they interact.
+	 *
+	 * This has only been tested with default settings and CLKIN = 24 MHz.
+	 */
+	ulong uart_clkin;
+
+	if (readl(&scu->misc_ctrl2) & (1 << (uart + SCU_MISC2_UARTCLK_SHIFT)))
+		uart_clkin = 192 * 1000 * 1000;
+	else
+		uart_clkin = 24 * 1000 * 1000;
+
+	if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
+		uart_clkin /= 13;
+
+	return uart_clkin;
+}
+
+static ulong ast2500_clk_get_rate(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong clkin = ast2500_get_clkin(priv->scu);
+	ulong rate;
+
+	switch (clk->id) {
+	case PLL_HPLL:
+	case ARMCLK:
+		/*
+		 * This ignores dynamic/static slowdown of ARMCLK and may
+		 * be inaccurate.
+		 */
+		rate = ast2500_get_hpll_rate(clkin,
+					     readl(&priv->scu->h_pll_param));
+		break;
+	case MCLK_DDR:
+		rate = ast2500_get_mpll_rate(clkin,
+					     readl(&priv->scu->m_pll_param));
+		break;
+	case PCLK_UART1:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
+		break;
+	case PCLK_UART2:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 2);
+		break;
+	case PCLK_UART3:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 3);
+		break;
+	case PCLK_UART4:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 4);
+		break;
+	case PCLK_UART5:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 5);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static void ast2500_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+static void ast2500_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
+
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+
+	/*
+	 * There are not that many combinations of numerator, denumerator
+	 * and post divider, so just brute force the best combination.
+	 * However, to avoid overflow when multiplying, use kHz.
+	 */
+	const ulong clkin_khz = clkin / 1000;
+	const ulong rate_khz = rate / 1000;
+
+	ulong best_num = 0;
+	ulong best_denum = 0;
+	ulong best_post = 0;
+	ulong delta = rate;
+
+	ulong num, denum, post;
+	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
+		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
+			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
+			ulong new_rate_khz = (clkin_khz
+					      * ((num + 1) / (denum + 1)))
+					     / (post + 1);
+
+			/* Keep the rate below requested one. */
+			if (new_rate_khz > rate_khz)
+				continue;
+
+			if (new_rate_khz - rate_khz < delta) {
+				delta = new_rate_khz - rate_khz;
+
+				best_num = num;
+				best_denum = denum;
+				best_post = post;
+
+				if (delta == 0)
+					goto rate_calc_done;
+			}
+		}
+	}
+
+ rate_calc_done:
+
+	mpll_reg = readl(&scu->m_pll_param);
+	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
+		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
+		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
+	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
+	    | (best_num << SCU_MPLL_NUM_SHIFT)
+	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+
+	ast2500_scu_unlock(scu);
+	writel(mpll_reg, &scu->m_pll_param);
+	ast2500_scu_lock(scu);
+
+	return ast2500_get_mpll_rate(clkin, mpll_reg);
+}
+
+static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong new_rate;
+	switch (clk->id) {
+	case PLL_MPLL:
+	case MCLK_DDR:
+		new_rate = ast2500_configure_ddr(priv->scu, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+struct clk_ops ast2500_clk_ops = {
+	.get_rate = ast2500_clk_get_rate,
+	.set_rate = ast2500_clk_set_rate,
+};
+
+static int ast2500_clk_probe(struct udevice *dev)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(dev);
+	priv->scu = (struct ast2500_scu *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static int ast2500_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+	if (ret)
+		debug("Warning: No reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_clk_ids[] = {
+	{ .compatible = "aspeed,ast2500-scu" },
+	{ }
+};
+
+U_BOOT_DRIVER(aspeed_ast2500_scu) = {
+	.name		= "aspeed_ast2500_scu",
+	.id		= UCLASS_CLK,
+	.of_match	= ast2500_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
+	.ops		= &ast2500_clk_ops,
+	.bind		= ast2500_clk_bind,
+	.probe		= ast2500_clk_probe,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (5 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver Maxim Sloyko
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Helper function to get access to SCU (System Control Unit) through Clock
driver. This is similar to rockchip_get_cru function, which was used as
an example.

It will be used by other drivers to get access to SCU.

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/mach-aspeed/Kconfig               |  2 ++
 arch/arm/mach-aspeed/Makefile              |  1 +
 arch/arm/mach-aspeed/ast2500/Kconfig       |  6 ++++++
 arch/arm/mach-aspeed/ast2500/Makefile      |  1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c | 31 ++++++++++++++++++++++++++++++
 5 files changed, 41 insertions(+)
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c

diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index 43cdbeda84..4aba39cae5 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -12,4 +12,6 @@ config ASPEED_AST2500
 	help
 	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
 
+source "arch/arm/mach-aspeed/ast2500/Kconfig"
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index a14b8f751d..1f7af71b03 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
new file mode 100644
index 0000000000..c0b448f19e
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -0,0 +1,6 @@
+if ASPEED_AST2500
+
+config SYS_CPU
+	default "arm1176"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
new file mode 100644
index 0000000000..97d4078ddd
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += clk_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
new file mode 100644
index 0000000000..06aca5d63a
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/scu_ast2500.h>
+
+int ast_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(aspeed_ast2500_scu), devp);
+}
+
+void *ast_get_scu(void)
+{
+	struct ast2500_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = ast_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->scu;
+}
+
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (6 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards Maxim Sloyko
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

The driver is very ast2500 specific and is completely incompatible
with previous versions of the chip.

The memory controller is very poorly documented by Aspeed in the
datasheet, with any mention of the whole range of registers missing. The
initialization procedure has been basically taken from Aspeed SDK, where
it is implemented in assembly and rewritten in C, with very limited
understanding of what exacly it is doing.

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 133 +++++++
 arch/arm/mach-aspeed/ast2500/Makefile            |   2 +-
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 3 files changed, 577 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c

diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
new file mode 100644
index 0000000000..ca70898df6
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
@@ -0,0 +1,133 @@
+#ifndef _ASM_ARCH_SDRAM_AST2500_H
+#define _ASM_ARCH_SDRAM_AST2500_H
+
+#define SDRAM_UNLOCK_KEY		0xfc600309
+#define SDRAM_VIDEO_UNLOCK_KEY		0x2003000f
+
+#define SDRAM_PCR_CKE_EN		(1 << 0)
+#define SDRAM_PCR_AUTOPWRDN_EN		(1 << 1)
+#define SDRAM_PCR_CKE_DELAY_SHIFT	4
+#define SDRAM_PCR_CKE_DELAY_MASK	7
+#define SDRAM_PCR_RESETN_DIS		(1 << 7)
+#define SDRAM_PCR_ODT_EN		(1 << 8)
+#define SDRAM_PCR_ODT_AUTO_ON		(1 << 10)
+#define SDRAM_PCR_ODT_EXT_EN		(1 << 11)
+#define SDRAM_PCR_TCKE_PW_SHIFT		12
+#define SDRAM_PCR_TCKE_PW_MASK		7
+#define SDRAM_PCR_RGAP_CTRL_EN		(1 << 15)
+#define SDRAM_PCR_MREQI_DIS		(1 << 17)
+
+/* Fixed priority DRAM Requests mask */
+#define SDRAM_REQ_VGA_HW_CURSOR		(1 << 0)
+#define SDRAM_REQ_VGA_TEXT_CG_FONT	(1 << 1)
+#define SDRAM_REQ_VGA_TEXT_ASCII	(1 << 2)
+#define SDRAM_REQ_VGA_CRT		(1 << 3)
+#define SDRAM_REQ_SOC_DC_CURSOR		(1 << 4)
+#define SDRAM_REQ_SOC_DC_OCD		(1 << 5)
+#define SDRAM_REQ_SOC_DC_CRT		(1 << 6)
+#define SDRAM_REQ_VIDEO_HIPRI_WRITE	(1 << 7)
+#define SDRAM_REQ_USB20_EHCI1		(1 << 8)
+#define SDRAM_REQ_USB20_EHCI2		(1 << 9)
+#define SDRAM_REQ_CPU			(1 << 10)
+#define SDRAM_REQ_AHB2			(1 << 11)
+#define SDRAM_REQ_AHB			(1 << 12)
+#define SDRAM_REQ_MAC0			(1 << 13)
+#define SDRAM_REQ_MAC1			(1 << 14)
+#define SDRAM_REQ_PCIE			(1 << 16)
+#define SDRAM_REQ_XDMA			(1 << 17)
+#define SDRAM_REQ_ENCRYPTION		(1 << 18)
+#define SDRAM_REQ_VIDEO_FLAG		(1 << 21)
+#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE	(1 << 28)
+#define SDRAM_REQ_2D_RW			(1 << 29)
+#define SDRAM_REQ_MEMCHECK		(1 << 30)
+
+#define SDRAM_ICR_RESET_ALL		(1 << 31)
+
+#define SDRAM_CONF_CAP_SHIFT		0
+#define SDRAM_CONF_CAP_MASK		3
+#define SDRAM_CONF_DDR4			(1 << 4)
+#define SDRAM_CONF_SCRAMBLE		(1 << 8)
+#define SDRAM_CONF_SCRAMBLE_PAT2	(1 << 9)
+#define SDRAM_CONF_CACHE_EN		(1 << 10)
+#define SDRAM_CONF_CACHE_INIT_EN	(1 << 12)
+#define SDRAM_CONF_DUALX8		(1 << 13)
+#define SDRAM_CONF_CACHE_INIT_DONE	(1 << 19)
+
+#define SDRAM_CONF_CAP_128M		0
+#define SDRAM_CONF_CAP_256M		1
+#define SDRAM_CONF_CAP_512M		2
+#define SDRAM_CONF_CAP_1024M		3
+
+#define SDRAM_MISC_DDR4_TREFRESH	(1 << 3)
+
+#define SDRAM_PHYCTRL0_INIT		(1 << 0)
+#define SDRAM_PHYCTRL0_AUTO_UPDATE	(1 << 1)
+#define SDRAM_PHYCTRL0_NRST		(1 << 2)
+
+#define SDRAM_REFRESH_CYCLES_SHIFT	0
+#define SDRAM_REFRESH_CYCLES_MASK	0xf
+#define SDRAM_REFRESH_ZQCS_EN		(1 << 7)
+#define SDRAM_REFRESH_PERIOD_SHIFT	8
+#define SDRAM_REFRESH_PERIOD_MASK	0xf
+
+#define SDRAM_TEST_LEN_SHIFT		4
+#define SDRAM_TEST_LEN_MASK		0xfffff
+#define SDRAM_TEST_START_ADDR_SHIFT	24
+#define SDRAM_TEST_START_ADDR_MASK	0x3f
+
+#define SDRAM_TEST_EN			(1 << 0)
+#define SDRAM_TEST_MODE_SHIFT		1
+#define SDRAM_TEST_MODE_MASK		3
+#define SDRAM_TEST_MODE_WO		0
+#define SDRAM_TEST_MODE_RB		1
+#define SDRAM_TEST_MODE_RW		2
+#define SDRAM_TEST_GEN_MODE_SHIFT	3
+#define SDRAM_TEST_GEN_MODE_MASK	7
+#define SDRAM_TEST_TWO_MODES		(1 << 6)
+#define SDRAM_TEST_ERRSTOP		(1 << 7)
+#define SDRAM_TEST_DONE			(1 << 12)
+#define SDRAM_TEST_FAIL			(1 << 13)
+
+#define SDRAM_AC_TRFC_SHIFT		0
+#define SDRAM_AC_TRFC_MASK		0xff
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_sdrammc_regs {
+	u32 protection_key;
+	u32 config;
+	u32 gm_protection_key;
+	u32 refresh_timing;
+	u32 ac_timing[3];
+	u32 misc_control;
+	u32 mr46_mode_setting;
+	u32 mr5_mode_setting;
+	u32 mode_setting_control;
+	u32 mr02_mode_setting;
+	u32 mr13_mode_setting;
+	u32 power_control;
+	u32 req_limit_mask;
+	u32 pri_group_setting;
+	u32 max_grant_len[4];
+	u32 intr_ctrl;
+	u32 ecc_range_ctrl;
+	u32 first_ecc_err_addr;
+	u32 last_ecc_err_addr;
+	u32 phy_ctrl[4];
+	u32 ecc_test_ctrl;
+	u32 test_addr;
+	u32 test_fail_dq_bit;
+	u32 test_init_val;
+	u32 phy_debug_ctrl;
+	u32 phy_debug_data;
+	u32 reserved1[30];
+	u32 scu_passwd;
+	u32 reserved2[7];
+	u32 scu_mpll;
+	u32 reserved3[19];
+	u32 scu_hwstrap;
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
index 97d4078ddd..a35b239ef3 100644
--- a/arch/arm/mach-aspeed/ast2500/Makefile
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -1 +1 @@
-obj-y += clk_ast2500.o
+obj-y += clk_ast2500.o sdram_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
new file mode 100644
index 0000000000..da25756e94
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *
+ * Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:		GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/sdram_ast2500.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <regmap.h>
+
+/* These configuration parameters are taken from Aspeed SDK */
+#define DDR4_MR46_MODE		0x08000000
+#define DDR4_MR5_MODE		0x400
+#define DDR4_MR13_MODE		0x101
+#define DDR4_MR02_MODE		0x410
+#define DDR4_TRFC		0x45457188
+
+#define PHY_CFG_SIZE		15
+
+static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
+static const struct {
+	u32 index[PHY_CFG_SIZE];
+	u32 value[PHY_CFG_SIZE];
+} ddr4_phy_config = {
+	.index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
+	.value = {
+		0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
+		0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
+		0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
+	},
+};
+
+#define SDRAM_MAX_SIZE		(1024 * 1024 * 1024)
+#define SDRAM_MIN_SIZE		(128 * 1024 * 1024)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Bandwidth configuration parameters for different SDRAM requests.
+ * These are hardcoded settings taken from Aspeed SDK.
+ */
+static const u32 ddr_max_grant_params[4] = {
+	0x88448844, 0x24422288, 0x22222222, 0x22222222
+};
+
+/*
+ * These registers are not documented by Aspeed at all.
+ * All writes and reads are taken pretty much as is from SDK.
+ */
+struct ast2500_ddr_phy {
+	u32 phy[117];
+};
+
+struct dram_info {
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct ast2500_sdrammc_regs *regs;
+	struct ast2500_scu *scu;
+	struct ast2500_ddr_phy *phy;
+	ulong clock_rate;
+};
+
+static int ast2500_sdrammc_reset(void)
+{
+	struct ast_wdt *wdt = ast_get_wdt(0);
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	/* Only Reset SDRAM */
+	writel(WDT_RESET_SDRAM, &wdt->reset_mask);
+	clrbits_le32(&wdt->ctrl,
+		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
+	wdt_start(wdt, 1);
+
+	/* Wait for WDT to reset */
+	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+		;
+	wdt_stop(wdt);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
+{
+	writel(0, &phy->phy[2]);
+	writel(0, &phy->phy[6]);
+	writel(0, &phy->phy[8]);
+	writel(0, &phy->phy[10]);
+	writel(0, &phy->phy[12]);
+	writel(0, &phy->phy[42]);
+	writel(0, &phy->phy[44]);
+
+	writel(0x86000000, &phy->phy[16]);
+	writel(0x00008600, &phy->phy[17]);
+	writel(0x80000000, &phy->phy[18]);
+	writel(0x80808080, &phy->phy[19]);
+
+	return 0;
+}
+
+static void ast2500_ddr_phy_init_process(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	writel(0, &regs->phy_ctrl[0]);
+	writel(0x4040, &info->phy->phy[51]);
+
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
+	while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
+		;
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
+	       &regs->phy_ctrl[0]);
+}
+
+static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
+{
+	writel(0, &info->regs->phy_ctrl[0]);
+	writel((vref << 8) | 0x6, &info->phy->phy[48]);
+	ast2500_ddr_phy_init_process(info);
+}
+
+static int ast2500_ddr_cbr_test(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	int i;
+	const u32 test_params = SDRAM_TEST_EN
+			| SDRAM_TEST_ERRSTOP
+			| SDRAM_TEST_TWO_MODES;
+	int ret = 0;
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
+	       (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
+	writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
+	writel(0xff00ff00, &regs->test_init_val);
+	writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
+	       SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
+
+	while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+		;
+
+	if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+		ret = -EIO;
+	} else {
+		for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
+			writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
+			       &regs->ecc_test_ctrl);
+			while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+				;
+			if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+				ret = -EIO;
+				break;
+			}
+		}
+	}
+
+	writel(0, &regs->refresh_timing);
+	writel(0, &regs->ecc_test_ctrl);
+	return ret;
+}
+
+static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
+{
+	int i;
+	int vref_min = 0xff;
+	int vref_max = 0;
+	int range_size = 0;
+
+	for (i = 1; i < 0x40; ++i) {
+		ast2500_sdrammc_set_vref(info, i);
+
+		int res = ast2500_ddr_cbr_test(info);
+		if (res < 0) {
+			if (range_size > 0)
+				break;
+		} else {
+			++range_size;
+			vref_min = min(vref_min, i);
+			vref_max = max(vref_max, i);
+		}
+	}
+
+	/* Pick average setting */
+	ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
+
+	return 0;
+}
+
+static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
+{
+	size_t vga_mem_size_base = 8 * 1024 * 1024;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap)
+			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
+			& SCU_HWSTRAP_VGAMEM_MASK;
+
+	return vga_mem_size_base << vga_hwconf;
+}
+
+/*
+ * Find out RAM size and save it in dram_info
+ *
+ * The procedure is taken from Aspeed SDK
+ */
+static void ast2500_sdrammc_calc_size(struct dram_info *info)
+{
+	/* The controller supports 128/256/512/1024 MB ram */
+	size_t ram_size = SDRAM_MIN_SIZE;
+	const int write_test_offset = 0x100000;
+	u32 test_pattern = 0xdeadbeef;
+	u32 cap_param = SDRAM_CONF_CAP_1024M;
+	u32 refresh_timing_param = DDR4_TRFC;
+	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
+
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		writel(test_pattern, write_addr_base + (ram_size >> 1));
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	/* One last write to overwrite all wrapped values */
+	writel(test_pattern, write_addr_base);
+
+	/* Reset the pattern and see which value was really written */
+	test_pattern = 0xdeadbeef;
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
+			break;
+
+		--cap_param;
+		refresh_timing_param >>= 8;
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	clrsetbits_le32(&info->regs->ac_timing[1],
+			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
+			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
+			 << SDRAM_AC_TRFC_SHIFT));
+
+	info->info.base = CONFIG_SYS_SDRAM_BASE;
+	info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
+	clrsetbits_le32(&info->regs->config,
+			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
+			((cap_param & SDRAM_CONF_CAP_MASK)
+			 << SDRAM_CONF_CAP_SHIFT));
+}
+
+static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
+{
+	int i;
+	const u32 power_control = SDRAM_PCR_CKE_EN
+	    | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
+	    | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
+	    | SDRAM_PCR_RESETN_DIS
+	    | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
+	const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
+#ifdef CONFIG_DUALX8_RAM
+	    | SDRAM_CONF_DUALX8
+#endif
+	    | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
+
+	writel(conf, &info->regs->config);
+	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
+		writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
+
+	writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
+	writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
+	writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
+	writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
+
+	for (i = 0; i < PHY_CFG_SIZE; ++i) {
+		writel(ddr4_phy_config.value[i],
+		       &info->phy->phy[ddr4_phy_config.index[i]]);
+	}
+
+	writel(power_control, &info->regs->power_control);
+
+	ast2500_ddr_phy_init_process(info);
+
+	int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
+	if (ret < 0) {
+		debug("Vref calibration failed!\n");
+		return ret;
+	}
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
+	       | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
+	       &info->regs->refresh_timing);
+
+	setbits_le32(&info->regs->power_control,
+		     SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
+
+	ast2500_sdrammc_calc_size(info);
+
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
+	while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
+		;
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
+
+	writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
+
+	/* Enable all requests except video & display */
+	writel(SDRAM_REQ_USB20_EHCI1
+	       | SDRAM_REQ_USB20_EHCI2
+	       | SDRAM_REQ_CPU
+	       | SDRAM_REQ_AHB2
+	       | SDRAM_REQ_AHB
+	       | SDRAM_REQ_MAC0
+	       | SDRAM_REQ_MAC1
+	       | SDRAM_REQ_PCIE
+	       | SDRAM_REQ_XDMA
+	       | SDRAM_REQ_ENCRYPTION
+	       | SDRAM_REQ_VIDEO_FLAG
+	       | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
+	       | SDRAM_REQ_2D_RW
+	       | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
+
+	return 0;
+}
+
+static void ast2500_sdrammc_unlock(struct dram_info *info)
+{
+	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (!readl(&info->regs->protection_key))
+		;
+}
+
+static void ast2500_sdrammc_lock(struct dram_info *info)
+{
+	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (readl(&info->regs->protection_key))
+		;
+}
+
+static int ast2500_sdrammc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
+	struct ast2500_sdrammc_regs *regs = priv->regs;
+	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+	int i;
+
+	if (ret) {
+		debug("DDR:No CLK\n");
+		return ret;
+	}
+
+	priv->scu = ast_get_scu();
+	if (IS_ERR(priv->scu))
+		return PTR_ERR(priv->scu);
+
+	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
+	ret = ast2500_sdrammc_reset();
+	if (ret)
+		return ret;
+
+	ast2500_sdrammc_unlock(priv);
+
+	writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
+	       &regs->power_control);
+	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
+
+	/* Mask all requests except CPU and AHB during PHY init */
+	writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
+
+	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
+		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
+
+	setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+
+	ast2500_sdrammc_init_phy(priv->phy);
+	if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
+		ast2500_sdrammc_init_ddr4(priv);
+	} else {
+		debug("Unsupported DRAM3\n");
+		return -EINVAL;
+	}
+
+	clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+	ast2500_sdrammc_lock(priv);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret = regmap_init_mem(dev, &map);
+
+	if (ret)
+		return ret;
+
+	priv->regs = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "clock-frequency", 0);
+
+	if (!priv->clock_rate) {
+		debug("DDR Clock Rate not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops ast2500_sdrammc_ops = {
+	.get_info = ast2500_sdrammc_get_info,
+};
+
+static const struct udevice_id ast2500_sdrammc_ids[] = {
+	{ .compatible = "aspeed,ast2500-sdrammc" },
+	{ }
+};
+
+U_BOOT_DRIVER(sdrammc_ast2500) = {
+	.name = "aspeed_ast2500_sdrammc",
+	.id = UCLASS_RAM,
+	.of_match = ast2500_sdrammc_ids,
+	.ops = &ast2500_sdrammc_ops,
+	.ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
+	.probe = ast2500_sdrammc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (7 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards Maxim Sloyko
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/mach-aspeed/Makefile        |  2 +-
 arch/arm/mach-aspeed/ast2500-board.c | 74 ++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c

diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 1f7af71b03..9d29ff7f6f 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
new file mode 100644
index 0000000000..5b2b0ce132
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -0,0 +1,74 @@
+#include <common.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+#include <ram.h>
+#include <timer.h>
+
+/* Second Watchdog Timer by default is configured
+ * to trigger secondary boot source.
+ */
+#define AST_2ND_BOOT_WDT		(1)
+
+/* Third Watchdog Timer by default is configured
+ * to toggle Flash address mode switch before reset.
+ */
+#define AST_FLASH_ADDR_DETECT_WDT	(2)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void lowlevel_init(void)
+{
+	/*
+	 * These two watchdogs need to be stopped as soon as possible,
+	 * otherwise the board might hang. By default they are set to
+	 * a very short timeout and even simple debug write to serial
+	 * console early in the init process might cause them to fire.
+	 */
+	struct ast_wdt *flash_addr_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_FLASH_ADDR_DETECT_WDT);
+
+	clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
+
+#ifndef CONFIG_FIRMWARE_2ND_BOOT
+	struct ast_wdt *sec_boot_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_2ND_BOOT_WDT);
+
+	clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
+#endif
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct udevice *dev;
+	int ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM FAIL1\r\n");
+		return ret;
+	}
+
+	struct ram_info ram;
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("DRAM FAIL2\r\n");
+		return ret;
+	}
+
+
+	gd->ram_size = ram.size;
+	return 0;
+}
+
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (8 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board Maxim Sloyko
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 include/configs/aspeed-common.h | 84 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 include/configs/aspeed-common.h

diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
new file mode 100644
index 0000000000..c125e39e3f
--- /dev/null
+++ b/include/configs/aspeed-common.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 IBM Corporation
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __AST_COMMON_CONFIG_H
+#define __AST_COMMON_CONFIG_H
+
+/* Misc CPU related */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_CMDLINE_EDITING		1
+
+/* Enable cache controller */
+#define CONFIG_SYS_DCACHE_OFF		1
+
+#ifdef CONFIG_PRE_CON_BUF_SZ
+#define PRE_CON_RAM_SZ		CONFIG_PRE_CON_BUF_SZ
+#else
+#define PRE_CON_RAM_SZ	0
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000 + PRE_CON_RAM_SZ)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024 - PRE_CON_RAM_SZ)
+#define SYS_INIT_RAM_END		(CONFIG_SYS_INIT_RAM_ADDR \
+					 + CONFIG_SYS_INIT_RAM_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(SYS_INIT_RAM_END \
+					 - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE \
+					 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_TEXT_BASE		0x00000000
+
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_SUBNETMASK
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE		256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					 + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+#define CONFIG_BOOTARGS \
+		"console=ttyS4,115200n8" \
+		" root=/dev/ram rw"
+
+#define CONFIG_BOOTCOMMAND		"bootm 20080000 20300000"
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=yes\0"	\
+	"spi_dma=yes\0" \
+	""
+
+#endif	/* __AST_COMMON_CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (9 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 19:46 ` [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board Maxim Sloyko
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Maxim Sloyko <maxims@google.com>
---

 arch/arm/dts/Makefile        |  2 ++
 arch/arm/dts/ast2500-evb.dts | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f43746966c..1bee50e237 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb
 
+dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
new file mode 100644
index 0000000000..b1a415f7d7
--- /dev/null
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "ast2500.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&sdrammc {
+	clock-frequency = <400000000>;
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (10 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board Maxim Sloyko
@ 2017-01-04 19:46 ` Maxim Sloyko
  2017-01-14 17:14   ` Simon Glass
  2017-01-04 20:26 ` [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and " Tom Rini
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 19:46 UTC (permalink / raw)
  To: u-boot

---

---

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
 board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
 board/aspeed/evb_ast2500/Makefile      |  1 +
 board/aspeed/evb_ast2500/evb_ast2500.c |  1 +
 configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
 include/configs/evb_ast2500.h          | 30 ++++++++++++++++++++++++++++++
 6 files changed, 72 insertions(+)
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 include/configs/evb_ast2500.h

diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
index c0b448f19e..7397d0c179 100644
--- a/arch/arm/mach-aspeed/ast2500/Kconfig
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -3,4 +3,11 @@ if ASPEED_AST2500
 config SYS_CPU
 	default "arm1176"
 
+config TARGET_EVB_AST2500
+	bool "Evb-AST2500"
+	help
+	  Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
+
+source "board/aspeed/evb_ast2500/Kconfig"
+
 endif
diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
new file mode 100644
index 0000000000..73a8ae85f6
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2500
+
+config SYS_BOARD
+	default "evb_ast2500"
+
+config SYS_VENDOR
+	default "aspeed"
+
+config SYS_CONFIG_NAME
+	default "evb_ast2500"
+
+endif
diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
new file mode 100644
index 0000000000..4564098299
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2500.o
diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
new file mode 100644
index 0000000000..65e11030d8
--- /dev/null
+++ b/board/aspeed/evb_ast2500/evb_ast2500.c
@@ -0,0 +1 @@
+#include <common.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
new file mode 100644
index 0000000000..4598f6f418
--- /dev/null
+++ b/configs/evb-ast2500_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_ASPEED_AST2500=y
+CONFIG_TARGET_EVB_AST2500=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_CLK=y
+CONFIG_TIMER=y
+CONFIG_RAM=y
+CONFIG_REGMAP=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x1e720000
+CONFIG_PRE_CON_BUF_SZ=4096
+CONFIG_SYS_NO_FLASH=y
+CONFIG_CMD_IMLS=n
diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
new file mode 100644
index 0000000000..28d11a2bdf
--- /dev/null
+++ b/include/configs/evb_ast2500.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 Google Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+
+#define CONFIG_SYS_MEMTEST_START	(CONFIG_SYS_SDRAM_BASE + 0x300000)
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x5000000)
+
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/*
+ * Memory Info
+ */
+#define CONFIG_SYS_LOAD_ADDR		0x83000000
+
+#define CONFIG_ENV_IS_NOWHERE		1
+
+#define CONFIG_ENV_SIZE			0x20000
+
+#endif	/* __CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig
  2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
@ 2017-01-04 19:58   ` Rick Altherr
  2017-01-04 20:23     ` Tom Rini
  2017-01-14 17:13   ` Simon Glass
  1 sibling, 1 reply; 90+ messages in thread
From: Rick Altherr @ 2017-01-04 19:58 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 4, 2017 at 11:46 AM, Maxim Sloyko <maxims@google.com> wrote:

> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/Kconfig              |  7 +++++++
>  arch/arm/Makefile             |  1 +
>  arch/arm/mach-aspeed/Kconfig  | 15 +++++++++++++++
>  arch/arm/mach-aspeed/Makefile |  8 ++++++++
>  4 files changed, 31 insertions(+)
>  create mode 100644 arch/arm/mach-aspeed/Kconfig
>  create mode 100644 arch/arm/mach-aspeed/Makefile
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 714dd8b514..135c544335 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
>         select OF_CONTROL
>         select SYS_CACHE_SHIFT_7
>
> +config ARCH_ASPEED
> +       bool "Support Aspeed SoCs"
> +       select OF_CONTROL
> +       select DM
> +
>  endchoice
>
> +source "arch/arm/mach-aspeed/Kconfig"
> +
>  source "arch/arm/mach-at91/Kconfig"
>
>  source "arch/arm/mach-bcm283x/Kconfig"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 236debb452..cc73e1038e 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
>
>  # Machine directory name.  This list is sorted alphanumerically
>  # by CONFIG_* macro name.
> +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
>  machine-$(CONFIG_ARCH_AT91)            += at91
>  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
>  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> new file mode 100644
> index 0000000000..43cdbeda84
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Kconfig
> @@ -0,0 +1,15 @@
> +if ARCH_ASPEED
> +
> +config SYS_ARCH
> +       default "arm"
> +
> +config SYS_SOC
> +       default "aspeed"
> +
> +config ASPEED_AST2500
> +       bool "Support Aspeed AST2500 SoC"
> +       select CPU_ARM1176
> +       help
> +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
> +
> +endif
> diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
> new file mode 100644
> index 0000000000..8e276b4a9f
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Makefile
> @@ -0,0 +1,8 @@
> +#
> +# Copyright (c) 2014 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
>

These files don't exist yet.


> --
> 2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig
  2017-01-04 19:58   ` Rick Altherr
@ 2017-01-04 20:23     ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:23 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:58:17AM -0800, Rick Altherr wrote:
> On Wed, Jan 4, 2017 at 11:46 AM, Maxim Sloyko <maxims@google.com> wrote:
> 
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/Kconfig              |  7 +++++++
> >  arch/arm/Makefile             |  1 +
> >  arch/arm/mach-aspeed/Kconfig  | 15 +++++++++++++++
> >  arch/arm/mach-aspeed/Makefile |  8 ++++++++
> >  4 files changed, 31 insertions(+)
> >  create mode 100644 arch/arm/mach-aspeed/Kconfig
> >  create mode 100644 arch/arm/mach-aspeed/Makefile
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 714dd8b514..135c544335 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
> >         select OF_CONTROL
> >         select SYS_CACHE_SHIFT_7
> >
> > +config ARCH_ASPEED
> > +       bool "Support Aspeed SoCs"
> > +       select OF_CONTROL
> > +       select DM
> > +
> >  endchoice
> >
> > +source "arch/arm/mach-aspeed/Kconfig"
> > +
> >  source "arch/arm/mach-at91/Kconfig"
> >
> >  source "arch/arm/mach-bcm283x/Kconfig"
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index 236debb452..cc73e1038e 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
> >
> >  # Machine directory name.  This list is sorted alphanumerically
> >  # by CONFIG_* macro name.
> > +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
> >  machine-$(CONFIG_ARCH_AT91)            += at91
> >  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
> >  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
> > diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> > new file mode 100644
> > index 0000000000..43cdbeda84
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/Kconfig
> > @@ -0,0 +1,15 @@
> > +if ARCH_ASPEED
> > +
> > +config SYS_ARCH
> > +       default "arm"
> > +
> > +config SYS_SOC
> > +       default "aspeed"
> > +
> > +config ASPEED_AST2500
> > +       bool "Support Aspeed AST2500 SoC"
> > +       select CPU_ARM1176
> > +       help
> > +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
> > +
> > +endif
> > diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
> > new file mode 100644
> > index 0000000000..8e276b4a9f
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/Makefile
> > @@ -0,0 +1,8 @@
> > +#
> > +# Copyright (c) 2014 Google, Inc
> > +#
> > +# SPDX-License-Identifier:     GPL-2.0+
> > +#
> > +
> > +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> > +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
> >
> 
> These files don't exist yet.

Indeed.  The basic answer here is that the series should probably be 4-5
patches long.  I'll reply to 0/12 about my suggestion there, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/da2f2da6/attachment.sig>

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

* [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (11 preceding siblings ...)
  2017-01-04 19:46 ` [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board Maxim Sloyko
@ 2017-01-04 20:26 ` Tom Rini
  2017-01-04 22:47   ` Maxim Sloyko
  2017-01-04 20:58 ` Tom Rini
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
  14 siblings, 1 reply; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:26 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:46:44AM -0800, Maxim Sloyko wrote:

> This series adds minimal support for AST2500 part and eval board,
> enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
> Clock (very basic) and SDRAM MC drivers, all written from scratch,
> using AST2500 datasheet. Aspeed's SDK was used only for reference.
> Given very limited documentation provided by Aspeed, some parts of SDRAM
> init sequence were basically rewritten to do the same thing that is done
> in Aspeed SDK, without real understanding of what is going on.
> 
> The file layout closely follows the example of rk3288 chip and firefly-rk3288
> board.
> 
> For the first round of reviews I'm mostly looking for a nod to add
> mach-aspeed and arch-aspeed directories, as well as for feedback
> on naming, file locations and overall approach.

Thanks for doing this.  I'll review the individual patches for other
changes but in general:

> Maxim Sloyko (12):
>   aspeed: Add mach-aspeed directory and basic Kconfig
>   aspeed: Add support for Watchdot Timer
>   aspeed: Add Timer Support
>   aspeed: Add sysreset driver
>   aspeed/ast2500: Device Tree and bindings for some of the clocks
>   aspeed/ast2500: Add Clock Driver
>   aspeed/ast2500: Helper function to get access to SCU
>   aspeed/ast2500: Add SDRAM MC driver
>   aspeed/ast2500: Common board init functions for ast2500 based boards

This can really be one patch.  Or maybe 2-3 (wdt, timer, sysreset,
everything else).  The stuff that one could lump together and say "this
must be here for the SoC to build and have minimal functionality" is one
patch.  The changes that adds useful functionality is a patch each.

>   aspeed: Common configuration parameters for aspeed boards
>   aspeed: Device Tree for ast2500 Eval Board
>   aspeed: Configuration for ast2500 eval board

Adding the ast2500 EVB would be another single patch.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/9f5dd612/attachment.sig>

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

* [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (12 preceding siblings ...)
  2017-01-04 20:26 ` [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and " Tom Rini
@ 2017-01-04 20:58 ` Tom Rini
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
  14 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:58 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:46:44AM -0800, Maxim Sloyko wrote:

> This series adds minimal support for AST2500 part and eval board,
> enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
> Clock (very basic) and SDRAM MC drivers, all written from scratch,
> using AST2500 datasheet. Aspeed's SDK was used only for reference.
> Given very limited documentation provided by Aspeed, some parts of SDRAM
> init sequence were basically rewritten to do the same thing that is done
> in Aspeed SDK, without real understanding of what is going on.
> 
> The file layout closely follows the example of rk3288 chip and firefly-rk3288
> board.
> 
> For the first round of reviews I'm mostly looking for a nod to add
> mach-aspeed and arch-aspeed directories, as well as for feedback
> on naming, file locations and overall approach.

I have a few minor comments I'll reply with but in a number of patches
you add C/H files without a header/SPDX tag on them and that's a no-no.
Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/5e3e58b1/attachment.sig>

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

* [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer
  2017-01-04 19:46 ` [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer Maxim Sloyko
@ 2017-01-04 20:58   ` Tom Rini
  2017-01-14 17:13   ` Simon Glass
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:58 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:46:46AM -0800, Maxim Sloyko wrote:

> The driver is compatible with AST2400 and AST2500 watchdogs.
> There is no uclass for Watchdog yet, so the driver does not follow
> the driver model. It also uses fixed clock, so no clock driver
> is needed.
[snip]
> +/* Number of available watchdog timers */
> +#ifdef CONFIG_ASPEED_AST2500
> +#define WDT_MAX_NUM			2
> +#else
> +#define WDT_MAX_NUM			1
> +#endif

2400 has 1 WDT I assume.  Move this to a Kconfig 'int' question and have
the right number come that way.

Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/20fbdc04/attachment.sig>

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-04 19:46 ` [U-Boot] [PATCH 03/12] aspeed: Add Timer Support Maxim Sloyko
@ 2017-01-04 20:58   ` Tom Rini
  2017-01-14 17:13   ` Simon Glass
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:58 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:46:47AM -0800, Maxim Sloyko wrote:

> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK.
> 
> The timer uses fixed clock, so does not rely on a clock driver.
[snip]
> +U_BOOT_DRIVER(sandbox_timer) = {

Not sandbox_timer :)

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/8bbba630/attachment.sig>

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-04 19:46 ` [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks Maxim Sloyko
@ 2017-01-04 20:58   ` Tom Rini
  2017-01-05  1:18     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Tom Rini @ 2017-01-04 20:58 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:

> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
> 
>  arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>  2 files changed, 452 insertions(+)
>  create mode 100644 arch/arm/dts/ast2500.dtsi
>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
> 
> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
> new file mode 100644
> index 0000000000..1a2a3f7ee3
> --- /dev/null
> +++ b/arch/arm/dts/ast2500.dtsi
> @@ -0,0 +1,423 @@
> +/* This device tree is copied from
> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi

Is this also found in the Linux kernel or not yet?  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/e2e78669/attachment.sig>

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

* [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-04 20:26 ` [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and " Tom Rini
@ 2017-01-04 22:47   ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-04 22:47 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 4, 2017 at 12:26 PM, Tom Rini <trini@konsulko.com> wrote:
> On Wed, Jan 04, 2017 at 11:46:44AM -0800, Maxim Sloyko wrote:
>
>> This series adds minimal support for AST2500 part and eval board,
>> enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
>> Clock (very basic) and SDRAM MC drivers, all written from scratch,
>> using AST2500 datasheet. Aspeed's SDK was used only for reference.
>> Given very limited documentation provided by Aspeed, some parts of SDRAM
>> init sequence were basically rewritten to do the same thing that is done
>> in Aspeed SDK, without real understanding of what is going on.
>>
>> The file layout closely follows the example of rk3288 chip and firefly-rk3288
>> board.
>>
>> For the first round of reviews I'm mostly looking for a nod to add
>> mach-aspeed and arch-aspeed directories, as well as for feedback
>> on naming, file locations and overall approach.
>
> Thanks for doing this.  I'll review the individual patches for other
> changes but in general:
>
>> Maxim Sloyko (12):
>>   aspeed: Add mach-aspeed directory and basic Kconfig
>>   aspeed: Add support for Watchdot Timer
>>   aspeed: Add Timer Support
>>   aspeed: Add sysreset driver
>>   aspeed/ast2500: Device Tree and bindings for some of the clocks
>>   aspeed/ast2500: Add Clock Driver
>>   aspeed/ast2500: Helper function to get access to SCU
>>   aspeed/ast2500: Add SDRAM MC driver
>>   aspeed/ast2500: Common board init functions for ast2500 based boards
>
> This can really be one patch.  Or maybe 2-3 (wdt, timer, sysreset,
> everything else).  The stuff that one could lump together and say "this
> must be here for the SoC to build and have minimal functionality" is one
> patch.  The changes that adds useful functionality is a patch each.

Well, the review would certainly be easier for me, if this was just
one patch, so I would gladly merge them.

>
>>   aspeed: Common configuration parameters for aspeed boards
>>   aspeed: Device Tree for ast2500 Eval Board
>>   aspeed: Configuration for ast2500 eval board
>
> Adding the ast2500 EVB would be another single patch.

Sounds good to me.

>
> --
> Tom



-- 
Maxim Sloyko

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-04 20:58   ` Tom Rini
@ 2017-01-05  1:18     ` Maxim Sloyko
  2017-01-05  3:26       ` Tom Rini
  0 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05  1:18 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
> On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
>
>> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> ---
>>
>>  arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
>>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>>  2 files changed, 452 insertions(+)
>>  create mode 100644 arch/arm/dts/ast2500.dtsi
>>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>>
>> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
>> new file mode 100644
>> index 0000000000..1a2a3f7ee3
>> --- /dev/null
>> +++ b/arch/arm/dts/ast2500.dtsi
>> @@ -0,0 +1,423 @@
>> +/* This device tree is copied from
>> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
>
> Is this also found in the Linux kernel or not yet?  Thanks!

Yes, this is also in in main Linux kernel now, as I've found out, but
actually there is a number of differences, most notably there is no
pin configuration in this device tree, because there is no pinctrl
driver.

Should I remove this reference or modify it?

>
> --
> Tom



-- 
Maxim Sloyko

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-05  1:18     ` Maxim Sloyko
@ 2017-01-05  3:26       ` Tom Rini
  2017-01-05 22:20         ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Tom Rini @ 2017-01-05  3:26 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
> >
> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
> >> ---
> >>
> >>  arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
> >>  2 files changed, 452 insertions(+)
> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
> >>
> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
> >> new file mode 100644
> >> index 0000000000..1a2a3f7ee3
> >> --- /dev/null
> >> +++ b/arch/arm/dts/ast2500.dtsi
> >> @@ -0,0 +1,423 @@
> >> +/* This device tree is copied from
> >> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
> >
> > Is this also found in the Linux kernel or not yet?  Thanks!
> 
> Yes, this is also in in main Linux kernel now, as I've found out, but
> actually there is a number of differences, most notably there is no
> pin configuration in this device tree, because there is no pinctrl
> driver.
> 
> Should I remove this reference or modify it?

Ideally, we will take the kernel dts files and then add what we need on
top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
-u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
arch/arm/dts/tegra124-nyan-big-u-boot.dtsi

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170104/64fa86ef/attachment.sig>

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-05  3:26       ` Tom Rini
@ 2017-01-05 22:20         ` Maxim Sloyko
  2017-01-14 17:13           ` Simon Glass
  0 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:20 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
>> >
>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> >> ---
>> >>
>> >>  arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>> >>  2 files changed, 452 insertions(+)
>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>> >>
>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
>> >> new file mode 100644
>> >> index 0000000000..1a2a3f7ee3
>> >> --- /dev/null
>> >> +++ b/arch/arm/dts/ast2500.dtsi
>> >> @@ -0,0 +1,423 @@
>> >> +/* This device tree is copied from
>> >> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
>> >
>> > Is this also found in the Linux kernel or not yet?  Thanks!
>>
>> Yes, this is also in in main Linux kernel now, as I've found out, but
>> actually there is a number of differences, most notably there is no
>> pin configuration in this device tree, because there is no pinctrl
>> driver.

Actually, I take that back, I was looking at the wrong linux Linux
kernel tree still... Only basic version of device tree has made it to
mainline kernel, but it's enough at the moment, so I used that
instead.

>>
>> Should I remove this reference or modify it?
>
> Ideally, we will take the kernel dts files and then add what we need on
> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi

OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
added modifications in ast2500-u-boot.dtsi and now include
ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
you.

Thanks!

>
> --
> Tom



-- 
Maxim Sloyko

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

* [U-Boot] [PATCH v1 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                   ` (13 preceding siblings ...)
  2017-01-04 20:58 ` Tom Rini
@ 2017-01-05 22:42 ` Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
                     ` (4 more replies)
  14 siblings, 5 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:42 UTC (permalink / raw)
  To: u-boot

This series adds minimal support for AST2500 part and eval board,
enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
Clock (very basic) and SDRAM MC drivers, all written from scratch,
using AST2500 datasheet. Aspeed's SDK was used only for reference.
Given very limited documentation provided by Aspeed, some parts of SDRAM
init sequence were basically rewritten to do the same thing that is done
in Aspeed SDK, without real understanding of what is going on.

The file layout closely follows the example of rk3288 chip and firefly-rk3288
board.

For the first round of reviews I'm mostly looking for a nod to add
mach-aspeed and arch-aspeed directories, as well as for feedback
on naming, file locations and overall approach.

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Maxim Sloyko (4):
  aspeed: Add drivers common to all Aspeed SoCs
  aspeed: Add basic ast2500 specific drivers and configuration
  aspeed: Board init functions and common configs for ast2500 based
    boards
  aspeed: Support for ast2500 Eval Board

 arch/arm/Kconfig                                 |   7 +
 arch/arm/Makefile                                |   1 +
 arch/arm/dts/Makefile                            |   2 +
 arch/arm/dts/ast2500-evb.dts                     |  23 ++
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/include/asm/arch-aspeed/timer.h         |  54 +++
 arch/arm/include/asm/arch-aspeed/wdt.h           |  89 +++++
 arch/arm/mach-aspeed/Kconfig                     |  17 +
 arch/arm/mach-aspeed/Makefile                    |   8 +
 arch/arm/mach-aspeed/ast2500-board.c             |  78 ++++
 arch/arm/mach-aspeed/ast2500/Kconfig             |  13 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast_wdt.c                   |  44 +++
 board/aspeed/evb_ast2500/Kconfig                 |  12 +
 board/aspeed/evb_ast2500/Makefile                |   1 +
 board/aspeed/evb_ast2500/evb_ast2500.c           |   6 +
 configs/evb-ast2500_defconfig                    |  21 ++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 drivers/sysreset/Makefile                        |   1 +
 drivers/sysreset/sysreset_ast.c                  |  55 +++
 drivers/timer/Kconfig                            |   7 +
 drivers/timer/Makefile                           |   1 +
 drivers/timer/ast_timer.c                        |  96 +++++
 include/configs/aspeed-common.h                  |  84 +++++
 include/configs/evb_ast2500.h                    |  30 ++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 33 files changed, 1895 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c
 create mode 100644 include/configs/aspeed-common.h
 create mode 100644 include/configs/evb_ast2500.h
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v1 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
@ 2017-01-05 22:42   ` Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:42 UTC (permalink / raw)
  To: u-boot

Add support for Watchdog Timer, which is compatible with AST2400 and
AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
does not follow the driver model. It also uses fixed clock, so no clock
driver is needed.

Add support for timer for Aspeed ast2400/ast2500 devices.
The driver actually controls several devices, but because all devices
share the same Control Register, it is somewhat difficult to completely
decouple them. Since only one timer is needed at the moment, this should
be OK. The timer uses fixed clock, so does not rely on a clock driver.

Add sysreset driver, which uses watchdog timer to do resets and particular
watchdog device to use is hardcoded (0)

---

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/Kconfig                         |  7 +++
 arch/arm/Makefile                        |  1 +
 arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
 arch/arm/include/asm/arch-aspeed/wdt.h   | 89 +++++++++++++++++++++++++++++
 arch/arm/mach-aspeed/Kconfig             | 15 +++++
 arch/arm/mach-aspeed/Makefile            |  7 +++
 arch/arm/mach-aspeed/ast_wdt.c           | 44 +++++++++++++++
 drivers/sysreset/Makefile                |  1 +
 drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
 drivers/timer/Kconfig                    |  7 +++
 drivers/timer/Makefile                   |  1 +
 drivers/timer/ast_timer.c                | 96 ++++++++++++++++++++++++++++++++
 12 files changed, 377 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 714dd8b514..135c544335 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
 	select OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 
+config ARCH_ASPEED
+	bool "Support Aspeed SoCs"
+	select OF_CONTROL
+	select DM
+
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm283x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 236debb452..cc73e1038e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ASPEED)		+= aspeed
 machine-$(CONFIG_ARCH_AT91)		+= at91
 machine-$(CONFIG_ARCH_BCM283X)		+= bcm283x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
new file mode 100644
index 0000000000..87c5b354ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/timer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_TIMER_H
+#define _ASM_ARCH_TIMER_H
+
+/* Each timer has 4 control bits in ctrl1 register.
+ * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
+ * such that timer X uses bits (4 * X - 4):(4 * X - 1)
+ * If the timer does not support PWM, bit 4 is reserved.
+ */
+#define AST_TMC_EN			(1 << 0)
+#define AST_TMC_1MHZ			(1 << 1)
+#define AST_TMC_OVFINTR			(1 << 2)
+#define AST_TMC_PWM			(1 << 3)
+
+/* Timers are counted from 1 in the datasheet. */
+#define AST_TMC_CTRL1_SHIFT(n)			(4 * ((n) - 1))
+
+#define AST_TMC_RATE  (1000*1000)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All timers share control registers, which makes it harder to make them
+ * separate devices. Since only one timer is needed@the moment, making
+ * it this just one device.
+ */
+
+struct ast_timer_counter {
+	u32 status;
+	u32 reload_val;
+	u32 match1;
+	u32 match2;
+};
+
+struct ast_timer {
+	struct ast_timer_counter timers1[3];
+	u32 ctrl1;
+	u32 ctrl2;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 ctrl3;
+	u32 ctrl1_clr;
+#else
+	u32 reserved[2];
+#endif
+	struct ast_timer_counter timers2[5];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_TIMER_H */
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
new file mode 100644
index 0000000000..32774b1a70
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_WDT_H
+#define _ASM_ARCH_WDT_H
+
+#define WDT_BASE			0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL		0x4755
+
+/* Control register */
+#define WDT_CTRL_RESET_MODE_SHIFT	5
+#define WDT_CTRL_RESET_MODE_MASK	3
+
+#define WDT_CTRL_EN			(1 << 0)
+#define WDT_CTRL_RESET			(1 << 1)
+#define WDT_CTRL_CLK1MHZ		(1 << 4)
+#define WDT_CTRL_2ND_BOOT		(1 << 7)
+
+/* Values for Reset Mode */
+#define WDT_CTRL_RESET_SOC		0
+#define WDT_CTRL_RESET_CHIP		1
+#define WDT_CTRL_RESET_CPU		2
+#define WDT_CTRL_RESET_MASK		3
+
+/* Reset Mask register */
+#define WDT_RESET_ARM			(1 << 0)
+#define WDT_RESET_COPROC		(1 << 1)
+#define WDT_RESET_SDRAM			(1 << 2)
+#define WDT_RESET_AHB			(1 << 3)
+#define WDT_RESET_I2C			(1 << 4)
+#define WDT_RESET_MAC1			(1 << 5)
+#define WDT_RESET_MAC2			(1 << 6)
+#define WDT_RESET_GCRT			(1 << 7)
+#define WDT_RESET_USB20			(1 << 8)
+#define WDT_RESET_USB11_HOST		(1 << 9)
+#define WDT_RESET_USB11_EHCI2		(1 << 10)
+#define WDT_RESET_VIDEO			(1 << 11)
+#define WDT_RESET_HAC			(1 << 12)
+#define WDT_RESET_LPC			(1 << 13)
+#define WDT_RESET_SDSDIO		(1 << 14)
+#define WDT_RESET_MIC			(1 << 15)
+#define WDT_RESET_CRT2C			(1 << 16)
+#define WDT_RESET_PWM			(1 << 17)
+#define WDT_RESET_PECI			(1 << 18)
+#define WDT_RESET_JTAG			(1 << 19)
+#define WDT_RESET_ADC			(1 << 20)
+#define WDT_RESET_GPIO			(1 << 21)
+#define WDT_RESET_MCTP			(1 << 22)
+#define WDT_RESET_XDMA			(1 << 23)
+#define WDT_RESET_SPI			(1 << 24)
+#define WDT_RESET_MISC			(1 << 25)
+
+#ifndef __ASSEMBLY__
+struct ast_wdt {
+	u32 counter_status;
+	u32 counter_reload_val;
+	u32 counter_restart;
+	u32 ctrl;
+	u32 timeout_status;
+	u32 clr_timeout_status;
+	u32 reset_width;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 reset_mask;
+#else
+	u32 reserved0;
+#endif
+};
+
+void wdt_stop(struct ast_wdt *wdt);
+void wdt_start(struct ast_wdt *wdt, u32 timeout);
+
+/**
+ * ast_get_wdt() - get a pointer to watchdog registers
+ *
+ * @wdt_number: 0-based WDT peripheral number
+ * @return pointer to registers or -ve error on error
+ */
+struct ast_wdt *ast_get_wdt(u8 wdt_number);
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000000..43cdbeda84
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,15 @@
+if ARCH_ASPEED
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_SOC
+	default "aspeed"
+
+config ASPEED_AST2500
+	bool "Support Aspeed AST2500 SoC"
+	select CPU_ARM1176
+	help
+	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000000..a14b8f751d
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
new file mode 100644
index 0000000000..0b62abc455
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+/* Number of available watchdog timers */
+#ifdef CONFIG_ASPEED_AST2500
+#define WDT_MAX_NUM			2
+#else
+#define WDT_MAX_NUM			1
+#endif
+
+void wdt_stop(struct ast_wdt *wdt)
+{
+	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+}
+
+void wdt_start(struct ast_wdt *wdt, u32 timeout)
+{
+	writel(timeout, &wdt->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&wdt->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+}
+
+struct ast_wdt *ast_get_wdt(u8 wdt_number)
+{
+	if (wdt_number > WDT_MAX_NUM)
+		return ERR_PTR(-EINVAL);
+
+	return (struct ast_wdt *)(WDT_BASE +
+				  sizeof(struct ast_wdt) * wdt_number);
+}
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index fa75cc52de..37638a8eea 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
new file mode 100644
index 0000000000..a0ab12851d
--- /dev/null
+++ b/drivers/sysreset/sysreset_ast.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+/* Number of Watchdog Timer ticks before reset */
+#define AST_WDT_RESET_TIMEOUT	10
+#define AST_WDT_FOR_RESET	0
+
+static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
+	u32 reset_mode = 0;
+
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		reset_mode = WDT_CTRL_RESET_CPU;
+		break;
+	case SYSRESET_COLD:
+		reset_mode = WDT_CTRL_RESET_CHIP;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	/* Clear reset mode bits */
+	clrsetbits_le32(&wdt->ctrl,
+			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
+			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
+	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops ast_sysreset = {
+	.request	= ast_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_ast) = {
+	.name	= "ast_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &ast_sysreset,
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index cb18f12fc9..9c5f98bb88 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -46,4 +46,11 @@ config OMAP_TIMER
 	help
 	  Select this to enable an timer for Omap devices.
 
+config AST_TIMER
+	bool "Aspeed ast2400/ast2500 timer support"
+	depends on TIMER
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable timer for Aspeed ast2400/ast2500 devices.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index f351fbb4e0..a4b1a486b0 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
new file mode 100644
index 0000000000..be48d24cea
--- /dev/null
+++ b/drivers/timer/ast_timer.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define AST_TICK_TIMER  1
+#define AST_TMC_RELOAD_VAL  0xffffffff
+
+struct ast_timer_priv {
+	struct ast_timer *regs;
+};
+
+static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
+						       int n)
+{
+	if (n > 3)
+		return &timer->timers2[n - 4];
+	else
+		return &timer->timers1[n - 1];
+}
+
+static int ast_timer_probe(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
+
+	/*
+	 * Stop the timer. This will also load reload_val into
+	 * the status register.
+	 */
+	clrbits_le32(&priv->regs->ctrl1,
+		     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+	/* Start the timer from the fixed 1MHz clock. */
+	setbits_le32(&priv->regs->ctrl1,
+		     (AST_TMC_EN | AST_TMC_1MHZ) <<
+		     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+
+	uc_priv->clock_rate = AST_TMC_RATE;
+
+	return 0;
+}
+
+static int ast_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+
+	*count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
+
+	return 0;
+}
+
+static int ast_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = (struct ast_timer *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static const struct timer_ops ast_timer_ops = {
+	.get_count = ast_timer_get_count,
+};
+
+static const struct udevice_id ast_timer_ids[] = {
+	{ .compatible = "aspeed,ast2500-timer" },
+	{ .compatible = "aspeed,ast2400-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(ast_timer) = {
+	.name = "ast_timer",
+	.id = UCLASS_TIMER,
+	.of_match = ast_timer_ids,
+	.probe = ast_timer_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_timer_priv),
+	.ofdata_to_platdata = ast_timer_ofdata_to_platdata,
+	.ops = &ast_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v1 2/4] aspeed: Add basic ast2500 specific drivers and configuration
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-05 22:42   ` Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:42 UTC (permalink / raw)
  To: u-boot

Clock Driver

This driver is ast2500 specific and is not compatible with earlier
versions of this chip. The differences are not that big, but they are
in somewhat random places, so making it compatible with ast2400 is not
worth the effort at the moment.

SDRAM MC driver

The driver is very ast2500 specific and is completely incompatible
with previous versions of the chip.

The memory controller is very poorly documented by Aspeed in the
datasheet, with any mention of the whole range of registers missing. The
initialization procedure has been basically taken from Aspeed SDK, where
it is implemented in assembly and rewritten in C, with very limited
understanding of what exacly it is doing.

---

Changes in v1:
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/mach-aspeed/Kconfig                     |   2 +
 arch/arm/mach-aspeed/Makefile                    |   1 +
 arch/arm/mach-aspeed/ast2500/Kconfig             |   6 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 14 files changed, 1254 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
new file mode 100644
index 0000000000..c95a7ba835
--- /dev/null
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -0,0 +1,53 @@
+#include <dt-bindings/clock/ast2500-scu.h>
+
+#include "ast2500.dtsi"
+
+/ {
+	scu: clock-controller at 1e6e2000 {
+		compatible = "aspeed,ast2500-scu";
+		reg = <0x1e6e2000 0x1000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	sdrammc: sdrammc at 1e6e0000 {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-sdrammc";
+		reg = <0x1e6e0000 0x174
+			0x1e6e0200 0x1d4 >;
+		clocks = <&scu PLL_MPLL>;
+	};
+
+	ahb {
+		u-boot,dm-pre-reloc;
+
+		apb {
+			u-boot,dm-pre-reloc;
+
+			timer: timer at 1e782000 {
+				u-boot,dm-pre-reloc;
+			};
+
+			uart1: serial at 1e783000 {
+				clocks = <&scu PCLK_UART1>;
+			};
+
+			uart2: serial at 1e78d000 {
+				clocks = <&scu PCLK_UART2>;
+			};
+
+			uart3: serial at 1e78e000 {
+				clocks = <&scu PCLK_UART3>;
+			};
+
+			uart4: serial at 1e78f000 {
+				clocks = <&scu PCLK_UART4>;
+			};
+
+			uart5: serial at 1e784000 {
+				clocks = <&scu PCLK_UART5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
new file mode 100644
index 0000000000..97fac69d11
--- /dev/null
+++ b/arch/arm/dts/ast2500.dtsi
@@ -0,0 +1,174 @@
+/*
+ * This device tree is copied from
+ * https://raw.githubusercontent.com/torvalds/linux/02440622/arch/arm/boot/dts/
+ */
+#include "skeleton.dtsi"
+
+/ {
+	model = "Aspeed BMC";
+	compatible = "aspeed,ast2500";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&vic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,arm1176jzf-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vic: interrupt-controller at 1e6c0080 {
+			compatible = "aspeed,ast2400-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			valid-sources = <0xfefff7ff 0x0807ffff>;
+			reg = <0x1e6c0080 0x80>;
+		};
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			clk_clkin: clk_clkin at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-clkin-clock";
+				reg = <0x1e6e2070 0x04>;
+			};
+
+			clk_hpll: clk_hpll at 1e6e2024 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-hpll-clock";
+				reg = <0x1e6e2024 0x4>;
+				clocks = <&clk_clkin>;
+			};
+
+			clk_ahb: clk_ahb at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-ahb-clock";
+				reg = <0x1e6e2070 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_apb: clk_apb at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-apb-clock";
+				reg = <0x1e6e2008 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_uart: clk_uart at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,uart-clock";
+				reg = <0x1e6e202c 0x4>;
+			};
+
+			sram at 1e720000 {
+				compatible = "mmio-sram";
+				reg = <0x1e720000 0x9000>;	// 36K
+			};
+
+			timer: timer at 1e782000 {
+				compatible = "aspeed,ast2400-timer";
+				reg = <0x1e782000 0x90>;
+				// The moxart_timer driver registers only one
+				// interrupt and assumes it's for timer 1
+				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16>;
+				clocks = <&clk_apb>;
+			};
+
+			wdt1: wdt at 1e785000 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785000 0x1c>;
+				interrupts = <27>;
+			};
+
+			wdt2: wdt at 1e785020 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785020 0x1c>;
+				interrupts = <27>;
+				status = "disabled";
+			};
+
+			wdt3: wdt at 1e785040 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785074 0x1c>;
+				status = "disabled";
+			};
+
+			uart1: serial at 1e783000 {
+				compatible = "ns16550a";
+				reg = <0x1e783000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <9>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart2: serial at 1e78d000 {
+				compatible = "ns16550a";
+				reg = <0x1e78d000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <32>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart3: serial at 1e78e000 {
+				compatible = "ns16550a";
+				reg = <0x1e78e000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <33>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart4: serial at 1e78f000 {
+				compatible = "ns16550a";
+				reg = <0x1e78f000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <34>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart5: serial at 1e784000 {
+				compatible = "ns16550a";
+				reg = <0x1e784000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				current-speed = <38400>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart6: serial at 1e787000 {
+				compatible = "ns16550a";
+				reg = <0x1e787000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
new file mode 100644
index 0000000000..6c6af68f4f
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SCU_AST2500_H
+#define _ASM_ARCH_SCU_AST2500_H
+
+#define SCU_UNLOCK_VALUE		0x1688a8a8
+
+#define SCU_HWSTRAP_VGAMEM_MASK		3
+#define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_DDR4		(1 << 24)
+#define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
+
+#define SCU_MPLL_DENUM_SHIFT		0
+#define SCU_MPLL_DENUM_MASK		0x1f
+#define SCU_MPLL_NUM_SHIFT		5
+#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_POST_SHIFT		13
+#define SCU_MPLL_POST_MASK		0x3f
+
+#define SCU_HPLL_DENUM_SHIFT		0
+#define SCU_HPLL_DENUM_MASK		0x1f
+#define SCU_HPLL_NUM_SHIFT		5
+#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_POST_SHIFT		13
+#define SCU_HPLL_POST_MASK		0x3f
+
+#define SCU_MISC2_UARTCLK_SHIFT		24
+
+#define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_clk_priv {
+	struct ast2500_scu *scu;
+};
+
+struct ast2500_scu {
+	u32 protection_key;
+	u32 sysreset_ctrl1;
+	u32 clk_sel1;
+	u32 clk_stop_ctrl1;
+	u32 freq_counter_ctrl;
+	u32 freq_counter_cmp;
+	u32 intr_ctrl;
+	u32 d2_pll_param;
+	u32 m_pll_param;
+	u32 h_pll_param;
+	u32 d_pll_param;
+	u32 misc_ctrl1;
+	u32 pci_config[3];
+	u32 sysreset_status;
+	u32 vga_handshake[2];
+	u32 mac_clk_delay;
+	u32 misc_ctrl2;
+	u32 vga_scratch[8];
+	u32 hwstrap;
+	u32 rng_ctrl;
+	u32 rng_data;
+	u32 rev_id;
+	u32 pinmux_ctrl[6];
+	u32 reserved0;
+	u32 extrst_sel;
+	u32 pinmux_ctrl1[4];
+	u32 reserved1[2];
+	u32 mac_clk_delay_100M;
+	u32 mac_clk_delay_10M;
+	u32 wakeup_enable;
+	u32 wakeup_control;
+	u32 reserved2[3];
+	u32 sysreset_ctrl2;
+	u32 clk_sel2;
+	u32 clk_stop_ctrl2;
+	u32 freerun_counter;
+	u32 freerun_counter_ext;
+	u32 clk_duty_meas_ctrl;
+	u32 clk_duty_meas_res;
+	u32 reserved3[4];
+	/* The next registers are not key protected */
+	struct ast2500_cpu2 {
+		u32 ctrl;
+		u32 base_addr[9];
+		u32 cache_ctrl;
+	} cpu2;
+	u32 reserved4;
+	u32 d_pll_ext_param[3];
+	u32 d2_pll_ext_param[3];
+	u32 mh_pll_ext_param;
+	u32 reserved5;
+	u32 chip_id[2];
+	u32 reserved6[2];
+	u32 uart_clk_ctrl;
+	u32 reserved7[7];
+	u32 pcie_config;
+	u32 mmio_decode;
+	u32 reloc_ctrl_decode[2];
+	u32 mailbox_addr;
+	u32 shared_sram_decode[2];
+	u32 bmc_rev_id;
+	u32 reserved8;
+	u32 bmc_device_id;
+	u32 reserved9[13];
+	u32 clk_duty_sel;
+};
+
+int ast_get_clk(struct udevice **devp);
+void *ast_get_scu(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
new file mode 100644
index 0000000000..a5f8615ae2
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_AST2500_H
+#define _ASM_ARCH_SDRAM_AST2500_H
+
+#define SDRAM_UNLOCK_KEY		0xfc600309
+#define SDRAM_VIDEO_UNLOCK_KEY		0x2003000f
+
+#define SDRAM_PCR_CKE_EN		(1 << 0)
+#define SDRAM_PCR_AUTOPWRDN_EN		(1 << 1)
+#define SDRAM_PCR_CKE_DELAY_SHIFT	4
+#define SDRAM_PCR_CKE_DELAY_MASK	7
+#define SDRAM_PCR_RESETN_DIS		(1 << 7)
+#define SDRAM_PCR_ODT_EN		(1 << 8)
+#define SDRAM_PCR_ODT_AUTO_ON		(1 << 10)
+#define SDRAM_PCR_ODT_EXT_EN		(1 << 11)
+#define SDRAM_PCR_TCKE_PW_SHIFT		12
+#define SDRAM_PCR_TCKE_PW_MASK		7
+#define SDRAM_PCR_RGAP_CTRL_EN		(1 << 15)
+#define SDRAM_PCR_MREQI_DIS		(1 << 17)
+
+/* Fixed priority DRAM Requests mask */
+#define SDRAM_REQ_VGA_HW_CURSOR		(1 << 0)
+#define SDRAM_REQ_VGA_TEXT_CG_FONT	(1 << 1)
+#define SDRAM_REQ_VGA_TEXT_ASCII	(1 << 2)
+#define SDRAM_REQ_VGA_CRT		(1 << 3)
+#define SDRAM_REQ_SOC_DC_CURSOR		(1 << 4)
+#define SDRAM_REQ_SOC_DC_OCD		(1 << 5)
+#define SDRAM_REQ_SOC_DC_CRT		(1 << 6)
+#define SDRAM_REQ_VIDEO_HIPRI_WRITE	(1 << 7)
+#define SDRAM_REQ_USB20_EHCI1		(1 << 8)
+#define SDRAM_REQ_USB20_EHCI2		(1 << 9)
+#define SDRAM_REQ_CPU			(1 << 10)
+#define SDRAM_REQ_AHB2			(1 << 11)
+#define SDRAM_REQ_AHB			(1 << 12)
+#define SDRAM_REQ_MAC0			(1 << 13)
+#define SDRAM_REQ_MAC1			(1 << 14)
+#define SDRAM_REQ_PCIE			(1 << 16)
+#define SDRAM_REQ_XDMA			(1 << 17)
+#define SDRAM_REQ_ENCRYPTION		(1 << 18)
+#define SDRAM_REQ_VIDEO_FLAG		(1 << 21)
+#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE	(1 << 28)
+#define SDRAM_REQ_2D_RW			(1 << 29)
+#define SDRAM_REQ_MEMCHECK		(1 << 30)
+
+#define SDRAM_ICR_RESET_ALL		(1 << 31)
+
+#define SDRAM_CONF_CAP_SHIFT		0
+#define SDRAM_CONF_CAP_MASK		3
+#define SDRAM_CONF_DDR4			(1 << 4)
+#define SDRAM_CONF_SCRAMBLE		(1 << 8)
+#define SDRAM_CONF_SCRAMBLE_PAT2	(1 << 9)
+#define SDRAM_CONF_CACHE_EN		(1 << 10)
+#define SDRAM_CONF_CACHE_INIT_EN	(1 << 12)
+#define SDRAM_CONF_DUALX8		(1 << 13)
+#define SDRAM_CONF_CACHE_INIT_DONE	(1 << 19)
+
+#define SDRAM_CONF_CAP_128M		0
+#define SDRAM_CONF_CAP_256M		1
+#define SDRAM_CONF_CAP_512M		2
+#define SDRAM_CONF_CAP_1024M		3
+
+#define SDRAM_MISC_DDR4_TREFRESH	(1 << 3)
+
+#define SDRAM_PHYCTRL0_INIT		(1 << 0)
+#define SDRAM_PHYCTRL0_AUTO_UPDATE	(1 << 1)
+#define SDRAM_PHYCTRL0_NRST		(1 << 2)
+
+#define SDRAM_REFRESH_CYCLES_SHIFT	0
+#define SDRAM_REFRESH_CYCLES_MASK	0xf
+#define SDRAM_REFRESH_ZQCS_EN		(1 << 7)
+#define SDRAM_REFRESH_PERIOD_SHIFT	8
+#define SDRAM_REFRESH_PERIOD_MASK	0xf
+
+#define SDRAM_TEST_LEN_SHIFT		4
+#define SDRAM_TEST_LEN_MASK		0xfffff
+#define SDRAM_TEST_START_ADDR_SHIFT	24
+#define SDRAM_TEST_START_ADDR_MASK	0x3f
+
+#define SDRAM_TEST_EN			(1 << 0)
+#define SDRAM_TEST_MODE_SHIFT		1
+#define SDRAM_TEST_MODE_MASK		3
+#define SDRAM_TEST_MODE_WO		0
+#define SDRAM_TEST_MODE_RB		1
+#define SDRAM_TEST_MODE_RW		2
+#define SDRAM_TEST_GEN_MODE_SHIFT	3
+#define SDRAM_TEST_GEN_MODE_MASK	7
+#define SDRAM_TEST_TWO_MODES		(1 << 6)
+#define SDRAM_TEST_ERRSTOP		(1 << 7)
+#define SDRAM_TEST_DONE			(1 << 12)
+#define SDRAM_TEST_FAIL			(1 << 13)
+
+#define SDRAM_AC_TRFC_SHIFT		0
+#define SDRAM_AC_TRFC_MASK		0xff
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_sdrammc_regs {
+	u32 protection_key;
+	u32 config;
+	u32 gm_protection_key;
+	u32 refresh_timing;
+	u32 ac_timing[3];
+	u32 misc_control;
+	u32 mr46_mode_setting;
+	u32 mr5_mode_setting;
+	u32 mode_setting_control;
+	u32 mr02_mode_setting;
+	u32 mr13_mode_setting;
+	u32 power_control;
+	u32 req_limit_mask;
+	u32 pri_group_setting;
+	u32 max_grant_len[4];
+	u32 intr_ctrl;
+	u32 ecc_range_ctrl;
+	u32 first_ecc_err_addr;
+	u32 last_ecc_err_addr;
+	u32 phy_ctrl[4];
+	u32 ecc_test_ctrl;
+	u32 test_addr;
+	u32 test_fail_dq_bit;
+	u32 test_init_val;
+	u32 phy_debug_ctrl;
+	u32 phy_debug_data;
+	u32 reserved1[30];
+	u32 scu_passwd;
+	u32 reserved2[7];
+	u32 scu_mpll;
+	u32 reserved3[19];
+	u32 scu_hwstrap;
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index 43cdbeda84..4aba39cae5 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -12,4 +12,6 @@ config ASPEED_AST2500
 	help
 	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
 
+source "arch/arm/mach-aspeed/ast2500/Kconfig"
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index a14b8f751d..1f7af71b03 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
new file mode 100644
index 0000000000..c0b448f19e
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -0,0 +1,6 @@
+if ASPEED_AST2500
+
+config SYS_CPU
+	default "arm1176"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
new file mode 100644
index 0000000000..a35b239ef3
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += clk_ast2500.o sdram_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
new file mode 100644
index 0000000000..079909fa64
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/scu_ast2500.h>
+
+int ast_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(aspeed_ast2500_scu), devp);
+}
+
+void *ast_get_scu(void)
+{
+	struct ast2500_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = ast_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->scu;
+}
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
new file mode 100644
index 0000000000..da25756e94
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *
+ * Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:		GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/sdram_ast2500.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <regmap.h>
+
+/* These configuration parameters are taken from Aspeed SDK */
+#define DDR4_MR46_MODE		0x08000000
+#define DDR4_MR5_MODE		0x400
+#define DDR4_MR13_MODE		0x101
+#define DDR4_MR02_MODE		0x410
+#define DDR4_TRFC		0x45457188
+
+#define PHY_CFG_SIZE		15
+
+static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
+static const struct {
+	u32 index[PHY_CFG_SIZE];
+	u32 value[PHY_CFG_SIZE];
+} ddr4_phy_config = {
+	.index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
+	.value = {
+		0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
+		0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
+		0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
+	},
+};
+
+#define SDRAM_MAX_SIZE		(1024 * 1024 * 1024)
+#define SDRAM_MIN_SIZE		(128 * 1024 * 1024)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Bandwidth configuration parameters for different SDRAM requests.
+ * These are hardcoded settings taken from Aspeed SDK.
+ */
+static const u32 ddr_max_grant_params[4] = {
+	0x88448844, 0x24422288, 0x22222222, 0x22222222
+};
+
+/*
+ * These registers are not documented by Aspeed at all.
+ * All writes and reads are taken pretty much as is from SDK.
+ */
+struct ast2500_ddr_phy {
+	u32 phy[117];
+};
+
+struct dram_info {
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct ast2500_sdrammc_regs *regs;
+	struct ast2500_scu *scu;
+	struct ast2500_ddr_phy *phy;
+	ulong clock_rate;
+};
+
+static int ast2500_sdrammc_reset(void)
+{
+	struct ast_wdt *wdt = ast_get_wdt(0);
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	/* Only Reset SDRAM */
+	writel(WDT_RESET_SDRAM, &wdt->reset_mask);
+	clrbits_le32(&wdt->ctrl,
+		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
+	wdt_start(wdt, 1);
+
+	/* Wait for WDT to reset */
+	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+		;
+	wdt_stop(wdt);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
+{
+	writel(0, &phy->phy[2]);
+	writel(0, &phy->phy[6]);
+	writel(0, &phy->phy[8]);
+	writel(0, &phy->phy[10]);
+	writel(0, &phy->phy[12]);
+	writel(0, &phy->phy[42]);
+	writel(0, &phy->phy[44]);
+
+	writel(0x86000000, &phy->phy[16]);
+	writel(0x00008600, &phy->phy[17]);
+	writel(0x80000000, &phy->phy[18]);
+	writel(0x80808080, &phy->phy[19]);
+
+	return 0;
+}
+
+static void ast2500_ddr_phy_init_process(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	writel(0, &regs->phy_ctrl[0]);
+	writel(0x4040, &info->phy->phy[51]);
+
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
+	while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
+		;
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
+	       &regs->phy_ctrl[0]);
+}
+
+static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
+{
+	writel(0, &info->regs->phy_ctrl[0]);
+	writel((vref << 8) | 0x6, &info->phy->phy[48]);
+	ast2500_ddr_phy_init_process(info);
+}
+
+static int ast2500_ddr_cbr_test(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	int i;
+	const u32 test_params = SDRAM_TEST_EN
+			| SDRAM_TEST_ERRSTOP
+			| SDRAM_TEST_TWO_MODES;
+	int ret = 0;
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
+	       (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
+	writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
+	writel(0xff00ff00, &regs->test_init_val);
+	writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
+	       SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
+
+	while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+		;
+
+	if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+		ret = -EIO;
+	} else {
+		for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
+			writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
+			       &regs->ecc_test_ctrl);
+			while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+				;
+			if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+				ret = -EIO;
+				break;
+			}
+		}
+	}
+
+	writel(0, &regs->refresh_timing);
+	writel(0, &regs->ecc_test_ctrl);
+	return ret;
+}
+
+static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
+{
+	int i;
+	int vref_min = 0xff;
+	int vref_max = 0;
+	int range_size = 0;
+
+	for (i = 1; i < 0x40; ++i) {
+		ast2500_sdrammc_set_vref(info, i);
+
+		int res = ast2500_ddr_cbr_test(info);
+		if (res < 0) {
+			if (range_size > 0)
+				break;
+		} else {
+			++range_size;
+			vref_min = min(vref_min, i);
+			vref_max = max(vref_max, i);
+		}
+	}
+
+	/* Pick average setting */
+	ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
+
+	return 0;
+}
+
+static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
+{
+	size_t vga_mem_size_base = 8 * 1024 * 1024;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap)
+			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
+			& SCU_HWSTRAP_VGAMEM_MASK;
+
+	return vga_mem_size_base << vga_hwconf;
+}
+
+/*
+ * Find out RAM size and save it in dram_info
+ *
+ * The procedure is taken from Aspeed SDK
+ */
+static void ast2500_sdrammc_calc_size(struct dram_info *info)
+{
+	/* The controller supports 128/256/512/1024 MB ram */
+	size_t ram_size = SDRAM_MIN_SIZE;
+	const int write_test_offset = 0x100000;
+	u32 test_pattern = 0xdeadbeef;
+	u32 cap_param = SDRAM_CONF_CAP_1024M;
+	u32 refresh_timing_param = DDR4_TRFC;
+	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
+
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		writel(test_pattern, write_addr_base + (ram_size >> 1));
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	/* One last write to overwrite all wrapped values */
+	writel(test_pattern, write_addr_base);
+
+	/* Reset the pattern and see which value was really written */
+	test_pattern = 0xdeadbeef;
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
+			break;
+
+		--cap_param;
+		refresh_timing_param >>= 8;
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	clrsetbits_le32(&info->regs->ac_timing[1],
+			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
+			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
+			 << SDRAM_AC_TRFC_SHIFT));
+
+	info->info.base = CONFIG_SYS_SDRAM_BASE;
+	info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
+	clrsetbits_le32(&info->regs->config,
+			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
+			((cap_param & SDRAM_CONF_CAP_MASK)
+			 << SDRAM_CONF_CAP_SHIFT));
+}
+
+static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
+{
+	int i;
+	const u32 power_control = SDRAM_PCR_CKE_EN
+	    | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
+	    | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
+	    | SDRAM_PCR_RESETN_DIS
+	    | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
+	const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
+#ifdef CONFIG_DUALX8_RAM
+	    | SDRAM_CONF_DUALX8
+#endif
+	    | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
+
+	writel(conf, &info->regs->config);
+	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
+		writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
+
+	writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
+	writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
+	writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
+	writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
+
+	for (i = 0; i < PHY_CFG_SIZE; ++i) {
+		writel(ddr4_phy_config.value[i],
+		       &info->phy->phy[ddr4_phy_config.index[i]]);
+	}
+
+	writel(power_control, &info->regs->power_control);
+
+	ast2500_ddr_phy_init_process(info);
+
+	int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
+	if (ret < 0) {
+		debug("Vref calibration failed!\n");
+		return ret;
+	}
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
+	       | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
+	       &info->regs->refresh_timing);
+
+	setbits_le32(&info->regs->power_control,
+		     SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
+
+	ast2500_sdrammc_calc_size(info);
+
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
+	while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
+		;
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
+
+	writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
+
+	/* Enable all requests except video & display */
+	writel(SDRAM_REQ_USB20_EHCI1
+	       | SDRAM_REQ_USB20_EHCI2
+	       | SDRAM_REQ_CPU
+	       | SDRAM_REQ_AHB2
+	       | SDRAM_REQ_AHB
+	       | SDRAM_REQ_MAC0
+	       | SDRAM_REQ_MAC1
+	       | SDRAM_REQ_PCIE
+	       | SDRAM_REQ_XDMA
+	       | SDRAM_REQ_ENCRYPTION
+	       | SDRAM_REQ_VIDEO_FLAG
+	       | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
+	       | SDRAM_REQ_2D_RW
+	       | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
+
+	return 0;
+}
+
+static void ast2500_sdrammc_unlock(struct dram_info *info)
+{
+	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (!readl(&info->regs->protection_key))
+		;
+}
+
+static void ast2500_sdrammc_lock(struct dram_info *info)
+{
+	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (readl(&info->regs->protection_key))
+		;
+}
+
+static int ast2500_sdrammc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
+	struct ast2500_sdrammc_regs *regs = priv->regs;
+	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+	int i;
+
+	if (ret) {
+		debug("DDR:No CLK\n");
+		return ret;
+	}
+
+	priv->scu = ast_get_scu();
+	if (IS_ERR(priv->scu))
+		return PTR_ERR(priv->scu);
+
+	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
+	ret = ast2500_sdrammc_reset();
+	if (ret)
+		return ret;
+
+	ast2500_sdrammc_unlock(priv);
+
+	writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
+	       &regs->power_control);
+	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
+
+	/* Mask all requests except CPU and AHB during PHY init */
+	writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
+
+	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
+		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
+
+	setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+
+	ast2500_sdrammc_init_phy(priv->phy);
+	if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
+		ast2500_sdrammc_init_ddr4(priv);
+	} else {
+		debug("Unsupported DRAM3\n");
+		return -EINVAL;
+	}
+
+	clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+	ast2500_sdrammc_lock(priv);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret = regmap_init_mem(dev, &map);
+
+	if (ret)
+		return ret;
+
+	priv->regs = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "clock-frequency", 0);
+
+	if (!priv->clock_rate) {
+		debug("DDR Clock Rate not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops ast2500_sdrammc_ops = {
+	.get_info = ast2500_sdrammc_get_info,
+};
+
+static const struct udevice_id ast2500_sdrammc_ids[] = {
+	{ .compatible = "aspeed,ast2500-sdrammc" },
+	{ }
+};
+
+U_BOOT_DRIVER(sdrammc_ast2500) = {
+	.name = "aspeed_ast2500_sdrammc",
+	.id = UCLASS_RAM,
+	.of_match = ast2500_sdrammc_ids,
+	.ops = &ast2500_sdrammc_ops,
+	.ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
+	.probe = ast2500_sdrammc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 40a5e8cae8..625513789c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
new file mode 100644
index 0000000000..65d1cd6e29
--- /dev/null
+++ b/drivers/clk/aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
new file mode 100644
index 0000000000..c888a6d35b
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ */
+
+/*
+ * Get the rate of the M-PLL clock from input clock frequency and
+ * the value of the M-PLL Parameter Register.
+ */
+static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
+{
+	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
+	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
+			& SCU_MPLL_DENUM_MASK;
+	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
+			& SCU_MPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+/*
+ * Get the rate of the H-PLL clock from input clock frequency and
+ * the value of the H-PLL Parameter Register.
+ */
+static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
+{
+	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
+	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
+			& SCU_HPLL_DENUM_MASK;
+	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
+			& SCU_HPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+static ulong ast2500_get_clkin(struct ast2500_scu *scu)
+{
+	return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
+			? 25*1000*1000 : 24*1000*1000;
+}
+
+static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart)
+{
+	/*
+	 * ast2500 datasheet is very confusing when it comes to UART clocks,
+	 * especially when CLKIN = 25 MHz. The settings are in
+	 * different registers and it is unclear how they interact.
+	 *
+	 * This has only been tested with default settings and CLKIN = 24 MHz.
+	 */
+	ulong uart_clkin;
+
+	if (readl(&scu->misc_ctrl2) & (1 << (uart + SCU_MISC2_UARTCLK_SHIFT)))
+		uart_clkin = 192 * 1000 * 1000;
+	else
+		uart_clkin = 24 * 1000 * 1000;
+
+	if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
+		uart_clkin /= 13;
+
+	return uart_clkin;
+}
+
+static ulong ast2500_clk_get_rate(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong clkin = ast2500_get_clkin(priv->scu);
+	ulong rate;
+
+	switch (clk->id) {
+	case PLL_HPLL:
+	case ARMCLK:
+		/*
+		 * This ignores dynamic/static slowdown of ARMCLK and may
+		 * be inaccurate.
+		 */
+		rate = ast2500_get_hpll_rate(clkin,
+					     readl(&priv->scu->h_pll_param));
+		break;
+	case MCLK_DDR:
+		rate = ast2500_get_mpll_rate(clkin,
+					     readl(&priv->scu->m_pll_param));
+		break;
+	case PCLK_UART1:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
+		break;
+	case PCLK_UART2:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 2);
+		break;
+	case PCLK_UART3:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 3);
+		break;
+	case PCLK_UART4:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 4);
+		break;
+	case PCLK_UART5:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 5);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static void ast2500_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+static void ast2500_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
+
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+
+	/*
+	 * There are not that many combinations of numerator, denumerator
+	 * and post divider, so just brute force the best combination.
+	 * However, to avoid overflow when multiplying, use kHz.
+	 */
+	const ulong clkin_khz = clkin / 1000;
+	const ulong rate_khz = rate / 1000;
+
+	ulong best_num = 0;
+	ulong best_denum = 0;
+	ulong best_post = 0;
+	ulong delta = rate;
+
+	ulong num, denum, post;
+	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
+		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
+			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
+			ulong new_rate_khz = (clkin_khz
+					      * ((num + 1) / (denum + 1)))
+					     / (post + 1);
+
+			/* Keep the rate below requested one. */
+			if (new_rate_khz > rate_khz)
+				continue;
+
+			if (new_rate_khz - rate_khz < delta) {
+				delta = new_rate_khz - rate_khz;
+
+				best_num = num;
+				best_denum = denum;
+				best_post = post;
+
+				if (delta == 0)
+					goto rate_calc_done;
+			}
+		}
+	}
+
+ rate_calc_done:
+
+	mpll_reg = readl(&scu->m_pll_param);
+	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
+		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
+		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
+	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
+	    | (best_num << SCU_MPLL_NUM_SHIFT)
+	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+
+	ast2500_scu_unlock(scu);
+	writel(mpll_reg, &scu->m_pll_param);
+	ast2500_scu_lock(scu);
+
+	return ast2500_get_mpll_rate(clkin, mpll_reg);
+}
+
+static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong new_rate;
+	switch (clk->id) {
+	case PLL_MPLL:
+	case MCLK_DDR:
+		new_rate = ast2500_configure_ddr(priv->scu, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+struct clk_ops ast2500_clk_ops = {
+	.get_rate = ast2500_clk_get_rate,
+	.set_rate = ast2500_clk_set_rate,
+};
+
+static int ast2500_clk_probe(struct udevice *dev)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(dev);
+	priv->scu = (struct ast2500_scu *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static int ast2500_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+	if (ret)
+		debug("Warning: No reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_clk_ids[] = {
+	{ .compatible = "aspeed,ast2500-scu" },
+	{ }
+};
+
+U_BOOT_DRIVER(aspeed_ast2500_scu) = {
+	.name		= "aspeed_ast2500_scu",
+	.id		= UCLASS_CLK,
+	.of_match	= ast2500_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
+	.ops		= &ast2500_clk_ops,
+	.bind		= ast2500_clk_bind,
+	.probe		= ast2500_clk_probe,
+};
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
new file mode 100644
index 0000000000..ca58b12943
--- /dev/null
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Core Clocks */
+#define PLL_HPLL	1
+#define PLL_DPLL	2
+#define PLL_D2PLL	3
+#define PLL_MPLL	4
+#define ARMCLK		5
+
+
+/* Bus Clocks, derived from core clocks */
+#define BCLK_PCLK	101
+#define BCLK_LHCLK	102
+#define BCLK_MACCLK	103
+#define BCLK_SDCLK	104
+#define BCLK_ARMCLK	105
+
+#define MCLK_DDR	201
+
+/* Special clocks */
+#define PCLK_UART1	501
+#define PCLK_UART2	502
+#define PCLK_UART3	503
+#define PCLK_UART4	504
+#define PCLK_UART5	505
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v1 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
@ 2017-01-05 22:42   ` Maxim Sloyko
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:42 UTC (permalink / raw)
  To: u-boot

---

Changes in v1:
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/mach-aspeed/Makefile        |  2 +-
 arch/arm/mach-aspeed/ast2500-board.c | 78 +++++++++++++++++++++++++++++++++
 include/configs/aspeed-common.h      | 84 ++++++++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 include/configs/aspeed-common.h

diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 1f7af71b03..9d29ff7f6f 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
new file mode 100644
index 0000000000..6ff74f0a1f
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+#include <ram.h>
+#include <timer.h>
+
+/* Second Watchdog Timer by default is configured
+ * to trigger secondary boot source.
+ */
+#define AST_2ND_BOOT_WDT		(1)
+
+/* Third Watchdog Timer by default is configured
+ * to toggle Flash address mode switch before reset.
+ */
+#define AST_FLASH_ADDR_DETECT_WDT	(2)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void lowlevel_init(void)
+{
+	/*
+	 * These two watchdogs need to be stopped as soon as possible,
+	 * otherwise the board might hang. By default they are set to
+	 * a very short timeout and even simple debug write to serial
+	 * console early in the init process might cause them to fire.
+	 */
+	struct ast_wdt *flash_addr_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_FLASH_ADDR_DETECT_WDT);
+
+	clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
+
+#ifndef CONFIG_FIRMWARE_2ND_BOOT
+	struct ast_wdt *sec_boot_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_2ND_BOOT_WDT);
+
+	clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
+#endif
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct udevice *dev;
+	int ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM FAIL1\r\n");
+		return ret;
+	}
+
+	struct ram_info ram;
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("DRAM FAIL2\r\n");
+		return ret;
+	}
+
+
+	gd->ram_size = ram.size;
+	return 0;
+}
diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
new file mode 100644
index 0000000000..c125e39e3f
--- /dev/null
+++ b/include/configs/aspeed-common.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 IBM Corporation
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __AST_COMMON_CONFIG_H
+#define __AST_COMMON_CONFIG_H
+
+/* Misc CPU related */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_CMDLINE_EDITING		1
+
+/* Enable cache controller */
+#define CONFIG_SYS_DCACHE_OFF		1
+
+#ifdef CONFIG_PRE_CON_BUF_SZ
+#define PRE_CON_RAM_SZ		CONFIG_PRE_CON_BUF_SZ
+#else
+#define PRE_CON_RAM_SZ	0
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000 + PRE_CON_RAM_SZ)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024 - PRE_CON_RAM_SZ)
+#define SYS_INIT_RAM_END		(CONFIG_SYS_INIT_RAM_ADDR \
+					 + CONFIG_SYS_INIT_RAM_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(SYS_INIT_RAM_END \
+					 - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE \
+					 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_TEXT_BASE		0x00000000
+
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_SUBNETMASK
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE		256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					 + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+#define CONFIG_BOOTARGS \
+		"console=ttyS4,115200n8" \
+		" root=/dev/ram rw"
+
+#define CONFIG_BOOTCOMMAND		"bootm 20080000 20300000"
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=yes\0"	\
+	"spi_dma=yes\0" \
+	""
+
+#endif	/* __AST_COMMON_CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v1 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
                     ` (2 preceding siblings ...)
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-05 22:42   ` Maxim Sloyko
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-05 22:42 UTC (permalink / raw)
  To: u-boot

ast2500 Eval Board device tree and board specific configuration.

---

Changes in v1:
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/Makefile                  |  2 ++
 arch/arm/dts/ast2500-evb.dts           | 23 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
 board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
 board/aspeed/evb_ast2500/Makefile      |  1 +
 board/aspeed/evb_ast2500/evb_ast2500.c |  6 ++++++
 configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
 include/configs/evb_ast2500.h          | 30 ++++++++++++++++++++++++++++++
 8 files changed, 102 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 include/configs/evb_ast2500.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f43746966c..1bee50e237 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb
 
+dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
new file mode 100644
index 0000000000..dc13952fb8
--- /dev/null
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "ast2500-u-boot.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&sdrammc {
+	clock-frequency = <400000000>;
+};
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
index c0b448f19e..7397d0c179 100644
--- a/arch/arm/mach-aspeed/ast2500/Kconfig
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -3,4 +3,11 @@ if ASPEED_AST2500
 config SYS_CPU
 	default "arm1176"
 
+config TARGET_EVB_AST2500
+	bool "Evb-AST2500"
+	help
+	  Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
+
+source "board/aspeed/evb_ast2500/Kconfig"
+
 endif
diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
new file mode 100644
index 0000000000..73a8ae85f6
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2500
+
+config SYS_BOARD
+	default "evb_ast2500"
+
+config SYS_VENDOR
+	default "aspeed"
+
+config SYS_CONFIG_NAME
+	default "evb_ast2500"
+
+endif
diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
new file mode 100644
index 0000000000..4564098299
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2500.o
diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
new file mode 100644
index 0000000000..649e3ba27e
--- /dev/null
+++ b/board/aspeed/evb_ast2500/evb_ast2500.c
@@ -0,0 +1,6 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
new file mode 100644
index 0000000000..4598f6f418
--- /dev/null
+++ b/configs/evb-ast2500_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_ASPEED_AST2500=y
+CONFIG_TARGET_EVB_AST2500=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_CLK=y
+CONFIG_TIMER=y
+CONFIG_RAM=y
+CONFIG_REGMAP=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x1e720000
+CONFIG_PRE_CON_BUF_SZ=4096
+CONFIG_SYS_NO_FLASH=y
+CONFIG_CMD_IMLS=n
diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
new file mode 100644
index 0000000000..28d11a2bdf
--- /dev/null
+++ b/include/configs/evb_ast2500.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 Google Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+
+#define CONFIG_SYS_MEMTEST_START	(CONFIG_SYS_SDRAM_BASE + 0x300000)
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x5000000)
+
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/*
+ * Memory Info
+ */
+#define CONFIG_SYS_LOAD_ADDR		0x83000000
+
+#define CONFIG_ENV_IS_NOWHERE		1
+
+#define CONFIG_ENV_SIZE			0x20000
+
+#endif	/* __CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
                     ` (3 preceding siblings ...)
  2017-01-05 22:42   ` [U-Boot] [PATCH v1 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-10  1:50   ` Maxim Sloyko
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
                       ` (4 more replies)
  4 siblings, 5 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-10  1:50 UTC (permalink / raw)
  To: u-boot

This series adds minimal support for AST2500 part and eval board,
enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
Clock (very basic) and SDRAM MC drivers, all written from scratch,
using AST2500 datasheet. Aspeed's SDK was used only for reference.
Given very limited documentation provided by Aspeed, some parts of SDRAM
init sequence were basically rewritten to do the same thing that is done
in Aspeed SDK, without real understanding of what is going on.

The file layout closely follows the example of rk3288 chip and firefly-rk3288
board.

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Maxim Sloyko (4):
  aspeed: Add drivers common to all Aspeed SoCs
  aspeed: Add basic ast2500 specific drivers and configuration
  aspeed: Board init functions and common configs for ast2500 based
    boards
  aspeed: Support for ast2500 Eval Board

 arch/arm/Kconfig                                 |   7 +
 arch/arm/Makefile                                |   1 +
 arch/arm/dts/Makefile                            |   2 +
 arch/arm/dts/ast2500-evb.dts                     |  23 ++
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/include/asm/arch-aspeed/timer.h         |  54 +++
 arch/arm/include/asm/arch-aspeed/wdt.h           |  89 +++++
 arch/arm/mach-aspeed/Kconfig                     |  24 ++
 arch/arm/mach-aspeed/Makefile                    |   8 +
 arch/arm/mach-aspeed/ast2500-board.c             |  78 ++++
 arch/arm/mach-aspeed/ast2500/Kconfig             |  13 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast_wdt.c                   |  37 ++
 board/aspeed/evb_ast2500/Kconfig                 |  12 +
 board/aspeed/evb_ast2500/Makefile                |   1 +
 board/aspeed/evb_ast2500/evb_ast2500.c           |   6 +
 configs/evb-ast2500_defconfig                    |  21 ++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 drivers/sysreset/Makefile                        |   1 +
 drivers/sysreset/sysreset_ast.c                  |  55 +++
 drivers/timer/Kconfig                            |   7 +
 drivers/timer/Makefile                           |   1 +
 drivers/timer/ast_timer.c                        |  96 +++++
 include/configs/aspeed-common.h                  |  84 +++++
 include/configs/evb_ast2500.h                    |  30 ++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 33 files changed, 1895 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c
 create mode 100644 include/configs/aspeed-common.h
 create mode 100644 include/configs/evb_ast2500.h
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

--
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
@ 2017-01-10  1:50     ` Maxim Sloyko
  2017-01-11  3:20       ` Tom Rini
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-10  1:50 UTC (permalink / raw)
  To: u-boot

Add support for Watchdog Timer, which is compatible with AST2400 and
AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
does not follow the driver model. It also uses fixed clock, so no clock
driver is needed.

Add support for timer for Aspeed ast2400/ast2500 devices.
The driver actually controls several devices, but because all devices
share the same Control Register, it is somewhat difficult to completely
decouple them. Since only one timer is needed at the moment, this should
be OK. The timer uses fixed clock, so does not rely on a clock driver.

Add sysreset driver, which uses watchdog timer to do resets and particular
watchdog device to use is hardcoded (0)

---

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/Kconfig                         |  7 +++
 arch/arm/Makefile                        |  1 +
 arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
 arch/arm/include/asm/arch-aspeed/wdt.h   | 89 +++++++++++++++++++++++++++++
 arch/arm/mach-aspeed/Kconfig             | 22 ++++++++
 arch/arm/mach-aspeed/Makefile            |  7 +++
 arch/arm/mach-aspeed/ast_wdt.c           | 37 ++++++++++++
 drivers/sysreset/Makefile                |  1 +
 drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
 drivers/timer/Kconfig                    |  7 +++
 drivers/timer/Makefile                   |  1 +
 drivers/timer/ast_timer.c                | 96 ++++++++++++++++++++++++++++++++
 12 files changed, 377 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 714dd8b514..135c544335 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
 	select OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 
+config ARCH_ASPEED
+	bool "Support Aspeed SoCs"
+	select OF_CONTROL
+	select DM
+
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm283x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 236debb452..cc73e1038e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ASPEED)		+= aspeed
 machine-$(CONFIG_ARCH_AT91)		+= at91
 machine-$(CONFIG_ARCH_BCM283X)		+= bcm283x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
new file mode 100644
index 0000000000..87c5b354ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/timer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_TIMER_H
+#define _ASM_ARCH_TIMER_H
+
+/* Each timer has 4 control bits in ctrl1 register.
+ * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
+ * such that timer X uses bits (4 * X - 4):(4 * X - 1)
+ * If the timer does not support PWM, bit 4 is reserved.
+ */
+#define AST_TMC_EN			(1 << 0)
+#define AST_TMC_1MHZ			(1 << 1)
+#define AST_TMC_OVFINTR			(1 << 2)
+#define AST_TMC_PWM			(1 << 3)
+
+/* Timers are counted from 1 in the datasheet. */
+#define AST_TMC_CTRL1_SHIFT(n)			(4 * ((n) - 1))
+
+#define AST_TMC_RATE  (1000*1000)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All timers share control registers, which makes it harder to make them
+ * separate devices. Since only one timer is needed@the moment, making
+ * it this just one device.
+ */
+
+struct ast_timer_counter {
+	u32 status;
+	u32 reload_val;
+	u32 match1;
+	u32 match2;
+};
+
+struct ast_timer {
+	struct ast_timer_counter timers1[3];
+	u32 ctrl1;
+	u32 ctrl2;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 ctrl3;
+	u32 ctrl1_clr;
+#else
+	u32 reserved[2];
+#endif
+	struct ast_timer_counter timers2[5];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_TIMER_H */
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
new file mode 100644
index 0000000000..32774b1a70
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_WDT_H
+#define _ASM_ARCH_WDT_H
+
+#define WDT_BASE			0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL		0x4755
+
+/* Control register */
+#define WDT_CTRL_RESET_MODE_SHIFT	5
+#define WDT_CTRL_RESET_MODE_MASK	3
+
+#define WDT_CTRL_EN			(1 << 0)
+#define WDT_CTRL_RESET			(1 << 1)
+#define WDT_CTRL_CLK1MHZ		(1 << 4)
+#define WDT_CTRL_2ND_BOOT		(1 << 7)
+
+/* Values for Reset Mode */
+#define WDT_CTRL_RESET_SOC		0
+#define WDT_CTRL_RESET_CHIP		1
+#define WDT_CTRL_RESET_CPU		2
+#define WDT_CTRL_RESET_MASK		3
+
+/* Reset Mask register */
+#define WDT_RESET_ARM			(1 << 0)
+#define WDT_RESET_COPROC		(1 << 1)
+#define WDT_RESET_SDRAM			(1 << 2)
+#define WDT_RESET_AHB			(1 << 3)
+#define WDT_RESET_I2C			(1 << 4)
+#define WDT_RESET_MAC1			(1 << 5)
+#define WDT_RESET_MAC2			(1 << 6)
+#define WDT_RESET_GCRT			(1 << 7)
+#define WDT_RESET_USB20			(1 << 8)
+#define WDT_RESET_USB11_HOST		(1 << 9)
+#define WDT_RESET_USB11_EHCI2		(1 << 10)
+#define WDT_RESET_VIDEO			(1 << 11)
+#define WDT_RESET_HAC			(1 << 12)
+#define WDT_RESET_LPC			(1 << 13)
+#define WDT_RESET_SDSDIO		(1 << 14)
+#define WDT_RESET_MIC			(1 << 15)
+#define WDT_RESET_CRT2C			(1 << 16)
+#define WDT_RESET_PWM			(1 << 17)
+#define WDT_RESET_PECI			(1 << 18)
+#define WDT_RESET_JTAG			(1 << 19)
+#define WDT_RESET_ADC			(1 << 20)
+#define WDT_RESET_GPIO			(1 << 21)
+#define WDT_RESET_MCTP			(1 << 22)
+#define WDT_RESET_XDMA			(1 << 23)
+#define WDT_RESET_SPI			(1 << 24)
+#define WDT_RESET_MISC			(1 << 25)
+
+#ifndef __ASSEMBLY__
+struct ast_wdt {
+	u32 counter_status;
+	u32 counter_reload_val;
+	u32 counter_restart;
+	u32 ctrl;
+	u32 timeout_status;
+	u32 clr_timeout_status;
+	u32 reset_width;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 reset_mask;
+#else
+	u32 reserved0;
+#endif
+};
+
+void wdt_stop(struct ast_wdt *wdt);
+void wdt_start(struct ast_wdt *wdt, u32 timeout);
+
+/**
+ * ast_get_wdt() - get a pointer to watchdog registers
+ *
+ * @wdt_number: 0-based WDT peripheral number
+ * @return pointer to registers or -ve error on error
+ */
+struct ast_wdt *ast_get_wdt(u8 wdt_number);
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000000..837a887cae
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,22 @@
+if ARCH_ASPEED
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_SOC
+	default "aspeed"
+
+config ASPEED_AST2500
+	bool "Support Aspeed AST2500 SoC"
+	select CPU_ARM1176
+	help
+	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
+
+config WDT_NUM
+	int "Number of Watchdog Timers"
+	default 3 if ASPEED_AST2500
+	help
+	  The number of Watchdot Timers on a SoC.
+	  AST2500 has three WDTsk earlier versions have two or fewer.
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000000..a14b8f751d
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
new file mode 100644
index 0000000000..7070824318
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+void wdt_stop(struct ast_wdt *wdt)
+{
+	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+}
+
+void wdt_start(struct ast_wdt *wdt, u32 timeout)
+{
+	writel(timeout, &wdt->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&wdt->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+}
+
+struct ast_wdt *ast_get_wdt(u8 wdt_number)
+{
+	if (wdt_number > CONFIG_WDT_NUM - 1)
+		return ERR_PTR(-EINVAL);
+
+	return (struct ast_wdt *)(WDT_BASE +
+				  sizeof(struct ast_wdt) * wdt_number);
+}
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index fa75cc52de..37638a8eea 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
new file mode 100644
index 0000000000..a0ab12851d
--- /dev/null
+++ b/drivers/sysreset/sysreset_ast.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+/* Number of Watchdog Timer ticks before reset */
+#define AST_WDT_RESET_TIMEOUT	10
+#define AST_WDT_FOR_RESET	0
+
+static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
+	u32 reset_mode = 0;
+
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		reset_mode = WDT_CTRL_RESET_CPU;
+		break;
+	case SYSRESET_COLD:
+		reset_mode = WDT_CTRL_RESET_CHIP;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	/* Clear reset mode bits */
+	clrsetbits_le32(&wdt->ctrl,
+			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
+			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
+	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops ast_sysreset = {
+	.request	= ast_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_ast) = {
+	.name	= "ast_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &ast_sysreset,
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index cb18f12fc9..9c5f98bb88 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -46,4 +46,11 @@ config OMAP_TIMER
 	help
 	  Select this to enable an timer for Omap devices.
 
+config AST_TIMER
+	bool "Aspeed ast2400/ast2500 timer support"
+	depends on TIMER
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable timer for Aspeed ast2400/ast2500 devices.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index f351fbb4e0..a4b1a486b0 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
new file mode 100644
index 0000000000..be48d24cea
--- /dev/null
+++ b/drivers/timer/ast_timer.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define AST_TICK_TIMER  1
+#define AST_TMC_RELOAD_VAL  0xffffffff
+
+struct ast_timer_priv {
+	struct ast_timer *regs;
+};
+
+static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
+						       int n)
+{
+	if (n > 3)
+		return &timer->timers2[n - 4];
+	else
+		return &timer->timers1[n - 1];
+}
+
+static int ast_timer_probe(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
+
+	/*
+	 * Stop the timer. This will also load reload_val into
+	 * the status register.
+	 */
+	clrbits_le32(&priv->regs->ctrl1,
+		     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+	/* Start the timer from the fixed 1MHz clock. */
+	setbits_le32(&priv->regs->ctrl1,
+		     (AST_TMC_EN | AST_TMC_1MHZ) <<
+		     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+
+	uc_priv->clock_rate = AST_TMC_RATE;
+
+	return 0;
+}
+
+static int ast_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+
+	*count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
+
+	return 0;
+}
+
+static int ast_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = (struct ast_timer *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static const struct timer_ops ast_timer_ops = {
+	.get_count = ast_timer_get_count,
+};
+
+static const struct udevice_id ast_timer_ids[] = {
+	{ .compatible = "aspeed,ast2500-timer" },
+	{ .compatible = "aspeed,ast2400-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(ast_timer) = {
+	.name = "ast_timer",
+	.id = UCLASS_TIMER,
+	.of_match = ast_timer_ids,
+	.probe = ast_timer_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_timer_priv),
+	.ofdata_to_platdata = ast_timer_ofdata_to_platdata,
+	.ops = &ast_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-10  1:50     ` Maxim Sloyko
  2017-01-11  3:20       ` Tom Rini
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
                       ` (2 subsequent siblings)
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-10  1:50 UTC (permalink / raw)
  To: u-boot

Clock Driver

This driver is ast2500 specific and is not compatible with earlier
versions of this chip. The differences are not that big, but they are
in somewhat random places, so making it compatible with ast2400 is not
worth the effort at the moment.

SDRAM MC driver

The driver is very ast2500 specific and is completely incompatible
with previous versions of the chip.

The memory controller is very poorly documented by Aspeed in the
datasheet, with any mention of the whole range of registers missing. The
initialization procedure has been basically taken from Aspeed SDK, where
it is implemented in assembly and rewritten in C, with very limited
understanding of what exacly it is doing.

---

Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/mach-aspeed/Kconfig                     |   2 +
 arch/arm/mach-aspeed/Makefile                    |   1 +
 arch/arm/mach-aspeed/ast2500/Kconfig             |   6 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 14 files changed, 1254 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
new file mode 100644
index 0000000000..c95a7ba835
--- /dev/null
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -0,0 +1,53 @@
+#include <dt-bindings/clock/ast2500-scu.h>
+
+#include "ast2500.dtsi"
+
+/ {
+	scu: clock-controller at 1e6e2000 {
+		compatible = "aspeed,ast2500-scu";
+		reg = <0x1e6e2000 0x1000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	sdrammc: sdrammc at 1e6e0000 {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-sdrammc";
+		reg = <0x1e6e0000 0x174
+			0x1e6e0200 0x1d4 >;
+		clocks = <&scu PLL_MPLL>;
+	};
+
+	ahb {
+		u-boot,dm-pre-reloc;
+
+		apb {
+			u-boot,dm-pre-reloc;
+
+			timer: timer at 1e782000 {
+				u-boot,dm-pre-reloc;
+			};
+
+			uart1: serial at 1e783000 {
+				clocks = <&scu PCLK_UART1>;
+			};
+
+			uart2: serial at 1e78d000 {
+				clocks = <&scu PCLK_UART2>;
+			};
+
+			uart3: serial at 1e78e000 {
+				clocks = <&scu PCLK_UART3>;
+			};
+
+			uart4: serial at 1e78f000 {
+				clocks = <&scu PCLK_UART4>;
+			};
+
+			uart5: serial at 1e784000 {
+				clocks = <&scu PCLK_UART5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
new file mode 100644
index 0000000000..97fac69d11
--- /dev/null
+++ b/arch/arm/dts/ast2500.dtsi
@@ -0,0 +1,174 @@
+/*
+ * This device tree is copied from
+ * https://raw.githubusercontent.com/torvalds/linux/02440622/arch/arm/boot/dts/
+ */
+#include "skeleton.dtsi"
+
+/ {
+	model = "Aspeed BMC";
+	compatible = "aspeed,ast2500";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&vic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,arm1176jzf-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vic: interrupt-controller at 1e6c0080 {
+			compatible = "aspeed,ast2400-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			valid-sources = <0xfefff7ff 0x0807ffff>;
+			reg = <0x1e6c0080 0x80>;
+		};
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			clk_clkin: clk_clkin at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-clkin-clock";
+				reg = <0x1e6e2070 0x04>;
+			};
+
+			clk_hpll: clk_hpll at 1e6e2024 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-hpll-clock";
+				reg = <0x1e6e2024 0x4>;
+				clocks = <&clk_clkin>;
+			};
+
+			clk_ahb: clk_ahb at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-ahb-clock";
+				reg = <0x1e6e2070 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_apb: clk_apb at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-apb-clock";
+				reg = <0x1e6e2008 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_uart: clk_uart at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,uart-clock";
+				reg = <0x1e6e202c 0x4>;
+			};
+
+			sram at 1e720000 {
+				compatible = "mmio-sram";
+				reg = <0x1e720000 0x9000>;	// 36K
+			};
+
+			timer: timer at 1e782000 {
+				compatible = "aspeed,ast2400-timer";
+				reg = <0x1e782000 0x90>;
+				// The moxart_timer driver registers only one
+				// interrupt and assumes it's for timer 1
+				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16>;
+				clocks = <&clk_apb>;
+			};
+
+			wdt1: wdt at 1e785000 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785000 0x1c>;
+				interrupts = <27>;
+			};
+
+			wdt2: wdt at 1e785020 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785020 0x1c>;
+				interrupts = <27>;
+				status = "disabled";
+			};
+
+			wdt3: wdt at 1e785040 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785074 0x1c>;
+				status = "disabled";
+			};
+
+			uart1: serial at 1e783000 {
+				compatible = "ns16550a";
+				reg = <0x1e783000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <9>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart2: serial at 1e78d000 {
+				compatible = "ns16550a";
+				reg = <0x1e78d000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <32>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart3: serial at 1e78e000 {
+				compatible = "ns16550a";
+				reg = <0x1e78e000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <33>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart4: serial at 1e78f000 {
+				compatible = "ns16550a";
+				reg = <0x1e78f000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <34>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart5: serial at 1e784000 {
+				compatible = "ns16550a";
+				reg = <0x1e784000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				current-speed = <38400>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart6: serial at 1e787000 {
+				compatible = "ns16550a";
+				reg = <0x1e787000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
new file mode 100644
index 0000000000..6c6af68f4f
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SCU_AST2500_H
+#define _ASM_ARCH_SCU_AST2500_H
+
+#define SCU_UNLOCK_VALUE		0x1688a8a8
+
+#define SCU_HWSTRAP_VGAMEM_MASK		3
+#define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_DDR4		(1 << 24)
+#define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
+
+#define SCU_MPLL_DENUM_SHIFT		0
+#define SCU_MPLL_DENUM_MASK		0x1f
+#define SCU_MPLL_NUM_SHIFT		5
+#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_POST_SHIFT		13
+#define SCU_MPLL_POST_MASK		0x3f
+
+#define SCU_HPLL_DENUM_SHIFT		0
+#define SCU_HPLL_DENUM_MASK		0x1f
+#define SCU_HPLL_NUM_SHIFT		5
+#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_POST_SHIFT		13
+#define SCU_HPLL_POST_MASK		0x3f
+
+#define SCU_MISC2_UARTCLK_SHIFT		24
+
+#define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_clk_priv {
+	struct ast2500_scu *scu;
+};
+
+struct ast2500_scu {
+	u32 protection_key;
+	u32 sysreset_ctrl1;
+	u32 clk_sel1;
+	u32 clk_stop_ctrl1;
+	u32 freq_counter_ctrl;
+	u32 freq_counter_cmp;
+	u32 intr_ctrl;
+	u32 d2_pll_param;
+	u32 m_pll_param;
+	u32 h_pll_param;
+	u32 d_pll_param;
+	u32 misc_ctrl1;
+	u32 pci_config[3];
+	u32 sysreset_status;
+	u32 vga_handshake[2];
+	u32 mac_clk_delay;
+	u32 misc_ctrl2;
+	u32 vga_scratch[8];
+	u32 hwstrap;
+	u32 rng_ctrl;
+	u32 rng_data;
+	u32 rev_id;
+	u32 pinmux_ctrl[6];
+	u32 reserved0;
+	u32 extrst_sel;
+	u32 pinmux_ctrl1[4];
+	u32 reserved1[2];
+	u32 mac_clk_delay_100M;
+	u32 mac_clk_delay_10M;
+	u32 wakeup_enable;
+	u32 wakeup_control;
+	u32 reserved2[3];
+	u32 sysreset_ctrl2;
+	u32 clk_sel2;
+	u32 clk_stop_ctrl2;
+	u32 freerun_counter;
+	u32 freerun_counter_ext;
+	u32 clk_duty_meas_ctrl;
+	u32 clk_duty_meas_res;
+	u32 reserved3[4];
+	/* The next registers are not key protected */
+	struct ast2500_cpu2 {
+		u32 ctrl;
+		u32 base_addr[9];
+		u32 cache_ctrl;
+	} cpu2;
+	u32 reserved4;
+	u32 d_pll_ext_param[3];
+	u32 d2_pll_ext_param[3];
+	u32 mh_pll_ext_param;
+	u32 reserved5;
+	u32 chip_id[2];
+	u32 reserved6[2];
+	u32 uart_clk_ctrl;
+	u32 reserved7[7];
+	u32 pcie_config;
+	u32 mmio_decode;
+	u32 reloc_ctrl_decode[2];
+	u32 mailbox_addr;
+	u32 shared_sram_decode[2];
+	u32 bmc_rev_id;
+	u32 reserved8;
+	u32 bmc_device_id;
+	u32 reserved9[13];
+	u32 clk_duty_sel;
+};
+
+int ast_get_clk(struct udevice **devp);
+void *ast_get_scu(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
new file mode 100644
index 0000000000..a5f8615ae2
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_AST2500_H
+#define _ASM_ARCH_SDRAM_AST2500_H
+
+#define SDRAM_UNLOCK_KEY		0xfc600309
+#define SDRAM_VIDEO_UNLOCK_KEY		0x2003000f
+
+#define SDRAM_PCR_CKE_EN		(1 << 0)
+#define SDRAM_PCR_AUTOPWRDN_EN		(1 << 1)
+#define SDRAM_PCR_CKE_DELAY_SHIFT	4
+#define SDRAM_PCR_CKE_DELAY_MASK	7
+#define SDRAM_PCR_RESETN_DIS		(1 << 7)
+#define SDRAM_PCR_ODT_EN		(1 << 8)
+#define SDRAM_PCR_ODT_AUTO_ON		(1 << 10)
+#define SDRAM_PCR_ODT_EXT_EN		(1 << 11)
+#define SDRAM_PCR_TCKE_PW_SHIFT		12
+#define SDRAM_PCR_TCKE_PW_MASK		7
+#define SDRAM_PCR_RGAP_CTRL_EN		(1 << 15)
+#define SDRAM_PCR_MREQI_DIS		(1 << 17)
+
+/* Fixed priority DRAM Requests mask */
+#define SDRAM_REQ_VGA_HW_CURSOR		(1 << 0)
+#define SDRAM_REQ_VGA_TEXT_CG_FONT	(1 << 1)
+#define SDRAM_REQ_VGA_TEXT_ASCII	(1 << 2)
+#define SDRAM_REQ_VGA_CRT		(1 << 3)
+#define SDRAM_REQ_SOC_DC_CURSOR		(1 << 4)
+#define SDRAM_REQ_SOC_DC_OCD		(1 << 5)
+#define SDRAM_REQ_SOC_DC_CRT		(1 << 6)
+#define SDRAM_REQ_VIDEO_HIPRI_WRITE	(1 << 7)
+#define SDRAM_REQ_USB20_EHCI1		(1 << 8)
+#define SDRAM_REQ_USB20_EHCI2		(1 << 9)
+#define SDRAM_REQ_CPU			(1 << 10)
+#define SDRAM_REQ_AHB2			(1 << 11)
+#define SDRAM_REQ_AHB			(1 << 12)
+#define SDRAM_REQ_MAC0			(1 << 13)
+#define SDRAM_REQ_MAC1			(1 << 14)
+#define SDRAM_REQ_PCIE			(1 << 16)
+#define SDRAM_REQ_XDMA			(1 << 17)
+#define SDRAM_REQ_ENCRYPTION		(1 << 18)
+#define SDRAM_REQ_VIDEO_FLAG		(1 << 21)
+#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE	(1 << 28)
+#define SDRAM_REQ_2D_RW			(1 << 29)
+#define SDRAM_REQ_MEMCHECK		(1 << 30)
+
+#define SDRAM_ICR_RESET_ALL		(1 << 31)
+
+#define SDRAM_CONF_CAP_SHIFT		0
+#define SDRAM_CONF_CAP_MASK		3
+#define SDRAM_CONF_DDR4			(1 << 4)
+#define SDRAM_CONF_SCRAMBLE		(1 << 8)
+#define SDRAM_CONF_SCRAMBLE_PAT2	(1 << 9)
+#define SDRAM_CONF_CACHE_EN		(1 << 10)
+#define SDRAM_CONF_CACHE_INIT_EN	(1 << 12)
+#define SDRAM_CONF_DUALX8		(1 << 13)
+#define SDRAM_CONF_CACHE_INIT_DONE	(1 << 19)
+
+#define SDRAM_CONF_CAP_128M		0
+#define SDRAM_CONF_CAP_256M		1
+#define SDRAM_CONF_CAP_512M		2
+#define SDRAM_CONF_CAP_1024M		3
+
+#define SDRAM_MISC_DDR4_TREFRESH	(1 << 3)
+
+#define SDRAM_PHYCTRL0_INIT		(1 << 0)
+#define SDRAM_PHYCTRL0_AUTO_UPDATE	(1 << 1)
+#define SDRAM_PHYCTRL0_NRST		(1 << 2)
+
+#define SDRAM_REFRESH_CYCLES_SHIFT	0
+#define SDRAM_REFRESH_CYCLES_MASK	0xf
+#define SDRAM_REFRESH_ZQCS_EN		(1 << 7)
+#define SDRAM_REFRESH_PERIOD_SHIFT	8
+#define SDRAM_REFRESH_PERIOD_MASK	0xf
+
+#define SDRAM_TEST_LEN_SHIFT		4
+#define SDRAM_TEST_LEN_MASK		0xfffff
+#define SDRAM_TEST_START_ADDR_SHIFT	24
+#define SDRAM_TEST_START_ADDR_MASK	0x3f
+
+#define SDRAM_TEST_EN			(1 << 0)
+#define SDRAM_TEST_MODE_SHIFT		1
+#define SDRAM_TEST_MODE_MASK		3
+#define SDRAM_TEST_MODE_WO		0
+#define SDRAM_TEST_MODE_RB		1
+#define SDRAM_TEST_MODE_RW		2
+#define SDRAM_TEST_GEN_MODE_SHIFT	3
+#define SDRAM_TEST_GEN_MODE_MASK	7
+#define SDRAM_TEST_TWO_MODES		(1 << 6)
+#define SDRAM_TEST_ERRSTOP		(1 << 7)
+#define SDRAM_TEST_DONE			(1 << 12)
+#define SDRAM_TEST_FAIL			(1 << 13)
+
+#define SDRAM_AC_TRFC_SHIFT		0
+#define SDRAM_AC_TRFC_MASK		0xff
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_sdrammc_regs {
+	u32 protection_key;
+	u32 config;
+	u32 gm_protection_key;
+	u32 refresh_timing;
+	u32 ac_timing[3];
+	u32 misc_control;
+	u32 mr46_mode_setting;
+	u32 mr5_mode_setting;
+	u32 mode_setting_control;
+	u32 mr02_mode_setting;
+	u32 mr13_mode_setting;
+	u32 power_control;
+	u32 req_limit_mask;
+	u32 pri_group_setting;
+	u32 max_grant_len[4];
+	u32 intr_ctrl;
+	u32 ecc_range_ctrl;
+	u32 first_ecc_err_addr;
+	u32 last_ecc_err_addr;
+	u32 phy_ctrl[4];
+	u32 ecc_test_ctrl;
+	u32 test_addr;
+	u32 test_fail_dq_bit;
+	u32 test_init_val;
+	u32 phy_debug_ctrl;
+	u32 phy_debug_data;
+	u32 reserved1[30];
+	u32 scu_passwd;
+	u32 reserved2[7];
+	u32 scu_mpll;
+	u32 reserved3[19];
+	u32 scu_hwstrap;
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index 837a887cae..4b99a5abbb 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -19,4 +19,6 @@ config WDT_NUM
 	  The number of Watchdot Timers on a SoC.
 	  AST2500 has three WDTsk earlier versions have two or fewer.
 
+source "arch/arm/mach-aspeed/ast2500/Kconfig"
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index a14b8f751d..1f7af71b03 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
new file mode 100644
index 0000000000..c0b448f19e
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -0,0 +1,6 @@
+if ASPEED_AST2500
+
+config SYS_CPU
+	default "arm1176"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
new file mode 100644
index 0000000000..a35b239ef3
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += clk_ast2500.o sdram_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
new file mode 100644
index 0000000000..079909fa64
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/scu_ast2500.h>
+
+int ast_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(aspeed_ast2500_scu), devp);
+}
+
+void *ast_get_scu(void)
+{
+	struct ast2500_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = ast_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->scu;
+}
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
new file mode 100644
index 0000000000..da25756e94
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *
+ * Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:		GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/sdram_ast2500.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <regmap.h>
+
+/* These configuration parameters are taken from Aspeed SDK */
+#define DDR4_MR46_MODE		0x08000000
+#define DDR4_MR5_MODE		0x400
+#define DDR4_MR13_MODE		0x101
+#define DDR4_MR02_MODE		0x410
+#define DDR4_TRFC		0x45457188
+
+#define PHY_CFG_SIZE		15
+
+static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
+static const struct {
+	u32 index[PHY_CFG_SIZE];
+	u32 value[PHY_CFG_SIZE];
+} ddr4_phy_config = {
+	.index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
+	.value = {
+		0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
+		0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
+		0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
+	},
+};
+
+#define SDRAM_MAX_SIZE		(1024 * 1024 * 1024)
+#define SDRAM_MIN_SIZE		(128 * 1024 * 1024)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Bandwidth configuration parameters for different SDRAM requests.
+ * These are hardcoded settings taken from Aspeed SDK.
+ */
+static const u32 ddr_max_grant_params[4] = {
+	0x88448844, 0x24422288, 0x22222222, 0x22222222
+};
+
+/*
+ * These registers are not documented by Aspeed at all.
+ * All writes and reads are taken pretty much as is from SDK.
+ */
+struct ast2500_ddr_phy {
+	u32 phy[117];
+};
+
+struct dram_info {
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct ast2500_sdrammc_regs *regs;
+	struct ast2500_scu *scu;
+	struct ast2500_ddr_phy *phy;
+	ulong clock_rate;
+};
+
+static int ast2500_sdrammc_reset(void)
+{
+	struct ast_wdt *wdt = ast_get_wdt(0);
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	/* Only Reset SDRAM */
+	writel(WDT_RESET_SDRAM, &wdt->reset_mask);
+	clrbits_le32(&wdt->ctrl,
+		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
+	wdt_start(wdt, 1);
+
+	/* Wait for WDT to reset */
+	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+		;
+	wdt_stop(wdt);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
+{
+	writel(0, &phy->phy[2]);
+	writel(0, &phy->phy[6]);
+	writel(0, &phy->phy[8]);
+	writel(0, &phy->phy[10]);
+	writel(0, &phy->phy[12]);
+	writel(0, &phy->phy[42]);
+	writel(0, &phy->phy[44]);
+
+	writel(0x86000000, &phy->phy[16]);
+	writel(0x00008600, &phy->phy[17]);
+	writel(0x80000000, &phy->phy[18]);
+	writel(0x80808080, &phy->phy[19]);
+
+	return 0;
+}
+
+static void ast2500_ddr_phy_init_process(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	writel(0, &regs->phy_ctrl[0]);
+	writel(0x4040, &info->phy->phy[51]);
+
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
+	while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
+		;
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
+	       &regs->phy_ctrl[0]);
+}
+
+static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
+{
+	writel(0, &info->regs->phy_ctrl[0]);
+	writel((vref << 8) | 0x6, &info->phy->phy[48]);
+	ast2500_ddr_phy_init_process(info);
+}
+
+static int ast2500_ddr_cbr_test(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	int i;
+	const u32 test_params = SDRAM_TEST_EN
+			| SDRAM_TEST_ERRSTOP
+			| SDRAM_TEST_TWO_MODES;
+	int ret = 0;
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
+	       (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
+	writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
+	writel(0xff00ff00, &regs->test_init_val);
+	writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
+	       SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
+
+	while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+		;
+
+	if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+		ret = -EIO;
+	} else {
+		for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
+			writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
+			       &regs->ecc_test_ctrl);
+			while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+				;
+			if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+				ret = -EIO;
+				break;
+			}
+		}
+	}
+
+	writel(0, &regs->refresh_timing);
+	writel(0, &regs->ecc_test_ctrl);
+	return ret;
+}
+
+static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
+{
+	int i;
+	int vref_min = 0xff;
+	int vref_max = 0;
+	int range_size = 0;
+
+	for (i = 1; i < 0x40; ++i) {
+		ast2500_sdrammc_set_vref(info, i);
+
+		int res = ast2500_ddr_cbr_test(info);
+		if (res < 0) {
+			if (range_size > 0)
+				break;
+		} else {
+			++range_size;
+			vref_min = min(vref_min, i);
+			vref_max = max(vref_max, i);
+		}
+	}
+
+	/* Pick average setting */
+	ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
+
+	return 0;
+}
+
+static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
+{
+	size_t vga_mem_size_base = 8 * 1024 * 1024;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap)
+			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
+			& SCU_HWSTRAP_VGAMEM_MASK;
+
+	return vga_mem_size_base << vga_hwconf;
+}
+
+/*
+ * Find out RAM size and save it in dram_info
+ *
+ * The procedure is taken from Aspeed SDK
+ */
+static void ast2500_sdrammc_calc_size(struct dram_info *info)
+{
+	/* The controller supports 128/256/512/1024 MB ram */
+	size_t ram_size = SDRAM_MIN_SIZE;
+	const int write_test_offset = 0x100000;
+	u32 test_pattern = 0xdeadbeef;
+	u32 cap_param = SDRAM_CONF_CAP_1024M;
+	u32 refresh_timing_param = DDR4_TRFC;
+	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
+
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		writel(test_pattern, write_addr_base + (ram_size >> 1));
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	/* One last write to overwrite all wrapped values */
+	writel(test_pattern, write_addr_base);
+
+	/* Reset the pattern and see which value was really written */
+	test_pattern = 0xdeadbeef;
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
+			break;
+
+		--cap_param;
+		refresh_timing_param >>= 8;
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	clrsetbits_le32(&info->regs->ac_timing[1],
+			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
+			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
+			 << SDRAM_AC_TRFC_SHIFT));
+
+	info->info.base = CONFIG_SYS_SDRAM_BASE;
+	info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
+	clrsetbits_le32(&info->regs->config,
+			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
+			((cap_param & SDRAM_CONF_CAP_MASK)
+			 << SDRAM_CONF_CAP_SHIFT));
+}
+
+static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
+{
+	int i;
+	const u32 power_control = SDRAM_PCR_CKE_EN
+	    | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
+	    | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
+	    | SDRAM_PCR_RESETN_DIS
+	    | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
+	const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
+#ifdef CONFIG_DUALX8_RAM
+	    | SDRAM_CONF_DUALX8
+#endif
+	    | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
+
+	writel(conf, &info->regs->config);
+	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
+		writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
+
+	writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
+	writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
+	writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
+	writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
+
+	for (i = 0; i < PHY_CFG_SIZE; ++i) {
+		writel(ddr4_phy_config.value[i],
+		       &info->phy->phy[ddr4_phy_config.index[i]]);
+	}
+
+	writel(power_control, &info->regs->power_control);
+
+	ast2500_ddr_phy_init_process(info);
+
+	int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
+	if (ret < 0) {
+		debug("Vref calibration failed!\n");
+		return ret;
+	}
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
+	       | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
+	       &info->regs->refresh_timing);
+
+	setbits_le32(&info->regs->power_control,
+		     SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
+
+	ast2500_sdrammc_calc_size(info);
+
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
+	while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
+		;
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
+
+	writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
+
+	/* Enable all requests except video & display */
+	writel(SDRAM_REQ_USB20_EHCI1
+	       | SDRAM_REQ_USB20_EHCI2
+	       | SDRAM_REQ_CPU
+	       | SDRAM_REQ_AHB2
+	       | SDRAM_REQ_AHB
+	       | SDRAM_REQ_MAC0
+	       | SDRAM_REQ_MAC1
+	       | SDRAM_REQ_PCIE
+	       | SDRAM_REQ_XDMA
+	       | SDRAM_REQ_ENCRYPTION
+	       | SDRAM_REQ_VIDEO_FLAG
+	       | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
+	       | SDRAM_REQ_2D_RW
+	       | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
+
+	return 0;
+}
+
+static void ast2500_sdrammc_unlock(struct dram_info *info)
+{
+	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (!readl(&info->regs->protection_key))
+		;
+}
+
+static void ast2500_sdrammc_lock(struct dram_info *info)
+{
+	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (readl(&info->regs->protection_key))
+		;
+}
+
+static int ast2500_sdrammc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
+	struct ast2500_sdrammc_regs *regs = priv->regs;
+	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+	int i;
+
+	if (ret) {
+		debug("DDR:No CLK\n");
+		return ret;
+	}
+
+	priv->scu = ast_get_scu();
+	if (IS_ERR(priv->scu))
+		return PTR_ERR(priv->scu);
+
+	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
+	ret = ast2500_sdrammc_reset();
+	if (ret)
+		return ret;
+
+	ast2500_sdrammc_unlock(priv);
+
+	writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
+	       &regs->power_control);
+	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
+
+	/* Mask all requests except CPU and AHB during PHY init */
+	writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
+
+	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
+		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
+
+	setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+
+	ast2500_sdrammc_init_phy(priv->phy);
+	if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
+		ast2500_sdrammc_init_ddr4(priv);
+	} else {
+		debug("Unsupported DRAM3\n");
+		return -EINVAL;
+	}
+
+	clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+	ast2500_sdrammc_lock(priv);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret = regmap_init_mem(dev, &map);
+
+	if (ret)
+		return ret;
+
+	priv->regs = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "clock-frequency", 0);
+
+	if (!priv->clock_rate) {
+		debug("DDR Clock Rate not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops ast2500_sdrammc_ops = {
+	.get_info = ast2500_sdrammc_get_info,
+};
+
+static const struct udevice_id ast2500_sdrammc_ids[] = {
+	{ .compatible = "aspeed,ast2500-sdrammc" },
+	{ }
+};
+
+U_BOOT_DRIVER(sdrammc_ast2500) = {
+	.name = "aspeed_ast2500_sdrammc",
+	.id = UCLASS_RAM,
+	.of_match = ast2500_sdrammc_ids,
+	.ops = &ast2500_sdrammc_ops,
+	.ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
+	.probe = ast2500_sdrammc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 40a5e8cae8..625513789c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
new file mode 100644
index 0000000000..65d1cd6e29
--- /dev/null
+++ b/drivers/clk/aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
new file mode 100644
index 0000000000..c888a6d35b
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ */
+
+/*
+ * Get the rate of the M-PLL clock from input clock frequency and
+ * the value of the M-PLL Parameter Register.
+ */
+static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
+{
+	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
+	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
+			& SCU_MPLL_DENUM_MASK;
+	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
+			& SCU_MPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+/*
+ * Get the rate of the H-PLL clock from input clock frequency and
+ * the value of the H-PLL Parameter Register.
+ */
+static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
+{
+	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
+	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
+			& SCU_HPLL_DENUM_MASK;
+	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
+			& SCU_HPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+static ulong ast2500_get_clkin(struct ast2500_scu *scu)
+{
+	return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
+			? 25*1000*1000 : 24*1000*1000;
+}
+
+static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart)
+{
+	/*
+	 * ast2500 datasheet is very confusing when it comes to UART clocks,
+	 * especially when CLKIN = 25 MHz. The settings are in
+	 * different registers and it is unclear how they interact.
+	 *
+	 * This has only been tested with default settings and CLKIN = 24 MHz.
+	 */
+	ulong uart_clkin;
+
+	if (readl(&scu->misc_ctrl2) & (1 << (uart + SCU_MISC2_UARTCLK_SHIFT)))
+		uart_clkin = 192 * 1000 * 1000;
+	else
+		uart_clkin = 24 * 1000 * 1000;
+
+	if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
+		uart_clkin /= 13;
+
+	return uart_clkin;
+}
+
+static ulong ast2500_clk_get_rate(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong clkin = ast2500_get_clkin(priv->scu);
+	ulong rate;
+
+	switch (clk->id) {
+	case PLL_HPLL:
+	case ARMCLK:
+		/*
+		 * This ignores dynamic/static slowdown of ARMCLK and may
+		 * be inaccurate.
+		 */
+		rate = ast2500_get_hpll_rate(clkin,
+					     readl(&priv->scu->h_pll_param));
+		break;
+	case MCLK_DDR:
+		rate = ast2500_get_mpll_rate(clkin,
+					     readl(&priv->scu->m_pll_param));
+		break;
+	case PCLK_UART1:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
+		break;
+	case PCLK_UART2:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 2);
+		break;
+	case PCLK_UART3:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 3);
+		break;
+	case PCLK_UART4:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 4);
+		break;
+	case PCLK_UART5:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 5);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static void ast2500_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+static void ast2500_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
+
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+
+	/*
+	 * There are not that many combinations of numerator, denumerator
+	 * and post divider, so just brute force the best combination.
+	 * However, to avoid overflow when multiplying, use kHz.
+	 */
+	const ulong clkin_khz = clkin / 1000;
+	const ulong rate_khz = rate / 1000;
+
+	ulong best_num = 0;
+	ulong best_denum = 0;
+	ulong best_post = 0;
+	ulong delta = rate;
+
+	ulong num, denum, post;
+	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
+		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
+			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
+			ulong new_rate_khz = (clkin_khz
+					      * ((num + 1) / (denum + 1)))
+					     / (post + 1);
+
+			/* Keep the rate below requested one. */
+			if (new_rate_khz > rate_khz)
+				continue;
+
+			if (new_rate_khz - rate_khz < delta) {
+				delta = new_rate_khz - rate_khz;
+
+				best_num = num;
+				best_denum = denum;
+				best_post = post;
+
+				if (delta == 0)
+					goto rate_calc_done;
+			}
+		}
+	}
+
+ rate_calc_done:
+
+	mpll_reg = readl(&scu->m_pll_param);
+	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
+		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
+		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
+	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
+	    | (best_num << SCU_MPLL_NUM_SHIFT)
+	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+
+	ast2500_scu_unlock(scu);
+	writel(mpll_reg, &scu->m_pll_param);
+	ast2500_scu_lock(scu);
+
+	return ast2500_get_mpll_rate(clkin, mpll_reg);
+}
+
+static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong new_rate;
+	switch (clk->id) {
+	case PLL_MPLL:
+	case MCLK_DDR:
+		new_rate = ast2500_configure_ddr(priv->scu, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+struct clk_ops ast2500_clk_ops = {
+	.get_rate = ast2500_clk_get_rate,
+	.set_rate = ast2500_clk_set_rate,
+};
+
+static int ast2500_clk_probe(struct udevice *dev)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(dev);
+	priv->scu = (struct ast2500_scu *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static int ast2500_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+	if (ret)
+		debug("Warning: No reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_clk_ids[] = {
+	{ .compatible = "aspeed,ast2500-scu" },
+	{ }
+};
+
+U_BOOT_DRIVER(aspeed_ast2500_scu) = {
+	.name		= "aspeed_ast2500_scu",
+	.id		= UCLASS_CLK,
+	.of_match	= ast2500_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
+	.ops		= &ast2500_clk_ops,
+	.bind		= ast2500_clk_bind,
+	.probe		= ast2500_clk_probe,
+};
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
new file mode 100644
index 0000000000..ca58b12943
--- /dev/null
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Core Clocks */
+#define PLL_HPLL	1
+#define PLL_DPLL	2
+#define PLL_D2PLL	3
+#define PLL_MPLL	4
+#define ARMCLK		5
+
+
+/* Bus Clocks, derived from core clocks */
+#define BCLK_PCLK	101
+#define BCLK_LHCLK	102
+#define BCLK_MACCLK	103
+#define BCLK_SDCLK	104
+#define BCLK_ARMCLK	105
+
+#define MCLK_DDR	201
+
+/* Special clocks */
+#define PCLK_UART1	501
+#define PCLK_UART2	502
+#define PCLK_UART3	503
+#define PCLK_UART4	504
+#define PCLK_UART5	505
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
@ 2017-01-10  1:50     ` Maxim Sloyko
  2017-01-11  3:20       ` Tom Rini
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-10  1:50 UTC (permalink / raw)
  To: u-boot

---

Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/mach-aspeed/Makefile        |  2 +-
 arch/arm/mach-aspeed/ast2500-board.c | 78 +++++++++++++++++++++++++++++++++
 include/configs/aspeed-common.h      | 84 ++++++++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 include/configs/aspeed-common.h

diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 1f7af71b03..9d29ff7f6f 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
new file mode 100644
index 0000000000..6ff74f0a1f
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+#include <ram.h>
+#include <timer.h>
+
+/* Second Watchdog Timer by default is configured
+ * to trigger secondary boot source.
+ */
+#define AST_2ND_BOOT_WDT		(1)
+
+/* Third Watchdog Timer by default is configured
+ * to toggle Flash address mode switch before reset.
+ */
+#define AST_FLASH_ADDR_DETECT_WDT	(2)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void lowlevel_init(void)
+{
+	/*
+	 * These two watchdogs need to be stopped as soon as possible,
+	 * otherwise the board might hang. By default they are set to
+	 * a very short timeout and even simple debug write to serial
+	 * console early in the init process might cause them to fire.
+	 */
+	struct ast_wdt *flash_addr_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_FLASH_ADDR_DETECT_WDT);
+
+	clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
+
+#ifndef CONFIG_FIRMWARE_2ND_BOOT
+	struct ast_wdt *sec_boot_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_2ND_BOOT_WDT);
+
+	clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
+#endif
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct udevice *dev;
+	int ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM FAIL1\r\n");
+		return ret;
+	}
+
+	struct ram_info ram;
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("DRAM FAIL2\r\n");
+		return ret;
+	}
+
+
+	gd->ram_size = ram.size;
+	return 0;
+}
diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
new file mode 100644
index 0000000000..c125e39e3f
--- /dev/null
+++ b/include/configs/aspeed-common.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 IBM Corporation
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __AST_COMMON_CONFIG_H
+#define __AST_COMMON_CONFIG_H
+
+/* Misc CPU related */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_CMDLINE_EDITING		1
+
+/* Enable cache controller */
+#define CONFIG_SYS_DCACHE_OFF		1
+
+#ifdef CONFIG_PRE_CON_BUF_SZ
+#define PRE_CON_RAM_SZ		CONFIG_PRE_CON_BUF_SZ
+#else
+#define PRE_CON_RAM_SZ	0
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000 + PRE_CON_RAM_SZ)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024 - PRE_CON_RAM_SZ)
+#define SYS_INIT_RAM_END		(CONFIG_SYS_INIT_RAM_ADDR \
+					 + CONFIG_SYS_INIT_RAM_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(SYS_INIT_RAM_END \
+					 - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE \
+					 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_TEXT_BASE		0x00000000
+
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_SUBNETMASK
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE		256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					 + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+#define CONFIG_BOOTARGS \
+		"console=ttyS4,115200n8" \
+		" root=/dev/ram rw"
+
+#define CONFIG_BOOTCOMMAND		"bootm 20080000 20300000"
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=yes\0"	\
+	"spi_dma=yes\0" \
+	""
+
+#endif	/* __AST_COMMON_CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                       ` (2 preceding siblings ...)
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-10  1:50     ` Maxim Sloyko
  2017-01-11  3:20       ` Tom Rini
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-10  1:50 UTC (permalink / raw)
  To: u-boot

ast2500 Eval Board device tree and board specific configuration.

---

Changes in v2: None
Changes in v1:
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/Makefile                  |  2 ++
 arch/arm/dts/ast2500-evb.dts           | 23 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
 board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
 board/aspeed/evb_ast2500/Makefile      |  1 +
 board/aspeed/evb_ast2500/evb_ast2500.c |  6 ++++++
 configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
 include/configs/evb_ast2500.h          | 30 ++++++++++++++++++++++++++++++
 8 files changed, 102 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 include/configs/evb_ast2500.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f43746966c..1bee50e237 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb
 
+dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
new file mode 100644
index 0000000000..dc13952fb8
--- /dev/null
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "ast2500-u-boot.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&sdrammc {
+	clock-frequency = <400000000>;
+};
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
index c0b448f19e..7397d0c179 100644
--- a/arch/arm/mach-aspeed/ast2500/Kconfig
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -3,4 +3,11 @@ if ASPEED_AST2500
 config SYS_CPU
 	default "arm1176"
 
+config TARGET_EVB_AST2500
+	bool "Evb-AST2500"
+	help
+	  Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
+
+source "board/aspeed/evb_ast2500/Kconfig"
+
 endif
diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
new file mode 100644
index 0000000000..73a8ae85f6
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2500
+
+config SYS_BOARD
+	default "evb_ast2500"
+
+config SYS_VENDOR
+	default "aspeed"
+
+config SYS_CONFIG_NAME
+	default "evb_ast2500"
+
+endif
diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
new file mode 100644
index 0000000000..4564098299
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2500.o
diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
new file mode 100644
index 0000000000..649e3ba27e
--- /dev/null
+++ b/board/aspeed/evb_ast2500/evb_ast2500.c
@@ -0,0 +1,6 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
new file mode 100644
index 0000000000..4598f6f418
--- /dev/null
+++ b/configs/evb-ast2500_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_ASPEED_AST2500=y
+CONFIG_TARGET_EVB_AST2500=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_CLK=y
+CONFIG_TIMER=y
+CONFIG_RAM=y
+CONFIG_REGMAP=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x1e720000
+CONFIG_PRE_CON_BUF_SZ=4096
+CONFIG_SYS_NO_FLASH=y
+CONFIG_CMD_IMLS=n
diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
new file mode 100644
index 0000000000..28d11a2bdf
--- /dev/null
+++ b/include/configs/evb_ast2500.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 Google Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+
+#define CONFIG_SYS_MEMTEST_START	(CONFIG_SYS_SDRAM_BASE + 0x300000)
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x5000000)
+
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/*
+ * Memory Info
+ */
+#define CONFIG_SYS_LOAD_ADDR		0x83000000
+
+#define CONFIG_ENV_IS_NOWHERE		1
+
+#define CONFIG_ENV_SIZE			0x20000
+
+#endif	/* __CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-11  3:20       ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-11  3:20 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 09, 2017 at 05:50:37PM -0800, Maxim Sloyko wrote:

> Add support for Watchdog Timer, which is compatible with AST2400 and
> AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
> does not follow the driver model. It also uses fixed clock, so no clock
> driver is needed.
> 
> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK. The timer uses fixed clock, so does not rely on a clock driver.
> 
> Add sysreset driver, which uses watchdog timer to do resets and particular
> watchdog device to use is hardcoded (0)
> 

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170110/fbf5598d/attachment.sig>

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

* [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
@ 2017-01-11  3:20       ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-11  3:20 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 09, 2017 at 05:50:38PM -0800, Maxim Sloyko wrote:

> Clock Driver
> 
> This driver is ast2500 specific and is not compatible with earlier
> versions of this chip. The differences are not that big, but they are
> in somewhat random places, so making it compatible with ast2400 is not
> worth the effort at the moment.
> 
> SDRAM MC driver
> 
> The driver is very ast2500 specific and is completely incompatible
> with previous versions of the chip.
> 
> The memory controller is very poorly documented by Aspeed in the
> datasheet, with any mention of the whole range of registers missing. The
> initialization procedure has been basically taken from Aspeed SDK, where
> it is implemented in assembly and rewritten in C, with very limited
> understanding of what exacly it is doing.
> 

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170110/e9fe711c/attachment.sig>

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

* [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-11  3:20       ` Tom Rini
  2017-01-11 23:40         ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Tom Rini @ 2017-01-11  3:20 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 09, 2017 at 05:50:39PM -0800, Maxim Sloyko wrote:

[snip]
> +#define CONFIG_CMDLINE_EDITING		1

In general, we just do '#define CONFIG_FOO'.

> +#define CONFIG_SYS_TEXT_BASE		0x00000000

This one at least is in Kconfig now.  Please check for anything else
that has also been migrated, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170110/922ea817/attachment.sig>

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

* [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-11  3:20       ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-11  3:20 UTC (permalink / raw)
  To: u-boot

On Mon, Jan 09, 2017 at 05:50:40PM -0800, Maxim Sloyko wrote:

> ast2500 Eval Board device tree and board specific configuration.
> 

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170110/f7811fb4/attachment.sig>

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

* [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-11  3:20       ` Tom Rini
@ 2017-01-11 23:40         ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:40 UTC (permalink / raw)
  To: u-boot

On Tue, Jan 10, 2017 at 7:20 PM, Tom Rini <trini@konsulko.com> wrote:
> On Mon, Jan 09, 2017 at 05:50:39PM -0800, Maxim Sloyko wrote:
>
> [snip]
>> +#define CONFIG_CMDLINE_EDITING               1
>
> In general, we just do '#define CONFIG_FOO'.

Fixed several defines in aspeed-common.h and evb_ast2500.h

>
>> +#define CONFIG_SYS_TEXT_BASE         0x00000000
>
> This one at least is in Kconfig now.  Please check for anything else
> that has also been migrated, thanks!

This seems to be the only one. Checked by grepping all Kconfigs for
all options in aspeed-common.h, basically by running

for v in $(cat include/configs/aspeed-common.h | awk '/^#define
CONFIG/ { print gensub("CONFIG_", "", 1, $2) }'); do find . -name
Kconfig -exec grep -Hn $v {} \; ; done

The fix still ended up being spread around three patches from this
series, so I'm copying Revewed-by to only one of those that was left
untouched.


>
> --
> Tom



-- 
Maxim Sloyko

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

* [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                       ` (3 preceding siblings ...)
  2017-01-10  1:50     ` [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-11 23:45     ` Maxim Sloyko
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
                         ` (4 more replies)
  4 siblings, 5 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:45 UTC (permalink / raw)
  To: u-boot

This series adds minimal support for AST2500 part and eval board,
enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
Clock (very basic) and SDRAM MC drivers, all written from scratch,
using AST2500 datasheet. Aspeed's SDK was used only for reference.
Given very limited documentation provided by Aspeed, some parts of SDRAM
init sequence were basically rewritten to do the same thing that is done
in Aspeed SDK, without real understanding of what is going on.

The file layout closely follows the example of rk3288 chip and firefly-rk3288
board.

Changes in v3:
- Added SYS_TEXT_BASE as Kconfig option
- Removed CONFIG_SYS_TEXT_BASE in favor of Kconfig option
- In aspeed-common.h changed some options from define CONFIG_FOO 1 to
  define CONFIG_FOO
- In evb_ast2500.h fixed some options to define CONFIG_FOO instead of
  define CONFIG_FOO 1

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Maxim Sloyko (4):
  aspeed: Add drivers common to all Aspeed SoCs
  aspeed: Add basic ast2500 specific drivers and configuration
  aspeed: Board init functions and common configs for ast2500 based
    boards
  aspeed: Support for ast2500 Eval Board

 arch/arm/Kconfig                                 |   7 +
 arch/arm/Makefile                                |   1 +
 arch/arm/dts/Makefile                            |   2 +
 arch/arm/dts/ast2500-evb.dts                     |  23 ++
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/include/asm/arch-aspeed/timer.h         |  54 +++
 arch/arm/include/asm/arch-aspeed/wdt.h           |  89 +++++
 arch/arm/mach-aspeed/Kconfig                     |  27 ++
 arch/arm/mach-aspeed/Makefile                    |   8 +
 arch/arm/mach-aspeed/ast2500-board.c             |  78 ++++
 arch/arm/mach-aspeed/ast2500/Kconfig             |  13 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast_wdt.c                   |  37 ++
 board/aspeed/evb_ast2500/Kconfig                 |  12 +
 board/aspeed/evb_ast2500/Makefile                |   1 +
 board/aspeed/evb_ast2500/evb_ast2500.c           |   6 +
 configs/evb-ast2500_defconfig                    |  21 ++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 drivers/sysreset/Makefile                        |   1 +
 drivers/sysreset/sysreset_ast.c                  |  55 +++
 drivers/timer/Kconfig                            |   7 +
 drivers/timer/Makefile                           |   1 +
 drivers/timer/ast_timer.c                        |  96 +++++
 include/configs/aspeed-common.h                  |  82 +++++
 include/configs/evb_ast2500.h                    |  30 ++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 33 files changed, 1896 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c
 create mode 100644 include/configs/aspeed-common.h
 create mode 100644 include/configs/evb_ast2500.h
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
@ 2017-01-11 23:45       ` Maxim Sloyko
  2017-01-13  0:51         ` Tom Rini
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:45 UTC (permalink / raw)
  To: u-boot

Add support for Watchdog Timer, which is compatible with AST2400 and
AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
does not follow the driver model. It also uses fixed clock, so no clock
driver is needed.

Add support for timer for Aspeed ast2400/ast2500 devices.
The driver actually controls several devices, but because all devices
share the same Control Register, it is somewhat difficult to completely
decouple them. Since only one timer is needed at the moment, this should
be OK. The timer uses fixed clock, so does not rely on a clock driver.

Add sysreset driver, which uses watchdog timer to do resets and particular
watchdog device to use is hardcoded (0)

---

Changes in v3:
- Added SYS_TEXT_BASE as Kconfig option

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/Kconfig                         |  7 +++
 arch/arm/Makefile                        |  1 +
 arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
 arch/arm/include/asm/arch-aspeed/wdt.h   | 89 +++++++++++++++++++++++++++++
 arch/arm/mach-aspeed/Kconfig             | 25 +++++++++
 arch/arm/mach-aspeed/Makefile            |  7 +++
 arch/arm/mach-aspeed/ast_wdt.c           | 37 ++++++++++++
 drivers/sysreset/Makefile                |  1 +
 drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
 drivers/timer/Kconfig                    |  7 +++
 drivers/timer/Makefile                   |  1 +
 drivers/timer/ast_timer.c                | 96 ++++++++++++++++++++++++++++++++
 12 files changed, 380 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 714dd8b514..135c544335 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
 	select OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 
+config ARCH_ASPEED
+	bool "Support Aspeed SoCs"
+	select OF_CONTROL
+	select DM
+
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm283x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 236debb452..cc73e1038e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ASPEED)		+= aspeed
 machine-$(CONFIG_ARCH_AT91)		+= at91
 machine-$(CONFIG_ARCH_BCM283X)		+= bcm283x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
new file mode 100644
index 0000000000..87c5b354ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/timer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_TIMER_H
+#define _ASM_ARCH_TIMER_H
+
+/* Each timer has 4 control bits in ctrl1 register.
+ * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
+ * such that timer X uses bits (4 * X - 4):(4 * X - 1)
+ * If the timer does not support PWM, bit 4 is reserved.
+ */
+#define AST_TMC_EN			(1 << 0)
+#define AST_TMC_1MHZ			(1 << 1)
+#define AST_TMC_OVFINTR			(1 << 2)
+#define AST_TMC_PWM			(1 << 3)
+
+/* Timers are counted from 1 in the datasheet. */
+#define AST_TMC_CTRL1_SHIFT(n)			(4 * ((n) - 1))
+
+#define AST_TMC_RATE  (1000*1000)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All timers share control registers, which makes it harder to make them
+ * separate devices. Since only one timer is needed@the moment, making
+ * it this just one device.
+ */
+
+struct ast_timer_counter {
+	u32 status;
+	u32 reload_val;
+	u32 match1;
+	u32 match2;
+};
+
+struct ast_timer {
+	struct ast_timer_counter timers1[3];
+	u32 ctrl1;
+	u32 ctrl2;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 ctrl3;
+	u32 ctrl1_clr;
+#else
+	u32 reserved[2];
+#endif
+	struct ast_timer_counter timers2[5];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_TIMER_H */
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
new file mode 100644
index 0000000000..32774b1a70
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_WDT_H
+#define _ASM_ARCH_WDT_H
+
+#define WDT_BASE			0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL		0x4755
+
+/* Control register */
+#define WDT_CTRL_RESET_MODE_SHIFT	5
+#define WDT_CTRL_RESET_MODE_MASK	3
+
+#define WDT_CTRL_EN			(1 << 0)
+#define WDT_CTRL_RESET			(1 << 1)
+#define WDT_CTRL_CLK1MHZ		(1 << 4)
+#define WDT_CTRL_2ND_BOOT		(1 << 7)
+
+/* Values for Reset Mode */
+#define WDT_CTRL_RESET_SOC		0
+#define WDT_CTRL_RESET_CHIP		1
+#define WDT_CTRL_RESET_CPU		2
+#define WDT_CTRL_RESET_MASK		3
+
+/* Reset Mask register */
+#define WDT_RESET_ARM			(1 << 0)
+#define WDT_RESET_COPROC		(1 << 1)
+#define WDT_RESET_SDRAM			(1 << 2)
+#define WDT_RESET_AHB			(1 << 3)
+#define WDT_RESET_I2C			(1 << 4)
+#define WDT_RESET_MAC1			(1 << 5)
+#define WDT_RESET_MAC2			(1 << 6)
+#define WDT_RESET_GCRT			(1 << 7)
+#define WDT_RESET_USB20			(1 << 8)
+#define WDT_RESET_USB11_HOST		(1 << 9)
+#define WDT_RESET_USB11_EHCI2		(1 << 10)
+#define WDT_RESET_VIDEO			(1 << 11)
+#define WDT_RESET_HAC			(1 << 12)
+#define WDT_RESET_LPC			(1 << 13)
+#define WDT_RESET_SDSDIO		(1 << 14)
+#define WDT_RESET_MIC			(1 << 15)
+#define WDT_RESET_CRT2C			(1 << 16)
+#define WDT_RESET_PWM			(1 << 17)
+#define WDT_RESET_PECI			(1 << 18)
+#define WDT_RESET_JTAG			(1 << 19)
+#define WDT_RESET_ADC			(1 << 20)
+#define WDT_RESET_GPIO			(1 << 21)
+#define WDT_RESET_MCTP			(1 << 22)
+#define WDT_RESET_XDMA			(1 << 23)
+#define WDT_RESET_SPI			(1 << 24)
+#define WDT_RESET_MISC			(1 << 25)
+
+#ifndef __ASSEMBLY__
+struct ast_wdt {
+	u32 counter_status;
+	u32 counter_reload_val;
+	u32 counter_restart;
+	u32 ctrl;
+	u32 timeout_status;
+	u32 clr_timeout_status;
+	u32 reset_width;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 reset_mask;
+#else
+	u32 reserved0;
+#endif
+};
+
+void wdt_stop(struct ast_wdt *wdt);
+void wdt_start(struct ast_wdt *wdt, u32 timeout);
+
+/**
+ * ast_get_wdt() - get a pointer to watchdog registers
+ *
+ * @wdt_number: 0-based WDT peripheral number
+ * @return pointer to registers or -ve error on error
+ */
+struct ast_wdt *ast_get_wdt(u8 wdt_number);
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000000..404599557a
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,25 @@
+if ARCH_ASPEED
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_SOC
+	default "aspeed"
+
+config SYS_TEXT_BASE
+	default 0x00000000
+
+config ASPEED_AST2500
+	bool "Support Aspeed AST2500 SoC"
+	select CPU_ARM1176
+	help
+	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
+
+config WDT_NUM
+	int "Number of Watchdog Timers"
+	default 3 if ASPEED_AST2500
+	help
+	  The number of Watchdot Timers on a SoC.
+	  AST2500 has three WDTsk earlier versions have two or fewer.
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000000..a14b8f751d
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
new file mode 100644
index 0000000000..7070824318
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <linux/err.h>
+
+void wdt_stop(struct ast_wdt *wdt)
+{
+	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+}
+
+void wdt_start(struct ast_wdt *wdt, u32 timeout)
+{
+	writel(timeout, &wdt->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&wdt->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+}
+
+struct ast_wdt *ast_get_wdt(u8 wdt_number)
+{
+	if (wdt_number > CONFIG_WDT_NUM - 1)
+		return ERR_PTR(-EINVAL);
+
+	return (struct ast_wdt *)(WDT_BASE +
+				  sizeof(struct ast_wdt) * wdt_number);
+}
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index fa75cc52de..37638a8eea 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
new file mode 100644
index 0000000000..a0ab12851d
--- /dev/null
+++ b/drivers/sysreset/sysreset_ast.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+/* Number of Watchdog Timer ticks before reset */
+#define AST_WDT_RESET_TIMEOUT	10
+#define AST_WDT_FOR_RESET	0
+
+static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
+	u32 reset_mode = 0;
+
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		reset_mode = WDT_CTRL_RESET_CPU;
+		break;
+	case SYSRESET_COLD:
+		reset_mode = WDT_CTRL_RESET_CHIP;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	/* Clear reset mode bits */
+	clrsetbits_le32(&wdt->ctrl,
+			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
+			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
+	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops ast_sysreset = {
+	.request	= ast_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_ast) = {
+	.name	= "ast_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &ast_sysreset,
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index cb18f12fc9..9c5f98bb88 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -46,4 +46,11 @@ config OMAP_TIMER
 	help
 	  Select this to enable an timer for Omap devices.
 
+config AST_TIMER
+	bool "Aspeed ast2400/ast2500 timer support"
+	depends on TIMER
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable timer for Aspeed ast2400/ast2500 devices.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index f351fbb4e0..a4b1a486b0 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
new file mode 100644
index 0000000000..be48d24cea
--- /dev/null
+++ b/drivers/timer/ast_timer.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define AST_TICK_TIMER  1
+#define AST_TMC_RELOAD_VAL  0xffffffff
+
+struct ast_timer_priv {
+	struct ast_timer *regs;
+};
+
+static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
+						       int n)
+{
+	if (n > 3)
+		return &timer->timers2[n - 4];
+	else
+		return &timer->timers1[n - 1];
+}
+
+static int ast_timer_probe(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
+
+	/*
+	 * Stop the timer. This will also load reload_val into
+	 * the status register.
+	 */
+	clrbits_le32(&priv->regs->ctrl1,
+		     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+	/* Start the timer from the fixed 1MHz clock. */
+	setbits_le32(&priv->regs->ctrl1,
+		     (AST_TMC_EN | AST_TMC_1MHZ) <<
+		     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+
+	uc_priv->clock_rate = AST_TMC_RATE;
+
+	return 0;
+}
+
+static int ast_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
+							      AST_TICK_TIMER);
+
+	*count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
+
+	return 0;
+}
+
+static int ast_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = (struct ast_timer *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static const struct timer_ops ast_timer_ops = {
+	.get_count = ast_timer_get_count,
+};
+
+static const struct udevice_id ast_timer_ids[] = {
+	{ .compatible = "aspeed,ast2500-timer" },
+	{ .compatible = "aspeed,ast2400-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(ast_timer) = {
+	.name = "ast_timer",
+	.id = UCLASS_TIMER,
+	.of_match = ast_timer_ids,
+	.probe = ast_timer_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_timer_priv),
+	.ofdata_to_platdata = ast_timer_ofdata_to_platdata,
+	.ops = &ast_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v3 2/4] aspeed: Add basic ast2500 specific drivers and configuration
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-11 23:45       ` Maxim Sloyko
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:45 UTC (permalink / raw)
  To: u-boot

Clock Driver

This driver is ast2500 specific and is not compatible with earlier
versions of this chip. The differences are not that big, but they are
in somewhat random places, so making it compatible with ast2400 is not
worth the effort at the moment.

SDRAM MC driver

The driver is very ast2500 specific and is completely incompatible
with previous versions of the chip.

The memory controller is very poorly documented by Aspeed in the
datasheet, with any mention of the whole range of registers missing. The
initialization procedure has been basically taken from Aspeed SDK, where
it is implemented in assembly and rewritten in C, with very limited
understanding of what exacly it is doing.

---

Changes in v3: None
Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi


Reviewed-by: Tom Rini <trini@konsulko.com>

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 113 ++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 +++++++
 arch/arm/mach-aspeed/Kconfig                     |   2 +
 arch/arm/mach-aspeed/Makefile                    |   1 +
 arch/arm/mach-aspeed/ast2500/Kconfig             |   6 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 255 +++++++++++++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 14 files changed, 1254 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
new file mode 100644
index 0000000000..c95a7ba835
--- /dev/null
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -0,0 +1,53 @@
+#include <dt-bindings/clock/ast2500-scu.h>
+
+#include "ast2500.dtsi"
+
+/ {
+	scu: clock-controller at 1e6e2000 {
+		compatible = "aspeed,ast2500-scu";
+		reg = <0x1e6e2000 0x1000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	sdrammc: sdrammc at 1e6e0000 {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-sdrammc";
+		reg = <0x1e6e0000 0x174
+			0x1e6e0200 0x1d4 >;
+		clocks = <&scu PLL_MPLL>;
+	};
+
+	ahb {
+		u-boot,dm-pre-reloc;
+
+		apb {
+			u-boot,dm-pre-reloc;
+
+			timer: timer at 1e782000 {
+				u-boot,dm-pre-reloc;
+			};
+
+			uart1: serial at 1e783000 {
+				clocks = <&scu PCLK_UART1>;
+			};
+
+			uart2: serial at 1e78d000 {
+				clocks = <&scu PCLK_UART2>;
+			};
+
+			uart3: serial at 1e78e000 {
+				clocks = <&scu PCLK_UART3>;
+			};
+
+			uart4: serial at 1e78f000 {
+				clocks = <&scu PCLK_UART4>;
+			};
+
+			uart5: serial at 1e784000 {
+				clocks = <&scu PCLK_UART5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
new file mode 100644
index 0000000000..97fac69d11
--- /dev/null
+++ b/arch/arm/dts/ast2500.dtsi
@@ -0,0 +1,174 @@
+/*
+ * This device tree is copied from
+ * https://raw.githubusercontent.com/torvalds/linux/02440622/arch/arm/boot/dts/
+ */
+#include "skeleton.dtsi"
+
+/ {
+	model = "Aspeed BMC";
+	compatible = "aspeed,ast2500";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&vic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,arm1176jzf-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vic: interrupt-controller at 1e6c0080 {
+			compatible = "aspeed,ast2400-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			valid-sources = <0xfefff7ff 0x0807ffff>;
+			reg = <0x1e6c0080 0x80>;
+		};
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			clk_clkin: clk_clkin at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-clkin-clock";
+				reg = <0x1e6e2070 0x04>;
+			};
+
+			clk_hpll: clk_hpll at 1e6e2024 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-hpll-clock";
+				reg = <0x1e6e2024 0x4>;
+				clocks = <&clk_clkin>;
+			};
+
+			clk_ahb: clk_ahb at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-ahb-clock";
+				reg = <0x1e6e2070 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_apb: clk_apb at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-apb-clock";
+				reg = <0x1e6e2008 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_uart: clk_uart at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,uart-clock";
+				reg = <0x1e6e202c 0x4>;
+			};
+
+			sram at 1e720000 {
+				compatible = "mmio-sram";
+				reg = <0x1e720000 0x9000>;	// 36K
+			};
+
+			timer: timer at 1e782000 {
+				compatible = "aspeed,ast2400-timer";
+				reg = <0x1e782000 0x90>;
+				// The moxart_timer driver registers only one
+				// interrupt and assumes it's for timer 1
+				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16>;
+				clocks = <&clk_apb>;
+			};
+
+			wdt1: wdt at 1e785000 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785000 0x1c>;
+				interrupts = <27>;
+			};
+
+			wdt2: wdt at 1e785020 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785020 0x1c>;
+				interrupts = <27>;
+				status = "disabled";
+			};
+
+			wdt3: wdt at 1e785040 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785074 0x1c>;
+				status = "disabled";
+			};
+
+			uart1: serial at 1e783000 {
+				compatible = "ns16550a";
+				reg = <0x1e783000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <9>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart2: serial at 1e78d000 {
+				compatible = "ns16550a";
+				reg = <0x1e78d000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <32>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart3: serial at 1e78e000 {
+				compatible = "ns16550a";
+				reg = <0x1e78e000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <33>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart4: serial at 1e78f000 {
+				compatible = "ns16550a";
+				reg = <0x1e78f000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <34>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart5: serial at 1e784000 {
+				compatible = "ns16550a";
+				reg = <0x1e784000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				current-speed = <38400>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart6: serial at 1e787000 {
+				compatible = "ns16550a";
+				reg = <0x1e787000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
new file mode 100644
index 0000000000..6c6af68f4f
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SCU_AST2500_H
+#define _ASM_ARCH_SCU_AST2500_H
+
+#define SCU_UNLOCK_VALUE		0x1688a8a8
+
+#define SCU_HWSTRAP_VGAMEM_MASK		3
+#define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_DDR4		(1 << 24)
+#define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
+
+#define SCU_MPLL_DENUM_SHIFT		0
+#define SCU_MPLL_DENUM_MASK		0x1f
+#define SCU_MPLL_NUM_SHIFT		5
+#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_POST_SHIFT		13
+#define SCU_MPLL_POST_MASK		0x3f
+
+#define SCU_HPLL_DENUM_SHIFT		0
+#define SCU_HPLL_DENUM_MASK		0x1f
+#define SCU_HPLL_NUM_SHIFT		5
+#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_POST_SHIFT		13
+#define SCU_HPLL_POST_MASK		0x3f
+
+#define SCU_MISC2_UARTCLK_SHIFT		24
+
+#define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_clk_priv {
+	struct ast2500_scu *scu;
+};
+
+struct ast2500_scu {
+	u32 protection_key;
+	u32 sysreset_ctrl1;
+	u32 clk_sel1;
+	u32 clk_stop_ctrl1;
+	u32 freq_counter_ctrl;
+	u32 freq_counter_cmp;
+	u32 intr_ctrl;
+	u32 d2_pll_param;
+	u32 m_pll_param;
+	u32 h_pll_param;
+	u32 d_pll_param;
+	u32 misc_ctrl1;
+	u32 pci_config[3];
+	u32 sysreset_status;
+	u32 vga_handshake[2];
+	u32 mac_clk_delay;
+	u32 misc_ctrl2;
+	u32 vga_scratch[8];
+	u32 hwstrap;
+	u32 rng_ctrl;
+	u32 rng_data;
+	u32 rev_id;
+	u32 pinmux_ctrl[6];
+	u32 reserved0;
+	u32 extrst_sel;
+	u32 pinmux_ctrl1[4];
+	u32 reserved1[2];
+	u32 mac_clk_delay_100M;
+	u32 mac_clk_delay_10M;
+	u32 wakeup_enable;
+	u32 wakeup_control;
+	u32 reserved2[3];
+	u32 sysreset_ctrl2;
+	u32 clk_sel2;
+	u32 clk_stop_ctrl2;
+	u32 freerun_counter;
+	u32 freerun_counter_ext;
+	u32 clk_duty_meas_ctrl;
+	u32 clk_duty_meas_res;
+	u32 reserved3[4];
+	/* The next registers are not key protected */
+	struct ast2500_cpu2 {
+		u32 ctrl;
+		u32 base_addr[9];
+		u32 cache_ctrl;
+	} cpu2;
+	u32 reserved4;
+	u32 d_pll_ext_param[3];
+	u32 d2_pll_ext_param[3];
+	u32 mh_pll_ext_param;
+	u32 reserved5;
+	u32 chip_id[2];
+	u32 reserved6[2];
+	u32 uart_clk_ctrl;
+	u32 reserved7[7];
+	u32 pcie_config;
+	u32 mmio_decode;
+	u32 reloc_ctrl_decode[2];
+	u32 mailbox_addr;
+	u32 shared_sram_decode[2];
+	u32 bmc_rev_id;
+	u32 reserved8;
+	u32 bmc_device_id;
+	u32 reserved9[13];
+	u32 clk_duty_sel;
+};
+
+int ast_get_clk(struct udevice **devp);
+void *ast_get_scu(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
new file mode 100644
index 0000000000..a5f8615ae2
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_AST2500_H
+#define _ASM_ARCH_SDRAM_AST2500_H
+
+#define SDRAM_UNLOCK_KEY		0xfc600309
+#define SDRAM_VIDEO_UNLOCK_KEY		0x2003000f
+
+#define SDRAM_PCR_CKE_EN		(1 << 0)
+#define SDRAM_PCR_AUTOPWRDN_EN		(1 << 1)
+#define SDRAM_PCR_CKE_DELAY_SHIFT	4
+#define SDRAM_PCR_CKE_DELAY_MASK	7
+#define SDRAM_PCR_RESETN_DIS		(1 << 7)
+#define SDRAM_PCR_ODT_EN		(1 << 8)
+#define SDRAM_PCR_ODT_AUTO_ON		(1 << 10)
+#define SDRAM_PCR_ODT_EXT_EN		(1 << 11)
+#define SDRAM_PCR_TCKE_PW_SHIFT		12
+#define SDRAM_PCR_TCKE_PW_MASK		7
+#define SDRAM_PCR_RGAP_CTRL_EN		(1 << 15)
+#define SDRAM_PCR_MREQI_DIS		(1 << 17)
+
+/* Fixed priority DRAM Requests mask */
+#define SDRAM_REQ_VGA_HW_CURSOR		(1 << 0)
+#define SDRAM_REQ_VGA_TEXT_CG_FONT	(1 << 1)
+#define SDRAM_REQ_VGA_TEXT_ASCII	(1 << 2)
+#define SDRAM_REQ_VGA_CRT		(1 << 3)
+#define SDRAM_REQ_SOC_DC_CURSOR		(1 << 4)
+#define SDRAM_REQ_SOC_DC_OCD		(1 << 5)
+#define SDRAM_REQ_SOC_DC_CRT		(1 << 6)
+#define SDRAM_REQ_VIDEO_HIPRI_WRITE	(1 << 7)
+#define SDRAM_REQ_USB20_EHCI1		(1 << 8)
+#define SDRAM_REQ_USB20_EHCI2		(1 << 9)
+#define SDRAM_REQ_CPU			(1 << 10)
+#define SDRAM_REQ_AHB2			(1 << 11)
+#define SDRAM_REQ_AHB			(1 << 12)
+#define SDRAM_REQ_MAC0			(1 << 13)
+#define SDRAM_REQ_MAC1			(1 << 14)
+#define SDRAM_REQ_PCIE			(1 << 16)
+#define SDRAM_REQ_XDMA			(1 << 17)
+#define SDRAM_REQ_ENCRYPTION		(1 << 18)
+#define SDRAM_REQ_VIDEO_FLAG		(1 << 21)
+#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE	(1 << 28)
+#define SDRAM_REQ_2D_RW			(1 << 29)
+#define SDRAM_REQ_MEMCHECK		(1 << 30)
+
+#define SDRAM_ICR_RESET_ALL		(1 << 31)
+
+#define SDRAM_CONF_CAP_SHIFT		0
+#define SDRAM_CONF_CAP_MASK		3
+#define SDRAM_CONF_DDR4			(1 << 4)
+#define SDRAM_CONF_SCRAMBLE		(1 << 8)
+#define SDRAM_CONF_SCRAMBLE_PAT2	(1 << 9)
+#define SDRAM_CONF_CACHE_EN		(1 << 10)
+#define SDRAM_CONF_CACHE_INIT_EN	(1 << 12)
+#define SDRAM_CONF_DUALX8		(1 << 13)
+#define SDRAM_CONF_CACHE_INIT_DONE	(1 << 19)
+
+#define SDRAM_CONF_CAP_128M		0
+#define SDRAM_CONF_CAP_256M		1
+#define SDRAM_CONF_CAP_512M		2
+#define SDRAM_CONF_CAP_1024M		3
+
+#define SDRAM_MISC_DDR4_TREFRESH	(1 << 3)
+
+#define SDRAM_PHYCTRL0_INIT		(1 << 0)
+#define SDRAM_PHYCTRL0_AUTO_UPDATE	(1 << 1)
+#define SDRAM_PHYCTRL0_NRST		(1 << 2)
+
+#define SDRAM_REFRESH_CYCLES_SHIFT	0
+#define SDRAM_REFRESH_CYCLES_MASK	0xf
+#define SDRAM_REFRESH_ZQCS_EN		(1 << 7)
+#define SDRAM_REFRESH_PERIOD_SHIFT	8
+#define SDRAM_REFRESH_PERIOD_MASK	0xf
+
+#define SDRAM_TEST_LEN_SHIFT		4
+#define SDRAM_TEST_LEN_MASK		0xfffff
+#define SDRAM_TEST_START_ADDR_SHIFT	24
+#define SDRAM_TEST_START_ADDR_MASK	0x3f
+
+#define SDRAM_TEST_EN			(1 << 0)
+#define SDRAM_TEST_MODE_SHIFT		1
+#define SDRAM_TEST_MODE_MASK		3
+#define SDRAM_TEST_MODE_WO		0
+#define SDRAM_TEST_MODE_RB		1
+#define SDRAM_TEST_MODE_RW		2
+#define SDRAM_TEST_GEN_MODE_SHIFT	3
+#define SDRAM_TEST_GEN_MODE_MASK	7
+#define SDRAM_TEST_TWO_MODES		(1 << 6)
+#define SDRAM_TEST_ERRSTOP		(1 << 7)
+#define SDRAM_TEST_DONE			(1 << 12)
+#define SDRAM_TEST_FAIL			(1 << 13)
+
+#define SDRAM_AC_TRFC_SHIFT		0
+#define SDRAM_AC_TRFC_MASK		0xff
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_sdrammc_regs {
+	u32 protection_key;
+	u32 config;
+	u32 gm_protection_key;
+	u32 refresh_timing;
+	u32 ac_timing[3];
+	u32 misc_control;
+	u32 mr46_mode_setting;
+	u32 mr5_mode_setting;
+	u32 mode_setting_control;
+	u32 mr02_mode_setting;
+	u32 mr13_mode_setting;
+	u32 power_control;
+	u32 req_limit_mask;
+	u32 pri_group_setting;
+	u32 max_grant_len[4];
+	u32 intr_ctrl;
+	u32 ecc_range_ctrl;
+	u32 first_ecc_err_addr;
+	u32 last_ecc_err_addr;
+	u32 phy_ctrl[4];
+	u32 ecc_test_ctrl;
+	u32 test_addr;
+	u32 test_fail_dq_bit;
+	u32 test_init_val;
+	u32 phy_debug_ctrl;
+	u32 phy_debug_data;
+	u32 reserved1[30];
+	u32 scu_passwd;
+	u32 reserved2[7];
+	u32 scu_mpll;
+	u32 reserved3[19];
+	u32 scu_hwstrap;
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index 404599557a..d049b64784 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -22,4 +22,6 @@ config WDT_NUM
 	  The number of Watchdot Timers on a SoC.
 	  AST2500 has three WDTsk earlier versions have two or fewer.
 
+source "arch/arm/mach-aspeed/ast2500/Kconfig"
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index a14b8f751d..1f7af71b03 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
new file mode 100644
index 0000000000..c0b448f19e
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -0,0 +1,6 @@
+if ASPEED_AST2500
+
+config SYS_CPU
+	default "arm1176"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
new file mode 100644
index 0000000000..a35b239ef3
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += clk_ast2500.o sdram_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
new file mode 100644
index 0000000000..079909fa64
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/scu_ast2500.h>
+
+int ast_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(aspeed_ast2500_scu), devp);
+}
+
+void *ast_get_scu(void)
+{
+	struct ast2500_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = ast_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->scu;
+}
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
new file mode 100644
index 0000000000..da25756e94
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *
+ * Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:		GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/sdram_ast2500.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <regmap.h>
+
+/* These configuration parameters are taken from Aspeed SDK */
+#define DDR4_MR46_MODE		0x08000000
+#define DDR4_MR5_MODE		0x400
+#define DDR4_MR13_MODE		0x101
+#define DDR4_MR02_MODE		0x410
+#define DDR4_TRFC		0x45457188
+
+#define PHY_CFG_SIZE		15
+
+static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
+static const struct {
+	u32 index[PHY_CFG_SIZE];
+	u32 value[PHY_CFG_SIZE];
+} ddr4_phy_config = {
+	.index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
+	.value = {
+		0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
+		0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
+		0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
+	},
+};
+
+#define SDRAM_MAX_SIZE		(1024 * 1024 * 1024)
+#define SDRAM_MIN_SIZE		(128 * 1024 * 1024)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Bandwidth configuration parameters for different SDRAM requests.
+ * These are hardcoded settings taken from Aspeed SDK.
+ */
+static const u32 ddr_max_grant_params[4] = {
+	0x88448844, 0x24422288, 0x22222222, 0x22222222
+};
+
+/*
+ * These registers are not documented by Aspeed at all.
+ * All writes and reads are taken pretty much as is from SDK.
+ */
+struct ast2500_ddr_phy {
+	u32 phy[117];
+};
+
+struct dram_info {
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct ast2500_sdrammc_regs *regs;
+	struct ast2500_scu *scu;
+	struct ast2500_ddr_phy *phy;
+	ulong clock_rate;
+};
+
+static int ast2500_sdrammc_reset(void)
+{
+	struct ast_wdt *wdt = ast_get_wdt(0);
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	/* Only Reset SDRAM */
+	writel(WDT_RESET_SDRAM, &wdt->reset_mask);
+	clrbits_le32(&wdt->ctrl,
+		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
+	wdt_start(wdt, 1);
+
+	/* Wait for WDT to reset */
+	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+		;
+	wdt_stop(wdt);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
+{
+	writel(0, &phy->phy[2]);
+	writel(0, &phy->phy[6]);
+	writel(0, &phy->phy[8]);
+	writel(0, &phy->phy[10]);
+	writel(0, &phy->phy[12]);
+	writel(0, &phy->phy[42]);
+	writel(0, &phy->phy[44]);
+
+	writel(0x86000000, &phy->phy[16]);
+	writel(0x00008600, &phy->phy[17]);
+	writel(0x80000000, &phy->phy[18]);
+	writel(0x80808080, &phy->phy[19]);
+
+	return 0;
+}
+
+static void ast2500_ddr_phy_init_process(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	writel(0, &regs->phy_ctrl[0]);
+	writel(0x4040, &info->phy->phy[51]);
+
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
+	while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
+		;
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
+	       &regs->phy_ctrl[0]);
+}
+
+static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
+{
+	writel(0, &info->regs->phy_ctrl[0]);
+	writel((vref << 8) | 0x6, &info->phy->phy[48]);
+	ast2500_ddr_phy_init_process(info);
+}
+
+static int ast2500_ddr_cbr_test(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	int i;
+	const u32 test_params = SDRAM_TEST_EN
+			| SDRAM_TEST_ERRSTOP
+			| SDRAM_TEST_TWO_MODES;
+	int ret = 0;
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
+	       (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
+	writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
+	writel(0xff00ff00, &regs->test_init_val);
+	writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
+	       SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
+
+	while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+		;
+
+	if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+		ret = -EIO;
+	} else {
+		for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
+			writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
+			       &regs->ecc_test_ctrl);
+			while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+				;
+			if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+				ret = -EIO;
+				break;
+			}
+		}
+	}
+
+	writel(0, &regs->refresh_timing);
+	writel(0, &regs->ecc_test_ctrl);
+	return ret;
+}
+
+static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
+{
+	int i;
+	int vref_min = 0xff;
+	int vref_max = 0;
+	int range_size = 0;
+
+	for (i = 1; i < 0x40; ++i) {
+		ast2500_sdrammc_set_vref(info, i);
+
+		int res = ast2500_ddr_cbr_test(info);
+		if (res < 0) {
+			if (range_size > 0)
+				break;
+		} else {
+			++range_size;
+			vref_min = min(vref_min, i);
+			vref_max = max(vref_max, i);
+		}
+	}
+
+	/* Pick average setting */
+	ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
+
+	return 0;
+}
+
+static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
+{
+	size_t vga_mem_size_base = 8 * 1024 * 1024;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap)
+			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
+			& SCU_HWSTRAP_VGAMEM_MASK;
+
+	return vga_mem_size_base << vga_hwconf;
+}
+
+/*
+ * Find out RAM size and save it in dram_info
+ *
+ * The procedure is taken from Aspeed SDK
+ */
+static void ast2500_sdrammc_calc_size(struct dram_info *info)
+{
+	/* The controller supports 128/256/512/1024 MB ram */
+	size_t ram_size = SDRAM_MIN_SIZE;
+	const int write_test_offset = 0x100000;
+	u32 test_pattern = 0xdeadbeef;
+	u32 cap_param = SDRAM_CONF_CAP_1024M;
+	u32 refresh_timing_param = DDR4_TRFC;
+	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
+
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		writel(test_pattern, write_addr_base + (ram_size >> 1));
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	/* One last write to overwrite all wrapped values */
+	writel(test_pattern, write_addr_base);
+
+	/* Reset the pattern and see which value was really written */
+	test_pattern = 0xdeadbeef;
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
+			break;
+
+		--cap_param;
+		refresh_timing_param >>= 8;
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	clrsetbits_le32(&info->regs->ac_timing[1],
+			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
+			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
+			 << SDRAM_AC_TRFC_SHIFT));
+
+	info->info.base = CONFIG_SYS_SDRAM_BASE;
+	info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
+	clrsetbits_le32(&info->regs->config,
+			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
+			((cap_param & SDRAM_CONF_CAP_MASK)
+			 << SDRAM_CONF_CAP_SHIFT));
+}
+
+static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
+{
+	int i;
+	const u32 power_control = SDRAM_PCR_CKE_EN
+	    | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
+	    | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
+	    | SDRAM_PCR_RESETN_DIS
+	    | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
+	const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
+#ifdef CONFIG_DUALX8_RAM
+	    | SDRAM_CONF_DUALX8
+#endif
+	    | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
+
+	writel(conf, &info->regs->config);
+	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
+		writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
+
+	writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
+	writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
+	writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
+	writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
+
+	for (i = 0; i < PHY_CFG_SIZE; ++i) {
+		writel(ddr4_phy_config.value[i],
+		       &info->phy->phy[ddr4_phy_config.index[i]]);
+	}
+
+	writel(power_control, &info->regs->power_control);
+
+	ast2500_ddr_phy_init_process(info);
+
+	int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
+	if (ret < 0) {
+		debug("Vref calibration failed!\n");
+		return ret;
+	}
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
+	       | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
+	       &info->regs->refresh_timing);
+
+	setbits_le32(&info->regs->power_control,
+		     SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
+
+	ast2500_sdrammc_calc_size(info);
+
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
+	while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
+		;
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
+
+	writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
+
+	/* Enable all requests except video & display */
+	writel(SDRAM_REQ_USB20_EHCI1
+	       | SDRAM_REQ_USB20_EHCI2
+	       | SDRAM_REQ_CPU
+	       | SDRAM_REQ_AHB2
+	       | SDRAM_REQ_AHB
+	       | SDRAM_REQ_MAC0
+	       | SDRAM_REQ_MAC1
+	       | SDRAM_REQ_PCIE
+	       | SDRAM_REQ_XDMA
+	       | SDRAM_REQ_ENCRYPTION
+	       | SDRAM_REQ_VIDEO_FLAG
+	       | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
+	       | SDRAM_REQ_2D_RW
+	       | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
+
+	return 0;
+}
+
+static void ast2500_sdrammc_unlock(struct dram_info *info)
+{
+	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (!readl(&info->regs->protection_key))
+		;
+}
+
+static void ast2500_sdrammc_lock(struct dram_info *info)
+{
+	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (readl(&info->regs->protection_key))
+		;
+}
+
+static int ast2500_sdrammc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
+	struct ast2500_sdrammc_regs *regs = priv->regs;
+	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+	int i;
+
+	if (ret) {
+		debug("DDR:No CLK\n");
+		return ret;
+	}
+
+	priv->scu = ast_get_scu();
+	if (IS_ERR(priv->scu))
+		return PTR_ERR(priv->scu);
+
+	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
+	ret = ast2500_sdrammc_reset();
+	if (ret)
+		return ret;
+
+	ast2500_sdrammc_unlock(priv);
+
+	writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
+	       &regs->power_control);
+	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
+
+	/* Mask all requests except CPU and AHB during PHY init */
+	writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
+
+	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
+		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
+
+	setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+
+	ast2500_sdrammc_init_phy(priv->phy);
+	if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
+		ast2500_sdrammc_init_ddr4(priv);
+	} else {
+		debug("Unsupported DRAM3\n");
+		return -EINVAL;
+	}
+
+	clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+	ast2500_sdrammc_lock(priv);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret = regmap_init_mem(dev, &map);
+
+	if (ret)
+		return ret;
+
+	priv->regs = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "clock-frequency", 0);
+
+	if (!priv->clock_rate) {
+		debug("DDR Clock Rate not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops ast2500_sdrammc_ops = {
+	.get_info = ast2500_sdrammc_get_info,
+};
+
+static const struct udevice_id ast2500_sdrammc_ids[] = {
+	{ .compatible = "aspeed,ast2500-sdrammc" },
+	{ }
+};
+
+U_BOOT_DRIVER(sdrammc_ast2500) = {
+	.name = "aspeed_ast2500_sdrammc",
+	.id = UCLASS_RAM,
+	.of_match = ast2500_sdrammc_ids,
+	.ops = &ast2500_sdrammc_ops,
+	.ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
+	.probe = ast2500_sdrammc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 40a5e8cae8..625513789c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
new file mode 100644
index 0000000000..65d1cd6e29
--- /dev/null
+++ b/drivers/clk/aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
new file mode 100644
index 0000000000..c888a6d35b
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ */
+
+/*
+ * Get the rate of the M-PLL clock from input clock frequency and
+ * the value of the M-PLL Parameter Register.
+ */
+static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
+{
+	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
+	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
+			& SCU_MPLL_DENUM_MASK;
+	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
+			& SCU_MPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+/*
+ * Get the rate of the H-PLL clock from input clock frequency and
+ * the value of the H-PLL Parameter Register.
+ */
+static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
+{
+	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
+	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
+			& SCU_HPLL_DENUM_MASK;
+	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
+			& SCU_HPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+static ulong ast2500_get_clkin(struct ast2500_scu *scu)
+{
+	return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
+			? 25*1000*1000 : 24*1000*1000;
+}
+
+static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart)
+{
+	/*
+	 * ast2500 datasheet is very confusing when it comes to UART clocks,
+	 * especially when CLKIN = 25 MHz. The settings are in
+	 * different registers and it is unclear how they interact.
+	 *
+	 * This has only been tested with default settings and CLKIN = 24 MHz.
+	 */
+	ulong uart_clkin;
+
+	if (readl(&scu->misc_ctrl2) & (1 << (uart + SCU_MISC2_UARTCLK_SHIFT)))
+		uart_clkin = 192 * 1000 * 1000;
+	else
+		uart_clkin = 24 * 1000 * 1000;
+
+	if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
+		uart_clkin /= 13;
+
+	return uart_clkin;
+}
+
+static ulong ast2500_clk_get_rate(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong clkin = ast2500_get_clkin(priv->scu);
+	ulong rate;
+
+	switch (clk->id) {
+	case PLL_HPLL:
+	case ARMCLK:
+		/*
+		 * This ignores dynamic/static slowdown of ARMCLK and may
+		 * be inaccurate.
+		 */
+		rate = ast2500_get_hpll_rate(clkin,
+					     readl(&priv->scu->h_pll_param));
+		break;
+	case MCLK_DDR:
+		rate = ast2500_get_mpll_rate(clkin,
+					     readl(&priv->scu->m_pll_param));
+		break;
+	case PCLK_UART1:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
+		break;
+	case PCLK_UART2:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 2);
+		break;
+	case PCLK_UART3:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 3);
+		break;
+	case PCLK_UART4:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 4);
+		break;
+	case PCLK_UART5:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 5);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static void ast2500_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+static void ast2500_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
+
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+
+	/*
+	 * There are not that many combinations of numerator, denumerator
+	 * and post divider, so just brute force the best combination.
+	 * However, to avoid overflow when multiplying, use kHz.
+	 */
+	const ulong clkin_khz = clkin / 1000;
+	const ulong rate_khz = rate / 1000;
+
+	ulong best_num = 0;
+	ulong best_denum = 0;
+	ulong best_post = 0;
+	ulong delta = rate;
+
+	ulong num, denum, post;
+	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
+		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
+			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
+			ulong new_rate_khz = (clkin_khz
+					      * ((num + 1) / (denum + 1)))
+					     / (post + 1);
+
+			/* Keep the rate below requested one. */
+			if (new_rate_khz > rate_khz)
+				continue;
+
+			if (new_rate_khz - rate_khz < delta) {
+				delta = new_rate_khz - rate_khz;
+
+				best_num = num;
+				best_denum = denum;
+				best_post = post;
+
+				if (delta == 0)
+					goto rate_calc_done;
+			}
+		}
+	}
+
+ rate_calc_done:
+
+	mpll_reg = readl(&scu->m_pll_param);
+	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
+		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
+		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
+	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
+	    | (best_num << SCU_MPLL_NUM_SHIFT)
+	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+
+	ast2500_scu_unlock(scu);
+	writel(mpll_reg, &scu->m_pll_param);
+	ast2500_scu_lock(scu);
+
+	return ast2500_get_mpll_rate(clkin, mpll_reg);
+}
+
+static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong new_rate;
+	switch (clk->id) {
+	case PLL_MPLL:
+	case MCLK_DDR:
+		new_rate = ast2500_configure_ddr(priv->scu, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+struct clk_ops ast2500_clk_ops = {
+	.get_rate = ast2500_clk_get_rate,
+	.set_rate = ast2500_clk_set_rate,
+};
+
+static int ast2500_clk_probe(struct udevice *dev)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(dev);
+	priv->scu = (struct ast2500_scu *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static int ast2500_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+	if (ret)
+		debug("Warning: No reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_clk_ids[] = {
+	{ .compatible = "aspeed,ast2500-scu" },
+	{ }
+};
+
+U_BOOT_DRIVER(aspeed_ast2500_scu) = {
+	.name		= "aspeed_ast2500_scu",
+	.id		= UCLASS_CLK,
+	.of_match	= ast2500_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
+	.ops		= &ast2500_clk_ops,
+	.bind		= ast2500_clk_bind,
+	.probe		= ast2500_clk_probe,
+};
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
new file mode 100644
index 0000000000..ca58b12943
--- /dev/null
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Core Clocks */
+#define PLL_HPLL	1
+#define PLL_DPLL	2
+#define PLL_D2PLL	3
+#define PLL_MPLL	4
+#define ARMCLK		5
+
+
+/* Bus Clocks, derived from core clocks */
+#define BCLK_PCLK	101
+#define BCLK_LHCLK	102
+#define BCLK_MACCLK	103
+#define BCLK_SDCLK	104
+#define BCLK_ARMCLK	105
+
+#define MCLK_DDR	201
+
+/* Special clocks */
+#define PCLK_UART1	501
+#define PCLK_UART2	502
+#define PCLK_UART3	503
+#define PCLK_UART4	504
+#define PCLK_UART5	505
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
@ 2017-01-11 23:45       ` Maxim Sloyko
  2017-01-13  0:51         ` Tom Rini
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:45 UTC (permalink / raw)
  To: u-boot

---

Changes in v3:
- Removed CONFIG_SYS_TEXT_BASE in favor of Kconfig option
- In aspeed-common.h changed some options from define CONFIG_FOO 1 to
  define CONFIG_FOO

Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/mach-aspeed/Makefile        |  2 +-
 arch/arm/mach-aspeed/ast2500-board.c | 78 ++++++++++++++++++++++++++++++++++
 include/configs/aspeed-common.h      | 82 ++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 include/configs/aspeed-common.h

diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 1f7af71b03..9d29ff7f6f 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
new file mode 100644
index 0000000000..6ff74f0a1f
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/wdt.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+#include <ram.h>
+#include <timer.h>
+
+/* Second Watchdog Timer by default is configured
+ * to trigger secondary boot source.
+ */
+#define AST_2ND_BOOT_WDT		(1)
+
+/* Third Watchdog Timer by default is configured
+ * to toggle Flash address mode switch before reset.
+ */
+#define AST_FLASH_ADDR_DETECT_WDT	(2)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void lowlevel_init(void)
+{
+	/*
+	 * These two watchdogs need to be stopped as soon as possible,
+	 * otherwise the board might hang. By default they are set to
+	 * a very short timeout and even simple debug write to serial
+	 * console early in the init process might cause them to fire.
+	 */
+	struct ast_wdt *flash_addr_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_FLASH_ADDR_DETECT_WDT);
+
+	clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
+
+#ifndef CONFIG_FIRMWARE_2ND_BOOT
+	struct ast_wdt *sec_boot_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_2ND_BOOT_WDT);
+
+	clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
+#endif
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct udevice *dev;
+	int ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM FAIL1\r\n");
+		return ret;
+	}
+
+	struct ram_info ram;
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("DRAM FAIL2\r\n");
+		return ret;
+	}
+
+
+	gd->ram_size = ram.size;
+	return 0;
+}
diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
new file mode 100644
index 0000000000..3243e1d2d1
--- /dev/null
+++ b/include/configs/aspeed-common.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 IBM Corporation
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __AST_COMMON_CONFIG_H
+#define __AST_COMMON_CONFIG_H
+
+/* Misc CPU related */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_CMDLINE_EDITING
+
+/* Enable cache controller */
+#define CONFIG_SYS_DCACHE_OFF
+
+#ifdef CONFIG_PRE_CON_BUF_SZ
+#define PRE_CON_RAM_SZ		CONFIG_PRE_CON_BUF_SZ
+#else
+#define PRE_CON_RAM_SZ	0
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000 + PRE_CON_RAM_SZ)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024 - PRE_CON_RAM_SZ)
+#define SYS_INIT_RAM_END		(CONFIG_SYS_INIT_RAM_ADDR \
+					 + CONFIG_SYS_INIT_RAM_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(SYS_INIT_RAM_END \
+					 - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE \
+					 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_SUBNETMASK
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE		256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					 + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+#define CONFIG_BOOTARGS \
+		"console=ttyS4,115200n8" \
+		" root=/dev/ram rw"
+
+#define CONFIG_BOOTCOMMAND		"bootm 20080000 20300000"
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=yes\0"	\
+	"spi_dma=yes\0" \
+	""
+
+#endif	/* __AST_COMMON_CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                         ` (2 preceding siblings ...)
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-11 23:45       ` Maxim Sloyko
  2017-01-13  0:51         ` Tom Rini
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  4 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-11 23:45 UTC (permalink / raw)
  To: u-boot

ast2500 Eval Board device tree and board specific configuration.

---

Changes in v3:
- In evb_ast2500.h fixed some options to define CONFIG_FOO instead of
  define CONFIG_FOO 1

Changes in v2: None
Changes in v1:
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/Makefile                  |  2 ++
 arch/arm/dts/ast2500-evb.dts           | 23 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
 board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
 board/aspeed/evb_ast2500/Makefile      |  1 +
 board/aspeed/evb_ast2500/evb_ast2500.c |  6 ++++++
 configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
 include/configs/evb_ast2500.h          | 30 ++++++++++++++++++++++++++++++
 8 files changed, 102 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 include/configs/evb_ast2500.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f43746966c..1bee50e237 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb
 
+dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
new file mode 100644
index 0000000000..dc13952fb8
--- /dev/null
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "ast2500-u-boot.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&sdrammc {
+	clock-frequency = <400000000>;
+};
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
index c0b448f19e..7397d0c179 100644
--- a/arch/arm/mach-aspeed/ast2500/Kconfig
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -3,4 +3,11 @@ if ASPEED_AST2500
 config SYS_CPU
 	default "arm1176"
 
+config TARGET_EVB_AST2500
+	bool "Evb-AST2500"
+	help
+	  Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
+
+source "board/aspeed/evb_ast2500/Kconfig"
+
 endif
diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
new file mode 100644
index 0000000000..73a8ae85f6
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2500
+
+config SYS_BOARD
+	default "evb_ast2500"
+
+config SYS_VENDOR
+	default "aspeed"
+
+config SYS_CONFIG_NAME
+	default "evb_ast2500"
+
+endif
diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
new file mode 100644
index 0000000000..4564098299
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2500.o
diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
new file mode 100644
index 0000000000..649e3ba27e
--- /dev/null
+++ b/board/aspeed/evb_ast2500/evb_ast2500.c
@@ -0,0 +1,6 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
new file mode 100644
index 0000000000..4598f6f418
--- /dev/null
+++ b/configs/evb-ast2500_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_ASPEED_AST2500=y
+CONFIG_TARGET_EVB_AST2500=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_CLK=y
+CONFIG_TIMER=y
+CONFIG_RAM=y
+CONFIG_REGMAP=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x1e720000
+CONFIG_PRE_CON_BUF_SZ=4096
+CONFIG_SYS_NO_FLASH=y
+CONFIG_CMD_IMLS=n
diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
new file mode 100644
index 0000000000..699271c170
--- /dev/null
+++ b/include/configs/evb_ast2500.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 Google Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+
+#define CONFIG_SYS_MEMTEST_START	(CONFIG_SYS_SDRAM_BASE + 0x300000)
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x5000000)
+
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/*
+ * Memory Info
+ */
+#define CONFIG_SYS_LOAD_ADDR		0x83000000
+
+#define CONFIG_ENV_IS_NOWHERE
+
+#define CONFIG_ENV_SIZE			0x20000
+
+#endif	/* __CONFIG_H */
-- 
2.11.0.390.gc69c2f50cf-goog

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

* [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-13  0:51         ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-13  0:51 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 11, 2017 at 03:45:10PM -0800, Maxim Sloyko wrote:

> Add support for Watchdog Timer, which is compatible with AST2400 and
> AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
> does not follow the driver model. It also uses fixed clock, so no clock
> driver is needed.
> 
> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK. The timer uses fixed clock, so does not rely on a clock driver.
> 
> Add sysreset driver, which uses watchdog timer to do resets and particular
> watchdog device to use is hardcoded (0)
> 

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170112/b5c9257b/attachment.sig>

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

* [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-13  0:51         ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-13  0:51 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 11, 2017 at 03:45:12PM -0800, Maxim Sloyko wrote:


Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170112/c9bca66d/attachment.sig>

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

* [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-13  0:51         ` Tom Rini
  0 siblings, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-13  0:51 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 11, 2017 at 03:45:13PM -0800, Maxim Sloyko wrote:

> ast2500 Eval Board device tree and board specific configuration.
> 

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170112/9eeb22c2/attachment.sig>

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

* [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig
  2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
  2017-01-04 19:58   ` Rick Altherr
@ 2017-01-14 17:13   ` Simon Glass
  2017-01-18  0:15     ` Maxim Sloyko
  1 sibling, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:13 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/Kconfig              |  7 +++++++
>  arch/arm/Makefile             |  1 +
>  arch/arm/mach-aspeed/Kconfig  | 15 +++++++++++++++
>  arch/arm/mach-aspeed/Makefile |  8 ++++++++
>  4 files changed, 31 insertions(+)
>  create mode 100644 arch/arm/mach-aspeed/Kconfig
>  create mode 100644 arch/arm/mach-aspeed/Makefile
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 714dd8b514..135c544335 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
>         select OF_CONTROL
>         select SYS_CACHE_SHIFT_7
>
> +config ARCH_ASPEED
> +       bool "Support Aspeed SoCs"
> +       select OF_CONTROL
> +       select DM
> +
>  endchoice
>
> +source "arch/arm/mach-aspeed/Kconfig"
> +
>  source "arch/arm/mach-at91/Kconfig"
>
>  source "arch/arm/mach-bcm283x/Kconfig"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 236debb452..cc73e1038e 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
>
>  # Machine directory name.  This list is sorted alphanumerically
>  # by CONFIG_* macro name.
> +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
>  machine-$(CONFIG_ARCH_AT91)            += at91
>  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
>  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> new file mode 100644
> index 0000000000..43cdbeda84
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Kconfig
> @@ -0,0 +1,15 @@
> +if ARCH_ASPEED
> +
> +config SYS_ARCH
> +       default "arm"
> +
> +config SYS_SOC
> +       default "aspeed"
> +
> +config ASPEED_AST2500
> +       bool "Support Aspeed AST2500 SoC"
> +       select CPU_ARM1176
> +       help
> +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU

Can you please expand this a bit? E.g. a summary of peripherals it
has, what the chip is used for...

> +
> +endif
> diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
> new file mode 100644
> index 0000000000..8e276b4a9f
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Makefile
> @@ -0,0 +1,8 @@
> +#
> +# Copyright (c) 2014 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer
  2017-01-04 19:46 ` [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer Maxim Sloyko
  2017-01-04 20:58   ` Tom Rini
@ 2017-01-14 17:13   ` Simon Glass
  1 sibling, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:13 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> The driver is compatible with AST2400 and AST2500 watchdogs.
> There is no uclass for Watchdog yet, so the driver does not follow
> the driver model. It also uses fixed clock, so no clock driver
> is needed.
>
> # Conflicts:
> #       arch/arm/mach-aspeed/Makefile
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/include/asm/arch-aspeed/wdt.h | 89 ++++++++++++++++++++++++++++++++++
>  arch/arm/mach-aspeed/Makefile          |  3 +-
>  arch/arm/mach-aspeed/ast_wdt.c         | 44 +++++++++++++++++
>  3 files changed, 134 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
>  create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
>
> diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
> new file mode 100644
> index 0000000000..32774b1a70
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/wdt.h
> @@ -0,0 +1,89 @@
> +/*
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef _ASM_ARCH_WDT_H
> +#define _ASM_ARCH_WDT_H
> +
> +#define WDT_BASE                       0x1e785000

This should come from DT. I suggest creating a simple uclass for the
watchdog timer, so you can make this a proper driver-model driver.

Regards,
Simon

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-04 19:46 ` [U-Boot] [PATCH 03/12] aspeed: Add Timer Support Maxim Sloyko
  2017-01-04 20:58   ` Tom Rini
@ 2017-01-14 17:13   ` Simon Glass
  2017-01-17 17:57     ` Maxim Sloyko
  2017-01-17 23:59     ` Maxim Sloyko
  1 sibling, 2 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:13 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK.
>
> The timer uses fixed clock, so does not rely on a clock driver.
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
>  drivers/timer/Kconfig                    |  7 +++
>  drivers/timer/Makefile                   |  1 +
>  drivers/timer/ast_timer.c                | 96 ++++++++++++++++++++++++++++++++
>  4 files changed, 158 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
>  create mode 100644 drivers/timer/ast_timer.c

Reviewed-by: Simon Glass <sjg@chromium.org>

nits below.

>
> diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
> new file mode 100644
> index 0000000000..87c5b354ec
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/timer.h
> @@ -0,0 +1,54 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +#ifndef _ASM_ARCH_TIMER_H
> +#define _ASM_ARCH_TIMER_H
> +
> +/* Each timer has 4 control bits in ctrl1 register.
> + * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
> + * such that timer X uses bits (4 * X - 4):(4 * X - 1)
> + * If the timer does not support PWM, bit 4 is reserved.
> + */
> +#define AST_TMC_EN                     (1 << 0)
> +#define AST_TMC_1MHZ                   (1 << 1)
> +#define AST_TMC_OVFINTR                        (1 << 2)
> +#define AST_TMC_PWM                    (1 << 3)
> +
> +/* Timers are counted from 1 in the datasheet. */
> +#define AST_TMC_CTRL1_SHIFT(n)                 (4 * ((n) - 1))
> +
> +#define AST_TMC_RATE  (1000*1000)
> +
> +#ifndef __ASSEMBLY__
> +
> +/*
> + * All timers share control registers, which makes it harder to make them
> + * separate devices. Since only one timer is needed at the moment, making
> + * it this just one device.
> + */
> +
> +struct ast_timer_counter {
> +       u32 status;
> +       u32 reload_val;
> +       u32 match1;
> +       u32 match2;
> +};
> +
> +struct ast_timer {
> +       struct ast_timer_counter timers1[3];
> +       u32 ctrl1;
> +       u32 ctrl2;
> +#ifdef CONFIG_ASPEED_AST2500
> +       u32 ctrl3;
> +       u32 ctrl1_clr;
> +#else
> +       u32 reserved[2];
> +#endif
> +       struct ast_timer_counter timers2[5];
> +};
> +
> +#endif  /* __ASSEMBLY__ */
> +
> +#endif  /* _ASM_ARCH_TIMER_H */
> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> index cb18f12fc9..9c5f98bb88 100644
> --- a/drivers/timer/Kconfig
> +++ b/drivers/timer/Kconfig
> @@ -46,4 +46,11 @@ config OMAP_TIMER
>         help
>           Select this to enable an timer for Omap devices.
>
> +config AST_TIMER
> +       bool "Aspeed ast2400/ast2500 timer support"
> +       depends on TIMER
> +       default y if ARCH_ASPEED
> +       help
> +         Select this to enable timer for Aspeed ast2400/ast2500 devices.

Can you add more detail? How many channels? What features are
supported by the driver?

> +
>  endmenu
> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> index f351fbb4e0..a4b1a486b0 100644
> --- a/drivers/timer/Makefile
> +++ b/drivers/timer/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)      += altera_timer.o
>  obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
>  obj-$(CONFIG_X86_TSC_TIMER)    += tsc_timer.o
>  obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
> +obj-$(CONFIG_AST_TIMER)        += ast_timer.o
> diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
> new file mode 100644
> index 0000000000..f644882f40
> --- /dev/null
> +++ b/drivers/timer/ast_timer.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright 2016 Google Inc.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <timer.h>
> +#include <asm/io.h>
> +#include <asm/arch/timer.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define AST_TICK_TIMER  1
> +#define AST_TMC_RELOAD_VAL  0xffffffff
> +
> +struct ast_timer_priv {
> +       struct ast_timer *regs;
> +};
> +
> +static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
> +                                                      int n)
> +{
> +       if (n > 3)
> +               return &timer->timers2[n - 4];
> +       else
> +               return &timer->timers1[n - 1];
> +}
> +
> +static int ast_timer_probe(struct udevice *dev)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
> +                                                             AST_TICK_TIMER);

I suppose tmc could be in your struct ast_timer_priv to save you doing
this each time?

> +       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> +
> +       writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
> +
> +       /*
> +        * Stop the timer. This will also load reload_val into
> +        * the status register.
> +        */
> +       clrbits_le32(&priv->regs->ctrl1,
> +                    AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> +       /* Start the timer from the fixed 1MHz clock. */
> +       setbits_le32(&priv->regs->ctrl1,
> +                    (AST_TMC_EN | AST_TMC_1MHZ) <<
> +                    AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> +
> +       uc_priv->clock_rate = AST_TMC_RATE;
> +
> +       return 0;
> +}
> +
> +static int ast_timer_get_count(struct udevice *dev, u64 *count)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->regs,
> +                                                             AST_TICK_TIMER);
> +
> +       *count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
> +
> +       return 0;
> +}
> +
> +static int ast_timer_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +
> +       priv->regs = (struct ast_timer *)dev_get_addr(dev);

You can use dev_get_addr_ptr() if you like.

> +
> +       return 0;
> +}
> +
> +static const struct timer_ops ast_timer_ops = {
> +       .get_count = ast_timer_get_count,
> +};
> +
> +static const struct udevice_id ast_timer_ids[] = {
> +       { .compatible = "aspeed,ast2500-timer" },
> +       { .compatible = "aspeed,ast2400-timer" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(sandbox_timer) = {

s/sandbox/ast/ or something, as Tom, mentioned.

> +       .name = "ast_timer",
> +       .id = UCLASS_TIMER,
> +       .of_match = ast_timer_ids,
> +       .probe = ast_timer_probe,
> +       .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
> +       .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
> +       .ops = &ast_timer_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> --
> 2.11.0.390.gc69c2f50cf-goog

Regards,
Simon

>

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-05 22:20         ` Maxim Sloyko
@ 2017-01-14 17:13           ` Simon Glass
  2017-01-17 23:27             ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:13 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 5 January 2017 at 15:20, Maxim Sloyko <maxims@google.com> wrote:
> On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
>> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
>>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
>>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
>>> >
>>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
>>> >> ---
>>> >>
>>> >>  arch/arm/dts/ast2500.dtsi               | 423 ++++++++++++++++++++++++++++++++
>>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>>> >>  2 files changed, 452 insertions(+)
>>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
>>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>>> >>
>>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
>>> >> new file mode 100644
>>> >> index 0000000000..1a2a3f7ee3
>>> >> --- /dev/null
>>> >> +++ b/arch/arm/dts/ast2500.dtsi
>>> >> @@ -0,0 +1,423 @@
>>> >> +/* This device tree is copied from
>>> >> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
>>> >
>>> > Is this also found in the Linux kernel or not yet?  Thanks!
>>>
>>> Yes, this is also in in main Linux kernel now, as I've found out, but
>>> actually there is a number of differences, most notably there is no
>>> pin configuration in this device tree, because there is no pinctrl
>>> driver.
>
> Actually, I take that back, I was looking at the wrong linux Linux
> kernel tree still... Only basic version of device tree has made it to
> mainline kernel, but it's enough at the moment, so I used that
> instead.
>
>>>
>>> Should I remove this reference or modify it?
>>
>> Ideally, we will take the kernel dts files and then add what we need on
>> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
>> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
>> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
>
> OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
> added modifications in ast2500-u-boot.dtsi and now include
> ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
> you.

There is some magic in the Makefile which automatically includes the
.dtsi if you name it correctly:

# Try these files in order to find the U-Boot-specific .dtsi include file
u_boot_dtsi_options = $(wildcard $(dts_dir)/$(basename $(notdir
$<))-u-boot.dtsi) \
$(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_SOC))-u-boot.dtsi) \
$(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_CPU))-u-boot.dtsi) \
$(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_VENDOR))-u-boot.dtsi) \
$(wildcard $(dts_dir)/u-boot.dtsi)


So you should not need to include it explicitly.

Regards,
Simon

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

* [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver
  2017-01-04 19:46 ` [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  0 siblings, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> The driver uses watchdog timer to do resets and particular
> watchdog device to use is hardcoded (0)
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  drivers/sysreset/Makefile       |  1 +
>  drivers/sysreset/sysreset_ast.c | 55 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 56 insertions(+)
>  create mode 100644 drivers/sysreset/sysreset_ast.c

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver
  2017-01-04 19:46 ` [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 23:18     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> This driver is ast2500 specific and is not compatible with earlier

ast2500-specific

> versions of this chip. The differences are not that large, but they are
> in somewhat random places, so making it compatible with ast2400 is not
> worth the effort at the moment.
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 108 +++++++++++
>  drivers/clk/Makefile                           |   2 +
>  drivers/clk/aspeed/Makefile                    |   7 +
>  drivers/clk/aspeed/clk_ast2500.c               | 255 +++++++++++++++++++++++++
>  4 files changed, 372 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
>  create mode 100644 drivers/clk/aspeed/Makefile
>  create mode 100644 drivers/clk/aspeed/clk_ast2500.c
>
> diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> new file mode 100644
> index 0000000000..febff9d2d3
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> @@ -0,0 +1,108 @@
> +#ifndef _ASM_ARCH_SCU_AST2500_H
> +#define _ASM_ARCH_SCU_AST2500_H
> +
> +#define SCU_UNLOCK_VALUE               0x1688a8a8
> +
> +#define SCU_HWSTRAP_VGAMEM_MASK                3
> +#define SCU_HWSTRAP_VGAMEM_SHIFT       2
> +#define SCU_HWSTRAP_DDR4               (1 << 24)
> +#define SCU_HWSTRAP_CLKIN_25MHZ                (1 << 23)
> +
> +#define SCU_MPLL_DENUM_SHIFT           0
> +#define SCU_MPLL_DENUM_MASK            0x1f
> +#define SCU_MPLL_NUM_SHIFT             5
> +#define SCU_MPLL_NUM_MASK              0xff
> +#define SCU_MPLL_POST_SHIFT            13
> +#define SCU_MPLL_POST_MASK             0x3f
> +
> +#define SCU_HPLL_DENUM_SHIFT           0
> +#define SCU_HPLL_DENUM_MASK            0x1f
> +#define SCU_HPLL_NUM_SHIFT             5
> +#define SCU_HPLL_NUM_MASK              0xff
> +#define SCU_HPLL_POST_SHIFT            13
> +#define SCU_HPLL_POST_MASK             0x3f
> +
> +#define SCU_MISC2_UARTCLK_SHIFT                24
> +
> +#define SCU_MISC_UARTCLK_DIV13         (1 << 12)
> +
> +#ifndef __ASSEMBLY__
> +
> +struct ast2500_clk_priv {
> +       struct ast2500_scu *scu;
> +};
> +
> +struct ast2500_scu {
> +       u32 protection_key;
> +       u32 sysreset_ctrl1;
> +       u32 clk_sel1;
> +       u32 clk_stop_ctrl1;
> +       u32 freq_counter_ctrl;
> +       u32 freq_counter_cmp;
> +       u32 intr_ctrl;
> +       u32 d2_pll_param;
> +       u32 m_pll_param;
> +       u32 h_pll_param;
> +       u32 d_pll_param;
> +       u32 misc_ctrl1;
> +       u32 pci_config[3];
> +       u32 sysreset_status;
> +       u32 vga_handshake[2];
> +       u32 mac_clk_delay;
> +       u32 misc_ctrl2;
> +       u32 vga_scratch[8];
> +       u32 hwstrap;
> +       u32 rng_ctrl;
> +       u32 rng_data;
> +       u32 rev_id;
> +       u32 pinmux_ctrl[6];
> +       u32 reserved0;
> +       u32 extrst_sel;
> +       u32 pinmux_ctrl1[4];
> +       u32 reserved1[2];
> +       u32 mac_clk_delay_100M;
> +       u32 mac_clk_delay_10M;
> +       u32 wakeup_enable;
> +       u32 wakeup_control;
> +       u32 reserved2[3];
> +       u32 sysreset_ctrl2;
> +       u32 clk_sel2;
> +       u32 clk_stop_ctrl2;
> +       u32 freerun_counter;
> +       u32 freerun_counter_ext;
> +       u32 clk_duty_meas_ctrl;
> +       u32 clk_duty_meas_res;
> +       u32 reserved3[4];
> +       /* The next registers are not key protected */

key-protected

> +       struct ast2500_cpu2 {
> +               u32 ctrl;
> +               u32 base_addr[9];
> +               u32 cache_ctrl;
> +       } cpu2;
> +       u32 reserved4;
> +       u32 d_pll_ext_param[3];
> +       u32 d2_pll_ext_param[3];
> +       u32 mh_pll_ext_param;
> +       u32 reserved5;
> +       u32 chip_id[2];
> +       u32 reserved6[2];
> +       u32 uart_clk_ctrl;
> +       u32 reserved7[7];
> +       u32 pcie_config;
> +       u32 mmio_decode;
> +       u32 reloc_ctrl_decode[2];
> +       u32 mailbox_addr;
> +       u32 shared_sram_decode[2];
> +       u32 bmc_rev_id;
> +       u32 reserved8;
> +       u32 bmc_device_id;
> +       u32 reserved9[13];
> +       u32 clk_duty_sel;
> +};
> +
> +int ast_get_clk(struct udevice **devp);
> +void *ast_get_scu(void);

Function comments please.

> +
> +#endif  /* __ASSEMBLY__ */
> +
> +#endif  /* _ASM_ARCH_SCU_AST2500_H */
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 40a5e8cae8..625513789c 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
>  obj-$(CONFIG_CLK_EXYNOS) += exynos/
>  obj-$(CONFIG_CLK_AT91) += at91/
>  obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
> +
> +obj-$(CONFIG_ARCH_ASPEED) += aspeed/
> diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
> new file mode 100644
> index 0000000000..65d1cd6e29
> --- /dev/null
> +++ b/drivers/clk/aspeed/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Copyright (c) 2016 Google, Inc
> +#
> +# SPDX-License-Identifier:      GPL-2.0+
> +#
> +
> +obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
> diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
> new file mode 100644
> index 0000000000..c888a6d35b
> --- /dev/null
> +++ b/drivers/clk/aspeed/clk_ast2500.c
> @@ -0,0 +1,255 @@
> +/*
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0
> + */
> +
> +#include <common.h>
> +#include <asm/arch/scu_ast2500.h>
> +#include <asm/io.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <dm/lists.h>
> +#include <dt-bindings/clock/ast2500-scu.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * For H-PLL and M-PLL the formula is
> + * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
> + * M - Numerator
> + * N - Denumerator
> + * P - Post Divider
> + * They have the same layout in their control register.
> + */
> +
> +/*
> + * Get the rate of the M-PLL clock from input clock frequency and
> + * the value of the M-PLL Parameter Register.
> + */
> +static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
> +{
> +       const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
> +       const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
> +                       & SCU_MPLL_DENUM_MASK;
> +       const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
> +                       & SCU_MPLL_POST_MASK;
> +
> +       return (clkin * ((num + 1) / (denum + 1))) / post_div;
> +}
> +
> +/*
> + * Get the rate of the H-PLL clock from input clock frequency and
> + * the value of the H-PLL Parameter Register.
> + */
> +static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
> +{
> +       const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
> +       const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
> +                       & SCU_HPLL_DENUM_MASK;
> +       const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
> +                       & SCU_HPLL_POST_MASK;
> +
> +       return (clkin * ((num + 1) / (denum + 1))) / post_div;
> +}
> +
> +static ulong ast2500_get_clkin(struct ast2500_scu *scu)
> +{
> +       return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
> +                       ? 25*1000*1000 : 24*1000*1000;

Spaces around *

> +}
> +
> +static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart)

Function comment. What is 'uart' for?

> +{
> +       /*
> +        * ast2500 datasheet is very confusing when it comes to UART clocks,
> +        * especially when CLKIN = 25 MHz. The settings are in
> +        * different registers and it is unclear how they interact.
> +        *
> +        * This has only been tested with default settings and CLKIN = 24 MHz.

Can you detect this and return -EINVAL if it can't work? If not, that's fine.

> +        */
> +       ulong uart_clkin;
> +
> +       if (readl(&scu->misc_ctrl2) & (1 << (uart + SCU_MISC2_UARTCLK_SHIFT)))
> +               uart_clkin = 192 * 1000 * 1000;
> +       else
> +               uart_clkin = 24 * 1000 * 1000;
> +
> +       if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
> +               uart_clkin /= 13;
> +
> +       return uart_clkin;
> +}
> +
> +static ulong ast2500_clk_get_rate(struct clk *clk)
> +{
> +       struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
> +       ulong clkin = ast2500_get_clkin(priv->scu);
> +       ulong rate;
> +
> +       switch (clk->id) {
> +       case PLL_HPLL:
> +       case ARMCLK:
> +               /*
> +                * This ignores dynamic/static slowdown of ARMCLK and may
> +                * be inaccurate.
> +                */
> +               rate = ast2500_get_hpll_rate(clkin,
> +                                            readl(&priv->scu->h_pll_param));
> +               break;
> +       case MCLK_DDR:
> +               rate = ast2500_get_mpll_rate(clkin,
> +                                            readl(&priv->scu->m_pll_param));
> +               break;
> +       case PCLK_UART1:
> +               rate = ast2500_get_uart_clk_rate(priv->scu, 1);
> +               break;
> +       case PCLK_UART2:
> +               rate = ast2500_get_uart_clk_rate(priv->scu, 2);
> +               break;
> +       case PCLK_UART3:
> +               rate = ast2500_get_uart_clk_rate(priv->scu, 3);
> +               break;
> +       case PCLK_UART4:
> +               rate = ast2500_get_uart_clk_rate(priv->scu, 4);
> +               break;
> +       case PCLK_UART5:
> +               rate = ast2500_get_uart_clk_rate(priv->scu, 5);
> +               break;
> +       default:
> +               return -ENOENT;
> +       }
> +
> +       return rate;
> +}
> +
> +static void ast2500_scu_unlock(struct ast2500_scu *scu)
> +{
> +       writel(SCU_UNLOCK_VALUE, &scu->protection_key);
> +       while (!readl(&scu->protection_key))
> +               ;

Can this ever timeout?

> +}
> +
> +static void ast2500_scu_lock(struct ast2500_scu *scu)
> +{
> +       writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
> +       while (readl(&scu->protection_key))
> +               ;
> +}
> +
> +static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
> +{
> +       ulong clkin = ast2500_get_clkin(scu);
> +       u32 mpll_reg;
> +
> +       /*
> +        * There are not that many combinations of numerator, denumerator
> +        * and post divider, so just brute force the best combination.
> +        * However, to avoid overflow when multiplying, use kHz.
> +        */
> +       const ulong clkin_khz = clkin / 1000;
> +       const ulong rate_khz = rate / 1000;
> +

drop blank line

> +       ulong best_num = 0;
> +       ulong best_denum = 0;
> +       ulong best_post = 0;
> +       ulong delta = rate;
> +

drop blank line

> +       ulong num, denum, post;

add blank line

> +       for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
> +               for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
> +                       num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
> +                       ulong new_rate_khz = (clkin_khz
> +                                             * ((num + 1) / (denum + 1)))
> +                                            / (post + 1);
> +
> +                       /* Keep the rate below requested one. */
> +                       if (new_rate_khz > rate_khz)
> +                               continue;
> +
> +                       if (new_rate_khz - rate_khz < delta) {
> +                               delta = new_rate_khz - rate_khz;
> +
> +                               best_num = num;
> +                               best_denum = denum;
> +                               best_post = post;
> +
> +                               if (delta == 0)
> +                                       goto rate_calc_done;
> +                       }
> +               }
> +       }
> +
> + rate_calc_done:

Drop blank line

Can it fail? Do you need to check delta?

> +
> +       mpll_reg = readl(&scu->m_pll_param);
> +       mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
> +                     | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
> +                     | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
> +       mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
> +           | (best_num << SCU_MPLL_NUM_SHIFT)
> +           | (best_denum << SCU_MPLL_DENUM_SHIFT);
> +
> +       ast2500_scu_unlock(scu);
> +       writel(mpll_reg, &scu->m_pll_param);
> +       ast2500_scu_lock(scu);
> +
> +       return ast2500_get_mpll_rate(clkin, mpll_reg);
> +}
> +
> +static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
> +{
> +       struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +       ulong new_rate;
> +       switch (clk->id) {
> +       case PLL_MPLL:
> +       case MCLK_DDR:
> +               new_rate = ast2500_configure_ddr(priv->scu, rate);
> +               break;
> +       default:
> +               return -ENOENT;
> +       }
> +
> +       return new_rate;
> +}
> +
> +struct clk_ops ast2500_clk_ops = {
> +       .get_rate = ast2500_clk_get_rate,
> +       .set_rate = ast2500_clk_set_rate,
> +};
> +
> +static int ast2500_clk_probe(struct udevice *dev)
> +{
> +       struct ast2500_clk_priv *priv = dev_get_priv(dev);

blank line

> +       priv->scu = (struct ast2500_scu *)dev_get_addr(dev);

Maybe dev_get_addr_ptr()

Also should check that it is not FDT_ADDR_NONE.

> +
> +       return 0;
> +}
> +
> +static int ast2500_clk_bind(struct udevice *dev)
> +{
> +       int ret;
> +
> +       /* The reset driver does not have a device node, so bind it here */
> +       ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
> +       if (ret)
> +               debug("Warning: No reset driver: ret=%d\n", ret);
> +
> +       return 0;
> +}
> +
> +static const struct udevice_id ast2500_clk_ids[] = {
> +       { .compatible = "aspeed,ast2500-scu" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(aspeed_ast2500_scu) = {
> +       .name           = "aspeed_ast2500_scu",
> +       .id             = UCLASS_CLK,
> +       .of_match       = ast2500_clk_ids,
> +       .priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
> +       .ops            = &ast2500_clk_ops,
> +       .bind           = ast2500_clk_bind,
> +       .probe          = ast2500_clk_probe,
> +};
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU
  2017-01-04 19:46 ` [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 22:27     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Helper function to get access to SCU (System Control Unit) through Clock
> driver. This is similar to rockchip_get_cru function, which was used as
> an example.
>
> It will be used by other drivers to get access to SCU.
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/mach-aspeed/Kconfig               |  2 ++
>  arch/arm/mach-aspeed/Makefile              |  1 +
>  arch/arm/mach-aspeed/ast2500/Kconfig       |  6 ++++++
>  arch/arm/mach-aspeed/ast2500/Makefile      |  1 +
>  arch/arm/mach-aspeed/ast2500/clk_ast2500.c | 31 ++++++++++++++++++++++++++++++
>  5 files changed, 41 insertions(+)
>  create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
>  create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
>  create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c

The code seems fine.

It seems odd that you have Kconfig changes here also. Why is that?

Regards,
Simon

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

* [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver
  2017-01-04 19:46 ` [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-18 20:16     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> The driver is very ast2500 specific and is completely incompatible

ast2500-specific

> with previous versions of the chip.
>
> The memory controller is very poorly documented by Aspeed in the
> datasheet, with any mention of the whole range of registers missing. The
> initialization procedure has been basically taken from Aspeed SDK, where
> it is implemented in assembly and rewritten in C, with very limited
> understanding of what exacly it is doing.

Here I think you mean:
where
 it is implemented in assembly. Here it is rewritten in C, with very limited
 understanding of what exactly (spelling) it is doing.


>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 133 +++++++
>  arch/arm/mach-aspeed/ast2500/Makefile            |   2 +-
>  arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443 +++++++++++++++++++++++
>  3 files changed, 577 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
>  create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
>
> diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> new file mode 100644
> index 0000000000..ca70898df6
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> @@ -0,0 +1,133 @@
> +#ifndef _ASM_ARCH_SDRAM_AST2500_H
> +#define _ASM_ARCH_SDRAM_AST2500_H
> +
> +#define SDRAM_UNLOCK_KEY               0xfc600309
> +#define SDRAM_VIDEO_UNLOCK_KEY         0x2003000f
> +
> +#define SDRAM_PCR_CKE_EN               (1 << 0)
> +#define SDRAM_PCR_AUTOPWRDN_EN         (1 << 1)
> +#define SDRAM_PCR_CKE_DELAY_SHIFT      4
> +#define SDRAM_PCR_CKE_DELAY_MASK       7
> +#define SDRAM_PCR_RESETN_DIS           (1 << 7)
> +#define SDRAM_PCR_ODT_EN               (1 << 8)
> +#define SDRAM_PCR_ODT_AUTO_ON          (1 << 10)
> +#define SDRAM_PCR_ODT_EXT_EN           (1 << 11)
> +#define SDRAM_PCR_TCKE_PW_SHIFT                12
> +#define SDRAM_PCR_TCKE_PW_MASK         7
> +#define SDRAM_PCR_RGAP_CTRL_EN         (1 << 15)
> +#define SDRAM_PCR_MREQI_DIS            (1 << 17)
> +
> +/* Fixed priority DRAM Requests mask */
> +#define SDRAM_REQ_VGA_HW_CURSOR                (1 << 0)
> +#define SDRAM_REQ_VGA_TEXT_CG_FONT     (1 << 1)
> +#define SDRAM_REQ_VGA_TEXT_ASCII       (1 << 2)
> +#define SDRAM_REQ_VGA_CRT              (1 << 3)
> +#define SDRAM_REQ_SOC_DC_CURSOR                (1 << 4)
> +#define SDRAM_REQ_SOC_DC_OCD           (1 << 5)
> +#define SDRAM_REQ_SOC_DC_CRT           (1 << 6)
> +#define SDRAM_REQ_VIDEO_HIPRI_WRITE    (1 << 7)
> +#define SDRAM_REQ_USB20_EHCI1          (1 << 8)
> +#define SDRAM_REQ_USB20_EHCI2          (1 << 9)
> +#define SDRAM_REQ_CPU                  (1 << 10)
> +#define SDRAM_REQ_AHB2                 (1 << 11)
> +#define SDRAM_REQ_AHB                  (1 << 12)
> +#define SDRAM_REQ_MAC0                 (1 << 13)
> +#define SDRAM_REQ_MAC1                 (1 << 14)
> +#define SDRAM_REQ_PCIE                 (1 << 16)
> +#define SDRAM_REQ_XDMA                 (1 << 17)
> +#define SDRAM_REQ_ENCRYPTION           (1 << 18)
> +#define SDRAM_REQ_VIDEO_FLAG           (1 << 21)
> +#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE  (1 << 28)
> +#define SDRAM_REQ_2D_RW                        (1 << 29)
> +#define SDRAM_REQ_MEMCHECK             (1 << 30)
> +
> +#define SDRAM_ICR_RESET_ALL            (1 << 31)
> +
> +#define SDRAM_CONF_CAP_SHIFT           0
> +#define SDRAM_CONF_CAP_MASK            3
> +#define SDRAM_CONF_DDR4                        (1 << 4)
> +#define SDRAM_CONF_SCRAMBLE            (1 << 8)
> +#define SDRAM_CONF_SCRAMBLE_PAT2       (1 << 9)
> +#define SDRAM_CONF_CACHE_EN            (1 << 10)
> +#define SDRAM_CONF_CACHE_INIT_EN       (1 << 12)
> +#define SDRAM_CONF_DUALX8              (1 << 13)
> +#define SDRAM_CONF_CACHE_INIT_DONE     (1 << 19)
> +
> +#define SDRAM_CONF_CAP_128M            0
> +#define SDRAM_CONF_CAP_256M            1
> +#define SDRAM_CONF_CAP_512M            2
> +#define SDRAM_CONF_CAP_1024M           3
> +
> +#define SDRAM_MISC_DDR4_TREFRESH       (1 << 3)
> +
> +#define SDRAM_PHYCTRL0_INIT            (1 << 0)
> +#define SDRAM_PHYCTRL0_AUTO_UPDATE     (1 << 1)
> +#define SDRAM_PHYCTRL0_NRST            (1 << 2)
> +
> +#define SDRAM_REFRESH_CYCLES_SHIFT     0
> +#define SDRAM_REFRESH_CYCLES_MASK      0xf
> +#define SDRAM_REFRESH_ZQCS_EN          (1 << 7)
> +#define SDRAM_REFRESH_PERIOD_SHIFT     8
> +#define SDRAM_REFRESH_PERIOD_MASK      0xf
> +
> +#define SDRAM_TEST_LEN_SHIFT           4
> +#define SDRAM_TEST_LEN_MASK            0xfffff
> +#define SDRAM_TEST_START_ADDR_SHIFT    24
> +#define SDRAM_TEST_START_ADDR_MASK     0x3f
> +
> +#define SDRAM_TEST_EN                  (1 << 0)
> +#define SDRAM_TEST_MODE_SHIFT          1
> +#define SDRAM_TEST_MODE_MASK           3
> +#define SDRAM_TEST_MODE_WO             0
> +#define SDRAM_TEST_MODE_RB             1
> +#define SDRAM_TEST_MODE_RW             2
> +#define SDRAM_TEST_GEN_MODE_SHIFT      3
> +#define SDRAM_TEST_GEN_MODE_MASK       7
> +#define SDRAM_TEST_TWO_MODES           (1 << 6)
> +#define SDRAM_TEST_ERRSTOP             (1 << 7)
> +#define SDRAM_TEST_DONE                        (1 << 12)
> +#define SDRAM_TEST_FAIL                        (1 << 13)
> +
> +#define SDRAM_AC_TRFC_SHIFT            0
> +#define SDRAM_AC_TRFC_MASK             0xff
> +
> +#ifndef __ASSEMBLY__
> +
> +struct ast2500_sdrammc_regs {
> +       u32 protection_key;
> +       u32 config;
> +       u32 gm_protection_key;
> +       u32 refresh_timing;
> +       u32 ac_timing[3];
> +       u32 misc_control;
> +       u32 mr46_mode_setting;
> +       u32 mr5_mode_setting;
> +       u32 mode_setting_control;
> +       u32 mr02_mode_setting;
> +       u32 mr13_mode_setting;
> +       u32 power_control;
> +       u32 req_limit_mask;
> +       u32 pri_group_setting;
> +       u32 max_grant_len[4];
> +       u32 intr_ctrl;
> +       u32 ecc_range_ctrl;
> +       u32 first_ecc_err_addr;
> +       u32 last_ecc_err_addr;
> +       u32 phy_ctrl[4];
> +       u32 ecc_test_ctrl;
> +       u32 test_addr;
> +       u32 test_fail_dq_bit;
> +       u32 test_init_val;
> +       u32 phy_debug_ctrl;
> +       u32 phy_debug_data;
> +       u32 reserved1[30];
> +       u32 scu_passwd;
> +       u32 reserved2[7];
> +       u32 scu_mpll;
> +       u32 reserved3[19];
> +       u32 scu_hwstrap;
> +};
> +
> +#endif  /* __ASSEMBLY__ */
> +
> +#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
> diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
> index 97d4078ddd..a35b239ef3 100644
> --- a/arch/arm/mach-aspeed/ast2500/Makefile
> +++ b/arch/arm/mach-aspeed/ast2500/Makefile
> @@ -1 +1 @@
> -obj-y += clk_ast2500.o
> +obj-y += clk_ast2500.o sdram_ast2500.o
> diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> new file mode 100644
> index 0000000000..da25756e94
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> @@ -0,0 +1,443 @@
> +/*
> + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> + *
> + * Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:            GPL-2.0
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dt-bindings/clock/ast2500-scu.h>
> +#include <errno.h>
> +#include <ram.h>
> +#include <asm/io.h>
> +#include <asm/arch/scu_ast2500.h>
> +#include <asm/arch/sdram_ast2500.h>
> +#include <asm/arch/wdt.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <regmap.h>

Check ordering: http://www.denx.de/wiki/U-Boot/CodingStyle

> +
> +/* These configuration parameters are taken from Aspeed SDK */
> +#define DDR4_MR46_MODE         0x08000000
> +#define DDR4_MR5_MODE          0x400
> +#define DDR4_MR13_MODE         0x101
> +#define DDR4_MR02_MODE         0x410
> +#define DDR4_TRFC              0x45457188
> +
> +#define PHY_CFG_SIZE           15
> +
> +static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
> +static const struct {
> +       u32 index[PHY_CFG_SIZE];
> +       u32 value[PHY_CFG_SIZE];
> +} ddr4_phy_config = {
> +       .index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
> +       .value = {
> +               0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
> +               0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
> +               0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
> +       },
> +};
> +
> +#define SDRAM_MAX_SIZE         (1024 * 1024 * 1024)
> +#define SDRAM_MIN_SIZE         (128 * 1024 * 1024)
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * Bandwidth configuration parameters for different SDRAM requests.
> + * These are hardcoded settings taken from Aspeed SDK.
> + */
> +static const u32 ddr_max_grant_params[4] = {
> +       0x88448844, 0x24422288, 0x22222222, 0x22222222
> +};
> +
> +/*
> + * These registers are not documented by Aspeed at all.
> + * All writes and reads are taken pretty much as is from SDK.
> + */
> +struct ast2500_ddr_phy {
> +       u32 phy[117];
> +};
> +
> +struct dram_info {
> +       struct ram_info info;
> +       struct clk ddr_clk;
> +       struct ast2500_sdrammc_regs *regs;
> +       struct ast2500_scu *scu;
> +       struct ast2500_ddr_phy *phy;
> +       ulong clock_rate;
> +};
> +
> +static int ast2500_sdrammc_reset(void)
> +{
> +       struct ast_wdt *wdt = ast_get_wdt(0);

blank line. But can you pass this in as a parameter?

> +       if (IS_ERR(wdt))
> +               return PTR_ERR(wdt);
> +
> +       /* Only Reset SDRAM */
> +       writel(WDT_RESET_SDRAM, &wdt->reset_mask);
> +       clrbits_le32(&wdt->ctrl,
> +                    WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
> +       wdt_start(wdt, 1);
> +
> +       /* Wait for WDT to reset */
> +       while (readl(&wdt->ctrl) & WDT_CTRL_EN)
> +               ;
> +       wdt_stop(wdt);

Feels like you should have a helper function or driver to do the
reset, not access the watchdog here.

> +
> +       return 0;
> +}
> +
> +static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
> +{
> +       writel(0, &phy->phy[2]);
> +       writel(0, &phy->phy[6]);
> +       writel(0, &phy->phy[8]);
> +       writel(0, &phy->phy[10]);
> +       writel(0, &phy->phy[12]);
> +       writel(0, &phy->phy[42]);
> +       writel(0, &phy->phy[44]);
> +
> +       writel(0x86000000, &phy->phy[16]);
> +       writel(0x00008600, &phy->phy[17]);
> +       writel(0x80000000, &phy->phy[18]);
> +       writel(0x80808080, &phy->phy[19]);
> +
> +       return 0;
> +}
> +
> +static void ast2500_ddr_phy_init_process(struct dram_info *info)
> +{
> +       struct ast2500_sdrammc_regs *regs = info->regs;

blank line. Please fix globally - need a line between decls and code.

> +       writel(0, &regs->phy_ctrl[0]);
> +       writel(0x4040, &info->phy->phy[51]);
> +
> +       writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
> +       while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
> +               ;
> +       writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
> +              &regs->phy_ctrl[0]);
> +}
> +
> +static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
> +{
> +       writel(0, &info->regs->phy_ctrl[0]);
> +       writel((vref << 8) | 0x6, &info->phy->phy[48]);
> +       ast2500_ddr_phy_init_process(info);
> +}
> +
> +static int ast2500_ddr_cbr_test(struct dram_info *info)
> +{
> +       struct ast2500_sdrammc_regs *regs = info->regs;
> +       int i;
> +       const u32 test_params = SDRAM_TEST_EN
> +                       | SDRAM_TEST_ERRSTOP
> +                       | SDRAM_TEST_TWO_MODES;
> +       int ret = 0;
> +
> +       writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
> +              (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
> +       writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
> +       writel(0xff00ff00, &regs->test_init_val);
> +       writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
> +              SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
> +
> +       while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
> +               ;
> +
> +       if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
> +               ret = -EIO;
> +       } else {
> +               for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
> +                       writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
> +                              &regs->ecc_test_ctrl);
> +                       while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
> +                               ;
> +                       if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
> +                               ret = -EIO;
> +                               break;
> +                       }
> +               }
> +       }
> +
> +       writel(0, &regs->refresh_timing);
> +       writel(0, &regs->ecc_test_ctrl);

blank line before 'return' line.

> +       return ret;
> +}
> +
> +static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
> +{
> +       int i;
> +       int vref_min = 0xff;
> +       int vref_max = 0;
> +       int range_size = 0;
> +
> +       for (i = 1; i < 0x40; ++i) {
> +               ast2500_sdrammc_set_vref(info, i);
> +
> +               int res = ast2500_ddr_cbr_test(info);
> +               if (res < 0) {
> +                       if (range_size > 0)
> +                               break;
> +               } else {
> +                       ++range_size;
> +                       vref_min = min(vref_min, i);
> +                       vref_max = max(vref_max, i);
> +               }
> +       }
> +
> +       /* Pick average setting */
> +       ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
> +
> +       return 0;
> +}
> +
> +static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
> +{
> +       size_t vga_mem_size_base = 8 * 1024 * 1024;
> +       u32 vga_hwconf = (readl(&info->scu->hwstrap)
> +                         >> SCU_HWSTRAP_VGAMEM_SHIFT)
> +                       & SCU_HWSTRAP_VGAMEM_MASK;
> +
> +       return vga_mem_size_base << vga_hwconf;
> +}
> +
> +/*
> + * Find out RAM size and save it in dram_info
> + *
> + * The procedure is taken from Aspeed SDK
> + */
> +static void ast2500_sdrammc_calc_size(struct dram_info *info)
> +{
> +       /* The controller supports 128/256/512/1024 MB ram */
> +       size_t ram_size = SDRAM_MIN_SIZE;
> +       const int write_test_offset = 0x100000;
> +       u32 test_pattern = 0xdeadbeef;
> +       u32 cap_param = SDRAM_CONF_CAP_1024M;
> +       u32 refresh_timing_param = DDR4_TRFC;
> +       const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
> +
> +       for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
> +            ram_size >>= 1) {
> +               writel(test_pattern, write_addr_base + (ram_size >> 1));
> +               test_pattern = (test_pattern >> 4) | (test_pattern << 28);
> +       }
> +
> +       /* One last write to overwrite all wrapped values */
> +       writel(test_pattern, write_addr_base);
> +
> +       /* Reset the pattern and see which value was really written */
> +       test_pattern = 0xdeadbeef;
> +       for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
> +            ram_size >>= 1) {
> +               if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
> +                       break;
> +
> +               --cap_param;
> +               refresh_timing_param >>= 8;
> +               test_pattern = (test_pattern >> 4) | (test_pattern << 28);
> +       }
> +
> +       clrsetbits_le32(&info->regs->ac_timing[1],
> +                       (SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
> +                       ((refresh_timing_param & SDRAM_AC_TRFC_MASK)
> +                        << SDRAM_AC_TRFC_SHIFT));
> +
> +       info->info.base = CONFIG_SYS_SDRAM_BASE;
> +       info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
> +       clrsetbits_le32(&info->regs->config,
> +                       (SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
> +                       ((cap_param & SDRAM_CONF_CAP_MASK)
> +                        << SDRAM_CONF_CAP_SHIFT));
> +}
> +
> +static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
> +{
> +       int i;
> +       const u32 power_control = SDRAM_PCR_CKE_EN
> +           | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
> +           | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
> +           | SDRAM_PCR_RESETN_DIS
> +           | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
> +       const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
> +#ifdef CONFIG_DUALX8_RAM
> +           | SDRAM_CONF_DUALX8
> +#endif
> +           | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
> +
> +       writel(conf, &info->regs->config);
> +       for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
> +               writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
> +
> +       writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
> +       writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
> +       writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
> +       writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
> +
> +       for (i = 0; i < PHY_CFG_SIZE; ++i) {
> +               writel(ddr4_phy_config.value[i],
> +                      &info->phy->phy[ddr4_phy_config.index[i]]);
> +       }
> +
> +       writel(power_control, &info->regs->power_control);
> +
> +       ast2500_ddr_phy_init_process(info);
> +
> +       int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);

please declare variables at the top of functions if you can, or inside
the block that needs them.

> +       if (ret < 0) {
> +               debug("Vref calibration failed!\n");
> +               return ret;
> +       }
> +
> +       writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
> +              | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
> +              &info->regs->refresh_timing);
> +
> +       setbits_le32(&info->regs->power_control,
> +                    SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
> +
> +       ast2500_sdrammc_calc_size(info);
> +
> +       setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
> +       while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
> +               ;
> +       setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
> +
> +       writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
> +
> +       /* Enable all requests except video & display */
> +       writel(SDRAM_REQ_USB20_EHCI1
> +              | SDRAM_REQ_USB20_EHCI2
> +              | SDRAM_REQ_CPU
> +              | SDRAM_REQ_AHB2
> +              | SDRAM_REQ_AHB
> +              | SDRAM_REQ_MAC0
> +              | SDRAM_REQ_MAC1
> +              | SDRAM_REQ_PCIE
> +              | SDRAM_REQ_XDMA
> +              | SDRAM_REQ_ENCRYPTION
> +              | SDRAM_REQ_VIDEO_FLAG
> +              | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
> +              | SDRAM_REQ_2D_RW
> +              | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
> +
> +       return 0;
> +}
> +
> +static void ast2500_sdrammc_unlock(struct dram_info *info)
> +{
> +       writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
> +       while (!readl(&info->regs->protection_key))
> +               ;
> +}
> +
> +static void ast2500_sdrammc_lock(struct dram_info *info)
> +{
> +       writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
> +       while (readl(&info->regs->protection_key))
> +               ;
> +}
> +
> +static int ast2500_sdrammc_probe(struct udevice *dev)
> +{
> +       struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
> +       struct ast2500_sdrammc_regs *regs = priv->regs;
> +       int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);

Move this assignment to just before your 'if' below.

> +       int i;
> +
> +       if (ret) {
> +               debug("DDR:No CLK\n");
> +               return ret;
> +       }
> +
> +       priv->scu = ast_get_scu();
> +       if (IS_ERR(priv->scu))

debug()

> +               return PTR_ERR(priv->scu);
> +
> +       clk_set_rate(&priv->ddr_clk, priv->clock_rate);
> +       ret = ast2500_sdrammc_reset();
> +       if (ret)

debug()

> +               return ret;
> +
> +       ast2500_sdrammc_unlock(priv);
> +
> +       writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
> +              &regs->power_control);
> +       writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
> +
> +       /* Mask all requests except CPU and AHB during PHY init */
> +       writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
> +
> +       for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
> +               writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
> +
> +       setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
> +
> +       ast2500_sdrammc_init_phy(priv->phy);
> +       if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
> +               ast2500_sdrammc_init_ddr4(priv);
> +       } else {
> +               debug("Unsupported DRAM3\n");
> +               return -EINVAL;
> +       }
> +
> +       clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
> +       ast2500_sdrammc_lock(priv);
> +
> +       return 0;
> +}
> +
> +static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct dram_info *priv = dev_get_priv(dev);
> +       struct regmap *map;
> +       int ret = regmap_init_mem(dev, &map);
> +

Move assignment or ret to here.

> +       if (ret)
> +               return ret;
> +
> +       priv->regs = regmap_get_range(map, 0);
> +       priv->phy = regmap_get_range(map, 1);
> +
> +       priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
> +                                         "clock-frequency", 0);
> +
> +       if (!priv->clock_rate) {
> +               debug("DDR Clock Rate not defined\n");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
> +{
> +       struct dram_info *priv = dev_get_priv(dev);
> +
> +       *info = priv->info;
> +
> +       return 0;
> +}
> +
> +static struct ram_ops ast2500_sdrammc_ops = {
> +       .get_info = ast2500_sdrammc_get_info,
> +};
> +
> +static const struct udevice_id ast2500_sdrammc_ids[] = {
> +       { .compatible = "aspeed,ast2500-sdrammc" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(sdrammc_ast2500) = {
> +       .name = "aspeed_ast2500_sdrammc",
> +       .id = UCLASS_RAM,
> +       .of_match = ast2500_sdrammc_ids,
> +       .ops = &ast2500_sdrammc_ops,
> +       .ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
> +       .probe = ast2500_sdrammc_probe,
> +       .priv_auto_alloc_size = sizeof(struct dram_info),
> +};
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards
  2017-01-04 19:46 ` [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 20:17     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  arch/arm/mach-aspeed/Makefile        |  2 +-
>  arch/arm/mach-aspeed/ast2500-board.c | 74 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 75 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
>
> diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
> index 1f7af71b03..9d29ff7f6f 100644
> --- a/arch/arm/mach-aspeed/Makefile
> +++ b/arch/arm/mach-aspeed/Makefile
> @@ -5,4 +5,4 @@
>  #
>
>  obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> -obj-$(CONFIG_ASPEED_AST2500) += ast2500/
> +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
> diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
> new file mode 100644
> index 0000000000..5b2b0ce132
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/ast2500-board.c
> @@ -0,0 +1,74 @@
> +#include <common.h>
> +#include <asm/arch/timer.h>
> +#include <asm/arch/wdt.h>
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <dm/uclass.h>
> +#include <linux/err.h>
> +#include <ram.h>
> +#include <timer.h>

Check include file order.

> +
> +/* Second Watchdog Timer by default is configured

/*
 * Second watchdog...
 * ...
 */

Please check globally. Try to use more columns if you can.

> + * to trigger secondary boot source.
> + */
> +#define AST_2ND_BOOT_WDT               (1)

Remove () around simple constants.

> +
> +/* Third Watchdog Timer by default is configured
> + * to toggle Flash address mode switch before reset.
> + */
> +#define AST_FLASH_ADDR_DETECT_WDT      (2)
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +void lowlevel_init(void)
> +{
> +       /*
> +        * These two watchdogs need to be stopped as soon as possible,
> +        * otherwise the board might hang. By default they are set to
> +        * a very short timeout and even simple debug write to serial
> +        * console early in the init process might cause them to fire.
> +        */
> +       struct ast_wdt *flash_addr_wdt =
> +           (struct ast_wdt *)(WDT_BASE +
> +                              sizeof(struct ast_wdt) *
> +                              AST_FLASH_ADDR_DETECT_WDT);
> +
> +       clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
> +
> +#ifndef CONFIG_FIRMWARE_2ND_BOOT
> +       struct ast_wdt *sec_boot_wdt =
> +           (struct ast_wdt *)(WDT_BASE +
> +                              sizeof(struct ast_wdt) *
> +                              AST_2ND_BOOT_WDT);
> +
> +       clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
> +#endif

Seems this should call a helper function in ast_wdt.c or similar.

> +}
> +
> +int board_init(void)
> +{
> +       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

blank line

> +       return 0;
> +}
> +
> +int dram_init(void)
> +{
> +       struct udevice *dev;
> +       int ret = uclass_get_device(UCLASS_RAM, 0, &dev);

blank line, and better to separate decl and code in this case, since
you check it below.

> +       if (ret) {
> +               debug("DRAM FAIL1\r\n");
> +               return ret;
> +       }
> +
> +       struct ram_info ram;

move to top of function

> +       ret = ram_get_info(dev, &ram);
> +       if (ret) {
> +               debug("DRAM FAIL2\r\n");
> +               return ret;
> +       }
> +

drop extra blank line

> +
> +       gd->ram_size = ram.size;

blank line

> +       return 0;
> +}
> +
> --
> 2.11.0.390.gc69c2f50cf-goog
>

REgards,
Simon

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

* [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards
  2017-01-04 19:46 ` [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 20:02     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>
>  include/configs/aspeed-common.h | 84 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
>  create mode 100644 include/configs/aspeed-common.h
>
> diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
> new file mode 100644
> index 0000000000..c125e39e3f
> --- /dev/null
> +++ b/include/configs/aspeed-common.h
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> + * Ryan Chen <ryan_chen@aspeedtech.com>
> + *
> + * Copyright 2016 IBM Corporation
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef __AST_COMMON_CONFIG_H
> +#define __AST_COMMON_CONFIG_H
> +
> +/* Misc CPU related */
> +#define CONFIG_CMDLINE_TAG
> +#define CONFIG_SETUP_MEMORY_TAGS
> +#define CONFIG_INITRD_TAG
> +
> +#define CONFIG_CMDLINE_EDITING         1

Drop the '1' from this

> +
> +/* Enable cache controller */
> +#define CONFIG_SYS_DCACHE_OFF          1

and this

> +
> +#ifdef CONFIG_PRE_CON_BUF_SZ
> +#define PRE_CON_RAM_SZ         CONFIG_PRE_CON_BUF_SZ
> +#else
> +#define PRE_CON_RAM_SZ 0
> +#endif

What is this for?

> +
> +#define CONFIG_SYS_SDRAM_BASE          0x80000000
> +#define CONFIG_SYS_INIT_RAM_ADDR       (0x1e720000 + PRE_CON_RAM_SZ)
> +#define CONFIG_SYS_INIT_RAM_SIZE       (36*1024 - PRE_CON_RAM_SZ)
> +#define SYS_INIT_RAM_END               (CONFIG_SYS_INIT_RAM_ADDR \
> +                                        + CONFIG_SYS_INIT_RAM_SIZE)
> +#define CONFIG_SYS_INIT_SP_ADDR                (SYS_INIT_RAM_END \
> +                                        - GENERATED_GBL_DATA_SIZE)
> +#define CONFIG_SYS_GBL_DATA_OFFSET     (CONFIG_SYS_INIT_RAM_SIZE \
> +                                        - GENERATED_GBL_DATA_SIZE)

Those last two should not be needed

> +
> +#define CONFIG_NR_DRAM_BANKS           1
> +
> +#define CONFIG_SYS_TEXT_BASE           0x00000000
> +
> +#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
> +
> +/*
> + * NS16550 Configuration
> + */
> +#define CONFIG_BAUDRATE                        115200
> +
> +/*
> + * BOOTP options
> + */
> +#define CONFIG_BOOTP_BOOTFILESIZE
> +#define CONFIG_BOOTP_BOOTPATH
> +#define CONFIG_BOOTP_GATEWAY
> +#define CONFIG_BOOTP_HOSTNAME
> +#define CONFIG_BOOTP_SUBNETMASK
> +
> +/*
> + * Miscellaneous configurable options
> + */
> +#define CONFIG_SYS_LONGHELP
> +#define CONFIG_SYS_CBSIZE              256
> +
> +/* Print Buffer Size */
> +#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE \
> +                                        + sizeof(CONFIG_SYS_PROMPT) + 16)
> +#define CONFIG_SYS_MAXARGS             16
> +#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
> +
> +#define CONFIG_BOOTARGS \
> +               "console=ttyS4,115200n8" \
> +               " root=/dev/ram rw"
> +
> +#define CONFIG_BOOTCOMMAND             "bootm 20080000 20300000"
> +#define CONFIG_ENV_OVERWRITE
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +       "verify=yes\0"  \
> +       "spi_dma=yes\0" \
> +       ""
> +
> +#endif /* __AST_COMMON_CONFIG_H */
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board
  2017-01-04 19:46 ` [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 19:51     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> Signed-off-by: Maxim Sloyko <maxims@google.com>

Please add a commit message explaining where it came from.

> ---
>
>  arch/arm/dts/Makefile        |  2 ++
>  arch/arm/dts/ast2500-evb.dts | 23 +++++++++++++++++++++++
>  2 files changed, 25 insertions(+)
>  create mode 100644 arch/arm/dts/ast2500-evb.dts

Reviewed-by: Simon Glass <sjg@chromium.org>

>
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index f43746966c..1bee50e237 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
>         bcm2836-rpi-2-b.dtb \
>         bcm2837-rpi-3-b.dtb
>
> +dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
> +
>  targets += $(dtb-y)
>
>  # Add any required device tree compiler flags here
> diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
> new file mode 100644
> index 0000000000..b1a415f7d7
> --- /dev/null
> +++ b/arch/arm/dts/ast2500-evb.dts
> @@ -0,0 +1,23 @@
> +/dts-v1/;
> +
> +#include "ast2500.dtsi"
> +
> +/ {
> +       memory {
> +               device_type = "memory";
> +               reg = <0x80000000 0x20000000>;
> +       };
> +
> +       chosen {
> +               stdout-path = &uart5;
> +       };
> +};
> +
> +&uart5 {
> +       u-boot,dm-pre-reloc;

Consider putting this and any other U-Boot-specific things in a
u-boot*.dtsi file if you have one.

> +       status = "okay";
> +};
> +
> +&sdrammc {
> +       clock-frequency = <400000000>;
> +};
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board
  2017-01-04 19:46 ` [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board Maxim Sloyko
@ 2017-01-14 17:14   ` Simon Glass
  2017-01-17 19:46     ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-14 17:14 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> ---
>

Commit message?

> ---
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>  arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
>  board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
>  board/aspeed/evb_ast2500/Makefile      |  1 +
>  board/aspeed/evb_ast2500/evb_ast2500.c |  1 +
>  configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
>  include/configs/evb_ast2500.h          | 30 ++++++++++++++++++++++++++++++
>  6 files changed, 72 insertions(+)
>  create mode 100644 board/aspeed/evb_ast2500/Kconfig
>  create mode 100644 board/aspeed/evb_ast2500/Makefile
>  create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
>  create mode 100644 configs/evb-ast2500_defconfig
>  create mode 100644 include/configs/evb_ast2500.h
>
> diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
> index c0b448f19e..7397d0c179 100644
> --- a/arch/arm/mach-aspeed/ast2500/Kconfig
> +++ b/arch/arm/mach-aspeed/ast2500/Kconfig
> @@ -3,4 +3,11 @@ if ASPEED_AST2500
>  config SYS_CPU
>         default "arm1176"
>
> +config TARGET_EVB_AST2500
> +       bool "Evb-AST2500"
> +       help
> +         Evb-AST2500 is Aspeed evaluation board for AST2500 chip.

More details? What peripherals does it provide?

> +
> +source "board/aspeed/evb_ast2500/Kconfig"
> +
>  endif
> diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
> new file mode 100644
> index 0000000000..73a8ae85f6
> --- /dev/null
> +++ b/board/aspeed/evb_ast2500/Kconfig
> @@ -0,0 +1,12 @@
> +if TARGET_EVB_AST2500
> +
> +config SYS_BOARD
> +       default "evb_ast2500"
> +
> +config SYS_VENDOR
> +       default "aspeed"
> +
> +config SYS_CONFIG_NAME
> +       default "evb_ast2500"
> +
> +endif
> diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
> new file mode 100644
> index 0000000000..4564098299
> --- /dev/null
> +++ b/board/aspeed/evb_ast2500/Makefile
> @@ -0,0 +1 @@
> +obj-y += evb_ast2500.o
> diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
> new file mode 100644
> index 0000000000..65e11030d8
> --- /dev/null
> +++ b/board/aspeed/evb_ast2500/evb_ast2500.c
> @@ -0,0 +1 @@
> +#include <common.h>
> diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
> new file mode 100644
> index 0000000000..4598f6f418
> --- /dev/null
> +++ b/configs/evb-ast2500_defconfig
> @@ -0,0 +1,21 @@
> +CONFIG_ARM=y
> +CONFIG_ARCH_ASPEED=y
> +CONFIG_ASPEED_AST2500=y
> +CONFIG_TARGET_EVB_AST2500=y
> +CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
> +CONFIG_OF_CONTROL=y
> +CONFIG_DM=y
> +CONFIG_SYS_MALLOC_F_LEN=0x2000
> +CONFIG_DISPLAY_CPUINFO=n
> +CONFIG_SYS_NS16550=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_SYSRESET=y
> +CONFIG_CLK=y
> +CONFIG_TIMER=y
> +CONFIG_RAM=y
> +CONFIG_REGMAP=y
> +CONFIG_PRE_CONSOLE_BUFFER=y
> +CONFIG_PRE_CON_BUF_ADDR=0x1e720000
> +CONFIG_PRE_CON_BUF_SZ=4096
> +CONFIG_SYS_NO_FLASH=y
> +CONFIG_CMD_IMLS=n
> diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
> new file mode 100644
> index 0000000000..28d11a2bdf
> --- /dev/null
> +++ b/include/configs/evb_ast2500.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> + * Ryan Chen <ryan_chen@aspeedtech.com>
> + *
> + * Copyright 2016 Google Inc
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#include <configs/aspeed-common.h>
> +
> +

Drop extra BLANK LINE

> +#define CONFIG_SYS_MEMTEST_START       (CONFIG_SYS_SDRAM_BASE + 0x300000)
> +#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + 0x5000000)
> +
> +#define CONFIG_SYS_UBOOT_BASE          CONFIG_SYS_TEXT_BASE
> +
> +/*
> + * Memory Info
> + */

Could be on one line

> +#define CONFIG_SYS_LOAD_ADDR           0x83000000
> +
> +#define CONFIG_ENV_IS_NOWHERE          1

You can drop the 1.

> +
> +#define CONFIG_ENV_SIZE                        0x20000
> +
> +#endif /* __CONFIG_H */
> --
> 2.11.0.390.gc69c2f50cf-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-14 17:13   ` Simon Glass
@ 2017-01-17 17:57     ` Maxim Sloyko
  2017-01-17 21:37       ` Simon Glass
  2017-01-17 23:59     ` Maxim Sloyko
  1 sibling, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 17:57 UTC (permalink / raw)
  To: u-boot

Hi Simon,

This is older series, that I merged into a smaller number of patches and
already addressed all of Tom's comments:
http://lists.denx.de/pipermail/u-boot/2017-January/277883.html

Most of your comments still apply, just want to make sure we are on the
same page.

On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Add support for timer for Aspeed ast2400/ast2500 devices.
> > The driver actually controls several devices, but because all devices
> > share the same Control Register, it is somewhat difficult to completely
> > decouple them. Since only one timer is needed at the moment, this should
> > be OK.
> >
> > The timer uses fixed clock, so does not rely on a clock driver.
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
> >  drivers/timer/Kconfig                    |  7 +++
> >  drivers/timer/Makefile                   |  1 +
> >  drivers/timer/ast_timer.c                | 96
> ++++++++++++++++++++++++++++++++
> >  4 files changed, 158 insertions(+)
> >  create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
> >  create mode 100644 drivers/timer/ast_timer.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> nits below.
>
> >
> > diff --git a/arch/arm/include/asm/arch-aspeed/timer.h
> b/arch/arm/include/asm/arch-aspeed/timer.h
> > new file mode 100644
> > index 0000000000..87c5b354ec
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-aspeed/timer.h
> > @@ -0,0 +1,54 @@
> > +/*
> > + * Copyright (c) 2016 Google, Inc
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0+
> > + */
> > +#ifndef _ASM_ARCH_TIMER_H
> > +#define _ASM_ARCH_TIMER_H
> > +
> > +/* Each timer has 4 control bits in ctrl1 register.
> > + * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
> > + * such that timer X uses bits (4 * X - 4):(4 * X - 1)
> > + * If the timer does not support PWM, bit 4 is reserved.
> > + */
> > +#define AST_TMC_EN                     (1 << 0)
> > +#define AST_TMC_1MHZ                   (1 << 1)
> > +#define AST_TMC_OVFINTR                        (1 << 2)
> > +#define AST_TMC_PWM                    (1 << 3)
> > +
> > +/* Timers are counted from 1 in the datasheet. */
> > +#define AST_TMC_CTRL1_SHIFT(n)                 (4 * ((n) - 1))
> > +
> > +#define AST_TMC_RATE  (1000*1000)
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +/*
> > + * All timers share control registers, which makes it harder to make
> them
> > + * separate devices. Since only one timer is needed at the moment,
> making
> > + * it this just one device.
> > + */
> > +
> > +struct ast_timer_counter {
> > +       u32 status;
> > +       u32 reload_val;
> > +       u32 match1;
> > +       u32 match2;
> > +};
> > +
> > +struct ast_timer {
> > +       struct ast_timer_counter timers1[3];
> > +       u32 ctrl1;
> > +       u32 ctrl2;
> > +#ifdef CONFIG_ASPEED_AST2500
> > +       u32 ctrl3;
> > +       u32 ctrl1_clr;
> > +#else
> > +       u32 reserved[2];
> > +#endif
> > +       struct ast_timer_counter timers2[5];
> > +};
> > +
> > +#endif  /* __ASSEMBLY__ */
> > +
> > +#endif  /* _ASM_ARCH_TIMER_H */
> > diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> > index cb18f12fc9..9c5f98bb88 100644
> > --- a/drivers/timer/Kconfig
> > +++ b/drivers/timer/Kconfig
> > @@ -46,4 +46,11 @@ config OMAP_TIMER
> >         help
> >           Select this to enable an timer for Omap devices.
> >
> > +config AST_TIMER
> > +       bool "Aspeed ast2400/ast2500 timer support"
> > +       depends on TIMER
> > +       default y if ARCH_ASPEED
> > +       help
> > +         Select this to enable timer for Aspeed ast2400/ast2500 devices.
>
> Can you add more detail? How many channels? What features are
> supported by the driver?
>
> > +
> >  endmenu
> > diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> > index f351fbb4e0..a4b1a486b0 100644
> > --- a/drivers/timer/Makefile
> > +++ b/drivers/timer/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)      += altera_timer.o
> >  obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
> >  obj-$(CONFIG_X86_TSC_TIMER)    += tsc_timer.o
> >  obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
> > +obj-$(CONFIG_AST_TIMER)        += ast_timer.o
> > diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
> > new file mode 100644
> > index 0000000000..f644882f40
> > --- /dev/null
> > +++ b/drivers/timer/ast_timer.c
> > @@ -0,0 +1,96 @@
> > +/*
> > + * Copyright 2016 Google Inc.
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0+
> > + */
> > +
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <errno.h>
> > +#include <timer.h>
> > +#include <asm/io.h>
> > +#include <asm/arch/timer.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +#define AST_TICK_TIMER  1
> > +#define AST_TMC_RELOAD_VAL  0xffffffff
> > +
> > +struct ast_timer_priv {
> > +       struct ast_timer *regs;
> > +};
> > +
> > +static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer
> *timer,
> > +                                                      int n)
> > +{
> > +       if (n > 3)
> > +               return &timer->timers2[n - 4];
> > +       else
> > +               return &timer->timers1[n - 1];
> > +}
> > +
> > +static int ast_timer_probe(struct udevice *dev)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->
> regs,
> > +
>  AST_TICK_TIMER);
>
> I suppose tmc could be in your struct ast_timer_priv to save you doing
> this each time?
>
> > +       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> > +
> > +       writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
> > +
> > +       /*
> > +        * Stop the timer. This will also load reload_val into
> > +        * the status register.
> > +        */
> > +       clrbits_le32(&priv->regs->ctrl1,
> > +                    AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> > +       /* Start the timer from the fixed 1MHz clock. */
> > +       setbits_le32(&priv->regs->ctrl1,
> > +                    (AST_TMC_EN | AST_TMC_1MHZ) <<
> > +                    AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> > +
> > +       uc_priv->clock_rate = AST_TMC_RATE;
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast_timer_get_count(struct udevice *dev, u64 *count)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->
> regs,
> > +
>  AST_TICK_TIMER);
> > +
> > +       *count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast_timer_ofdata_to_platdata(struct udevice *dev)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +
> > +       priv->regs = (struct ast_timer *)dev_get_addr(dev);
>
> You can use dev_get_addr_ptr() if you like.
>
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct timer_ops ast_timer_ops = {
> > +       .get_count = ast_timer_get_count,
> > +};
> > +
> > +static const struct udevice_id ast_timer_ids[] = {
> > +       { .compatible = "aspeed,ast2500-timer" },
> > +       { .compatible = "aspeed,ast2400-timer" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(sandbox_timer) = {
>
> s/sandbox/ast/ or something, as Tom, mentioned.
>
> > +       .name = "ast_timer",
> > +       .id = UCLASS_TIMER,
> > +       .of_match = ast_timer_ids,
> > +       .probe = ast_timer_probe,
> > +       .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
> > +       .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
> > +       .ops = &ast_timer_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > --
> > 2.11.0.390.gc69c2f50cf-goog
>
> Regards,
> Simon
>
> >
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 19:46     ` Maxim Sloyko
  2017-01-21  3:51       ` Simon Glass
  0 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 19:46 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > ---
> >
>
> Commit message?
>
> > ---
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >  arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
> >  board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
> >  board/aspeed/evb_ast2500/Makefile      |  1 +
> >  board/aspeed/evb_ast2500/evb_ast2500.c |  1 +
> >  configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
> >  include/configs/evb_ast2500.h          | 30
> ++++++++++++++++++++++++++++++
> >  6 files changed, 72 insertions(+)
> >  create mode 100644 board/aspeed/evb_ast2500/Kconfig
> >  create mode 100644 board/aspeed/evb_ast2500/Makefile
> >  create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
> >  create mode 100644 configs/evb-ast2500_defconfig
> >  create mode 100644 include/configs/evb_ast2500.h
> >
> > diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig
> b/arch/arm/mach-aspeed/ast2500/Kconfig
> > index c0b448f19e..7397d0c179 100644
> > --- a/arch/arm/mach-aspeed/ast2500/Kconfig
> > +++ b/arch/arm/mach-aspeed/ast2500/Kconfig
> > @@ -3,4 +3,11 @@ if ASPEED_AST2500
> >  config SYS_CPU
> >         default "arm1176"
> >
> > +config TARGET_EVB_AST2500
> > +       bool "Evb-AST2500"
> > +       help
> > +         Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
>
> More details? What peripherals does it provide?
>

Do you mean the hardware or what has been implemented so far?


>
> > +
> > +source "board/aspeed/evb_ast2500/Kconfig"
> > +
> >  endif
> > diff --git a/board/aspeed/evb_ast2500/Kconfig
> b/board/aspeed/evb_ast2500/Kconfig
> > new file mode 100644
> > index 0000000000..73a8ae85f6
> > --- /dev/null
> > +++ b/board/aspeed/evb_ast2500/Kconfig
> > @@ -0,0 +1,12 @@
> > +if TARGET_EVB_AST2500
> > +
> > +config SYS_BOARD
> > +       default "evb_ast2500"
> > +
> > +config SYS_VENDOR
> > +       default "aspeed"
> > +
> > +config SYS_CONFIG_NAME
> > +       default "evb_ast2500"
> > +
> > +endif
> > diff --git a/board/aspeed/evb_ast2500/Makefile
> b/board/aspeed/evb_ast2500/Makefile
> > new file mode 100644
> > index 0000000000..4564098299
> > --- /dev/null
> > +++ b/board/aspeed/evb_ast2500/Makefile
> > @@ -0,0 +1 @@
> > +obj-y += evb_ast2500.o
> > diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c
> b/board/aspeed/evb_ast2500/evb_ast2500.c
> > new file mode 100644
> > index 0000000000..65e11030d8
> > --- /dev/null
> > +++ b/board/aspeed/evb_ast2500/evb_ast2500.c
> > @@ -0,0 +1 @@
> > +#include <common.h>
> > diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_
> defconfig
> > new file mode 100644
> > index 0000000000..4598f6f418
> > --- /dev/null
> > +++ b/configs/evb-ast2500_defconfig
> > @@ -0,0 +1,21 @@
> > +CONFIG_ARM=y
> > +CONFIG_ARCH_ASPEED=y
> > +CONFIG_ASPEED_AST2500=y
> > +CONFIG_TARGET_EVB_AST2500=y
> > +CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
> > +CONFIG_OF_CONTROL=y
> > +CONFIG_DM=y
> > +CONFIG_SYS_MALLOC_F_LEN=0x2000
> > +CONFIG_DISPLAY_CPUINFO=n
> > +CONFIG_SYS_NS16550=y
> > +CONFIG_DM_SERIAL=y
> > +CONFIG_SYSRESET=y
> > +CONFIG_CLK=y
> > +CONFIG_TIMER=y
> > +CONFIG_RAM=y
> > +CONFIG_REGMAP=y
> > +CONFIG_PRE_CONSOLE_BUFFER=y
> > +CONFIG_PRE_CON_BUF_ADDR=0x1e720000
> > +CONFIG_PRE_CON_BUF_SZ=4096
> > +CONFIG_SYS_NO_FLASH=y
> > +CONFIG_CMD_IMLS=n
> > diff --git a/include/configs/evb_ast2500.h
> b/include/configs/evb_ast2500.h
> > new file mode 100644
> > index 0000000000..28d11a2bdf
> > --- /dev/null
> > +++ b/include/configs/evb_ast2500.h
> > @@ -0,0 +1,30 @@
> > +/*
> > + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> > + * Ryan Chen <ryan_chen@aspeedtech.com>
> > + *
> > + * Copyright 2016 Google Inc
> > + *
> > + * SPDX-License-Identifier:     GPL-2.0+
> > + */
> > +
> > +#ifndef __CONFIG_H
> > +#define __CONFIG_H
> > +
> > +#include <configs/aspeed-common.h>
> > +
> > +
>
> Drop extra BLANK LINE
>
> > +#define CONFIG_SYS_MEMTEST_START       (CONFIG_SYS_SDRAM_BASE +
> 0x300000)
> > +#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START +
> 0x5000000)
> > +
> > +#define CONFIG_SYS_UBOOT_BASE          CONFIG_SYS_TEXT_BASE
> > +
> > +/*
> > + * Memory Info
> > + */
>
> Could be on one line
>
> > +#define CONFIG_SYS_LOAD_ADDR           0x83000000
> > +
> > +#define CONFIG_ENV_IS_NOWHERE          1
>
> You can drop the 1.
>

This has been addressed in v3.


>
> > +
> > +#define CONFIG_ENV_SIZE                        0x20000
> > +
> > +#endif /* __CONFIG_H */
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 19:51     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 19:51 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
>
> Please add a commit message explaining where it came from.
>

In v3 top comment in ast2500.dtsi file points to the source. Evb specific
parts and u-boot specific parts were added by me.


>
> > ---
> >
> >  arch/arm/dts/Makefile        |  2 ++
> >  arch/arm/dts/ast2500-evb.dts | 23 +++++++++++++++++++++++
> >  2 files changed, 25 insertions(+)
> >  create mode 100644 arch/arm/dts/ast2500-evb.dts
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> >
> > diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> > index f43746966c..1bee50e237 100644
> > --- a/arch/arm/dts/Makefile
> > +++ b/arch/arm/dts/Makefile
> > @@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
> >         bcm2836-rpi-2-b.dtb \
> >         bcm2837-rpi-3-b.dtb
> >
> > +dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
> > +
> >  targets += $(dtb-y)
> >
> >  # Add any required device tree compiler flags here
> > diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
> > new file mode 100644
> > index 0000000000..b1a415f7d7
> > --- /dev/null
> > +++ b/arch/arm/dts/ast2500-evb.dts
> > @@ -0,0 +1,23 @@
> > +/dts-v1/;
> > +
> > +#include "ast2500.dtsi"
> > +
> > +/ {
> > +       memory {
> > +               device_type = "memory";
> > +               reg = <0x80000000 0x20000000>;
> > +       };
> > +
> > +       chosen {
> > +               stdout-path = &uart5;
> > +       };
> > +};
> > +
> > +&uart5 {
> > +       u-boot,dm-pre-reloc;
>
> Consider putting this and any other U-Boot-specific things in a
> u-boot*.dtsi file if you have one.
>

This has been addressed in v3


>
> > +       status = "okay";
> > +};
> > +
> > +&sdrammc {
> > +       clock-frequency = <400000000>;
> > +};
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 20:02     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 20:02 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  include/configs/aspeed-common.h | 84 ++++++++++++++++++++++++++++++
> +++++++++++
> >  1 file changed, 84 insertions(+)
> >  create mode 100644 include/configs/aspeed-common.h
> >
> > diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-
> common.h
> > new file mode 100644
> > index 0000000000..c125e39e3f
> > --- /dev/null
> > +++ b/include/configs/aspeed-common.h
> > @@ -0,0 +1,84 @@
> > +/*
> > + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> > + * Ryan Chen <ryan_chen@aspeedtech.com>
> > + *
> > + * Copyright 2016 IBM Corporation
> > + * (C) Copyright 2016 Google, Inc
> > + *
> > + * SPDX-License-Identifier:     GPL-2.0+
> > + */
> > +
> > +#ifndef __AST_COMMON_CONFIG_H
> > +#define __AST_COMMON_CONFIG_H
> > +
> > +/* Misc CPU related */
> > +#define CONFIG_CMDLINE_TAG
> > +#define CONFIG_SETUP_MEMORY_TAGS
> > +#define CONFIG_INITRD_TAG
> > +
> > +#define CONFIG_CMDLINE_EDITING         1
>
> Drop the '1' from this
>
> > +
> > +/* Enable cache controller */
> > +#define CONFIG_SYS_DCACHE_OFF          1
>
> and this
>
> > +
> > +#ifdef CONFIG_PRE_CON_BUF_SZ
> > +#define PRE_CON_RAM_SZ         CONFIG_PRE_CON_BUF_SZ
> > +#else
> > +#define PRE_CON_RAM_SZ 0
> > +#endif
>
> What is this for?
>

This is a local variable to offset the INIT_RAM_ADDR and INIT_RAM_SIZE
below by
the size of the PRE_CON_BUF_SZ. I'll put it inline for v4.


>
> > +
> > +#define CONFIG_SYS_SDRAM_BASE          0x80000000
> > +#define CONFIG_SYS_INIT_RAM_ADDR       (0x1e720000 + PRE_CON_RAM_SZ)
> > +#define CONFIG_SYS_INIT_RAM_SIZE       (36*1024 - PRE_CON_RAM_SZ)
> > +#define SYS_INIT_RAM_END               (CONFIG_SYS_INIT_RAM_ADDR \
> > +                                        + CONFIG_SYS_INIT_RAM_SIZE)
> > +#define CONFIG_SYS_INIT_SP_ADDR                (SYS_INIT_RAM_END \
> > +                                        - GENERATED_GBL_DATA_SIZE)
> > +#define CONFIG_SYS_GBL_DATA_OFFSET     (CONFIG_SYS_INIT_RAM_SIZE \
> > +                                        - GENERATED_GBL_DATA_SIZE)
>
> Those last two should not be needed
>

It does not compile without CONFIG_SYS_INIT_SP_ADDR set.
CONFIG_SYS_GBL_DATA_OFFSET dropped for v4.


>
> > +
> > +#define CONFIG_NR_DRAM_BANKS           1
> > +
> > +#define CONFIG_SYS_TEXT_BASE           0x00000000
> > +
> > +#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
> > +
> > +/*
> > + * NS16550 Configuration
> > + */
> > +#define CONFIG_BAUDRATE                        115200
> > +
> > +/*
> > + * BOOTP options
> > + */
> > +#define CONFIG_BOOTP_BOOTFILESIZE
> > +#define CONFIG_BOOTP_BOOTPATH
> > +#define CONFIG_BOOTP_GATEWAY
> > +#define CONFIG_BOOTP_HOSTNAME
> > +#define CONFIG_BOOTP_SUBNETMASK
> > +
> > +/*
> > + * Miscellaneous configurable options
> > + */
> > +#define CONFIG_SYS_LONGHELP
> > +#define CONFIG_SYS_CBSIZE              256
> > +
> > +/* Print Buffer Size */
> > +#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE \
> > +                                        + sizeof(CONFIG_SYS_PROMPT) +
> 16)
> > +#define CONFIG_SYS_MAXARGS             16
> > +#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
> > +
> > +#define CONFIG_BOOTARGS \
> > +               "console=ttyS4,115200n8" \
> > +               " root=/dev/ram rw"
> > +
> > +#define CONFIG_BOOTCOMMAND             "bootm 20080000 20300000"
> > +#define CONFIG_ENV_OVERWRITE
> > +
> > +#define CONFIG_EXTRA_ENV_SETTINGS \
> > +       "verify=yes\0"  \
> > +       "spi_dma=yes\0" \
> > +       ""
> > +
> > +#endif /* __AST_COMMON_CONFIG_H */
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 20:17     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 20:17 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/mach-aspeed/Makefile        |  2 +-
> >  arch/arm/mach-aspeed/ast2500-board.c | 74
> ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 75 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
> >
> > diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/
> Makefile
> > index 1f7af71b03..9d29ff7f6f 100644
> > --- a/arch/arm/mach-aspeed/Makefile
> > +++ b/arch/arm/mach-aspeed/Makefile
> > @@ -5,4 +5,4 @@
> >  #
> >
> >  obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> > -obj-$(CONFIG_ASPEED_AST2500) += ast2500/
> > +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
> > diff --git a/arch/arm/mach-aspeed/ast2500-board.c
> b/arch/arm/mach-aspeed/ast2500-board.c
> > new file mode 100644
> > index 0000000000..5b2b0ce132
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/ast2500-board.c
> > @@ -0,0 +1,74 @@
> > +#include <common.h>
> > +#include <asm/arch/timer.h>
> > +#include <asm/arch/wdt.h>
> > +#include <asm/io.h>
> > +#include <dm.h>
> > +#include <dm/uclass.h>
> > +#include <linux/err.h>
> > +#include <ram.h>
> > +#include <timer.h>
>
> Check include file order.
>
> > +
> > +/* Second Watchdog Timer by default is configured
>
> /*
>  * Second watchdog...
>  * ...
>  */
>
> Please check globally. Try to use more columns if you can.
>
> > + * to trigger secondary boot source.
> > + */
> > +#define AST_2ND_BOOT_WDT               (1)
>
> Remove () around simple constants.
>
> > +
> > +/* Third Watchdog Timer by default is configured
> > + * to toggle Flash address mode switch before reset.
> > + */
> > +#define AST_FLASH_ADDR_DETECT_WDT      (2)
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +void lowlevel_init(void)
> > +{
> > +       /*
> > +        * These two watchdogs need to be stopped as soon as possible,
> > +        * otherwise the board might hang. By default they are set to
> > +        * a very short timeout and even simple debug write to serial
> > +        * console early in the init process might cause them to fire.
> > +        */
> > +       struct ast_wdt *flash_addr_wdt =
> > +           (struct ast_wdt *)(WDT_BASE +
> > +                              sizeof(struct ast_wdt) *
> > +                              AST_FLASH_ADDR_DETECT_WDT);
> > +
> > +       clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
> > +
> > +#ifndef CONFIG_FIRMWARE_2ND_BOOT
> > +       struct ast_wdt *sec_boot_wdt =
> > +           (struct ast_wdt *)(WDT_BASE +
> > +                              sizeof(struct ast_wdt) *
> > +                              AST_2ND_BOOT_WDT);
> > +
> > +       clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
> > +#endif
>
> Seems this should call a helper function in ast_wdt.c or similar.
>

I can't call wdt_stop() here, because that would require stack, which is
not yet available in lowlevel_init.

Other comments will be addressed for v4.


>
> > +}
> > +
> > +int board_init(void)
> > +{
> > +       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
>
> blank line
>
> > +       return 0;
> > +}
> > +
> > +int dram_init(void)
> > +{
> > +       struct udevice *dev;
> > +       int ret = uclass_get_device(UCLASS_RAM, 0, &dev);
>
> blank line, and better to separate decl and code in this case, since
> you check it below.
>
> > +       if (ret) {
> > +               debug("DRAM FAIL1\r\n");
> > +               return ret;
> > +       }
> > +
> > +       struct ram_info ram;
>
> move to top of function
>
> > +       ret = ram_get_info(dev, &ram);
> > +       if (ret) {
> > +               debug("DRAM FAIL2\r\n");
> > +               return ret;
> > +       }
> > +
>
> drop extra blank line
>
> > +
> > +       gd->ram_size = ram.size;
>
> blank line
>
> > +       return 0;
> > +}
> > +
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> REgards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-17 17:57     ` Maxim Sloyko
@ 2017-01-17 21:37       ` Simon Glass
  0 siblings, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-17 21:37 UTC (permalink / raw)
  To: u-boot

Hi Maxim,


On 17 January 2017 at 10:57, Maxim Sloyko <maxims@google.com> wrote:
>
> Hi Simon,
>
> This is older series, that I merged into a smaller number of patches and already addressed all of Tom's comments: http://lists.denx.de/pipermail/u-boot/2017-January/277883.html
>
> Most of your comments still apply, just want to make sure we are on the same page.

Yes that's fine, thanks.

- Simon
[snip]

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

* [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 22:27     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 22:27 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Helper function to get access to SCU (System Control Unit) through Clock
> > driver. This is similar to rockchip_get_cru function, which was used as
> > an example.
> >
> > It will be used by other drivers to get access to SCU.
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/mach-aspeed/Kconfig               |  2 ++
> >  arch/arm/mach-aspeed/Makefile              |  1 +
> >  arch/arm/mach-aspeed/ast2500/Kconfig       |  6 ++++++
> >  arch/arm/mach-aspeed/ast2500/Makefile      |  1 +
> >  arch/arm/mach-aspeed/ast2500/clk_ast2500.c | 31
> ++++++++++++++++++++++++++++++
> >  5 files changed, 41 insertions(+)
> >  create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
> >  create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
> >  create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
>
> The code seems fine.
>
> It seems odd that you have Kconfig changes here also. Why is that?
>

This was probably a mistake, looks like this does not apply to a series
with fewer patches.


>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-17 23:18     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 23:18 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > This driver is ast2500 specific and is not compatible with earlier
>
> ast2500-specific
>
> > versions of this chip. The differences are not that large, but they are
> > in somewhat random places, so making it compatible with ast2400 is not
> > worth the effort at the moment.
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 108 +++++++++++
> >  drivers/clk/Makefile                           |   2 +
> >  drivers/clk/aspeed/Makefile                    |   7 +
> >  drivers/clk/aspeed/clk_ast2500.c               | 255
> +++++++++++++++++++++++++
> >  4 files changed, 372 insertions(+)
> >  create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> >  create mode 100644 drivers/clk/aspeed/Makefile
> >  create mode 100644 drivers/clk/aspeed/clk_ast2500.c
> >
> > diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> > new file mode 100644
> > index 0000000000..febff9d2d3
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
> > @@ -0,0 +1,108 @@
> > +#ifndef _ASM_ARCH_SCU_AST2500_H
> > +#define _ASM_ARCH_SCU_AST2500_H
> > +
> > +#define SCU_UNLOCK_VALUE               0x1688a8a8
> > +
> > +#define SCU_HWSTRAP_VGAMEM_MASK                3
> > +#define SCU_HWSTRAP_VGAMEM_SHIFT       2
> > +#define SCU_HWSTRAP_DDR4               (1 << 24)
> > +#define SCU_HWSTRAP_CLKIN_25MHZ                (1 << 23)
> > +
> > +#define SCU_MPLL_DENUM_SHIFT           0
> > +#define SCU_MPLL_DENUM_MASK            0x1f
> > +#define SCU_MPLL_NUM_SHIFT             5
> > +#define SCU_MPLL_NUM_MASK              0xff
> > +#define SCU_MPLL_POST_SHIFT            13
> > +#define SCU_MPLL_POST_MASK             0x3f
> > +
> > +#define SCU_HPLL_DENUM_SHIFT           0
> > +#define SCU_HPLL_DENUM_MASK            0x1f
> > +#define SCU_HPLL_NUM_SHIFT             5
> > +#define SCU_HPLL_NUM_MASK              0xff
> > +#define SCU_HPLL_POST_SHIFT            13
> > +#define SCU_HPLL_POST_MASK             0x3f
> > +
> > +#define SCU_MISC2_UARTCLK_SHIFT                24
> > +
> > +#define SCU_MISC_UARTCLK_DIV13         (1 << 12)
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +struct ast2500_clk_priv {
> > +       struct ast2500_scu *scu;
> > +};
> > +
> > +struct ast2500_scu {
> > +       u32 protection_key;
> > +       u32 sysreset_ctrl1;
> > +       u32 clk_sel1;
> > +       u32 clk_stop_ctrl1;
> > +       u32 freq_counter_ctrl;
> > +       u32 freq_counter_cmp;
> > +       u32 intr_ctrl;
> > +       u32 d2_pll_param;
> > +       u32 m_pll_param;
> > +       u32 h_pll_param;
> > +       u32 d_pll_param;
> > +       u32 misc_ctrl1;
> > +       u32 pci_config[3];
> > +       u32 sysreset_status;
> > +       u32 vga_handshake[2];
> > +       u32 mac_clk_delay;
> > +       u32 misc_ctrl2;
> > +       u32 vga_scratch[8];
> > +       u32 hwstrap;
> > +       u32 rng_ctrl;
> > +       u32 rng_data;
> > +       u32 rev_id;
> > +       u32 pinmux_ctrl[6];
> > +       u32 reserved0;
> > +       u32 extrst_sel;
> > +       u32 pinmux_ctrl1[4];
> > +       u32 reserved1[2];
> > +       u32 mac_clk_delay_100M;
> > +       u32 mac_clk_delay_10M;
> > +       u32 wakeup_enable;
> > +       u32 wakeup_control;
> > +       u32 reserved2[3];
> > +       u32 sysreset_ctrl2;
> > +       u32 clk_sel2;
> > +       u32 clk_stop_ctrl2;
> > +       u32 freerun_counter;
> > +       u32 freerun_counter_ext;
> > +       u32 clk_duty_meas_ctrl;
> > +       u32 clk_duty_meas_res;
> > +       u32 reserved3[4];
> > +       /* The next registers are not key protected */
>
> key-protected
>

Fixed.


>
> > +       struct ast2500_cpu2 {
> > +               u32 ctrl;
> > +               u32 base_addr[9];
> > +               u32 cache_ctrl;
> > +       } cpu2;
> > +       u32 reserved4;
> > +       u32 d_pll_ext_param[3];
> > +       u32 d2_pll_ext_param[3];
> > +       u32 mh_pll_ext_param;
> > +       u32 reserved5;
> > +       u32 chip_id[2];
> > +       u32 reserved6[2];
> > +       u32 uart_clk_ctrl;
> > +       u32 reserved7[7];
> > +       u32 pcie_config;
> > +       u32 mmio_decode;
> > +       u32 reloc_ctrl_decode[2];
> > +       u32 mailbox_addr;
> > +       u32 shared_sram_decode[2];
> > +       u32 bmc_rev_id;
> > +       u32 reserved8;
> > +       u32 bmc_device_id;
> > +       u32 reserved9[13];
> > +       u32 clk_duty_sel;
> > +};
> > +
> > +int ast_get_clk(struct udevice **devp);
> > +void *ast_get_scu(void);
>
> Function comments please.
>

Fixed.


>
> > +
> > +#endif  /* __ASSEMBLY__ */
> > +
> > +#endif  /* _ASM_ARCH_SCU_AST2500_H */
> > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> > index 40a5e8cae8..625513789c 100644
> > --- a/drivers/clk/Makefile
> > +++ b/drivers/clk/Makefile
> > @@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
> >  obj-$(CONFIG_CLK_EXYNOS) += exynos/
> >  obj-$(CONFIG_CLK_AT91) += at91/
> >  obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
> > +
> > +obj-$(CONFIG_ARCH_ASPEED) += aspeed/
> > diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
> > new file mode 100644
> > index 0000000000..65d1cd6e29
> > --- /dev/null
> > +++ b/drivers/clk/aspeed/Makefile
> > @@ -0,0 +1,7 @@
> > +#
> > +# Copyright (c) 2016 Google, Inc
> > +#
> > +# SPDX-License-Identifier:      GPL-2.0+
> > +#
> > +
> > +obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
> > diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_
> ast2500.c
> > new file mode 100644
> > index 0000000000..c888a6d35b
> > --- /dev/null
> > +++ b/drivers/clk/aspeed/clk_ast2500.c
> > @@ -0,0 +1,255 @@
> > +/*
> > + * (C) Copyright 2016 Google, Inc
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0
> > + */
> > +
> > +#include <common.h>
> > +#include <asm/arch/scu_ast2500.h>
> > +#include <asm/io.h>
> > +#include <clk-uclass.h>
> > +#include <dm.h>
> > +#include <dm/lists.h>
> > +#include <dt-bindings/clock/ast2500-scu.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +/*
> > + * For H-PLL and M-PLL the formula is
> > + * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
> > + * M - Numerator
> > + * N - Denumerator
> > + * P - Post Divider
> > + * They have the same layout in their control register.
> > + */
> > +
> > +/*
> > + * Get the rate of the M-PLL clock from input clock frequency and
> > + * the value of the M-PLL Parameter Register.
> > + */
> > +static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
> > +{
> > +       const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) &
> SCU_MPLL_NUM_MASK;
> > +       const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
> > +                       & SCU_MPLL_DENUM_MASK;
> > +       const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
> > +                       & SCU_MPLL_POST_MASK;
> > +
> > +       return (clkin * ((num + 1) / (denum + 1))) / post_div;
> > +}
> > +
> > +/*
> > + * Get the rate of the H-PLL clock from input clock frequency and
> > + * the value of the H-PLL Parameter Register.
> > + */
> > +static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
> > +{
> > +       const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) &
> SCU_HPLL_NUM_MASK;
> > +       const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
> > +                       & SCU_HPLL_DENUM_MASK;
> > +       const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
> > +                       & SCU_HPLL_POST_MASK;
> > +
> > +       return (clkin * ((num + 1) / (denum + 1))) / post_div;
> > +}
> > +
> > +static ulong ast2500_get_clkin(struct ast2500_scu *scu)
> > +{
> > +       return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
> > +                       ? 25*1000*1000 : 24*1000*1000;
>
> Spaces around *
>

Fixed.


>
> > +}
> > +
> > +static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int
> uart)
>
> Function comment. What is 'uart' for?
>

Fixed. Renamed uart to uart_index to be more clear about its purpose.


>
> > +{
> > +       /*
> > +        * ast2500 datasheet is very confusing when it comes to UART
> clocks,
> > +        * especially when CLKIN = 25 MHz. The settings are in
> > +        * different registers and it is unclear how they interact.
> > +        *
> > +        * This has only been tested with default settings and CLKIN =
> 24 MHz.
>
> Can you detect this and return -EINVAL if it can't work? If not, that's
> fine.
>

I can detect if CLKIN = 24 MHz or 25 MHz, but it's not clear what UART
input clock rate is for CLKIN = 25MHz
There is a setting (on by default) to generate UART 24MHz clock from 25MHz,
but there are also somewhat
conflicting settings for dividers.

I don't have access to 25MHz based hardware to test this at the moment, all
our boards use 24MHz crystal.


>
> > +        */
> > +       ulong uart_clkin;
> > +
> > +       if (readl(&scu->misc_ctrl2) & (1 << (uart +
> SCU_MISC2_UARTCLK_SHIFT)))
> > +               uart_clkin = 192 * 1000 * 1000;
> > +       else
> > +               uart_clkin = 24 * 1000 * 1000;
> > +
> > +       if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
> > +               uart_clkin /= 13;
> > +
> > +       return uart_clkin;
> > +}
> > +
> > +static ulong ast2500_clk_get_rate(struct clk *clk)
> > +{
> > +       struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
> > +       ulong clkin = ast2500_get_clkin(priv->scu);
> > +       ulong rate;
> > +
> > +       switch (clk->id) {
> > +       case PLL_HPLL:
> > +       case ARMCLK:
> > +               /*
> > +                * This ignores dynamic/static slowdown of ARMCLK and may
> > +                * be inaccurate.
> > +                */
> > +               rate = ast2500_get_hpll_rate(clkin,
> > +
> readl(&priv->scu->h_pll_param));
> > +               break;
> > +       case MCLK_DDR:
> > +               rate = ast2500_get_mpll_rate(clkin,
> > +
> readl(&priv->scu->m_pll_param));
> > +               break;
> > +       case PCLK_UART1:
> > +               rate = ast2500_get_uart_clk_rate(priv->scu, 1);
> > +               break;
> > +       case PCLK_UART2:
> > +               rate = ast2500_get_uart_clk_rate(priv->scu, 2);
> > +               break;
> > +       case PCLK_UART3:
> > +               rate = ast2500_get_uart_clk_rate(priv->scu, 3);
> > +               break;
> > +       case PCLK_UART4:
> > +               rate = ast2500_get_uart_clk_rate(priv->scu, 4);
> > +               break;
> > +       case PCLK_UART5:
> > +               rate = ast2500_get_uart_clk_rate(priv->scu, 5);
> > +               break;
> > +       default:
> > +               return -ENOENT;
> > +       }
> > +
> > +       return rate;
> > +}
> > +
> > +static void ast2500_scu_unlock(struct ast2500_scu *scu)
> > +{
> > +       writel(SCU_UNLOCK_VALUE, &scu->protection_key);
> > +       while (!readl(&scu->protection_key))
> > +               ;
>
> Can this ever timeout?
>

Not according to the datasheet.


>
> > +}
> > +
> > +static void ast2500_scu_lock(struct ast2500_scu *scu)
> > +{
> > +       writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
> > +       while (readl(&scu->protection_key))
> > +               ;
> > +}
> > +
> > +static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
> > +{
> > +       ulong clkin = ast2500_get_clkin(scu);
> > +       u32 mpll_reg;
> > +
> > +       /*
> > +        * There are not that many combinations of numerator, denumerator
> > +        * and post divider, so just brute force the best combination.
> > +        * However, to avoid overflow when multiplying, use kHz.
> > +        */
> > +       const ulong clkin_khz = clkin / 1000;
> > +       const ulong rate_khz = rate / 1000;
> > +
>
> drop blank line
>
> > +       ulong best_num = 0;
> > +       ulong best_denum = 0;
> > +       ulong best_post = 0;
> > +       ulong delta = rate;
> > +
>
> drop blank line
>
> > +       ulong num, denum, post;
>
> add blank line
>
> > +       for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
> > +               for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
> > +                       num = (rate_khz * (post + 1) / clkin_khz) *
> (denum + 1);
> > +                       ulong new_rate_khz = (clkin_khz
> > +                                             * ((num + 1) / (denum +
> 1)))
> > +                                            / (post + 1);
> > +
> > +                       /* Keep the rate below requested one. */
> > +                       if (new_rate_khz > rate_khz)
> > +                               continue;
> > +
> > +                       if (new_rate_khz - rate_khz < delta) {
> > +                               delta = new_rate_khz - rate_khz;
> > +
> > +                               best_num = num;
> > +                               best_denum = denum;
> > +                               best_post = post;
> > +
> > +                               if (delta == 0)
> > +                                       goto rate_calc_done;
> > +                       }
> > +               }
> > +       }
> > +
> > + rate_calc_done:
>
> Drop blank line
>
> Can it fail? Do you need to check delta?
>

I just check delta for an early exit, if we found a match.
It returns the best approximation for target rate we could achieve and it
can fail
in a sense that this approximation might not be good enough. In which case
DDR init will fail --
I tried to play with the configured rate during development and that's how
failure manifested itself.
However, I don't know any way of verifying the rate in advance.


>
> > +
> > +       mpll_reg = readl(&scu->m_pll_param);
> > +       mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
> > +                     | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
> > +                     | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
> > +       mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
> > +           | (best_num << SCU_MPLL_NUM_SHIFT)
> > +           | (best_denum << SCU_MPLL_DENUM_SHIFT);
> > +
> > +       ast2500_scu_unlock(scu);
> > +       writel(mpll_reg, &scu->m_pll_param);
> > +       ast2500_scu_lock(scu);
> > +
> > +       return ast2500_get_mpll_rate(clkin, mpll_reg);
> > +}
> > +
> > +static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
> > +{
> > +       struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
> > +
> > +       ulong new_rate;
> > +       switch (clk->id) {
> > +       case PLL_MPLL:
> > +       case MCLK_DDR:
> > +               new_rate = ast2500_configure_ddr(priv->scu, rate);
> > +               break;
> > +       default:
> > +               return -ENOENT;
> > +       }
> > +
> > +       return new_rate;
> > +}
> > +
> > +struct clk_ops ast2500_clk_ops = {
> > +       .get_rate = ast2500_clk_get_rate,
> > +       .set_rate = ast2500_clk_set_rate,
> > +};
> > +
> > +static int ast2500_clk_probe(struct udevice *dev)
> > +{
> > +       struct ast2500_clk_priv *priv = dev_get_priv(dev);
>
> blank line
>

Done.


>
> > +       priv->scu = (struct ast2500_scu *)dev_get_addr(dev);
>
> Maybe dev_get_addr_ptr()
>
> Also should check that it is not FDT_ADDR_NONE.
>

Done.


>
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast2500_clk_bind(struct udevice *dev)
> > +{
> > +       int ret;
> > +
> > +       /* The reset driver does not have a device node, so bind it here
> */
> > +       ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset",
> &dev);
> > +       if (ret)
> > +               debug("Warning: No reset driver: ret=%d\n", ret);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct udevice_id ast2500_clk_ids[] = {
> > +       { .compatible = "aspeed,ast2500-scu" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(aspeed_ast2500_scu) = {
> > +       .name           = "aspeed_ast2500_scu",
> > +       .id             = UCLASS_CLK,
> > +       .of_match       = ast2500_clk_ids,
> > +       .priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
> > +       .ops            = &ast2500_clk_ops,
> > +       .bind           = ast2500_clk_bind,
> > +       .probe          = ast2500_clk_probe,
> > +};
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-14 17:13           ` Simon Glass
@ 2017-01-17 23:27             ` Maxim Sloyko
  2017-01-21  3:52               ` Simon Glass
  0 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 23:27 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 5 January 2017 at 15:20, Maxim Sloyko <maxims@google.com> wrote:
> > On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
> >> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
> >>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
> >>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
> >>> >
> >>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
> >>> >> ---
> >>> >>
> >>> >>  arch/arm/dts/ast2500.dtsi               | 423
> ++++++++++++++++++++++++++++++++
> >>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
> >>> >>  2 files changed, 452 insertions(+)
> >>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
> >>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
> >>> >>
> >>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
> >>> >> new file mode 100644
> >>> >> index 0000000000..1a2a3f7ee3
> >>> >> --- /dev/null
> >>> >> +++ b/arch/arm/dts/ast2500.dtsi
> >>> >> @@ -0,0 +1,423 @@
> >>> >> +/* This device tree is copied from
> >>> >> + * https://github.com/openbmc/linux/blob/c5682cb/arch/arm/
> boot/dts/aspeed-g5.dtsi
> >>> >
> >>> > Is this also found in the Linux kernel or not yet?  Thanks!
> >>>
> >>> Yes, this is also in in main Linux kernel now, as I've found out, but
> >>> actually there is a number of differences, most notably there is no
> >>> pin configuration in this device tree, because there is no pinctrl
> >>> driver.
> >
> > Actually, I take that back, I was looking at the wrong linux Linux
> > kernel tree still... Only basic version of device tree has made it to
> > mainline kernel, but it's enough at the moment, so I used that
> > instead.
> >
> >>>
> >>> Should I remove this reference or modify it?
> >>
> >> Ideally, we will take the kernel dts files and then add what we need on
> >> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
> >> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
> >> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
> >
> > OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
> > added modifications in ast2500-u-boot.dtsi and now include
> > ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
> > you.
>
> There is some magic in the Makefile which automatically includes the
> .dtsi if you name it correctly:
>
> # Try these files in order to find the U-Boot-specific .dtsi include file
> u_boot_dtsi_options = $(wildcard $(dts_dir)/$(basename $(notdir
> $<))-u-boot.dtsi) \
> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_SOC))-u-boot.dtsi) \
> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_CPU))-u-boot.dtsi) \
> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_VENDOR))-u-boot.dtsi) \
> $(wildcard $(dts_dir)/u-boot.dtsi)
>
>
> So you should not need to include it explicitly.
>

Well, it looks like the only applicable for this case would be
CONFIG_SYS_SOC, but it looks like this setting also affects the mach- and
arch- directories used. In this case I want different aspeed SoCs to share
those directories, but
they will have different DTs.


>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 03/12] aspeed: Add Timer Support
  2017-01-14 17:13   ` Simon Glass
  2017-01-17 17:57     ` Maxim Sloyko
@ 2017-01-17 23:59     ` Maxim Sloyko
  1 sibling, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-17 23:59 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Add support for timer for Aspeed ast2400/ast2500 devices.
> > The driver actually controls several devices, but because all devices
> > share the same Control Register, it is somewhat difficult to completely
> > decouple them. Since only one timer is needed at the moment, this should
> > be OK.
> >
> > The timer uses fixed clock, so does not rely on a clock driver.
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/include/asm/arch-aspeed/timer.h | 54 ++++++++++++++++++
> >  drivers/timer/Kconfig                    |  7 +++
> >  drivers/timer/Makefile                   |  1 +
> >  drivers/timer/ast_timer.c                | 96
> ++++++++++++++++++++++++++++++++
> >  4 files changed, 158 insertions(+)
> >  create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
> >  create mode 100644 drivers/timer/ast_timer.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> nits below.
>
> >
> > diff --git a/arch/arm/include/asm/arch-aspeed/timer.h
> b/arch/arm/include/asm/arch-aspeed/timer.h
> > new file mode 100644
> > index 0000000000..87c5b354ec
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-aspeed/timer.h
> > @@ -0,0 +1,54 @@
> > +/*
> > + * Copyright (c) 2016 Google, Inc
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0+
> > + */
> > +#ifndef _ASM_ARCH_TIMER_H
> > +#define _ASM_ARCH_TIMER_H
> > +
> > +/* Each timer has 4 control bits in ctrl1 register.
> > + * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
> > + * such that timer X uses bits (4 * X - 4):(4 * X - 1)
> > + * If the timer does not support PWM, bit 4 is reserved.
> > + */
> > +#define AST_TMC_EN                     (1 << 0)
> > +#define AST_TMC_1MHZ                   (1 << 1)
> > +#define AST_TMC_OVFINTR                        (1 << 2)
> > +#define AST_TMC_PWM                    (1 << 3)
> > +
> > +/* Timers are counted from 1 in the datasheet. */
> > +#define AST_TMC_CTRL1_SHIFT(n)                 (4 * ((n) - 1))
> > +
> > +#define AST_TMC_RATE  (1000*1000)
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +/*
> > + * All timers share control registers, which makes it harder to make
> them
> > + * separate devices. Since only one timer is needed at the moment,
> making
> > + * it this just one device.
> > + */
> > +
> > +struct ast_timer_counter {
> > +       u32 status;
> > +       u32 reload_val;
> > +       u32 match1;
> > +       u32 match2;
> > +};
> > +
> > +struct ast_timer {
> > +       struct ast_timer_counter timers1[3];
> > +       u32 ctrl1;
> > +       u32 ctrl2;
> > +#ifdef CONFIG_ASPEED_AST2500
> > +       u32 ctrl3;
> > +       u32 ctrl1_clr;
> > +#else
> > +       u32 reserved[2];
> > +#endif
> > +       struct ast_timer_counter timers2[5];
> > +};
> > +
> > +#endif  /* __ASSEMBLY__ */
> > +
> > +#endif  /* _ASM_ARCH_TIMER_H */
> > diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> > index cb18f12fc9..9c5f98bb88 100644
> > --- a/drivers/timer/Kconfig
> > +++ b/drivers/timer/Kconfig
> > @@ -46,4 +46,11 @@ config OMAP_TIMER
> >         help
> >           Select this to enable an timer for Omap devices.
> >
> > +config AST_TIMER
> > +       bool "Aspeed ast2400/ast2500 timer support"
> > +       depends on TIMER
> > +       default y if ARCH_ASPEED
> > +       help
> > +         Select this to enable timer for Aspeed ast2400/ast2500 devices.
>
> Can you add more detail? How many channels? What features are
> supported by the driver?
>

Expanded the description.


>
> > +
> >  endmenu
> > diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> > index f351fbb4e0..a4b1a486b0 100644
> > --- a/drivers/timer/Makefile
> > +++ b/drivers/timer/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)      += altera_timer.o
> >  obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
> >  obj-$(CONFIG_X86_TSC_TIMER)    += tsc_timer.o
> >  obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
> > +obj-$(CONFIG_AST_TIMER)        += ast_timer.o
> > diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
> > new file mode 100644
> > index 0000000000..f644882f40
> > --- /dev/null
> > +++ b/drivers/timer/ast_timer.c
> > @@ -0,0 +1,96 @@
> > +/*
> > + * Copyright 2016 Google Inc.
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0+
> > + */
> > +
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <errno.h>
> > +#include <timer.h>
> > +#include <asm/io.h>
> > +#include <asm/arch/timer.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +#define AST_TICK_TIMER  1
> > +#define AST_TMC_RELOAD_VAL  0xffffffff
> > +
> > +struct ast_timer_priv {
> > +       struct ast_timer *regs;
> > +};
> > +
> > +static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer
> *timer,
> > +                                                      int n)
> > +{
> > +       if (n > 3)
> > +               return &timer->timers2[n - 4];
> > +       else
> > +               return &timer->timers1[n - 1];
> > +}
> > +
> > +static int ast_timer_probe(struct udevice *dev)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->
> regs,
> > +
>  AST_TICK_TIMER);
>
> I suppose tmc could be in your struct ast_timer_priv to save you doing
> this each time?
>

Fixed.


>
> > +       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> > +
> > +       writel(AST_TMC_RELOAD_VAL, &tmc->reload_val);
> > +
> > +       /*
> > +        * Stop the timer. This will also load reload_val into
> > +        * the status register.
> > +        */
> > +       clrbits_le32(&priv->regs->ctrl1,
> > +                    AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> > +       /* Start the timer from the fixed 1MHz clock. */
> > +       setbits_le32(&priv->regs->ctrl1,
> > +                    (AST_TMC_EN | AST_TMC_1MHZ) <<
> > +                    AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> > +
> > +       uc_priv->clock_rate = AST_TMC_RATE;
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast_timer_get_count(struct udevice *dev, u64 *count)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +       struct ast_timer_counter *tmc = ast_get_timer_counter(priv->
> regs,
> > +
>  AST_TICK_TIMER);
> > +
> > +       *count = AST_TMC_RELOAD_VAL - readl(&tmc->status);
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast_timer_ofdata_to_platdata(struct udevice *dev)
> > +{
> > +       struct ast_timer_priv *priv = dev_get_priv(dev);
> > +
> > +       priv->regs = (struct ast_timer *)dev_get_addr(dev);
>
> You can use dev_get_addr_ptr() if you like.
>

Done.


>
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct timer_ops ast_timer_ops = {
> > +       .get_count = ast_timer_get_count,
> > +};
> > +
> > +static const struct udevice_id ast_timer_ids[] = {
> > +       { .compatible = "aspeed,ast2500-timer" },
> > +       { .compatible = "aspeed,ast2400-timer" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(sandbox_timer) = {
>
> s/sandbox/ast/ or something, as Tom, mentioned.
>

Addressed earlier.


>
> > +       .name = "ast_timer",
> > +       .id = UCLASS_TIMER,
> > +       .of_match = ast_timer_ids,
> > +       .probe = ast_timer_probe,
> > +       .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
> > +       .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
> > +       .ops = &ast_timer_ops,
> > +       .flags = DM_FLAG_PRE_RELOC,
> > +};
> > --
> > 2.11.0.390.gc69c2f50cf-goog
>
> Regards,
> Simon
>
> >
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig
  2017-01-14 17:13   ` Simon Glass
@ 2017-01-18  0:15     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18  0:15 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/Kconfig              |  7 +++++++
> >  arch/arm/Makefile             |  1 +
> >  arch/arm/mach-aspeed/Kconfig  | 15 +++++++++++++++
> >  arch/arm/mach-aspeed/Makefile |  8 ++++++++
> >  4 files changed, 31 insertions(+)
> >  create mode 100644 arch/arm/mach-aspeed/Kconfig
> >  create mode 100644 arch/arm/mach-aspeed/Makefile
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 714dd8b514..135c544335 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
> >         select OF_CONTROL
> >         select SYS_CACHE_SHIFT_7
> >
> > +config ARCH_ASPEED
> > +       bool "Support Aspeed SoCs"
> > +       select OF_CONTROL
> > +       select DM
> > +
> >  endchoice
> >
> > +source "arch/arm/mach-aspeed/Kconfig"
> > +
> >  source "arch/arm/mach-at91/Kconfig"
> >
> >  source "arch/arm/mach-bcm283x/Kconfig"
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index 236debb452..cc73e1038e 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
> >
> >  # Machine directory name.  This list is sorted alphanumerically
> >  # by CONFIG_* macro name.
> > +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
> >  machine-$(CONFIG_ARCH_AT91)            += at91
> >  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
> >  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
> > diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> > new file mode 100644
> > index 0000000000..43cdbeda84
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/Kconfig
> > @@ -0,0 +1,15 @@
> > +if ARCH_ASPEED
> > +
> > +config SYS_ARCH
> > +       default "arm"
> > +
> > +config SYS_SOC
> > +       default "aspeed"
> > +
> > +config ASPEED_AST2500
> > +       bool "Support Aspeed AST2500 SoC"
> > +       select CPU_ARM1176
> > +       help
> > +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU
>
> Can you please expand this a bit? E.g. a summary of peripherals it
> has, what the chip is used for...
>

With 47 different types of peripherals it has, that would be a pretty big
summary :)
I expanded it to say that this is a BMC.


> > +
> > +endif
> > diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/
> Makefile
> > new file mode 100644
> > index 0000000000..8e276b4a9f
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/Makefile
> > @@ -0,0 +1,8 @@
> > +#
> > +# Copyright (c) 2014 Google, Inc
> > +#
> > +# SPDX-License-Identifier:     GPL-2.0+
> > +#
> > +
> > +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> > +obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver
  2017-01-14 17:14   ` Simon Glass
@ 2017-01-18 20:16     ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 20:16 UTC (permalink / raw)
  To: u-boot

On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:

> Hi Maxim,
>
> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
> > The driver is very ast2500 specific and is completely incompatible
>
> ast2500-specific
>
> > with previous versions of the chip.
> >
> > The memory controller is very poorly documented by Aspeed in the
> > datasheet, with any mention of the whole range of registers missing. The
> > initialization procedure has been basically taken from Aspeed SDK, where
> > it is implemented in assembly and rewritten in C, with very limited
> > understanding of what exacly it is doing.
>
> Here I think you mean:
> where
>  it is implemented in assembly. Here it is rewritten in C, with very
> limited
>  understanding of what exactly (spelling) it is doing.
>

Fixed the message.


>
>
> >
> > Signed-off-by: Maxim Sloyko <maxims@google.com>
> > ---
> >
> >  arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 133 +++++++
> >  arch/arm/mach-aspeed/ast2500/Makefile            |   2 +-
> >  arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 443
> +++++++++++++++++++++++
> >  3 files changed, 577 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> >  create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> >
> > diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> > new file mode 100644
> > index 0000000000..ca70898df6
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
> > @@ -0,0 +1,133 @@
> > +#ifndef _ASM_ARCH_SDRAM_AST2500_H
> > +#define _ASM_ARCH_SDRAM_AST2500_H
> > +
> > +#define SDRAM_UNLOCK_KEY               0xfc600309
> > +#define SDRAM_VIDEO_UNLOCK_KEY         0x2003000f
> > +
> > +#define SDRAM_PCR_CKE_EN               (1 << 0)
> > +#define SDRAM_PCR_AUTOPWRDN_EN         (1 << 1)
> > +#define SDRAM_PCR_CKE_DELAY_SHIFT      4
> > +#define SDRAM_PCR_CKE_DELAY_MASK       7
> > +#define SDRAM_PCR_RESETN_DIS           (1 << 7)
> > +#define SDRAM_PCR_ODT_EN               (1 << 8)
> > +#define SDRAM_PCR_ODT_AUTO_ON          (1 << 10)
> > +#define SDRAM_PCR_ODT_EXT_EN           (1 << 11)
> > +#define SDRAM_PCR_TCKE_PW_SHIFT                12
> > +#define SDRAM_PCR_TCKE_PW_MASK         7
> > +#define SDRAM_PCR_RGAP_CTRL_EN         (1 << 15)
> > +#define SDRAM_PCR_MREQI_DIS            (1 << 17)
> > +
> > +/* Fixed priority DRAM Requests mask */
> > +#define SDRAM_REQ_VGA_HW_CURSOR                (1 << 0)
> > +#define SDRAM_REQ_VGA_TEXT_CG_FONT     (1 << 1)
> > +#define SDRAM_REQ_VGA_TEXT_ASCII       (1 << 2)
> > +#define SDRAM_REQ_VGA_CRT              (1 << 3)
> > +#define SDRAM_REQ_SOC_DC_CURSOR                (1 << 4)
> > +#define SDRAM_REQ_SOC_DC_OCD           (1 << 5)
> > +#define SDRAM_REQ_SOC_DC_CRT           (1 << 6)
> > +#define SDRAM_REQ_VIDEO_HIPRI_WRITE    (1 << 7)
> > +#define SDRAM_REQ_USB20_EHCI1          (1 << 8)
> > +#define SDRAM_REQ_USB20_EHCI2          (1 << 9)
> > +#define SDRAM_REQ_CPU                  (1 << 10)
> > +#define SDRAM_REQ_AHB2                 (1 << 11)
> > +#define SDRAM_REQ_AHB                  (1 << 12)
> > +#define SDRAM_REQ_MAC0                 (1 << 13)
> > +#define SDRAM_REQ_MAC1                 (1 << 14)
> > +#define SDRAM_REQ_PCIE                 (1 << 16)
> > +#define SDRAM_REQ_XDMA                 (1 << 17)
> > +#define SDRAM_REQ_ENCRYPTION           (1 << 18)
> > +#define SDRAM_REQ_VIDEO_FLAG           (1 << 21)
> > +#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE  (1 << 28)
> > +#define SDRAM_REQ_2D_RW                        (1 << 29)
> > +#define SDRAM_REQ_MEMCHECK             (1 << 30)
> > +
> > +#define SDRAM_ICR_RESET_ALL            (1 << 31)
> > +
> > +#define SDRAM_CONF_CAP_SHIFT           0
> > +#define SDRAM_CONF_CAP_MASK            3
> > +#define SDRAM_CONF_DDR4                        (1 << 4)
> > +#define SDRAM_CONF_SCRAMBLE            (1 << 8)
> > +#define SDRAM_CONF_SCRAMBLE_PAT2       (1 << 9)
> > +#define SDRAM_CONF_CACHE_EN            (1 << 10)
> > +#define SDRAM_CONF_CACHE_INIT_EN       (1 << 12)
> > +#define SDRAM_CONF_DUALX8              (1 << 13)
> > +#define SDRAM_CONF_CACHE_INIT_DONE     (1 << 19)
> > +
> > +#define SDRAM_CONF_CAP_128M            0
> > +#define SDRAM_CONF_CAP_256M            1
> > +#define SDRAM_CONF_CAP_512M            2
> > +#define SDRAM_CONF_CAP_1024M           3
> > +
> > +#define SDRAM_MISC_DDR4_TREFRESH       (1 << 3)
> > +
> > +#define SDRAM_PHYCTRL0_INIT            (1 << 0)
> > +#define SDRAM_PHYCTRL0_AUTO_UPDATE     (1 << 1)
> > +#define SDRAM_PHYCTRL0_NRST            (1 << 2)
> > +
> > +#define SDRAM_REFRESH_CYCLES_SHIFT     0
> > +#define SDRAM_REFRESH_CYCLES_MASK      0xf
> > +#define SDRAM_REFRESH_ZQCS_EN          (1 << 7)
> > +#define SDRAM_REFRESH_PERIOD_SHIFT     8
> > +#define SDRAM_REFRESH_PERIOD_MASK      0xf
> > +
> > +#define SDRAM_TEST_LEN_SHIFT           4
> > +#define SDRAM_TEST_LEN_MASK            0xfffff
> > +#define SDRAM_TEST_START_ADDR_SHIFT    24
> > +#define SDRAM_TEST_START_ADDR_MASK     0x3f
> > +
> > +#define SDRAM_TEST_EN                  (1 << 0)
> > +#define SDRAM_TEST_MODE_SHIFT          1
> > +#define SDRAM_TEST_MODE_MASK           3
> > +#define SDRAM_TEST_MODE_WO             0
> > +#define SDRAM_TEST_MODE_RB             1
> > +#define SDRAM_TEST_MODE_RW             2
> > +#define SDRAM_TEST_GEN_MODE_SHIFT      3
> > +#define SDRAM_TEST_GEN_MODE_MASK       7
> > +#define SDRAM_TEST_TWO_MODES           (1 << 6)
> > +#define SDRAM_TEST_ERRSTOP             (1 << 7)
> > +#define SDRAM_TEST_DONE                        (1 << 12)
> > +#define SDRAM_TEST_FAIL                        (1 << 13)
> > +
> > +#define SDRAM_AC_TRFC_SHIFT            0
> > +#define SDRAM_AC_TRFC_MASK             0xff
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +struct ast2500_sdrammc_regs {
> > +       u32 protection_key;
> > +       u32 config;
> > +       u32 gm_protection_key;
> > +       u32 refresh_timing;
> > +       u32 ac_timing[3];
> > +       u32 misc_control;
> > +       u32 mr46_mode_setting;
> > +       u32 mr5_mode_setting;
> > +       u32 mode_setting_control;
> > +       u32 mr02_mode_setting;
> > +       u32 mr13_mode_setting;
> > +       u32 power_control;
> > +       u32 req_limit_mask;
> > +       u32 pri_group_setting;
> > +       u32 max_grant_len[4];
> > +       u32 intr_ctrl;
> > +       u32 ecc_range_ctrl;
> > +       u32 first_ecc_err_addr;
> > +       u32 last_ecc_err_addr;
> > +       u32 phy_ctrl[4];
> > +       u32 ecc_test_ctrl;
> > +       u32 test_addr;
> > +       u32 test_fail_dq_bit;
> > +       u32 test_init_val;
> > +       u32 phy_debug_ctrl;
> > +       u32 phy_debug_data;
> > +       u32 reserved1[30];
> > +       u32 scu_passwd;
> > +       u32 reserved2[7];
> > +       u32 scu_mpll;
> > +       u32 reserved3[19];
> > +       u32 scu_hwstrap;
> > +};
> > +
> > +#endif  /* __ASSEMBLY__ */
> > +
> > +#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
> > diff --git a/arch/arm/mach-aspeed/ast2500/Makefile
> b/arch/arm/mach-aspeed/ast2500/Makefile
> > index 97d4078ddd..a35b239ef3 100644
> > --- a/arch/arm/mach-aspeed/ast2500/Makefile
> > +++ b/arch/arm/mach-aspeed/ast2500/Makefile
> > @@ -1 +1 @@
> > -obj-y += clk_ast2500.o
> > +obj-y += clk_ast2500.o sdram_ast2500.o
> > diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> > new file mode 100644
> > index 0000000000..da25756e94
> > --- /dev/null
> > +++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
> > @@ -0,0 +1,443 @@
> > +/*
> > + * Copyright (C) 2012-2020  ASPEED Technology Inc.
> > + *
> > + * Copyright 2016 Google, Inc
> > + *
> > + * SPDX-License-Identifier:            GPL-2.0
> > + */
> > +
> > +#include <common.h>
> > +#include <clk.h>
> > +#include <dm.h>
> > +#include <dt-bindings/clock/ast2500-scu.h>
> > +#include <errno.h>
> > +#include <ram.h>
> > +#include <asm/io.h>
> > +#include <asm/arch/scu_ast2500.h>
> > +#include <asm/arch/sdram_ast2500.h>
> > +#include <asm/arch/wdt.h>
> > +#include <linux/err.h>
> > +#include <linux/kernel.h>
> > +#include <regmap.h>
>
> Check ordering: http://www.denx.de/wiki/U-Boot/CodingStyle


Done


>
>
> > +
> > +/* These configuration parameters are taken from Aspeed SDK */
> > +#define DDR4_MR46_MODE         0x08000000
> > +#define DDR4_MR5_MODE          0x400
> > +#define DDR4_MR13_MODE         0x101
> > +#define DDR4_MR02_MODE         0x410
> > +#define DDR4_TRFC              0x45457188
> > +
> > +#define PHY_CFG_SIZE           15
> > +
> > +static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99,
> 0x00019000};
> > +static const struct {
> > +       u32 index[PHY_CFG_SIZE];
> > +       u32 value[PHY_CFG_SIZE];
> > +} ddr4_phy_config = {
> > +       .index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
> > +       .value = {
> > +               0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
> > +               0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106,
> 0x08080607,
> > +               0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c,
> 0x00631e0e,
> > +       },
> > +};
> > +
> > +#define SDRAM_MAX_SIZE         (1024 * 1024 * 1024)
> > +#define SDRAM_MIN_SIZE         (128 * 1024 * 1024)
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +/*
> > + * Bandwidth configuration parameters for different SDRAM requests.
> > + * These are hardcoded settings taken from Aspeed SDK.
> > + */
> > +static const u32 ddr_max_grant_params[4] = {
> > +       0x88448844, 0x24422288, 0x22222222, 0x22222222
> > +};
> > +
> > +/*
> > + * These registers are not documented by Aspeed at all.
> > + * All writes and reads are taken pretty much as is from SDK.
> > + */
> > +struct ast2500_ddr_phy {
> > +       u32 phy[117];
> > +};
> > +
> > +struct dram_info {
> > +       struct ram_info info;
> > +       struct clk ddr_clk;
> > +       struct ast2500_sdrammc_regs *regs;
> > +       struct ast2500_scu *scu;
> > +       struct ast2500_ddr_phy *phy;
> > +       ulong clock_rate;
> > +};
> > +
> > +static int ast2500_sdrammc_reset(void)
> > +{
> > +       struct ast_wdt *wdt = ast_get_wdt(0);
>
> blank line. But can you pass this in as a parameter?
>
> > +       if (IS_ERR(wdt))
> > +               return PTR_ERR(wdt);
> > +
> > +       /* Only Reset SDRAM */
> > +       writel(WDT_RESET_SDRAM, &wdt->reset_mask);
> > +       clrbits_le32(&wdt->ctrl,
> > +                    WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
> > +       wdt_start(wdt, 1);
> > +
> > +       /* Wait for WDT to reset */
> > +       while (readl(&wdt->ctrl) & WDT_CTRL_EN)
> > +               ;
> > +       wdt_stop(wdt);
>
> Feels like you should have a helper function or driver to do the
> reset, not access the watchdog here.
>

I created a helper function in ast_wdt.c

I agree that it would be best to have reset driver here, especially since I
would need it in the future,
but as I tried to implement it the change kind of snowballed. I.e. for
aspeed reset driver would need to use watchdog, but then for watchdog, as
you suggested, there also need to be a -uclass.c to make it a proper DM
driver.
I don't mind doing all of this -- feel free to hold my future changes
hostage before I do :) -- but for the sake of keeping the size of this
change under control, I would rather just use a function here.

All other comments have been addressed for v4.


>
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
> > +{
> > +       writel(0, &phy->phy[2]);
> > +       writel(0, &phy->phy[6]);
> > +       writel(0, &phy->phy[8]);
> > +       writel(0, &phy->phy[10]);
> > +       writel(0, &phy->phy[12]);
> > +       writel(0, &phy->phy[42]);
> > +       writel(0, &phy->phy[44]);
> > +
> > +       writel(0x86000000, &phy->phy[16]);
> > +       writel(0x00008600, &phy->phy[17]);
> > +       writel(0x80000000, &phy->phy[18]);
> > +       writel(0x80808080, &phy->phy[19]);
> > +
> > +       return 0;
> > +}
> > +
> > +static void ast2500_ddr_phy_init_process(struct dram_info *info)
> > +{
> > +       struct ast2500_sdrammc_regs *regs = info->regs;
>
> blank line. Please fix globally - need a line between decls and code.
>
> > +       writel(0, &regs->phy_ctrl[0]);
> > +       writel(0x4040, &info->phy->phy[51]);
> > +
> > +       writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT,
> &regs->phy_ctrl[0]);
> > +       while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
> > +               ;
> > +       writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
> > +              &regs->phy_ctrl[0]);
> > +}
> > +
> > +static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
> > +{
> > +       writel(0, &info->regs->phy_ctrl[0]);
> > +       writel((vref << 8) | 0x6, &info->phy->phy[48]);
> > +       ast2500_ddr_phy_init_process(info);
> > +}
> > +
> > +static int ast2500_ddr_cbr_test(struct dram_info *info)
> > +{
> > +       struct ast2500_sdrammc_regs *regs = info->regs;
> > +       int i;
> > +       const u32 test_params = SDRAM_TEST_EN
> > +                       | SDRAM_TEST_ERRSTOP
> > +                       | SDRAM_TEST_TWO_MODES;
> > +       int ret = 0;
> > +
> > +       writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
> > +              (0x5c << SDRAM_REFRESH_PERIOD_SHIFT),
> &regs->refresh_timing);
> > +       writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
> > +       writel(0xff00ff00, &regs->test_init_val);
> > +       writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW <<
> SDRAM_TEST_MODE_SHIFT) |
> > +              SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
> > +
> > +       while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
> > +               ;
> > +
> > +       if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
> > +               ret = -EIO;
> > +       } else {
> > +               for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
> > +                       writel((i << SDRAM_TEST_GEN_MODE_SHIFT) |
> test_params,
> > +                              &regs->ecc_test_ctrl);
> > +                       while (!(readl(&regs->ecc_test_ctrl) &
> SDRAM_TEST_DONE))
> > +                               ;
> > +                       if (readl(&regs->ecc_test_ctrl) &
> SDRAM_TEST_FAIL) {
> > +                               ret = -EIO;
> > +                               break;
> > +                       }
> > +               }
> > +       }
> > +
> > +       writel(0, &regs->refresh_timing);
> > +       writel(0, &regs->ecc_test_ctrl);
>
> blank line before 'return' line.
>
> > +       return ret;
> > +}
> > +
> > +static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
> > +{
> > +       int i;
> > +       int vref_min = 0xff;
> > +       int vref_max = 0;
> > +       int range_size = 0;
> > +
> > +       for (i = 1; i < 0x40; ++i) {
> > +               ast2500_sdrammc_set_vref(info, i);
> > +
> > +               int res = ast2500_ddr_cbr_test(info);
> > +               if (res < 0) {
> > +                       if (range_size > 0)
> > +                               break;
> > +               } else {
> > +                       ++range_size;
> > +                       vref_min = min(vref_min, i);
> > +                       vref_max = max(vref_max, i);
> > +               }
> > +       }
> > +
> > +       /* Pick average setting */
> > +       ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
> > +
> > +       return 0;
> > +}
> > +
> > +static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
> > +{
> > +       size_t vga_mem_size_base = 8 * 1024 * 1024;
> > +       u32 vga_hwconf = (readl(&info->scu->hwstrap)
> > +                         >> SCU_HWSTRAP_VGAMEM_SHIFT)
> > +                       & SCU_HWSTRAP_VGAMEM_MASK;
> > +
> > +       return vga_mem_size_base << vga_hwconf;
> > +}
> > +
> > +/*
> > + * Find out RAM size and save it in dram_info
> > + *
> > + * The procedure is taken from Aspeed SDK
> > + */
> > +static void ast2500_sdrammc_calc_size(struct dram_info *info)
> > +{
> > +       /* The controller supports 128/256/512/1024 MB ram */
> > +       size_t ram_size = SDRAM_MIN_SIZE;
> > +       const int write_test_offset = 0x100000;
> > +       u32 test_pattern = 0xdeadbeef;
> > +       u32 cap_param = SDRAM_CONF_CAP_1024M;
> > +       u32 refresh_timing_param = DDR4_TRFC;
> > +       const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE +
> write_test_offset;
> > +
> > +       for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
> > +            ram_size >>= 1) {
> > +               writel(test_pattern, write_addr_base + (ram_size >> 1));
> > +               test_pattern = (test_pattern >> 4) | (test_pattern <<
> 28);
> > +       }
> > +
> > +       /* One last write to overwrite all wrapped values */
> > +       writel(test_pattern, write_addr_base);
> > +
> > +       /* Reset the pattern and see which value was really written */
> > +       test_pattern = 0xdeadbeef;
> > +       for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
> > +            ram_size >>= 1) {
> > +               if (readl(write_addr_base + (ram_size >> 1)) ==
> test_pattern)
> > +                       break;
> > +
> > +               --cap_param;
> > +               refresh_timing_param >>= 8;
> > +               test_pattern = (test_pattern >> 4) | (test_pattern <<
> 28);
> > +       }
> > +
> > +       clrsetbits_le32(&info->regs->ac_timing[1],
> > +                       (SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
> > +                       ((refresh_timing_param & SDRAM_AC_TRFC_MASK)
> > +                        << SDRAM_AC_TRFC_SHIFT));
> > +
> > +       info->info.base = CONFIG_SYS_SDRAM_BASE;
> > +       info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_
> size(info);
> > +       clrsetbits_le32(&info->regs->config,
> > +                       (SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
> > +                       ((cap_param & SDRAM_CONF_CAP_MASK)
> > +                        << SDRAM_CONF_CAP_SHIFT));
> > +}
> > +
> > +static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
> > +{
> > +       int i;
> > +       const u32 power_control = SDRAM_PCR_CKE_EN
> > +           | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
> > +           | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
> > +           | SDRAM_PCR_RESETN_DIS
> > +           | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN |
> SDRAM_PCR_ODT_EXT_EN;
> > +       const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
> > +#ifdef CONFIG_DUALX8_RAM
> > +           | SDRAM_CONF_DUALX8
> > +#endif
> > +           | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 |
> SDRAM_CONF_DDR4;
> > +
> > +       writel(conf, &info->regs->config);
> > +       for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
> > +               writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
> > +
> > +       writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
> > +       writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
> > +       writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
> > +       writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
> > +
> > +       for (i = 0; i < PHY_CFG_SIZE; ++i) {
> > +               writel(ddr4_phy_config.value[i],
> > +                      &info->phy->phy[ddr4_phy_config.index[i]]);
> > +       }
> > +
> > +       writel(power_control, &info->regs->power_control);
> > +
> > +       ast2500_ddr_phy_init_process(info);
> > +
> > +       int ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
>
> please declare variables at the top of functions if you can, or inside
> the block that needs them.
>
> > +       if (ret < 0) {
> > +               debug("Vref calibration failed!\n");
> > +               return ret;
> > +       }
> > +
> > +       writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
> > +              | SDRAM_REFRESH_ZQCS_EN | (0x2f <<
> SDRAM_REFRESH_PERIOD_SHIFT),
> > +              &info->regs->refresh_timing);
> > +
> > +       setbits_le32(&info->regs->power_control,
> > +                    SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
> > +
> > +       ast2500_sdrammc_calc_size(info);
> > +
> > +       setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
> > +       while (!(readl(&info->regs->config) &
> SDRAM_CONF_CACHE_INIT_DONE))
> > +               ;
> > +       setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
> > +
> > +       writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
> > +
> > +       /* Enable all requests except video & display */
> > +       writel(SDRAM_REQ_USB20_EHCI1
> > +              | SDRAM_REQ_USB20_EHCI2
> > +              | SDRAM_REQ_CPU
> > +              | SDRAM_REQ_AHB2
> > +              | SDRAM_REQ_AHB
> > +              | SDRAM_REQ_MAC0
> > +              | SDRAM_REQ_MAC1
> > +              | SDRAM_REQ_PCIE
> > +              | SDRAM_REQ_XDMA
> > +              | SDRAM_REQ_ENCRYPTION
> > +              | SDRAM_REQ_VIDEO_FLAG
> > +              | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
> > +              | SDRAM_REQ_2D_RW
> > +              | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
> > +
> > +       return 0;
> > +}
> > +
> > +static void ast2500_sdrammc_unlock(struct dram_info *info)
> > +{
> > +       writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
> > +       while (!readl(&info->regs->protection_key))
> > +               ;
> > +}
> > +
> > +static void ast2500_sdrammc_lock(struct dram_info *info)
> > +{
> > +       writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
> > +       while (readl(&info->regs->protection_key))
> > +               ;
> > +}
> > +
> > +static int ast2500_sdrammc_probe(struct udevice *dev)
> > +{
> > +       struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
> > +       struct ast2500_sdrammc_regs *regs = priv->regs;
> > +       int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
>
> Move this assignment to just before your 'if' below.
>
> > +       int i;
> > +
> > +       if (ret) {
> > +               debug("DDR:No CLK\n");
> > +               return ret;
> > +       }
> > +
> > +       priv->scu = ast_get_scu();
> > +       if (IS_ERR(priv->scu))
>
> debug()
>
> > +               return PTR_ERR(priv->scu);
> > +
> > +       clk_set_rate(&priv->ddr_clk, priv->clock_rate);
> > +       ret = ast2500_sdrammc_reset();
> > +       if (ret)
>
> debug()
>
> > +               return ret;
> > +
> > +       ast2500_sdrammc_unlock(priv);
> > +
> > +       writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
> > +              &regs->power_control);
> > +       writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
> > +
> > +       /* Mask all requests except CPU and AHB during PHY init */
> > +       writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
> > +
> > +       for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
> > +               writel(ddr_max_grant_params[i],
> &regs->max_grant_len[i]);
> > +
> > +       setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
> > +
> > +       ast2500_sdrammc_init_phy(priv->phy);
> > +       if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
> > +               ast2500_sdrammc_init_ddr4(priv);
> > +       } else {
> > +               debug("Unsupported DRAM3\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
> > +       ast2500_sdrammc_lock(priv);
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
> > +{
> > +       struct dram_info *priv = dev_get_priv(dev);
> > +       struct regmap *map;
> > +       int ret = regmap_init_mem(dev, &map);
> > +
>
> Move assignment or ret to here.
>
> > +       if (ret)
> > +               return ret;
> > +
> > +       priv->regs = regmap_get_range(map, 0);
> > +       priv->phy = regmap_get_range(map, 1);
> > +
> > +       priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
> > +                                         "clock-frequency", 0);
> > +
> > +       if (!priv->clock_rate) {
> > +               debug("DDR Clock Rate not defined\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int ast2500_sdrammc_get_info(struct udevice *dev, struct
> ram_info *info)
> > +{
> > +       struct dram_info *priv = dev_get_priv(dev);
> > +
> > +       *info = priv->info;
> > +
> > +       return 0;
> > +}
> > +
> > +static struct ram_ops ast2500_sdrammc_ops = {
> > +       .get_info = ast2500_sdrammc_get_info,
> > +};
> > +
> > +static const struct udevice_id ast2500_sdrammc_ids[] = {
> > +       { .compatible = "aspeed,ast2500-sdrammc" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(sdrammc_ast2500) = {
> > +       .name = "aspeed_ast2500_sdrammc",
> > +       .id = UCLASS_RAM,
> > +       .of_match = ast2500_sdrammc_ids,
> > +       .ops = &ast2500_sdrammc_ops,
> > +       .ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
> > +       .probe = ast2500_sdrammc_probe,
> > +       .priv_auto_alloc_size = sizeof(struct dram_info),
> > +};
> > --
> > 2.11.0.390.gc69c2f50cf-goog
> >
>
> Regards,
> Simon
>



-- 
*M*axim *S*loyko

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

* [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board
  2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                         ` (3 preceding siblings ...)
  2017-01-11 23:45       ` [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-18 21:44       ` Maxim Sloyko
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
                           ` (3 more replies)
  4 siblings, 4 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 21:44 UTC (permalink / raw)
  To: u-boot

This series adds minimal support for AST2500 part and eval board,
enough to boot EVB into prompt. It contains WDT, Timer, Sysreset,
Clock (very basic) and SDRAM MC drivers, all written from scratch,
using AST2500 datasheet. Aspeed's SDK was used only for reference.
Given very limited documentation provided by Aspeed, some parts of SDRAM
init sequence were basically rewritten to do the same thing that is done
in Aspeed SDK, without real understanding of what is going on.

The file layout closely follows the example of rk3288 chip and firefly-rk3288
board.

Changes in v4:
- Expanded AST2500 description in Kconfig
- Expanded ast_timer description in Kconfig
- Added struct ast_timer_counter to timer private data
- Use dev_get_addr_ptr in timer's of_platdata
- Added helper function to wdt for resetting peripherals
- Expanded AST2500 EVB description in Kconfig
- Added docstrings for ast_get_clk() and ast_get_scu()
- Fixed include file ordering
- Added docstring for ast2500_get_uart_clk_rate
- Use dev_get_addr_ptr
- Use WDT helper function to reset memory controller
- Fixed include file order in ast2500-board.c
- Multiple cosmetic changes: new lines, removed parens etc.
- Removed local PRE_CON_RAM_SZ variable from aspeed-common.h
- Cosmetic: Fixed comment formatting

Changes in v3:
- Added SYS_TEXT_BASE as Kconfig option
- Removed CONFIG_SYS_TEXT_BASE in favor of Kconfig option
- In aspeed-common.h changed some options from define CONFIG_FOO 1 to
  define CONFIG_FOO
- In evb_ast2500.h fixed some options to define CONFIG_FOO instead of
  define CONFIG_FOO 1

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Maxim Sloyko (4):
  aspeed: Add drivers common to all Aspeed SoCs
  aspeed: Add basic ast2500-specific drivers and configuration
  aspeed: Board init functions and common configs for ast2500 based
    boards
  aspeed: Support for ast2500 Eval Board

 arch/arm/Kconfig                                 |   7 +
 arch/arm/Makefile                                |   1 +
 arch/arm/dts/Makefile                            |   2 +
 arch/arm/dts/ast2500-evb.dts                     |  23 ++
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 125 +++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 ++++++++
 arch/arm/include/asm/arch-aspeed/timer.h         |  54 +++
 arch/arm/include/asm/arch-aspeed/wdt.h           |  99 ++++++
 arch/arm/mach-aspeed/Kconfig                     |  29 ++
 arch/arm/mach-aspeed/Makefile                    |   8 +
 arch/arm/mach-aspeed/ast2500-board.c             |  83 +++++
 arch/arm/mach-aspeed/ast2500/Kconfig             |  16 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 432 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast_wdt.c                   |  59 ++++
 board/aspeed/evb_ast2500/Kconfig                 |  12 +
 board/aspeed/evb_ast2500/Makefile                |   1 +
 board/aspeed/evb_ast2500/evb_ast2500.c           |   6 +
 configs/evb-ast2500_defconfig                    |  21 ++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 265 ++++++++++++++
 drivers/sysreset/Makefile                        |   1 +
 drivers/sysreset/sysreset_ast.c                  |  55 +++
 drivers/timer/Kconfig                            |  12 +
 drivers/timer/Makefile                           |   1 +
 drivers/timer/ast_timer.c                        |  97 +++++
 include/configs/aspeed-common.h                  |  81 +++++
 include/configs/evb_ast2500.h                    |  27 ++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 33 files changed, 1951 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c
 create mode 100644 include/configs/aspeed-common.h
 create mode 100644 include/configs/evb_ast2500.h
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

--
2.11.0.483.g087da7b7c-goog

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

* [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
@ 2017-01-18 21:44         ` Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration Maxim Sloyko
                           ` (2 subsequent siblings)
  3 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 21:44 UTC (permalink / raw)
  To: u-boot

Add support for Watchdog Timer, which is compatible with AST2400 and
AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
does not follow the driver model. It also uses fixed clock, so no clock
driver is needed.

Add support for timer for Aspeed ast2400/ast2500 devices.
The driver actually controls several devices, but because all devices
share the same Control Register, it is somewhat difficult to completely
decouple them. Since only one timer is needed at the moment, this should
be OK. The timer uses fixed clock, so does not rely on a clock driver.

Add sysreset driver, which uses watchdog timer to do resets and particular
watchdog device to use is hardcoded (0)

---

Changes in v4:
- Expanded AST2500 description in Kconfig
- Expanded ast_timer description in Kconfig
- Added struct ast_timer_counter to timer private data
- Use dev_get_addr_ptr in timer's of_platdata
- Added helper function to wdt for resetting peripherals

Changes in v3:
- Added SYS_TEXT_BASE as Kconfig option

Changes in v2:
- Moved number of WDTs to a Kconfig option

Changes in v1:
- Merged together the patches related to aspeed common drivers and
  configuration
- Fixed timer driver name (was sandbox_timer)
- Removed yet nonexistent files from mach-aspeed/Makefile


Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/Kconfig                         |  7 +++
 arch/arm/Makefile                        |  1 +
 arch/arm/include/asm/arch-aspeed/timer.h | 54 +++++++++++++++++
 arch/arm/include/asm/arch-aspeed/wdt.h   | 99 ++++++++++++++++++++++++++++++++
 arch/arm/mach-aspeed/Kconfig             | 27 +++++++++
 arch/arm/mach-aspeed/Makefile            |  7 +++
 arch/arm/mach-aspeed/ast_wdt.c           | 59 +++++++++++++++++++
 drivers/sysreset/Makefile                |  1 +
 drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
 drivers/timer/Kconfig                    | 12 ++++
 drivers/timer/Makefile                   |  1 +
 drivers/timer/ast_timer.c                | 97 +++++++++++++++++++++++++++++++
 12 files changed, 420 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
 create mode 100644 arch/arm/mach-aspeed/Kconfig
 create mode 100644 arch/arm/mach-aspeed/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
 create mode 100644 drivers/sysreset/sysreset_ast.c
 create mode 100644 drivers/timer/ast_timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 714dd8b514..135c544335 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
 	select OF_CONTROL
 	select SYS_CACHE_SHIFT_7
 
+config ARCH_ASPEED
+	bool "Support Aspeed SoCs"
+	select OF_CONTROL
+	select DM
+
 endchoice
 
+source "arch/arm/mach-aspeed/Kconfig"
+
 source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm283x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 236debb452..cc73e1038e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ASPEED)		+= aspeed
 machine-$(CONFIG_ARCH_AT91)		+= at91
 machine-$(CONFIG_ARCH_BCM283X)		+= bcm283x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
new file mode 100644
index 0000000000..87c5b354ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/timer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_TIMER_H
+#define _ASM_ARCH_TIMER_H
+
+/* Each timer has 4 control bits in ctrl1 register.
+ * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
+ * such that timer X uses bits (4 * X - 4):(4 * X - 1)
+ * If the timer does not support PWM, bit 4 is reserved.
+ */
+#define AST_TMC_EN			(1 << 0)
+#define AST_TMC_1MHZ			(1 << 1)
+#define AST_TMC_OVFINTR			(1 << 2)
+#define AST_TMC_PWM			(1 << 3)
+
+/* Timers are counted from 1 in the datasheet. */
+#define AST_TMC_CTRL1_SHIFT(n)			(4 * ((n) - 1))
+
+#define AST_TMC_RATE  (1000*1000)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All timers share control registers, which makes it harder to make them
+ * separate devices. Since only one timer is needed@the moment, making
+ * it this just one device.
+ */
+
+struct ast_timer_counter {
+	u32 status;
+	u32 reload_val;
+	u32 match1;
+	u32 match2;
+};
+
+struct ast_timer {
+	struct ast_timer_counter timers1[3];
+	u32 ctrl1;
+	u32 ctrl2;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 ctrl3;
+	u32 ctrl1_clr;
+#else
+	u32 reserved[2];
+#endif
+	struct ast_timer_counter timers2[5];
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_TIMER_H */
diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
new file mode 100644
index 0000000000..b292a0e67b
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/wdt.h
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_WDT_H
+#define _ASM_ARCH_WDT_H
+
+#define WDT_BASE			0x1e785000
+
+/*
+ * Special value that needs to be written to counter_restart register to
+ * (re)start the timer
+ */
+#define WDT_COUNTER_RESTART_VAL		0x4755
+
+/* Control register */
+#define WDT_CTRL_RESET_MODE_SHIFT	5
+#define WDT_CTRL_RESET_MODE_MASK	3
+
+#define WDT_CTRL_EN			(1 << 0)
+#define WDT_CTRL_RESET			(1 << 1)
+#define WDT_CTRL_CLK1MHZ		(1 << 4)
+#define WDT_CTRL_2ND_BOOT		(1 << 7)
+
+/* Values for Reset Mode */
+#define WDT_CTRL_RESET_SOC		0
+#define WDT_CTRL_RESET_CHIP		1
+#define WDT_CTRL_RESET_CPU		2
+#define WDT_CTRL_RESET_MASK		3
+
+/* Reset Mask register */
+#define WDT_RESET_ARM			(1 << 0)
+#define WDT_RESET_COPROC		(1 << 1)
+#define WDT_RESET_SDRAM			(1 << 2)
+#define WDT_RESET_AHB			(1 << 3)
+#define WDT_RESET_I2C			(1 << 4)
+#define WDT_RESET_MAC1			(1 << 5)
+#define WDT_RESET_MAC2			(1 << 6)
+#define WDT_RESET_GCRT			(1 << 7)
+#define WDT_RESET_USB20			(1 << 8)
+#define WDT_RESET_USB11_HOST		(1 << 9)
+#define WDT_RESET_USB11_EHCI2		(1 << 10)
+#define WDT_RESET_VIDEO			(1 << 11)
+#define WDT_RESET_HAC			(1 << 12)
+#define WDT_RESET_LPC			(1 << 13)
+#define WDT_RESET_SDSDIO		(1 << 14)
+#define WDT_RESET_MIC			(1 << 15)
+#define WDT_RESET_CRT2C			(1 << 16)
+#define WDT_RESET_PWM			(1 << 17)
+#define WDT_RESET_PECI			(1 << 18)
+#define WDT_RESET_JTAG			(1 << 19)
+#define WDT_RESET_ADC			(1 << 20)
+#define WDT_RESET_GPIO			(1 << 21)
+#define WDT_RESET_MCTP			(1 << 22)
+#define WDT_RESET_XDMA			(1 << 23)
+#define WDT_RESET_SPI			(1 << 24)
+#define WDT_RESET_MISC			(1 << 25)
+
+#ifndef __ASSEMBLY__
+struct ast_wdt {
+	u32 counter_status;
+	u32 counter_reload_val;
+	u32 counter_restart;
+	u32 ctrl;
+	u32 timeout_status;
+	u32 clr_timeout_status;
+	u32 reset_width;
+#ifdef CONFIG_ASPEED_AST2500
+	u32 reset_mask;
+#else
+	u32 reserved0;
+#endif
+};
+
+void wdt_stop(struct ast_wdt *wdt);
+void wdt_start(struct ast_wdt *wdt, u32 timeout);
+
+/**
+ * Reset peripherals specified by mask
+ *
+ * Note, that this is only supported by ast2500 SoC
+ *
+ * @wdt: watchdog to use for this reset
+ * @mask: reset mask.
+ */
+int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask);
+
+/**
+ * ast_get_wdt() - get a pointer to watchdog registers
+ *
+ * @wdt_number: 0-based WDT peripheral number
+ * @return pointer to registers or -ve error on error
+ */
+struct ast_wdt *ast_get_wdt(u8 wdt_number);
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_ARCH_WDT_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
new file mode 100644
index 0000000000..b72ed89af7
--- /dev/null
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -0,0 +1,27 @@
+if ARCH_ASPEED
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_SOC
+	default "aspeed"
+
+config SYS_TEXT_BASE
+	default 0x00000000
+
+config ASPEED_AST2500
+	bool "Support Aspeed AST2500 SoC"
+	select CPU_ARM1176
+	help
+	  The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU.
+	  It is used as Board Management Controller on many server boards,
+	  which is enabled by support of LPC and eSPI peripherals.
+
+config WDT_NUM
+	int "Number of Watchdog Timers"
+	default 3 if ASPEED_AST2500
+	help
+	  The number of Watchdot Timers on a SoC.
+	  AST2500 has three WDTsk earlier versions have two or fewer.
+
+endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644
index 0000000000..a14b8f751d
--- /dev/null
+++ b/arch/arm/mach-aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
new file mode 100644
index 0000000000..22481ab7ea
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast_wdt.c
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+void wdt_stop(struct ast_wdt *wdt)
+{
+	clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
+}
+
+void wdt_start(struct ast_wdt *wdt, u32 timeout)
+{
+	writel(timeout, &wdt->counter_reload_val);
+	writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
+	/*
+	 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
+	 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
+	 * read-only
+	 */
+	setbits_le32(&wdt->ctrl,
+		     WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
+}
+
+struct ast_wdt *ast_get_wdt(u8 wdt_number)
+{
+	if (wdt_number > CONFIG_WDT_NUM - 1)
+		return ERR_PTR(-EINVAL);
+
+	return (struct ast_wdt *)(WDT_BASE +
+				  sizeof(struct ast_wdt) * wdt_number);
+}
+
+int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask)
+{
+#ifdef CONFIG_ASPEED_AST2500
+	if (!mask)
+		return -EINVAL;
+
+	writel(mask, &wdt->reset_mask);
+	clrbits_le32(&wdt->ctrl,
+		     WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
+	wdt_start(wdt, 1);
+
+	/* Wait for WDT to reset */
+	while (readl(&wdt->ctrl) & WDT_CTRL_EN)
+		;
+	wdt_stop(wdt);
+
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index fa75cc52de..37638a8eea 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
new file mode 100644
index 0000000000..a0ab12851d
--- /dev/null
+++ b/drivers/sysreset/sysreset_ast.c
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+
+/* Number of Watchdog Timer ticks before reset */
+#define AST_WDT_RESET_TIMEOUT	10
+#define AST_WDT_FOR_RESET	0
+
+static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
+	u32 reset_mode = 0;
+
+	if (IS_ERR(wdt))
+		return PTR_ERR(wdt);
+
+	switch (type) {
+	case SYSRESET_WARM:
+		reset_mode = WDT_CTRL_RESET_CPU;
+		break;
+	case SYSRESET_COLD:
+		reset_mode = WDT_CTRL_RESET_CHIP;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	/* Clear reset mode bits */
+	clrsetbits_le32(&wdt->ctrl,
+			(WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
+			(reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
+	wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops ast_sysreset = {
+	.request	= ast_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_ast) = {
+	.name	= "ast_sysreset",
+	.id	= UCLASS_SYSRESET,
+	.ops	= &ast_sysreset,
+};
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index cb18f12fc9..cd38a6d4bd 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -46,4 +46,16 @@ config OMAP_TIMER
 	help
 	  Select this to enable an timer for Omap devices.
 
+config AST_TIMER
+	bool "Aspeed ast2400/ast2500 timer support"
+	depends on TIMER
+	default y if ARCH_ASPEED
+	help
+	  Select this to enable timer for Aspeed ast2400/ast2500 devices.
+	  This is a simple sys timer driver, it is compatible with lib/time.c,
+	  but does not support any interrupts. Even though SoC has 8 hardware
+	  counters, they are all treated as a single device by this driver.
+	  This is mostly because they all share several registers which
+	  makes it difficult to completely separate them.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index f351fbb4e0..a4b1a486b0 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
new file mode 100644
index 0000000000..d7c5460cd3
--- /dev/null
+++ b/drivers/timer/ast_timer.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define AST_TICK_TIMER  1
+#define AST_TMC_RELOAD_VAL  0xffffffff
+
+struct ast_timer_priv {
+	struct ast_timer *regs;
+	struct ast_timer_counter *tmc;
+};
+
+static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
+						       int n)
+{
+	if (n > 3)
+		return &timer->timers2[n - 4];
+	else
+		return &timer->timers1[n - 1];
+}
+
+static int ast_timer_probe(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val);
+
+	/*
+	 * Stop the timer. This will also load reload_val into
+	 * the status register.
+	 */
+	clrbits_le32(&priv->regs->ctrl1,
+		     AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+	/* Start the timer from the fixed 1MHz clock. */
+	setbits_le32(&priv->regs->ctrl1,
+		     (AST_TMC_EN | AST_TMC_1MHZ) <<
+		     AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
+
+	uc_priv->clock_rate = AST_TMC_RATE;
+
+	return 0;
+}
+
+static int ast_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	*count = AST_TMC_RELOAD_VAL - readl(&priv->tmc->status);
+
+	return 0;
+}
+
+static int ast_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct ast_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = dev_get_addr_ptr(dev);
+	if (IS_ERR(priv->regs))
+		return PTR_ERR(priv->regs);
+
+	priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER);
+
+	return 0;
+}
+
+static const struct timer_ops ast_timer_ops = {
+	.get_count = ast_timer_get_count,
+};
+
+static const struct udevice_id ast_timer_ids[] = {
+	{ .compatible = "aspeed,ast2500-timer" },
+	{ .compatible = "aspeed,ast2400-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(ast_timer) = {
+	.name = "ast_timer",
+	.id = UCLASS_TIMER,
+	.of_match = ast_timer_ids,
+	.probe = ast_timer_probe,
+	.priv_auto_alloc_size = sizeof(struct ast_timer_priv),
+	.ofdata_to_platdata = ast_timer_ofdata_to_platdata,
+	.ops = &ast_timer_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.11.0.483.g087da7b7c-goog

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

* [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-18 21:44         ` Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  3 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 21:44 UTC (permalink / raw)
  To: u-boot

Clock Driver

This driver is ast2500-specific and is not compatible with earlier
versions of this chip. The differences are not that big, but they are
in somewhat random places, so making it compatible with ast2400 is not
worth the effort at the moment.

SDRAM MC driver

The driver is very ast2500-specific and is completely incompatible
with previous versions of the chip.

The memory controller is very poorly documented by Aspeed in the
datasheet, with any mention of the whole range of registers missing. The
initialization procedure has been basically taken from Aspeed SDK, where
it is implemented in assembly. Here it is rewritten in C, with very limited
understanding of what exactly it is doing.

---

Changes in v4:
- Expanded AST2500 EVB description in Kconfig
- Added docstrings for ast_get_clk() and ast_get_scu()
- Fixed include file ordering
- Added docstring for ast2500_get_uart_clk_rate
- Use dev_get_addr_ptr
- Use WDT helper function to reset memory controller

Changes in v3: None
Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 specific drivers
- Add Copyright statement to all c/h files
- Use DT include from Linux Kernel, Add U-Boot specific modifications in
  ast2500-u-boot.dtsi


Reviewed-by: Tom Rini <trini@konsulko.com>

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
 arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 125 +++++++
 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 ++++++++
 arch/arm/mach-aspeed/Kconfig                     |   2 +
 arch/arm/mach-aspeed/Makefile                    |   1 +
 arch/arm/mach-aspeed/ast2500/Kconfig             |  14 +
 arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
 arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 432 +++++++++++++++++++++++
 drivers/clk/Makefile                             |   2 +
 drivers/clk/aspeed/Makefile                      |   7 +
 drivers/clk/aspeed/clk_ast2500.c                 | 265 ++++++++++++++
 include/dt-bindings/clock/ast2500-scu.h          |  29 ++
 14 files changed, 1273 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
 create mode 100644 arch/arm/dts/ast2500.dtsi
 create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
 create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
 create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
 create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
 create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
 create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
 create mode 100644 drivers/clk/aspeed/Makefile
 create mode 100644 drivers/clk/aspeed/clk_ast2500.c
 create mode 100644 include/dt-bindings/clock/ast2500-scu.h

diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
new file mode 100644
index 0000000000..c95a7ba835
--- /dev/null
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -0,0 +1,53 @@
+#include <dt-bindings/clock/ast2500-scu.h>
+
+#include "ast2500.dtsi"
+
+/ {
+	scu: clock-controller at 1e6e2000 {
+		compatible = "aspeed,ast2500-scu";
+		reg = <0x1e6e2000 0x1000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	sdrammc: sdrammc at 1e6e0000 {
+		u-boot,dm-pre-reloc;
+		compatible = "aspeed,ast2500-sdrammc";
+		reg = <0x1e6e0000 0x174
+			0x1e6e0200 0x1d4 >;
+		clocks = <&scu PLL_MPLL>;
+	};
+
+	ahb {
+		u-boot,dm-pre-reloc;
+
+		apb {
+			u-boot,dm-pre-reloc;
+
+			timer: timer at 1e782000 {
+				u-boot,dm-pre-reloc;
+			};
+
+			uart1: serial at 1e783000 {
+				clocks = <&scu PCLK_UART1>;
+			};
+
+			uart2: serial at 1e78d000 {
+				clocks = <&scu PCLK_UART2>;
+			};
+
+			uart3: serial at 1e78e000 {
+				clocks = <&scu PCLK_UART3>;
+			};
+
+			uart4: serial at 1e78f000 {
+				clocks = <&scu PCLK_UART4>;
+			};
+
+			uart5: serial at 1e784000 {
+				clocks = <&scu PCLK_UART5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
new file mode 100644
index 0000000000..97fac69d11
--- /dev/null
+++ b/arch/arm/dts/ast2500.dtsi
@@ -0,0 +1,174 @@
+/*
+ * This device tree is copied from
+ * https://raw.githubusercontent.com/torvalds/linux/02440622/arch/arm/boot/dts/
+ */
+#include "skeleton.dtsi"
+
+/ {
+	model = "Aspeed BMC";
+	compatible = "aspeed,ast2500";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&vic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,arm1176jzf-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vic: interrupt-controller at 1e6c0080 {
+			compatible = "aspeed,ast2400-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			valid-sources = <0xfefff7ff 0x0807ffff>;
+			reg = <0x1e6c0080 0x80>;
+		};
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			clk_clkin: clk_clkin at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-clkin-clock";
+				reg = <0x1e6e2070 0x04>;
+			};
+
+			clk_hpll: clk_hpll at 1e6e2024 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-hpll-clock";
+				reg = <0x1e6e2024 0x4>;
+				clocks = <&clk_clkin>;
+			};
+
+			clk_ahb: clk_ahb at 1e6e2070 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-ahb-clock";
+				reg = <0x1e6e2070 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_apb: clk_apb at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,g5-apb-clock";
+				reg = <0x1e6e2008 0x4>;
+				clocks = <&clk_hpll>;
+			};
+
+			clk_uart: clk_uart at 1e6e2008 {
+				#clock-cells = <0>;
+				compatible = "aspeed,uart-clock";
+				reg = <0x1e6e202c 0x4>;
+			};
+
+			sram at 1e720000 {
+				compatible = "mmio-sram";
+				reg = <0x1e720000 0x9000>;	// 36K
+			};
+
+			timer: timer at 1e782000 {
+				compatible = "aspeed,ast2400-timer";
+				reg = <0x1e782000 0x90>;
+				// The moxart_timer driver registers only one
+				// interrupt and assumes it's for timer 1
+				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16>;
+				clocks = <&clk_apb>;
+			};
+
+			wdt1: wdt at 1e785000 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785000 0x1c>;
+				interrupts = <27>;
+			};
+
+			wdt2: wdt at 1e785020 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785020 0x1c>;
+				interrupts = <27>;
+				status = "disabled";
+			};
+
+			wdt3: wdt at 1e785040 {
+				compatible = "aspeed,wdt";
+				reg = <0x1e785074 0x1c>;
+				status = "disabled";
+			};
+
+			uart1: serial at 1e783000 {
+				compatible = "ns16550a";
+				reg = <0x1e783000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <9>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart2: serial at 1e78d000 {
+				compatible = "ns16550a";
+				reg = <0x1e78d000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <32>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart3: serial at 1e78e000 {
+				compatible = "ns16550a";
+				reg = <0x1e78e000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <33>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart4: serial at 1e78f000 {
+				compatible = "ns16550a";
+				reg = <0x1e78f000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <34>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart5: serial at 1e784000 {
+				compatible = "ns16550a";
+				reg = <0x1e784000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				current-speed = <38400>;
+				no-loopback-test;
+				status = "disabled";
+			};
+
+			uart6: serial at 1e787000 {
+				compatible = "ns16550a";
+				reg = <0x1e787000 0x1000>;
+				reg-shift = <2>;
+				interrupts = <10>;
+				clocks = <&clk_uart>;
+				no-loopback-test;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
new file mode 100644
index 0000000000..fc0c01ae33
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SCU_AST2500_H
+#define _ASM_ARCH_SCU_AST2500_H
+
+#define SCU_UNLOCK_VALUE		0x1688a8a8
+
+#define SCU_HWSTRAP_VGAMEM_MASK		3
+#define SCU_HWSTRAP_VGAMEM_SHIFT	2
+#define SCU_HWSTRAP_DDR4		(1 << 24)
+#define SCU_HWSTRAP_CLKIN_25MHZ		(1 << 23)
+
+#define SCU_MPLL_DENUM_SHIFT		0
+#define SCU_MPLL_DENUM_MASK		0x1f
+#define SCU_MPLL_NUM_SHIFT		5
+#define SCU_MPLL_NUM_MASK		0xff
+#define SCU_MPLL_POST_SHIFT		13
+#define SCU_MPLL_POST_MASK		0x3f
+
+#define SCU_HPLL_DENUM_SHIFT		0
+#define SCU_HPLL_DENUM_MASK		0x1f
+#define SCU_HPLL_NUM_SHIFT		5
+#define SCU_HPLL_NUM_MASK		0xff
+#define SCU_HPLL_POST_SHIFT		13
+#define SCU_HPLL_POST_MASK		0x3f
+
+#define SCU_MISC2_UARTCLK_SHIFT		24
+
+#define SCU_MISC_UARTCLK_DIV13		(1 << 12)
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_clk_priv {
+	struct ast2500_scu *scu;
+};
+
+struct ast2500_scu {
+	u32 protection_key;
+	u32 sysreset_ctrl1;
+	u32 clk_sel1;
+	u32 clk_stop_ctrl1;
+	u32 freq_counter_ctrl;
+	u32 freq_counter_cmp;
+	u32 intr_ctrl;
+	u32 d2_pll_param;
+	u32 m_pll_param;
+	u32 h_pll_param;
+	u32 d_pll_param;
+	u32 misc_ctrl1;
+	u32 pci_config[3];
+	u32 sysreset_status;
+	u32 vga_handshake[2];
+	u32 mac_clk_delay;
+	u32 misc_ctrl2;
+	u32 vga_scratch[8];
+	u32 hwstrap;
+	u32 rng_ctrl;
+	u32 rng_data;
+	u32 rev_id;
+	u32 pinmux_ctrl[6];
+	u32 reserved0;
+	u32 extrst_sel;
+	u32 pinmux_ctrl1[4];
+	u32 reserved1[2];
+	u32 mac_clk_delay_100M;
+	u32 mac_clk_delay_10M;
+	u32 wakeup_enable;
+	u32 wakeup_control;
+	u32 reserved2[3];
+	u32 sysreset_ctrl2;
+	u32 clk_sel2;
+	u32 clk_stop_ctrl2;
+	u32 freerun_counter;
+	u32 freerun_counter_ext;
+	u32 clk_duty_meas_ctrl;
+	u32 clk_duty_meas_res;
+	u32 reserved3[4];
+	/* The next registers are not key-protected */
+	struct ast2500_cpu2 {
+		u32 ctrl;
+		u32 base_addr[9];
+		u32 cache_ctrl;
+	} cpu2;
+	u32 reserved4;
+	u32 d_pll_ext_param[3];
+	u32 d2_pll_ext_param[3];
+	u32 mh_pll_ext_param;
+	u32 reserved5;
+	u32 chip_id[2];
+	u32 reserved6[2];
+	u32 uart_clk_ctrl;
+	u32 reserved7[7];
+	u32 pcie_config;
+	u32 mmio_decode;
+	u32 reloc_ctrl_decode[2];
+	u32 mailbox_addr;
+	u32 shared_sram_decode[2];
+	u32 bmc_rev_id;
+	u32 reserved8;
+	u32 bmc_device_id;
+	u32 reserved9[13];
+	u32 clk_duty_sel;
+};
+
+/**
+ * ast_get_clk() - get a pointer to Clock Driver
+ *
+ * @devp, OUT - pointer to Clock Driver
+ * @return zero on success, error code (< 0) otherwise.
+ */
+int ast_get_clk(struct udevice **devp);
+
+/**
+ * ast_get_scu() - get a pointer to SCU registers
+ *
+ * @return pointer to struct ast2500_scu on success, ERR_PTR otherwise
+ */
+void *ast_get_scu(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
new file mode 100644
index 0000000000..a5f8615ae2
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _ASM_ARCH_SDRAM_AST2500_H
+#define _ASM_ARCH_SDRAM_AST2500_H
+
+#define SDRAM_UNLOCK_KEY		0xfc600309
+#define SDRAM_VIDEO_UNLOCK_KEY		0x2003000f
+
+#define SDRAM_PCR_CKE_EN		(1 << 0)
+#define SDRAM_PCR_AUTOPWRDN_EN		(1 << 1)
+#define SDRAM_PCR_CKE_DELAY_SHIFT	4
+#define SDRAM_PCR_CKE_DELAY_MASK	7
+#define SDRAM_PCR_RESETN_DIS		(1 << 7)
+#define SDRAM_PCR_ODT_EN		(1 << 8)
+#define SDRAM_PCR_ODT_AUTO_ON		(1 << 10)
+#define SDRAM_PCR_ODT_EXT_EN		(1 << 11)
+#define SDRAM_PCR_TCKE_PW_SHIFT		12
+#define SDRAM_PCR_TCKE_PW_MASK		7
+#define SDRAM_PCR_RGAP_CTRL_EN		(1 << 15)
+#define SDRAM_PCR_MREQI_DIS		(1 << 17)
+
+/* Fixed priority DRAM Requests mask */
+#define SDRAM_REQ_VGA_HW_CURSOR		(1 << 0)
+#define SDRAM_REQ_VGA_TEXT_CG_FONT	(1 << 1)
+#define SDRAM_REQ_VGA_TEXT_ASCII	(1 << 2)
+#define SDRAM_REQ_VGA_CRT		(1 << 3)
+#define SDRAM_REQ_SOC_DC_CURSOR		(1 << 4)
+#define SDRAM_REQ_SOC_DC_OCD		(1 << 5)
+#define SDRAM_REQ_SOC_DC_CRT		(1 << 6)
+#define SDRAM_REQ_VIDEO_HIPRI_WRITE	(1 << 7)
+#define SDRAM_REQ_USB20_EHCI1		(1 << 8)
+#define SDRAM_REQ_USB20_EHCI2		(1 << 9)
+#define SDRAM_REQ_CPU			(1 << 10)
+#define SDRAM_REQ_AHB2			(1 << 11)
+#define SDRAM_REQ_AHB			(1 << 12)
+#define SDRAM_REQ_MAC0			(1 << 13)
+#define SDRAM_REQ_MAC1			(1 << 14)
+#define SDRAM_REQ_PCIE			(1 << 16)
+#define SDRAM_REQ_XDMA			(1 << 17)
+#define SDRAM_REQ_ENCRYPTION		(1 << 18)
+#define SDRAM_REQ_VIDEO_FLAG		(1 << 21)
+#define SDRAM_REQ_VIDEO_LOW_PRI_WRITE	(1 << 28)
+#define SDRAM_REQ_2D_RW			(1 << 29)
+#define SDRAM_REQ_MEMCHECK		(1 << 30)
+
+#define SDRAM_ICR_RESET_ALL		(1 << 31)
+
+#define SDRAM_CONF_CAP_SHIFT		0
+#define SDRAM_CONF_CAP_MASK		3
+#define SDRAM_CONF_DDR4			(1 << 4)
+#define SDRAM_CONF_SCRAMBLE		(1 << 8)
+#define SDRAM_CONF_SCRAMBLE_PAT2	(1 << 9)
+#define SDRAM_CONF_CACHE_EN		(1 << 10)
+#define SDRAM_CONF_CACHE_INIT_EN	(1 << 12)
+#define SDRAM_CONF_DUALX8		(1 << 13)
+#define SDRAM_CONF_CACHE_INIT_DONE	(1 << 19)
+
+#define SDRAM_CONF_CAP_128M		0
+#define SDRAM_CONF_CAP_256M		1
+#define SDRAM_CONF_CAP_512M		2
+#define SDRAM_CONF_CAP_1024M		3
+
+#define SDRAM_MISC_DDR4_TREFRESH	(1 << 3)
+
+#define SDRAM_PHYCTRL0_INIT		(1 << 0)
+#define SDRAM_PHYCTRL0_AUTO_UPDATE	(1 << 1)
+#define SDRAM_PHYCTRL0_NRST		(1 << 2)
+
+#define SDRAM_REFRESH_CYCLES_SHIFT	0
+#define SDRAM_REFRESH_CYCLES_MASK	0xf
+#define SDRAM_REFRESH_ZQCS_EN		(1 << 7)
+#define SDRAM_REFRESH_PERIOD_SHIFT	8
+#define SDRAM_REFRESH_PERIOD_MASK	0xf
+
+#define SDRAM_TEST_LEN_SHIFT		4
+#define SDRAM_TEST_LEN_MASK		0xfffff
+#define SDRAM_TEST_START_ADDR_SHIFT	24
+#define SDRAM_TEST_START_ADDR_MASK	0x3f
+
+#define SDRAM_TEST_EN			(1 << 0)
+#define SDRAM_TEST_MODE_SHIFT		1
+#define SDRAM_TEST_MODE_MASK		3
+#define SDRAM_TEST_MODE_WO		0
+#define SDRAM_TEST_MODE_RB		1
+#define SDRAM_TEST_MODE_RW		2
+#define SDRAM_TEST_GEN_MODE_SHIFT	3
+#define SDRAM_TEST_GEN_MODE_MASK	7
+#define SDRAM_TEST_TWO_MODES		(1 << 6)
+#define SDRAM_TEST_ERRSTOP		(1 << 7)
+#define SDRAM_TEST_DONE			(1 << 12)
+#define SDRAM_TEST_FAIL			(1 << 13)
+
+#define SDRAM_AC_TRFC_SHIFT		0
+#define SDRAM_AC_TRFC_MASK		0xff
+
+#ifndef __ASSEMBLY__
+
+struct ast2500_sdrammc_regs {
+	u32 protection_key;
+	u32 config;
+	u32 gm_protection_key;
+	u32 refresh_timing;
+	u32 ac_timing[3];
+	u32 misc_control;
+	u32 mr46_mode_setting;
+	u32 mr5_mode_setting;
+	u32 mode_setting_control;
+	u32 mr02_mode_setting;
+	u32 mr13_mode_setting;
+	u32 power_control;
+	u32 req_limit_mask;
+	u32 pri_group_setting;
+	u32 max_grant_len[4];
+	u32 intr_ctrl;
+	u32 ecc_range_ctrl;
+	u32 first_ecc_err_addr;
+	u32 last_ecc_err_addr;
+	u32 phy_ctrl[4];
+	u32 ecc_test_ctrl;
+	u32 test_addr;
+	u32 test_fail_dq_bit;
+	u32 test_init_val;
+	u32 phy_debug_ctrl;
+	u32 phy_debug_data;
+	u32 reserved1[30];
+	u32 scu_passwd;
+	u32 reserved2[7];
+	u32 scu_mpll;
+	u32 reserved3[19];
+	u32 scu_hwstrap;
+};
+
+#endif  /* __ASSEMBLY__ */
+
+#endif  /* _ASM_ARCH_SDRAM_AST2500_H */
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index b72ed89af7..c5b90bd96a 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -24,4 +24,6 @@ config WDT_NUM
 	  The number of Watchdot Timers on a SoC.
 	  AST2500 has three WDTsk earlier versions have two or fewer.
 
+source "arch/arm/mach-aspeed/ast2500/Kconfig"
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index a14b8f751d..1f7af71b03 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
new file mode 100644
index 0000000000..05cb27ea1f
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -0,0 +1,14 @@
+if ASPEED_AST2500
+
+config SYS_CPU
+	default "arm1176"
+
+config TARGET_EVB_AST2500
+	bool "Evb-AST2500"
+	help
+	  Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
+	  It has 512M of RAM, 32M of SPI flash, two Ethernet ports,
+	  4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot,
+	  20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs.
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2500/Makefile b/arch/arm/mach-aspeed/ast2500/Makefile
new file mode 100644
index 0000000000..a35b239ef3
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += clk_ast2500.o sdram_ast2500.o
diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
new file mode 100644
index 0000000000..079909fa64
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/scu_ast2500.h>
+
+int ast_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(aspeed_ast2500_scu), devp);
+}
+
+void *ast_get_scu(void)
+{
+	struct ast2500_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = ast_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->scu;
+}
diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
new file mode 100644
index 0000000000..ace1028116
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *
+ * Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:		GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <ram.h>
+#include <regmap.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <asm/arch/sdram_ast2500.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+/* These configuration parameters are taken from Aspeed SDK */
+#define DDR4_MR46_MODE		0x08000000
+#define DDR4_MR5_MODE		0x400
+#define DDR4_MR13_MODE		0x101
+#define DDR4_MR02_MODE		0x410
+#define DDR4_TRFC		0x45457188
+
+#define PHY_CFG_SIZE		15
+
+static const u32 ddr4_ac_timing[3] = {0x63604e37, 0xe97afa99, 0x00019000};
+static const struct {
+	u32 index[PHY_CFG_SIZE];
+	u32 value[PHY_CFG_SIZE];
+} ddr4_phy_config = {
+	.index = {0, 1, 3, 4, 5, 56, 57, 58, 59, 60, 61, 62, 36, 49, 50},
+	.value = {
+		0x42492aae, 0x09002000, 0x55e00b0b, 0x20000000, 0x24,
+		0x03002900, 0x0e0000a0, 0x000e001c, 0x35b8c106, 0x08080607,
+		0x9b000900, 0x0e400a00, 0x00100008, 0x3c183c3c, 0x00631e0e,
+	},
+};
+
+#define SDRAM_MAX_SIZE		(1024 * 1024 * 1024)
+#define SDRAM_MIN_SIZE		(128 * 1024 * 1024)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Bandwidth configuration parameters for different SDRAM requests.
+ * These are hardcoded settings taken from Aspeed SDK.
+ */
+static const u32 ddr_max_grant_params[4] = {
+	0x88448844, 0x24422288, 0x22222222, 0x22222222
+};
+
+/*
+ * These registers are not documented by Aspeed at all.
+ * All writes and reads are taken pretty much as is from SDK.
+ */
+struct ast2500_ddr_phy {
+	u32 phy[117];
+};
+
+struct dram_info {
+	struct ram_info info;
+	struct clk ddr_clk;
+	struct ast2500_sdrammc_regs *regs;
+	struct ast2500_scu *scu;
+	struct ast2500_ddr_phy *phy;
+	ulong clock_rate;
+};
+
+static int ast2500_sdrammc_init_phy(struct ast2500_ddr_phy *phy)
+{
+	writel(0, &phy->phy[2]);
+	writel(0, &phy->phy[6]);
+	writel(0, &phy->phy[8]);
+	writel(0, &phy->phy[10]);
+	writel(0, &phy->phy[12]);
+	writel(0, &phy->phy[42]);
+	writel(0, &phy->phy[44]);
+
+	writel(0x86000000, &phy->phy[16]);
+	writel(0x00008600, &phy->phy[17]);
+	writel(0x80000000, &phy->phy[18]);
+	writel(0x80808080, &phy->phy[19]);
+
+	return 0;
+}
+
+static void ast2500_ddr_phy_init_process(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+
+	writel(0, &regs->phy_ctrl[0]);
+	writel(0x4040, &info->phy->phy[51]);
+
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
+	while ((readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT))
+		;
+	writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_AUTO_UPDATE,
+	       &regs->phy_ctrl[0]);
+}
+
+static void ast2500_sdrammc_set_vref(struct dram_info *info, u32 vref)
+{
+	writel(0, &info->regs->phy_ctrl[0]);
+	writel((vref << 8) | 0x6, &info->phy->phy[48]);
+	ast2500_ddr_phy_init_process(info);
+}
+
+static int ast2500_ddr_cbr_test(struct dram_info *info)
+{
+	struct ast2500_sdrammc_regs *regs = info->regs;
+	int i;
+	const u32 test_params = SDRAM_TEST_EN
+			| SDRAM_TEST_ERRSTOP
+			| SDRAM_TEST_TWO_MODES;
+	int ret = 0;
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT) |
+	       (0x5c << SDRAM_REFRESH_PERIOD_SHIFT), &regs->refresh_timing);
+	writel((0xfff << SDRAM_TEST_LEN_SHIFT), &regs->test_addr);
+	writel(0xff00ff00, &regs->test_init_val);
+	writel(SDRAM_TEST_EN | (SDRAM_TEST_MODE_RW << SDRAM_TEST_MODE_SHIFT) |
+	       SDRAM_TEST_ERRSTOP, &regs->ecc_test_ctrl);
+
+	while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+		;
+
+	if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+		ret = -EIO;
+	} else {
+		for (i = 0; i <= SDRAM_TEST_GEN_MODE_MASK; ++i) {
+			writel((i << SDRAM_TEST_GEN_MODE_SHIFT) | test_params,
+			       &regs->ecc_test_ctrl);
+			while (!(readl(&regs->ecc_test_ctrl) & SDRAM_TEST_DONE))
+				;
+			if (readl(&regs->ecc_test_ctrl) & SDRAM_TEST_FAIL) {
+				ret = -EIO;
+				break;
+			}
+		}
+	}
+
+	writel(0, &regs->refresh_timing);
+	writel(0, &regs->ecc_test_ctrl);
+
+	return ret;
+}
+
+static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info)
+{
+	int i;
+	int vref_min = 0xff;
+	int vref_max = 0;
+	int range_size = 0;
+
+	for (i = 1; i < 0x40; ++i) {
+		int res;
+
+		ast2500_sdrammc_set_vref(info, i);
+		res = ast2500_ddr_cbr_test(info);
+		if (res < 0) {
+			if (range_size > 0)
+				break;
+		} else {
+			++range_size;
+			vref_min = min(vref_min, i);
+			vref_max = max(vref_max, i);
+		}
+	}
+
+	/* Pick average setting */
+	ast2500_sdrammc_set_vref(info, (vref_min + vref_max + 1) / 2);
+
+	return 0;
+}
+
+static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info)
+{
+	size_t vga_mem_size_base = 8 * 1024 * 1024;
+	u32 vga_hwconf = (readl(&info->scu->hwstrap)
+			  >> SCU_HWSTRAP_VGAMEM_SHIFT)
+			& SCU_HWSTRAP_VGAMEM_MASK;
+
+	return vga_mem_size_base << vga_hwconf;
+}
+
+/*
+ * Find out RAM size and save it in dram_info
+ *
+ * The procedure is taken from Aspeed SDK
+ */
+static void ast2500_sdrammc_calc_size(struct dram_info *info)
+{
+	/* The controller supports 128/256/512/1024 MB ram */
+	size_t ram_size = SDRAM_MIN_SIZE;
+	const int write_test_offset = 0x100000;
+	u32 test_pattern = 0xdeadbeef;
+	u32 cap_param = SDRAM_CONF_CAP_1024M;
+	u32 refresh_timing_param = DDR4_TRFC;
+	const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
+
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		writel(test_pattern, write_addr_base + (ram_size >> 1));
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	/* One last write to overwrite all wrapped values */
+	writel(test_pattern, write_addr_base);
+
+	/* Reset the pattern and see which value was really written */
+	test_pattern = 0xdeadbeef;
+	for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
+	     ram_size >>= 1) {
+		if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
+			break;
+
+		--cap_param;
+		refresh_timing_param >>= 8;
+		test_pattern = (test_pattern >> 4) | (test_pattern << 28);
+	}
+
+	clrsetbits_le32(&info->regs->ac_timing[1],
+			(SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
+			((refresh_timing_param & SDRAM_AC_TRFC_MASK)
+			 << SDRAM_AC_TRFC_SHIFT));
+
+	info->info.base = CONFIG_SYS_SDRAM_BASE;
+	info->info.size = ram_size - ast2500_sdrammc_get_vga_mem_size(info);
+	clrsetbits_le32(&info->regs->config,
+			(SDRAM_CONF_CAP_MASK << SDRAM_CONF_CAP_SHIFT),
+			((cap_param & SDRAM_CONF_CAP_MASK)
+			 << SDRAM_CONF_CAP_SHIFT));
+}
+
+static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
+{
+	int i;
+	const u32 power_control = SDRAM_PCR_CKE_EN
+	    | (1 << SDRAM_PCR_CKE_DELAY_SHIFT)
+	    | (2 << SDRAM_PCR_TCKE_PW_SHIFT)
+	    | SDRAM_PCR_RESETN_DIS
+	    | SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
+	const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
+#ifdef CONFIG_DUALX8_RAM
+	    | SDRAM_CONF_DUALX8
+#endif
+	    | SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
+	int ret;
+
+	writel(conf, &info->regs->config);
+	for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
+		writel(ddr4_ac_timing[i], &info->regs->ac_timing[i]);
+
+	writel(DDR4_MR46_MODE, &info->regs->mr46_mode_setting);
+	writel(DDR4_MR5_MODE, &info->regs->mr5_mode_setting);
+	writel(DDR4_MR02_MODE, &info->regs->mr02_mode_setting);
+	writel(DDR4_MR13_MODE, &info->regs->mr13_mode_setting);
+
+	for (i = 0; i < PHY_CFG_SIZE; ++i) {
+		writel(ddr4_phy_config.value[i],
+		       &info->phy->phy[ddr4_phy_config.index[i]]);
+	}
+
+	writel(power_control, &info->regs->power_control);
+
+	ast2500_ddr_phy_init_process(info);
+
+	ret = ast2500_sdrammc_ddr4_calibrate_vref(info);
+	if (ret < 0) {
+		debug("Vref calibration failed!\n");
+		return ret;
+	}
+
+	writel((1 << SDRAM_REFRESH_CYCLES_SHIFT)
+	       | SDRAM_REFRESH_ZQCS_EN | (0x2f << SDRAM_REFRESH_PERIOD_SHIFT),
+	       &info->regs->refresh_timing);
+
+	setbits_le32(&info->regs->power_control,
+		     SDRAM_PCR_AUTOPWRDN_EN | SDRAM_PCR_ODT_AUTO_ON);
+
+	ast2500_sdrammc_calc_size(info);
+
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_INIT_EN);
+	while (!(readl(&info->regs->config) & SDRAM_CONF_CACHE_INIT_DONE))
+		;
+	setbits_le32(&info->regs->config, SDRAM_CONF_CACHE_EN);
+
+	writel(SDRAM_MISC_DDR4_TREFRESH, &info->regs->misc_control);
+
+	/* Enable all requests except video & display */
+	writel(SDRAM_REQ_USB20_EHCI1
+	       | SDRAM_REQ_USB20_EHCI2
+	       | SDRAM_REQ_CPU
+	       | SDRAM_REQ_AHB2
+	       | SDRAM_REQ_AHB
+	       | SDRAM_REQ_MAC0
+	       | SDRAM_REQ_MAC1
+	       | SDRAM_REQ_PCIE
+	       | SDRAM_REQ_XDMA
+	       | SDRAM_REQ_ENCRYPTION
+	       | SDRAM_REQ_VIDEO_FLAG
+	       | SDRAM_REQ_VIDEO_LOW_PRI_WRITE
+	       | SDRAM_REQ_2D_RW
+	       | SDRAM_REQ_MEMCHECK, &info->regs->req_limit_mask);
+
+	return 0;
+}
+
+static void ast2500_sdrammc_unlock(struct dram_info *info)
+{
+	writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (!readl(&info->regs->protection_key))
+		;
+}
+
+static void ast2500_sdrammc_lock(struct dram_info *info)
+{
+	writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
+	while (readl(&info->regs->protection_key))
+		;
+}
+
+static int ast2500_sdrammc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
+	struct ast2500_sdrammc_regs *regs = priv->regs;
+	int i;
+	int ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
+
+	if (ret) {
+		debug("DDR:No CLK\n");
+		return ret;
+	}
+
+	priv->scu = ast_get_scu();
+	if (IS_ERR(priv->scu)) {
+		debug("%s(): can't get SCU\n", __func__);
+		return PTR_ERR(priv->scu);
+	}
+
+	clk_set_rate(&priv->ddr_clk, priv->clock_rate);
+	ret = ast_wdt_reset_masked(ast_get_wdt(0), WDT_RESET_SDRAM);
+	if (ret) {
+		debug("%s(): SDRAM reset failed\n", __func__);
+		return ret;
+	}
+
+	ast2500_sdrammc_unlock(priv);
+
+	writel(SDRAM_PCR_MREQI_DIS | SDRAM_PCR_RESETN_DIS,
+	       &regs->power_control);
+	writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
+
+	/* Mask all requests except CPU and AHB during PHY init */
+	writel(~(SDRAM_REQ_CPU | SDRAM_REQ_AHB), &regs->req_limit_mask);
+
+	for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
+		writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
+
+	setbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+
+	ast2500_sdrammc_init_phy(priv->phy);
+	if (readl(&priv->scu->hwstrap) & SCU_HWSTRAP_DDR4) {
+		ast2500_sdrammc_init_ddr4(priv);
+	} else {
+		debug("Unsupported DRAM3\n");
+		return -EINVAL;
+	}
+
+	clrbits_le32(&regs->intr_ctrl, SDRAM_ICR_RESET_ALL);
+	ast2500_sdrammc_lock(priv);
+
+	return 0;
+}
+
+static int ast2500_sdrammc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct regmap *map;
+	int ret;
+
+	ret = regmap_init_mem(dev, &map);
+	if (ret)
+		return ret;
+
+	priv->regs = regmap_get_range(map, 0);
+	priv->phy = regmap_get_range(map, 1);
+
+	priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					  "clock-frequency", 0);
+
+	if (!priv->clock_rate) {
+		debug("DDR Clock Rate not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ast2500_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops ast2500_sdrammc_ops = {
+	.get_info = ast2500_sdrammc_get_info,
+};
+
+static const struct udevice_id ast2500_sdrammc_ids[] = {
+	{ .compatible = "aspeed,ast2500-sdrammc" },
+	{ }
+};
+
+U_BOOT_DRIVER(sdrammc_ast2500) = {
+	.name = "aspeed_ast2500_sdrammc",
+	.id = UCLASS_RAM,
+	.of_match = ast2500_sdrammc_ids,
+	.ops = &ast2500_sdrammc_ops,
+	.ofdata_to_platdata = ast2500_sdrammc_ofdata_to_platdata,
+	.probe = ast2500_sdrammc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 40a5e8cae8..625513789c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,3 +16,5 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
new file mode 100644
index 0000000000..65d1cd6e29
--- /dev/null
+++ b/drivers/clk/aspeed/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
new file mode 100644
index 0000000000..af369cc4c8
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -0,0 +1,265 @@
+/*
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2500.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/ast2500-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ */
+
+/*
+ * Get the rate of the M-PLL clock from input clock frequency and
+ * the value of the M-PLL Parameter Register.
+ */
+static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg)
+{
+	const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK;
+	const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT)
+			& SCU_MPLL_DENUM_MASK;
+	const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT)
+			& SCU_MPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+/*
+ * Get the rate of the H-PLL clock from input clock frequency and
+ * the value of the H-PLL Parameter Register.
+ */
+static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg)
+{
+	const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK;
+	const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT)
+			& SCU_HPLL_DENUM_MASK;
+	const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT)
+			& SCU_HPLL_POST_MASK;
+
+	return (clkin * ((num + 1) / (denum + 1))) / post_div;
+}
+
+static ulong ast2500_get_clkin(struct ast2500_scu *scu)
+{
+	return readl(&scu->hwstrap) & SCU_HWSTRAP_CLKIN_25MHZ
+			? 25 * 1000 * 1000 : 24 * 1000 * 1000;
+}
+
+/**
+ * Get current rate or uart clock
+ *
+ * @scu SCU registers
+ * @uart_index UART index, 1-5
+ *
+ * @return current setting for uart clock rate
+ */
+static ulong ast2500_get_uart_clk_rate(struct ast2500_scu *scu, int uart_index)
+{
+	/*
+	 * ast2500 datasheet is very confusing when it comes to UART clocks,
+	 * especially when CLKIN = 25 MHz. The settings are in
+	 * different registers and it is unclear how they interact.
+	 *
+	 * This has only been tested with default settings and CLKIN = 24 MHz.
+	 */
+	ulong uart_clkin;
+
+	if (readl(&scu->misc_ctrl2) &
+	    (1 << (uart_index - 1 + SCU_MISC2_UARTCLK_SHIFT)))
+		uart_clkin = 192 * 1000 * 1000;
+	else
+		uart_clkin = 24 * 1000 * 1000;
+
+	if (readl(&scu->misc_ctrl1) & SCU_MISC_UARTCLK_DIV13)
+		uart_clkin /= 13;
+
+	return uart_clkin;
+}
+
+static ulong ast2500_clk_get_rate(struct clk *clk)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong clkin = ast2500_get_clkin(priv->scu);
+	ulong rate;
+
+	switch (clk->id) {
+	case PLL_HPLL:
+	case ARMCLK:
+		/*
+		 * This ignores dynamic/static slowdown of ARMCLK and may
+		 * be inaccurate.
+		 */
+		rate = ast2500_get_hpll_rate(clkin,
+					     readl(&priv->scu->h_pll_param));
+		break;
+	case MCLK_DDR:
+		rate = ast2500_get_mpll_rate(clkin,
+					     readl(&priv->scu->m_pll_param));
+		break;
+	case PCLK_UART1:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 1);
+		break;
+	case PCLK_UART2:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 2);
+		break;
+	case PCLK_UART3:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 3);
+		break;
+	case PCLK_UART4:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 4);
+		break;
+	case PCLK_UART5:
+		rate = ast2500_get_uart_clk_rate(priv->scu, 5);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static void ast2500_scu_unlock(struct ast2500_scu *scu)
+{
+	writel(SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (!readl(&scu->protection_key))
+		;
+}
+
+static void ast2500_scu_lock(struct ast2500_scu *scu)
+{
+	writel(~SCU_UNLOCK_VALUE, &scu->protection_key);
+	while (readl(&scu->protection_key))
+		;
+}
+
+static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate)
+{
+	ulong clkin = ast2500_get_clkin(scu);
+	u32 mpll_reg;
+
+	/*
+	 * There are not that many combinations of numerator, denumerator
+	 * and post divider, so just brute force the best combination.
+	 * However, to avoid overflow when multiplying, use kHz.
+	 */
+	const ulong clkin_khz = clkin / 1000;
+	const ulong rate_khz = rate / 1000;
+	ulong best_num = 0;
+	ulong best_denum = 0;
+	ulong best_post = 0;
+	ulong delta = rate;
+	ulong num, denum, post;
+
+	for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) {
+		for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) {
+			num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1);
+			ulong new_rate_khz = (clkin_khz
+					      * ((num + 1) / (denum + 1)))
+					     / (post + 1);
+
+			/* Keep the rate below requested one. */
+			if (new_rate_khz > rate_khz)
+				continue;
+
+			if (new_rate_khz - rate_khz < delta) {
+				delta = new_rate_khz - rate_khz;
+
+				best_num = num;
+				best_denum = denum;
+				best_post = post;
+
+				if (delta == 0)
+					goto rate_calc_done;
+			}
+		}
+	}
+
+ rate_calc_done:
+	mpll_reg = readl(&scu->m_pll_param);
+	mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT)
+		      | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT)
+		      | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT));
+	mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT)
+	    | (best_num << SCU_MPLL_NUM_SHIFT)
+	    | (best_denum << SCU_MPLL_DENUM_SHIFT);
+
+	ast2500_scu_unlock(scu);
+	writel(mpll_reg, &scu->m_pll_param);
+	ast2500_scu_lock(scu);
+
+	return ast2500_get_mpll_rate(clkin, mpll_reg);
+}
+
+static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
+
+	ulong new_rate;
+	switch (clk->id) {
+	case PLL_MPLL:
+	case MCLK_DDR:
+		new_rate = ast2500_configure_ddr(priv->scu, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
+struct clk_ops ast2500_clk_ops = {
+	.get_rate = ast2500_clk_get_rate,
+	.set_rate = ast2500_clk_set_rate,
+};
+
+static int ast2500_clk_probe(struct udevice *dev)
+{
+	struct ast2500_clk_priv *priv = dev_get_priv(dev);
+
+	priv->scu = dev_get_addr_ptr(dev);
+	if (IS_ERR(priv->scu))
+		return PTR_ERR(priv->scu);
+
+	return 0;
+}
+
+static int ast2500_clk_bind(struct udevice *dev)
+{
+	int ret;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+	if (ret)
+		debug("Warning: No reset driver: ret=%d\n", ret);
+
+	return 0;
+}
+
+static const struct udevice_id ast2500_clk_ids[] = {
+	{ .compatible = "aspeed,ast2500-scu" },
+	{ }
+};
+
+U_BOOT_DRIVER(aspeed_ast2500_scu) = {
+	.name		= "aspeed_ast2500_scu",
+	.id		= UCLASS_CLK,
+	.of_match	= ast2500_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct ast2500_clk_priv),
+	.ops		= &ast2500_clk_ops,
+	.bind		= ast2500_clk_bind,
+	.probe		= ast2500_clk_probe,
+};
diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h
new file mode 100644
index 0000000000..ca58b12943
--- /dev/null
+++ b/include/dt-bindings/clock/ast2500-scu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* Core Clocks */
+#define PLL_HPLL	1
+#define PLL_DPLL	2
+#define PLL_D2PLL	3
+#define PLL_MPLL	4
+#define ARMCLK		5
+
+
+/* Bus Clocks, derived from core clocks */
+#define BCLK_PCLK	101
+#define BCLK_LHCLK	102
+#define BCLK_MACCLK	103
+#define BCLK_SDCLK	104
+#define BCLK_ARMCLK	105
+
+#define MCLK_DDR	201
+
+/* Special clocks */
+#define PCLK_UART1	501
+#define PCLK_UART2	502
+#define PCLK_UART3	503
+#define PCLK_UART4	504
+#define PCLK_UART5	505
-- 
2.11.0.483.g087da7b7c-goog

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

* [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration Maxim Sloyko
@ 2017-01-18 21:44         ` Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  3 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 21:44 UTC (permalink / raw)
  To: u-boot

Add configuration file with parameters that are very likely to be shared by
all ast2500-based boards.
Add ast2500-board.c file with the init code that is very likely to be
shared by all ast2500-based boards.

---

Changes in v4:
- Fixed include file order in ast2500-board.c
- Multiple cosmetic changes: new lines, removed parens etc.
- Removed local PRE_CON_RAM_SZ variable from aspeed-common.h

Changes in v3:
- Removed CONFIG_SYS_TEXT_BASE in favor of Kconfig option
- In aspeed-common.h changed some options from define CONFIG_FOO 1 to
  define CONFIG_FOO

Changes in v2: None
Changes in v1:
- Merge together all patches related to ast2500 boards common
  functions/configs
- Add copyright statement to ast2500-board.c

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/mach-aspeed/Makefile        |  2 +-
 arch/arm/mach-aspeed/ast2500-board.c | 83 ++++++++++++++++++++++++++++++++++++
 include/configs/aspeed-common.h      | 81 +++++++++++++++++++++++++++++++++++
 3 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
 create mode 100644 include/configs/aspeed-common.h

diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 1f7af71b03..9d29ff7f6f 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
-obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2500) += ast2500/ ast2500-board.o
diff --git a/arch/arm/mach-aspeed/ast2500-board.c b/arch/arm/mach-aspeed/ast2500-board.c
new file mode 100644
index 0000000000..80446af089
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/wdt.h>
+#include <linux/err.h>
+#include <dm/uclass.h>
+
+/*
+ * Second Watchdog Timer by default is configured
+ * to trigger secondary boot source.
+ */
+#define AST_2ND_BOOT_WDT		1
+
+/*
+ * Third Watchdog Timer by default is configured
+ * to toggle Flash address mode switch before reset.
+ */
+#define AST_FLASH_ADDR_DETECT_WDT	2
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void lowlevel_init(void)
+{
+	/*
+	 * These two watchdogs need to be stopped as soon as possible,
+	 * otherwise the board might hang. By default they are set to
+	 * a very short timeout and even simple debug write to serial
+	 * console early in the init process might cause them to fire.
+	 */
+	struct ast_wdt *flash_addr_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_FLASH_ADDR_DETECT_WDT);
+
+	clrbits_le32(&flash_addr_wdt->ctrl, WDT_CTRL_EN);
+
+#ifndef CONFIG_FIRMWARE_2ND_BOOT
+	struct ast_wdt *sec_boot_wdt =
+	    (struct ast_wdt *)(WDT_BASE +
+			       sizeof(struct ast_wdt) *
+			       AST_2ND_BOOT_WDT);
+
+	clrbits_le32(&sec_boot_wdt->ctrl, WDT_CTRL_EN);
+#endif
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct udevice *dev;
+	struct ram_info ram;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM FAIL1\r\n");
+		return ret;
+	}
+
+	ret = ram_get_info(dev, &ram);
+	if (ret) {
+		debug("DRAM FAIL2\r\n");
+		return ret;
+	}
+
+	gd->ram_size = ram.size;
+
+	return 0;
+}
diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
new file mode 100644
index 0000000000..93b57d46c0
--- /dev/null
+++ b/include/configs/aspeed-common.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 IBM Corporation
+ * (C) Copyright 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __AST_COMMON_CONFIG_H
+#define __AST_COMMON_CONFIG_H
+
+/* Misc CPU related */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_CMDLINE_EDITING
+
+/* Enable cache controller */
+#define CONFIG_SYS_DCACHE_OFF
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+#ifdef CONFIG_PRE_CON_BUF_SZ
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000 + CONFIG_PRE_CON_BUF_SZ)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024 - CONFIG_PRE_CON_BUF_SZ)
+#else
+#define CONFIG_SYS_INIT_RAM_ADDR	(0x1e720000)
+#define CONFIG_SYS_INIT_RAM_SIZE	(36*1024)
+#endif
+
+#define SYS_INIT_RAM_END		(CONFIG_SYS_INIT_RAM_ADDR \
+					 + CONFIG_SYS_INIT_RAM_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(SYS_INIT_RAM_END \
+					 - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_MALLOC_LEN		(32 << 20)
+
+/*
+ * NS16550 Configuration
+ */
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_SUBNETMASK
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE		256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					 + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+#define CONFIG_BOOTARGS \
+		"console=ttyS4,115200n8" \
+		" root=/dev/ram rw"
+
+#define CONFIG_BOOTCOMMAND		"bootm 20080000 20300000"
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=yes\0"	\
+	"spi_dma=yes\0" \
+	""
+
+#endif	/* __AST_COMMON_CONFIG_H */
-- 
2.11.0.483.g087da7b7c-goog

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

* [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
                           ` (2 preceding siblings ...)
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-18 21:44         ` Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  3 siblings, 2 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-18 21:44 UTC (permalink / raw)
  To: u-boot

ast2500 Eval Board device tree and board specific configuration.

---

Changes in v4:
- Cosmetic: Fixed comment formatting

Changes in v3:
- In evb_ast2500.h fixed some options to define CONFIG_FOO instead of
  define CONFIG_FOO 1

Changes in v2: None
Changes in v1:
- Merge together patches related to ast2500 eval board configuration
- Add Copyright statement to evb_ast2500.c
- Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
  Kernel DT Include

Signed-off-by: Maxim Sloyko <maxims@google.com>
---
 arch/arm/dts/Makefile                  |  2 ++
 arch/arm/dts/ast2500-evb.dts           | 23 +++++++++++++++++++++++
 arch/arm/mach-aspeed/ast2500/Kconfig   |  2 ++
 board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
 board/aspeed/evb_ast2500/Makefile      |  1 +
 board/aspeed/evb_ast2500/evb_ast2500.c |  6 ++++++
 configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
 include/configs/evb_ast2500.h          | 27 +++++++++++++++++++++++++++
 8 files changed, 94 insertions(+)
 create mode 100644 arch/arm/dts/ast2500-evb.dts
 create mode 100644 board/aspeed/evb_ast2500/Kconfig
 create mode 100644 board/aspeed/evb_ast2500/Makefile
 create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
 create mode 100644 configs/evb-ast2500_defconfig
 create mode 100644 include/configs/evb_ast2500.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f43746966c..1bee50e237 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -316,6 +316,8 @@ dtb-$(CONFIG_ARCH_BCM283X) += \
 	bcm2836-rpi-2-b.dtb \
 	bcm2837-rpi-3-b.dtb
 
+dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
+
 targets += $(dtb-y)
 
 # Add any required device tree compiler flags here
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
new file mode 100644
index 0000000000..dc13952fb8
--- /dev/null
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+#include "ast2500-u-boot.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&sdrammc {
+	clock-frequency = <400000000>;
+};
diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig b/arch/arm/mach-aspeed/ast2500/Kconfig
index 05cb27ea1f..b815153bfc 100644
--- a/arch/arm/mach-aspeed/ast2500/Kconfig
+++ b/arch/arm/mach-aspeed/ast2500/Kconfig
@@ -11,4 +11,6 @@ config TARGET_EVB_AST2500
 	  4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot,
 	  20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs.
 
+source "board/aspeed/evb_ast2500/Kconfig"
+
 endif
diff --git a/board/aspeed/evb_ast2500/Kconfig b/board/aspeed/evb_ast2500/Kconfig
new file mode 100644
index 0000000000..73a8ae85f6
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2500
+
+config SYS_BOARD
+	default "evb_ast2500"
+
+config SYS_VENDOR
+	default "aspeed"
+
+config SYS_CONFIG_NAME
+	default "evb_ast2500"
+
+endif
diff --git a/board/aspeed/evb_ast2500/Makefile b/board/aspeed/evb_ast2500/Makefile
new file mode 100644
index 0000000000..4564098299
--- /dev/null
+++ b/board/aspeed/evb_ast2500/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2500.o
diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c
new file mode 100644
index 0000000000..649e3ba27e
--- /dev/null
+++ b/board/aspeed/evb_ast2500/evb_ast2500.c
@@ -0,0 +1,6 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
new file mode 100644
index 0000000000..4598f6f418
--- /dev/null
+++ b/configs/evb-ast2500_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_ASPEED_AST2500=y
+CONFIG_TARGET_EVB_AST2500=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISPLAY_CPUINFO=n
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_CLK=y
+CONFIG_TIMER=y
+CONFIG_RAM=y
+CONFIG_REGMAP=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x1e720000
+CONFIG_PRE_CON_BUF_SZ=4096
+CONFIG_SYS_NO_FLASH=y
+CONFIG_CMD_IMLS=n
diff --git a/include/configs/evb_ast2500.h b/include/configs/evb_ast2500.h
new file mode 100644
index 0000000000..a571f2a749
--- /dev/null
+++ b/include/configs/evb_ast2500.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012-2020  ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ *
+ * Copyright 2016 Google Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+#define CONFIG_SYS_MEMTEST_START	(CONFIG_SYS_SDRAM_BASE + 0x300000)
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x5000000)
+
+#define CONFIG_SYS_UBOOT_BASE		CONFIG_SYS_TEXT_BASE
+
+/* Memory Info */
+#define CONFIG_SYS_LOAD_ADDR		0x83000000
+
+#define CONFIG_ENV_IS_NOWHERE
+
+#define CONFIG_ENV_SIZE			0x20000
+
+#endif	/* __CONFIG_H */
-- 
2.11.0.483.g087da7b7c-goog

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

* [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board
  2017-01-17 19:46     ` Maxim Sloyko
@ 2017-01-21  3:51       ` Simon Glass
  0 siblings, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-21  3:51 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 17 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
>
>
> On Sat, Jan 14, 2017 at 9:14 AM, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Maxim,
>>
>> On 4 January 2017 at 12:46, Maxim Sloyko <maxims@google.com> wrote:
>> > ---
>> >
>>
>> Commit message?
>>
>> > ---
>> >
>> > Signed-off-by: Maxim Sloyko <maxims@google.com>
>> > ---
>> >  arch/arm/mach-aspeed/ast2500/Kconfig   |  7 +++++++
>> >  board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
>> >  board/aspeed/evb_ast2500/Makefile      |  1 +
>> >  board/aspeed/evb_ast2500/evb_ast2500.c |  1 +
>> >  configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
>> >  include/configs/evb_ast2500.h          | 30
>> > ++++++++++++++++++++++++++++++
>> >  6 files changed, 72 insertions(+)
>> >  create mode 100644 board/aspeed/evb_ast2500/Kconfig
>> >  create mode 100644 board/aspeed/evb_ast2500/Makefile
>> >  create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
>> >  create mode 100644 configs/evb-ast2500_defconfig
>> >  create mode 100644 include/configs/evb_ast2500.h
>> >
>> > diff --git a/arch/arm/mach-aspeed/ast2500/Kconfig
>> > b/arch/arm/mach-aspeed/ast2500/Kconfig
>> > index c0b448f19e..7397d0c179 100644
>> > --- a/arch/arm/mach-aspeed/ast2500/Kconfig
>> > +++ b/arch/arm/mach-aspeed/ast2500/Kconfig
>> > @@ -3,4 +3,11 @@ if ASPEED_AST2500
>> >  config SYS_CPU
>> >         default "arm1176"
>> >
>> > +config TARGET_EVB_AST2500
>> > +       bool "Evb-AST2500"
>> > +       help
>> > +         Evb-AST2500 is Aspeed evaluation board for AST2500 chip.
>>
>> More details? What peripherals does it provide?
>
>
> Do you mean the hardware or what has been implemented so far?

Just a bit about the hardware.

>

[...]

Regards,
Simon

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-17 23:27             ` Maxim Sloyko
@ 2017-01-21  3:52               ` Simon Glass
  2017-01-23 17:52                 ` Maxim Sloyko
  0 siblings, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-21  3:52 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 17 January 2017 at 16:27, Maxim Sloyko <maxims@google.com> wrote:
>
>
> On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Maxim,
>>
>> On 5 January 2017 at 15:20, Maxim Sloyko <maxims@google.com> wrote:
>> > On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
>> >> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
>> >>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
>> >>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
>> >>> >
>> >>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> >>> >> ---
>> >>> >>
>> >>> >>  arch/arm/dts/ast2500.dtsi               | 423
>> >>> >> ++++++++++++++++++++++++++++++++
>> >>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>> >>> >>  2 files changed, 452 insertions(+)
>> >>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
>> >>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>> >>> >>
>> >>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
>> >>> >> new file mode 100644
>> >>> >> index 0000000000..1a2a3f7ee3
>> >>> >> --- /dev/null
>> >>> >> +++ b/arch/arm/dts/ast2500.dtsi
>> >>> >> @@ -0,0 +1,423 @@
>> >>> >> +/* This device tree is copied from
>> >>> >> + *
>> >>> >> https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
>> >>> >
>> >>> > Is this also found in the Linux kernel or not yet?  Thanks!
>> >>>
>> >>> Yes, this is also in in main Linux kernel now, as I've found out, but
>> >>> actually there is a number of differences, most notably there is no
>> >>> pin configuration in this device tree, because there is no pinctrl
>> >>> driver.
>> >
>> > Actually, I take that back, I was looking at the wrong linux Linux
>> > kernel tree still... Only basic version of device tree has made it to
>> > mainline kernel, but it's enough at the moment, so I used that
>> > instead.
>> >
>> >>>
>> >>> Should I remove this reference or modify it?
>> >>
>> >> Ideally, we will take the kernel dts files and then add what we need on
>> >> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
>> >> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
>> >> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
>> >
>> > OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
>> > added modifications in ast2500-u-boot.dtsi and now include
>> > ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
>> > you.
>>
>> There is some magic in the Makefile which automatically includes the
>> .dtsi if you name it correctly:
>>
>> # Try these files in order to find the U-Boot-specific .dtsi include file
>> u_boot_dtsi_options = $(wildcard $(dts_dir)/$(basename $(notdir
>> $<))-u-boot.dtsi) \
>> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_SOC))-u-boot.dtsi) \
>> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_CPU))-u-boot.dtsi) \
>> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_VENDOR))-u-boot.dtsi) \
>> $(wildcard $(dts_dir)/u-boot.dtsi)
>>
>>
>> So you should not need to include it explicitly.
>
>
> Well, it looks like the only applicable for this case would be
> CONFIG_SYS_SOC, but it looks like this setting also affects the mach- and
> arch- directories used. In this case I want different aspeed SoCs to share
> those directories, but
> they will have different DTs.

The first option is to a .dtsi derived from the .dts filename. Does that help?

Regards,
Simon

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-21  3:52               ` Simon Glass
@ 2017-01-23 17:52                 ` Maxim Sloyko
  2017-01-23 19:51                   ` Simon Glass
  0 siblings, 1 reply; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-23 17:52 UTC (permalink / raw)
  To: u-boot

On Fri, Jan 20, 2017 at 7:52 PM, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Maxim,
>
> On 17 January 2017 at 16:27, Maxim Sloyko <maxims@google.com> wrote:
> >
> >
> > On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi Maxim,
> >>
> >> On 5 January 2017 at 15:20, Maxim Sloyko <maxims@google.com> wrote:
> >> > On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
> >> >> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
> >> >>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
> >> >>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
> >> >>> >
> >> >>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
> >> >>> >> ---
> >> >>> >>
> >> >>> >>  arch/arm/dts/ast2500.dtsi               | 423
> >> >>> >> ++++++++++++++++++++++++++++++++
> >> >>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
> >> >>> >>  2 files changed, 452 insertions(+)
> >> >>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
> >> >>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
> >> >>> >>
> >> >>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
> >> >>> >> new file mode 100644
> >> >>> >> index 0000000000..1a2a3f7ee3
> >> >>> >> --- /dev/null
> >> >>> >> +++ b/arch/arm/dts/ast2500.dtsi
> >> >>> >> @@ -0,0 +1,423 @@
> >> >>> >> +/* This device tree is copied from
> >> >>> >> + *
> >> >>> >> https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
> >> >>> >
> >> >>> > Is this also found in the Linux kernel or not yet?  Thanks!
> >> >>>
> >> >>> Yes, this is also in in main Linux kernel now, as I've found out, but
> >> >>> actually there is a number of differences, most notably there is no
> >> >>> pin configuration in this device tree, because there is no pinctrl
> >> >>> driver.
> >> >
> >> > Actually, I take that back, I was looking at the wrong linux Linux
> >> > kernel tree still... Only basic version of device tree has made it to
> >> > mainline kernel, but it's enough at the moment, so I used that
> >> > instead.
> >> >
> >> >>>
> >> >>> Should I remove this reference or modify it?
> >> >>
> >> >> Ideally, we will take the kernel dts files and then add what we need on
> >> >> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
> >> >> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
> >> >> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
> >> >
> >> > OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
> >> > added modifications in ast2500-u-boot.dtsi and now include
> >> > ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
> >> > you.
> >>
> >> There is some magic in the Makefile which automatically includes the
> >> .dtsi if you name it correctly:
> >>
> >> # Try these files in order to find the U-Boot-specific .dtsi include file
> >> u_boot_dtsi_options = $(wildcard $(dts_dir)/$(basename $(notdir
> >> $<))-u-boot.dtsi) \
> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_SOC))-u-boot.dtsi) \
> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_CPU))-u-boot.dtsi) \
> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_VENDOR))-u-boot.dtsi) \
> >> $(wildcard $(dts_dir)/u-boot.dtsi)
> >>
> >>
> >> So you should not need to include it explicitly.
> >
> >
> > Well, it looks like the only applicable for this case would be
> > CONFIG_SYS_SOC, but it looks like this setting also affects the mach- and
> > arch- directories used. In this case I want different aspeed SoCs to share
> > those directories, but
> > they will have different DTs.
>
> The first option is to a .dtsi derived from the .dts filename. Does that help?

Hmm, probably not... if I understand that correctly.

This is what I have right now:

ast2500.dtsi -- device tree from the linux kernel, used by all
ast2500-based boards.
ast2500-u-boot.dtsi -- these are u-boot specific additions, with
u-boot,dm-pre-reloc labels, clock specification and SDRAM driver node.
These are still need to be shared by all ast2500-based boards.
ast2500-evb.dts -- Eval board specific stuff, right now basically just
chosen node with stdout-path and clock frequency specification for
SDRAM.

I don't this it would make sense to have ast2500-evb-u-boot.dtsi just
to avoid include, because when I later create ast2500-zaius-bmc.dts or
something like that, I would have the same problem.

>
> Regards,
> Simon




-- 
Maxim Sloyko

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

* [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks
  2017-01-23 17:52                 ` Maxim Sloyko
@ 2017-01-23 19:51                   ` Simon Glass
  0 siblings, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-23 19:51 UTC (permalink / raw)
  To: u-boot

Hi Maxim,

On 23 January 2017 at 10:52, Maxim Sloyko <maxims@google.com> wrote:
> On Fri, Jan 20, 2017 at 7:52 PM, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Maxim,
>>
>> On 17 January 2017 at 16:27, Maxim Sloyko <maxims@google.com> wrote:
>> >
>> >
>> > On Sat, Jan 14, 2017 at 9:13 AM, Simon Glass <sjg@chromium.org> wrote:
>> >>
>> >> Hi Maxim,
>> >>
>> >> On 5 January 2017 at 15:20, Maxim Sloyko <maxims@google.com> wrote:
>> >> > On Wed, Jan 4, 2017 at 7:26 PM, Tom Rini <trini@konsulko.com> wrote:
>> >> >> On Wed, Jan 04, 2017 at 05:18:42PM -0800, Maxim Sloyko wrote:
>> >> >>> On Wed, Jan 4, 2017 at 12:58 PM, Tom Rini <trini@konsulko.com> wrote:
>> >> >>> > On Wed, Jan 04, 2017 at 11:46:49AM -0800, Maxim Sloyko wrote:
>> >> >>> >
>> >> >>> >> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> >> >>> >> ---
>> >> >>> >>
>> >> >>> >>  arch/arm/dts/ast2500.dtsi               | 423
>> >> >>> >> ++++++++++++++++++++++++++++++++
>> >> >>> >>  include/dt-bindings/clock/ast2500-scu.h |  29 +++
>> >> >>> >>  2 files changed, 452 insertions(+)
>> >> >>> >>  create mode 100644 arch/arm/dts/ast2500.dtsi
>> >> >>> >>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>> >> >>> >>
>> >> >>> >> diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
>> >> >>> >> new file mode 100644
>> >> >>> >> index 0000000000..1a2a3f7ee3
>> >> >>> >> --- /dev/null
>> >> >>> >> +++ b/arch/arm/dts/ast2500.dtsi
>> >> >>> >> @@ -0,0 +1,423 @@
>> >> >>> >> +/* This device tree is copied from
>> >> >>> >> + *
>> >> >>> >> https://github.com/openbmc/linux/blob/c5682cb/arch/arm/boot/dts/aspeed-g5.dtsi
>> >> >>> >
>> >> >>> > Is this also found in the Linux kernel or not yet?  Thanks!
>> >> >>>
>> >> >>> Yes, this is also in in main Linux kernel now, as I've found out, but
>> >> >>> actually there is a number of differences, most notably there is no
>> >> >>> pin configuration in this device tree, because there is no pinctrl
>> >> >>> driver.
>> >> >
>> >> > Actually, I take that back, I was looking at the wrong linux Linux
>> >> > kernel tree still... Only basic version of device tree has made it to
>> >> > mainline kernel, but it's enough at the moment, so I used that
>> >> > instead.
>> >> >
>> >> >>>
>> >> >>> Should I remove this reference or modify it?
>> >> >>
>> >> >> Ideally, we will take the kernel dts files and then add what we need on
>> >> >> top of that in one of CONFIG_SYS_CPU/CONFIG_SYS_SOC/CONFIG_SYS_VENDOR
>> >> >> -u-boot.dtsi files, see for example arch/arm/dts/sunxi-u-boot.dtsi or
>> >> >> arch/arm/dts/tegra124-nyan-big-u-boot.dtsi
>> >> >
>> >> > OK, so I took the device tree from the Linux kernel, (ast2500.dtsi),
>> >> > added modifications in ast2500-u-boot.dtsi and now include
>> >> > ast2500-u-boot.dtsi in ast2500-evb.dts. Let me know if I misunderstood
>> >> > you.
>> >>
>> >> There is some magic in the Makefile which automatically includes the
>> >> .dtsi if you name it correctly:
>> >>
>> >> # Try these files in order to find the U-Boot-specific .dtsi include file
>> >> u_boot_dtsi_options = $(wildcard $(dts_dir)/$(basename $(notdir
>> >> $<))-u-boot.dtsi) \
>> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_SOC))-u-boot.dtsi) \
>> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_CPU))-u-boot.dtsi) \
>> >> $(wildcard $(dts_dir)/$(subst $\",,$(CONFIG_SYS_VENDOR))-u-boot.dtsi) \
>> >> $(wildcard $(dts_dir)/u-boot.dtsi)
>> >>
>> >>
>> >> So you should not need to include it explicitly.
>> >
>> >
>> > Well, it looks like the only applicable for this case would be
>> > CONFIG_SYS_SOC, but it looks like this setting also affects the mach- and
>> > arch- directories used. In this case I want different aspeed SoCs to share
>> > those directories, but
>> > they will have different DTs.
>>
>> The first option is to a .dtsi derived from the .dts filename. Does that help?
>
> Hmm, probably not... if I understand that correctly.
>
> This is what I have right now:
>
> ast2500.dtsi -- device tree from the linux kernel, used by all
> ast2500-based boards.
> ast2500-u-boot.dtsi -- these are u-boot specific additions, with
> u-boot,dm-pre-reloc labels, clock specification and SDRAM driver node.
> These are still need to be shared by all ast2500-based boards.
> ast2500-evb.dts -- Eval board specific stuff, right now basically just
> chosen node with stdout-path and clock frequency specification for
> SDRAM.
>
> I don't this it would make sense to have ast2500-evb-u-boot.dtsi just
> to avoid include, because when I later create ast2500-zaius-bmc.dts or
> something like that, I would have the same problem.

Yes you may as well have your own include.

The idea is to use the same files as Linux, and put the U-Boot
additions in a separate file. But it's not critical - just a new idea
we had. Also if you can get the U-Boot additions into the upstream
Linux version then you won't need this.

Regards,
Simon

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

* [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
@ 2017-01-26 14:23           ` Simon Glass
  2017-01-26 18:31             ` Maxim Sloyko
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  1 sibling, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-26 14:23 UTC (permalink / raw)
  To: u-boot

On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
> Add support for Watchdog Timer, which is compatible with AST2400 and
> AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
> does not follow the driver model. It also uses fixed clock, so no clock
> driver is needed.
>
> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK. The timer uses fixed clock, so does not rely on a clock driver.
>
> Add sysreset driver, which uses watchdog timer to do resets and particular
> watchdog device to use is hardcoded (0)
>
> ---
>
> Changes in v4:
> - Expanded AST2500 description in Kconfig
> - Expanded ast_timer description in Kconfig
> - Added struct ast_timer_counter to timer private data
> - Use dev_get_addr_ptr in timer's of_platdata
> - Added helper function to wdt for resetting peripherals
>
> Changes in v3:
> - Added SYS_TEXT_BASE as Kconfig option
>
> Changes in v2:
> - Moved number of WDTs to a Kconfig option
>
> Changes in v1:
> - Merged together the patches related to aspeed common drivers and
>   configuration
> - Fixed timer driver name (was sandbox_timer)
> - Removed yet nonexistent files from mach-aspeed/Makefile
>
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>  arch/arm/Kconfig                         |  7 +++
>  arch/arm/Makefile                        |  1 +
>  arch/arm/include/asm/arch-aspeed/timer.h | 54 +++++++++++++++++
>  arch/arm/include/asm/arch-aspeed/wdt.h   | 99 ++++++++++++++++++++++++++++++++
>  arch/arm/mach-aspeed/Kconfig             | 27 +++++++++
>  arch/arm/mach-aspeed/Makefile            |  7 +++
>  arch/arm/mach-aspeed/ast_wdt.c           | 59 +++++++++++++++++++
>  drivers/sysreset/Makefile                |  1 +
>  drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
>  drivers/timer/Kconfig                    | 12 ++++
>  drivers/timer/Makefile                   |  1 +
>  drivers/timer/ast_timer.c                | 97 +++++++++++++++++++++++++++++++
>  12 files changed, 420 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
>  create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
>  create mode 100644 arch/arm/mach-aspeed/Kconfig
>  create mode 100644 arch/arm/mach-aspeed/Makefile
>  create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
>  create mode 100644 drivers/sysreset/sysreset_ast.c
>  create mode 100644 drivers/timer/ast_timer.c

Reviewed-by: Simon Glass <sjg@chromium.org>

Some comments below which you could do as part of your clean-up if you like.

>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 714dd8b514..135c544335 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
>         select OF_CONTROL
>         select SYS_CACHE_SHIFT_7
>
> +config ARCH_ASPEED
> +       bool "Support Aspeed SoCs"
> +       select OF_CONTROL
> +       select DM
> +
>  endchoice
>
> +source "arch/arm/mach-aspeed/Kconfig"
> +
>  source "arch/arm/mach-at91/Kconfig"
>
>  source "arch/arm/mach-bcm283x/Kconfig"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 236debb452..cc73e1038e 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
>
>  # Machine directory name.  This list is sorted alphanumerically
>  # by CONFIG_* macro name.
> +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
>  machine-$(CONFIG_ARCH_AT91)            += at91
>  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
>  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
> diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
> new file mode 100644
> index 0000000000..87c5b354ec
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/timer.h
> @@ -0,0 +1,54 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +#ifndef _ASM_ARCH_TIMER_H
> +#define _ASM_ARCH_TIMER_H
> +
> +/* Each timer has 4 control bits in ctrl1 register.
> + * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
> + * such that timer X uses bits (4 * X - 4):(4 * X - 1)
> + * If the timer does not support PWM, bit 4 is reserved.
> + */
> +#define AST_TMC_EN                     (1 << 0)
> +#define AST_TMC_1MHZ                   (1 << 1)
> +#define AST_TMC_OVFINTR                        (1 << 2)
> +#define AST_TMC_PWM                    (1 << 3)
> +
> +/* Timers are counted from 1 in the datasheet. */
> +#define AST_TMC_CTRL1_SHIFT(n)                 (4 * ((n) - 1))
> +
> +#define AST_TMC_RATE  (1000*1000)
> +
> +#ifndef __ASSEMBLY__
> +
> +/*
> + * All timers share control registers, which makes it harder to make them
> + * separate devices. Since only one timer is needed at the moment, making
> + * it this just one device.
> + */
> +
> +struct ast_timer_counter {
> +       u32 status;
> +       u32 reload_val;
> +       u32 match1;
> +       u32 match2;
> +};
> +
> +struct ast_timer {
> +       struct ast_timer_counter timers1[3];
> +       u32 ctrl1;
> +       u32 ctrl2;
> +#ifdef CONFIG_ASPEED_AST2500
> +       u32 ctrl3;
> +       u32 ctrl1_clr;
> +#else
> +       u32 reserved[2];
> +#endif

We don't want have to #ifdefs in drivers. The driver should support
both devices and use the compatible string to determine which is used.
So here I think you can get rid of 'reserved'. Perhaps add a comment
that these two registers don't exist on one device?

> +       struct ast_timer_counter timers2[5];
> +};
> +
> +#endif  /* __ASSEMBLY__ */
> +
> +#endif  /* _ASM_ARCH_TIMER_H */
> diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
> new file mode 100644
> index 0000000000..b292a0e67b
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-aspeed/wdt.h
> @@ -0,0 +1,99 @@
> +/*
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef _ASM_ARCH_WDT_H
> +#define _ASM_ARCH_WDT_H
> +
> +#define WDT_BASE                       0x1e785000

TODO(email): Use device tree to get this value

> +
> +/*
> + * Special value that needs to be written to counter_restart register to
> + * (re)start the timer
> + */
> +#define WDT_COUNTER_RESTART_VAL                0x4755
> +
> +/* Control register */
> +#define WDT_CTRL_RESET_MODE_SHIFT      5
> +#define WDT_CTRL_RESET_MODE_MASK       3
> +
> +#define WDT_CTRL_EN                    (1 << 0)
> +#define WDT_CTRL_RESET                 (1 << 1)
> +#define WDT_CTRL_CLK1MHZ               (1 << 4)
> +#define WDT_CTRL_2ND_BOOT              (1 << 7)
> +
> +/* Values for Reset Mode */
> +#define WDT_CTRL_RESET_SOC             0
> +#define WDT_CTRL_RESET_CHIP            1
> +#define WDT_CTRL_RESET_CPU             2
> +#define WDT_CTRL_RESET_MASK            3
> +
> +/* Reset Mask register */
> +#define WDT_RESET_ARM                  (1 << 0)
> +#define WDT_RESET_COPROC               (1 << 1)
> +#define WDT_RESET_SDRAM                        (1 << 2)
> +#define WDT_RESET_AHB                  (1 << 3)
> +#define WDT_RESET_I2C                  (1 << 4)
> +#define WDT_RESET_MAC1                 (1 << 5)
> +#define WDT_RESET_MAC2                 (1 << 6)
> +#define WDT_RESET_GCRT                 (1 << 7)
> +#define WDT_RESET_USB20                        (1 << 8)
> +#define WDT_RESET_USB11_HOST           (1 << 9)
> +#define WDT_RESET_USB11_EHCI2          (1 << 10)
> +#define WDT_RESET_VIDEO                        (1 << 11)
> +#define WDT_RESET_HAC                  (1 << 12)
> +#define WDT_RESET_LPC                  (1 << 13)
> +#define WDT_RESET_SDSDIO               (1 << 14)
> +#define WDT_RESET_MIC                  (1 << 15)
> +#define WDT_RESET_CRT2C                        (1 << 16)
> +#define WDT_RESET_PWM                  (1 << 17)
> +#define WDT_RESET_PECI                 (1 << 18)
> +#define WDT_RESET_JTAG                 (1 << 19)
> +#define WDT_RESET_ADC                  (1 << 20)
> +#define WDT_RESET_GPIO                 (1 << 21)
> +#define WDT_RESET_MCTP                 (1 << 22)
> +#define WDT_RESET_XDMA                 (1 << 23)
> +#define WDT_RESET_SPI                  (1 << 24)
> +#define WDT_RESET_MISC                 (1 << 25)
> +
> +#ifndef __ASSEMBLY__
> +struct ast_wdt {
> +       u32 counter_status;
> +       u32 counter_reload_val;
> +       u32 counter_restart;
> +       u32 ctrl;
> +       u32 timeout_status;
> +       u32 clr_timeout_status;
> +       u32 reset_width;
> +#ifdef CONFIG_ASPEED_AST2500
> +       u32 reset_mask;
> +#else
> +       u32 reserved0;
> +#endif

Same here

> +};
> +
> +void wdt_stop(struct ast_wdt *wdt);
> +void wdt_start(struct ast_wdt *wdt, u32 timeout);
> +
> +/**
> + * Reset peripherals specified by mask
> + *
> + * Note, that this is only supported by ast2500 SoC
> + *
> + * @wdt: watchdog to use for this reset
> + * @mask: reset mask.

@return?

> + */
> +int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask);
> +
> +/**
> + * ast_get_wdt() - get a pointer to watchdog registers
> + *
> + * @wdt_number: 0-based WDT peripheral number
> + * @return pointer to registers or -ve error on error
> + */
> +struct ast_wdt *ast_get_wdt(u8 wdt_number);
> +#endif  /* __ASSEMBLY__ */
> +
> +#endif /* _ASM_ARCH_WDT_H */
> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> new file mode 100644
> index 0000000000..b72ed89af7
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Kconfig
> @@ -0,0 +1,27 @@
> +if ARCH_ASPEED
> +
> +config SYS_ARCH
> +       default "arm"
> +
> +config SYS_SOC
> +       default "aspeed"
> +
> +config SYS_TEXT_BASE
> +       default 0x00000000
> +
> +config ASPEED_AST2500
> +       bool "Support Aspeed AST2500 SoC"
> +       select CPU_ARM1176
> +       help
> +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU.
> +         It is used as Board Management Controller on many server boards,
> +         which is enabled by support of LPC and eSPI peripherals.
> +
> +config WDT_NUM
> +       int "Number of Watchdog Timers"
> +       default 3 if ASPEED_AST2500
> +       help
> +         The number of Watchdot Timers on a SoC.
> +         AST2500 has three WDTsk earlier versions have two or fewer.
> +
> +endif
> diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
> new file mode 100644
> index 0000000000..a14b8f751d
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Copyright (c) 2016 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
> diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
> new file mode 100644
> index 0000000000..22481ab7ea
> --- /dev/null
> +++ b/arch/arm/mach-aspeed/ast_wdt.c
> @@ -0,0 +1,59 @@
> +/*
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/wdt.h>
> +#include <linux/err.h>
> +
> +void wdt_stop(struct ast_wdt *wdt)
> +{
> +       clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
> +}
> +
> +void wdt_start(struct ast_wdt *wdt, u32 timeout)
> +{
> +       writel(timeout, &wdt->counter_reload_val);
> +       writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
> +       /*
> +        * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
> +        * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
> +        * read-only
> +        */
> +       setbits_le32(&wdt->ctrl,
> +                    WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
> +}
> +
> +struct ast_wdt *ast_get_wdt(u8 wdt_number)
> +{
> +       if (wdt_number > CONFIG_WDT_NUM - 1)
> +               return ERR_PTR(-EINVAL);
> +
> +       return (struct ast_wdt *)(WDT_BASE +
> +                                 sizeof(struct ast_wdt) * wdt_number);
> +}
> +
> +int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask)
> +{
> +#ifdef CONFIG_ASPEED_AST2500
> +       if (!mask)
> +               return -EINVAL;
> +
> +       writel(mask, &wdt->reset_mask);
> +       clrbits_le32(&wdt->ctrl,
> +                    WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
> +       wdt_start(wdt, 1);
> +
> +       /* Wait for WDT to reset */
> +       while (readl(&wdt->ctrl) & WDT_CTRL_EN)
> +               ;
> +       wdt_stop(wdt);
> +
> +       return 0;
> +#else
> +       return -EINVAL;
> +#endif
> +}
> diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
> index fa75cc52de..37638a8eea 100644
> --- a/drivers/sysreset/Makefile
> +++ b/drivers/sysreset/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
>  obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
>  obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
>  obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
> +obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
> diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
> new file mode 100644
> index 0000000000..a0ab12851d
> --- /dev/null
> +++ b/drivers/sysreset/sysreset_ast.c
> @@ -0,0 +1,55 @@
> +/*
> + * (C) Copyright 2016 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <sysreset.h>
> +#include <asm/io.h>
> +#include <asm/arch/wdt.h>
> +#include <linux/err.h>
> +
> +/* Number of Watchdog Timer ticks before reset */
> +#define AST_WDT_RESET_TIMEOUT  10
> +#define AST_WDT_FOR_RESET      0
> +
> +static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
> +{
> +       struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
> +       u32 reset_mode = 0;
> +
> +       if (IS_ERR(wdt))
> +               return PTR_ERR(wdt);
> +
> +       switch (type) {
> +       case SYSRESET_WARM:
> +               reset_mode = WDT_CTRL_RESET_CPU;
> +               break;
> +       case SYSRESET_COLD:
> +               reset_mode = WDT_CTRL_RESET_CHIP;
> +               break;
> +       default:
> +               return -EPROTONOSUPPORT;
> +       }
> +
> +       /* Clear reset mode bits */
> +       clrsetbits_le32(&wdt->ctrl,
> +                       (WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
> +                       (reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
> +       wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
> +
> +       return -EINPROGRESS;
> +}
> +
> +static struct sysreset_ops ast_sysreset = {
> +       .request        = ast_sysreset_request,
> +};
> +
> +U_BOOT_DRIVER(sysreset_ast) = {
> +       .name   = "ast_sysreset",
> +       .id     = UCLASS_SYSRESET,
> +       .ops    = &ast_sysreset,
> +};
> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> index cb18f12fc9..cd38a6d4bd 100644
> --- a/drivers/timer/Kconfig
> +++ b/drivers/timer/Kconfig
> @@ -46,4 +46,16 @@ config OMAP_TIMER
>         help
>           Select this to enable an timer for Omap devices.
>
> +config AST_TIMER
> +       bool "Aspeed ast2400/ast2500 timer support"
> +       depends on TIMER
> +       default y if ARCH_ASPEED
> +       help
> +         Select this to enable timer for Aspeed ast2400/ast2500 devices.
> +         This is a simple sys timer driver, it is compatible with lib/time.c,
> +         but does not support any interrupts. Even though SoC has 8 hardware
> +         counters, they are all treated as a single device by this driver.
> +         This is mostly because they all share several registers which
> +         makes it difficult to completely separate them.
> +
>  endmenu
> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> index f351fbb4e0..a4b1a486b0 100644
> --- a/drivers/timer/Makefile
> +++ b/drivers/timer/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)      += altera_timer.o
>  obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
>  obj-$(CONFIG_X86_TSC_TIMER)    += tsc_timer.o
>  obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
> +obj-$(CONFIG_AST_TIMER)        += ast_timer.o
> diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
> new file mode 100644
> index 0000000000..d7c5460cd3
> --- /dev/null
> +++ b/drivers/timer/ast_timer.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright 2016 Google Inc.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <timer.h>
> +#include <asm/io.h>
> +#include <asm/arch/timer.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define AST_TICK_TIMER  1
> +#define AST_TMC_RELOAD_VAL  0xffffffff
> +
> +struct ast_timer_priv {
> +       struct ast_timer *regs;
> +       struct ast_timer_counter *tmc;
> +};
> +
> +static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
> +                                                      int n)
> +{
> +       if (n > 3)
> +               return &timer->timers2[n - 4];
> +       else
> +               return &timer->timers1[n - 1];
> +}
> +
> +static int ast_timer_probe(struct udevice *dev)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> +
> +       writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val);
> +
> +       /*
> +        * Stop the timer. This will also load reload_val into
> +        * the status register.
> +        */
> +       clrbits_le32(&priv->regs->ctrl1,
> +                    AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> +       /* Start the timer from the fixed 1MHz clock. */
> +       setbits_le32(&priv->regs->ctrl1,
> +                    (AST_TMC_EN | AST_TMC_1MHZ) <<
> +                    AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
> +
> +       uc_priv->clock_rate = AST_TMC_RATE;
> +
> +       return 0;
> +}
> +
> +static int ast_timer_get_count(struct udevice *dev, u64 *count)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +
> +       *count = AST_TMC_RELOAD_VAL - readl(&priv->tmc->status);
> +
> +       return 0;
> +}
> +
> +static int ast_timer_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct ast_timer_priv *priv = dev_get_priv(dev);
> +
> +       priv->regs = dev_get_addr_ptr(dev);
> +       if (IS_ERR(priv->regs))
> +               return PTR_ERR(priv->regs);
> +
> +       priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER);
> +
> +       return 0;
> +}
> +
> +static const struct timer_ops ast_timer_ops = {
> +       .get_count = ast_timer_get_count,
> +};
> +
> +static const struct udevice_id ast_timer_ids[] = {
> +       { .compatible = "aspeed,ast2500-timer" },
> +       { .compatible = "aspeed,ast2400-timer" },

Here you can put .data = ... and use an enum to select it. Then your
driver can operate with either at runtime.

Having said that I cannot see where ast_wdt_reset_masked() is called.

> +       { }
> +};
> +
> +U_BOOT_DRIVER(ast_timer) = {
> +       .name = "ast_timer",
> +       .id = UCLASS_TIMER,
> +       .of_match = ast_timer_ids,
> +       .probe = ast_timer_probe,
> +       .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
> +       .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
> +       .ops = &ast_timer_ops,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> --
> 2.11.0.483.g087da7b7c-goog
>

Regards,
Simon

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

* [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
@ 2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-26 14:23 UTC (permalink / raw)
  To: u-boot

On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
> Add configuration file with parameters that are very likely to be shared by
> all ast2500-based boards.
> Add ast2500-board.c file with the init code that is very likely to be
> shared by all ast2500-based boards.
>
> ---
>
> Changes in v4:
> - Fixed include file order in ast2500-board.c
> - Multiple cosmetic changes: new lines, removed parens etc.
> - Removed local PRE_CON_RAM_SZ variable from aspeed-common.h
>
> Changes in v3:
> - Removed CONFIG_SYS_TEXT_BASE in favor of Kconfig option
> - In aspeed-common.h changed some options from define CONFIG_FOO 1 to
>   define CONFIG_FOO
>
> Changes in v2: None
> Changes in v1:
> - Merge together all patches related to ast2500 boards common
>   functions/configs
> - Add copyright statement to ast2500-board.c
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>  arch/arm/mach-aspeed/Makefile        |  2 +-
>  arch/arm/mach-aspeed/ast2500-board.c | 83 ++++++++++++++++++++++++++++++++++++
>  include/configs/aspeed-common.h      | 81 +++++++++++++++++++++++++++++++++++
>  3 files changed, 165 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/mach-aspeed/ast2500-board.c
>  create mode 100644 include/configs/aspeed-common.h

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration Maxim Sloyko
@ 2017-01-26 14:23           ` Simon Glass
  2017-01-26 18:02             ` Maxim Sloyko
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  1 sibling, 1 reply; 90+ messages in thread
From: Simon Glass @ 2017-01-26 14:23 UTC (permalink / raw)
  To: u-boot

On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
> Clock Driver
>
> This driver is ast2500-specific and is not compatible with earlier
> versions of this chip. The differences are not that big, but they are
> in somewhat random places, so making it compatible with ast2400 is not
> worth the effort at the moment.
>
> SDRAM MC driver
>
> The driver is very ast2500-specific and is completely incompatible
> with previous versions of the chip.
>
> The memory controller is very poorly documented by Aspeed in the
> datasheet, with any mention of the whole range of registers missing. The
> initialization procedure has been basically taken from Aspeed SDK, where
> it is implemented in assembly. Here it is rewritten in C, with very limited
> understanding of what exactly it is doing.
>
> ---
>
> Changes in v4:
> - Expanded AST2500 EVB description in Kconfig
> - Added docstrings for ast_get_clk() and ast_get_scu()
> - Fixed include file ordering
> - Added docstring for ast2500_get_uart_clk_rate
> - Use dev_get_addr_ptr
> - Use WDT helper function to reset memory controller
>
> Changes in v3: None
> Changes in v2: None
> Changes in v1:
> - Merge together all patches related to ast2500 specific drivers
> - Add Copyright statement to all c/h files
> - Use DT include from Linux Kernel, Add U-Boot specific modifications in
>   ast2500-u-boot.dtsi
>
>
> Reviewed-by: Tom Rini <trini@konsulko.com>
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>  arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
>  arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
>  arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 125 +++++++
>  arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 ++++++++
>  arch/arm/mach-aspeed/Kconfig                     |   2 +
>  arch/arm/mach-aspeed/Makefile                    |   1 +
>  arch/arm/mach-aspeed/ast2500/Kconfig             |  14 +
>  arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
>  arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
>  arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 432 +++++++++++++++++++++++
>  drivers/clk/Makefile                             |   2 +
>  drivers/clk/aspeed/Makefile                      |   7 +
>  drivers/clk/aspeed/clk_ast2500.c                 | 265 ++++++++++++++
>  include/dt-bindings/clock/ast2500-scu.h          |  29 ++
>  14 files changed, 1273 insertions(+)
>  create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
>  create mode 100644 arch/arm/dts/ast2500.dtsi
>  create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
>  create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
>  create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
>  create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
>  create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
>  create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
>  create mode 100644 drivers/clk/aspeed/Makefile
>  create mode 100644 drivers/clk/aspeed/clk_ast2500.c
>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h

Reviewed-by: Simon Glass <sjg@chromium.org>

A few nits for later:

I think it is better to define a shifted mask:

#define SDRAM_REFRESH_PERIOD_SHIFT     8
#define SDRAM_REFRESH_PERIOD_MASK      (0xf << SDRAM_REFRESH_PERIOD_SHIFT)

What is CONFIG_DUALX8_RAM for? Can this be encoded in the device tree?

Regards,
Simon

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

* [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
@ 2017-01-26 14:23           ` Simon Glass
  2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Simon Glass @ 2017-01-26 14:23 UTC (permalink / raw)
  To: u-boot

On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
> ast2500 Eval Board device tree and board specific configuration.
>
> ---
>
> Changes in v4:
> - Cosmetic: Fixed comment formatting
>
> Changes in v3:
> - In evb_ast2500.h fixed some options to define CONFIG_FOO instead of
>   define CONFIG_FOO 1
>
> Changes in v2: None
> Changes in v1:
> - Merge together patches related to ast2500 eval board configuration
> - Add Copyright statement to evb_ast2500.c
> - Use ast2500-u-boot.dtsi instead of ast2500.dtsi, which is now Linux
>   Kernel DT Include
>
> Signed-off-by: Maxim Sloyko <maxims@google.com>
> ---
>  arch/arm/dts/Makefile                  |  2 ++
>  arch/arm/dts/ast2500-evb.dts           | 23 +++++++++++++++++++++++
>  arch/arm/mach-aspeed/ast2500/Kconfig   |  2 ++
>  board/aspeed/evb_ast2500/Kconfig       | 12 ++++++++++++
>  board/aspeed/evb_ast2500/Makefile      |  1 +
>  board/aspeed/evb_ast2500/evb_ast2500.c |  6 ++++++
>  configs/evb-ast2500_defconfig          | 21 +++++++++++++++++++++
>  include/configs/evb_ast2500.h          | 27 +++++++++++++++++++++++++++
>  8 files changed, 94 insertions(+)
>  create mode 100644 arch/arm/dts/ast2500-evb.dts
>  create mode 100644 board/aspeed/evb_ast2500/Kconfig
>  create mode 100644 board/aspeed/evb_ast2500/Makefile
>  create mode 100644 board/aspeed/evb_ast2500/evb_ast2500.c
>  create mode 100644 configs/evb-ast2500_defconfig
>  create mode 100644 include/configs/evb_ast2500.h
>

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-26 18:02             ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-26 18:02 UTC (permalink / raw)
  To: u-boot

On Thu, Jan 26, 2017 at 6:23 AM, Simon Glass <sjg@chromium.org> wrote:
> On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
>> Clock Driver
>>
>> This driver is ast2500-specific and is not compatible with earlier
>> versions of this chip. The differences are not that big, but they are
>> in somewhat random places, so making it compatible with ast2400 is not
>> worth the effort at the moment.
>>
>> SDRAM MC driver
>>
>> The driver is very ast2500-specific and is completely incompatible
>> with previous versions of the chip.
>>
>> The memory controller is very poorly documented by Aspeed in the
>> datasheet, with any mention of the whole range of registers missing. The
>> initialization procedure has been basically taken from Aspeed SDK, where
>> it is implemented in assembly. Here it is rewritten in C, with very limited
>> understanding of what exactly it is doing.
>>
>> ---
>>
>> Changes in v4:
>> - Expanded AST2500 EVB description in Kconfig
>> - Added docstrings for ast_get_clk() and ast_get_scu()
>> - Fixed include file ordering
>> - Added docstring for ast2500_get_uart_clk_rate
>> - Use dev_get_addr_ptr
>> - Use WDT helper function to reset memory controller
>>
>> Changes in v3: None
>> Changes in v2: None
>> Changes in v1:
>> - Merge together all patches related to ast2500 specific drivers
>> - Add Copyright statement to all c/h files
>> - Use DT include from Linux Kernel, Add U-Boot specific modifications in
>>   ast2500-u-boot.dtsi
>>
>>
>> Reviewed-by: Tom Rini <trini@konsulko.com>
>>
>> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> ---
>>  arch/arm/dts/ast2500-u-boot.dtsi                 |  53 +++
>>  arch/arm/dts/ast2500.dtsi                        | 174 +++++++++
>>  arch/arm/include/asm/arch-aspeed/scu_ast2500.h   | 125 +++++++
>>  arch/arm/include/asm/arch-aspeed/sdram_ast2500.h | 138 ++++++++
>>  arch/arm/mach-aspeed/Kconfig                     |   2 +
>>  arch/arm/mach-aspeed/Makefile                    |   1 +
>>  arch/arm/mach-aspeed/ast2500/Kconfig             |  14 +
>>  arch/arm/mach-aspeed/ast2500/Makefile            |   1 +
>>  arch/arm/mach-aspeed/ast2500/clk_ast2500.c       |  30 ++
>>  arch/arm/mach-aspeed/ast2500/sdram_ast2500.c     | 432 +++++++++++++++++++++++
>>  drivers/clk/Makefile                             |   2 +
>>  drivers/clk/aspeed/Makefile                      |   7 +
>>  drivers/clk/aspeed/clk_ast2500.c                 | 265 ++++++++++++++
>>  include/dt-bindings/clock/ast2500-scu.h          |  29 ++
>>  14 files changed, 1273 insertions(+)
>>  create mode 100644 arch/arm/dts/ast2500-u-boot.dtsi
>>  create mode 100644 arch/arm/dts/ast2500.dtsi
>>  create mode 100644 arch/arm/include/asm/arch-aspeed/scu_ast2500.h
>>  create mode 100644 arch/arm/include/asm/arch-aspeed/sdram_ast2500.h
>>  create mode 100644 arch/arm/mach-aspeed/ast2500/Kconfig
>>  create mode 100644 arch/arm/mach-aspeed/ast2500/Makefile
>>  create mode 100644 arch/arm/mach-aspeed/ast2500/clk_ast2500.c
>>  create mode 100644 arch/arm/mach-aspeed/ast2500/sdram_ast2500.c
>>  create mode 100644 drivers/clk/aspeed/Makefile
>>  create mode 100644 drivers/clk/aspeed/clk_ast2500.c
>>  create mode 100644 include/dt-bindings/clock/ast2500-scu.h
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> A few nits for later:
>
> I think it is better to define a shifted mask:
>
> #define SDRAM_REFRESH_PERIOD_SHIFT     8
> #define SDRAM_REFRESH_PERIOD_MASK      (0xf << SDRAM_REFRESH_PERIOD_SHIFT)
>
> What is CONFIG_DUALX8_RAM for? Can this be encoded in the device tree?

This should be used when the board has two DRAM PHY chips connected to
single controller. At least that's my understanding.
We don't use that configuration on any of our boards, so probably it
would be easier just to remove it.

>
> Regards,
> Simon



-- 
Maxim Sloyko

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

* [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-26 18:31             ` Maxim Sloyko
  0 siblings, 0 replies; 90+ messages in thread
From: Maxim Sloyko @ 2017-01-26 18:31 UTC (permalink / raw)
  To: u-boot

Simon,

I'll address your comments in followup cleanup, where I also created
-uclass for WDT. The main reason is that many pieces of the code you
commenting on will be gone.
That series is pretty much ready and I'll send it as soon as this one
gets in and I rebase it to new master.

Thank you!

On Thu, Jan 26, 2017 at 6:23 AM, Simon Glass <sjg@chromium.org> wrote:
> On 18 January 2017 at 14:44, Maxim Sloyko <maxims@google.com> wrote:
>> Add support for Watchdog Timer, which is compatible with AST2400 and
>> AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
>> does not follow the driver model. It also uses fixed clock, so no clock
>> driver is needed.
>>
>> Add support for timer for Aspeed ast2400/ast2500 devices.
>> The driver actually controls several devices, but because all devices
>> share the same Control Register, it is somewhat difficult to completely
>> decouple them. Since only one timer is needed at the moment, this should
>> be OK. The timer uses fixed clock, so does not rely on a clock driver.
>>
>> Add sysreset driver, which uses watchdog timer to do resets and particular
>> watchdog device to use is hardcoded (0)
>>
>> ---
>>
>> Changes in v4:
>> - Expanded AST2500 description in Kconfig
>> - Expanded ast_timer description in Kconfig
>> - Added struct ast_timer_counter to timer private data
>> - Use dev_get_addr_ptr in timer's of_platdata
>> - Added helper function to wdt for resetting peripherals
>>
>> Changes in v3:
>> - Added SYS_TEXT_BASE as Kconfig option
>>
>> Changes in v2:
>> - Moved number of WDTs to a Kconfig option
>>
>> Changes in v1:
>> - Merged together the patches related to aspeed common drivers and
>>   configuration
>> - Fixed timer driver name (was sandbox_timer)
>> - Removed yet nonexistent files from mach-aspeed/Makefile
>>
>>
>> Signed-off-by: Maxim Sloyko <maxims@google.com>
>> ---
>>  arch/arm/Kconfig                         |  7 +++
>>  arch/arm/Makefile                        |  1 +
>>  arch/arm/include/asm/arch-aspeed/timer.h | 54 +++++++++++++++++
>>  arch/arm/include/asm/arch-aspeed/wdt.h   | 99 ++++++++++++++++++++++++++++++++
>>  arch/arm/mach-aspeed/Kconfig             | 27 +++++++++
>>  arch/arm/mach-aspeed/Makefile            |  7 +++
>>  arch/arm/mach-aspeed/ast_wdt.c           | 59 +++++++++++++++++++
>>  drivers/sysreset/Makefile                |  1 +
>>  drivers/sysreset/sysreset_ast.c          | 55 ++++++++++++++++++
>>  drivers/timer/Kconfig                    | 12 ++++
>>  drivers/timer/Makefile                   |  1 +
>>  drivers/timer/ast_timer.c                | 97 +++++++++++++++++++++++++++++++
>>  12 files changed, 420 insertions(+)
>>  create mode 100644 arch/arm/include/asm/arch-aspeed/timer.h
>>  create mode 100644 arch/arm/include/asm/arch-aspeed/wdt.h
>>  create mode 100644 arch/arm/mach-aspeed/Kconfig
>>  create mode 100644 arch/arm/mach-aspeed/Makefile
>>  create mode 100644 arch/arm/mach-aspeed/ast_wdt.c
>>  create mode 100644 drivers/sysreset/sysreset_ast.c
>>  create mode 100644 drivers/timer/ast_timer.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Some comments below which you could do as part of your clean-up if you like.
>
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 714dd8b514..135c544335 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -882,8 +882,15 @@ config TARGET_THUNDERX_88XX
>>         select OF_CONTROL
>>         select SYS_CACHE_SHIFT_7
>>
>> +config ARCH_ASPEED
>> +       bool "Support Aspeed SoCs"
>> +       select OF_CONTROL
>> +       select DM
>> +
>>  endchoice
>>
>> +source "arch/arm/mach-aspeed/Kconfig"
>> +
>>  source "arch/arm/mach-at91/Kconfig"
>>
>>  source "arch/arm/mach-bcm283x/Kconfig"
>> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
>> index 236debb452..cc73e1038e 100644
>> --- a/arch/arm/Makefile
>> +++ b/arch/arm/Makefile
>> @@ -50,6 +50,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
>>
>>  # Machine directory name.  This list is sorted alphanumerically
>>  # by CONFIG_* macro name.
>> +machine-$(CONFIG_ARCH_ASPEED)          += aspeed
>>  machine-$(CONFIG_ARCH_AT91)            += at91
>>  machine-$(CONFIG_ARCH_BCM283X)         += bcm283x
>>  machine-$(CONFIG_ARCH_DAVINCI)         += davinci
>> diff --git a/arch/arm/include/asm/arch-aspeed/timer.h b/arch/arm/include/asm/arch-aspeed/timer.h
>> new file mode 100644
>> index 0000000000..87c5b354ec
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arch-aspeed/timer.h
>> @@ -0,0 +1,54 @@
>> +/*
>> + * Copyright (c) 2016 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +#ifndef _ASM_ARCH_TIMER_H
>> +#define _ASM_ARCH_TIMER_H
>> +
>> +/* Each timer has 4 control bits in ctrl1 register.
>> + * Timer1 uses bits 0:3, Timer2 uses bits 4:7 and so on,
>> + * such that timer X uses bits (4 * X - 4):(4 * X - 1)
>> + * If the timer does not support PWM, bit 4 is reserved.
>> + */
>> +#define AST_TMC_EN                     (1 << 0)
>> +#define AST_TMC_1MHZ                   (1 << 1)
>> +#define AST_TMC_OVFINTR                        (1 << 2)
>> +#define AST_TMC_PWM                    (1 << 3)
>> +
>> +/* Timers are counted from 1 in the datasheet. */
>> +#define AST_TMC_CTRL1_SHIFT(n)                 (4 * ((n) - 1))
>> +
>> +#define AST_TMC_RATE  (1000*1000)
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +/*
>> + * All timers share control registers, which makes it harder to make them
>> + * separate devices. Since only one timer is needed at the moment, making
>> + * it this just one device.
>> + */
>> +
>> +struct ast_timer_counter {
>> +       u32 status;
>> +       u32 reload_val;
>> +       u32 match1;
>> +       u32 match2;
>> +};
>> +
>> +struct ast_timer {
>> +       struct ast_timer_counter timers1[3];
>> +       u32 ctrl1;
>> +       u32 ctrl2;
>> +#ifdef CONFIG_ASPEED_AST2500
>> +       u32 ctrl3;
>> +       u32 ctrl1_clr;
>> +#else
>> +       u32 reserved[2];
>> +#endif
>
> We don't want have to #ifdefs in drivers. The driver should support
> both devices and use the compatible string to determine which is used.
> So here I think you can get rid of 'reserved'. Perhaps add a comment
> that these two registers don't exist on one device?
>
>> +       struct ast_timer_counter timers2[5];
>> +};
>> +
>> +#endif  /* __ASSEMBLY__ */
>> +
>> +#endif  /* _ASM_ARCH_TIMER_H */
>> diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h
>> new file mode 100644
>> index 0000000000..b292a0e67b
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arch-aspeed/wdt.h
>> @@ -0,0 +1,99 @@
>> +/*
>> + * (C) Copyright 2016 Google, Inc
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#ifndef _ASM_ARCH_WDT_H
>> +#define _ASM_ARCH_WDT_H
>> +
>> +#define WDT_BASE                       0x1e785000
>
> TODO(email): Use device tree to get this value
>
>> +
>> +/*
>> + * Special value that needs to be written to counter_restart register to
>> + * (re)start the timer
>> + */
>> +#define WDT_COUNTER_RESTART_VAL                0x4755
>> +
>> +/* Control register */
>> +#define WDT_CTRL_RESET_MODE_SHIFT      5
>> +#define WDT_CTRL_RESET_MODE_MASK       3
>> +
>> +#define WDT_CTRL_EN                    (1 << 0)
>> +#define WDT_CTRL_RESET                 (1 << 1)
>> +#define WDT_CTRL_CLK1MHZ               (1 << 4)
>> +#define WDT_CTRL_2ND_BOOT              (1 << 7)
>> +
>> +/* Values for Reset Mode */
>> +#define WDT_CTRL_RESET_SOC             0
>> +#define WDT_CTRL_RESET_CHIP            1
>> +#define WDT_CTRL_RESET_CPU             2
>> +#define WDT_CTRL_RESET_MASK            3
>> +
>> +/* Reset Mask register */
>> +#define WDT_RESET_ARM                  (1 << 0)
>> +#define WDT_RESET_COPROC               (1 << 1)
>> +#define WDT_RESET_SDRAM                        (1 << 2)
>> +#define WDT_RESET_AHB                  (1 << 3)
>> +#define WDT_RESET_I2C                  (1 << 4)
>> +#define WDT_RESET_MAC1                 (1 << 5)
>> +#define WDT_RESET_MAC2                 (1 << 6)
>> +#define WDT_RESET_GCRT                 (1 << 7)
>> +#define WDT_RESET_USB20                        (1 << 8)
>> +#define WDT_RESET_USB11_HOST           (1 << 9)
>> +#define WDT_RESET_USB11_EHCI2          (1 << 10)
>> +#define WDT_RESET_VIDEO                        (1 << 11)
>> +#define WDT_RESET_HAC                  (1 << 12)
>> +#define WDT_RESET_LPC                  (1 << 13)
>> +#define WDT_RESET_SDSDIO               (1 << 14)
>> +#define WDT_RESET_MIC                  (1 << 15)
>> +#define WDT_RESET_CRT2C                        (1 << 16)
>> +#define WDT_RESET_PWM                  (1 << 17)
>> +#define WDT_RESET_PECI                 (1 << 18)
>> +#define WDT_RESET_JTAG                 (1 << 19)
>> +#define WDT_RESET_ADC                  (1 << 20)
>> +#define WDT_RESET_GPIO                 (1 << 21)
>> +#define WDT_RESET_MCTP                 (1 << 22)
>> +#define WDT_RESET_XDMA                 (1 << 23)
>> +#define WDT_RESET_SPI                  (1 << 24)
>> +#define WDT_RESET_MISC                 (1 << 25)
>> +
>> +#ifndef __ASSEMBLY__
>> +struct ast_wdt {
>> +       u32 counter_status;
>> +       u32 counter_reload_val;
>> +       u32 counter_restart;
>> +       u32 ctrl;
>> +       u32 timeout_status;
>> +       u32 clr_timeout_status;
>> +       u32 reset_width;
>> +#ifdef CONFIG_ASPEED_AST2500
>> +       u32 reset_mask;
>> +#else
>> +       u32 reserved0;
>> +#endif
>
> Same here
>
>> +};
>> +
>> +void wdt_stop(struct ast_wdt *wdt);
>> +void wdt_start(struct ast_wdt *wdt, u32 timeout);
>> +
>> +/**
>> + * Reset peripherals specified by mask
>> + *
>> + * Note, that this is only supported by ast2500 SoC
>> + *
>> + * @wdt: watchdog to use for this reset
>> + * @mask: reset mask.
>
> @return?
>
>> + */
>> +int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask);
>> +
>> +/**
>> + * ast_get_wdt() - get a pointer to watchdog registers
>> + *
>> + * @wdt_number: 0-based WDT peripheral number
>> + * @return pointer to registers or -ve error on error
>> + */
>> +struct ast_wdt *ast_get_wdt(u8 wdt_number);
>> +#endif  /* __ASSEMBLY__ */
>> +
>> +#endif /* _ASM_ARCH_WDT_H */
>> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
>> new file mode 100644
>> index 0000000000..b72ed89af7
>> --- /dev/null
>> +++ b/arch/arm/mach-aspeed/Kconfig
>> @@ -0,0 +1,27 @@
>> +if ARCH_ASPEED
>> +
>> +config SYS_ARCH
>> +       default "arm"
>> +
>> +config SYS_SOC
>> +       default "aspeed"
>> +
>> +config SYS_TEXT_BASE
>> +       default 0x00000000
>> +
>> +config ASPEED_AST2500
>> +       bool "Support Aspeed AST2500 SoC"
>> +       select CPU_ARM1176
>> +       help
>> +         The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU.
>> +         It is used as Board Management Controller on many server boards,
>> +         which is enabled by support of LPC and eSPI peripherals.
>> +
>> +config WDT_NUM
>> +       int "Number of Watchdog Timers"
>> +       default 3 if ASPEED_AST2500
>> +       help
>> +         The number of Watchdot Timers on a SoC.
>> +         AST2500 has three WDTsk earlier versions have two or fewer.
>> +
>> +endif
>> diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
>> new file mode 100644
>> index 0000000000..a14b8f751d
>> --- /dev/null
>> +++ b/arch/arm/mach-aspeed/Makefile
>> @@ -0,0 +1,7 @@
>> +#
>> +# Copyright (c) 2016 Google, Inc
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
>> diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c
>> new file mode 100644
>> index 0000000000..22481ab7ea
>> --- /dev/null
>> +++ b/arch/arm/mach-aspeed/ast_wdt.c
>> @@ -0,0 +1,59 @@
>> +/*
>> + * (C) Copyright 2016 Google, Inc
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/wdt.h>
>> +#include <linux/err.h>
>> +
>> +void wdt_stop(struct ast_wdt *wdt)
>> +{
>> +       clrbits_le32(&wdt->ctrl, WDT_CTRL_EN);
>> +}
>> +
>> +void wdt_start(struct ast_wdt *wdt, u32 timeout)
>> +{
>> +       writel(timeout, &wdt->counter_reload_val);
>> +       writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart);
>> +       /*
>> +        * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
>> +        * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
>> +        * read-only
>> +        */
>> +       setbits_le32(&wdt->ctrl,
>> +                    WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ);
>> +}
>> +
>> +struct ast_wdt *ast_get_wdt(u8 wdt_number)
>> +{
>> +       if (wdt_number > CONFIG_WDT_NUM - 1)
>> +               return ERR_PTR(-EINVAL);
>> +
>> +       return (struct ast_wdt *)(WDT_BASE +
>> +                                 sizeof(struct ast_wdt) * wdt_number);
>> +}
>> +
>> +int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask)
>> +{
>> +#ifdef CONFIG_ASPEED_AST2500
>> +       if (!mask)
>> +               return -EINVAL;
>> +
>> +       writel(mask, &wdt->reset_mask);
>> +       clrbits_le32(&wdt->ctrl,
>> +                    WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT);
>> +       wdt_start(wdt, 1);
>> +
>> +       /* Wait for WDT to reset */
>> +       while (readl(&wdt->ctrl) & WDT_CTRL_EN)
>> +               ;
>> +       wdt_stop(wdt);
>> +
>> +       return 0;
>> +#else
>> +       return -EINVAL;
>> +#endif
>> +}
>> diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
>> index fa75cc52de..37638a8eea 100644
>> --- a/drivers/sysreset/Makefile
>> +++ b/drivers/sysreset/Makefile
>> @@ -14,3 +14,4 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
>>  obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
>>  obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
>>  obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
>> +obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
>> diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
>> new file mode 100644
>> index 0000000000..a0ab12851d
>> --- /dev/null
>> +++ b/drivers/sysreset/sysreset_ast.c
>> @@ -0,0 +1,55 @@
>> +/*
>> + * (C) Copyright 2016 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <errno.h>
>> +#include <sysreset.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/wdt.h>
>> +#include <linux/err.h>
>> +
>> +/* Number of Watchdog Timer ticks before reset */
>> +#define AST_WDT_RESET_TIMEOUT  10
>> +#define AST_WDT_FOR_RESET      0
>> +
>> +static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
>> +{
>> +       struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET);
>> +       u32 reset_mode = 0;
>> +
>> +       if (IS_ERR(wdt))
>> +               return PTR_ERR(wdt);
>> +
>> +       switch (type) {
>> +       case SYSRESET_WARM:
>> +               reset_mode = WDT_CTRL_RESET_CPU;
>> +               break;
>> +       case SYSRESET_COLD:
>> +               reset_mode = WDT_CTRL_RESET_CHIP;
>> +               break;
>> +       default:
>> +               return -EPROTONOSUPPORT;
>> +       }
>> +
>> +       /* Clear reset mode bits */
>> +       clrsetbits_le32(&wdt->ctrl,
>> +                       (WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT),
>> +                       (reset_mode << WDT_CTRL_RESET_MODE_SHIFT));
>> +       wdt_start(wdt, AST_WDT_RESET_TIMEOUT);
>> +
>> +       return -EINPROGRESS;
>> +}
>> +
>> +static struct sysreset_ops ast_sysreset = {
>> +       .request        = ast_sysreset_request,
>> +};
>> +
>> +U_BOOT_DRIVER(sysreset_ast) = {
>> +       .name   = "ast_sysreset",
>> +       .id     = UCLASS_SYSRESET,
>> +       .ops    = &ast_sysreset,
>> +};
>> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
>> index cb18f12fc9..cd38a6d4bd 100644
>> --- a/drivers/timer/Kconfig
>> +++ b/drivers/timer/Kconfig
>> @@ -46,4 +46,16 @@ config OMAP_TIMER
>>         help
>>           Select this to enable an timer for Omap devices.
>>
>> +config AST_TIMER
>> +       bool "Aspeed ast2400/ast2500 timer support"
>> +       depends on TIMER
>> +       default y if ARCH_ASPEED
>> +       help
>> +         Select this to enable timer for Aspeed ast2400/ast2500 devices.
>> +         This is a simple sys timer driver, it is compatible with lib/time.c,
>> +         but does not support any interrupts. Even though SoC has 8 hardware
>> +         counters, they are all treated as a single device by this driver.
>> +         This is mostly because they all share several registers which
>> +         makes it difficult to completely separate them.
>> +
>>  endmenu
>> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
>> index f351fbb4e0..a4b1a486b0 100644
>> --- a/drivers/timer/Makefile
>> +++ b/drivers/timer/Makefile
>> @@ -9,3 +9,4 @@ obj-$(CONFIG_ALTERA_TIMER)      += altera_timer.o
>>  obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
>>  obj-$(CONFIG_X86_TSC_TIMER)    += tsc_timer.o
>>  obj-$(CONFIG_OMAP_TIMER)       += omap-timer.o
>> +obj-$(CONFIG_AST_TIMER)        += ast_timer.o
>> diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
>> new file mode 100644
>> index 0000000000..d7c5460cd3
>> --- /dev/null
>> +++ b/drivers/timer/ast_timer.c
>> @@ -0,0 +1,97 @@
>> +/*
>> + * Copyright 2016 Google Inc.
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <errno.h>
>> +#include <timer.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/timer.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define AST_TICK_TIMER  1
>> +#define AST_TMC_RELOAD_VAL  0xffffffff
>> +
>> +struct ast_timer_priv {
>> +       struct ast_timer *regs;
>> +       struct ast_timer_counter *tmc;
>> +};
>> +
>> +static struct ast_timer_counter *ast_get_timer_counter(struct ast_timer *timer,
>> +                                                      int n)
>> +{
>> +       if (n > 3)
>> +               return &timer->timers2[n - 4];
>> +       else
>> +               return &timer->timers1[n - 1];
>> +}
>> +
>> +static int ast_timer_probe(struct udevice *dev)
>> +{
>> +       struct ast_timer_priv *priv = dev_get_priv(dev);
>> +       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
>> +
>> +       writel(AST_TMC_RELOAD_VAL, &priv->tmc->reload_val);
>> +
>> +       /*
>> +        * Stop the timer. This will also load reload_val into
>> +        * the status register.
>> +        */
>> +       clrbits_le32(&priv->regs->ctrl1,
>> +                    AST_TMC_EN << AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
>> +       /* Start the timer from the fixed 1MHz clock. */
>> +       setbits_le32(&priv->regs->ctrl1,
>> +                    (AST_TMC_EN | AST_TMC_1MHZ) <<
>> +                    AST_TMC_CTRL1_SHIFT(AST_TICK_TIMER));
>> +
>> +       uc_priv->clock_rate = AST_TMC_RATE;
>> +
>> +       return 0;
>> +}
>> +
>> +static int ast_timer_get_count(struct udevice *dev, u64 *count)
>> +{
>> +       struct ast_timer_priv *priv = dev_get_priv(dev);
>> +
>> +       *count = AST_TMC_RELOAD_VAL - readl(&priv->tmc->status);
>> +
>> +       return 0;
>> +}
>> +
>> +static int ast_timer_ofdata_to_platdata(struct udevice *dev)
>> +{
>> +       struct ast_timer_priv *priv = dev_get_priv(dev);
>> +
>> +       priv->regs = dev_get_addr_ptr(dev);
>> +       if (IS_ERR(priv->regs))
>> +               return PTR_ERR(priv->regs);
>> +
>> +       priv->tmc = ast_get_timer_counter(priv->regs, AST_TICK_TIMER);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct timer_ops ast_timer_ops = {
>> +       .get_count = ast_timer_get_count,
>> +};
>> +
>> +static const struct udevice_id ast_timer_ids[] = {
>> +       { .compatible = "aspeed,ast2500-timer" },
>> +       { .compatible = "aspeed,ast2400-timer" },
>
> Here you can put .data = ... and use an enum to select it. Then your
> driver can operate with either at runtime.
>
> Having said that I cannot see where ast_wdt_reset_masked() is called.
>
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(ast_timer) = {
>> +       .name = "ast_timer",
>> +       .id = UCLASS_TIMER,
>> +       .of_match = ast_timer_ids,
>> +       .probe = ast_timer_probe,
>> +       .priv_auto_alloc_size = sizeof(struct ast_timer_priv),
>> +       .ofdata_to_platdata = ast_timer_ofdata_to_platdata,
>> +       .ops = &ast_timer_ops,
>> +       .flags = DM_FLAG_PRE_RELOC,
>> +};
>> --
>> 2.11.0.483.g087da7b7c-goog
>>
>
> Regards,
> Simon



-- 
Maxim Sloyko

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

* [U-Boot] [U-Boot, v4, 1/4] aspeed: Add drivers common to all Aspeed SoCs
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-28 22:44           ` Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-28 22:44 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 01:44:55PM -0800, maxims at google.com wrote:

> Add support for Watchdog Timer, which is compatible with AST2400 and
> AST2500 watchdogs. There is no uclass for Watchdog yet, so the driver
> does not follow the driver model. It also uses fixed clock, so no clock
> driver is needed.
> 
> Add support for timer for Aspeed ast2400/ast2500 devices.
> The driver actually controls several devices, but because all devices
> share the same Control Register, it is somewhat difficult to completely
> decouple them. Since only one timer is needed at the moment, this should
> be OK. The timer uses fixed clock, so does not rely on a clock driver.
> 
> Add sysreset driver, which uses watchdog timer to do resets and particular
> watchdog device to use is hardcoded (0)
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170128/7573b1dc/attachment.sig>

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

* [U-Boot] [U-Boot, v4, 2/4] aspeed: Add basic ast2500-specific drivers and configuration
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-28 22:44           ` Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-28 22:44 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 01:44:56PM -0800, maxims at google.com wrote:

> Clock Driver
> 
> This driver is ast2500-specific and is not compatible with earlier
> versions of this chip. The differences are not that big, but they are
> in somewhat random places, so making it compatible with ast2400 is not
> worth the effort at the moment.
> 
> SDRAM MC driver
> 
> The driver is very ast2500-specific and is completely incompatible
> with previous versions of the chip.
> 
> The memory controller is very poorly documented by Aspeed in the
> datasheet, with any mention of the whole range of registers missing. The
> initialization procedure has been basically taken from Aspeed SDK, where
> it is implemented in assembly. Here it is rewritten in C, with very limited
> understanding of what exactly it is doing.
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170128/5bbe9019/attachment.sig>

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

* [U-Boot] [U-Boot, v4, 3/4] aspeed: Board init functions and common configs for ast2500 based boards
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-28 22:44           ` Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-28 22:44 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 01:44:57PM -0800, maxims at google.com wrote:

> Add configuration file with parameters that are very likely to be shared by
> all ast2500-based boards.
> Add ast2500-board.c file with the init code that is very likely to be
> shared by all ast2500-based boards.
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170128/8410b5e6/attachment.sig>

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

* [U-Boot] [U-Boot, v4, 4/4] aspeed: Support for ast2500 Eval Board
  2017-01-18 21:44         ` [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
  2017-01-26 14:23           ` Simon Glass
@ 2017-01-28 22:44           ` Tom Rini
  1 sibling, 0 replies; 90+ messages in thread
From: Tom Rini @ 2017-01-28 22:44 UTC (permalink / raw)
  To: u-boot

On Wed, Jan 18, 2017 at 01:44:58PM -0800, maxims at google.com wrote:

> ast2500 Eval Board device tree and board specific configuration.
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170128/96a9988c/attachment.sig>

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

end of thread, other threads:[~2017-01-28 22:44 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-04 19:46 [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 01/12] aspeed: Add mach-aspeed directory and basic Kconfig Maxim Sloyko
2017-01-04 19:58   ` Rick Altherr
2017-01-04 20:23     ` Tom Rini
2017-01-14 17:13   ` Simon Glass
2017-01-18  0:15     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 02/12] aspeed: Add support for Watchdot Timer Maxim Sloyko
2017-01-04 20:58   ` Tom Rini
2017-01-14 17:13   ` Simon Glass
2017-01-04 19:46 ` [U-Boot] [PATCH 03/12] aspeed: Add Timer Support Maxim Sloyko
2017-01-04 20:58   ` Tom Rini
2017-01-14 17:13   ` Simon Glass
2017-01-17 17:57     ` Maxim Sloyko
2017-01-17 21:37       ` Simon Glass
2017-01-17 23:59     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 04/12] aspeed: Add sysreset driver Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-04 19:46 ` [U-Boot] [PATCH 05/12] aspeed/ast2500: Device Tree and bindings for some of the clocks Maxim Sloyko
2017-01-04 20:58   ` Tom Rini
2017-01-05  1:18     ` Maxim Sloyko
2017-01-05  3:26       ` Tom Rini
2017-01-05 22:20         ` Maxim Sloyko
2017-01-14 17:13           ` Simon Glass
2017-01-17 23:27             ` Maxim Sloyko
2017-01-21  3:52               ` Simon Glass
2017-01-23 17:52                 ` Maxim Sloyko
2017-01-23 19:51                   ` Simon Glass
2017-01-04 19:46 ` [U-Boot] [PATCH 06/12] aspeed/ast2500: Add Clock Driver Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 23:18     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 07/12] aspeed/ast2500: Helper function to get access to SCU Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 22:27     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 08/12] aspeed/ast2500: Add SDRAM MC driver Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-18 20:16     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 09/12] aspeed/ast2500: Common board init functions for ast2500 based boards Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 20:17     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 10/12] aspeed: Common configuration parameters for aspeed boards Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 20:02     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 11/12] aspeed: Device Tree for ast2500 Eval Board Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 19:51     ` Maxim Sloyko
2017-01-04 19:46 ` [U-Boot] [PATCH 12/12] aspeed: Configuration for ast2500 eval board Maxim Sloyko
2017-01-14 17:14   ` Simon Glass
2017-01-17 19:46     ` Maxim Sloyko
2017-01-21  3:51       ` Simon Glass
2017-01-04 20:26 ` [U-Boot] [PATCH 00/12] arm: aspeed: Basic support for Aspeed AST2500 part and " Tom Rini
2017-01-04 22:47   ` Maxim Sloyko
2017-01-04 20:58 ` Tom Rini
2017-01-05 22:42 ` [U-Boot] [PATCH v1 0/4] " Maxim Sloyko
2017-01-05 22:42   ` [U-Boot] [PATCH v1 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
2017-01-05 22:42   ` [U-Boot] [PATCH v1 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
2017-01-05 22:42   ` [U-Boot] [PATCH v1 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
2017-01-05 22:42   ` [U-Boot] [PATCH v1 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
2017-01-10  1:50   ` [U-Boot] [PATCH v2 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
2017-01-10  1:50     ` [U-Boot] [PATCH v2 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
2017-01-11  3:20       ` Tom Rini
2017-01-10  1:50     ` [U-Boot] [PATCH v2 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
2017-01-11  3:20       ` Tom Rini
2017-01-10  1:50     ` [U-Boot] [PATCH v2 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
2017-01-11  3:20       ` Tom Rini
2017-01-11 23:40         ` Maxim Sloyko
2017-01-10  1:50     ` [U-Boot] [PATCH v2 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
2017-01-11  3:20       ` Tom Rini
2017-01-11 23:45     ` [U-Boot] [PATCH v3 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
2017-01-11 23:45       ` [U-Boot] [PATCH v3 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
2017-01-13  0:51         ` Tom Rini
2017-01-11 23:45       ` [U-Boot] [PATCH v3 2/4] aspeed: Add basic ast2500 specific drivers and configuration Maxim Sloyko
2017-01-11 23:45       ` [U-Boot] [PATCH v3 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
2017-01-13  0:51         ` Tom Rini
2017-01-11 23:45       ` [U-Boot] [PATCH v3 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
2017-01-13  0:51         ` Tom Rini
2017-01-18 21:44       ` [U-Boot] [PATCH v4 0/4] arm: aspeed: Basic support for Aspeed AST2500 part and eval board Maxim Sloyko
2017-01-18 21:44         ` [U-Boot] [PATCH v4 1/4] aspeed: Add drivers common to all Aspeed SoCs Maxim Sloyko
2017-01-26 14:23           ` Simon Glass
2017-01-26 18:31             ` Maxim Sloyko
2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
2017-01-18 21:44         ` [U-Boot] [PATCH v4 2/4] aspeed: Add basic ast2500-specific drivers and configuration Maxim Sloyko
2017-01-26 14:23           ` Simon Glass
2017-01-26 18:02             ` Maxim Sloyko
2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
2017-01-18 21:44         ` [U-Boot] [PATCH v4 3/4] aspeed: Board init functions and common configs for ast2500 based boards Maxim Sloyko
2017-01-26 14:23           ` Simon Glass
2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini
2017-01-18 21:44         ` [U-Boot] [PATCH v4 4/4] aspeed: Support for ast2500 Eval Board Maxim Sloyko
2017-01-26 14:23           ` Simon Glass
2017-01-28 22:44           ` [U-Boot] [U-Boot, v4, " Tom Rini

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.