[U-Boot] [PATCH 0/6] J721e: Add HyperBus support

This series adds support for HyperBus Memory Controller of TI's J721e and AM654 SoCs.
Vignesh Raghavendra (6): mtd: cfi_flash: Use CONFIG_SYS_MONITOR_BASE only when defined mtd: Add TI HyperBus Memory Controller driver arm: dts: k3-j721e-mcu-wakeup: Add HyperBus Controller node arm: dts: k3-j721e-som-p0: Add HyperFlash node configs: j721e_evm.h: Define CONFIG_SYS_MAX_FLASH_BANKS_DETECT configs: j721e_evm_a72_defconfig: Add HBMC related configs
arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 26 +++++++ arch/arm/dts/k3-j721e-som-p0.dtsi | 34 +++++++++ configs/j721e_evm_a72_defconfig | 12 +++ drivers/mtd/Kconfig | 7 ++ drivers/mtd/Makefile | 1 + drivers/mtd/cfi_flash.c | 5 +- drivers/mtd/hbmc-am654.c | 105 ++++++++++++++++++++++++++ include/configs/j721e_evm.h | 3 + 8 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/hbmc-am654.c

Make use of CONFIG_SYS_MONITOR_BASE only when available to avoid build error when CONFIG_SYS_MONITOR_BASE is not defined.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- drivers/mtd/cfi_flash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index c59254c76e3e..fea15fb523d8 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -178,7 +178,8 @@ __maybe_weak u64 flash_read64(void *addr) /*----------------------------------------------------------------------- */ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || \ - (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) + (defined(CONFIG_SYS_MONITOR_BASE) && \ + (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)) static flash_info_t *flash_get_info(ulong base) { int i; @@ -2329,12 +2330,14 @@ static void flash_protect_default(void) #endif
/* Monitor protection ON by default */ +#ifdef CONFIG_SYS_MONITOR_BASE #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) && \ (!defined(CONFIG_MONITOR_IS_IN_RAM)) flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, flash_get_info(CONFIG_SYS_MONITOR_BASE)); +#endif #endif
/* Environment protection ON by default */

Hi Vignesh,
sorry for the late review.
On 10.09.19 07:10, Vignesh Raghavendra wrote:
Make use of CONFIG_SYS_MONITOR_BASE only when available to avoid build error when CONFIG_SYS_MONITOR_BASE is not defined.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com
drivers/mtd/cfi_flash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index c59254c76e3e..fea15fb523d8 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -178,7 +178,8 @@ __maybe_weak u64 flash_read64(void *addr) /*----------------------------------------------------------------------- */ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || \
- (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
- (defined(CONFIG_SYS_MONITOR_BASE) && \
- (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE))
Here you extend the exisiting #ifdef ...
static flash_info_t *flash_get_info(ulong base) { int i; @@ -2329,12 +2330,14 @@ static void flash_protect_default(void) #endif
/* Monitor protection ON by default */ +#ifdef CONFIG_SYS_MONITOR_BASE #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) && \ (!defined(CONFIG_MONITOR_IS_IN_RAM)) flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, flash_get_info(CONFIG_SYS_MONITOR_BASE)); +#endif #endif
... and here you add a 2nd #ifdef. Why don't you extend the existing one here as well?
Thanks, Stefan

Hi Stefan,
On 09/10/19 12:46 PM, Stefan Roese wrote:
Hi Vignesh,
sorry for the late review.
On 10.09.19 07:10, Vignesh Raghavendra wrote:
Make use of CONFIG_SYS_MONITOR_BASE only when available to avoid build error when CONFIG_SYS_MONITOR_BASE is not defined.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com
drivers/mtd/cfi_flash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index c59254c76e3e..fea15fb523d8 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -178,7 +178,8 @@ __maybe_weak u64 flash_read64(void *addr) /*----------------------------------------------------------------------- */ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || \ - (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) + (defined(CONFIG_SYS_MONITOR_BASE) && \ + (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE))
Here you extend the exisiting #ifdef ...
static flash_info_t *flash_get_info(ulong base) { int i; @@ -2329,12 +2330,14 @@ static void flash_protect_default(void) #endif /* Monitor protection ON by default */ +#ifdef CONFIG_SYS_MONITOR_BASE #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) && \ (!defined(CONFIG_MONITOR_IS_IN_RAM)) flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, flash_get_info(CONFIG_SYS_MONITOR_BASE)); +#endif #endif
... and here you add a 2nd #ifdef. Why don't you extend the existing one here as well?
Ah, yes, Will fix it in next version. Thanks!
Thanks, Stefan

AM654/J721e has HyperBus Memory Controller that supports HyperFlash and HyperRAM devices. It provides a memory mapped interface to interact with these devices. Add a driver to support the same. Driver calibrates the controller, setups up for MMIO access and probes HyperFlash child node.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- drivers/mtd/Kconfig | 7 +++ drivers/mtd/Makefile | 1 + drivers/mtd/hbmc-am654.c | 105 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 drivers/mtd/hbmc-am654.c
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 0050fb2b9bf1..37f379d47803 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -94,6 +94,13 @@ config RENESAS_RPC_HF This enables access to Hyperflash memory through the Renesas RCar Gen3 RPC controller.
+config HBMC_AM654 + bool "HyperBus controller driver for AM65x SoC" + depends on SYSCON + help + This is the driver for HyperBus controller on TI's AM65x and + other SoCs + source "drivers/mtd/nand/Kconfig"
source "drivers/mtd/spi/Kconfig" diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 22ceda93c06d..293079d709aa 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o obj-$(CONFIG_ST_SMI) += st_smi.o obj-$(CONFIG_STM32_FLASH) += stm32_flash.o obj-$(CONFIG_RENESAS_RPC_HF) += renesas_rpc_hf.o +obj-$(CONFIG_HBMC_AM654) += hbmc-am654.o
obj-y += nand/ diff --git a/drivers/mtd/hbmc-am654.c b/drivers/mtd/hbmc-am654.c new file mode 100644 index 000000000000..5a560f1253ba --- /dev/null +++ b/drivers/mtd/hbmc-am654.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ +// Author: Vignesh Raghavendra vigneshr@ti.com + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> + +#define FSS_SYSC_REG 0x4 + +#define HYPERBUS_CALIB_COUNT 25 + +struct am654_hbmc_priv { + void __iomem *mmiobase; + bool calibrated; +}; + +/* Calibrate by looking for "QRY" string within the CFI space */ +static int am654_hyperbus_calibrate(struct udevice *dev) +{ + struct am654_hbmc_priv *priv = dev_get_priv(dev); + int count = HYPERBUS_CALIB_COUNT; + int pass_count = 0; + u16 qry[3]; + + if (priv->calibrated) + return 0; + + writew(0xF0, priv->mmiobase); + writew(0x98, priv->mmiobase + 0xaa); + + while (count--) { + qry[0] = readw(priv->mmiobase + 0x20); + qry[1] = readw(priv->mmiobase + 0x22); + qry[2] = readw(priv->mmiobase + 0x24); + + if (qry[0] == 'Q' && qry[1] == 'R' && qry[2] == 'Y') + pass_count++; + else + pass_count = 0; + if (pass_count == 5) + break; + } + writew(0xF0, priv->mmiobase); + writew(0xFF, priv->mmiobase); + + return pass_count == 5; +} + +static int am654_select_hbmc(struct udevice *dev) +{ + struct regmap *regmap = syscon_get_regmap(dev_get_parent(dev)); + + return regmap_update_bits(regmap, FSS_SYSC_REG, 0x2, 0x2); +} + +static int am654_hbmc_bind(struct udevice *dev) +{ + return dm_scan_fdt_dev(dev); +} + +static int am654_hbmc_probe(struct udevice *dev) +{ + struct am654_hbmc_priv *priv = dev_get_priv(dev); + int ret; + + priv->mmiobase = devfdt_remap_addr_index(dev, 1); + if (dev_read_bool(dev, "mux-controls")) { + ret = am654_select_hbmc(dev); + if (ret) { + dev_err(dev, "Failed to select HBMC mux\n"); + return ret; + } + } + + if (!priv->calibrated) { + ret = am654_hyperbus_calibrate(dev); + if (!ret) { + dev_err(dev, "Calibration Failed\n"); + return -EIO; + } + } + priv->calibrated = true; + + return 0; +} + +static const struct udevice_id am654_hbmc_dt_ids[] = { + { + .compatible = "ti,am654-hbmc", + }, + { /* end of table */ } +}; + +U_BOOT_DRIVER(hbmc_am654) = { + .name = "hbmc-am654", + .id = UCLASS_MTD, + .of_match = am654_hbmc_dt_ids, + .probe = am654_hbmc_probe, + .bind = am654_hbmc_bind, + .priv_auto_alloc_size = sizeof(struct am654_hbmc_priv), +};

Add DT node for HyperBus Memory Controller in the FSS. On J721e, its not possible to use OSPI0 and HBMC simultaneously as they are muxed within the Flash Subsystem hence disable HBMC by default as keep OSPI enabled. Bootloader will fixup DT when it detects HyperFlash instead of OSPI.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi index 01a8f4a9908f..bb652f2fb8d4 100644 --- a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi @@ -118,4 +118,30 @@ loczrama = <1>; }; }; + + fss: fss@47000000 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0x47000000 0x0 0x100>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + hbmc_mux: hbmc-mux { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x4 0x2>; /* HBMC select */ + }; + + hbmc: hyperbus@47034000 { + compatible = "ti,j721e-hbmc", "ti,am654-hbmc"; + reg = <0x0 0x47034000 0x0 0x100>, + <0x5 0x00000000 0x1 0x0000000>; + power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>; + #address-cells = <2>; + #size-cells = <1>; + mux-controls = <&hbmc_mux 0>; + assigned-clocks = <&k3_clks 102 0>; + assigned-clock-rates = <166666666>; + }; + }; };

J721e SoM as a 64MB HyperFlash on board. Add pinmux and DT node for the same.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- arch/arm/dts/k3-j721e-som-p0.dtsi | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/arch/arm/dts/k3-j721e-som-p0.dtsi b/arch/arm/dts/k3-j721e-som-p0.dtsi index 1884fc70148f..1e1519f1c900 100644 --- a/arch/arm/dts/k3-j721e-som-p0.dtsi +++ b/arch/arm/dts/k3-j721e-som-p0.dtsi @@ -27,3 +27,37 @@ }; }; }; + +&wkup_pmx0 { + mcu_fss0_hpb0_pins_default: mcu-fss0-hpb0-pins-default { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x0, PIN_OUTPUT, 1) /* (E20) MCU_OSPI0_CLK.MCU_HYPERBUS0_CK */ + J721E_WKUP_IOPAD(0x4, PIN_OUTPUT, 1) /* (C21) MCU_OSPI0_LBCLKO.MCU_HYPERBUS0_CKn */ + J721E_WKUP_IOPAD(0x2c, PIN_OUTPUT, 1) /* (F19) MCU_OSPI0_CSn0.MCU_HYPERBUS0_CSn0 */ + J721E_WKUP_IOPAD(0x54, PIN_OUTPUT, 3) /* (E22) MCU_OSPI1_CSn1.MCU_HYPERBUS0_CSn1 */ + J721E_WKUP_IOPAD(0x30, PIN_OUTPUT, 1) /* (E19) MCU_OSPI0_CSn1.MCU_HYPERBUS0_RESETn */ + J721E_WKUP_IOPAD(0x8, PIN_INPUT, 1) /* (D21) MCU_OSPI0_DQS.MCU_HYPERBUS0_RWDS */ + J721E_WKUP_IOPAD(0xc, PIN_INPUT, 1) /* (D20) MCU_OSPI0_D0.MCU_HYPERBUS0_DQ0 */ + J721E_WKUP_IOPAD(0x10, PIN_INPUT, 1) /* (G19) MCU_OSPI0_D1.MCU_HYPERBUS0_DQ1 */ + J721E_WKUP_IOPAD(0x14, PIN_INPUT, 1) /* (G20) MCU_OSPI0_D2.MCU_HYPERBUS0_DQ2 */ + J721E_WKUP_IOPAD(0x18, PIN_INPUT, 1) /* (F20) MCU_OSPI0_D3.MCU_HYPERBUS0_DQ3 */ + J721E_WKUP_IOPAD(0x1c, PIN_INPUT, 1) /* (F21) MCU_OSPI0_D4.MCU_HYPERBUS0_DQ4 */ + J721E_WKUP_IOPAD(0x20, PIN_INPUT, 1) /* (E21) MCU_OSPI0_D5.MCU_HYPERBUS0_DQ5 */ + J721E_WKUP_IOPAD(0x24, PIN_INPUT, 1) /* (B22) MCU_OSPI0_D6.MCU_HYPERBUS0_DQ6 */ + J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1) /* (G21) MCU_OSPI0_D7.MCU_HYPERBUS0_DQ7 */ + >; + }; +}; + +&hbmc { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&mcu_fss0_hpb0_pins_default>; + ranges = <0x0 0x0 0x5 0x0 0x4000000>, /* 64MB Flash on CS0 */ + <0x1 0x0 0x5 0x4000000 0x800000>; /* 8MB RAM on CS1 */ + + flash@0,0 { + compatible = "cypress,hyperflash", "cfi-flash"; + reg = <0x0 0x0 0x4000000>; + }; +};

