summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2016-04-08 00:27:11 +0200
committerKlaus Goger <klaus.goger@theobroma-systems.com>2016-09-18 13:45:14 +0200
commit2b9c186d3c66addaec852774b7b2e98358feb03c (patch)
tree4f7c2ffb15ccce26deea3d72d9a171b137abcd8d /arch
parent9329adc4c7efa2e56a529960969a5ea47082ed15 (diff)
sunxi: add gtbus-initialisation for sun9i
On sun9i, the GTBUS manages transaction priority and bandwidth for multiple read ports when accessing DRAM. The initialisation mirrors the settings from Allwinner's boot0 for now, even though this may not be optimal for all applications (e.g. headless systems might want to give priority to IO modules). Adding a common callout to gtbus_init() from the SPL clock init with a weakly defined implementation in sunxi/clock.c to fallback to for platforms that don't require this.
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile1
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock.c6
-rw-r--r--arch/arm/cpu/armv7/sunxi/gtbus_sun9i.c42
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun9i.h2
-rw-r--r--arch/arm/include/asm/arch-sunxi/gtbus.h21
-rw-r--r--arch/arm/include/asm/arch-sunxi/gtbus_sun9i.h89
6 files changed, 161 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 229dd63138..0d6335abea 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -32,6 +32,7 @@ else
obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o
endif
obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o
+obj-$(CONFIG_MACH_SUN9I) += gtbus_sun9i.o
obj-$(CONFIG_MACH_SUN6I) += tzpc.o
obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
index 0b8fc94711..e6f53f91e6 100644
--- a/arch/arm/cpu/armv7/sunxi/clock.c
+++ b/arch/arm/cpu/armv7/sunxi/clock.c
@@ -13,16 +13,22 @@
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/arch/prcm.h>
+#include <asm/arch/gtbus.h>
#include <asm/arch/sys_proto.h>
__weak void clock_init_sec(void)
{
}
+__weak void gtbus_init(void)
+{
+}
+
int clock_init(void)
{
#ifdef CONFIG_SPL_BUILD
clock_init_safe();
+ gtbus_init();
#endif
clock_init_uart();
clock_init_sec();
diff --git a/arch/arm/cpu/armv7/sunxi/gtbus_sun9i.c b/arch/arm/cpu/armv7/sunxi/gtbus_sun9i.c
new file mode 100644
index 0000000000..122a874cde
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/gtbus_sun9i.c
@@ -0,0 +1,42 @@
+/*
+ * GTBUS initialisation for sun9i
+ *
+ * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
+ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gtbus_sun9i.h>
+#include <asm/arch/sys_proto.h>
+
+#ifdef CONFIG_SPL_BUILD
+
+void gtbus_init(void)
+{
+ struct sunxi_gtbus_reg * const gtbus =
+ (struct sunxi_gtbus_reg *)SUNXI_GTBUS_BASE;
+
+ /* We use the same setting that Allwinner used in Boot0 for now. It may be
+ advantageous to adjust these for various workloads (e.g. headless use cases
+ that focus on IO throughput). */
+ writel((GT_PRIO_HIGH << GT_PORT_FE0) | (GT_PRIO_HIGH << GT_PORT_BE1)
+ | (GT_PRIO_HIGH << GT_PORT_BE2) | (GT_PRIO_HIGH << GT_PORT_IEP0)
+ | (GT_PRIO_HIGH << GT_PORT_FE1) | (GT_PRIO_HIGH << GT_PORT_BE0)
+ | (GT_PRIO_HIGH << GT_PORT_FE2) | (GT_PRIO_HIGH << GT_PORT_IEP1),
+ &gtbus->mst_read_prio_cfg[0]);
+
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_FE0]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_FE0]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_BE1]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_BE2]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_IEP0]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_FE1]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_BE0]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_FE2]);
+ writel(GP_MST_CFG_DEFAULT, &gtbus->mst_cfg[GT_PORT_IEP1]);
+}
+
+#endif
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
index 00ffeca553..8ace4e7cb0 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
@@ -23,6 +23,8 @@
#define SUNXI_NFC_BASE (REGS_AHB0_BASE + 0x3000)
#define SUNXI_TSC_BASE (REGS_AHB0_BASE + 0x4000)
+#define SUNXI_GTBUS_BASE (REGS_AHB0_BASE + 0x9000)
+
#define SUNXI_MMC0_BASE (REGS_AHB0_BASE + 0x0f000)
#define SUNXI_MMC1_BASE (REGS_AHB0_BASE + 0x10000)
#define SUNXI_MMC2_BASE (REGS_AHB0_BASE + 0x11000)
diff --git a/arch/arm/include/asm/arch-sunxi/gtbus.h b/arch/arm/include/asm/arch-sunxi/gtbus.h
new file mode 100644
index 0000000000..b8308d5135
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/gtbus.h
@@ -0,0 +1,21 @@
+/*
+ * GTBUS initialisation
+ *
+ * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
+ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SUNXI_GTBUS_H
+#define _SUNXI_GTBUS_H
+
+#if defined(CONFIG_MACH_SUN9I)
+#include <asm/arch/gtbus_sun9i.h>
+#endif
+
+#ifndef __ASSEMBLY__
+void gtbus_init(void);
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-sunxi/gtbus_sun9i.h b/arch/arm/include/asm/arch-sunxi/gtbus_sun9i.h
new file mode 100644
index 0000000000..91bc2bdb51
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/gtbus_sun9i.h
@@ -0,0 +1,89 @@
+/*
+ * GTBUS initialisation for sun9i
+ *
+ * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
+ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SUNXI_GTBUS_SUN9I_H
+#define _SUNXI_GTBUS_SUN9I_H
+
+#include <linux/types.h>
+
+struct sunxi_gtbus_reg {
+ u32 mst_cfg[36]; /* 0x000 */
+ u8 reserved1[0x70]; /* 0x090 */
+ u32 bw_wdw_cfg; /* 0x100 */
+ u32 mst_read_prio_cfg[2]; /* 0x104 */
+ u32 lvl2_mst_cfg; /* 0x10c */
+ u32 sw_clk_on; /* 0x110 */
+ u32 sw_clk_off; /* 0x114 */
+ u32 pmu_mst_en; /* 0x118 */
+ u32 pmu_cfg; /* 0x11c */
+ u32 pmu_cnt[19]; /* 0x120 */
+ u32 reserved2[0x94]; /* 0x16c */
+ u32 cci400_config[3]; /* 0x200 */
+ u32 cci400_status[2]; /* 0x20c */
+};
+
+/* for register GT_MST_CFG_REG(n) */
+#define GT_ENABLE_REQ (1<<31) /* clock on */
+#define GT_DISABLE_REQ (1<<30) /* clock off */
+#define GT_QOS_SHIFT 28
+#define GT_THD1_SHIFT 16
+#define GT_REQN_MAX 0xf /* max number master requests in one cycle */
+#define GT_REQN_SHIFT 12
+#define GT_THD0_SHIFT 0
+
+#define GT_QOS_MAX 0x3
+#define GT_THD_MAX 0xfff
+#define GT_BW_WDW_MAX 0xffff
+
+/* mst_read_prio_cfg */
+#define GT_PRIO_LOW 0
+#define GT_PRIO_HIGH 1
+
+/* GTBUS port ids */
+#define GT_PORT_CPUM1 0
+#define GT_PORT_CPUM2 1
+#define GT_PORT_SATA 2
+#define GT_PORT_USB3 3
+#define GT_PORT_FE0 4
+#define GT_PORT_BE1 5
+#define GT_PORT_BE2 6
+#define GT_PORT_IEP0 7
+#define GT_PORT_FE1 8
+#define GT_PORT_BE0 9
+#define GT_PORT_FE2 10
+#define GT_PORT_IEP1 11
+#define GT_PORT_VED 12
+#define GT_PORT_VEE 13
+#define GT_PORT_FD 14
+#define GT_PORT_CSI 15
+#define GT_PORT_MP 16
+#define GT_PORT_HSI 17
+#define GT_PORT_SS 18
+#define GT_PORT_TS 19
+#define GT_PORT_DMA 20
+#define GT_PORT_NDFC0 21
+#define GT_PORT_NDFC1 22
+#define GT_PORT_CPUS 23
+#define GT_PORT_TH 24
+#define GT_PORT_GMAC 25
+#define GT_PORT_USB0 26
+#define GT_PORT_MSTG0 27
+#define GT_PORT_MSTG1 28
+#define GT_PORT_MSTG2 29
+#define GT_PORT_MSTG3 30
+#define GT_PORT_USB1 31
+#define GT_PORT_GPU0 32
+#define GT_PORT_GPU1 33
+#define GT_PORT_USB2 34
+#define GT_PORT_CPUM0 35
+
+#define GP_MST_CFG_DEFAULT ((GT_QOS_MAX << GT_QOS_SHIFT) | (GT_THD_MAX << GT_THD1_SHIFT) \
+ | (GT_REQN_MAX << GT_REQN_SHIFT) | (GT_THD_MAX << GT_THD0_SHIFT))
+
+#endif