summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-06-21 07:57:37 -0400
committerTom Rini <trini@konsulko.com>2017-06-21 07:57:37 -0400
commit784667d7f9452780966dd0b400ef516f14f14c26 (patch)
treec4aa03175bd50b85ee37c43b7e23f44affb9165d /arch/arm
parent2aaf7c49002d2595887d6d90001b7adee7a90a36 (diff)
parente625881ad77c7cc0ffc39376ae32179c933b3710 (diff)
Merge tag 'xilinx-for-v2017.07' of git://www.denx.de/git/u-boot-microblaze
Xilinx changes for v2017.07 ZynqMP: - config cleanup - SD LS mode support - psu_init* cleanup - unmap OCM - Support for SMC Zynq: - add ddrc to Kconfig - add topic-miamilite board support
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c114
-rw-r--r--arch/arm/cpu/armv8/zynqmp/spl.c13
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/zynq-topic-miamilite.dts17
-rw-r--r--arch/arm/include/asm/arch-zynqmp/sys_proto.h8
-rw-r--r--arch/arm/mach-zynq/Kconfig8
-rw-r--r--arch/arm/mach-zynq/ddrc.c4
7 files changed, 156 insertions, 9 deletions
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index b0f12955a1..94ecf90660 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -38,12 +38,6 @@ static struct mm_region zynqmp_mem_map[] = {
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .virt = 0xffe00000UL,
- .phys = 0xffe00000UL,
- .size = 0x00200000UL,
- .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE
- }, {
.virt = 0x400000000UL,
.phys = 0x400000000UL,
.size = 0x200000000UL,
@@ -104,3 +98,111 @@ unsigned int zynqmp_get_silicon_version(void)
return ZYNQMP_CSU_VERSION_SILICON;
}
+
+#define ZYNQMP_MMIO_READ 0xC2000014
+#define ZYNQMP_MMIO_WRITE 0xC2000013
+
+#ifndef CONFIG_SPL_BUILD
+int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
+ u32 *ret_payload)
+{
+ /*
+ * Added SIP service call Function Identifier
+ * Make sure to stay in x0 register
+ */
+ struct pt_regs regs;
+
+ regs.regs[0] = pm_api_id;
+ regs.regs[1] = ((u64)arg1 << 32) | arg0;
+ regs.regs[2] = ((u64)arg3 << 32) | arg2;
+
+ smc_call(&regs);
+
+ if (ret_payload != NULL) {
+ ret_payload[0] = (u32)regs.regs[0];
+ ret_payload[1] = upper_32_bits(regs.regs[0]);
+ ret_payload[2] = (u32)regs.regs[1];
+ ret_payload[3] = upper_32_bits(regs.regs[1]);
+ ret_payload[4] = (u32)regs.regs[2];
+ }
+
+ return regs.regs[0];
+}
+
+#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001
+
+#define ZYNQMP_PM_VERSION_MAJOR 0
+#define ZYNQMP_PM_VERSION_MINOR 3
+#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16
+#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF
+
+#define ZYNQMP_PM_VERSION \
+ ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \
+ ZYNQMP_PM_VERSION_MINOR)
+
+#if defined(CONFIG_CLK_ZYNQMP)
+void zynqmp_pmufw_version(void)
+{
+ int ret;
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ u32 pm_api_version;
+
+ ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0,
+ ret_payload);
+ pm_api_version = ret_payload[1];
+
+ if (ret)
+ panic("PMUFW is not found - Please load it!\n");
+
+ printf("PMUFW:\tv%d.%d\n",
+ pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
+ pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
+
+ if (pm_api_version != ZYNQMP_PM_VERSION)
+ panic("PMUFW version error. Expected: v%d.%d\n",
+ ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
+}
+#endif
+
+int zynqmp_mmio_write(const u32 address,
+ const u32 mask,
+ const u32 value)
+{
+ return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask, value, 0, NULL);
+}
+
+int zynqmp_mmio_read(const u32 address, u32 *value)
+{
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ u32 ret;
+
+ if (!value)
+ return -EINVAL;
+
+ ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0, 0, ret_payload);
+ *value = ret_payload[1];
+
+ return ret;
+}
+#else
+int zynqmp_mmio_write(const u32 address,
+ const u32 mask,
+ const u32 value)
+{
+ u32 data;
+ u32 value_local = value;
+
+ zynqmp_mmio_read(address, &data);
+ data &= ~mask;
+ value_local &= mask;
+ value_local |= data;
+ writel(value_local, (ulong)address);
+ return 0;
+}
+
+int zynqmp_mmio_read(const u32 address, u32 *value)
+{
+ *value = readl((ulong)address);
+ return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c
index 0a5f4306e8..26bf80ec52 100644
--- a/arch/arm/cpu/armv8/zynqmp/spl.c
+++ b/arch/arm/cpu/armv8/zynqmp/spl.c
@@ -83,9 +83,15 @@ u32 spl_boot_device(void)
case JTAG_MODE:
return BOOT_DEVICE_RAM;
#ifdef CONFIG_SPL_MMC_SUPPORT
- case EMMC_MODE:
- case SD_MODE:
case SD_MODE1:
+ case SD1_LSHFT_MODE: /* not working on silicon v1 */
+/* if both controllers enabled, then these two are the second controller */
+#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
+ return BOOT_DEVICE_MMC2;
+/* else, fall through, the one SDHCI controller that is enabled is number 1 */
+#endif
+ case SD_MODE:
+ case EMMC_MODE:
return BOOT_DEVICE_MMC1;
#endif
#ifdef CONFIG_SPL_DFU_SUPPORT
@@ -106,10 +112,11 @@ u32 spl_boot_device(void)
u32 spl_boot_mode(const u32 boot_device)
{
- switch (spl_boot_device()) {
+ switch (boot_device) {
case BOOT_DEVICE_RAM:
return 0;
case BOOT_DEVICE_MMC1:
+ case BOOT_DEVICE_MMC2:
return MMCSD_MODE_FS;
default:
puts("spl: error: unsupported device\n");
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7b405e5c93..a01c9b60b3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -127,6 +127,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
zynq-microzed.dtb \
zynq-picozed.dtb \
zynq-topic-miami.dtb \
+ zynq-topic-miamilite.dtb \
zynq-topic-miamiplus.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm011.dtb \
diff --git a/arch/arm/dts/zynq-topic-miamilite.dts b/arch/arm/dts/zynq-topic-miamilite.dts
new file mode 100644
index 0000000000..f88cb4bf98
--- /dev/null
+++ b/arch/arm/dts/zynq-topic-miamilite.dts
@@ -0,0 +1,17 @@
+/*
+ * Topic Miami Lite board DTS
+ *
+ * Copyright (C) 2017 Topic Embedded Products
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include "zynq-topic-miami.dts"
+
+/ {
+ model = "Topic Miami Lite Zynq Board";
+ compatible = "topic,miamilite", "xlnx,zynq-7000";
+};
+
+&qspi {
+ is-dual = <1>;
+};
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 7b11895481..d91d98a119 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -8,6 +8,8 @@
#ifndef _ASM_ARCH_SYS_PROTO_H
#define _ASM_ARCH_SYS_PROTO_H
+#define PAYLOAD_ARG_CNT 5
+
int zynq_slcr_get_mio_pin_status(const char *periph);
unsigned int zynqmp_get_silicon_version(void);
@@ -16,4 +18,10 @@ void psu_init(void);
void handoff_setup(void);
+void zynqmp_pmufw_version(void);
+int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value);
+int zynqmp_mmio_read(const u32 address, u32 *value);
+int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
+ u32 *ret_payload);
+
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index 2529c9ff44..c428ce5cc7 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -24,6 +24,14 @@ config SPL_SPI_FLASH_SUPPORT
config SPL_SPI_SUPPORT
default y if ZYNQ_QSPI
+config ZYNQ_DDRC_INIT
+ bool "Zynq DDRC initialization"
+ default y
+ help
+ This option used to perform DDR specific initialization
+ if required. There might be cases like ddr less where we
+ want to skip ddr init and this option is useful for it.
+
config SYS_BOARD
default "zynq"
diff --git a/arch/arm/mach-zynq/ddrc.c b/arch/arm/mach-zynq/ddrc.c
index d74f8dbbc4..bde52d6562 100644
--- a/arch/arm/mach-zynq/ddrc.c
+++ b/arch/arm/mach-zynq/ddrc.c
@@ -12,6 +12,9 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_ZYNQ_DDRC_INIT
+void zynq_ddrc_init(void) {}
+#else
/* Control regsiter bitfield definitions */
#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK 0xC
#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT 2
@@ -46,3 +49,4 @@ void zynq_ddrc_init(void)
puts("ECC disabled ");
}
}
+#endif