From bd89fba2024305ae301fa7df80848b8d3e13efaf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 15 Feb 2017 09:10:16 +0100 Subject: arm64: zynqmp: Wire SD1 level shifter mode to SPL Add missing SD boot mode to SPL. zcu102-rev1.0 is supporting this boot mode. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/spl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 0a5f4306e8..7b78d23cf8 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -83,6 +83,7 @@ u32 spl_boot_device(void) case JTAG_MODE: return BOOT_DEVICE_RAM; #ifdef CONFIG_SPL_MMC_SUPPORT + case SD1_LSHFT_MODE: case EMMC_MODE: case SD_MODE: case SD_MODE1: -- cgit From e3fdf5d05659dbe5ce3f9661a4eb3202005b2be2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Sun, 2 Apr 2017 21:44:34 -0400 Subject: arm64: zynqmp: spl: fix dual SD controller support When enabling both SDHCI controllers, spl_mmc.c would actually choose device sdhci0 even if booted from sdhci1 (boot_device). This is because spl_mmc_get_device_index(boot_device) expects BOOT_DEVICE_MMC2[_2] in order to return index 1 instead of 0. The #if defined(...) statement is copied from board/xilinx/zynqmp/zynqmp.c So the key to properly enabling both controllers as boot sources is defining both CONFIG_ZYNQ_SDHCI0 and CONFIG_ZYNQ_SDHCI1 in your board's include/configs/*.h. Signed-off-by: Jean-Francois Dagenais Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/spl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 7b78d23cf8..6afa0740d0 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -83,10 +83,15 @@ u32 spl_boot_device(void) case JTAG_MODE: return BOOT_DEVICE_RAM; #ifdef CONFIG_SPL_MMC_SUPPORT + case SD_MODE1: case SD1_LSHFT_MODE: - case EMMC_MODE: +/* 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 SD_MODE1: + case EMMC_MODE: return BOOT_DEVICE_MMC1; #endif #ifdef CONFIG_SPL_DFU_SUPPORT @@ -111,6 +116,7 @@ u32 spl_boot_mode(const u32 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"); -- cgit From 8bf62ae7da0eea6a152a9d76d009fb79113a3119 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Sun, 2 Apr 2017 21:44:35 -0400 Subject: arm64: zynqmp: spl: use given boot_device instead of fetching it again The boot_device argument to spl_boot_mode was massively added without actually modifying the existing functions. This commit actually makes use of the handed value, which is the same. Signed-off-by: Jean-Francois Dagenais Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 6afa0740d0..db7432fd4b 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -112,7 +112,7 @@ 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: -- cgit From b0259c840ecd7ec35ebc5acad061bd6e2bcc847d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 2 Mar 2017 11:02:55 +0100 Subject: arm64: zynqmp: Add comment about level shifter mode v1 Silicon v1 didn't support SD boot mode with level shifter. Because system can't boot any error message is not shown that's why comment is just a record if someone tries to debug it. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index db7432fd4b..26bf80ec52 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -84,7 +84,7 @@ u32 spl_boot_device(void) return BOOT_DEVICE_RAM; #ifdef CONFIG_SPL_MMC_SUPPORT case SD_MODE1: - case SD1_LSHFT_MODE: + 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; -- cgit From 6a1d91be318b44365dfe095a9ca7df1619abefc9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sat, 25 Feb 2017 18:17:11 +0100 Subject: arm64: zynqmp: Do not map unused OCM/TCM region When OCM or TCM is protected this mapping still exist and it is causing access violation. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/cpu.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index b0f12955a1..280e07ad36 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -37,12 +37,6 @@ static struct mm_region zynqmp_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 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, -- cgit From d84bd9284ea05412928e5b95d4aaebfce18fef7c Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 12 May 2017 15:04:11 +0530 Subject: arm: zynq: Add Kconfig option for any DDR specific initialization Add Kconfig option for ddr init as this might be required in cases like ddr less systems where we want to skip ddrc init and this option is useful for it. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/mach-zynq/Kconfig | 8 ++++++++ arch/arm/mach-zynq/ddrc.c | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'arch/arm') 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 -- cgit From e0752bc18422ec0dc93a770e96b1c2f44ee64ed7 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Thu, 2 Feb 2017 01:10:46 +0530 Subject: arm64: zynqmp: Define routines for mmio write and read Define routines of mmio write and read functionalities for zynqmp platform. Also do not call SMC from SPL because SPL is running before ATF in EL3 that's why SMCs can't be called because there is nothing to call. zynqmp_mmio*() are doing direct read/write accesses and this patch does the same. PMUFW is up and running at this time and there is a way to talk to pmufw via IPI but there is no reason to implement IPI stuff in SPL if we need just simple read for getting clock driver to work. Also make invoke_smc as global so that it can be reused in multile places where ever possible. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/cpu.c | 73 ++++++++++++++++++++++++++++ arch/arm/include/asm/arch-zynqmp/sys_proto.h | 7 +++ 2 files changed, 80 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 280e07ad36..f7ed179c18 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -98,3 +98,76 @@ 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(®s); + + 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]; +} + +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/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index 7b11895481..4ae1bb6eef 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,9 @@ void psu_init(void); void handoff_setup(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 */ -- cgit From fb4000e87178bf20aeb0d6c6a71b0e25ff8dcda3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 7 Feb 2017 14:32:26 +0100 Subject: arm64: zynqmp: Check pmufw version If PMUFW version is not v0.3 then panic. ZynqMP switch to CCF based clock driver which requires PMUFW to be present at certain version. This patch ensure that you use correct and tested PMUFW binary. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/cpu.c | 35 ++++++++++++++++++++++++++++ arch/arm/include/asm/arch-zynqmp/sys_proto.h | 1 + 2 files changed, 36 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index f7ed179c18..94ecf90660 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -129,6 +129,41 @@ int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, 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) diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index 4ae1bb6eef..d91d98a119 100644 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h @@ -18,6 +18,7 @@ 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, -- cgit From e625881ad77c7cc0ffc39376ae32179c933b3710 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Wed, 7 Jun 2017 07:42:38 +0200 Subject: arm: zynq: Add support for the topic-miamilite system-on-module The topic-miamilite SoM contains a Zynq xc7z010 SoC, 1GB DDR3L RAM, 64MB dual-parallel QSPI NOR flash and clock sources. Signed-off-by: Mike Looijmans Signed-off-by: Michal Simek --- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-topic-miamilite.dts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 arch/arm/dts/zynq-topic-miamilite.dts (limited to 'arch/arm') diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 61a72186b1..dd6d1daf3e 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>; +}; -- cgit