From 8944f0e430312176db618706b599bc3825c881a3 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:20 +0100 Subject: ARM: zynq: zedboard: enable MACB driver in defconfig The board support is a bit more useful with active networking. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/configs/zedboard_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/zedboard_defconfig b/arch/arm/configs/zedboard_defconfig index cc03368751..be5720fd42 100644 --- a/arch/arm/configs/zedboard_defconfig +++ b/arch/arm/configs/zedboard_defconfig @@ -40,6 +40,7 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_NET=y CONFIG_DRIVER_SERIAL_CADENCE=y +CONFIG_DRIVER_NET_MACB=y # CONFIG_SPI is not set CONFIG_FS_TFTP=y CONFIG_DIGEST=y -- cgit v1.2.3 From d74176dee9b7d36258c5c69fe63dcbf4d795d6ff Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:21 +0100 Subject: ARM: zynq: add trivial image build mechanism Currently this just calls the zynq_mkimage script to stamp in the header checksum. Can be extended to a proper multi-image build later on. This requires a PBL to be build, but as the only supported Zynq board already selects the PBL option in the defconfig there is no big change to the previous status Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/Kconfig | 1 + arch/arm/configs/zedboard_defconfig | 1 - images/Makefile | 3 ++- images/Makefile.zynq | 12 ++++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 images/Makefile.zynq diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9589a6a511..6eb117487e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -250,6 +250,7 @@ config ARCH_UEMD config ARCH_ZYNQ bool "Xilinx Zynq-based boards" select HAS_DEBUG_LL + select PBL_IMAGE config ARCH_ZYNQMP bool "Xilinx ZynqMP-based boards" diff --git a/arch/arm/configs/zedboard_defconfig b/arch/arm/configs/zedboard_defconfig index be5720fd42..0e5078c402 100644 --- a/arch/arm/configs/zedboard_defconfig +++ b/arch/arm/configs/zedboard_defconfig @@ -1,7 +1,6 @@ CONFIG_ARCH_ZYNQ=y CONFIG_AEABI=y CONFIG_ARM_UNWIND=y -CONFIG_PBL_IMAGE=y CONFIG_MMU=y CONFIG_STACK_SIZE=0xf000 CONFIG_MALLOC_SIZE=0x8000000 diff --git a/images/Makefile b/images/Makefile index ceb00618d2..34b7a56101 100644 --- a/images/Makefile +++ b/images/Makefile @@ -161,6 +161,7 @@ include $(srctree)/images/Makefile.tegra include $(srctree)/images/Makefile.vexpress include $(srctree)/images/Makefile.xburst include $(srctree)/images/Makefile.at91 +include $(srctree)/images/Makefile.zynq include $(srctree)/images/Makefile.zynqmp include $(srctree)/images/Makefile.layerscape @@ -208,5 +209,5 @@ $(flash-list): $(image-y-path) clean-files := *.pbl *.pblb *.map start_*.imximg *.img barebox.z start_*.kwbimg \ start_*.kwbuartimg *.socfpgaimg *.mlo *.t20img *.t20img.cfg *.t30img \ *.t30img.cfg *.t124img *.t124img.cfg *.mlospi *.mlo *.mxsbs *.mxssd \ - start_*.simximg start_*.usimximg *.image + start_*.simximg start_*.usimximg *.zynqimg *.image clean-files += pbl.lds diff --git a/images/Makefile.zynq b/images/Makefile.zynq new file mode 100644 index 0000000000..e162aafae3 --- /dev/null +++ b/images/Makefile.zynq @@ -0,0 +1,12 @@ +# +# barebox image generation Makefile for Xilinx Zynq images +# +quiet_cmd_zynq_image = ZYNQIMG $@ + cmd_zynq_image = $(objtree)/scripts/zynq_mkimage $(subst .zynqimg,,$@) $@ +$(obj)/%.zynqimg: $(obj)/% FORCE + $(call if_changed,zynq_image) + +#------------------------------------------------------------------------------ + +FILE_barebox-avnet-zedboard.img = start_pbl.pblb.zynqimg +image-$(CONFIG_MACH_ZEDBOARD) += barebox-avnet-zedboard.img -- cgit v1.2.3 From b2142963ef7391229dbe5021d72bbb209f53a8dd Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:22 +0100 Subject: ARM: zynq: use getopt in zynq_mkimage Makes extending the command line much easier. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- images/Makefile.zynq | 4 +++- scripts/zynq_mkimage.c | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/images/Makefile.zynq b/images/Makefile.zynq index e162aafae3..cc0cf6d2df 100644 --- a/images/Makefile.zynq +++ b/images/Makefile.zynq @@ -2,7 +2,9 @@ # barebox image generation Makefile for Xilinx Zynq images # quiet_cmd_zynq_image = ZYNQIMG $@ - cmd_zynq_image = $(objtree)/scripts/zynq_mkimage $(subst .zynqimg,,$@) $@ + cmd_zynq_image = \ + $(objtree)/scripts/zynq_mkimage -f $(subst .zynqimg,,$@) -o $@ + $(obj)/%.zynqimg: $(obj)/% FORCE $(call if_changed,zynq_image) diff --git a/scripts/zynq_mkimage.c b/scripts/zynq_mkimage.c index a096b834d1..905d6fc69a 100644 --- a/scripts/zynq_mkimage.c +++ b/scripts/zynq_mkimage.c @@ -14,33 +14,58 @@ #include #include +#include #include #include #include #include +static char *prgname; + static void usage(char *name) { - printf("Usage: %s barebox-flash-image \n", name); + fprintf(stderr, "usage: %s [OPTIONS]\n\n" + "-f input image file\n" + "-o output file\n" + "-h this help\n", prgname); + exit(1); } int main(int argc, char *argv[]) { FILE *ifile, *ofile; unsigned int *buf; - const char *infile; - const char *outfile; + const char *infile = NULL, *outfile = NULL; struct stat st; - unsigned int i; - unsigned long sum = 0; + unsigned int i,sum = 0; + int opt; - if (argc != 3) { - usage(argv[0]); + prgname = argv[0]; + + while ((opt = getopt(argc, argv, "f:ho:")) != -1) { + switch (opt) { + case 'f': + infile = optarg; + break; + case 'o': + outfile = optarg; + break; + case 'h': + usage(argv[0]); + default: + exit(1); + } + } + + if (!infile) { + fprintf(stderr, "input file not given\n"); exit(1); } - infile = argv[1]; - outfile = argv[2]; + if (!outfile) { + fprintf(stderr, "output file not given\n"); + exit(1); + } if (stat(infile, &st) == -1) { perror("stat"); -- cgit v1.2.3 From 24fce509d00474d5978dc38828b39154431c8a49 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:23 +0100 Subject: ARM: zynq: move header generation to zynq_mkimage Instead of generating a suitable image header with linker magic, move all of this into zynq_mkimage. The configuration file format and parsing is based on imx-image. This gets us one step further on the road to proper multi-image support. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/boards/avnet-zedboard/Makefile | 1 - arch/arm/boards/avnet-zedboard/flash_header.c | 62 ------ arch/arm/boards/avnet-zedboard/zedboard.zynqcfg | 24 +++ arch/arm/mach-zynq/include/mach/barebox.lds.h | 8 - .../arm/mach-zynq/include/mach/zynq-flash-header.h | 39 ++-- .../mach-zynq/include/mach/zynq7000-header-regs.h | 49 +++++ images/Makefile.zynq | 11 +- include/asm-generic/barebox.lds.h | 3 +- scripts/Makefile | 1 + scripts/zynq_mkimage.c | 232 ++++++++++++++++++++- 10 files changed, 320 insertions(+), 110 deletions(-) delete mode 100644 arch/arm/boards/avnet-zedboard/flash_header.c create mode 100644 arch/arm/boards/avnet-zedboard/zedboard.zynqcfg delete mode 100644 arch/arm/mach-zynq/include/mach/barebox.lds.h create mode 100644 arch/arm/mach-zynq/include/mach/zynq7000-header-regs.h diff --git a/arch/arm/boards/avnet-zedboard/Makefile b/arch/arm/boards/avnet-zedboard/Makefile index a2c3104e6c..01c7a259e9 100644 --- a/arch/arm/boards/avnet-zedboard/Makefile +++ b/arch/arm/boards/avnet-zedboard/Makefile @@ -1,3 +1,2 @@ obj-y += board.o lwl-y += lowlevel.o -lwl-y += flash_header.o diff --git a/arch/arm/boards/avnet-zedboard/flash_header.c b/arch/arm/boards/avnet-zedboard/flash_header.c deleted file mode 100644 index d9eb35b0d5..0000000000 --- a/arch/arm/boards/avnet-zedboard/flash_header.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 Steffen Trumtrar - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#define REG(a, v) { .addr = cpu_to_le32(a), .val = cpu_to_le32(v), } - -struct zynq_reg_entry __ps7reg_entry_section reg_entry[] = { - REG(ZYNQ_SLCR_UNLOCK, 0x0000DF0D), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_CLK_621_TRUE, 0x00000001), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_APER_CLK_CTRL, 0x01FC044D), - - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028008), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CFG, 0x000FA220), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028011), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028010), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_ARM_PLL_CTRL, 0x00028000), - - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E008), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CFG, 0x001452C0), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E011), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E010), - REG(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_IO_PLL_CTRL, 0x0001E000), - - REG(0xf8000150, 0x00000a03), - - /* stop */ - REG(0xFFFFFFFF, 0x00000000), -}; - -struct zynq_flash_header __flash_header_section flash_header = { - .width_det = WIDTH_DETECTION_MAGIC, - .image_id = IMAGE_IDENTIFICATION, - .enc_stat = 0x0, - .user = 0x0, - .flash_offset = 0x8c0, - .length = (unsigned int)&_barebox_image_size, - .res0 = 0x0, - .start_of_exec = 0x0, - .total_len = (unsigned int)&_barebox_image_size, - .res1 = 0x1, - .checksum = 0x0, - .res2 = 0x0, -}; diff --git a/arch/arm/boards/avnet-zedboard/zedboard.zynqcfg b/arch/arm/boards/avnet-zedboard/zedboard.zynqcfg new file mode 100644 index 0000000000..3f8808d3d7 --- /dev/null +++ b/arch/arm/boards/avnet-zedboard/zedboard.zynqcfg @@ -0,0 +1,24 @@ +#include + +wm 32 ZYNQ_SLCR_UNLOCK 0x0000DF0D +wm 32 ZYNQ_CLK_621_TRUE 0x00000001 +wm 32 ZYNQ_APER_CLK_CTRL 0x01FC044D + +wm 32 ZYNQ_ARM_PLL_CTRL 0x00028008 +wm 32 ZYNQ_ARM_PLL_CFG 0x000FA220 +wm 32 ZYNQ_ARM_PLL_CTRL 0x00028010 +wm 32 ZYNQ_ARM_PLL_CTRL 0x00028011 +wm 32 ZYNQ_ARM_PLL_CTRL 0x00028010 +wm 32 ZYNQ_ARM_PLL_CTRL 0x00028000 + +wm 32 ZYNQ_IO_PLL_CTRL 0x0001E008 +wm 32 ZYNQ_IO_PLL_CFG 0x001452C0 +wm 32 ZYNQ_IO_PLL_CTRL 0x0001E010 +wm 32 ZYNQ_IO_PLL_CTRL 0x0001E011 +wm 32 ZYNQ_IO_PLL_CTRL 0x0001E010 +wm 32 ZYNQ_IO_PLL_CTRL 0x0001E000 + +wm 32 ZYNQ_SDIO_CLK_CTRL 0x00000a03 + +/* stop */ +wm 32 0xFFFFFFFF 0x00000000 \ No newline at end of file diff --git a/arch/arm/mach-zynq/include/mach/barebox.lds.h b/arch/arm/mach-zynq/include/mach/barebox.lds.h deleted file mode 100644 index 3d35fe9880..0000000000 --- a/arch/arm/mach-zynq/include/mach/barebox.lds.h +++ /dev/null @@ -1,8 +0,0 @@ -#define PRE_IMAGE \ - .pre_image : { \ - . = 0x20; \ - KEEP(*(.flash_header_0x0*)) \ - . = 0xa0; \ - KEEP(*(.ps7reg_entry_0x0A0)) \ - . = 0x8c0; \ - } diff --git a/arch/arm/mach-zynq/include/mach/zynq-flash-header.h b/arch/arm/mach-zynq/include/mach/zynq-flash-header.h index 3b67e55a71..ba4b67f479 100644 --- a/arch/arm/mach-zynq/include/mach/zynq-flash-header.h +++ b/arch/arm/mach-zynq/include/mach/zynq-flash-header.h @@ -1,38 +1,27 @@ #ifndef __MACH_FLASH_HEADER_H #define __MACH_FLASH_HEADER_H -#include +#include -#define __flash_header_section __section(.flash_header_0x0) -#define __ps7reg_entry_section __section(.ps7reg_entry_0x0A0) -#define __image_len_section __section(.image_len_0x08c0) -#define FLASH_HEADER_OFFSET 0x0 +#define REGINIT_OFFSET 0x0a0 #define IMAGE_OFFSET 0x8c0 -#define DEST_BASE 0x8c0 -#define FLASH_HEADER_BASE (DEST_BASE + FLASH_HEADER_OFFSET) - -struct zynq_reg_entry { - __le32 addr; - __le32 val; -}; - #define WIDTH_DETECTION_MAGIC 0xAA995566 #define IMAGE_IDENTIFICATION 0x584C4E58 /* "XLNX" */ struct zynq_flash_header { - __le32 width_det; - __le32 image_id; - __le32 enc_stat; - __le32 user; - __le32 flash_offset; - __le32 length; - __le32 res0; - __le32 start_of_exec; - __le32 total_len; - __le32 res1; - __le32 checksum; - __le32 res2; + uint32_t width_det; + uint32_t image_id; + uint32_t enc_stat; + uint32_t user; + uint32_t flash_offset; + uint32_t length; + uint32_t res0; + uint32_t start_of_exec; + uint32_t total_len; + uint32_t res1; + uint32_t checksum; + uint32_t res2; }; #endif /* __MACH_FLASH_HEADER_H */ diff --git a/arch/arm/mach-zynq/include/mach/zynq7000-header-regs.h b/arch/arm/mach-zynq/include/mach/zynq7000-header-regs.h new file mode 100644 index 0000000000..4e24064746 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/zynq7000-header-regs.h @@ -0,0 +1,49 @@ +/* + * (c) 2012 Steffen Trumtrar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define ZYNQ_SLCR_LOCK 0xF8000004 +#define ZYNQ_SLCR_UNLOCK 0xF8000008 +#define ZYNQ_ARM_PLL_CTRL 0xF8000100 +#define ZYNQ_DDR_PLL_CTRL 0xF8000104 +#define ZYNQ_IO_PLL_CTRL 0xF8000108 +#define ZYNQ_PLL_STATUS 0xF800010C +#define ZYNQ_ARM_PLL_CFG 0xF8000110 +#define ZYNQ_DDR_PLL_CFG 0xF8000114 +#define ZYNQ_IO_PLL_CFG 0xF8000118 +#define ZYNQ_ARM_CLK_CTRL 0xF8000120 +#define ZYNQ_DDR_CLK_CTRL 0xF8000124 +#define ZYNQ_DCI_CLK_CTRL 0xF8000128 +#define ZYNQ_APER_CLK_CTRL 0xF800012C +#define ZYNQ_USB0_CLK_CTRL 0xF8000130 +#define ZYNQ_USB1_CLK_CTRL 0xF8000134 +#define ZYNQ_GEM0_RCLK_CTRL 0xF8000138 +#define ZYNQ_GEM1_RCLK_CTRL 0xF800013C +#define ZYNQ_GEM0_CLK_CTRL 0xF8000140 +#define ZYNQ_GEM1_CLK_CTRL 0xF8000144 +#define ZYNQ_SMC_CLK_CTRL 0xF8000148 +#define ZYNQ_LQSPI_CLK_CTRL 0xF800014C +#define ZYNQ_SDIO_CLK_CTRL 0xF8000150 +#define ZYNQ_UART_CLK_CTRL 0xF8000154 +#define ZYNQ_SPI_CLK_CTRL 0xF8000158 +#define ZYNQ_CAN_CLK_CTRL 0xF800015C +#define ZYNQ_CAN_MIOCLK_CTRL 0xF8000160 +#define ZYNQ_DBG_CLK_CTRL 0xF8000164 +#define ZYNQ_PCAP_CLK_CTRL 0xF8000168 +#define ZYNQ_TOPSW_CLK_CTRL 0xF800016C +#define ZYNQ_FPGA0_CLK_CTRL 0xF8000170 +#define ZYNQ_FPGA1_CLK_CTRL 0xF8000180 +#define ZYNQ_FPGA2_CLK_CTRL 0xF8000190 +#define ZYNQ_FPGA3_CLK_CTRL 0xF80001A0 +#define ZYNQ_CLK_621_TRUE 0xF80001C4 diff --git a/images/Makefile.zynq b/images/Makefile.zynq index cc0cf6d2df..b089a9fd26 100644 --- a/images/Makefile.zynq +++ b/images/Makefile.zynq @@ -1,14 +1,23 @@ # # barebox image generation Makefile for Xilinx Zynq images # + +zynqcfg_cpp_flags = -Wp,-MD,$(depfile) -nostdinc -x assembler-with-cpp \ + -I arch/arm/mach-zynq/include + +zynqcfg-tmp = $(subst $(comma),_,$(dot-target).zynqcfg.tmp) + quiet_cmd_zynq_image = ZYNQIMG $@ cmd_zynq_image = \ - $(objtree)/scripts/zynq_mkimage -f $(subst .zynqimg,,$@) -o $@ + $(CPP) $(zynqcfg_cpp_flags) -o $(zynqcfg-tmp) $(CFG_$(@F)) ; \ + $(objtree)/scripts/zynq_mkimage -c $(zynqcfg-tmp) \ + -f $(subst .zynqimg,,$@) -o $@ $(obj)/%.zynqimg: $(obj)/% FORCE $(call if_changed,zynq_image) #------------------------------------------------------------------------------ +CFG_start_pbl.pblb.zynqimg = $(board)/avnet-zedboard/zedboard.zynqcfg FILE_barebox-avnet-zedboard.img = start_pbl.pblb.zynqimg image-$(CONFIG_MACH_ZEDBOARD) += barebox-avnet-zedboard.img diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h index b6ca8eb2be..68b78a13a9 100644 --- a/include/asm-generic/barebox.lds.h +++ b/include/asm-generic/barebox.lds.h @@ -7,8 +7,7 @@ #define STRUCT_ALIGN() . = ALIGN(STRUCT_ALIGNMENT) #if defined CONFIG_X86 || \ - defined CONFIG_ARCH_EP93XX || \ - defined CONFIG_ARCH_ZYNQ + defined CONFIG_ARCH_EP93XX #include #endif diff --git a/scripts/Makefile b/scripts/Makefile index 16bb513fbb..eb6718fadf 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -20,6 +20,7 @@ hostprogs-$(CONFIG_MVEBU_HOSTTOOLS) += kwbimage kwboot mvebuimg hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-omap-image hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader +HOSTCFLAGS_zynq_mkimage.o = -I$(srctree) -I$(srctree)/arch/arm/mach-zynq/include hostprogs-$(CONFIG_ARCH_ZYNQ) += zynq_mkimage hostprogs-$(CONFIG_ARCH_SOCFPGA) += socfpga_mkimage hostprogs-$(CONFIG_MXS_HOSTTOOLS)+= mxsimage mxsboot diff --git a/scripts/zynq_mkimage.c b/scripts/zynq_mkimage.c index 905d6fc69a..bf214ca5d0 100644 --- a/scripts/zynq_mkimage.c +++ b/scripts/zynq_mkimage.c @@ -15,35 +15,241 @@ #include #include #include +#include +#include #include +#include #include #include +#include #include +#include static char *prgname; static void usage(char *name) { fprintf(stderr, "usage: %s [OPTIONS]\n\n" + "-c configuration input file" "-f input image file\n" "-o output file\n" "-h this help\n", prgname); exit(1); } +#define MAXARGS 16 + +static int parse_line(char *line, char *argv[]) +{ + int nargs = 0; + + while (nargs < MAXARGS) { + + /* skip any white space */ + while ((*line == ' ') || (*line == '\t')) + ++line; + + if (*line == '\0') { /* end of line, no more args */ + argv[nargs] = NULL; + return nargs; + } + + argv[nargs++] = line; /* begin of argument string */ + + /* find end of string */ + while (*line && (*line != ' ') && (*line != '\t')) + ++line; + + if (*line == '\0') { /* end of line, no more args */ + argv[nargs] = NULL; + return nargs; + } + + *line++ = '\0'; /* terminate current arg */ + } + + printf("** Too many args (max. %d) **\n", MAXARGS); + + return nargs; +} + +struct command { + const char *name; + int (*parse)(char *buf, int argc, char *argv[]); +}; + +static int do_cmd_write_mem(char *buf, int argc, char *argv[]) +{ + unsigned int *wordbuf = (unsigned int *)(buf + REGINIT_OFFSET); + static int reginit_offset; + uint32_t addr, val, width; + char *end; + + if (argc != 4) { + fprintf(stderr, "usage: wm [8|16|32] \n"); + return -EINVAL; + } + + width = strtoul(argv[1], &end, 0); + if (*end != '\0' || width != 32) { + fprintf(stderr, "illegal width token \"%s\"\n", argv[1]); + return -EINVAL; + } + + addr = strtoul(argv[2], &end, 0); + if (*end != '\0') { + fprintf(stderr, "illegal address token \"%s\"\n", argv[2]); + return -EINVAL; + } + + val = strtoul(argv[3], &end, 0); + if (*end != '\0') { + fprintf(stderr, "illegal value token \"%s\"\n", argv[3]); + return -EINVAL; + } + + wordbuf[reginit_offset] = htole32(addr); + wordbuf[reginit_offset + 1] = htole32(val); + wordbuf[reginit_offset + 1] = htole32(val); + + reginit_offset += 2; + + return 0; +} + +struct command cmds[] = { + { + .name = "wm", + .parse = do_cmd_write_mem, + }, +}; + +static char *readcmd(FILE *f) +{ + static char *buf; + char *str; + ssize_t ret; + + if (!buf) { + buf = malloc(4096); + if (!buf) + return NULL; + } + + str = buf; + *str = 0; + + while (1) { + ret = fread(str, 1, 1, f); + if (!ret) + return strlen(buf) ? buf : NULL; + + if (*str == '\n' || *str == ';') { + *str = 0; + return buf; + } + + str++; + } +} + +int parse_config(char *buf, const char *filename) +{ + FILE *f; + int lineno = 0; + char *line = NULL, *tmp; + char *argv[MAXARGS]; + int nargs, i, ret = 0; + + f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Cannot open config file\n"); + exit(1); + } + + while (1) { + line = readcmd(f); + if (!line) + break; + + lineno++; + + tmp = strchr(line, '#'); + if (tmp) + *tmp = 0; + + nargs = parse_line(line, argv); + if (!nargs) + continue; + + ret = -ENOENT; + + for (i = 0; i < ARRAY_SIZE(cmds); i++) { + if (!strcmp(cmds[i].name, argv[0])) { + ret = cmds[i].parse(buf, nargs, argv); + if (ret) { + fprintf(stderr, "error in line %d: %s\n", + lineno, strerror(-ret)); + goto cleanup; + } + break; + } + } + + if (ret == -ENOENT) { + fprintf(stderr, "no such command: %s\n", argv[0]); + goto cleanup; + } + } + +cleanup: + fclose(f); + return ret; +} + +static void add_header(char *buf, unsigned int image_size) +{ + unsigned int *wordbuf = (unsigned int *)buf; + struct zynq_flash_header flash_header = { + .width_det = WIDTH_DETECTION_MAGIC, + .image_id = IMAGE_IDENTIFICATION, + .enc_stat = 0x0, + .user = 0x0, + .flash_offset = IMAGE_OFFSET, + .length = image_size, + .res0 = 0x0, + .start_of_exec = 0x0, + .total_len = image_size, + .res1 = 0x1, + .checksum = 0x0, + .res2 = 0x0, + }; + int i, sum = 0; + + memcpy(wordbuf + 0x8, &flash_header, sizeof(flash_header)); + + for (i = 0x8; i < 0x12; i++) + sum += htole32(wordbuf[i]); + + sum = ~sum; + wordbuf[i] = sum; +} + int main(int argc, char *argv[]) { FILE *ifile, *ofile; - unsigned int *buf; - const char *infile = NULL, *outfile = NULL; + char *buf; + const char *infile = NULL, *outfile = NULL, *cfgfile = NULL; struct stat st; - unsigned int i,sum = 0; int opt; prgname = argv[0]; - while ((opt = getopt(argc, argv, "f:ho:")) != -1) { + while ((opt = getopt(argc, argv, "c:f:ho:")) != -1) { switch (opt) { + case 'c': + cfgfile = optarg; + break; case 'f': infile = optarg; break; @@ -67,12 +273,17 @@ int main(int argc, char *argv[]) exit(1); } + if (!cfgfile) { + fprintf(stderr, "config file not given\n"); + exit(1); + } + if (stat(infile, &st) == -1) { perror("stat"); exit(EXIT_FAILURE); } - buf = malloc(st.st_size); + buf = calloc(st.st_size + IMAGE_OFFSET, sizeof(char)); if (!buf) { fprintf(stderr, "Unable to allocate buffer\n"); return -1; @@ -93,15 +304,14 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - fread(buf, 4, st.st_size, ifile); + fread(buf + IMAGE_OFFSET, sizeof(char), st.st_size, ifile); - for (i = 0x8; i < 0x12; i++) - sum += htole32(buf[i]); + add_header(buf, st.st_size); - sum = ~sum; - buf[i] = sum; + if (cfgfile) + parse_config(buf, cfgfile); - fwrite(buf, st.st_size / 4, 4, ofile); + fwrite(buf, sizeof(char), st.st_size + IMAGE_OFFSET, ofile); fclose(ofile); fclose(ifile); -- cgit v1.2.3 From b6d3e1fa56f365796b40d86e9195f882f0690952 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:24 +0100 Subject: ARM: zynq: add size check in zynq_mkimage Currently Barebox does not support 2 stage loading on Zynq, so the image must fit into the free OCRAM area. Add a check to the mkimage tool to validate this. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- scripts/zynq_mkimage.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/zynq_mkimage.c b/scripts/zynq_mkimage.c index bf214ca5d0..0a1c069472 100644 --- a/scripts/zynq_mkimage.c +++ b/scripts/zynq_mkimage.c @@ -283,6 +283,11 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + if (st.st_size > 192 * 1024) { + fprintf(stderr, "Image too big, will not fit in OCRAM!\n"); + exit(EXIT_FAILURE); + } + buf = calloc(st.st_size + IMAGE_OFFSET, sizeof(char)); if (!buf) { fprintf(stderr, "Unable to allocate buffer\n"); -- cgit v1.2.3 From 667f2367d35ef967fd766b134b0746fa3a17e3f4 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:25 +0100 Subject: ARM: zynq: zedboard: provide DTB Provide the DTB to allow devices to be probed from there, instead of board code. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/boards/avnet-zedboard/lowlevel.c | 8 +++++++- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-zed.dts | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/zynq-zed.dts diff --git a/arch/arm/boards/avnet-zedboard/lowlevel.c b/arch/arm/boards/avnet-zedboard/lowlevel.c index cf3c4ebd0c..ae279e4e64 100644 --- a/arch/arm/boards/avnet-zedboard/lowlevel.c +++ b/arch/arm/boards/avnet-zedboard/lowlevel.c @@ -27,8 +27,13 @@ #define PLL_DDR_LOCK (1 << 1) #define PLL_IO_LOCK (1 << 2) +extern char __dtb_zynq_zed_start[]; + void __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2) { + + void *fdt = __dtb_zynq_zed_start + get_runtime_offset(); + /* open sesame */ writel(0x0000DF0D, ZYNQ_SLCR_UNLOCK); @@ -257,5 +262,6 @@ void __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2) writel(0x0000767B, ZYNQ_SLCR_LOCK); arm_cpu_lowlevel_init(); - barebox_arm_entry(0, SZ_512M, NULL); + + barebox_arm_entry(0, SZ_512M, fdt); } diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 294a0bfa55..c097c10186 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -143,5 +143,6 @@ lwl-dtb-$(CONFIG_MACH_ZII_IMX7D_DEV) += imx7d-zii-rpu2.dtb.o imx7d-zii-rmu2.dtb. lwl-dtb-$(CONFIG_MACH_WAGO_PFC_AM35XX) += am35xx-pfc-750_820x.dtb.o lwl-dtb-$(CONFIG_MACH_LS1046ARDB) += fsl-ls1046a-rdb.dtb.o lwl-dtb-$(CONFIG_MACH_TQMLS1046A) += fsl-tqmls1046a-mbls10xxa.dtb.o +lwl-dtb-$(CONFIG_MACH_ZEDBOARD) += zynq-zed.dtb.o clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.lzo diff --git a/arch/arm/dts/zynq-zed.dts b/arch/arm/dts/zynq-zed.dts new file mode 100644 index 0000000000..52d6833249 --- /dev/null +++ b/arch/arm/dts/zynq-zed.dts @@ -0,0 +1,7 @@ +#include + +/ { + chosen { + stdout-path = &uart1; + }; +}; -- cgit v1.2.3 From 269b39454d5929e3352ab02761df63f0e2fbae79 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:26 +0100 Subject: net: macb: handle more clocks Both pclk and hclk are required clocks in the DT binding. rx_clk and tx_clk are optional, but must be enabled if a system has separate gates for them. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/net/macb.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index c4ab9efb63..df1e606454 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -69,7 +69,7 @@ struct macb_device { int phy_addr; - struct clk *pclk; + struct clk *pclk, *hclk, *txclk, *rxclk; const struct device_d *dev; struct eth_device netdev; @@ -653,7 +653,7 @@ static int macb_probe(struct device_d *dev) struct resource *iores; struct eth_device *edev; struct macb_device *macb; - const char *pclk_name; + const char *pclk_name, *hclk_name; u32 ncfgr; macb = xzalloc(sizeof(*macb)); @@ -689,6 +689,7 @@ static int macb_probe(struct device_d *dev) macb->phy_addr = pdata->phy_addr; macb->phy_flags = pdata->phy_flags; pclk_name = "macb_clk"; + hclk_name = NULL; } else if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node) { int ret; struct device_node *mdiobus; @@ -705,6 +706,7 @@ static int macb_probe(struct device_d *dev) macb->phy_addr = -1; pclk_name = "pclk"; + hclk_name = "hclk"; } else { dev_err(dev, "macb: no platform_data\n"); return -ENODEV; @@ -727,6 +729,24 @@ static int macb_probe(struct device_d *dev) clk_enable(macb->pclk); + if (hclk_name) { + macb->hclk = clk_get(dev, pclk_name); + if (IS_ERR(macb->pclk)) { + dev_err(dev, "no hclk\n"); + return PTR_ERR(macb->hclk); + } + + clk_enable(macb->hclk); + } + + macb->txclk = clk_get(dev, "tx_clk"); + if (!IS_ERR(macb->txclk)) + clk_enable(macb->txclk); + + macb->rxclk = clk_get(dev, "rx_clk"); + if (!IS_ERR(macb->rxclk)) + clk_enable(macb->rxclk); + macb->is_gem = read_is_gem(macb); if (macb_is_gem(macb)) -- cgit v1.2.3 From 6a6278eb98783f7534e26d6be6045b4adc90c0e6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:27 +0100 Subject: net: macb: add Zynq compatible Add compatible for the GEM on the Zynq 7000 device. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/net/macb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index df1e606454..4850e60c49 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -792,6 +792,7 @@ static const struct of_device_id macb_dt_ids[] = { { .compatible = "cdns,at91sam9260-macb",}, { .compatible = "atmel,sama5d2-gem",}, { .compatible = "atmel,sama5d3-gem",}, + { .compatible = "cdns,zynq-gem",}, { .compatible = "cdns,zynqmp-gem",}, { /* sentinel */ } }; -- cgit v1.2.3 From 73671592a41dd39051339c8e17742cae31e53823 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:28 +0100 Subject: ARM: zynq: move clock controller driver to drivers/clk No functional change, just adjusting the Zynq code to common practise. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/mach-zynq/Makefile | 2 +- arch/arm/mach-zynq/clk-zynq7000.c | 426 -------------------------------------- drivers/clk/Makefile | 1 + drivers/clk/zynq/Makefile | 1 + drivers/clk/zynq/clkc.c | 426 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 429 insertions(+), 427 deletions(-) delete mode 100644 arch/arm/mach-zynq/clk-zynq7000.c create mode 100644 drivers/clk/zynq/Makefile create mode 100644 drivers/clk/zynq/clkc.c diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index 459c957622..b401c77983 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -1 +1 @@ -obj-y += zynq.o devices.o clk-zynq7000.o +obj-y += zynq.o devices.o diff --git a/arch/arm/mach-zynq/clk-zynq7000.c b/arch/arm/mach-zynq/clk-zynq7000.c deleted file mode 100644 index cd49d8478f..0000000000 --- a/arch/arm/mach-zynq/clk-zynq7000.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2013 Josh Cartwright - * Copyright (c) 2013 Steffen Trumtrar - * - * Based on drivers/clk-zynq.c from Linux. - * - * Copyright (c) 2012 National Instruments - * - * Josh Cartwright - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -enum zynq_clks { - dummy, ps_clk, arm_pll, ddr_pll, io_pll, uart_clk, uart0, uart1, - cpu_clk, cpu_6x4x, cpu_3x2x, cpu_2x, cpu_1x, - gem_clk, gem0, gem1, clks_max -}; - -enum zynq_pll_type { - ZYNQ_PLL_ARM, - ZYNQ_PLL_DDR, - ZYNQ_PLL_IO, -}; - -#define PLL_STATUS_ARM_PLL_LOCK (1 << 0) -#define PLL_STATUS_DDR_PLL_LOCK (1 << 1) -#define PLL_STATUS_IO_PLL_LOCK (1 << 2) -#define PLL_STATUS_ARM_PLL_STABLE (1 << 0) -#define PLL_STATUS_DDR_PLL_STABLE (1 << 1) -#define PLL_STATUS_IO_PLL_STABLE (1 << 2) -#define PLL_CTRL_BYPASS_FORCE (1 << 4) - -static struct clk *clks[clks_max]; - -struct zynq_pll_clk { - struct clk clk; - u32 pll_lock; - void __iomem *pll_ctrl; -}; - -#define to_zynq_pll_clk(c) container_of(c, struct zynq_pll_clk, clk) - -#define PLL_CTRL_FDIV(x) (((x) >> 12) & 0x7F) - -static unsigned long zynq_pll_recalc_rate(struct clk *clk, - unsigned long parent_rate) -{ - struct zynq_pll_clk *pll = to_zynq_pll_clk(clk); - return parent_rate * PLL_CTRL_FDIV(readl(pll->pll_ctrl)); -} - -static int zynq_pll_enable(struct clk *clk) -{ - struct zynq_pll_clk *pll = to_zynq_pll_clk(clk); - u32 val; - int timeout = 10000; - - val = readl(pll->pll_ctrl); - val &= ~PLL_CTRL_BYPASS_FORCE; - writel(val, pll->pll_ctrl); - - while (timeout--) { - if (readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & pll->pll_lock) - break; - } - - if (!timeout) - return -ETIMEDOUT; - - return 0; -} - -static struct clk_ops zynq_pll_clk_ops = { - .recalc_rate = zynq_pll_recalc_rate, - .enable = zynq_pll_enable, -}; - -static inline struct clk *zynq_pll_clk(enum zynq_pll_type type, - const char *name, - void __iomem *pll_ctrl) -{ - static const char *pll_parent = "ps_clk"; - struct zynq_pll_clk *pll; - int ret; - - pll = xzalloc(sizeof(*pll)); - pll->pll_ctrl = pll_ctrl; - pll->clk.ops = &zynq_pll_clk_ops; - pll->clk.name = name; - pll->clk.parent_names = &pll_parent; - pll->clk.num_parents = 1; - - switch(type) { - case ZYNQ_PLL_ARM: - pll->pll_lock = PLL_STATUS_ARM_PLL_LOCK; - break; - case ZYNQ_PLL_DDR: - pll->pll_lock = PLL_STATUS_DDR_PLL_LOCK; - break; - case ZYNQ_PLL_IO: - pll->pll_lock = PLL_STATUS_IO_PLL_LOCK; - break; - } - - ret = clk_register(&pll->clk); - if (ret) { - free(pll); - return ERR_PTR(ret); - } - - return &pll->clk; -} - -struct zynq_periph_clk { - struct clk clk; - void __iomem *clk_ctrl; -}; - -#define to_zynq_periph_clk(c) container_of(c, struct zynq_periph_clk, c) - -static const u8 periph_clk_parent_map[] = { - 0, 0, 1, 2 -}; -#define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4]) -#define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) - -static unsigned long zynq_periph_recalc_rate(struct clk *clk, - unsigned long parent_rate) -{ - struct zynq_periph_clk *periph = to_zynq_periph_clk(clk); - return parent_rate / PERIPH_CLK_CTRL_DIV(readl(periph->clk_ctrl)); -} - -static int zynq_periph_get_parent(struct clk *clk) -{ - struct zynq_periph_clk *periph = to_zynq_periph_clk(clk); - return PERIPH_CLK_CTRL_SRC(readl(periph->clk_ctrl)); -} - -static const struct clk_ops zynq_periph_clk_ops = { - .recalc_rate = zynq_periph_recalc_rate, - .get_parent = zynq_periph_get_parent, -}; - -static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl) -{ - static const char *peripheral_parents[] = { - "io_pll", - "arm_pll", - "ddr_pll", - }; - struct zynq_periph_clk *periph; - int ret; - - periph = xzalloc(sizeof(*periph)); - - periph->clk_ctrl = clk_ctrl; - periph->clk.name = name; - periph->clk.ops = &zynq_periph_clk_ops; - periph->clk.parent_names = peripheral_parents; - periph->clk.num_parents = ARRAY_SIZE(peripheral_parents); - - ret = clk_register(&periph->clk); - if (ret) { - free(periph); - return ERR_PTR(ret); - } - - return &periph->clk; -} - -/* CPU Clock domain is modelled as a mux with 4 children subclks, whose - * derivative rates depend on CLK_621_TRUE - */ - -struct zynq_cpu_clk { - struct clk clk; - void __iomem *clk_ctrl; -}; - -#define to_zynq_cpu_clk(c) container_of(c, struct zynq_cpu_clk, c) - -static const u8 zynq_cpu_clk_parent_map[] = { - 1, 1, 2, 0 -}; -#define CPU_CLK_SRCSEL(x) (zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)]) -#define CPU_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) - -static unsigned long zynq_cpu_clk_recalc_rate(struct clk *clk, - unsigned long parent_rate) -{ - struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk); - return parent_rate / CPU_CLK_CTRL_DIV(readl(cpuclk->clk_ctrl)); -} - -static int zynq_cpu_clk_get_parent(struct clk *clk) -{ - struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk); - return CPU_CLK_SRCSEL(readl(cpuclk->clk_ctrl)); -} - -static const struct clk_ops zynq_cpu_clk_ops = { - .get_parent = zynq_cpu_clk_get_parent, - .recalc_rate = zynq_cpu_clk_recalc_rate, -}; - -static struct clk *zynq_cpu_clk(const char *name, void __iomem *clk_ctrl) -{ - static const char *cpu_parents[] = { - "io_pll", - "arm_pll", - "ddr_pll", - }; - struct zynq_cpu_clk *cpu; - int ret; - - cpu = xzalloc(sizeof(*cpu)); - - cpu->clk_ctrl = clk_ctrl; - cpu->clk.ops = &zynq_cpu_clk_ops; - cpu->clk.name = name; - cpu->clk.parent_names = cpu_parents; - cpu->clk.num_parents = ARRAY_SIZE(cpu_parents); - - ret = clk_register(&cpu->clk); - if (ret) { - free(cpu); - return ERR_PTR(ret); - } - - return &cpu->clk; -} - -enum zynq_cpu_subclk_which { - CPU_SUBCLK_6X4X, - CPU_SUBCLK_3X2X, - CPU_SUBCLK_2X, - CPU_SUBCLK_1X, -}; - -struct zynq_cpu_subclk { - struct clk clk; - void __iomem *clk_ctrl; - void __iomem *clk_621; - enum zynq_cpu_subclk_which which; -}; - -#define CLK_621_TRUE(x) ((x) & 1) - -#define to_zynq_cpu_subclk(c) container_of(c, struct zynq_cpu_subclk, c); - -static unsigned long zynq_cpu_subclk_recalc_rate(struct clk *clk, - unsigned long parent_rate) -{ - unsigned long uninitialized_var(rate); - struct zynq_cpu_subclk *subclk; - bool is_621; - - subclk = to_zynq_cpu_subclk(clk); - is_621 = CLK_621_TRUE(readl(subclk->clk_621)); - - switch (subclk->which) { - case CPU_SUBCLK_6X4X: - rate = parent_rate; - break; - case CPU_SUBCLK_3X2X: - rate = parent_rate / 2; - break; - case CPU_SUBCLK_2X: - rate = parent_rate / (is_621 ? 3 : 2); - break; - case CPU_SUBCLK_1X: - rate = parent_rate / (is_621 ? 6 : 4); - break; - }; - - return rate; -} - -static int zynq_cpu_subclk_enable(struct clk *clk) -{ - struct zynq_cpu_subclk *subclk; - u32 tmp; - - subclk = to_zynq_cpu_subclk(clk); - - tmp = readl(subclk->clk_ctrl); - tmp |= 1 << (24 + subclk->which); - writel(tmp, subclk->clk_ctrl); - - return 0; -} - -static void zynq_cpu_subclk_disable(struct clk *clk) -{ - struct zynq_cpu_subclk *subclk; - u32 tmp; - - subclk = to_zynq_cpu_subclk(clk); - - tmp = readl(subclk->clk_ctrl); - tmp &= ~(1 << (24 + subclk->which)); - writel(tmp, subclk->clk_ctrl); -} - -static const struct clk_ops zynq_cpu_subclk_ops = { - .enable = zynq_cpu_subclk_enable, - .disable = zynq_cpu_subclk_disable, - .recalc_rate = zynq_cpu_subclk_recalc_rate, -}; - -static struct clk *zynq_cpu_subclk(const char *name, - enum zynq_cpu_subclk_which which, - void __iomem *clk_ctrl, - void __iomem *clk_621) -{ - static const char *subclk_parent = "cpu_clk"; - struct zynq_cpu_subclk *subclk; - int ret; - - subclk = xzalloc(sizeof(*subclk)); - - subclk->clk_ctrl = clk_ctrl; - subclk->clk_621 = clk_621; - subclk->which = which; - subclk->clk.name = name; - subclk->clk.ops = &zynq_cpu_subclk_ops; - - subclk->clk.parent_names = &subclk_parent; - subclk->clk.num_parents = 1; - - ret = clk_register(&subclk->clk); - if (ret) { - free(subclk); - return ERR_PTR(ret); - } - - return &subclk->clk; -} - -static int zynq_clock_probe(struct device_d *dev) -{ - struct resource *iores; - void __iomem *slcr_base; - unsigned long ps_clk_rate = 33333330; - - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); - slcr_base = IOMEM(iores->start); - - clks[ps_clk] = clk_fixed("ps_clk", ps_clk_rate); - - clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", slcr_base + 0x100); - clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", slcr_base + 0x104); - clks[io_pll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", slcr_base + 0x108); - - clks[uart_clk] = zynq_periph_clk("uart_clk", slcr_base + 0x154); - - clks[uart0] = clk_gate("uart0", "uart_clk", slcr_base + 0x154, 0, 0, 0); - clks[uart1] = clk_gate("uart1", "uart_clk", slcr_base + 0x154, 1, 0, 0); - - clks[gem0] = clk_gate("gem0", "io_pll", slcr_base + 0x140, 0, 0, 0); - clks[gem1] = clk_gate("gem1", "io_pll", slcr_base + 0x144, 1, 0, 0); - - clks[cpu_clk] = zynq_cpu_clk("cpu_clk", slcr_base + 0x120); - - clks[cpu_6x4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X, - slcr_base + 0x120, slcr_base + 0x1C4); - clks[cpu_3x2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X, - slcr_base + 0x120, slcr_base + 0x1C4); - clks[cpu_2x] = zynq_cpu_subclk("cpu_2x", CPU_SUBCLK_2X, - slcr_base + 0x120, slcr_base + 0x1C4); - clks[cpu_1x] = zynq_cpu_subclk("cpu_1x", CPU_SUBCLK_1X, - slcr_base + 0x120, slcr_base + 0x1C4); - - clk_register_clkdev(clks[cpu_3x2x], NULL, "arm_smp_twd"); - clk_register_clkdev(clks[uart0], NULL, "zynq_serial0"); - clk_register_clkdev(clks[uart1], NULL, "zynq_serial1"); - clk_register_clkdev(clks[gem0], NULL, "macb0"); - clk_register_clkdev(clks[gem1], NULL, "macb1"); - - clkdev_add_physbase(clks[cpu_3x2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL); - clkdev_add_physbase(clks[uart1], ZYNQ_UART1_BASE_ADDR, NULL); - - return 0; -} - -static __maybe_unused struct of_device_id zynq_clock_dt_ids[] = { - { - .compatible = "xlnx,zynq-clock", - }, { - /* sentinel */ - } -}; - -static struct driver_d zynq_clock_driver = { - .probe = zynq_clock_probe, - .name = "zynq-clock", - .of_compatible = DRV_OF_COMPAT(zynq_clock_dt_ids), -}; - -static int zynq_clock_init(void) -{ - return platform_driver_register(&zynq_clock_driver); -} -postcore_initcall(zynq_clock_init); diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 1bd5f90358..8160620dc6 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_MVEBU) += mvebu/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-$(CONFIG_ARCH_ZYNQ) += zynq/ obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/ obj-$(CONFIG_CLK_SOCFPGA) += socfpga/ obj-$(CONFIG_SOC_QCA_AR9331) += clk-ar933x.o diff --git a/drivers/clk/zynq/Makefile b/drivers/clk/zynq/Makefile new file mode 100644 index 0000000000..8fedfc77e4 --- /dev/null +++ b/drivers/clk/zynq/Makefile @@ -0,0 +1 @@ +obj-y += clkc.o diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c new file mode 100644 index 0000000000..cd49d8478f --- /dev/null +++ b/drivers/clk/zynq/clkc.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2013 Josh Cartwright + * Copyright (c) 2013 Steffen Trumtrar + * + * Based on drivers/clk-zynq.c from Linux. + * + * Copyright (c) 2012 National Instruments + * + * Josh Cartwright + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +enum zynq_clks { + dummy, ps_clk, arm_pll, ddr_pll, io_pll, uart_clk, uart0, uart1, + cpu_clk, cpu_6x4x, cpu_3x2x, cpu_2x, cpu_1x, + gem_clk, gem0, gem1, clks_max +}; + +enum zynq_pll_type { + ZYNQ_PLL_ARM, + ZYNQ_PLL_DDR, + ZYNQ_PLL_IO, +}; + +#define PLL_STATUS_ARM_PLL_LOCK (1 << 0) +#define PLL_STATUS_DDR_PLL_LOCK (1 << 1) +#define PLL_STATUS_IO_PLL_LOCK (1 << 2) +#define PLL_STATUS_ARM_PLL_STABLE (1 << 0) +#define PLL_STATUS_DDR_PLL_STABLE (1 << 1) +#define PLL_STATUS_IO_PLL_STABLE (1 << 2) +#define PLL_CTRL_BYPASS_FORCE (1 << 4) + +static struct clk *clks[clks_max]; + +struct zynq_pll_clk { + struct clk clk; + u32 pll_lock; + void __iomem *pll_ctrl; +}; + +#define to_zynq_pll_clk(c) container_of(c, struct zynq_pll_clk, clk) + +#define PLL_CTRL_FDIV(x) (((x) >> 12) & 0x7F) + +static unsigned long zynq_pll_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct zynq_pll_clk *pll = to_zynq_pll_clk(clk); + return parent_rate * PLL_CTRL_FDIV(readl(pll->pll_ctrl)); +} + +static int zynq_pll_enable(struct clk *clk) +{ + struct zynq_pll_clk *pll = to_zynq_pll_clk(clk); + u32 val; + int timeout = 10000; + + val = readl(pll->pll_ctrl); + val &= ~PLL_CTRL_BYPASS_FORCE; + writel(val, pll->pll_ctrl); + + while (timeout--) { + if (readl(ZYNQ_CLOCK_CTRL_BASE + ZYNQ_PLL_STATUS) & pll->pll_lock) + break; + } + + if (!timeout) + return -ETIMEDOUT; + + return 0; +} + +static struct clk_ops zynq_pll_clk_ops = { + .recalc_rate = zynq_pll_recalc_rate, + .enable = zynq_pll_enable, +}; + +static inline struct clk *zynq_pll_clk(enum zynq_pll_type type, + const char *name, + void __iomem *pll_ctrl) +{ + static const char *pll_parent = "ps_clk"; + struct zynq_pll_clk *pll; + int ret; + + pll = xzalloc(sizeof(*pll)); + pll->pll_ctrl = pll_ctrl; + pll->clk.ops = &zynq_pll_clk_ops; + pll->clk.name = name; + pll->clk.parent_names = &pll_parent; + pll->clk.num_parents = 1; + + switch(type) { + case ZYNQ_PLL_ARM: + pll->pll_lock = PLL_STATUS_ARM_PLL_LOCK; + break; + case ZYNQ_PLL_DDR: + pll->pll_lock = PLL_STATUS_DDR_PLL_LOCK; + break; + case ZYNQ_PLL_IO: + pll->pll_lock = PLL_STATUS_IO_PLL_LOCK; + break; + } + + ret = clk_register(&pll->clk); + if (ret) { + free(pll); + return ERR_PTR(ret); + } + + return &pll->clk; +} + +struct zynq_periph_clk { + struct clk clk; + void __iomem *clk_ctrl; +}; + +#define to_zynq_periph_clk(c) container_of(c, struct zynq_periph_clk, c) + +static const u8 periph_clk_parent_map[] = { + 0, 0, 1, 2 +}; +#define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4]) +#define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) + +static unsigned long zynq_periph_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct zynq_periph_clk *periph = to_zynq_periph_clk(clk); + return parent_rate / PERIPH_CLK_CTRL_DIV(readl(periph->clk_ctrl)); +} + +static int zynq_periph_get_parent(struct clk *clk) +{ + struct zynq_periph_clk *periph = to_zynq_periph_clk(clk); + return PERIPH_CLK_CTRL_SRC(readl(periph->clk_ctrl)); +} + +static const struct clk_ops zynq_periph_clk_ops = { + .recalc_rate = zynq_periph_recalc_rate, + .get_parent = zynq_periph_get_parent, +}; + +static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl) +{ + static const char *peripheral_parents[] = { + "io_pll", + "arm_pll", + "ddr_pll", + }; + struct zynq_periph_clk *periph; + int ret; + + periph = xzalloc(sizeof(*periph)); + + periph->clk_ctrl = clk_ctrl; + periph->clk.name = name; + periph->clk.ops = &zynq_periph_clk_ops; + periph->clk.parent_names = peripheral_parents; + periph->clk.num_parents = ARRAY_SIZE(peripheral_parents); + + ret = clk_register(&periph->clk); + if (ret) { + free(periph); + return ERR_PTR(ret); + } + + return &periph->clk; +} + +/* CPU Clock domain is modelled as a mux with 4 children subclks, whose + * derivative rates depend on CLK_621_TRUE + */ + +struct zynq_cpu_clk { + struct clk clk; + void __iomem *clk_ctrl; +}; + +#define to_zynq_cpu_clk(c) container_of(c, struct zynq_cpu_clk, c) + +static const u8 zynq_cpu_clk_parent_map[] = { + 1, 1, 2, 0 +}; +#define CPU_CLK_SRCSEL(x) (zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)]) +#define CPU_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) + +static unsigned long zynq_cpu_clk_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk); + return parent_rate / CPU_CLK_CTRL_DIV(readl(cpuclk->clk_ctrl)); +} + +static int zynq_cpu_clk_get_parent(struct clk *clk) +{ + struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk); + return CPU_CLK_SRCSEL(readl(cpuclk->clk_ctrl)); +} + +static const struct clk_ops zynq_cpu_clk_ops = { + .get_parent = zynq_cpu_clk_get_parent, + .recalc_rate = zynq_cpu_clk_recalc_rate, +}; + +static struct clk *zynq_cpu_clk(const char *name, void __iomem *clk_ctrl) +{ + static const char *cpu_parents[] = { + "io_pll", + "arm_pll", + "ddr_pll", + }; + struct zynq_cpu_clk *cpu; + int ret; + + cpu = xzalloc(sizeof(*cpu)); + + cpu->clk_ctrl = clk_ctrl; + cpu->clk.ops = &zynq_cpu_clk_ops; + cpu->clk.name = name; + cpu->clk.parent_names = cpu_parents; + cpu->clk.num_parents = ARRAY_SIZE(cpu_parents); + + ret = clk_register(&cpu->clk); + if (ret) { + free(cpu); + return ERR_PTR(ret); + } + + return &cpu->clk; +} + +enum zynq_cpu_subclk_which { + CPU_SUBCLK_6X4X, + CPU_SUBCLK_3X2X, + CPU_SUBCLK_2X, + CPU_SUBCLK_1X, +}; + +struct zynq_cpu_subclk { + struct clk clk; + void __iomem *clk_ctrl; + void __iomem *clk_621; + enum zynq_cpu_subclk_which which; +}; + +#define CLK_621_TRUE(x) ((x) & 1) + +#define to_zynq_cpu_subclk(c) container_of(c, struct zynq_cpu_subclk, c); + +static unsigned long zynq_cpu_subclk_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + unsigned long uninitialized_var(rate); + struct zynq_cpu_subclk *subclk; + bool is_621; + + subclk = to_zynq_cpu_subclk(clk); + is_621 = CLK_621_TRUE(readl(subclk->clk_621)); + + switch (subclk->which) { + case CPU_SUBCLK_6X4X: + rate = parent_rate; + break; + case CPU_SUBCLK_3X2X: + rate = parent_rate / 2; + break; + case CPU_SUBCLK_2X: + rate = parent_rate / (is_621 ? 3 : 2); + break; + case CPU_SUBCLK_1X: + rate = parent_rate / (is_621 ? 6 : 4); + break; + }; + + return rate; +} + +static int zynq_cpu_subclk_enable(struct clk *clk) +{ + struct zynq_cpu_subclk *subclk; + u32 tmp; + + subclk = to_zynq_cpu_subclk(clk); + + tmp = readl(subclk->clk_ctrl); + tmp |= 1 << (24 + subclk->which); + writel(tmp, subclk->clk_ctrl); + + return 0; +} + +static void zynq_cpu_subclk_disable(struct clk *clk) +{ + struct zynq_cpu_subclk *subclk; + u32 tmp; + + subclk = to_zynq_cpu_subclk(clk); + + tmp = readl(subclk->clk_ctrl); + tmp &= ~(1 << (24 + subclk->which)); + writel(tmp, subclk->clk_ctrl); +} + +static const struct clk_ops zynq_cpu_subclk_ops = { + .enable = zynq_cpu_subclk_enable, + .disable = zynq_cpu_subclk_disable, + .recalc_rate = zynq_cpu_subclk_recalc_rate, +}; + +static struct clk *zynq_cpu_subclk(const char *name, + enum zynq_cpu_subclk_which which, + void __iomem *clk_ctrl, + void __iomem *clk_621) +{ + static const char *subclk_parent = "cpu_clk"; + struct zynq_cpu_subclk *subclk; + int ret; + + subclk = xzalloc(sizeof(*subclk)); + + subclk->clk_ctrl = clk_ctrl; + subclk->clk_621 = clk_621; + subclk->which = which; + subclk->clk.name = name; + subclk->clk.ops = &zynq_cpu_subclk_ops; + + subclk->clk.parent_names = &subclk_parent; + subclk->clk.num_parents = 1; + + ret = clk_register(&subclk->clk); + if (ret) { + free(subclk); + return ERR_PTR(ret); + } + + return &subclk->clk; +} + +static int zynq_clock_probe(struct device_d *dev) +{ + struct resource *iores; + void __iomem *slcr_base; + unsigned long ps_clk_rate = 33333330; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + slcr_base = IOMEM(iores->start); + + clks[ps_clk] = clk_fixed("ps_clk", ps_clk_rate); + + clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", slcr_base + 0x100); + clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", slcr_base + 0x104); + clks[io_pll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", slcr_base + 0x108); + + clks[uart_clk] = zynq_periph_clk("uart_clk", slcr_base + 0x154); + + clks[uart0] = clk_gate("uart0", "uart_clk", slcr_base + 0x154, 0, 0, 0); + clks[uart1] = clk_gate("uart1", "uart_clk", slcr_base + 0x154, 1, 0, 0); + + clks[gem0] = clk_gate("gem0", "io_pll", slcr_base + 0x140, 0, 0, 0); + clks[gem1] = clk_gate("gem1", "io_pll", slcr_base + 0x144, 1, 0, 0); + + clks[cpu_clk] = zynq_cpu_clk("cpu_clk", slcr_base + 0x120); + + clks[cpu_6x4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X, + slcr_base + 0x120, slcr_base + 0x1C4); + clks[cpu_3x2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X, + slcr_base + 0x120, slcr_base + 0x1C4); + clks[cpu_2x] = zynq_cpu_subclk("cpu_2x", CPU_SUBCLK_2X, + slcr_base + 0x120, slcr_base + 0x1C4); + clks[cpu_1x] = zynq_cpu_subclk("cpu_1x", CPU_SUBCLK_1X, + slcr_base + 0x120, slcr_base + 0x1C4); + + clk_register_clkdev(clks[cpu_3x2x], NULL, "arm_smp_twd"); + clk_register_clkdev(clks[uart0], NULL, "zynq_serial0"); + clk_register_clkdev(clks[uart1], NULL, "zynq_serial1"); + clk_register_clkdev(clks[gem0], NULL, "macb0"); + clk_register_clkdev(clks[gem1], NULL, "macb1"); + + clkdev_add_physbase(clks[cpu_3x2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL); + clkdev_add_physbase(clks[uart1], ZYNQ_UART1_BASE_ADDR, NULL); + + return 0; +} + +static __maybe_unused struct of_device_id zynq_clock_dt_ids[] = { + { + .compatible = "xlnx,zynq-clock", + }, { + /* sentinel */ + } +}; + +static struct driver_d zynq_clock_driver = { + .probe = zynq_clock_probe, + .name = "zynq-clock", + .of_compatible = DRV_OF_COMPAT(zynq_clock_dt_ids), +}; + +static int zynq_clock_init(void) +{ + return platform_driver_register(&zynq_clock_driver); +} +postcore_initcall(zynq_clock_init); -- cgit v1.2.3 From fee27d41640f4732f7df1648ba8c44b0f91153e3 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:29 +0100 Subject: clk: zynq: use base address of clock controller The clock controller is a subregion of the SLCR, use the real base of this region for mapping the registers. This will allow to switch to DT based probing later. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/mach-zynq/zynq.c | 3 ++- drivers/clk/zynq/clkc.c | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-zynq/zynq.c b/arch/arm/mach-zynq/zynq.c index f6112fd249..ec22b16c91 100644 --- a/arch/arm/mach-zynq/zynq.c +++ b/arch/arm/mach-zynq/zynq.c @@ -48,7 +48,8 @@ static int zynq_init(void) writel(val, 0xf8f00000); dmb(); - add_generic_device("zynq-clock", 0, NULL, ZYNQ_SLCR_BASE, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("zynq-clock", 0, NULL, ZYNQ_SLCR_BASE + 0x100, + 0x4000, IORESOURCE_MEM, NULL); add_generic_device("smp_twd", 0, NULL, CORTEXA9_SCU_TIMER_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); restart_handler_register_fn(zynq_restart_soc); diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index cd49d8478f..ba441740c5 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -360,38 +360,38 @@ static struct clk *zynq_cpu_subclk(const char *name, static int zynq_clock_probe(struct device_d *dev) { struct resource *iores; - void __iomem *slcr_base; + void __iomem *clk_base; unsigned long ps_clk_rate = 33333330; iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) return PTR_ERR(iores); - slcr_base = IOMEM(iores->start); + clk_base = IOMEM(iores->start); clks[ps_clk] = clk_fixed("ps_clk", ps_clk_rate); - clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", slcr_base + 0x100); - clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", slcr_base + 0x104); - clks[io_pll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", slcr_base + 0x108); + clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", clk_base + 0x0); + clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", clk_base + 0x4); + clks[io_pll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", clk_base + 0x8); - clks[uart_clk] = zynq_periph_clk("uart_clk", slcr_base + 0x154); + clks[uart_clk] = zynq_periph_clk("uart_clk", clk_base + 0x54); - clks[uart0] = clk_gate("uart0", "uart_clk", slcr_base + 0x154, 0, 0, 0); - clks[uart1] = clk_gate("uart1", "uart_clk", slcr_base + 0x154, 1, 0, 0); + clks[uart0] = clk_gate("uart0", "uart_clk", clk_base + 0x54, 0, 0, 0); + clks[uart1] = clk_gate("uart1", "uart_clk", clk_base + 0x54, 1, 0, 0); - clks[gem0] = clk_gate("gem0", "io_pll", slcr_base + 0x140, 0, 0, 0); - clks[gem1] = clk_gate("gem1", "io_pll", slcr_base + 0x144, 1, 0, 0); + clks[gem0] = clk_gate("gem0", "io_pll", clk_base + 0x40, 0, 0, 0); + clks[gem1] = clk_gate("gem1", "io_pll", clk_base + 0x44, 1, 0, 0); - clks[cpu_clk] = zynq_cpu_clk("cpu_clk", slcr_base + 0x120); + clks[cpu_clk] = zynq_cpu_clk("cpu_clk", clk_base + 0x20); clks[cpu_6x4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X, - slcr_base + 0x120, slcr_base + 0x1C4); + clk_base + 0x20, clk_base + 0xC4); clks[cpu_3x2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X, - slcr_base + 0x120, slcr_base + 0x1C4); + clk_base + 0x20, clk_base + 0xC4); clks[cpu_2x] = zynq_cpu_subclk("cpu_2x", CPU_SUBCLK_2X, - slcr_base + 0x120, slcr_base + 0x1C4); + clk_base + 0x20, clk_base + 0xC4); clks[cpu_1x] = zynq_cpu_subclk("cpu_1x", CPU_SUBCLK_1X, - slcr_base + 0x120, slcr_base + 0x1C4); + clk_base + 0x20, clk_base + 0xC4); clk_register_clkdev(clks[cpu_3x2x], NULL, "arm_smp_twd"); clk_register_clkdev(clks[uart0], NULL, "zynq_serial0"); -- cgit v1.2.3 From 676d3bef72e8791758b4da1fdc183fcff5c5f82f Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:30 +0100 Subject: clk: zynq: improve PLL enable handling Ensure that both the powerdown and reset bits are cleared when the PLL gets enabled, as any of those set would prevent the PLL from working. Also add a status readback function, so the real status of the PLL is reflected in the Barebox clock state. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/clk/zynq/clkc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index ba441740c5..07152e2ada 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -48,6 +48,8 @@ enum zynq_pll_type { #define PLL_STATUS_DDR_PLL_STABLE (1 << 1) #define PLL_STATUS_IO_PLL_STABLE (1 << 2) #define PLL_CTRL_BYPASS_FORCE (1 << 4) +#define PLL_CTRL_PWRDOWN (1 << 1) +#define PLL_CTRL_RESET (1 << 0) static struct clk *clks[clks_max]; @@ -75,7 +77,7 @@ static int zynq_pll_enable(struct clk *clk) int timeout = 10000; val = readl(pll->pll_ctrl); - val &= ~PLL_CTRL_BYPASS_FORCE; + val &= ~(PLL_CTRL_BYPASS_FORCE | PLL_CTRL_PWRDOWN | PLL_CTRL_RESET); writel(val, pll->pll_ctrl); while (timeout--) { @@ -89,9 +91,18 @@ static int zynq_pll_enable(struct clk *clk) return 0; } +static int zynq_pll_is_enabled(struct clk *clk) +{ + struct zynq_pll_clk *pll = to_zynq_pll_clk(clk); + u32 val = readl(pll->pll_ctrl); + + return !(val & (PLL_CTRL_PWRDOWN | PLL_CTRL_RESET)); +} + static struct clk_ops zynq_pll_clk_ops = { .recalc_rate = zynq_pll_recalc_rate, .enable = zynq_pll_enable, + .is_enabled = zynq_pll_is_enabled, }; static inline struct clk *zynq_pll_clk(enum zynq_pll_type type, -- cgit v1.2.3 From daf2ffab24f0dde8c45c34ef82ce29399c897b12 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:31 +0100 Subject: clk: zynq: fix up address from DT The upstream Zynq 7000 DT describes the SLCR child devices physical address as an offset within the SLCR. The driver thus needs to add the SLCR base offset to the address before trying to map the MMIO region. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/clk/zynq/clkc.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 07152e2ada..90ab71fe96 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -373,10 +373,32 @@ static int zynq_clock_probe(struct device_d *dev) struct resource *iores; void __iomem *clk_base; unsigned long ps_clk_rate = 33333330; + resource_size_t slcr_offset = 0; - iores = dev_request_mem_resource(dev, 0); + iores = dev_get_resource(dev, IORESOURCE_MEM, 0); if (IS_ERR(iores)) return PTR_ERR(iores); + + /* + * The Zynq 7000 DT describes the SLCR child devices with a reg offset + * in the SCLR region. So we can't directly map the address we get from + * the DT, but need to add the SCLR base offset. + */ + if (dev->device_node) { + struct resource *parent_res; + + parent_res = dev_get_resource(dev->parent, IORESOURCE_MEM, 0); + if (IS_ERR(parent_res)) + return PTR_ERR(parent_res); + + slcr_offset = parent_res->start; + } + + iores = request_iomem_region(dev_name(dev), iores->start + slcr_offset, + iores->end + slcr_offset); + if (IS_ERR(iores)) + return PTR_ERR(iores); + clk_base = IOMEM(iores->start); clks[ps_clk] = clk_fixed("ps_clk", ps_clk_rate); -- cgit v1.2.3 From cfffe9368ac4eeda52ed837f8adb41a54cc85e96 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:32 +0100 Subject: clk: zynq: partially sync with Linux Sync the clock enum with the clocks used by Linux and the DT binding. Implement AMBA bus clocks and SPI and SDIO peripheral clocks and register a DT clock controller, so the clocks can be looked up by DT handle. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/clk/zynq/clkc.c | 87 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 16 deletions(-) diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 90ab71fe96..f30aa8238a 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -29,10 +29,16 @@ #include #include -enum zynq_clks { - dummy, ps_clk, arm_pll, ddr_pll, io_pll, uart_clk, uart0, uart1, - cpu_clk, cpu_6x4x, cpu_3x2x, cpu_2x, cpu_1x, - gem_clk, gem0, gem1, clks_max +enum zynq_clk { + armpll, ddrpll, iopll, + cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x, + ddr2x, ddr3x, dci, + lqspi, smc, pcap, gem0, gem1, fclk0, fclk1, fclk2, fclk3, can0, can1, + sdio0, sdio1, uart0, uart1, spi0, spi1, dma, + usb0_aper, usb1_aper, gem0_aper, gem1_aper, + sdio0_aper, sdio1_aper, spi0_aper, spi1_aper, can0_aper, can1_aper, + i2c0_aper, i2c1_aper, uart0_aper, uart1_aper, gpio_aper, lqspi_aper, + smc_aper, swdt, dbg_trc, dbg_apb, clk_max }; enum zynq_pll_type { @@ -51,7 +57,8 @@ enum zynq_pll_type { #define PLL_CTRL_PWRDOWN (1 << 1) #define PLL_CTRL_RESET (1 << 0) -static struct clk *clks[clks_max]; +static struct clk *clks[clk_max]; +static struct clk_onecell_data clk_data; struct zynq_pll_clk { struct clk clk; @@ -401,46 +408,94 @@ static int zynq_clock_probe(struct device_d *dev) clk_base = IOMEM(iores->start); - clks[ps_clk] = clk_fixed("ps_clk", ps_clk_rate); + clk_fixed("ps_clk", ps_clk_rate); - clks[arm_pll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", clk_base + 0x0); - clks[ddr_pll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", clk_base + 0x4); - clks[io_pll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", clk_base + 0x8); + clks[armpll] = zynq_pll_clk(ZYNQ_PLL_ARM, "arm_pll", clk_base + 0x0); + clks[ddrpll] = zynq_pll_clk(ZYNQ_PLL_DDR, "ddr_pll", clk_base + 0x4); + clks[iopll] = zynq_pll_clk(ZYNQ_PLL_IO, "io_pll", clk_base + 0x8); - clks[uart_clk] = zynq_periph_clk("uart_clk", clk_base + 0x54); + zynq_periph_clk("sdio_clk", clk_base + 0x50); + clks[sdio0] = clk_gate("sdio0", "sdio_clk", clk_base + 0x50, 0, 0, 0); + clks[sdio1] = clk_gate("sdio1", "sdio_clk", clk_base + 0x50, 1, 0, 0); + zynq_periph_clk("uart_clk", clk_base + 0x54); clks[uart0] = clk_gate("uart0", "uart_clk", clk_base + 0x54, 0, 0, 0); clks[uart1] = clk_gate("uart1", "uart_clk", clk_base + 0x54, 1, 0, 0); + zynq_periph_clk("spi_clk", clk_base + 0x58); + clks[spi0] = clk_gate("spi0", "spi_clk", clk_base + 0x58, 0, 0, 0); + clks[spi1] = clk_gate("spi1", "spi_clk", clk_base + 0x58, 1, 0, 0); + clks[gem0] = clk_gate("gem0", "io_pll", clk_base + 0x40, 0, 0, 0); clks[gem1] = clk_gate("gem1", "io_pll", clk_base + 0x44, 1, 0, 0); - clks[cpu_clk] = zynq_cpu_clk("cpu_clk", clk_base + 0x20); + zynq_cpu_clk("cpu_clk", clk_base + 0x20); - clks[cpu_6x4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X, + clks[cpu_6or4x] = zynq_cpu_subclk("cpu_6x4x", CPU_SUBCLK_6X4X, clk_base + 0x20, clk_base + 0xC4); - clks[cpu_3x2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X, + clks[cpu_3or2x] = zynq_cpu_subclk("cpu_3x2x", CPU_SUBCLK_3X2X, clk_base + 0x20, clk_base + 0xC4); clks[cpu_2x] = zynq_cpu_subclk("cpu_2x", CPU_SUBCLK_2X, clk_base + 0x20, clk_base + 0xC4); clks[cpu_1x] = zynq_cpu_subclk("cpu_1x", CPU_SUBCLK_1X, clk_base + 0x20, clk_base + 0xC4); - clk_register_clkdev(clks[cpu_3x2x], NULL, "arm_smp_twd"); + clks[dma] = clk_gate("dma", "cpu_2x", clk_base + 0x2C, 0, 0, 0); + clks[usb0_aper] = clk_gate("usb0_aper", "cpu_1x", + clk_base + 0x2C, 2, 0, 0); + clks[usb1_aper] = clk_gate("usb1_aper", "cpu_1x", + clk_base + 0x2C, 3, 0, 0); + clks[gem0_aper] = clk_gate("gem0_aper", "cpu_1x", + clk_base + 0x2C, 6, 0, 0); + clks[gem1_aper] = clk_gate("gem1_aper", "cpu_1x", + clk_base + 0x2C, 7, 0, 0); + clks[sdio0_aper] = clk_gate("sdio0_aper", "cpu_1x", + clk_base + 0x2C, 10, 0, 0); + clks[sdio1_aper] = clk_gate("sdio1_aper", "cpu_1x", + clk_base + 0x2C, 11, 0, 0); + clks[spi0_aper] = clk_gate("spi0_aper", "cpu_1x", + clk_base + 0x2C, 14, 0, 0); + clks[spi1_aper] = clk_gate("spi1_aper", "cpu_1x", + clk_base + 0x2C, 15, 0, 0); + clks[can0_aper] = clk_gate("can0_aper", "cpu_1x", + clk_base + 0x2C, 16, 0, 0); + clks[can1_aper] = clk_gate("can1_aper", "cpu_1x", + clk_base + 0x2C, 17, 0, 0); + clks[i2c0_aper] = clk_gate("i2c0_aper", "cpu_1x", + clk_base + 0x2C, 18, 0, 0); + clks[i2c1_aper] = clk_gate("i2c1_aper", "cpu_1x", + clk_base + 0x2C, 19, 0, 0); + clks[uart0_aper] = clk_gate("uart0_aper", "cpu_1x", + clk_base + 0x2C, 20, 0, 0); + clks[uart1_aper] = clk_gate("uart1_aper", "cpu_1x", + clk_base + 0x2C, 21, 0, 0); + clks[gpio_aper] = clk_gate("gpio_aper", "cpu_1x", + clk_base + 0x2C, 22, 0, 0); + clks[lqspi_aper] = clk_gate("lqspi_aper", "cpu_1x", + clk_base + 0x2C, 23, 0, 0); + clks[smc_aper] = clk_gate("smc_aper", "cpu_1x", + clk_base + 0x2C, 24, 0, 0); + + clk_register_clkdev(clks[cpu_3or2x], NULL, "arm_smp_twd"); clk_register_clkdev(clks[uart0], NULL, "zynq_serial0"); clk_register_clkdev(clks[uart1], NULL, "zynq_serial1"); clk_register_clkdev(clks[gem0], NULL, "macb0"); clk_register_clkdev(clks[gem1], NULL, "macb1"); - clkdev_add_physbase(clks[cpu_3x2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL); + clkdev_add_physbase(clks[cpu_3or2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL); clkdev_add_physbase(clks[uart1], ZYNQ_UART1_BASE_ADDR, NULL); + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, + &clk_data); + return 0; } static __maybe_unused struct of_device_id zynq_clock_dt_ids[] = { { - .compatible = "xlnx,zynq-clock", + .compatible = "xlnx,ps7-clkc", }, { /* sentinel */ } -- cgit v1.2.3 From 70b00bda144d2bf0dfbf55cef62d70f9e5e4fb69 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:33 +0100 Subject: ARM: zynq: switch to DT based probing All the currently supported devices can now be probed from the DT. Remove platform devices and switch to DT. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/boards/avnet-zedboard/board.c | 24 ------------------------ arch/arm/mach-zynq/Kconfig | 3 +++ arch/arm/mach-zynq/Makefile | 2 +- arch/arm/mach-zynq/devices.c | 13 ------------- arch/arm/mach-zynq/include/mach/devices.h | 20 -------------------- arch/arm/mach-zynq/zynq.c | 4 ---- 6 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 arch/arm/mach-zynq/devices.c delete mode 100644 arch/arm/mach-zynq/include/mach/devices.h diff --git a/arch/arm/boards/avnet-zedboard/board.c b/arch/arm/boards/avnet-zedboard/board.c index 722bda302e..f53dde47c2 100644 --- a/arch/arm/boards/avnet-zedboard/board.c +++ b/arch/arm/boards/avnet-zedboard/board.c @@ -17,38 +17,14 @@ #include #include #include -#include #include #include -static int zedboard_mem_init(void) -{ - arm_add_mem_device("ram0", 0, SZ_512M); - - return 0; -} -mem_initcall(zedboard_mem_init); - -static struct macb_platform_data macb_pdata = { - .phy_interface = PHY_INTERFACE_MODE_RGMII, - .phy_addr = 0x0, -}; - -static int zedboard_device_init(void) -{ - zynq_add_eth0(&macb_pdata); - - return 0; -} -device_initcall(zedboard_device_init); static int zedboard_console_init(void) { - barebox_set_model("Avnet ZedBoard"); barebox_set_hostname("zedboard"); - zynq_add_uart1(); - return 0; } console_initcall(zedboard_console_init); diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index d35bd41232..944f325bcc 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -16,8 +16,11 @@ config ARCH_ZYNQ7000 select CPU_V7 select CLKDEV_LOOKUP select COMMON_CLK + select COMMON_CLK_OF_PROVIDER select ARM_SMP_TWD select HAS_MACB + select OFTREE + select OFDEVICE endchoice diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index b401c77983..3252247d17 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -1 +1 @@ -obj-y += zynq.o devices.o +obj-y += zynq.o diff --git a/arch/arm/mach-zynq/devices.c b/arch/arm/mach-zynq/devices.c deleted file mode 100644 index 55e9433c51..0000000000 --- a/arch/arm/mach-zynq/devices.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -struct device_d *zynq_add_uart(resource_size_t base, int id) -{ - return add_generic_device("cadence-uart", id, NULL, base, 0x1000, IORESOURCE_MEM, NULL); -} - -struct device_d *zynq_add_eth(resource_size_t base, int id, struct macb_platform_data *pdata) -{ - return add_generic_device("macb", id, NULL, base, 0x1000, IORESOURCE_MEM, pdata); -} diff --git a/arch/arm/mach-zynq/include/mach/devices.h b/arch/arm/mach-zynq/include/mach/devices.h deleted file mode 100644 index c9670b02f3..0000000000 --- a/arch/arm/mach-zynq/include/mach/devices.h +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -struct device_d *zynq_add_uart(resource_size_t base, int id); -struct device_d *zynq_add_eth(resource_size_t base, int id, struct macb_platform_data *pdata); - -static inline struct device_d *zynq_add_uart0(void) -{ - return zynq_add_uart((resource_size_t)ZYNQ_UART0_BASE_ADDR, 0); -} - -static inline struct device_d *zynq_add_uart1(void) -{ - return zynq_add_uart((resource_size_t)ZYNQ_UART1_BASE_ADDR, 1); -} - -static inline struct device_d *zynq_add_eth0(struct macb_platform_data *pdata) -{ - return zynq_add_eth((resource_size_t)ZYNQ_GEM0_BASE_ADDR, 0, pdata); -} diff --git a/arch/arm/mach-zynq/zynq.c b/arch/arm/mach-zynq/zynq.c index ec22b16c91..ad06c624d9 100644 --- a/arch/arm/mach-zynq/zynq.c +++ b/arch/arm/mach-zynq/zynq.c @@ -48,10 +48,6 @@ static int zynq_init(void) writel(val, 0xf8f00000); dmb(); - add_generic_device("zynq-clock", 0, NULL, ZYNQ_SLCR_BASE + 0x100, - 0x4000, IORESOURCE_MEM, NULL); - add_generic_device("smp_twd", 0, NULL, CORTEXA9_SCU_TIMER_BASE_ADDR, - 0x4000, IORESOURCE_MEM, NULL); restart_handler_register_fn(zynq_restart_soc); return 0; -- cgit v1.2.3 From 7984f6549f300ffd6cff0bae6794b8008cdbbbd0 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:34 +0100 Subject: clk: zynq: remove clkdevs They aren't needed anymore, as all the Zynq devices now use a DT based clock lookup. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- drivers/clk/zynq/clkc.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index f30aa8238a..30ca5a60fa 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -476,15 +476,6 @@ static int zynq_clock_probe(struct device_d *dev) clks[smc_aper] = clk_gate("smc_aper", "cpu_1x", clk_base + 0x2C, 24, 0, 0); - clk_register_clkdev(clks[cpu_3or2x], NULL, "arm_smp_twd"); - clk_register_clkdev(clks[uart0], NULL, "zynq_serial0"); - clk_register_clkdev(clks[uart1], NULL, "zynq_serial1"); - clk_register_clkdev(clks[gem0], NULL, "macb0"); - clk_register_clkdev(clks[gem1], NULL, "macb1"); - - clkdev_add_physbase(clks[cpu_3or2x], CORTEXA9_SCU_TIMER_BASE_ADDR, NULL); - clkdev_add_physbase(clks[uart1], ZYNQ_UART1_BASE_ADDR, NULL); - clk_data.clks = clks; clk_data.clk_num = ARRAY_SIZE(clks); of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, -- cgit v1.2.3 From 3acac5f7751a5055c023520ff21bb551a2c8ebc3 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:35 +0100 Subject: ARM: zynq: switch to multi-image build Finally move over to a multi-image based build. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/boards/avnet-zedboard/lowlevel.c | 2 +- arch/arm/configs/zedboard_defconfig | 45 ----------------------------- arch/arm/configs/zynq_defconfig | 47 +++++++++++++++++++++++++++++++ arch/arm/mach-zynq/Kconfig | 18 +++++------- images/Makefile.zynq | 4 +-- 5 files changed, 57 insertions(+), 59 deletions(-) delete mode 100644 arch/arm/configs/zedboard_defconfig create mode 100644 arch/arm/configs/zynq_defconfig diff --git a/arch/arm/boards/avnet-zedboard/lowlevel.c b/arch/arm/boards/avnet-zedboard/lowlevel.c index ae279e4e64..93e4da96ec 100644 --- a/arch/arm/boards/avnet-zedboard/lowlevel.c +++ b/arch/arm/boards/avnet-zedboard/lowlevel.c @@ -29,7 +29,7 @@ extern char __dtb_zynq_zed_start[]; -void __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2) +ENTRY_FUNCTION(start_avnet_zedboard, r0, r1, r2) { void *fdt = __dtb_zynq_zed_start + get_runtime_offset(); diff --git a/arch/arm/configs/zedboard_defconfig b/arch/arm/configs/zedboard_defconfig deleted file mode 100644 index 0e5078c402..0000000000 --- a/arch/arm/configs/zedboard_defconfig +++ /dev/null @@ -1,45 +0,0 @@ -CONFIG_ARCH_ZYNQ=y -CONFIG_AEABI=y -CONFIG_ARM_UNWIND=y -CONFIG_MMU=y -CONFIG_STACK_SIZE=0xf000 -CONFIG_MALLOC_SIZE=0x8000000 -CONFIG_MALLOC_TLSF=y -CONFIG_KALLSYMS=y -CONFIG_HUSH_FANCY_PROMPT=y -CONFIG_CMDLINE_EDITING=y -CONFIG_AUTO_COMPLETE=y -CONFIG_MENU=y -CONFIG_BOOTM_SHOW_TYPE=y -CONFIG_BOOTM_VERBOSE=y -CONFIG_BOOTM_INITRD=y -CONFIG_BOOTM_OFTREE=y -CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/avnet-zedboard/env" -CONFIG_DEBUG_LL=y -CONFIG_LONGHELP=y -CONFIG_CMD_MEMINFO=y -CONFIG_CMD_ARM_MMUINFO=y -CONFIG_CMD_GO=y -CONFIG_CMD_RESET=y -CONFIG_CMD_PARTITION=y -CONFIG_CMD_EXPORT=y -CONFIG_CMD_PRINTENV=y -CONFIG_CMD_SAVEENV=y -CONFIG_CMD_LN=y -CONFIG_CMD_SLEEP=y -CONFIG_CMD_DHCP=y -CONFIG_CMD_EDIT=y -CONFIG_CMD_MENU=y -CONFIG_CMD_MENU_MANAGEMENT=y -CONFIG_CMD_READLINE=y -CONFIG_CMD_TIMEOUT=y -CONFIG_CMD_CLK=y -CONFIG_CMD_OFTREE=y -CONFIG_CMD_TIME=y -CONFIG_NET=y -CONFIG_DRIVER_SERIAL_CADENCE=y -CONFIG_DRIVER_NET_MACB=y -# CONFIG_SPI is not set -CONFIG_FS_TFTP=y -CONFIG_DIGEST=y diff --git a/arch/arm/configs/zynq_defconfig b/arch/arm/configs/zynq_defconfig new file mode 100644 index 0000000000..a16c57d5ce --- /dev/null +++ b/arch/arm/configs/zynq_defconfig @@ -0,0 +1,47 @@ +CONFIG_ARCH_ZYNQ=y +CONFIG_MACH_ZEDBOARD=y +CONFIG_AEABI=y +CONFIG_ARM_UNWIND=y +CONFIG_MMU=y +CONFIG_STACK_SIZE=0xf000 +CONFIG_MALLOC_SIZE=0x8000000 +CONFIG_MALLOC_TLSF=y +CONFIG_KALLSYMS=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_BOOTM_SHOW_TYPE=y +CONFIG_BOOTM_VERBOSE=y +CONFIG_BOOTM_INITRD=y +CONFIG_BOOTM_OFTREE=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/avnet-zedboard/env" +CONFIG_DEBUG_LL=y +CONFIG_LONGHELP=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_ARM_MMUINFO=y +CONFIG_CMD_GO=y +CONFIG_CMD_RESET=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LN=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_CLK=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_NET=y +CONFIG_DRIVER_SERIAL_CADENCE=y +CONFIG_DRIVER_NET_MACB=y +# CONFIG_SPI is not set +# CONFIG_PINCTRL is not set +CONFIG_FS_TFTP=y +CONFIG_DIGEST=y diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index 944f325bcc..3e07633e5f 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -2,37 +2,33 @@ if ARCH_ZYNQ config ARCH_TEXT_BASE hex - default 0x1ff00000 if MACH_ZEDBOARD + default 0x0 config ZYNQ_DEBUG_LL_UART_BASE hex default 0xe0001000 if MACH_ZEDBOARD -choice - prompt "Xilinx Zynq type board" - config ARCH_ZYNQ7000 - bool "Zynq-7000" + bool select CPU_V7 select CLKDEV_LOOKUP select COMMON_CLK select COMMON_CLK_OF_PROVIDER select ARM_SMP_TWD select HAS_MACB + select HAVE_PBL_MULTI_IMAGES select OFTREE select OFDEVICE + select RELOCATABLE -endchoice -if ARCH_ZYNQ7000 -choice - prompt "Zynq-7000 Board Type" +menu "select Zynq boards to be built" config MACH_ZEDBOARD bool "Avnet Zynq-7000 ZedBoard" + select ARCH_ZYNQ7000 -endchoice -endif +endmenu endif diff --git a/images/Makefile.zynq b/images/Makefile.zynq index b089a9fd26..062496ac7d 100644 --- a/images/Makefile.zynq +++ b/images/Makefile.zynq @@ -18,6 +18,6 @@ $(obj)/%.zynqimg: $(obj)/% FORCE #------------------------------------------------------------------------------ -CFG_start_pbl.pblb.zynqimg = $(board)/avnet-zedboard/zedboard.zynqcfg -FILE_barebox-avnet-zedboard.img = start_pbl.pblb.zynqimg +CFG_start_avnet_zedboard.pblb.zynqimg = $(board)/avnet-zedboard/zedboard.zynqcfg +FILE_barebox-avnet-zedboard.img = start_avnet_zedboard.pblb.zynqimg image-$(CONFIG_MACH_ZEDBOARD) += barebox-avnet-zedboard.img -- cgit v1.2.3 From db3ea7aae9266e5f9328b25e440ac9cd095f8d17 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:36 +0100 Subject: bootsource: add JTAG bootsource Some SoCs are able to detect if they are booted from JTAG. Add the enum value to be able to represent this as a valid bootsource. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- common/bootsource.c | 1 + include/bootsource.h | 1 + 2 files changed, 2 insertions(+) diff --git a/common/bootsource.c b/common/bootsource.c index 4ef8d8ad95..1f2bf87e99 100644 --- a/common/bootsource.c +++ b/common/bootsource.c @@ -37,6 +37,7 @@ static const char *bootsource_str[] = { [BOOTSOURCE_USB] = "usb", [BOOTSOURCE_NET] = "net", [BOOTSOURCE_CAN] = "can", + [BOOTSOURCE_JTAG] = "jtag", }; static enum bootsource bootsource = BOOTSOURCE_UNKNOWN; diff --git a/include/bootsource.h b/include/bootsource.h index 29347aaeb0..92f7f27cd4 100644 --- a/include/bootsource.h +++ b/include/bootsource.h @@ -17,6 +17,7 @@ enum bootsource { BOOTSOURCE_USB, BOOTSOURCE_NET, BOOTSOURCE_CAN, + BOOTSOURCE_JTAG, }; #define BOOTSOURCE_INSTANCE_UNKNOWN -1 -- cgit v1.2.3 From 096d308b6b780dba72538cf86c5031beaffe5e04 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 9 Nov 2019 15:28:37 +0100 Subject: ARM: zynq: add bootsource detection Implement the bootsource detection by reading the BOOT_MODE SLCR register which holds the strap values used to select the boot source. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/mach-zynq/include/mach/zynq7000-regs.h | 1 + arch/arm/mach-zynq/zynq.c | 27 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-zynq/include/mach/zynq7000-regs.h b/arch/arm/mach-zynq/include/mach/zynq7000-regs.h index dd02f5b407..eeecfe1ded 100644 --- a/arch/arm/mach-zynq/include/mach/zynq7000-regs.h +++ b/arch/arm/mach-zynq/include/mach/zynq7000-regs.h @@ -63,6 +63,7 @@ #define ZYNQ_FPGA3_CLK_CTRL 0x0A0 #define ZYNQ_CLK_621_TRUE 0x0C4 #define ZYNQ_RST_CTRL_BASE (ZYNQ_SLCR_BASE + 0x200) +#define ZYNQ_SLCR_BOOT_MODE (ZYNQ_SLCR_BASE + 0x25C) #define ZYNQ_PSS_RST_CTRL (ZYNQ_RST_CTRL_BASE + 0x000) #define ZYNQ_DDR_RST_CTRL (ZYNQ_RST_CTRL_BASE + 0x004) #define ZYNQ_TOPSW_RST_CTRL (ZYNQ_RST_CTRL_BASE + 0x008) diff --git a/arch/arm/mach-zynq/zynq.c b/arch/arm/mach-zynq/zynq.c index ad06c624d9..79a6b908e0 100644 --- a/arch/arm/mach-zynq/zynq.c +++ b/arch/arm/mach-zynq/zynq.c @@ -14,11 +14,12 @@ */ #include -#include +#include #include #include -#include +#include #include +#include static void __noreturn zynq_restart_soc(struct restart_handler *rst) { @@ -30,6 +31,26 @@ static void __noreturn zynq_restart_soc(struct restart_handler *rst) hang(); } +static enum bootsource zynq_bootsource_get(void) +{ + u32 boot_mode = readl(ZYNQ_SLCR_BOOT_MODE); + + switch (boot_mode & 0x7) { + case 0x0: + return BOOTSOURCE_JTAG; + case 0x1: + return BOOTSOURCE_SPI; + case 0x2: + return BOOTSOURCE_NOR; + case 0x4: + return BOOTSOURCE_NAND; + case 0x5: + return BOOTSOURCE_MMC; + default: + return BOOTSOURCE_UNKNOWN; + } +} + static int zynq_init(void) { u32 val; @@ -50,6 +71,8 @@ static int zynq_init(void) restart_handler_register_fn(zynq_restart_soc); + bootsource_set(zynq_bootsource_get()); + return 0; } postcore_initcall(zynq_init); -- cgit v1.2.3 From 1b8c4b2050f19c2d72691b57c0a505d4b7960640 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Mon, 18 Nov 2019 19:48:08 +0100 Subject: ARM: zynqmp: defconfig: fix FIRMWARE_ZYNQMP_FPGA The config item has been renamed from FIRMWARE_ZYNQMP_PL to FIRMWARE_ZYNQMP_FPGA, but the defconfig has not been updated. Update it now. Signed-off-by: Michael Tretter Signed-off-by: Sascha Hauer --- arch/arm/configs/zynqmp_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/zynqmp_defconfig b/arch/arm/configs/zynqmp_defconfig index 834212e30f..50b7556081 100644 --- a/arch/arm/configs/zynqmp_defconfig +++ b/arch/arm/configs/zynqmp_defconfig @@ -35,5 +35,5 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_DRIVER_SERIAL_CADENCE=y # CONFIG_SPI is not set -CONFIG_FIRMWARE_ZYNQMP_PL=y +CONFIG_FIRMWARE_ZYNQMP_FPGA=y CONFIG_DIGEST=y -- cgit v1.2.3 From 55246d3136115b18133e6df8e90e0c2056893888 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Mon, 18 Nov 2019 19:48:09 +0100 Subject: ARM: zynqmp: defconfig: reenable DRIVER_NET_MACB Commit d952a0eeba37 ("Regenerate defconfig files") disabled the macb driver in the ZynqMP defconfig, because CONFIG_NET was not enabled in the defconfig. While not strictly required, you probably want to enable the macb driver on the ZynqMP. Enable CONFIG_NET and reenable CONFIG_DRIVER_NET_MACB. Signed-off-by: Michael Tretter Signed-off-by: Sascha Hauer --- arch/arm/configs/zynqmp_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/zynqmp_defconfig b/arch/arm/configs/zynqmp_defconfig index 50b7556081..762103c541 100644 --- a/arch/arm/configs/zynqmp_defconfig +++ b/arch/arm/configs/zynqmp_defconfig @@ -33,7 +33,9 @@ CONFIG_CMD_TIMEOUT=y CONFIG_CMD_CLK=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y +CONFIG_NET=y CONFIG_DRIVER_SERIAL_CADENCE=y +CONFIG_DRIVER_NET_MACB=y # CONFIG_SPI is not set CONFIG_FIRMWARE_ZYNQMP_FPGA=y CONFIG_DIGEST=y -- cgit v1.2.3