From 776abedef473659f165dd018388e8b5d81a5c54c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Oct 2018 12:49:19 +0200 Subject: [PATCH 1/7] pci: renesas: Add RCar Gen3 PCIe controller driver Add driver for the Renesas RCar PCIe controller present on Gen3 SoCs. The PCIe on Gen3 is used both to connect external PCIe peripherals. Signed-off-by: Marek Vasut Cc: Bin Meng Cc: Nobuhiro Iwamatsu --- drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pci-rcar-gen3.c | 411 ++++++++++++++++++++++++++++++++++++ 3 files changed, 420 insertions(+) create mode 100644 drivers/pci/pci-rcar-gen3.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 1521885bdeb..bfc43fe58e2 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 49236418959..e551f203d0a 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 00000000000..52ca13b70cb --- /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), +}; From 2548ca7d97aa5b8f16dd02fd1dc5b10c029bc390 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 May 2019 00:01:50 +0200 Subject: [PATCH 2/7] ARM: rmobile: Enable PCIe driver on R-Car Gen3 Salvator-X Enable PCIe driver on R-Car Gen3 Salvator-X boards. Signed-off-by: Marek Vasut Cc: Nobuhiro Iwamatsu --- configs/r8a7795_salvator-x_defconfig | 4 ++++ configs/r8a77965_salvator-x_defconfig | 4 ++++ configs/r8a7796_salvator-x_defconfig | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/configs/r8a7795_salvator-x_defconfig b/configs/r8a7795_salvator-x_defconfig index 8c5c9ed0c4b..39430972163 100644 --- a/configs/r8a7795_salvator-x_defconfig +++ b/configs/r8a7795_salvator-x_defconfig @@ -16,6 +16,7 @@ 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 @@ -51,6 +52,9 @@ CONFIG_RENESAS_RAVB=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_PFC=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_salvator-x_defconfig b/configs/r8a77965_salvator-x_defconfig index 228d848c239..c5a300ae092 100644 --- a/configs/r8a77965_salvator-x_defconfig +++ b/configs/r8a77965_salvator-x_defconfig @@ -17,6 +17,7 @@ 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 @@ -52,6 +53,9 @@ CONFIG_RENESAS_RAVB=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_PFC=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_salvator-x_defconfig b/configs/r8a7796_salvator-x_defconfig index 67d3b517f46..cd8e3eea51c 100644 --- a/configs/r8a7796_salvator-x_defconfig +++ b/configs/r8a7796_salvator-x_defconfig @@ -17,6 +17,7 @@ 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 @@ -52,6 +53,9 @@ CONFIG_RENESAS_RAVB=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_PFC=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 From b72d308c137f5ce1df41e43a301e707b7e70e489 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 May 2019 00:13:35 +0200 Subject: [PATCH 3/7] ARM: rmobile: Sync Gen3 defconfigs Synchronize R-Car Gen3 defconfigs to remove duplicate pinctrl entries. Signed-off-by: Marek Vasut Cc: Nobuhiro Iwamatsu --- configs/r8a7795_salvator-x_defconfig | 3 --- configs/r8a7795_ulcb_defconfig | 3 --- configs/r8a77965_salvator-x_defconfig | 3 --- configs/r8a77965_ulcb_defconfig | 3 --- configs/r8a7796_salvator-x_defconfig | 3 --- configs/r8a7796_ulcb_defconfig | 3 --- configs/r8a77970_eagle_defconfig | 3 --- configs/r8a77990_ebisu_defconfig | 3 --- configs/r8a77995_draak_defconfig | 3 --- 9 files changed, 27 deletions(-) diff --git a/configs/r8a7795_salvator-x_defconfig b/configs/r8a7795_salvator-x_defconfig index 39430972163..feb6180014d 100644 --- a/configs/r8a7795_salvator-x_defconfig +++ b/configs/r8a7795_salvator-x_defconfig @@ -49,9 +49,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_PCI_RCAR_GEN3=y diff --git a/configs/r8a7795_ulcb_defconfig b/configs/r8a7795_ulcb_defconfig index 8dc0c3fda91..2808a08b359 100644 --- a/configs/r8a7795_ulcb_defconfig +++ b/configs/r8a7795_ulcb_defconfig @@ -49,9 +49,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a77965_salvator-x_defconfig b/configs/r8a77965_salvator-x_defconfig index c5a300ae092..9f974371402 100644 --- a/configs/r8a77965_salvator-x_defconfig +++ b/configs/r8a77965_salvator-x_defconfig @@ -50,9 +50,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_PCI_RCAR_GEN3=y diff --git a/configs/r8a77965_ulcb_defconfig b/configs/r8a77965_ulcb_defconfig index 5cbc1615da0..fa76ba5524b 100644 --- a/configs/r8a77965_ulcb_defconfig +++ b/configs/r8a77965_ulcb_defconfig @@ -49,9 +49,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a7796_salvator-x_defconfig b/configs/r8a7796_salvator-x_defconfig index cd8e3eea51c..e1b159d8dd8 100644 --- a/configs/r8a7796_salvator-x_defconfig +++ b/configs/r8a7796_salvator-x_defconfig @@ -50,9 +50,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_PCI_RCAR_GEN3=y diff --git a/configs/r8a7796_ulcb_defconfig b/configs/r8a7796_ulcb_defconfig index ab395d58581..7a738d308c8 100644 --- a/configs/r8a7796_ulcb_defconfig +++ b/configs/r8a7796_ulcb_defconfig @@ -49,9 +49,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a77970_eagle_defconfig b/configs/r8a77970_eagle_defconfig index 6e5a8833588..d99293d1dc4 100644 --- a/configs/r8a77970_eagle_defconfig +++ b/configs/r8a77970_eagle_defconfig @@ -48,9 +48,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a77990_ebisu_defconfig b/configs/r8a77990_ebisu_defconfig index 33db2ada19a..e76bd59c07d 100644 --- a/configs/r8a77990_ebisu_defconfig +++ b/configs/r8a77990_ebisu_defconfig @@ -46,9 +46,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/r8a77995_draak_defconfig b/configs/r8a77995_draak_defconfig index 3e33d073319..cf1fcd82387 100644 --- a/configs/r8a77995_draak_defconfig +++ b/configs/r8a77995_draak_defconfig @@ -54,9 +54,6 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y CONFIG_RENESAS_RAVB=y -CONFIG_PINCTRL=y -CONFIG_PINCONF=y -CONFIG_PINCTRL_PFC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y From 5602330df0306a44d78c1ba67ab7e15aa6f3fc41 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 3 Oct 2018 12:44:13 +0200 Subject: [PATCH 4/7] ARM: rmobile: Add recovery SPL for R-Car Gen3 Build an SPL which can be started via SCIF download mode on R-Car Gen3 and allows loading and executing U-Boot uImage with the next stage code. This is also useful for starting e.g. ATF BL2, which inits the hardware and returns to the U-Boot SPL, which can then load e.g. U-Boot proper. The H3, M3-W, M3-N SoCs have plenty of SRAM for storing the U-Boot SPL while the payload, e.g. ATF BL2, executes, so there is no problem here. However, E3 and D3 have much less SRAM, hence the loader uses a trick where it copies itself beyond the area used by BL2 and executes from there. That area is 32kiB large and not enough to hold U-Boot SPL, BSS, stack and malloc area, so the later two are placed at +0x4000 offset from start of SRAM, another area not used by ATF BL2. To make things even more complicated, the SCIF loader cannot load to the upper 32kiB of the SRAM directly, hence the copying approach. Signed-off-by: Marek Vasut Cc: Nobuhiro Iwamatsu --- Kconfig | 1 + Makefile | 3 ++ arch/arm/mach-rmobile/Kconfig | 11 ++++ arch/arm/mach-rmobile/Makefile | 73 +++++++++++++++++++++++++++ board/renesas/draak/Makefile | 4 ++ board/renesas/eagle/Makefile | 4 ++ board/renesas/ebisu/Makefile | 4 ++ board/renesas/rcar-common/gen3-spl.c | 55 ++++++++++++++++++++ board/renesas/salvator-x/Makefile | 4 ++ board/renesas/ulcb/Makefile | 4 ++ configs/r8a7795_salvator-x_defconfig | 1 + configs/r8a7795_ulcb_defconfig | 1 + configs/r8a77965_salvator-x_defconfig | 1 + configs/r8a77965_ulcb_defconfig | 1 + configs/r8a7796_salvator-x_defconfig | 1 + configs/r8a7796_ulcb_defconfig | 1 + configs/r8a77970_eagle_defconfig | 1 + configs/r8a77990_ebisu_defconfig | 1 + configs/r8a77995_draak_defconfig | 1 + include/configs/rcar-gen3-common.h | 19 +++++++ 20 files changed, 191 insertions(+) create mode 100644 board/renesas/rcar-common/gen3-spl.c diff --git a/Kconfig b/Kconfig index 5f5c5ccfd6b..7bdb536012d 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 059978bfe68..4ebc288fbf8 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 a74f16d3484..aafeb355ef2 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 1f26adaca96..a3fdcc3bc0e 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 604522ebb16..0140b61bffb 100644 --- a/board/renesas/draak/Makefile +++ b/board/renesas/draak/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else obj-y := draak.o +endif diff --git a/board/renesas/eagle/Makefile b/board/renesas/eagle/Makefile index dffa2954045..04402a2ced3 100644 --- a/board/renesas/eagle/Makefile +++ b/board/renesas/eagle/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else obj-y := eagle.o +endif diff --git a/board/renesas/ebisu/Makefile b/board/renesas/ebisu/Makefile index 2741035c576..39971f11b20 100644 --- a/board/renesas/ebisu/Makefile +++ b/board/renesas/ebisu/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else obj-y := ebisu.o +endif diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c new file mode 100644 index 00000000000..27140c5c35c --- /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 5b4dea91c14..fb506be4706 100644 --- a/board/renesas/salvator-x/Makefile +++ b/board/renesas/salvator-x/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else obj-y := salvator-x.o +endif diff --git a/board/renesas/ulcb/Makefile b/board/renesas/ulcb/Makefile index 406fdc8fa40..cd9a5834c1b 100644 --- a/board/renesas/ulcb/Makefile +++ b/board/renesas/ulcb/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ../rcar-common/gen3-spl.o +else obj-y := ulcb.o cpld.o +endif diff --git a/configs/r8a7795_salvator-x_defconfig b/configs/r8a7795_salvator-x_defconfig index feb6180014d..dfe993a1252 100644 --- a/configs/r8a7795_salvator-x_defconfig +++ b/configs/r8a7795_salvator-x_defconfig @@ -11,6 +11,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-salvator-x.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/r8a7795_ulcb_defconfig b/configs/r8a7795_ulcb_defconfig index 2808a08b359..f85d37c7822 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 9f974371402..dc2d49547c3 100644 --- a/configs/r8a77965_salvator-x_defconfig +++ b/configs/r8a77965_salvator-x_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-salvator-x.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_ulcb_defconfig b/configs/r8a77965_ulcb_defconfig index fa76ba5524b..d8d915b2396 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 e1b159d8dd8..c6f713a8bab 100644 --- a/configs/r8a7796_salvator-x_defconfig +++ b/configs/r8a7796_salvator-x_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-salvator-x.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_ulcb_defconfig b/configs/r8a7796_ulcb_defconfig index 7a738d308c8..5c11d5c44a6 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 d99293d1dc4..d9e23426b39 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 e76bd59c07d..edc7478784c 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 cf1fcd82387..39daf983158 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/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h index 20f982165dd..203b0a78f23 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 */ From 6ef540d50f3beb0ff94d3fbdae3548b3b8dd05cd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 May 2019 23:25:16 +0200 Subject: [PATCH 5/7] ARM: renesas: Factor out DRAM setup on R-Car Gen3 Pull DRAM layout configuration code into rcar-common.c instead of having it in multiple copies across board files. This poses no change for Salvator-X/XS, ULCB and Ebisu boards, however it adds a bit of extra code for Draak and Eagle boards, which now gain the capability of being passed in the DRAM layout by the ATF. Signed-off-by: Marek Vasut Cc: Eugeniu Rosca Cc: Nobuhiro Iwamatsu --- board/renesas/draak/Makefile | 2 +- board/renesas/draak/draak.c | 15 ----------- board/renesas/eagle/Makefile | 2 +- board/renesas/eagle/eagle.c | 15 ----------- board/renesas/ebisu/Makefile | 2 +- board/renesas/ebisu/ebisu.c | 35 ------------------------ board/renesas/rcar-common/common.c | 38 +++++++++++++++++++++++++++ board/renesas/salvator-x/Makefile | 2 +- board/renesas/salvator-x/salvator-x.c | 35 ------------------------ board/renesas/ulcb/Makefile | 2 +- board/renesas/ulcb/ulcb.c | 35 ------------------------ 11 files changed, 43 insertions(+), 140 deletions(-) diff --git a/board/renesas/draak/Makefile b/board/renesas/draak/Makefile index 0140b61bffb..1fc90d1dab4 100644 --- a/board/renesas/draak/Makefile +++ b/board/renesas/draak/Makefile @@ -9,5 +9,5 @@ ifdef CONFIG_SPL_BUILD obj-y := ../rcar-common/gen3-spl.o else -obj-y := draak.o +obj-y := draak.o ../rcar-common/common.o endif diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c index 8f3d3915f77..46d9f74785c 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 04402a2ced3..062c46ba24f 100644 --- a/board/renesas/eagle/Makefile +++ b/board/renesas/eagle/Makefile @@ -9,5 +9,5 @@ ifdef CONFIG_SPL_BUILD obj-y := ../rcar-common/gen3-spl.o else -obj-y := eagle.o +obj-y := eagle.o ../rcar-common/common.o endif diff --git a/board/renesas/eagle/eagle.c b/board/renesas/eagle/eagle.c index 0e5efea19d0..d6240b19efb 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 39971f11b20..1fd9a03ecc9 100644 --- a/board/renesas/ebisu/Makefile +++ b/board/renesas/ebisu/Makefile @@ -9,5 +9,5 @@ ifdef CONFIG_SPL_BUILD obj-y := ../rcar-common/gen3-spl.o else -obj-y := ebisu.o +obj-y := ebisu.o ../rcar-common/common.o endif diff --git a/board/renesas/ebisu/ebisu.c b/board/renesas/ebisu/ebisu.c index 60429e45290..cb7d432a15a 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 1ce6e2eac1b..292867e496c 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/salvator-x/Makefile b/board/renesas/salvator-x/Makefile index fb506be4706..95258079e40 100644 --- a/board/renesas/salvator-x/Makefile +++ b/board/renesas/salvator-x/Makefile @@ -9,5 +9,5 @@ ifdef CONFIG_SPL_BUILD obj-y := ../rcar-common/gen3-spl.o else -obj-y := salvator-x.o +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 1db08fce6a2..22fe9619cfb 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 cd9a5834c1b..f4d24c68a67 100644 --- a/board/renesas/ulcb/Makefile +++ b/board/renesas/ulcb/Makefile @@ -9,5 +9,5 @@ ifdef CONFIG_SPL_BUILD obj-y := ../rcar-common/gen3-spl.o else -obj-y := ulcb.o cpld.o +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 faf19c35803..bcae6ff67ca 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) { From 1bac2b6b415bdeee35c21a30292a50ca2a614871 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 May 2019 02:33:06 +0200 Subject: [PATCH 6/7] mmc: tmio: sdhi: Minor macro cleanup Clean up the whitespaces in macros, no functional change. Signed-off-by: Marek Vasut Cc: Nobuhiro Iwamatsu Cc: Peng Fan --- drivers/mmc/renesas-sdhi.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 6c51ccc294b..698ecf69bd5 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -23,21 +23,21 @@ /* 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_MAX_TAP 3 From b5900a58caf0416355ccab4dc9da55c9a388a953 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 19 May 2019 03:47:07 +0200 Subject: [PATCH 7/7] mmc: tmio: sdhi: HS400 manual adjustment Since Gen3 SDHI has an internal DS signal AC-spec violation in HS400 mode, CRC-error may occur in read command in HS400 mode. This phoenomenon occurs at low/high temperature. To fix this, after completion of HS400 tuning, enable manual calibration. However, Gen3 M3 Ver.1.2 or earlier and H3 1.x does not support HS400. These SoC forcibly use HS200 mode by SoC attribute. The DT adjustment of the tuning parameters is not supported until the DT property names become clear. Signed-off-by: Marek Vasut Adapted from a patch by Takeshi Saito Cc: Nobuhiro Iwamatsu Cc: Peng Fan --- drivers/mmc/renesas-sdhi.c | 165 ++++++++++++++++++++++++++++++++++++- drivers/mmc/tmio-common.h | 4 + 2 files changed, 166 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 698ecf69bd5..7c53aa221e5 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -38,9 +38,111 @@ #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 58ce3d65b02..51607de1426 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 *); };