From: Tom Rini Date: Mon, 27 May 2019 00:18:20 +0000 (-0400) Subject: Merge branch 'master' of git://git.denx.de/u-boot-sh X-Git-Tag: v2019.07-rc3~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c18b103657d9541305a45a1fb21f979c317fba49;hp=696f02d99b41190786b17ad28316a0cd45792c2c;p=platform%2Fkernel%2Fu-boot.git Merge branch 'master' of git://git.denx.de/u-boot-sh - Gen3 PCIe driver + enablement on Salvator-X platforms. - Gen3 recovery SPL used to reload ATF/OpTee/U-Boot instead of minimon. - SDHI HS400 fixes ported from latest BSP and datasheet. --- diff --git a/Kconfig b/Kconfig index fcde0c3..301ebf8 100644 --- a/Kconfig +++ b/Kconfig @@ -155,6 +155,7 @@ config SYS_MALLOC_LEN config SPL_SYS_MALLOC_F_LEN hex "Size of malloc() pool in SPL before relocation" depends on SYS_MALLOC_F + default 0x2800 if RCAR_GEN3 default SYS_MALLOC_F_LEN help Before relocation, memory is very limited on many platforms. Still, diff --git a/Makefile b/Makefile index 059978b..4ebc288 100644 --- a/Makefile +++ b/Makefile @@ -1117,6 +1117,9 @@ OBJCOPYFLAGS_u-boot-spl.srec = $(OBJCOPYFLAGS_u-boot.srec) spl/u-boot-spl.srec: spl/u-boot-spl FORCE $(call if_changed,objcopy) +%.scif: %.srec + $(Q)$(MAKE) $(build)=arch/arm/mach-rmobile $@ + OBJCOPYFLAGS_u-boot-nodtb.bin := -O binary \ $(if $(CONFIG_X86_16BIT_INIT),-R .start16 -R .resetvec) \ $(if $(CONFIG_MPC85XX_HAVE_RESET_VECTOR),-R .bootpg -R .resetvec) diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig index a74f16d..aafeb35 100644 --- a/arch/arm/mach-rmobile/Kconfig +++ b/arch/arm/mach-rmobile/Kconfig @@ -16,11 +16,22 @@ config RCAR_GEN3 select PINCTRL select PINCONF select PINCTRL_PFC + select SUPPORT_SPL imply CMD_FS_UUID imply CMD_GPT imply CMD_UUID imply CMD_MMC_SWRITE if MMC imply SUPPORT_EMMC_RPMB if MMC + imply SPL + imply SPL_BOARD_INIT + imply SPL_GZIP + imply SPL_LIBCOMMON_SUPPORT + imply SPL_LIBGENERIC_SUPPORT + imply SPL_SERIAL_SUPPORT + imply SPL_SYS_MALLOC_SIMPLE + imply SPL_TINY_MEMSET + imply SPL_YMODEM_SUPPORT + imply USE_TINY_PRINTF config RZA1 prompt "Renesas ARM SoCs RZ/A1 (32bit)" diff --git a/arch/arm/mach-rmobile/Makefile b/arch/arm/mach-rmobile/Makefile index 1f26ada..a3fdcc3 100644 --- a/arch/arm/mach-rmobile/Makefile +++ b/arch/arm/mach-rmobile/Makefile @@ -13,3 +13,76 @@ obj-$(CONFIG_SH73A0) += lowlevel_init.o cpu_info-sh73a0.o pfc-sh73a0.o obj-$(CONFIG_R8A7740) += lowlevel_init.o cpu_info-r8a7740.o pfc-r8a7740.o obj-$(CONFIG_RCAR_GEN2) += lowlevel_init_ca15.o cpu_info-rcar.o obj-$(CONFIG_RCAR_GEN3) += lowlevel_init_gen3.o cpu_info-rcar.o memmap-gen3.o + +OBJCOPYFLAGS_u-boot-spl.srec := -O srec +quiet_cmd_objcopy = OBJCOPY $@ +cmd_objcopy = $(OBJCOPY) --gap-fill=0x00 $(OBJCOPYFLAGS) \ + $(OBJCOPYFLAGS_$(@F)) $< $@ + +spl/u-boot-spl.srec: spl/u-boot-spl FORCE + $(call if_changed,objcopy) + +ifneq ($(CONFIG_R8A77990)$(CONFIG_R8A77995),) +# +# The first 6 generate statements generate the R-Car Gen3 SCIF loader header. +# The subsequent generate statements represent the following chunk of assembler +# code, which copies the loaded data from 0xe6304030 to 0xe6318000. This is to +# work around a limitation of the D3/E3 BootROM, which does not permit loading +# to 0xe6318000 directly. +# +# mov x0, #0xe6000000 +# orr x0, x0, #0x00300000 +# orr x1, x0, #0x00004000 +# orr x1, x1, #0x00000030 +# +# orr x2, x0, #0x00018000 +# mov x0, x2 +# mov x3, #0x7000 +#1: ldp x4, x5, [x1], #16 +# +# stp x4, x5, [x2], #16 +# subs x3, x3, #16 +# b.ge 1b +# br x0 +# +quiet_cmd_srec_cat = SRECCAT $@ + cmd_srec_cat = srec_cat -output $@ -M 8 $< -M 8 \ + -offset -0x13fd0 \ + -Output_Block_Size 16 \ + -generate 0xe6300400 0xe6300404 -l-e-constant 0x0 4 \ + -generate 0xe630048c 0xe6300490 -l-e-constant 0x0 4 \ + -generate 0xe63005d4 0xe63005d8 -l-e-constant 0xe6304000 4 \ + -generate 0xe63006e4 0xe63006e8 -l-e-constant $2 4 \ + -generate 0xe6301154 0xe6301158 -l-e-constant 0xe6304000 4 \ + -generate 0xe6301264 0xe6301268 -l-e-constant $2 4 \ + -generate 0xe6304000 0xe6304004 -l-e-constant 0xd2bcc000 4 \ + -generate 0xe6304004 0xe6304008 -l-e-constant 0xb26c0400 4 \ + -generate 0xe6304008 0xe630400c -l-e-constant 0xb2720001 4 \ + -generate 0xe630400c 0xe6304010 -l-e-constant 0xb27c0421 4 \ + -generate 0xe6304010 0xe6304014 -l-e-constant 0xb2710402 4 \ + -generate 0xe6304014 0xe6304018 -l-e-constant 0xaa0203e0 4 \ + -generate 0xe6304018 0xe630401c -l-e-constant 0xd28e0003 4 \ + -generate 0xe630401c 0xe6304020 -l-e-constant 0xa8c11424 4 \ + -generate 0xe6304020 0xe6304024 -l-e-constant 0xa8811444 4 \ + -generate 0xe6304024 0xe6304028 -l-e-constant 0xf1004063 4 \ + -generate 0xe6304028 0xe630402c -l-e-constant 0x54ffffaa 4 \ + -generate 0xe630402c 0xe6304030 -l-e-constant 0xd61f0000 4 +else +quiet_cmd_srec_cat = SRECCAT $@ + cmd_srec_cat = srec_cat -output $@ -M 8 $< -M 8 \ + -Output_Block_Size 16 \ + -generate 0xe6300400 0xe6300404 -l-e-constant 0x0 4 \ + -generate 0xe630048c 0xe6300490 -l-e-constant 0x0 4 \ + -generate 0xe63005d4 0xe63005d8 -l-e-constant $(CONFIG_SPL_TEXT_BASE) 4 \ + -generate 0xe63006e4 0xe63006e8 -l-e-constant $2 4 \ + -generate 0xe6301154 0xe6301158 -l-e-constant $(CONFIG_SPL_TEXT_BASE) 4 \ + -generate 0xe6301264 0xe6301268 -l-e-constant $2 4 +endif + +spl/u-boot-spl.scif: spl/u-boot-spl.srec spl/u-boot-spl.bin + $(call cmd,srec_cat,$(shell wc -c spl/u-boot-spl.bin | awk '{printf("0x%08x\n",$$1)}')) + +# if srec_cat is present build u-boot-spl.scif by default +has_srec_cat = $(call try-run,srec_cat -VERSion,y,n) +ALL-$(has_srec_cat) += u-boot-spl.scif +CLEAN_FILES += u-boot-spl.scif diff --git a/board/renesas/draak/Makefile b/board/renesas/draak/Makefile index 604522e..1fc90d1 100644 --- a/board/renesas/draak/Makefile +++ b/board/renesas/draak/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := draak.o +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else +obj-y := draak.o ../rcar-common/common.o +endif diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c index 8f3d391..46d9f74 100644 --- a/board/renesas/draak/draak.c +++ b/board/renesas/draak/draak.c @@ -70,21 +70,6 @@ int board_init(void) return 0; } -int dram_init(void) -{ - if (fdtdec_setup_mem_size_base() != 0) - return -EINVAL; - - return 0; -} - -int dram_init_banksize(void) -{ - fdtdec_setup_memory_banksize(); - - return 0; -} - #define RST_BASE 0xE6160000 #define RST_CA57RESCNT (RST_BASE + 0x40) #define RST_CA53RESCNT (RST_BASE + 0x44) diff --git a/board/renesas/eagle/Makefile b/board/renesas/eagle/Makefile index dffa295..062c46b 100644 --- a/board/renesas/eagle/Makefile +++ b/board/renesas/eagle/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := eagle.o +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else +obj-y := eagle.o ../rcar-common/common.o +endif diff --git a/board/renesas/eagle/eagle.c b/board/renesas/eagle/eagle.c index 0e5efea..d6240b1 100644 --- a/board/renesas/eagle/eagle.c +++ b/board/renesas/eagle/eagle.c @@ -67,21 +67,6 @@ int board_init(void) return 0; } -int dram_init(void) -{ - if (fdtdec_setup_mem_size_base() != 0) - return -EINVAL; - - return 0; -} - -int dram_init_banksize(void) -{ - fdtdec_setup_memory_banksize(); - - return 0; -} - #define RST_BASE 0xE6160000 #define RST_CA57RESCNT (RST_BASE + 0x40) #define RST_CA53RESCNT (RST_BASE + 0x44) diff --git a/board/renesas/ebisu/Makefile b/board/renesas/ebisu/Makefile index 2741035..1fd9a03 100644 --- a/board/renesas/ebisu/Makefile +++ b/board/renesas/ebisu/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := ebisu.o +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else +obj-y := ebisu.o ../rcar-common/common.o +endif diff --git a/board/renesas/ebisu/ebisu.c b/board/renesas/ebisu/ebisu.c index 60429e4..cb7d432 100644 --- a/board/renesas/ebisu/ebisu.c +++ b/board/renesas/ebisu/ebisu.c @@ -43,41 +43,6 @@ int board_init(void) return 0; } -/* - * If the firmware passed a device tree use it for U-Boot DRAM setup. - */ -extern u64 rcar_atf_boot_args[]; - -int dram_init(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - return fdtdec_setup_mem_size_base_fdt(blob); -} - -int dram_init_banksize(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - fdtdec_setup_memory_banksize_fdt(blob); - - return 0; -} - #define RST_BASE 0xE6160000 #define RST_CA57RESCNT (RST_BASE + 0x40) #define RST_CA53RESCNT (RST_BASE + 0x44) diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c index 1ce6e2e..292867e 100644 --- a/board/renesas/rcar-common/common.c +++ b/board/renesas/rcar-common/common.c @@ -9,3 +9,41 @@ #include #include + +#ifdef CONFIG_RCAR_GEN3 + +DECLARE_GLOBAL_DATA_PTR; + +/* If the firmware passed a device tree use it for U-Boot DRAM setup. */ +extern u64 rcar_atf_boot_args[]; + +int dram_init(void) +{ + const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); + const void *blob; + + /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ + if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) + blob = atf_fdt_blob; + else + blob = gd->fdt_blob; + + return fdtdec_setup_mem_size_base_fdt(blob); +} + +int dram_init_banksize(void) +{ + const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); + const void *blob; + + /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ + if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) + blob = atf_fdt_blob; + else + blob = gd->fdt_blob; + + fdtdec_setup_memory_banksize_fdt(blob); + + return 0; +} +#endif diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c new file mode 100644 index 0000000..27140c5 --- /dev/null +++ b/board/renesas/rcar-common/gen3-spl.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car Gen3 recovery SPL + * + * Copyright (C) 2019 Marek Vasut + */ + +#include +#include +#include + +#define RCAR_CNTC_BASE 0xE6080000 +#define CNTCR_EN BIT(0) + +void board_init_f(ulong dummy) +{ + writel(CNTCR_EN, RCAR_CNTC_BASE); + timer_init(); +} + +void spl_board_init(void) +{ + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_UART; +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + debug("image entry point: 0x%lx\n", spl_image->entry_point); + if (spl_image->os == IH_OS_ARM_TRUSTED_FIRMWARE) { + typedef void (*image_entry_arg_t)(int, int, int, int) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t)(uintptr_t) spl_image->entry_point; + image_entry(IH_MAGIC, CONFIG_SPL_TEXT_BASE, 0, 0); + } else { + typedef void __noreturn (*image_entry_noargs_t)(void); + image_entry_noargs_t image_entry = + (image_entry_noargs_t)spl_image->entry_point; + image_entry(); + } +} + +void s_init(void) +{ +} + +void reset_cpu(ulong addr) +{ +} diff --git a/board/renesas/salvator-x/Makefile b/board/renesas/salvator-x/Makefile index 5b4dea9..9525807 100644 --- a/board/renesas/salvator-x/Makefile +++ b/board/renesas/salvator-x/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := salvator-x.o +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else +obj-y := salvator-x.o ../rcar-common/common.o +endif diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c index 1db08fc..22fe961 100644 --- a/board/renesas/salvator-x/salvator-x.c +++ b/board/renesas/salvator-x/salvator-x.c @@ -69,41 +69,6 @@ int board_init(void) return 0; } -/* - * If the firmware passed a device tree use it for U-Boot DRAM setup. - */ -extern u64 rcar_atf_boot_args[]; - -int dram_init(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - return fdtdec_setup_mem_size_base_fdt(blob); -} - -int dram_init_banksize(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - fdtdec_setup_memory_banksize_fdt(blob); - - return 0; -} - #define RST_BASE 0xE6160000 #define RST_CA57RESCNT (RST_BASE + 0x40) #define RST_CA53RESCNT (RST_BASE + 0x44) diff --git a/board/renesas/ulcb/Makefile b/board/renesas/ulcb/Makefile index 406fdc8..f4d24c6 100644 --- a/board/renesas/ulcb/Makefile +++ b/board/renesas/ulcb/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := ulcb.o cpld.o +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else +obj-y := ulcb.o cpld.o ../rcar-common/common.o +endif diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c index faf19c3..bcae6ff 100644 --- a/board/renesas/ulcb/ulcb.c +++ b/board/renesas/ulcb/ulcb.c @@ -68,41 +68,6 @@ int board_init(void) return 0; } -/* - * If the firmware passed a device tree use it for U-Boot DRAM setup. - */ -extern u64 rcar_atf_boot_args[]; - -int dram_init(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - return fdtdec_setup_mem_size_base_fdt(blob); -} - -int dram_init_banksize(void) -{ - const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]); - const void *blob; - - /* Check if ATF passed us DTB. If not, fall back to builtin DTB. */ - if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) - blob = atf_fdt_blob; - else - blob = gd->fdt_blob; - - fdtdec_setup_memory_banksize_fdt(blob); - - return 0; -} - #ifdef CONFIG_MULTI_DTB_FIT int board_fit_config_name_match(const char *name) { diff --git a/configs/r8a7795_salvator-x_defconfig b/configs/r8a7795_salvator-x_defconfig index 2b299ec..dfe993a 100644 --- a/configs/r8a7795_salvator-x_defconfig +++ b/configs/r8a7795_salvator-x_defconfig @@ -11,11 +11,13 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a7795-salvator-x.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y @@ -48,6 +50,9 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_RCAR_GEN3=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a7795_ulcb_defconfig b/configs/r8a7795_ulcb_defconfig index 2808a08..f85d37c 100644 --- a/configs/r8a7795_ulcb_defconfig +++ b/configs/r8a7795_ulcb_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a7795-h3ulcb.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/configs/r8a77965_salvator-x_defconfig b/configs/r8a77965_salvator-x_defconfig index aa1f7ed..dc2d495 100644 --- a/configs/r8a77965_salvator-x_defconfig +++ b/configs/r8a77965_salvator-x_defconfig @@ -12,11 +12,13 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a77965-salvator-x.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y @@ -49,6 +51,9 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_RCAR_GEN3=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a77965_ulcb_defconfig b/configs/r8a77965_ulcb_defconfig index fa76ba5..d8d915b 100644 --- a/configs/r8a77965_ulcb_defconfig +++ b/configs/r8a77965_ulcb_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a77965-m3nulcb.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/configs/r8a7796_salvator-x_defconfig b/configs/r8a7796_salvator-x_defconfig index 05d4c5a..c6f713a 100644 --- a/configs/r8a7796_salvator-x_defconfig +++ b/configs/r8a7796_salvator-x_defconfig @@ -12,11 +12,13 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a7796-salvator-x.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y @@ -49,6 +51,9 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_RCAR_GEN3=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a7796_ulcb_defconfig b/configs/r8a7796_ulcb_defconfig index 7a738d3..5c11d5c 100644 --- a/configs/r8a7796_ulcb_defconfig +++ b/configs/r8a7796_ulcb_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a7796-m3ulcb.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6338000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/configs/r8a77970_eagle_defconfig b/configs/r8a77970_eagle_defconfig index d99293d..d9e2342 100644 --- a/configs/r8a77970_eagle_defconfig +++ b/configs/r8a77970_eagle_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a77970-eagle.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6318000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/configs/r8a77990_ebisu_defconfig b/configs/r8a77990_ebisu_defconfig index e76bd59..edc7478 100644 --- a/configs/r8a77990_ebisu_defconfig +++ b/configs/r8a77990_ebisu_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a77990-ebisu.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6318000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/configs/r8a77995_draak_defconfig b/configs/r8a77995_draak_defconfig index cf1fcd8..39daf98 100644 --- a/configs/r8a77995_draak_defconfig +++ b/configs/r8a77995_draak_defconfig @@ -12,6 +12,7 @@ CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.2 CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DEFAULT_FDT_FILE="r8a77995-draak.dtb" CONFIG_VERSION_VARIABLE=y +CONFIG_SPL_TEXT_BASE=0xe6318000 CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 6c51ccc..7c53aa2 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -23,24 +23,126 @@ /* SCC registers */ #define RENESAS_SDHI_SCC_DTCNTL 0x800 -#define RENESAS_SDHI_SCC_DTCNTL_TAPEN BIT(0) -#define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT 16 -#define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK 0xff +#define RENESAS_SDHI_SCC_DTCNTL_TAPEN BIT(0) +#define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT 16 +#define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK 0xff #define RENESAS_SDHI_SCC_TAPSET 0x804 #define RENESAS_SDHI_SCC_DT2FF 0x808 #define RENESAS_SDHI_SCC_CKSEL 0x80c -#define RENESAS_SDHI_SCC_CKSEL_DTSEL BIT(0) -#define RENESAS_SDHI_SCC_RVSCNTL 0x810 -#define RENESAS_SDHI_SCC_RVSCNTL_RVSEN BIT(0) +#define RENESAS_SDHI_SCC_CKSEL_DTSEL BIT(0) +#define RENESAS_SDHI_SCC_RVSCNTL 0x810 +#define RENESAS_SDHI_SCC_RVSCNTL_RVSEN BIT(0) #define RENESAS_SDHI_SCC_RVSREQ 0x814 -#define RENESAS_SDHI_SCC_RVSREQ_RVSERR BIT(2) +#define RENESAS_SDHI_SCC_RVSREQ_RVSERR BIT(2) #define RENESAS_SDHI_SCC_SMPCMP 0x818 -#define RENESAS_SDHI_SCC_TMPPORT2 0x81c -#define RENESAS_SDHI_SCC_TMPPORT2_HS400EN BIT(31) -#define RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL BIT(4) +#define RENESAS_SDHI_SCC_TMPPORT2 0x81c +#define RENESAS_SDHI_SCC_TMPPORT2_HS400EN BIT(31) +#define RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL BIT(4) +#define RENESAS_SDHI_SCC_TMPPORT3 0x828 +#define RENESAS_SDHI_SCC_TMPPORT3_OFFSET_0 3 +#define RENESAS_SDHI_SCC_TMPPORT3_OFFSET_1 2 +#define RENESAS_SDHI_SCC_TMPPORT3_OFFSET_2 1 +#define RENESAS_SDHI_SCC_TMPPORT3_OFFSET_3 0 +#define RENESAS_SDHI_SCC_TMPPORT3_OFFSET_MASK 0x3 +#define RENESAS_SDHI_SCC_TMPPORT4 0x82c +#define RENESAS_SDHI_SCC_TMPPORT4_DLL_ACC_START BIT(0) +#define RENESAS_SDHI_SCC_TMPPORT5 0x830 +#define RENESAS_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R BIT(8) +#define RENESAS_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W (0 << 8) +#define RENESAS_SDHI_SCC_TMPPORT5_DLL_ADR_MASK 0x3F +#define RENESAS_SDHI_SCC_TMPPORT6 0x834 +#define RENESAS_SDHI_SCC_TMPPORT7 0x838 +#define RENESAS_SDHI_SCC_TMPPORT_DISABLE_WP_CODE 0xa5000000 +#define RENESAS_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f +#define RENESAS_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7) #define RENESAS_SDHI_MAX_TAP 3 +static u32 sd_scc_tmpport_read32(struct tmio_sd_priv *priv, u32 addr) +{ + /* read mode */ + tmio_sd_writel(priv, RENESAS_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R | + (RENESAS_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr), + RENESAS_SDHI_SCC_TMPPORT5); + + /* access start and stop */ + tmio_sd_writel(priv, RENESAS_SDHI_SCC_TMPPORT4_DLL_ACC_START, + RENESAS_SDHI_SCC_TMPPORT4); + tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_TMPPORT4); + + return tmio_sd_readl(priv, RENESAS_SDHI_SCC_TMPPORT7); +} + +static void sd_scc_tmpport_write32(struct tmio_sd_priv *priv, u32 addr, u32 val) +{ + /* write mode */ + tmio_sd_writel(priv, RENESAS_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W | + (RENESAS_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr), + RENESAS_SDHI_SCC_TMPPORT5); + tmio_sd_writel(priv, val, RENESAS_SDHI_SCC_TMPPORT6); + + /* access start and stop */ + tmio_sd_writel(priv, RENESAS_SDHI_SCC_TMPPORT4_DLL_ACC_START, + RENESAS_SDHI_SCC_TMPPORT4); + tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_TMPPORT4); +} + +static void renesas_sdhi_adjust_hs400_mode_enable(struct tmio_sd_priv *priv) +{ + u32 calib_code; + + if (!priv->adjust_hs400_enable) + return; + + if (!priv->needs_adjust_hs400) + return; + + /* + * Enabled Manual adjust HS400 mode + * + * 1) Disabled Write Protect + * W(addr=0x00, WP_DISABLE_CODE) + * 2) Read Calibration code and adjust + * R(addr=0x26) - adjust value + * 3) Enabled Manual Calibration + * W(addr=0x22, manual mode | Calibration code) + * 4) Set Offset value to TMPPORT3 Reg + */ + sd_scc_tmpport_write32(priv, 0x00, + RENESAS_SDHI_SCC_TMPPORT_DISABLE_WP_CODE); + calib_code = sd_scc_tmpport_read32(priv, 0x26); + calib_code &= RENESAS_SDHI_SCC_TMPPORT_CALIB_CODE_MASK; + if (calib_code > priv->adjust_hs400_calibrate) + calib_code -= priv->adjust_hs400_calibrate; + else + calib_code = 0; + sd_scc_tmpport_write32(priv, 0x22, + RENESAS_SDHI_SCC_TMPPORT_MANUAL_MODE | + calib_code); + tmio_sd_writel(priv, priv->adjust_hs400_offset, + RENESAS_SDHI_SCC_TMPPORT3); + + /* Clear flag */ + priv->needs_adjust_hs400 = false; +} + +static void renesas_sdhi_adjust_hs400_mode_disable(struct tmio_sd_priv *priv) +{ + + /* Disabled Manual adjust HS400 mode + * + * 1) Disabled Write Protect + * W(addr=0x00, WP_DISABLE_CODE) + * 2) Disabled Manual Calibration + * W(addr=0x22, 0) + * 3) Clear offset value to TMPPORT3 Reg + */ + sd_scc_tmpport_write32(priv, 0x00, + RENESAS_SDHI_SCC_TMPPORT_DISABLE_WP_CODE); + sd_scc_tmpport_write32(priv, 0x22, 0); + tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_TMPPORT3); +} + static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) { u32 reg; @@ -96,6 +198,9 @@ static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL); tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2); + /* Disable HS400 mode adjustment */ + renesas_sdhi_adjust_hs400_mode_disable(priv); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); reg |= TMIO_SD_CLKCTL_SCLKEN; tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); @@ -137,6 +242,10 @@ static int renesas_sdhi_hs400(struct udevice *dev) tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2); + /* Disable HS400 mode adjustment */ + if (!hs400) + renesas_sdhi_adjust_hs400_mode_disable(priv); + tmio_sd_writel(priv, (0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) | RENESAS_SDHI_SCC_DTCNTL_TAPEN, RENESAS_SDHI_SCC_DTCNTL); @@ -159,6 +268,10 @@ static int renesas_sdhi_hs400(struct udevice *dev) reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN; tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + /* Execute adjust hs400 offset after setting to HS400 mode */ + if (hs400) + priv->needs_adjust_hs400 = true; + return 0; } @@ -188,6 +301,8 @@ static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv, bool select = false; u32 reg; + priv->needs_adjust_hs400 = false; + /* Clear SCC_RVSREQ */ tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ); @@ -405,8 +520,29 @@ static int renesas_sdhi_wait_dat0(struct udevice *dev, int state, int timeout) } #endif +static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + int ret; + + ret = tmio_sd_send_cmd(dev, cmd, data); + if (ret) + return ret; + +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + struct tmio_sd_priv *priv = dev_get_priv(dev); + + if (cmd->cmdidx == MMC_CMD_SEND_STATUS) + renesas_sdhi_adjust_hs400_mode_enable(priv); +#endif + + return 0; +} + static const struct dm_mmc_ops renesas_sdhi_ops = { - .send_cmd = tmio_sd_send_cmd, + .send_cmd = renesas_sdhi_send_cmd, .set_ios = renesas_sdhi_set_ios, .get_cd = tmio_sd_get_cd, #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ @@ -451,14 +587,37 @@ static void renesas_sdhi_filter_caps(struct udevice *dev) if (!(priv->caps & TMIO_SD_CAP_RCAR_GEN3)) return; - /* HS400 is not supported on H3 ES1.x and M3W ES1.0,ES1.1 */ + /* HS400 is not supported on H3 ES1.x and M3W ES1.0,ES1.1,ES1.2 */ if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && (rmobile_get_cpu_rev_integer() <= 1)) || ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() <= 1))) + (rmobile_get_cpu_rev_fraction() <= 2))) plat->cfg.host_caps &= ~MMC_MODE_HS400; + /* M3W ES1.x for x>2 can use HS400 with manual adjustment */ + if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && + (rmobile_get_cpu_rev_integer() == 1) && + (rmobile_get_cpu_rev_fraction() > 2)) { + priv->adjust_hs400_enable = true; + priv->adjust_hs400_offset = 0; + priv->adjust_hs400_calibrate = 0x9; + } + + /* M3N can use HS400 with manual adjustment */ + if (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77965) { + priv->adjust_hs400_enable = true; + priv->adjust_hs400_offset = 0; + priv->adjust_hs400_calibrate = 0x0; + } + + /* E3 can use HS400 with manual adjustment */ + if (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) { + priv->adjust_hs400_enable = true; + priv->adjust_hs400_offset = 0; + priv->adjust_hs400_calibrate = 0x2; + } + /* H3 ES2.0 uses 4 tuning taps */ if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && (rmobile_get_cpu_rev_integer() == 2)) diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h index 58ce3d6..51607de 100644 --- a/drivers/mmc/tmio-common.h +++ b/drivers/mmc/tmio-common.h @@ -139,6 +139,10 @@ struct tmio_sd_priv { #if CONFIG_IS_ENABLED(RENESAS_SDHI) u8 tap_set; u8 nrtaps; + bool needs_adjust_hs400; + bool adjust_hs400_enable; + u8 adjust_hs400_offset; + u8 adjust_hs400_calibrate; #endif ulong (*clk_get_rate)(struct tmio_sd_priv *); }; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 763bd50..429bb83 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -69,6 +69,14 @@ config PCI_RCAR_GEN2 Renesas RCar Gen2 SoCs. The PCIe controller on RCar Gen2 is also used to access EHCI USB controller on the SoC. +config PCI_RCAR_GEN3 + bool "Renesas RCar Gen3 PCIe driver" + depends on DM_PCI + depends on RCAR_GEN3 + help + Say Y here if you want to enable PCIe controller support on + Renesas RCar Gen3 SoCs. + config PCI_SANDBOX bool "Sandbox PCI support" depends on SANDBOX && DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 8ee828a..bd392ed 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_PCIE_IMX) += pcie_imx.o obj-$(CONFIG_FTPCI100) += pci_ftpci100.o obj-$(CONFIG_PCI_MVEBU) += pci_mvebu.o obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o +obj-$(CONFIG_PCI_RCAR_GEN3) += pci-rcar-gen3.o obj-$(CONFIG_SH4_PCI) += pci_sh4.o obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o diff --git a/drivers/pci/pci-rcar-gen3.c b/drivers/pci/pci-rcar-gen3.c new file mode 100644 index 0000000..52ca13b --- /dev/null +++ b/drivers/pci/pci-rcar-gen3.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RCar Gen3 PCIEC driver + * + * Copyright (C) 2018-2019 Marek Vasut + * + * Based on Linux PCIe driver for Renesas R-Car SoCs + * Copyright (C) 2014 Renesas Electronics Europe Ltd + * + * Based on: + * arch/sh/drivers/pci/pcie-sh7786.c + * arch/sh/drivers/pci/ops-sh7786.c + * Copyright (C) 2009 - 2011 Paul Mundt + * + * Author: Phil Edworthy + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PCIECAR 0x000010 +#define PCIECCTLR 0x000018 +#define CONFIG_SEND_ENABLE BIT(31) +#define TYPE0 (0 << 8) +#define TYPE1 BIT(8) +#define PCIECDR 0x000020 +#define PCIEMSR 0x000028 +#define PCIEINTXR 0x000400 +#define PCIEPHYSR 0x0007f0 +#define PHYRDY BIT(0) +#define PCIEMSITXR 0x000840 + +/* Transfer control */ +#define PCIETCTLR 0x02000 +#define CFINIT 1 +#define PCIETSTR 0x02004 +#define DATA_LINK_ACTIVE 1 +#define PCIEERRFR 0x02020 +#define UNSUPPORTED_REQUEST BIT(4) +#define PCIEMSIFR 0x02044 +#define PCIEMSIALR 0x02048 +#define MSIFE 1 +#define PCIEMSIAUR 0x0204c +#define PCIEMSIIER 0x02050 + +/* root port address */ +#define PCIEPRAR(x) (0x02080 + ((x) * 0x4)) + +/* local address reg & mask */ +#define PCIELAR(x) (0x02200 + ((x) * 0x20)) +#define PCIELAMR(x) (0x02208 + ((x) * 0x20)) +#define LAM_PREFETCH BIT(3) +#define LAM_64BIT BIT(2) +#define LAR_ENABLE BIT(1) + +/* PCIe address reg & mask */ +#define PCIEPALR(x) (0x03400 + ((x) * 0x20)) +#define PCIEPAUR(x) (0x03404 + ((x) * 0x20)) +#define PCIEPAMR(x) (0x03408 + ((x) * 0x20)) +#define PCIEPTCTLR(x) (0x0340c + ((x) * 0x20)) +#define PAR_ENABLE BIT(31) +#define IO_SPACE BIT(8) + +/* Configuration */ +#define PCICONF(x) (0x010000 + ((x) * 0x4)) +#define PMCAP(x) (0x010040 + ((x) * 0x4)) +#define EXPCAP(x) (0x010070 + ((x) * 0x4)) +#define VCCAP(x) (0x010100 + ((x) * 0x4)) + +/* link layer */ +#define IDSETR1 0x011004 +#define TLCTLR 0x011048 +#define MACSR 0x011054 +#define SPCHGFIN BIT(4) +#define SPCHGFAIL BIT(6) +#define SPCHGSUC BIT(7) +#define LINK_SPEED (0xf << 16) +#define LINK_SPEED_2_5GTS (1 << 16) +#define LINK_SPEED_5_0GTS (2 << 16) +#define MACCTLR 0x011058 +#define SPEED_CHANGE BIT(24) +#define SCRAMBLE_DISABLE BIT(27) +#define MACS2R 0x011078 +#define MACCGSPSETR 0x011084 +#define SPCNGRSN BIT(31) + +/* R-Car H1 PHY */ +#define H1_PCIEPHYADRR 0x04000c +#define WRITE_CMD BIT(16) +#define PHY_ACK BIT(24) +#define RATE_POS 12 +#define LANE_POS 8 +#define ADR_POS 0 +#define H1_PCIEPHYDOUTR 0x040014 + +/* R-Car Gen2 PHY */ +#define GEN2_PCIEPHYADDR 0x780 +#define GEN2_PCIEPHYDATA 0x784 +#define GEN2_PCIEPHYCTRL 0x78c + +#define INT_PCI_MSI_NR 32 + +#define RCONF(x) (PCICONF(0) + (x)) +#define RPMCAP(x) (PMCAP(0) + (x)) +#define REXPCAP(x) (EXPCAP(0) + (x)) +#define RVCCAP(x) (VCCAP(0) + (x)) + +#define PCIE_CONF_BUS(b) (((b) & 0xff) << 24) +#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 19) +#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 16) + +#define RCAR_PCI_MAX_RESOURCES 4 +#define MAX_NR_INBOUND_MAPS 6 + +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */ + +enum { + RCAR_PCI_ACCESS_READ, + RCAR_PCI_ACCESS_WRITE, +}; + +struct rcar_gen3_pcie_priv { + fdt_addr_t regs; +}; + +static void rcar_rmw32(struct udevice *dev, int where, u32 mask, u32 data) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + int shift = 8 * (where & 3); + + clrsetbits_le32(priv->regs + (where & ~3), + mask << shift, data << shift); +} + +static u32 rcar_read_conf(struct udevice *dev, int where) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + int shift = 8 * (where & 3); + + return readl(priv->regs + (where & ~3)) >> shift; +} + +static int rcar_pcie_config_access(struct udevice *udev, + unsigned char access_type, + pci_dev_t bdf, int where, ulong *data) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(udev); + u32 reg = where & ~3; + + /* Clear errors */ + clrbits_le32(priv->regs + PCIEERRFR, 0); + + /* Set the PIO address */ + writel((bdf << 8) | reg, priv->regs + PCIECAR); + + /* Enable the configuration access */ + if (!PCI_BUS(bdf)) + writel(CONFIG_SEND_ENABLE | TYPE0, priv->regs + PCIECCTLR); + else + writel(CONFIG_SEND_ENABLE | TYPE1, priv->regs + PCIECCTLR); + + /* Check for errors */ + if (readl(priv->regs + PCIEERRFR) & UNSUPPORTED_REQUEST) + return -ENODEV; + + /* Check for master and target aborts */ + if (rcar_read_conf(udev, RCONF(PCI_STATUS)) & + (PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT)) + return -ENODEV; + + if (access_type == RCAR_PCI_ACCESS_READ) + *data = readl(priv->regs + PCIECDR); + else + writel(*data, priv->regs + PCIECDR); + + /* Disable the configuration access */ + writel(0, priv->regs + PCIECCTLR); + + return 0; +} + +static int rcar_gen3_pcie_addr_valid(pci_dev_t d, uint where) +{ + u32 slot; + + if (PCI_FUNC(d)) + return -EINVAL; + + slot = PCI_DEV(d); + if (slot != 1) + return -EINVAL; + + return 0; +} + +static int rcar_gen3_pcie_read_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong *val, + enum pci_size_t size) +{ + ulong reg; + int ret; + + ret = rcar_gen3_pcie_addr_valid(bdf, where); + if (ret) { + *val = pci_get_ff(size); + return 0; + } + + ret = rcar_pcie_config_access(dev, RCAR_PCI_ACCESS_READ, + bdf, where, ®); + if (ret != 0) + reg = 0xffffffffUL; + + *val = pci_conv_32_to_size(reg, where, size); + + return ret; +} + +static int rcar_gen3_pcie_write_config(struct udevice *dev, pci_dev_t bdf, + uint where, ulong val, + enum pci_size_t size) +{ + ulong data; + int ret; + + ret = rcar_gen3_pcie_addr_valid(bdf, where); + if (ret) + return ret; + + data = pci_conv_32_to_size(val, where, size); + + ret = rcar_pcie_config_access(dev, RCAR_PCI_ACCESS_WRITE, + bdf, where, &data); + + return ret; +} + +static int rcar_gen3_pcie_wait_for_phyrdy(struct udevice *dev) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + + return wait_for_bit_le32((void *)priv->regs + PCIEPHYSR, PHYRDY, + true, 50, false); +} + +static int rcar_gen3_pcie_wait_for_dl(struct udevice *dev) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + + return wait_for_bit_le32((void *)priv->regs + PCIETSTR, + DATA_LINK_ACTIVE, true, 50, false); +} + +static int rcar_gen3_pcie_hw_init(struct udevice *dev) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + int ret; + + /* Begin initialization */ + writel(0, priv->regs + PCIETCTLR); + + /* Set mode */ + writel(1, priv->regs + PCIEMSR); + + ret = rcar_gen3_pcie_wait_for_phyrdy(dev); + if (ret) + return ret; + + /* + * Initial header for port config space is type 1, set the device + * class to match. Hardware takes care of propagating the IDSETR + * settings, so there is no need to bother with a quirk. + */ + writel(PCI_CLASS_BRIDGE_PCI << 16, priv->regs + IDSETR1); + + /* + * Setup Secondary Bus Number & Subordinate Bus Number, even though + * they aren't used, to avoid bridge being detected as broken. + */ + rcar_rmw32(dev, RCONF(PCI_SECONDARY_BUS), 0xff, 1); + rcar_rmw32(dev, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1); + + /* Initialize default capabilities. */ + rcar_rmw32(dev, REXPCAP(0), 0xff, PCI_CAP_ID_EXP); + rcar_rmw32(dev, REXPCAP(PCI_EXP_FLAGS), + PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4); + rcar_rmw32(dev, RCONF(PCI_HEADER_TYPE), 0x7f, + PCI_HEADER_TYPE_BRIDGE); + + /* Enable data link layer active state reporting */ + rcar_rmw32(dev, REXPCAP(PCI_EXP_LNKCAP), + PCI_EXP_LNKCAP_DLLLARC, PCI_EXP_LNKCAP_DLLLARC); + + /* Write out the physical slot number = 0 */ + rcar_rmw32(dev, REXPCAP(PCI_EXP_SLTCAP), + PCI_EXP_SLTCAP_PSN, 0); + + /* Set the completion timer timeout to the maximum 50ms. */ + rcar_rmw32(dev, TLCTLR + 1, 0x3f, 50); + + /* Terminate list of capabilities (Next Capability Offset=0) */ + rcar_rmw32(dev, RVCCAP(0), 0xfff00000, 0); + + /* Finish initialization - establish a PCI Express link */ + writel(CFINIT, priv->regs + PCIETCTLR); + + return rcar_gen3_pcie_wait_for_dl(dev); +} + +static int rcar_gen3_pcie_probe(struct udevice *dev) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + struct pci_controller *hose = dev_get_uclass_priv(dev); + struct clk pci_clk; + u32 mask; + int i, cnt, ret; + + ret = clk_get_by_index(dev, 0, &pci_clk); + if (ret) + return ret; + + ret = clk_enable(&pci_clk); + if (ret) + return ret; + + for (i = 0; i < hose->region_count; i++) { + if (hose->regions[i].flags != PCI_REGION_SYS_MEMORY) + continue; + + if (hose->regions[i].phys_start == 0) + continue; + + mask = (hose->regions[i].size - 1) & ~0xf; + mask |= LAR_ENABLE; + writel(hose->regions[i].phys_start, priv->regs + PCIEPRAR(0)); + writel(hose->regions[i].phys_start, priv->regs + PCIELAR(0)); + writel(mask, priv->regs + PCIELAMR(0)); + break; + } + + writel(0, priv->regs + PCIEPRAR(4)); + writel(0, priv->regs + PCIELAR(4)); + writel(0, priv->regs + PCIELAMR(4)); + + ret = rcar_gen3_pcie_hw_init(dev); + if (ret) + return ret; + + for (i = 0, cnt = 0; i < hose->region_count; i++) { + if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY) + continue; + + writel(0, priv->regs + PCIEPTCTLR(cnt)); + writel((hose->regions[i].size - 1) & ~0x7f, + priv->regs + PCIEPAMR(cnt)); + writel(upper_32_bits(hose->regions[i].phys_start), + priv->regs + PCIEPAUR(cnt)); + writel(lower_32_bits(hose->regions[i].phys_start), + priv->regs + PCIEPALR(cnt)); + mask = PAR_ENABLE; + if (hose->regions[i].flags == PCI_REGION_IO) + mask |= IO_SPACE; + writel(mask, priv->regs + PCIEPTCTLR(cnt)); + + cnt++; + } + + return 0; +} + +static int rcar_gen3_pcie_ofdata_to_platdata(struct udevice *dev) +{ + struct rcar_gen3_pcie_priv *priv = dev_get_platdata(dev); + + priv->regs = devfdt_get_addr_index(dev, 0); + if (!priv->regs) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops rcar_gen3_pcie_ops = { + .read_config = rcar_gen3_pcie_read_config, + .write_config = rcar_gen3_pcie_write_config, +}; + +static const struct udevice_id rcar_gen3_pcie_ids[] = { + { .compatible = "renesas,pcie-rcar-gen3" }, + { } +}; + +U_BOOT_DRIVER(rcar_gen3_pcie) = { + .name = "rcar_gen3_pcie", + .id = UCLASS_PCI, + .of_match = rcar_gen3_pcie_ids, + .ops = &rcar_gen3_pcie_ops, + .probe = rcar_gen3_pcie_probe, + .ofdata_to_platdata = rcar_gen3_pcie_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct rcar_gen3_pcie_priv), +}; diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h index 20f9821..203b0a7 100644 --- a/include/configs/rcar-gen3-common.h +++ b/include/configs/rcar-gen3-common.h @@ -13,6 +13,10 @@ #define CONFIG_REMAKE_ELF +#ifdef CONFIG_SPL +#define CONFIG_SPL_TARGET "spl/u-boot-spl.scif" +#endif + /* boot option */ #define CONFIG_CMDLINE_TAG @@ -64,4 +68,19 @@ "tftp 0x48000000 Image-"CONFIG_DEFAULT_FDT_FILE"; " \ "booti 0x48080000 - 0x48000000" +/* SPL support */ +#if defined(CONFIG_R8A7795) || defined(CONFIG_R8A7796) || defined(CONFIG_R8A77965) +#define CONFIG_SPL_BSS_START_ADDR 0xe633f000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x1000 +#else +#define CONFIG_SPL_BSS_START_ADDR 0xe631f000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x1000 +#endif +#define CONFIG_SPL_STACK 0xe6304000 +#define CONFIG_SPL_MAX_SIZE 0x7000 +#ifdef CONFIG_SPL_BUILD +#define CONFIG_CONS_SCIF2 +#define CONFIG_SH_SCIF_CLK_FREQ 65000000 +#endif + #endif /* __RCAR_GEN3_COMMON_H */