Define CONFIG_SYS_MAX_FLASH_BANKS_DETECT so that number of flash banks are automatically detected by CFI flash driver
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- include/configs/j721e_evm.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/configs/j721e_evm.h b/include/configs/j721e_evm.h index dbe226b46d43..8d4040df9bd4 100644 --- a/include/configs/j721e_evm.h +++ b/include/configs/j721e_evm.h @@ -56,6 +56,9 @@ #define CONFIG_SYS_BOOTM_LEN SZ_64M #define CONFIG_CQSPI_REF_CLK 133333333
+/* HyperFlash related configuration */ +#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1 + /* U-Boot general configuration */ #define EXTRA_ENV_J721E_BOARD_SETTINGS \ "default_device_tree=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \

Enable HBMC and HyperFlash in A72 SPL and A72 U-Boot
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com --- configs/j721e_evm_a72_defconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index 56df452fb6ca..ef91d07aa33f 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -34,6 +34,7 @@ CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_CMD_ASKENV=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_SF=y # CONFIG_CMD_SETEXPR is not set @@ -63,6 +64,15 @@ CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_MTD_DEVICE=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_HBMC_AM654=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y @@ -85,3 +95,5 @@ CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_TI_SCI=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus" +CONFIG_MTDPARTS_DEFAULT="mtdparts=47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"

