Merge branch 'master' of git://git.denx.de/u-boot-sh
authorTom Rini <trini@konsulko.com>
Mon, 27 May 2019 00:18:20 +0000 (20:18 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 27 May 2019 00:18:20 +0000 (20:18 -0400)
- 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.

31 files changed:
Kconfig
Makefile
arch/arm/mach-rmobile/Kconfig
arch/arm/mach-rmobile/Makefile
board/renesas/draak/Makefile
board/renesas/draak/draak.c
board/renesas/eagle/Makefile
board/renesas/eagle/eagle.c
board/renesas/ebisu/Makefile
board/renesas/ebisu/ebisu.c
board/renesas/rcar-common/common.c
board/renesas/rcar-common/gen3-spl.c [new file with mode: 0644]
board/renesas/salvator-x/Makefile
board/renesas/salvator-x/salvator-x.c
board/renesas/ulcb/Makefile
board/renesas/ulcb/ulcb.c
configs/r8a7795_salvator-x_defconfig
configs/r8a7795_ulcb_defconfig
configs/r8a77965_salvator-x_defconfig
configs/r8a77965_ulcb_defconfig
configs/r8a7796_salvator-x_defconfig
configs/r8a7796_ulcb_defconfig
configs/r8a77970_eagle_defconfig
configs/r8a77990_ebisu_defconfig
configs/r8a77995_draak_defconfig
drivers/mmc/renesas-sdhi.c
drivers/mmc/tmio-common.h
drivers/pci/Kconfig
drivers/pci/Makefile
drivers/pci/pci-rcar-gen3.c [new file with mode: 0644]
include/configs/rcar-gen3-common.h

diff --git a/Kconfig b/Kconfig
index fcde0c3..301ebf8 100644 (file)
--- 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,
index 059978b..4ebc288 100644 (file)
--- 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)
index a74f16d..aafeb35 100644 (file)
@@ -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)"
index 1f26ada..a3fdcc3 100644 (file)
@@ -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
index 604522e..1fc90d1 100644 (file)
@@ -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
index 8f3d391..46d9f74 100644 (file)
@@ -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)
index dffa295..062c46b 100644 (file)
@@ -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
index 0e5efea..d6240b1 100644 (file)
@@ -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)
index 2741035..1fd9a03 100644 (file)
@@ -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
index 60429e4..cb7d432 100644 (file)
@@ -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)
index 1ce6e2e..292867e 100644 (file)
@@ -9,3 +9,41 @@
 
 #include <common.h>
 #include <asm/arch/rmobile.h>
+
+#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 (file)
index 0000000..27140c5
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R-Car Gen3 recovery SPL
+ *
+ * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <spl.h>
+
+#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)
+{
+}
index 5b4dea9..9525807 100644 (file)
@@ -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
index 1db08fc..22fe961 100644 (file)
@@ -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)
index 406fdc8..f4d24c6 100644 (file)
@@ -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
index faf19c3..bcae6ff 100644 (file)
@@ -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)
 {
index 2b299ec..dfe993a 100644 (file)
@@ -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
index 2808a08..f85d37c 100644 (file)
@@ -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
index aa1f7ed..dc2d495 100644 (file)
@@ -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
index fa76ba5..d8d915b 100644 (file)
@@ -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
index 05d4c5a..c6f713a 100644 (file)
@@ -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
index 7a738d3..5c11d5c 100644 (file)
@@ -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
index d99293d..d9e2342 100644 (file)
@@ -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
index e76bd59..edc7478 100644 (file)
@@ -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
index cf1fcd8..39daf98 100644 (file)
@@ -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
index 6c51ccc..7c53aa2 100644 (file)
 
 /* 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))
index 58ce3d6..51607de 100644 (file)
@@ -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 *);
 };
index 763bd50..429bb83 100644 (file)
@@ -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
index 8ee828a..bd392ed 100644 (file)
@@ -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 (file)
index 0000000..52ca13b
--- /dev/null
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RCar Gen3 PCIEC driver
+ *
+ * Copyright (C) 2018-2019 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * 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 <phil.edworthy@renesas.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <pci.h>
+#include <wait_bit.h>
+
+#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, &reg);
+       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),
+};
index 20f9821..203b0a7 100644 (file)
 
 #define CONFIG_REMAKE_ELF
 
+#ifdef CONFIG_SPL
+#define CONFIG_SPL_TARGET      "spl/u-boot-spl.scif"
+#endif
+
 /* boot option */
 
 #define CONFIG_CMDLINE_TAG
        "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 */