Hi Stefan,
On 10/09/19 10:40 AM, Vignesh Raghavendra wrote:
This series adds support for HyperBus Memory Controller of TI's J721e and AM654 SoCs.
Vignesh Raghavendra (6): mtd: cfi_flash: Use CONFIG_SYS_MONITOR_BASE only when defined mtd: Add TI HyperBus Memory Controller driver
Gentle ping.. Could you review and merge MTD changes?
arm: dts: k3-j721e-mcu-wakeup: Add HyperBus Controller node arm: dts: k3-j721e-som-p0: Add HyperFlash node configs: j721e_evm.h: Define CONFIG_SYS_MAX_FLASH_BANKS_DETECT configs: j721e_evm_a72_defconfig: Add HBMC related configs
arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 26 +++++++ arch/arm/dts/k3-j721e-som-p0.dtsi | 34 +++++++++ configs/j721e_evm_a72_defconfig | 12 +++ drivers/mtd/Kconfig | 7 ++ drivers/mtd/Makefile | 1 + drivers/mtd/cfi_flash.c | 5 +- drivers/mtd/hbmc-am654.c | 105 ++++++++++++++++++++++++++ include/configs/j721e_evm.h | 3 + 8 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/hbmc-am654.c
participants (2)
-
Stefan Roese
-
Vignesh Raghavendra