* [PATCH v2 01/10] reset: dra7: Add a reset driver
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 02/10] arm: mach-omap2: load/start remoteproc IPU1/IPU2 Amjad Ouled-Ameur
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot
Cc: khilman, Keerthy, Amjad Ouled-Ameur, Bin Meng, Chia-Wei, Wang,
Green Wan, Michal Simek, Ryan Chen
From: Keerthy <j-keerthy@ti.com>
Add a reset driver to bring IPs out of reset.
Signed-off-by: Keerthy <j-keerthy@ti.com>
[Amjad: reset_ops structure member "free" has been renamed to "rfree",
use the latter instead]
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
MAINTAINERS | 1 +
drivers/reset/Kconfig | 6 +++
drivers/reset/Makefile | 1 +
drivers/reset/reset-dra7.c | 97 ++++++++++++++++++++++++++++++++++++++
4 files changed, 105 insertions(+)
create mode 100644 drivers/reset/reset-dra7.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 5370b550648e..ec586ec5466f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -509,6 +509,7 @@ F: drivers/remoteproc/k3_system_controller.c
F: drivers/remoteproc/pruc_rpoc.c
F: drivers/remoteproc/ti*
F: drivers/reset/reset-ti-sci.c
+F: drivers/reset/reset-dra7.c
F: drivers/rtc/davinci.c
F: drivers/serial/serial_omap.c
F: drivers/soc/ti/
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d73daf5e3189..b57714111b5a 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -206,4 +206,10 @@ config RESET_ZYNQMP
passing request via Xilinx firmware interface to TF-A and PMU
firmware.
+config RESET_DRA7
+ bool "Support for TI's DRA7 Reset driver"
+ depends on DM_RESET
+ help
+ Support for TI DRA7-RESET subsystem. Basic Assert/Deassert
+ is supported.
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index d69486bdeb9e..97e3a782c0d8 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -30,3 +30,4 @@ obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
+obj-$(CONFIG_RESET_DRA7) += reset-dra7.o
diff --git a/drivers/reset/reset-dra7.c b/drivers/reset/reset-dra7.c
new file mode 100644
index 000000000000..585f8323c52e
--- /dev/null
+++ b/drivers/reset/reset-dra7.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Texas Instruments DRA7 reset driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Keerthy <j-keerthy@ti.com>
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <dm.h>
+#include <reset-uclass.h>
+#include <dm/device_compat.h>
+
+struct dra7_reset_priv {
+ u32 rstctrl;
+ u32 rstst;
+ u8 nreset;
+};
+
+static int dra7_reset_request(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int dra7_reset_free(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static inline void dra7_reset_rmw(u32 addr, u32 value, u32 mask)
+{
+ writel(((readl(addr) & (~mask)) | (value & mask)), addr);
+}
+
+static int dra7_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ struct dra7_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int mask = 1 << reset_ctl->id;
+
+ if (reset_ctl->id < 0 || reset_ctl->id >= priv->nreset)
+ return -EINVAL;
+
+ dra7_reset_rmw(priv->rstctrl, 0x0, mask);
+
+ while ((readl(priv->rstst) & mask) != mask)
+ ;
+
+ return 0;
+}
+
+static int dra7_reset_assert(struct reset_ctl *reset_ctl)
+{
+ struct dra7_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int mask = 1 << reset_ctl->id;
+
+ if (reset_ctl->id < 0 || reset_ctl->id >= priv->nreset)
+ return -EINVAL;
+
+ dra7_reset_rmw(priv->rstctrl, mask, 0x0);
+
+ return 0;
+}
+
+struct reset_ops dra7_reset_ops = {
+ .request = dra7_reset_request,
+ .rfree = dra7_reset_free,
+ .rst_assert = dra7_reset_assert,
+ .rst_deassert = dra7_reset_deassert,
+};
+
+static const struct udevice_id dra7_reset_ids[] = {
+ { .compatible = "ti,dra7-reset" },
+ { }
+};
+
+static int dra7_reset_probe(struct udevice *dev)
+{
+ struct dra7_reset_priv *priv = dev_get_priv(dev);
+
+ priv->rstctrl = dev_read_addr(dev);
+ priv->rstst = priv->rstctrl + 0x4;
+ priv->nreset = dev_read_u32_default(dev, "ti,nresets", 1);
+
+ dev_info(dev, "dra7-reset successfully probed %s\n", dev->name);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(dra7_reset) = {
+ .name = "dra7_reset",
+ .id = UCLASS_RESET,
+ .of_match = dra7_reset_ids,
+ .probe = dra7_reset_probe,
+ .ops = &dra7_reset_ops,
+ .priv_auto = sizeof(struct dra7_reset_priv),
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 02/10] arm: mach-omap2: load/start remoteproc IPU1/IPU2
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 01/10] reset: dra7: Add a reset driver Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 03/10] drivers: misc: Makefile: Enable fs_loader compilation at SPL Level Amjad Ouled-Ameur
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur, Tom Rini
From: Keerthy <j-keerthy@ti.com>
First check the presence of the ipu firmware in the boot partition.
If present enable the ipu and the related clocks & then move
on to load the firmware and eventually start remoteproc IPU1/IPU2.
do_enable_clocks by default puts the clock domains into auto
which does not work well with reset. Hence adding do_enable_ipu_clocks
function.
Signed-off-by: Keerthy <j-keerthy@ti.com>
[Amjad: fix IPU1_LOAD_ADDR and compile warnings]
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
arch/arm/include/asm/arch-omap5/clock.h | 3 +
arch/arm/include/asm/omap_common.h | 10 +++
arch/arm/mach-omap2/boot-common.c | 95 +++++++++++++++++++++++++
arch/arm/mach-omap2/clocks-common.c | 33 +++++++++
arch/arm/mach-omap2/omap5/hw_data.c | 92 ++++++++++++++++++++++--
arch/arm/mach-omap2/omap5/prcm-regs.c | 9 ++-
6 files changed, 235 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h
index 87eb3f335ab0..a00626e357c9 100644
--- a/arch/arm/include/asm/arch-omap5/clock.h
+++ b/arch/arm/include/asm/arch-omap5/clock.h
@@ -135,6 +135,9 @@
#define HSMMC_CLKCTRL_CLKSEL_MASK (1 << 24)
#define HSMMC_CLKCTRL_CLKSEL_DIV_MASK (3 << 25)
+/* CM_IPU1_IPU1_CLKCTRL CLKSEL MASK */
+#define IPU1_CLKCTRL_CLKSEL_MASK BIT(24)
+
/* CM_L3INIT_SATA_CLKCTRL */
#define SATA_CLKCTRL_OPTFCLKEN_MASK (1 << 8)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index de8fc99d0478..264a2e717a70 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -362,6 +362,10 @@ struct prcm_regs {
/* IPU */
u32 cm_ipu_clkstctrl;
u32 cm_ipu_i2c5_clkctrl;
+ u32 cm_ipu1_clkstctrl;
+ u32 cm_ipu1_ipu1_clkctrl;
+ u32 cm_ipu2_clkstctrl;
+ u32 cm_ipu2_ipu2_clkctrl;
/*l3main1 edma*/
u32 cm_l3main1_tptc1_clkctrl;
@@ -632,6 +636,12 @@ void do_disable_clocks(u32 const *clk_domains,
u8 wait_for_disable);
#endif /* CONFIG_OMAP44XX || CONFIG_OMAP54XX */
+void do_enable_ipu_clocks(u32 const *clk_domains,
+ u32 const *clk_modules_hw_auto,
+ u32 const *clk_modules_explicit_en,
+ u8 wait_for_enable);
+void enable_ipu1_clocks(void);
+void enable_ipu2_clocks(void);
void setup_post_dividers(u32 const base,
const struct dpll_params *params);
u32 omap_ddr_clk(void);
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index 7cdf7f158981..2bf4aff74c3a 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -10,6 +10,8 @@
#include <common.h>
#include <ahci.h>
#include <log.h>
+#include <dm/uclass.h>
+#include <fs_loader.h>
#include <spl.h>
#include <asm/global_data.h>
#include <asm/omap_common.h>
@@ -19,9 +21,14 @@
#include <watchdog.h>
#include <scsi.h>
#include <i2c.h>
+#include <remoteproc.h>
DECLARE_GLOBAL_DATA_PTR;
+#define IPU1_LOAD_ADDR (0xa17ff000)
+#define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000)
+#define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE)
+
__weak u32 omap_sys_boot_device(void)
{
return BOOT_DEVICE_NONE;
@@ -194,6 +201,91 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
return gd->arch.omap_boot_mode;
}
+int load_firmware(char *name_fw, u32 *loadaddr)
+{
+ struct udevice *fsdev;
+ int size = 0;
+
+ if (!IS_ENABLED(CONFIG_FS_LOADER))
+ return 0;
+
+ if (!*loadaddr)
+ return 0;
+
+ if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+ size = request_firmware_into_buf(fsdev, name_fw,
+ (void *)*loadaddr, 0, 0);
+ }
+
+ return size;
+}
+
+void spl_boot_ipu(void)
+{
+ int ret, size;
+ u32 loadaddr = IPU1_LOAD_ADDR;
+
+ if (!IS_ENABLED(CONFIG_SPL_BUILD) ||
+ !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ return;
+
+ size = load_firmware("dra7-ipu1-fw.xem4", &loadaddr);
+ if (size <= 0) {
+ pr_err("Firmware loading failed\n");
+ goto skip_ipu1;
+ }
+
+ enable_ipu1_clocks();
+ ret = rproc_dev_init(0);
+ if (ret) {
+ debug("%s: IPU1 failed to initialize on rproc (%d)\n",
+ __func__, ret);
+ goto skip_ipu1;
+ }
+
+ ret = rproc_load(0, IPU1_LOAD_ADDR, 0x2000000);
+ if (ret) {
+ debug("%s: IPU1 failed to load on rproc (%d)\n", __func__,
+ ret);
+ goto skip_ipu1;
+ }
+
+ debug("Starting IPU1...\n");
+
+ ret = rproc_start(0);
+ if (ret)
+ debug("%s: IPU1 failed to start (%d)\n", __func__, ret);
+
+skip_ipu1:
+ loadaddr = IPU2_LOAD_ADDR;
+ size = load_firmware("dra7-ipu2-fw.xem4", &loadaddr);
+ if (size <= 0) {
+ pr_err("Firmware loading failed for ipu2\n");
+ return;
+ }
+
+ enable_ipu2_clocks();
+ ret = rproc_dev_init(1);
+ if (ret) {
+ debug("%s: IPU2 failed to initialize on rproc (%d)\n", __func__,
+ ret);
+ return;
+ }
+
+ ret = rproc_load(1, IPU2_LOAD_ADDR, 0x2000000);
+ if (ret) {
+ debug("%s: IPU2 failed to load on rproc (%d)\n", __func__,
+ ret);
+ return;
+ }
+
+ debug("Starting IPU2...\n");
+
+ ret = rproc_start(1);
+ if (ret)
+ debug("%s: IPU2 failed to start (%d)\n", __func__, ret);
+}
+
void spl_board_init(void)
{
/* Prepare console output */
@@ -214,6 +306,9 @@ void spl_board_init(void)
#ifdef CONFIG_AM33XX
am33xx_spl_board_init();
#endif
+ if (IS_ENABLED(CONFIG_SPL_BUILD) &&
+ IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ spl_boot_ipu();
}
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
diff --git a/arch/arm/mach-omap2/clocks-common.c b/arch/arm/mach-omap2/clocks-common.c
index 14b638a65136..3d928fbc0e61 100644
--- a/arch/arm/mach-omap2/clocks-common.c
+++ b/arch/arm/mach-omap2/clocks-common.c
@@ -858,6 +858,39 @@ void do_enable_clocks(u32 const *clk_domains,
}
}
+void do_enable_ipu_clocks(u32 const *clk_domains,
+ u32 const *clk_modules_hw_auto,
+ u32 const *clk_modules_explicit_en,
+ u8 wait_for_enable)
+{
+ u32 i, max = 10;
+
+ if (!IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ return;
+
+ /* Put the clock domains in SW_WKUP mode */
+ for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) {
+ enable_clock_domain(clk_domains[i],
+ CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
+ }
+
+ /* Clock modules that need to be put in HW_AUTO */
+ for (i = 0; (i < max) && clk_modules_hw_auto &&
+ clk_modules_hw_auto[i]; i++) {
+ enable_clock_module(clk_modules_hw_auto[i],
+ MODULE_CLKCTRL_MODULEMODE_HW_AUTO,
+ wait_for_enable);
+ };
+
+ /* Clock modules that need to be put in SW_EXPLICIT_EN mode */
+ for (i = 0; (i < max) && clk_modules_explicit_en &&
+ clk_modules_explicit_en[i]; i++) {
+ enable_clock_module(clk_modules_explicit_en[i],
+ MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
+ wait_for_enable);
+ };
+}
+
void do_disable_clocks(u32 const *clk_domains,
u32 const *clk_modules_disable,
u8 wait_for_disable)
diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c
index fa4e27063c53..e6bee48dfcb3 100644
--- a/arch/arm/mach-omap2/omap5/hw_data.c
+++ b/arch/arm/mach-omap2/omap5/hw_data.c
@@ -376,6 +376,85 @@ struct vcores_data omap5430_volts_es2 = {
.mm.efuse.reg_bits = OMAP5_ES2_PROD_REGBITS,
};
+/*
+ * Enable IPU1 clock domains, modules and
+ * do some additional special settings needed
+ */
+void enable_ipu1_clocks(void)
+{
+ if (!IS_ENABLED(CONFIG_DRA7XX) ||
+ !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ return;
+
+ u32 const clk_domains[] = {
+ (*prcm)->cm_ipu_clkstctrl,
+ (*prcm)->cm_ipu1_clkstctrl,
+ 0
+ };
+
+ u32 const clk_modules_hw_auto_essential[] = {
+ (*prcm)->cm_ipu1_ipu1_clkctrl,
+ 0
+ };
+
+ u32 const clk_modules_explicit_en_essential[] = {
+ (*prcm)->cm_l4per_gptimer11_clkctrl,
+ (*prcm)->cm1_abe_timer7_clkctrl,
+ (*prcm)->cm1_abe_timer8_clkctrl,
+ 0
+ };
+ do_enable_ipu_clocks(clk_domains, clk_modules_hw_auto_essential,
+ clk_modules_explicit_en_essential, 0);
+
+ /* Enable optional additional functional clock for IPU1 */
+ setbits_le32((*prcm)->cm_ipu1_ipu1_clkctrl,
+ IPU1_CLKCTRL_CLKSEL_MASK);
+ /* Enable optional additional functional clock for IPU1 */
+ setbits_le32((*prcm)->cm1_abe_timer7_clkctrl,
+ IPU1_CLKCTRL_CLKSEL_MASK);
+ /* Enable optional additional functional clock for IPU1 */
+ setbits_le32((*prcm)->cm1_abe_timer8_clkctrl,
+ IPU1_CLKCTRL_CLKSEL_MASK);
+}
+
+/*
+ * Enable IPU2 clock domains, modules and
+ * do some additional special settings needed
+ */
+void enable_ipu2_clocks(void)
+{
+ if (!IS_ENABLED(CONFIG_DRA7XX) ||
+ !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ return;
+
+ u32 const clk_domains[] = {
+ (*prcm)->cm_ipu_clkstctrl,
+ (*prcm)->cm_ipu2_clkstctrl,
+ 0
+ };
+
+ u32 const clk_modules_hw_auto_essential[] = {
+ (*prcm)->cm_ipu2_ipu2_clkctrl,
+ 0
+ };
+
+ u32 const clk_modules_explicit_en_essential[] = {
+ (*prcm)->cm_l4per_gptimer3_clkctrl,
+ (*prcm)->cm_l4per_gptimer4_clkctrl,
+ (*prcm)->cm_l4per_gptimer9_clkctrl,
+ 0
+ };
+ do_enable_ipu_clocks(clk_domains, clk_modules_hw_auto_essential,
+ clk_modules_explicit_en_essential, 0);
+
+ /* Enable optional additional functional clock for IPU2 */
+ setbits_le32((*prcm)->cm_l4per_gptimer4_clkctrl,
+ IPU1_CLKCTRL_CLKSEL_MASK);
+ /* Enable optional additional functional clock for IPU2 */
+ setbits_le32((*prcm)->cm_l4per_gptimer9_clkctrl,
+ IPU1_CLKCTRL_CLKSEL_MASK);
+}
+
/*
* Enable essential clock domains, modules and
* do some additional special settings needed
@@ -478,12 +557,13 @@ void enable_basic_clocks(void)
void enable_basic_uboot_clocks(void)
{
- u32 const clk_domains_essential[] = {
-#if defined(CONFIG_DRA7XX)
- (*prcm)->cm_ipu_clkstctrl,
-#endif
- 0
- };
+ u32 cm_ipu_clkstctrl = 0;
+
+ if (IS_ENABLED(CONFIG_DRA7XX) &&
+ !IS_ENABLED(CONFIG_REMOTEPROC_TI_IPU))
+ cm_ipu_clkstctrl = (*prcm)->cm_ipu_clkstctrl;
+
+ u32 const clk_domains_essential[] = {cm_ipu_clkstctrl, 0};
u32 const clk_modules_hw_auto_essential[] = {
(*prcm)->cm_l3init_hsusbtll_clkctrl,
diff --git a/arch/arm/mach-omap2/omap5/prcm-regs.c b/arch/arm/mach-omap2/omap5/prcm-regs.c
index b5baebc06926..164b747cea20 100644
--- a/arch/arm/mach-omap2/omap5/prcm-regs.c
+++ b/arch/arm/mach-omap2/omap5/prcm-regs.c
@@ -832,7 +832,10 @@ struct prcm_regs const dra7xx_prcm = {
/* cm IPU */
.cm_ipu_clkstctrl = 0x4a005540,
.cm_ipu_i2c5_clkctrl = 0x4a005578,
-
+ .cm_ipu1_clkstctrl = 0x4a005500,
+ .cm_ipu1_ipu1_clkctrl = 0x4a005520,
+ .cm_ipu2_clkstctrl = 0x4a008900,
+ .cm_ipu2_ipu2_clkctrl = 0x4a008920,
/* prm irqstatus regs */
.prm_irqstatus_mpu = 0x4ae06010,
.prm_irqstatus_mpu_2 = 0x4ae06014,
@@ -1013,6 +1016,10 @@ struct prcm_regs const dra7xx_prcm = {
/*l3main1 edma*/
.cm_l3main1_tptc1_clkctrl = 0x4a008778,
.cm_l3main1_tptc2_clkctrl = 0x4a008780,
+
+ /* cm1.abe */
+ .cm1_abe_timer7_clkctrl = 0x4a005568,
+ .cm1_abe_timer8_clkctrl = 0x4a005570,
};
void clrset_spare_register(u8 spare_type, u32 clear_bits, u32 set_bits)
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 03/10] drivers: misc: Makefile: Enable fs_loader compilation at SPL Level
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 01/10] reset: dra7: Add a reset driver Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 02/10] arm: mach-omap2: load/start remoteproc IPU1/IPU2 Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 04/10] linux: bitmap.h: Add find_next_zero_area function Amjad Ouled-Ameur
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot
Cc: khilman, Keerthy, Amjad Ouled-Ameur, Andrew F. Davis,
Asherah Connor, Aswath Govindraju, Bin Meng, Faiz Abbas,
Heiko Schocher, Igor Opaniuk, Michal Simek, Simon Glass,
Suman Anna, Tero Kristo, Wasim Khan, Ye Li
From: Keerthy <j-keerthy@ti.com>
Enable fs_loader compilation at SPL Level.
Signed-off-by: Keerthy <j-keerthy@ti.com>
[Amjad: fix compilation failures for J721e platform]
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
arch/arm/mach-k3/common.c | 10 +++-------
configs/j721e_evm_r5_defconfig | 1 +
configs/j721e_hs_evm_r5_defconfig | 1 +
drivers/misc/Kconfig | 9 +++++++++
drivers/misc/Makefile | 2 +-
5 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 2666cd2d7b17..dddad8e3b056 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -156,13 +156,15 @@ void init_env(void)
#endif
}
-#ifdef CONFIG_FS_LOADER
int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
{
struct udevice *fsdev;
char *name = NULL;
int size = 0;
+ if (!IS_ENABLED(CONFIG_FS_LOADER))
+ return 0;
+
*loadaddr = 0;
#ifdef CONFIG_SPL_ENV_SUPPORT
switch (spl_boot_device()) {
@@ -186,12 +188,6 @@ int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
return size;
}
-#else
-int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
-{
- return 0;
-}
-#endif
__weak void release_resources_for_core_shutdown(void)
{
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index b5fd3bf23734..edc003f46b90 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -88,6 +88,7 @@ CONFIG_SYS_I2C_OMAP24XX=y
CONFIG_DM_MAILBOX=y
CONFIG_K3_SEC_PROXY=y
CONFIG_FS_LOADER=y
+CONFIG_SPL_FS_LOADER=y
CONFIG_ESM_K3=y
CONFIG_K3_AVS0=y
CONFIG_ESM_PMIC=y
diff --git a/configs/j721e_hs_evm_r5_defconfig b/configs/j721e_hs_evm_r5_defconfig
index 3a8e0b1cd15b..6c3675c1726c 100644
--- a/configs/j721e_hs_evm_r5_defconfig
+++ b/configs/j721e_hs_evm_r5_defconfig
@@ -82,6 +82,7 @@ CONFIG_SYS_I2C_OMAP24XX=y
CONFIG_DM_MAILBOX=y
CONFIG_K3_SEC_PROXY=y
CONFIG_FS_LOADER=y
+CONFIG_SPL_FS_LOADER=y
CONFIG_K3_AVS0=y
CONFIG_MMC_SDHCI=y
CONFIG_SPL_MMC_SDHCI_ADMA=y
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 997b71322110..e6a1dc677d6e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -468,6 +468,15 @@ config FS_LOADER
The consumer driver would then use this loader to program whatever,
ie. the FPGA device.
+config SPL_FS_LOADER
+ bool "Enable loader driver for file system"
+ help
+ This is file system generic loader which can be used to load
+ the file image from the storage into target such as memory.
+
+ The consumer driver would then use this loader to program whatever,
+ ie. the FPGA device.
+
config GDSYS_SOC
bool "Enable gdsys SOC driver"
depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b64cd2a4de91..c7c95ee76767 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_IIM) += fsl_iim.o
obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
-obj-$(CONFIG_FS_LOADER) += fs_loader.o
+obj-$(CONFIG_$(SPL_)FS_LOADER) += fs_loader.o
obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 04/10] linux: bitmap.h: Add find_next_zero_area function
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (2 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 03/10] drivers: misc: Makefile: Enable fs_loader compilation at SPL Level Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 05/10] remoteproc: uclass: Add remoteproc resource handling helpers Amjad Ouled-Ameur
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur
From: Keerthy <j-keerthy@ti.com>
Add find_next_zero_area to fetch the next zero area in the map.
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
include/linux/bitmap.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index dae4225be549..0a8503af9f14 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -159,6 +159,32 @@ static inline unsigned long find_first_bit(const unsigned long *addr, unsigned l
(bit) < (size); \
(bit) = find_next_bit((addr), (size), (bit) + 1))
+static inline unsigned long
+bitmap_find_next_zero_area(unsigned long *map,
+ unsigned long size,
+ unsigned long start,
+ unsigned int nr, unsigned long align_mask)
+{
+ unsigned long index, end, i;
+again:
+ index = find_next_zero_bit(map, size, start);
+
+ /*
+ * Align allocation
+ */
+ index = (index + align_mask) & ~align_mask;
+
+ end = index + nr;
+ if (end > size)
+ return end;
+ i = find_next_bit(map, end, index);
+ if (i < end) {
+ start = i + 1;
+ goto again;
+ }
+ return index;
+}
+
static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
{
if (small_const_nbits(nbits)) {
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 05/10] remoteproc: uclass: Add remoteproc resource handling helpers
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (3 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 04/10] linux: bitmap.h: Add find_next_zero_area function Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 06/10] remoteproc: ipu: Add driver to bring up ipu Amjad Ouled-Ameur
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot
Cc: khilman, Keerthy, Amjad Ouled-Ameur, Andy Shevchenko,
Patrick Delaunay, Pratyush Yadav, Simon Glass
From: Keerthy <j-keerthy@ti.com>
Add remoteproc resource handling helpers. These functions
are primarily to parse the resource table and to handle
different types of resources. Carveout, devmem, trace &
vring resources are handled.
Signed-off-by: Keerthy <j-keerthy@ti.com>
[Amjad: fix redefinition of "struct resource_table" and compile warnings ]
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
Changes in v2:
- Add useful checks and remove redundant code.
drivers/remoteproc/rproc-uclass.c | 532 ++++++++++++++++++++++++++++++
include/remoteproc.h | 384 ++++++++++++++++++++-
2 files changed, 915 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c
index 64c47c1e7225..6adff1f7d877 100644
--- a/drivers/remoteproc/rproc-uclass.c
+++ b/drivers/remoteproc/rproc-uclass.c
@@ -8,10 +8,12 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <common.h>
+#include <elf.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
+#include <virtio_ring.h>
#include <remoteproc.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -19,9 +21,21 @@
#include <dm.h>
#include <dm/uclass.h>
#include <dm/uclass-internal.h>
+#include <linux/compat.h>
DECLARE_GLOBAL_DATA_PTR;
+struct resource_table {
+ u32 ver;
+ u32 num;
+ u32 reserved[2];
+ u32 offset[0];
+} __packed;
+
+typedef int (*handle_resource_t) (struct udevice *, void *, int offset, int avail);
+
+static struct resource_table *rsc_table;
+
/**
* for_each_remoteproc_device() - iterate through the list of rproc devices
* @fn: check function to call per match, if this function returns fail,
@@ -208,6 +222,80 @@ static int rproc_post_probe(struct udevice *dev)
return 0;
}
+/**
+ * rproc_add_res() - After parsing the resource table add the mappings
+ * @dev: device we finished probing
+ * @mapping: rproc_mem_entry for the resource
+ *
+ * Return: if the remote proc driver has a add_res routine, invokes it and
+ * hands over the return value. overall, 0 if all went well, else appropriate
+ * error value.
+ */
+static int rproc_add_res(struct udevice *dev, struct rproc_mem_entry *mapping)
+{
+ const struct dm_rproc_ops *ops = rproc_get_ops(dev);
+
+ if (!ops->add_res)
+ return -ENOSYS;
+
+ return ops->add_res(dev, mapping);
+}
+
+/**
+ * rproc_alloc_mem() - After parsing the resource table allocat mem
+ * @dev: device we finished probing
+ * @len: rproc_mem_entry for the resource
+ * @align: alignment for the resource
+ *
+ * Return: if the remote proc driver has a add_res routine, invokes it and
+ * hands over the return value. overall, 0 if all went well, else appropriate
+ * error value.
+ */
+static void *rproc_alloc_mem(struct udevice *dev, unsigned long len,
+ unsigned long align)
+{
+ const struct dm_rproc_ops *ops;
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return NULL;
+ }
+
+ if (ops->alloc_mem)
+ return ops->alloc_mem(dev, len, align);
+
+ return NULL;
+}
+
+/**
+ * rproc_config_pagetable() - Configure page table for remote processor
+ * @dev: device we finished probing
+ * @virt: Virtual address of the resource
+ * @phys: Physical address the resource
+ * @len: length the resource
+ *
+ * Return: if the remote proc driver has a add_res routine, invokes it and
+ * hands over the return value. overall, 0 if all went well, else appropriate
+ * error value.
+ */
+static int rproc_config_pagetable(struct udevice *dev, unsigned int virt,
+ unsigned int phys, unsigned int len)
+{
+ const struct dm_rproc_ops *ops;
+
+ ops = rproc_get_ops(dev);
+ if (!ops) {
+ debug("%s driver has no ops?\n", dev->name);
+ return -EINVAL;
+ }
+
+ if (ops->config_pagetable)
+ return ops->config_pagetable(dev, virt, phys, len);
+
+ return 0;
+}
+
UCLASS_DRIVER(rproc) = {
.id = UCLASS_REMOTEPROC,
.name = "remoteproc",
@@ -438,3 +526,447 @@ int rproc_is_running(int id)
{
return _rproc_ops_wrapper(id, RPROC_RUNNING);
};
+
+
+static int handle_trace(struct udevice *dev, struct fw_rsc_trace *rsc,
+ int offset, int avail)
+{
+ if (sizeof(*rsc) > avail) {
+ debug("trace rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ /*
+ * make sure reserved bytes are zeroes
+ */
+ if (rsc->reserved) {
+ debug("trace rsc has non zero reserved bytes\n");
+ return -EINVAL;
+ }
+
+ debug("trace rsc: da 0x%x, len 0x%x\n", rsc->da, rsc->len);
+
+ return 0;
+}
+
+static int handle_devmem(struct udevice *dev, struct fw_rsc_devmem *rsc,
+ int offset, int avail)
+{
+ struct rproc_mem_entry *mapping;
+
+ if (sizeof(*rsc) > avail) {
+ debug("devmem rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ /*
+ * make sure reserved bytes are zeroes
+ */
+ if (rsc->reserved) {
+ debug("devmem rsc has non zero reserved bytes\n");
+ return -EINVAL;
+ }
+
+ debug("devmem rsc: pa 0x%x, da 0x%x, len 0x%x\n",
+ rsc->pa, rsc->da, rsc->len);
+
+ rproc_config_pagetable(dev, rsc->da, rsc->pa, rsc->len);
+
+ mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return -ENOMEM;
+
+ /*
+ * We'll need this info later when we'll want to unmap everything
+ * (e.g. on shutdown).
+ *
+ * We can't trust the remote processor not to change the resource
+ * table, so we must maintain this info independently.
+ */
+ mapping->dma = rsc->pa;
+ mapping->da = rsc->da;
+ mapping->len = rsc->len;
+ rproc_add_res(dev, mapping);
+
+ debug("mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
+ rsc->pa, rsc->da, rsc->len);
+
+ return 0;
+}
+
+static int handle_carveout(struct udevice *dev, struct fw_rsc_carveout *rsc,
+ int offset, int avail)
+{
+ struct rproc_mem_entry *mapping;
+
+ if (sizeof(*rsc) > avail) {
+ debug("carveout rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ /*
+ * make sure reserved bytes are zeroes
+ */
+ if (rsc->reserved) {
+ debug("carveout rsc has non zero reserved bytes\n");
+ return -EINVAL;
+ }
+
+ debug("carveout rsc: da %x, pa %x, len %x, flags %x\n",
+ rsc->da, rsc->pa, rsc->len, rsc->flags);
+
+ rsc->pa = (uintptr_t)rproc_alloc_mem(dev, rsc->len, 8);
+ if (!rsc->pa) {
+ debug
+ ("failed to allocate carveout rsc: da %x, pa %x, len %x, flags %x\n",
+ rsc->da, rsc->pa, rsc->len, rsc->flags);
+ return -ENOMEM;
+ }
+ rproc_config_pagetable(dev, rsc->da, rsc->pa, rsc->len);
+
+ /*
+ * Ok, this is non-standard.
+ *
+ * Sometimes we can't rely on the generic iommu-based DMA API
+ * to dynamically allocate the device address and then set the IOMMU
+ * tables accordingly, because some remote processors might
+ * _require_ us to use hard coded device addresses that their
+ * firmware was compiled with.
+ *
+ * In this case, we must use the IOMMU API directly and map
+ * the memory to the device address as expected by the remote
+ * processor.
+ *
+ * Obviously such remote processor devices should not be configured
+ * to use the iommu-based DMA API: we expect 'dma' to contain the
+ * physical address in this case.
+ */
+ mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return -ENOMEM;
+
+ /*
+ * We'll need this info later when we'll want to unmap
+ * everything (e.g. on shutdown).
+ *
+ * We can't trust the remote processor not to change the
+ * resource table, so we must maintain this info independently.
+ */
+ mapping->dma = rsc->pa;
+ mapping->da = rsc->da;
+ mapping->len = rsc->len;
+ rproc_add_res(dev, mapping);
+
+ debug("carveout mapped 0x%x to 0x%x\n", rsc->da, rsc->pa);
+
+ return 0;
+}
+
+#define RPROC_PAGE_SHIFT 12
+#define RPROC_PAGE_SIZE BIT(RPROC_PAGE_SHIFT)
+#define RPROC_PAGE_ALIGN(x) (((x) + (RPROC_PAGE_SIZE - 1)) & ~(RPROC_PAGE_SIZE - 1))
+
+static int alloc_vring(struct udevice *dev, struct fw_rsc_vdev *rsc, int i)
+{
+ struct fw_rsc_vdev_vring *vring = &rsc->vring[i];
+ int size;
+ int order;
+ void *pa;
+
+ debug("vdev rsc: vring%d: da %x, qsz %d, align %d\n",
+ i, vring->da, vring->num, vring->align);
+
+ /*
+ * verify queue size and vring alignment are sane
+ */
+ if (!vring->num || !vring->align) {
+ debug("invalid qsz (%d) or alignment (%d)\n", vring->num,
+ vring->align);
+ return -EINVAL;
+ }
+
+ /*
+ * actual size of vring (in bytes)
+ */
+ size = RPROC_PAGE_ALIGN(vring_size(vring->num, vring->align));
+ order = vring->align >> RPROC_PAGE_SHIFT;
+
+ pa = rproc_alloc_mem(dev, size, order);
+ if (!pa) {
+ debug("failed to allocate vring rsc\n");
+ return -ENOMEM;
+ }
+ debug("alloc_mem(%#x, %d): %p\n", size, order, pa);
+ vring->da = (uintptr_t)pa;
+
+ return !pa;
+}
+
+static int handle_vdev(struct udevice *dev, struct fw_rsc_vdev *rsc,
+ int offset, int avail)
+{
+ int i, ret;
+ void *pa;
+
+ /*
+ * make sure resource isn't truncated
+ */
+ if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring)
+ + rsc->config_len > avail) {
+ debug("vdev rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ /*
+ * make sure reserved bytes are zeroes
+ */
+ if (rsc->reserved[0] || rsc->reserved[1]) {
+ debug("vdev rsc has non zero reserved bytes\n");
+ return -EINVAL;
+ }
+
+ debug("vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n",
+ rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings);
+
+ /*
+ * we currently support only two vrings per rvdev
+ */
+ if (rsc->num_of_vrings > 2) {
+ debug("too many vrings: %d\n", rsc->num_of_vrings);
+ return -EINVAL;
+ }
+
+ /*
+ * allocate the vrings
+ */
+ for (i = 0; i < rsc->num_of_vrings; i++) {
+ ret = alloc_vring(dev, rsc, i);
+ if (ret)
+ goto alloc_error;
+ }
+
+ pa = rproc_alloc_mem(dev, RPMSG_TOTAL_BUF_SPACE, 6);
+ if (!pa) {
+ debug("failed to allocate vdev rsc\n");
+ return -ENOMEM;
+ }
+ debug("vring buffer alloc_mem(%#x, 6): %p\n", RPMSG_TOTAL_BUF_SPACE,
+ pa);
+
+ return 0;
+
+ alloc_error:
+ return ret;
+}
+
+/*
+ * A lookup table for resource handlers. The indices are defined in
+ * enum fw_resource_type.
+ */
+static handle_resource_t loading_handlers[RSC_LAST] = {
+ [RSC_CARVEOUT] = (handle_resource_t)handle_carveout,
+ [RSC_DEVMEM] = (handle_resource_t)handle_devmem,
+ [RSC_TRACE] = (handle_resource_t)handle_trace,
+ [RSC_VDEV] = (handle_resource_t)handle_vdev,
+};
+
+/*
+ * handle firmware resource entries before booting the remote processor
+ */
+static int handle_resources(struct udevice *dev, int len,
+ handle_resource_t handlers[RSC_LAST])
+{
+ handle_resource_t handler;
+ int ret = 0, i;
+
+ for (i = 0; i < rsc_table->num; i++) {
+ int offset = rsc_table->offset[i];
+ struct fw_rsc_hdr *hdr = (void *)rsc_table + offset;
+ int avail = len - offset - sizeof(*hdr);
+ void *rsc = (void *)hdr + sizeof(*hdr);
+
+ /*
+ * make sure table isn't truncated
+ */
+ if (avail < 0) {
+ debug("rsc table is truncated\n");
+ return -EINVAL;
+ }
+
+ debug("rsc: type %d\n", hdr->type);
+
+ if (hdr->type >= RSC_LAST) {
+ debug("unsupported resource %d\n", hdr->type);
+ continue;
+ }
+
+ handler = handlers[hdr->type];
+ if (!handler)
+ continue;
+
+ ret = handler(dev, rsc, offset + sizeof(*hdr), avail);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int
+handle_intmem_to_l3_mapping(struct udevice *dev,
+ struct rproc_intmem_to_l3_mapping *l3_mapping)
+{
+ u32 i = 0;
+
+ for (i = 0; i < l3_mapping->num_entries; i++) {
+ struct l3_map *curr_map = &l3_mapping->mappings[i];
+ struct rproc_mem_entry *mapping;
+
+ mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return -ENOMEM;
+
+ mapping->dma = curr_map->l3_addr;
+ mapping->da = curr_map->priv_addr;
+ mapping->len = curr_map->len;
+ rproc_add_res(dev, mapping);
+ }
+
+ return 0;
+}
+
+static Elf32_Shdr *rproc_find_table(unsigned int addr)
+{
+ Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+ Elf32_Shdr *shdr; /* Section header structure pointer */
+ Elf32_Shdr sectionheader;
+ int i;
+ u8 *elf_data;
+ char *name_table;
+ struct resource_table *ptable;
+
+ ehdr = (Elf32_Ehdr *)(uintptr_t)addr;
+ elf_data = (u8 *)ehdr;
+ shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff);
+ memcpy(§ionheader, &shdr[ehdr->e_shstrndx], sizeof(sectionheader));
+ name_table = (char *)(elf_data + sectionheader.sh_offset);
+
+ for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+ memcpy(§ionheader, shdr, sizeof(sectionheader));
+ u32 size = sectionheader.sh_size;
+ u32 offset = sectionheader.sh_offset;
+
+ if (strcmp
+ (name_table + sectionheader.sh_name, ".resource_table"))
+ continue;
+
+ ptable = (struct resource_table *)(elf_data + offset);
+
+ /*
+ * make sure table has at least the header
+ */
+ if (sizeof(struct resource_table) > size) {
+ debug("header-less resource table\n");
+ return NULL;
+ }
+
+ /*
+ * we don't support any version beyond the first
+ */
+ if (ptable->ver != 1) {
+ debug("unsupported fw ver: %d\n", ptable->ver);
+ return NULL;
+ }
+
+ /*
+ * make sure reserved bytes are zeroes
+ */
+ if (ptable->reserved[0] || ptable->reserved[1]) {
+ debug("non zero reserved bytes\n");
+ return NULL;
+ }
+
+ /*
+ * make sure the offsets array isn't truncated
+ */
+ if (ptable->num * sizeof(ptable->offset[0]) +
+ sizeof(struct resource_table) > size) {
+ debug("resource table incomplete\n");
+ return NULL;
+ }
+
+ return shdr;
+ }
+
+ return NULL;
+}
+
+struct resource_table *rproc_find_resource_table(struct udevice *dev,
+ unsigned int addr,
+ int *tablesz)
+{
+ Elf32_Shdr *shdr;
+ Elf32_Shdr sectionheader;
+ struct resource_table *ptable;
+ u8 *elf_data = (u8 *)(uintptr_t)addr;
+
+ shdr = rproc_find_table(addr);
+ if (!shdr) {
+ debug("%s: failed to get resource section header\n", __func__);
+ return NULL;
+ }
+
+ memcpy(§ionheader, shdr, sizeof(sectionheader));
+ ptable = (struct resource_table *)(elf_data + sectionheader.sh_offset);
+ if (tablesz)
+ *tablesz = sectionheader.sh_size;
+
+ return ptable;
+}
+
+unsigned long rproc_parse_resource_table(struct udevice *dev, struct rproc *cfg)
+{
+ struct resource_table *ptable = NULL;
+ int tablesz;
+ int ret;
+ unsigned long addr;
+
+ addr = cfg->load_addr;
+
+ ptable = rproc_find_resource_table(dev, addr, &tablesz);
+ if (!ptable) {
+ debug("%s : failed to find resource table\n", __func__);
+ return 0;
+ }
+
+ debug("%s : found resource table\n", __func__);
+ rsc_table = kzalloc(tablesz, GFP_KERNEL);
+ if (!rsc_table) {
+ debug("resource table alloc failed!\n");
+ return 0;
+ }
+
+ /*
+ * Copy the resource table into a local buffer before handling the
+ * resource table.
+ */
+ memcpy(rsc_table, ptable, tablesz);
+ if (cfg->intmem_to_l3_mapping)
+ handle_intmem_to_l3_mapping(dev, cfg->intmem_to_l3_mapping);
+ ret = handle_resources(dev, tablesz, loading_handlers);
+ if (ret) {
+ debug("handle_resources failed: %d\n", ret);
+ return 0;
+ }
+
+ /*
+ * Instead of trying to mimic the kernel flow of copying the
+ * processed resource table into its post ELF load location in DDR
+ * copying it into its original location.
+ */
+ memcpy(ptable, rsc_table, tablesz);
+ free(rsc_table);
+ rsc_table = NULL;
+
+ return 1;
+}
diff --git a/include/remoteproc.h b/include/remoteproc.h
index 089131f65fde..1a970bc23c52 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* (C) Copyright 2015
* Texas Instruments Incorporated - http://www.ti.com/
@@ -15,6 +15,375 @@
*/
#include <dm/platdata.h> /* For platform data support - non dt world */
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+struct fw_rsc_hdr {
+ u32 type;
+ u8 data[0];
+};
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT: request for allocation of a physically contiguous
+ * memory region.
+ * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE: announces the availability of a trace buffer into which
+ * the remote processor will be writing logs.
+ * @RSC_VDEV: declare support for a virtio device, and serve as its
+ * virtio header.
+ * @RSC_PRELOAD_VENDOR: a vendor resource type that needs to be handled by
+ * remoteproc implementations before loading
+ * @RSC_POSTLOAD_VENDOR: a vendor resource type that needs to be handled by
+ * remoteproc implementations after loading
+ * @RSC_LAST: just keep this one at the end
+ *
+ * For more details regarding a specific resource type, please see its
+ * dedicated structure below.
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+ RSC_CARVEOUT = 0,
+ RSC_DEVMEM = 1,
+ RSC_TRACE = 2,
+ RSC_VDEV = 3,
+ RSC_PRELOAD_VENDOR = 4,
+ RSC_POSTLOAD_VENDOR = 5,
+ RSC_LAST = 6,
+};
+
+#define FW_RSC_ADDR_ANY (-1)
+
+/**
+ * struct fw_rsc_carveout - physically contiguous memory request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested memory region
+ *
+ * This resource entry requests the host to allocate a physically contiguous
+ * memory region.
+ *
+ * These request entries should precede other firmware resource entries,
+ * as other entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ *
+ * If the firmware is compiled with static addresses, then @da should specify
+ * the expected device address of this memory region. If @da is set to
+ * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
+ * overwrite @da with the dynamically allocated address.
+ *
+ * We will always use @da to negotiate the device addresses, even if it
+ * isn't using an iommu. In that case, though, it will obviously contain
+ * physical addresses.
+ *
+ * Some remote processors needs to know the allocated physical address
+ * even if they do use an iommu. This is needed, e.g., if they control
+ * hardware accelerators which access the physical memory directly (this
+ * is the case with OMAP4 for instance). In that case, the host will
+ * overwrite @pa with the dynamically allocated physical address.
+ * Generally we don't want to expose physical addresses if we don't have to
+ * (remote processors are generally _not_ trusted), so we might want to
+ * change this to happen _only_ when explicitly required by the hardware.
+ *
+ * @flags is used to provide IOMMU protection flags, and @name should
+ * (optionally) contain a human readable name of this carveout region
+ * (mainly for debugging purposes).
+ */
+struct fw_rsc_carveout {
+ u32 da;
+ u32 pa;
+ u32 len;
+ u32 flags;
+ u32 reserved;
+ u8 name[32];
+};
+
+/**
+ * struct fw_rsc_devmem - iommu mapping request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested region to be mapped
+ *
+ * This resource entry requests the host to iommu map a physically contiguous
+ * memory region. This is needed in case the remote processor requires
+ * access to certain memory-based peripherals; _never_ use it to access
+ * regular memory.
+ *
+ * This is obviously only needed if the remote processor is accessing memory
+ * via an iommu.
+ *
+ * @da should specify the required device address, @pa should specify
+ * the physical address we want to map, @len should specify the size of
+ * the mapping and @flags is the IOMMU protection flags. As always, @name may
+ * (optionally) contain a human readable name of this mapping (mainly for
+ * debugging purposes).
+ *
+ * Note: at this point we just "trust" those devmem entries to contain valid
+ * physical addresses, but this isn't safe and will be changed: eventually we
+ * want remoteproc implementations to provide us ranges of physical addresses
+ * the firmware is allowed to request, and not allow firmwares to request
+ * access to physical addresses that are outside those ranges.
+ */
+struct fw_rsc_devmem {
+ u32 da;
+ u32 pa;
+ u32 len;
+ u32 flags;
+ u32 reserved;
+ u8 name[32];
+};
+
+/**
+ * struct fw_rsc_trace - trace buffer declaration
+ * @da: device address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the trace buffer
+ *
+ * This resource entry provides the host information about a trace buffer
+ * into which the remote processor will write log messages.
+ *
+ * @da specifies the device address of the buffer, @len specifies
+ * its size, and @name may contain a human readable name of the trace buffer.
+ *
+ * After booting the remote processor, the trace buffers are exposed to the
+ * user via debugfs entries (called trace0, trace1, etc..).
+ */
+struct fw_rsc_trace {
+ u32 da;
+ u32 len;
+ u32 reserved;
+ u8 name[32];
+};
+
+/**
+ * struct fw_rsc_vdev_vring - vring descriptor entry
+ * @da: device address
+ * @align: the alignment between the consumer and producer parts of the vring
+ * @num: num of buffers supported by this vring (must be power of two)
+ * @notifyid is a unique rproc-wide notify index for this vring. This notify
+ * index is used when kicking a remote processor, to let it know that this
+ * vring is triggered.
+ * @pa: physical address
+ *
+ * This descriptor is not a resource entry by itself; it is part of the
+ * vdev resource type (see below).
+ *
+ * Note that @da should either contain the device address where
+ * the remote processor is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ */
+struct fw_rsc_vdev_vring {
+ u32 da;
+ u32 align;
+ u32 num;
+ u32 notifyid;
+ u32 pa;
+};
+
+/**
+ * struct fw_rsc_vdev - virtio device header
+ * @id: virtio device id (as in virtio_ids.h)
+ * @notifyid is a unique rproc-wide notify index for this vdev. This notify
+ * index is used when kicking a remote processor, to let it know that the
+ * status/features of this vdev have changes.
+ * @dfeatures specifies the virtio device features supported by the firmware
+ * @gfeatures is a place holder used by the host to write back the
+ * negotiated features that are supported by both sides.
+ * @config_len is the size of the virtio config space of this vdev. The config
+ * space lies in the resource table immediate after this vdev header.
+ * @status is a place holder where the host will indicate its virtio progress.
+ * @num_of_vrings indicates how many vrings are described in this vdev header
+ * @reserved: reserved (must be zero)
+ * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
+ *
+ * This resource is a virtio device header: it provides information about
+ * the vdev, and is then used by the host and its peer remote processors
+ * to negotiate and share certain virtio properties.
+ *
+ * By providing this resource entry, the firmware essentially asks remoteproc
+ * to statically allocate a vdev upon registration of the rproc (dynamic vdev
+ * allocation is not yet supported).
+ *
+ * Note: unlike virtualization systems, the term 'host' here means
+ * the Linux side which is running remoteproc to control the remote
+ * processors. We use the name 'gfeatures' to comply with virtio's terms,
+ * though there isn't really any virtualized guest OS here: it's the host
+ * which is responsible for negotiating the final features.
+ * Yeah, it's a bit confusing.
+ *
+ * Note: immediately following this structure is the virtio config space for
+ * this vdev (which is specific to the vdev; for more info, read the virtio
+ * spec). the size of the config space is specified by @config_len.
+ */
+struct fw_rsc_vdev {
+ u32 id;
+ u32 notifyid;
+ u32 dfeatures;
+ u32 gfeatures;
+ u32 config_len;
+ u8 status;
+ u8 num_of_vrings;
+ u8 reserved[2];
+ struct fw_rsc_vdev_vring vring[0];
+};
+
+/**
+ * struct rproc_mem_entry - memory entry descriptor
+ * @va: virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ * @priv: associated data
+ * @name: associated memory region name (optional)
+ * @node: list node
+ */
+struct rproc_mem_entry {
+ void *va;
+ dma_addr_t dma;
+ int len;
+ u32 da;
+ void *priv;
+ char name[32];
+ struct list_head node;
+};
+
+struct rproc;
+
+typedef u32(*init_func_proto) (u32 core_id, struct rproc *cfg);
+
+struct l3_map {
+ u32 priv_addr;
+ u32 l3_addr;
+ u32 len;
+};
+
+struct rproc_intmem_to_l3_mapping {
+ u32 num_entries;
+ struct l3_map mappings[16];
+};
+
+/**
+ * enum rproc_crash_type - remote processor crash types
+ * @RPROC_MMUFAULT: iommu fault
+ * @RPROC_WATCHDOG: watchdog bite
+ * @RPROC_FATAL_ERROR fatal error
+ *
+ * Each element of the enum is used as an array index. So that, the value of
+ * the elements should be always something sane.
+ *
+ * Feel free to add more types when needed.
+ */
+enum rproc_crash_type {
+ RPROC_MMUFAULT,
+ RPROC_WATCHDOG,
+ RPROC_FATAL_ERROR,
+};
+
+/* we currently support only two vrings per rvdev */
+#define RVDEV_NUM_VRINGS 2
+
+#define RPMSG_NUM_BUFS (512)
+#define RPMSG_BUF_SIZE (512)
+#define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+/**
+ * struct rproc_vring - remoteproc vring state
+ * @va: virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ * @align: vring alignment
+ * @notifyid: rproc-specific unique vring index
+ * @rvdev: remote vdev
+ * @vq: the virtqueue of this vring
+ */
+struct rproc_vring {
+ void *va;
+ dma_addr_t dma;
+ int len;
+ u32 da;
+ u32 align;
+ int notifyid;
+ struct rproc_vdev *rvdev;
+ struct virtqueue *vq;
+};
+
+/** struct rproc - structure with all processor specific information for
+ * loading remotecore from boot loader.
+ *
+ * @num_iommus: Number of IOMMUs for this remote core. Zero indicates that the
+ * processor does not have an IOMMU.
+ *
+ * @cma_base: Base address of the carveout for this remotecore.
+ *
+ * @cma_size: Length of the carveout in bytes.
+ *
+ * @page_table_addr: array with the physical address of the page table. We are
+ * using the same page table for both IOMMU's. There is currently no strong
+ * usecase for maintaining different page tables for different MMU's servicing
+ * the same CPU.
+ *
+ * @mmu_base_addr: base address of the MMU
+ *
+ * @entry_point: address that is the entry point for the remote core. This
+ * address is in the memory view of the remotecore.
+ *
+ * @load_addr: Address to which the bootloader loads the firmware from
+ * persistent storage before invoking the ELF loader. Keeping this address
+ * configurable allows future optimizations such as loading the firmware from
+ * storage for remotecore2 via EDMA while the CPU is processing the ELF image
+ * of remotecore1. This address is in the memory view of the A15.
+ *
+ * @firmware_name: Name of the file that is expected to contain the ELF image.
+ *
+ * @has_rsc_table: Flag populated after parsing the ELF binary on target.
+ */
+
+struct rproc {
+ u32 num_iommus;
+ unsigned long cma_base;
+ u32 cma_size;
+ unsigned long page_table_addr;
+ unsigned long mmu_base_addr[2];
+ unsigned long load_addr;
+ unsigned long entry_point;
+ char *core_name;
+ char *firmware_name;
+ char *ptn;
+ init_func_proto start_clocks;
+ init_func_proto config_mmu;
+ init_func_proto config_peripherals;
+ init_func_proto start_core;
+ u32 has_rsc_table;
+ struct rproc_intmem_to_l3_mapping *intmem_to_l3_mapping;
+ u32 trace_pa;
+ u32 trace_len;
+};
+
+extern struct rproc *rproc_cfg_arr[2];
/**
* enum rproc_mem_type - What type of memory model does the rproc use
* @RPROC_INTERNAL_MEMORY_MAPPED: Remote processor uses own memory and is memory
@@ -126,6 +495,12 @@ struct dm_rproc_ops {
* @return virtual address.
*/
void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size);
+ int (*add_res)(struct udevice *dev,
+ struct rproc_mem_entry *mapping);
+ void * (*alloc_mem)(struct udevice *dev, unsigned long len,
+ unsigned long align);
+ unsigned int (*config_pagetable)(struct udevice *dev, unsigned int virt,
+ unsigned int phys, unsigned int len);
};
/* Accessor */
@@ -322,6 +697,13 @@ int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
*/
int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
+
+unsigned long rproc_parse_resource_table(struct udevice *dev,
+ struct rproc *cfg);
+
+struct resource_table *rproc_find_resource_table(struct udevice *dev,
+ unsigned int addr,
+ int *tablesz);
#else
static inline int rproc_init(void) { return -ENOSYS; }
static inline int rproc_dev_init(int id) { return -ENOSYS; }
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 06/10] remoteproc: ipu: Add driver to bring up ipu
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (4 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 05/10] remoteproc: uclass: Add remoteproc resource handling helpers Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes Amjad Ouled-Ameur
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot
Cc: khilman, Keerthy, Amjad Ouled-Ameur, Lokesh Vutla,
Murali Karicheri, Roger Quadros, Suman Anna
From: Keerthy <j-keerthy@ti.com>
The driver enables IPU support. Basically enables the clocks,
timers, watchdog timers and bare minimal MMU and supports
loading the firmware from mmc.
Signed-off-by: Keerthy <j-keerthy@ti.com>
[Amjad: fix compile warnings]
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
MAINTAINERS | 1 +
drivers/remoteproc/Kconfig | 10 +
drivers/remoteproc/Makefile | 1 +
drivers/remoteproc/ipu_rproc.c | 759 +++++++++++++++++++++++++++++++++
4 files changed, 771 insertions(+)
create mode 100644 drivers/remoteproc/ipu_rproc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ec586ec5466f..f7ec528af73a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -508,6 +508,7 @@ F: drivers/ram/k3*
F: drivers/remoteproc/k3_system_controller.c
F: drivers/remoteproc/pruc_rpoc.c
F: drivers/remoteproc/ti*
+F: drivers/remoteproc/ipu_rproc.c
F: drivers/reset/reset-ti-sci.c
F: drivers/reset/reset-dra7.c
F: drivers/rtc/davinci.c
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 24e536463bbd..27e4a60ff5b1 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -92,4 +92,14 @@ config REMOTEPROC_TI_PRU
help
Say 'y' here to add support for TI' K3 remoteproc driver.
+config REMOTEPROC_TI_IPU
+ bool "Support for TI's K3 based IPU remoteproc driver"
+ select REMOTEPROC
+ depends on DM
+ depends on SPL_DRIVERS_MISC
+ depends on SPL_FS_LOADER
+ depends on OF_CONTROL
+ help
+ Say 'y' here to add support for TI' K3 remoteproc driver.
+
endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index f0e83451d66f..fbe9c172bc04 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o
obj-$(CONFIG_REMOTEPROC_TI_PRU) += pru_rproc.o
+obj-$(CONFIG_REMOTEPROC_TI_IPU) += ipu_rproc.o
diff --git a/drivers/remoteproc/ipu_rproc.c b/drivers/remoteproc/ipu_rproc.c
new file mode 100644
index 000000000000..b4a06bc955a9
--- /dev/null
+++ b/drivers/remoteproc/ipu_rproc.c
@@ -0,0 +1,759 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IPU remoteproc driver for various SoCs
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Angela Stegmaier <angelabaker@ti.com>
+ * Venkateswara Rao Mandela <venkat.mandela@ti.com>
+ * Keerthy <j-keerthy@ti.com>
+ */
+
+#include <common.h>
+#include <hang.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <elf.h>
+#include <env.h>
+#include <dm/of_access.h>
+#include <fs_loader.h>
+#include <remoteproc.h>
+#include <errno.h>
+#include <clk.h>
+#include <reset.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <misc.h>
+#include <power-domain.h>
+#include <timer.h>
+#include <fs.h>
+#include <spl.h>
+#include <timer.h>
+#include <reset.h>
+#include <linux/bitmap.h>
+
+#define IPU1_LOAD_ADDR (0xa17ff000)
+#define MAX_REMOTECORE_BIN_SIZE (8 * 0x100000)
+
+enum ipu_num {
+ IPU1 = 0,
+ IPU2,
+ RPROC_END_ENUMS,
+};
+
+#define IPU2_LOAD_ADDR (IPU1_LOAD_ADDR + MAX_REMOTECORE_BIN_SIZE)
+
+#define PAGE_SHIFT 12
+#define PAGESIZE_1M 0x0
+#define PAGESIZE_64K 0x1
+#define PAGESIZE_4K 0x2
+#define PAGESIZE_16M 0x3
+#define LE 0
+#define BE 1
+#define ELEMSIZE_8 0x0
+#define ELEMSIZE_16 0x1
+#define ELEMSIZE_32 0x2
+#define MIXED_TLB 0x0
+#define MIXED_CPU 0x1
+
+#define PGT_SMALLPAGE_SIZE 0x00001000
+#define PGT_LARGEPAGE_SIZE 0x00010000
+#define PGT_SECTION_SIZE 0x00100000
+#define PGT_SUPERSECTION_SIZE 0x01000000
+
+#define PGT_L1_DESC_PAGE 0x00001
+#define PGT_L1_DESC_SECTION 0x00002
+#define PGT_L1_DESC_SUPERSECTION 0x40002
+
+#define PGT_L1_DESC_PAGE_MASK 0xfffffC00
+#define PGT_L1_DESC_SECTION_MASK 0xfff00000
+#define PGT_L1_DESC_SUPERSECTION_MASK 0xff000000
+
+#define PGT_L1_DESC_SMALLPAGE_INDEX_SHIFT 12
+#define PGT_L1_DESC_LARGEPAGE_INDEX_SHIFT 16
+#define PGT_L1_DESC_SECTION_INDEX_SHIFT 20
+#define PGT_L1_DESC_SUPERSECTION_INDEX_SHIFT 24
+
+#define PGT_L2_DESC_SMALLPAGE 0x02
+#define PGT_L2_DESC_LARGEPAGE 0x01
+
+#define PGT_L2_DESC_SMALLPAGE_MASK 0xfffff000
+#define PGT_L2_DESC_LARGEPAGE_MASK 0xffff0000
+
+/*
+ * The memory for the page tables (256 KB per IPU) is placed just before
+ * the carveout memories for the remote processors. 16 KB of memory is
+ * needed for the L1 page table (4096 entries * 4 bytes per 1 MB section).
+ * Any smaller page (64 KB or 4 KB) entries are supported through L2 page
+ * tables (1 KB per table). The remaining 240 KB can provide support for
+ * 240 L2 page tables. Any remoteproc firmware image requiring more than
+ * 240 L2 page table entries would need more memory to be reserved.
+ */
+#define PAGE_TABLE_SIZE_L1 (0x00004000)
+#define PAGE_TABLE_SIZE_L2 (0x400)
+#define MAX_NUM_L2_PAGE_TABLES (240)
+#define PAGE_TABLE_SIZE_L2_TOTAL (MAX_NUM_L2_PAGE_TABLES * PAGE_TABLE_SIZE_L2)
+#define PAGE_TABLE_SIZE (PAGE_TABLE_SIZE_L1 + (PAGE_TABLE_SIZE_L2_TOTAL))
+
+/**
+ * struct omap_rproc_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: bus address used to access the memory region
+ * @dev_addr: device address of the memory region from DSP view
+ * @size: size of the memory region
+ */
+struct omap_rproc_mem {
+ void __iomem *cpu_addr;
+ phys_addr_t bus_addr;
+ u32 dev_addr;
+ size_t size;
+};
+
+struct ipu_privdata {
+ struct omap_rproc_mem mem;
+ struct list_head mappings;
+ const char *fw_name;
+ u32 bootaddr;
+ int id;
+ struct udevice *rdev;
+};
+
+typedef int (*handle_resource_t) (void *, int offset, int avail);
+
+unsigned int *page_table_l1 = (unsigned int *)0x0;
+unsigned int *page_table_l2 = (unsigned int *)0x0;
+
+/*
+ * Set maximum carveout size to 96 MB
+ */
+#define DRA7_RPROC_MAX_CO_SIZE (96 * 0x100000)
+
+/*
+ * These global variables are used for deriving the MMU page tables. They
+ * are initialized for each core with the appropriate values. The length
+ * of the array mem_bitmap is set as per a 96 MB carveout which the
+ * maximum set aside in the current memory map.
+ */
+unsigned long mem_base;
+unsigned long mem_size;
+unsigned long
+
+mem_bitmap[BITS_TO_LONGS(DRA7_RPROC_MAX_CO_SIZE >> PAGE_SHIFT)];
+unsigned long mem_count;
+
+unsigned int pgtable_l2_map[MAX_NUM_L2_PAGE_TABLES];
+unsigned int pgtable_l2_cnt;
+
+void *ipu_alloc_mem(struct udevice *dev, unsigned long len, unsigned long align)
+{
+ unsigned long mask;
+ unsigned long pageno;
+ int count;
+
+ count = ((len + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ mask = (1 << align) - 1;
+ pageno =
+ bitmap_find_next_zero_area(mem_bitmap, mem_count, 0, count, mask);
+ debug("%s: count %d mask %#lx pageno %#lx\n", __func__, count, mask,
+ pageno);
+
+ if (pageno >= mem_count) {
+ debug("%s: %s Error allocating memory; "
+ "Please check carveout size\n", __FILE__, __func__);
+ return NULL;
+ }
+
+ bitmap_set(mem_bitmap, pageno, count);
+ return (void *)(mem_base + (pageno << PAGE_SHIFT));
+}
+
+int find_pagesz(unsigned int virt, unsigned int phys, unsigned int len)
+{
+ int pg_sz_ind = -1;
+ unsigned int min_align = __ffs(virt);
+
+ if (min_align > __ffs(phys))
+ min_align = __ffs(phys);
+
+ if (min_align >= PGT_L1_DESC_SUPERSECTION_INDEX_SHIFT &&
+ len >= 0x1000000) {
+ pg_sz_ind = PAGESIZE_16M;
+ goto ret_block;
+ }
+ if (min_align >= PGT_L1_DESC_SECTION_INDEX_SHIFT &&
+ len >= 0x100000) {
+ pg_sz_ind = PAGESIZE_1M;
+ goto ret_block;
+ }
+ if (min_align >= PGT_L1_DESC_LARGEPAGE_INDEX_SHIFT &&
+ len >= 0x10000) {
+ pg_sz_ind = PAGESIZE_64K;
+ goto ret_block;
+ }
+ if (min_align >= PGT_L1_DESC_SMALLPAGE_INDEX_SHIFT &&
+ len >= 0x1000) {
+ pg_sz_ind = PAGESIZE_4K;
+ goto ret_block;
+ }
+
+ ret_block:
+ return pg_sz_ind;
+}
+
+int get_l2_pg_tbl_addr(unsigned int virt, unsigned int *pg_tbl_addr)
+{
+ int ret = -1;
+ int i = 0;
+ int match_found = 0;
+ unsigned int tag = (virt & PGT_L1_DESC_SECTION_MASK);
+
+ *pg_tbl_addr = 0;
+ for (i = 0; (i < pgtable_l2_cnt) && (match_found == 0); i++) {
+ if (tag == pgtable_l2_map[i]) {
+ *pg_tbl_addr =
+ ((unsigned int)page_table_l2) +
+ (i * PAGE_TABLE_SIZE_L2);
+ match_found = 1;
+ ret = 0;
+ }
+ }
+
+ if (match_found == 0 && i < MAX_NUM_L2_PAGE_TABLES) {
+ pgtable_l2_map[i] = tag;
+ pgtable_l2_cnt++;
+ *pg_tbl_addr =
+ ((unsigned int)page_table_l2) + (i * PAGE_TABLE_SIZE_L2);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int
+config_l2_pagetable(unsigned int virt, unsigned int phys,
+ unsigned int pg_sz, unsigned int pg_tbl_addr)
+{
+ int ret = -1;
+ unsigned int desc = 0;
+ int i = 0;
+ unsigned int *pg_tbl = (unsigned int *)pg_tbl_addr;
+
+ /*
+ * Pick bit 19:12 of the virtual address as index
+ */
+ unsigned int index = (virt & (~PGT_L1_DESC_SECTION_MASK)) >> PAGE_SHIFT;
+
+ switch (pg_sz) {
+ case PAGESIZE_64K:
+ desc =
+ (phys & PGT_L2_DESC_LARGEPAGE_MASK) | PGT_L2_DESC_LARGEPAGE;
+ for (i = 0; i < 16; i++)
+ pg_tbl[index + i] = desc;
+ ret = 0;
+ break;
+ case PAGESIZE_4K:
+ desc =
+ (phys & PGT_L2_DESC_SMALLPAGE_MASK) | PGT_L2_DESC_SMALLPAGE;
+ pg_tbl[index] = desc;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+unsigned int
+ipu_config_pagetable(struct udevice *dev, unsigned int virt, unsigned int phys,
+ unsigned int len)
+{
+ unsigned int index;
+ unsigned int l = len;
+ unsigned int desc;
+ int pg_sz = 0;
+ int i = 0, err = 0;
+ unsigned int pg_tbl_l2_addr = 0;
+ unsigned int tmp_pgsz;
+
+ if ((len & 0x0FFF) != 0)
+ return 0;
+
+ while (l > 0) {
+ pg_sz = find_pagesz(virt, phys, l);
+ index = virt >> PGT_L1_DESC_SECTION_INDEX_SHIFT;
+ switch (pg_sz) {
+ /*
+ * 16 MB super section
+ */
+ case PAGESIZE_16M:
+ /*
+ * Program the next 16 descriptors
+ */
+ desc =
+ (phys & PGT_L1_DESC_SUPERSECTION_MASK) |
+ PGT_L1_DESC_SUPERSECTION;
+ for (i = 0; i < 16; i++)
+ page_table_l1[index + i] = desc;
+ l -= PGT_SUPERSECTION_SIZE;
+ phys += PGT_SUPERSECTION_SIZE;
+ virt += PGT_SUPERSECTION_SIZE;
+ break;
+ /*
+ * 1 MB section
+ */
+ case PAGESIZE_1M:
+ desc =
+ (phys & PGT_L1_DESC_SECTION_MASK) |
+ PGT_L1_DESC_SECTION;
+ page_table_l1[index] = desc;
+ l -= PGT_SECTION_SIZE;
+ phys += PGT_SECTION_SIZE;
+ virt += PGT_SECTION_SIZE;
+ break;
+ /*
+ * 64 KB large page
+ */
+ case PAGESIZE_64K:
+ case PAGESIZE_4K:
+ if (pg_sz == PAGESIZE_64K)
+ tmp_pgsz = 0x10000;
+ else
+ tmp_pgsz = 0x1000;
+
+ err = get_l2_pg_tbl_addr(virt, &pg_tbl_l2_addr);
+ if (err != 0) {
+ debug
+ ("Unable to get level 2 PT address\n");
+ hang();
+ }
+ err =
+ config_l2_pagetable(virt, phys, pg_sz,
+ pg_tbl_l2_addr);
+ desc =
+ (pg_tbl_l2_addr & PGT_L1_DESC_PAGE_MASK) |
+ PGT_L1_DESC_PAGE;
+ page_table_l1[index] = desc;
+ l -= tmp_pgsz;
+ phys += tmp_pgsz;
+ virt += tmp_pgsz;
+ break;
+ case -1:
+ default:
+ return 0;
+ }
+ }
+
+ return len;
+}
+
+int da_to_pa(struct udevice *dev, int da)
+{
+ struct rproc_mem_entry *maps = NULL;
+ struct ipu_privdata *priv = dev_get_priv(dev);
+
+ list_for_each_entry(maps, &priv->mappings, node) {
+ if (da >= maps->da && da < (maps->da + maps->len))
+ return maps->dma + (da - maps->da);
+ }
+
+ return 0;
+}
+
+u32 ipu_config_mmu(u32 core_id, struct rproc *cfg)
+{
+ u32 i = 0;
+ u32 reg = 0;
+
+ /*
+ * Clear the entire pagetable location before programming the
+ * address into the MMU
+ */
+ memset((void *)cfg->page_table_addr, 0x00, PAGE_TABLE_SIZE);
+
+ for (i = 0; i < cfg->num_iommus; i++) {
+ u32 mmu_base = cfg->mmu_base_addr[i];
+
+ __raw_writel((int)cfg->page_table_addr, mmu_base + 0x4c);
+ reg = __raw_readl(mmu_base + 0x88);
+
+ /*
+ * enable bus-error back
+ */
+ __raw_writel(reg | 0x1, mmu_base + 0x88);
+
+ /*
+ * Enable the MMU IRQs during MMU programming for the
+ * late attachcase. This is to allow the MMU fault to be
+ * detected by the kernel.
+ *
+ * MULTIHITFAULT|EMMUMISS|TRANSLATIONFAULT|TABLEWALKFAULT
+ */
+ __raw_writel(0x1E, mmu_base + 0x1c);
+
+ /*
+ * emutlbupdate|TWLENABLE|MMUENABLE
+ */
+ __raw_writel(0x6, mmu_base + 0x44);
+ }
+
+ return 0;
+}
+
+/**
+ * enum ipu_mem - PRU core memory range identifiers
+ */
+enum ipu_mem {
+ PRU_MEM_IRAM = 0,
+ PRU_MEM_CTRL,
+ PRU_MEM_DEBUG,
+ PRU_MEM_MAX,
+};
+
+static int ipu_start(struct udevice *dev)
+{
+ struct ipu_privdata *priv;
+ struct reset_ctl reset;
+ struct rproc *cfg = NULL;
+ int ret;
+
+ priv = dev_get_priv(dev);
+
+ cfg = rproc_cfg_arr[priv->id];
+ if (cfg->config_peripherals)
+ cfg->config_peripherals(priv->id, cfg);
+
+ /*
+ * Start running the remote core
+ */
+ ret = reset_get_by_index(dev, 0, &reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error getting reset index %d\n", __func__, 0);
+ return ret;
+ }
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error deasserting reset %d\n", __func__, 0);
+ return ret;
+ }
+
+ ret = reset_get_by_index(dev, 1, &reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error getting reset index %d\n", __func__, 1);
+ return ret;
+ }
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error deasserting reset %d\n", __func__, 1);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ipu_stop(struct udevice *dev)
+{
+ return 0;
+}
+
+/**
+ * ipu_init() - Initialize the remote processor
+ * @dev: rproc device pointer
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int ipu_init(struct udevice *dev)
+{
+ return 0;
+}
+
+static int ipu_add_res(struct udevice *dev, struct rproc_mem_entry *mapping)
+{
+ struct ipu_privdata *priv = dev_get_priv(dev);
+
+ list_add_tail(&mapping->node, &priv->mappings);
+ return 0;
+}
+
+static int ipu_load(struct udevice *dev, ulong addr, ulong size)
+{
+ Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+ Elf32_Phdr *phdr; /* Program header structure pointer */
+ Elf32_Phdr proghdr;
+ int va;
+ int pa;
+ int i;
+
+ ehdr = (Elf32_Ehdr *)addr;
+ phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
+ /*
+ * Load each program header
+ */
+ for (i = 0; i < ehdr->e_phnum; ++i) {
+ memcpy(&proghdr, phdr, sizeof(Elf32_Phdr));
+
+ if (proghdr.p_type != PT_LOAD) {
+ ++phdr;
+ continue;
+ }
+
+ va = proghdr.p_paddr;
+ pa = da_to_pa(dev, va);
+ if (pa)
+ proghdr.p_paddr = pa;
+
+ void *dst = (void *)(uintptr_t)proghdr.p_paddr;
+ void *src = (void *)addr + proghdr.p_offset;
+
+ debug("Loading phdr %i to 0x%p (%i bytes)\n", i, dst,
+ proghdr.p_filesz);
+ if (proghdr.p_filesz)
+ memcpy(dst, src, proghdr.p_filesz);
+
+ flush_cache((unsigned long)dst, proghdr.p_memsz);
+
+ ++phdr;
+ }
+
+ return 0;
+}
+
+static const struct dm_rproc_ops ipu_ops = {
+ .init = ipu_init,
+ .start = ipu_start,
+ .stop = ipu_stop,
+ .load = ipu_load,
+ .add_res = ipu_add_res,
+ .config_pagetable = ipu_config_pagetable,
+ .alloc_mem = ipu_alloc_mem,
+};
+
+/*
+ * If the remotecore binary expects any peripherals to be setup before it has
+ * booted, configure them here.
+ *
+ * These functions are left empty by default as their operation is usecase
+ * specific.
+ */
+
+u32 ipu1_config_peripherals(u32 core_id, struct rproc *cfg)
+{
+ return 0;
+}
+
+u32 ipu2_config_peripherals(u32 core_id, struct rproc *cfg)
+{
+ return 0;
+}
+
+struct rproc_intmem_to_l3_mapping ipu1_intmem_to_l3_mapping = {
+ .num_entries = 1,
+ .mappings = {
+ /*
+ * L2 SRAM
+ */
+ {
+ .priv_addr = 0x55020000,
+ .l3_addr = 0x58820000,
+ .len = (64 * 1024)},
+ }
+};
+
+struct rproc_intmem_to_l3_mapping ipu2_intmem_to_l3_mapping = {
+ .num_entries = 1,
+ .mappings = {
+ /*
+ * L2 SRAM
+ */
+ {
+ .priv_addr = 0x55020000,
+ .l3_addr = 0x55020000,
+ .len = (64 * 1024)},
+ }
+};
+
+struct rproc ipu1_config = {
+ .num_iommus = 1,
+ .mmu_base_addr = {0x58882000, 0},
+ .load_addr = IPU1_LOAD_ADDR,
+ .core_name = "IPU1",
+ .firmware_name = "dra7-ipu1-fw.xem4",
+ .config_mmu = ipu_config_mmu,
+ .config_peripherals = ipu1_config_peripherals,
+ .intmem_to_l3_mapping = &ipu1_intmem_to_l3_mapping
+};
+
+struct rproc ipu2_config = {
+ .num_iommus = 1,
+ .mmu_base_addr = {0x55082000, 0},
+ .load_addr = IPU2_LOAD_ADDR,
+ .core_name = "IPU2",
+ .firmware_name = "dra7-ipu2-fw.xem4",
+ .config_mmu = ipu_config_mmu,
+ .config_peripherals = ipu2_config_peripherals,
+ .intmem_to_l3_mapping = &ipu2_intmem_to_l3_mapping
+};
+
+struct rproc *rproc_cfg_arr[2] = {
+ [IPU2] = &ipu2_config,
+ [IPU1] = &ipu1_config,
+};
+
+u32 spl_pre_boot_core(struct udevice *dev, u32 core_id)
+{
+ struct rproc *cfg = NULL;
+ unsigned long load_elf_status = 0;
+ int tablesz;
+
+ cfg = rproc_cfg_arr[core_id];
+ /*
+ * Check for valid elf image
+ */
+ if (!valid_elf_image(cfg->load_addr))
+ return 1;
+
+ if (rproc_find_resource_table(dev, cfg->load_addr, &tablesz))
+ cfg->has_rsc_table = 1;
+ else
+ cfg->has_rsc_table = 0;
+
+ /*
+ * Configure the MMU
+ */
+ if (cfg->config_mmu && cfg->has_rsc_table)
+ cfg->config_mmu(core_id, cfg);
+
+ /*
+ * Load the remote core. Fill the page table of the first(possibly
+ * only) IOMMU during ELF loading. Copy the page table to the second
+ * IOMMU before running the remote core.
+ */
+
+ page_table_l1 = (unsigned int *)cfg->page_table_addr;
+ page_table_l2 =
+ (unsigned int *)(cfg->page_table_addr + PAGE_TABLE_SIZE_L1);
+ mem_base = cfg->cma_base;
+ mem_size = cfg->cma_size;
+ memset(mem_bitmap, 0x00, sizeof(mem_bitmap));
+ mem_count = (cfg->cma_size >> PAGE_SHIFT);
+
+ /*
+ * Clear variables used for level 2 page table allocation
+ */
+ memset(pgtable_l2_map, 0x00, sizeof(pgtable_l2_map));
+ pgtable_l2_cnt = 0;
+
+ load_elf_status = rproc_parse_resource_table(dev, cfg);
+ if (load_elf_status == 0) {
+ debug("load_elf_image_phdr returned error for core %s\n",
+ cfg->core_name);
+ return 1;
+ }
+
+ flush_cache(cfg->page_table_addr, PAGE_TABLE_SIZE);
+
+ return 0;
+}
+
+static fdt_addr_t ipu_parse_mem_nodes(struct udevice *dev, char *name,
+ int privid, fdt_size_t *sizep)
+{
+ int ret;
+ u32 sp;
+ ofnode mem_node;
+
+ ret = ofnode_read_u32(dev_ofnode(dev), name, &sp);
+ if (ret) {
+ dev_err(dev, "memory-region node fetch failed %d\n", ret);
+ return ret;
+ }
+
+ mem_node = ofnode_get_by_phandle(sp);
+ if (!ofnode_valid(mem_node))
+ return -EINVAL;
+
+ return ofnode_get_addr_size_index(mem_node, 0, sizep);
+}
+
+/**
+ * ipu_probe() - Basic probe
+ * @dev: corresponding k3 remote processor device
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int ipu_probe(struct udevice *dev)
+{
+ struct ipu_privdata *priv;
+ struct rproc *cfg = NULL;
+ struct reset_ctl reset;
+ static const char *const ipu_mem_names[] = { "l2ram" };
+ int ret;
+ fdt_size_t sizep;
+
+ priv = dev_get_priv(dev);
+
+ priv->mem.bus_addr =
+ devfdt_get_addr_size_name(dev,
+ ipu_mem_names[0],
+ (fdt_addr_t *)&priv->mem.size);
+
+ ret = reset_get_by_index(dev, 2, &reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error getting reset index %d\n", __func__, 2);
+ return ret;
+ }
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ dev_err(dev, "%s: error deasserting reset %d\n", __func__, 2);
+ return ret;
+ }
+
+ if (priv->mem.bus_addr == FDT_ADDR_T_NONE) {
+ dev_err(dev, "%s bus address not found\n", ipu_mem_names[0]);
+ return -EINVAL;
+ }
+ priv->mem.cpu_addr = map_physmem(priv->mem.bus_addr,
+ priv->mem.size, MAP_NOCACHE);
+
+ if (devfdt_get_addr(dev) == 0x58820000)
+ priv->id = 0;
+ else
+ priv->id = 1;
+
+ cfg = rproc_cfg_arr[priv->id];
+ cfg->cma_base = ipu_parse_mem_nodes(dev, "memory-region", priv->id,
+ &sizep);
+ cfg->cma_size = sizep;
+
+ cfg->page_table_addr = ipu_parse_mem_nodes(dev, "pg-tbl", priv->id,
+ &sizep);
+
+ dev_info(dev,
+ "ID %d memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
+ priv->id, ipu_mem_names[0], &priv->mem.bus_addr,
+ priv->mem.size, priv->mem.cpu_addr, priv->mem.dev_addr);
+
+ INIT_LIST_HEAD(&priv->mappings);
+ if (spl_pre_boot_core(dev, priv->id))
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id ipu_ids[] = {
+ {.compatible = "ti,dra7-ipu"},
+ {}
+};
+
+U_BOOT_DRIVER(ipu) = {
+ .name = "ipu",
+ .of_match = ipu_ids,
+ .id = UCLASS_REMOTEPROC,
+ .ops = &ipu_ops,
+ .probe = ipu_probe,
+ .priv_auto = sizeof(struct ipu_privdata),
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (5 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 06/10] remoteproc: ipu: Add driver to bring up ipu Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-10-11 18:59 ` Tom Rini
2021-09-30 16:21 ` [PATCH v2 08/10] arm: dts: dra7: Add ipu and " Amjad Ouled-Ameur
` (2 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur
From: Keerthy <j-keerthy@ti.com>
Add all the ipu early boot related nodes
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
MAINTAINERS | 1 +
arch/arm/dts/dra7-ipu-common-early-boot.dtsi | 113 +++++++++++++++++++
2 files changed, 114 insertions(+)
create mode 100644 arch/arm/dts/dra7-ipu-common-early-boot.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index f7ec528af73a..ffaf2015ca5f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -492,6 +492,7 @@ F: arch/arm/mach-keystone/
F: arch/arm/mach-omap2/
F: arch/arm/include/asm/arch-omap*/
F: arch/arm/include/asm/ti-common/
+F: arch/arm/dts/dra7*
F: board/ti/
F: drivers/dma/ti*
F: drivers/firmware/ti_sci.*
diff --git a/arch/arm/dts/dra7-ipu-common-early-boot.dtsi b/arch/arm/dts/dra7-ipu-common-early-boot.dtsi
new file mode 100644
index 000000000000..ec6040ff93eb
--- /dev/null
+++ b/arch/arm/dts/dra7-ipu-common-early-boot.dtsi
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/ {
+ chosen {
+ firmware-loader = &fs_loader0;
+ };
+
+ fs_loader0: fs_loader@0 {
+ u-boot,dm-pre-reloc;
+ compatible = "u-boot,fs-loader";
+ phandlepart = <&mmc1 1>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ u-boot,dm-spl;
+
+ ipu2_memory_region: ipu2-memory@95800000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x95800000 0x0 0x3800000>;
+ reusable;
+ status = "okay";
+ u-boot,dm-spl;
+ };
+
+ ipu1_memory_region: ipu1-memory@9d000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x9d000000 0x0 0x2000000>;
+ reusable;
+ status = "okay";
+ u-boot,dm-spl;
+ };
+
+ ipu1_pgtbl: ipu1-pgtbl@95700000 {
+ reg = <0x0 0x95700000 0x0 0x40000>;
+ no-map;
+ u-boot,dm-spl;
+ };
+
+ ipu2_pgtbl: ipu2-pgtbl@95740000 {
+ reg = <0x0 0x95740000 0x0 0x40000>;
+ no-map;
+ u-boot,dm-spl;
+ };
+ };
+};
+
+&timer3 {
+ u-boot,dm-spl;
+};
+
+&timer4 {
+ u-boot,dm-spl;
+};
+
+&timer7 {
+ u-boot,dm-spl;
+};
+
+&timer8 {
+ u-boot,dm-spl;
+};
+
+&timer9 {
+ u-boot,dm-spl;
+};
+
+&timer11 {
+ u-boot,dm-spl;
+};
+
+&mmu_ipu1 {
+ u-boot,dm-spl;
+};
+
+&mmu_ipu2 {
+ u-boot,dm-spl;
+};
+
+&ipu1 {
+ status = "okay";
+ memory-region = <&ipu1_memory_region>;
+ pg-tbl = <&ipu1_pgtbl>;
+ u-boot,dm-spl;
+};
+
+&ipu2 {
+ status = "okay";
+ memory-region = <&ipu2_memory_region>;
+ pg-tbl = <&ipu2_pgtbl>;
+ u-boot,dm-spl;
+};
+
+&l4_wkup {
+ u-boot,dm-spl;
+};
+
+&prm {
+ u-boot,dm-spl;
+};
+
+&ipu1_rst {
+ u-boot,dm-spl;
+};
+
+&ipu2_rst {
+ u-boot,dm-spl;
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes
2021-09-30 16:21 ` [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes Amjad Ouled-Ameur
@ 2021-10-11 18:59 ` Tom Rini
2022-01-05 11:42 ` Amjad Ouled-Ameur
0 siblings, 1 reply; 13+ messages in thread
From: Tom Rini @ 2021-10-11 18:59 UTC (permalink / raw)
To: Amjad Ouled-Ameur; +Cc: u-boot, khilman, Keerthy
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]
On Thu, Sep 30, 2021 at 06:21:08PM +0200, Amjad Ouled-Ameur wrote:
> From: Keerthy <j-keerthy@ti.com>
>
> Add all the ipu early boot related nodes
>
> Signed-off-by: Keerthy <j-keerthy@ti.com>
> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
> ---
>
> (no changes since v1)
>
> MAINTAINERS | 1 +
> arch/arm/dts/dra7-ipu-common-early-boot.dtsi | 113 +++++++++++++++++++
> 2 files changed, 114 insertions(+)
> create mode 100644 arch/arm/dts/dra7-ipu-common-early-boot.dtsi
This causes my J6 Eco board:
CPU : DRA752-GP ES1.1
Model: TI DRA742
Board: DRA74x EVM REV G.0
to stop booting in SPL with no output.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes
2021-10-11 18:59 ` Tom Rini
@ 2022-01-05 11:42 ` Amjad Ouled-Ameur
0 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2022-01-05 11:42 UTC (permalink / raw)
To: Tom Rini; +Cc: u-boot, khilman, Keerthy
Hi Tom,
On 11/10/2021 20:59, Tom Rini wrote:
> On Thu, Sep 30, 2021 at 06:21:08PM +0200, Amjad Ouled-Ameur wrote:
>
>> From: Keerthy <j-keerthy@ti.com>
>>
>> Add all the ipu early boot related nodes
>>
>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
>> ---
>>
>> (no changes since v1)
>>
>> MAINTAINERS | 1 +
>> arch/arm/dts/dra7-ipu-common-early-boot.dtsi | 113 +++++++++++++++++++
>> 2 files changed, 114 insertions(+)
>> create mode 100644 arch/arm/dts/dra7-ipu-common-early-boot.dtsi
> This causes my J6 Eco board:
> CPU : DRA752-GP ES1.1
> Model: TI DRA742
> Board: DRA74x EVM REV G.0
> to stop booting in SPL with no output.
Thank you for reporting the issue.
After debugging the j6eco board, I realized that board stops booting
in SPL when new nodes with "u-boot,dm-spl;"property are added to the
DTS. The issue seems to be unrelated to this patchset but rather to a
SPL's DTS limitation on j6eco. I am currently looking into SPL's linker
file
and load addresses to understand better why SPL breaks.
Regards,
Amjad
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 08/10] arm: dts: dra7: Add ipu and related nodes
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (6 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 07/10] dts: dra7-ipu-common-early-boot.dtsi: Add all the ipu early boot related nodes Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 09/10] arm: dts: dra7*/am57xx-idk-evm-u-boot: Add ipu early boot DT changes Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 10/10] dts: am57xx*: " Amjad Ouled-Ameur
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur, Tom Rini
From: Keerthy <j-keerthy@ti.com>
Add ipu and the associated nodes.
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
arch/arm/dts/dra7.dtsi | 45 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi
index fd1aea0b1b16..e2e958b36626 100644
--- a/arch/arm/dts/dra7.dtsi
+++ b/arch/arm/dts/dra7.dtsi
@@ -41,6 +41,8 @@
d_can0 = &dcan1;
d_can1 = &dcan2;
spi0 = &qspi;
+ remoteproc0 = &ipu1;
+ remoteproc1 = &ipu2;
};
timer {
@@ -263,9 +265,12 @@
};
prm: prm@6000 {
- compatible = "ti,dra7-prm";
+ compatible = "ti,dra7-prm", "simple-bus";
reg = <0x6000 0x3000>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x6000 0x3000>;
prm_clocks: clocks {
#address-cells = <1>;
@@ -274,6 +279,20 @@
prm_clockdomains: clockdomains {
};
+
+ ipu1_rst: ipu1_rst@510 {
+ compatible = "ti,dra7-reset";
+ reg = <0x510 0x8>;
+ ti,nresets = <3>;
+ #reset-cells = <1>;
+ };
+
+ ipu2_rst: ipu2_rst@910 {
+ compatible = "ti,dra7-reset";
+ reg = <0x910 0x8>;
+ ti,nresets = <3>;
+ #reset-cells = <1>;
+ };
};
scm_wkup: scm_conf@c000 {
@@ -2032,6 +2051,30 @@
clocks = <&l3_iclk_div>;
clock-names = "fck";
};
+
+ ipu1: ipu@58820000 {
+ compatible = "ti,dra7-ipu";
+ reg = <0x58820000 0x10000>;
+ reg-names = "l2ram";
+ ti,hwmods = "ipu1";
+ resets = <&ipu1_rst 0>, <&ipu1_rst 1>, <&ipu1_rst 2>;
+ iommus = <&mmu_ipu1>;
+ ti,rproc-standby-info = <0x4a005520>;
+ timers = <&timer11>;
+ watchdog-timers = <&timer7>, <&timer8>;
+ };
+
+ ipu2: ipu@55020000 {
+ compatible = "ti,dra7-ipu";
+ reg = <0x55020000 0x10000>;
+ reg-names = "l2ram";
+ ti,hwmods = "ipu2";
+ resets = <&ipu2_rst 0>, <&ipu2_rst 1>, <&ipu2_rst 2>;
+ iommus = <&mmu_ipu2>;
+ ti,rproc-standby-info = <0x4a008920>;
+ timers = <&timer3>;
+ watchdog-timers = <&timer4>, <&timer9>;
+ };
};
thermal_zones: thermal-zones {
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 09/10] arm: dts: dra7*/am57xx-idk-evm-u-boot: Add ipu early boot DT changes
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (7 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 08/10] arm: dts: dra7: Add ipu and " Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
2021-09-30 16:21 ` [PATCH v2 10/10] dts: am57xx*: " Amjad Ouled-Ameur
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur, Tom Rini
From: Keerthy <j-keerthy@ti.com>
Add support for ipu early boot.
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
arch/arm/dts/am57xx-idk-common-u-boot.dtsi | 1 +
arch/arm/dts/dra7-evm-u-boot.dtsi | 1 +
arch/arm/dts/dra71-evm-u-boot.dtsi | 1 +
arch/arm/dts/dra72-evm-revc-u-boot.dtsi | 1 +
arch/arm/dts/dra76-evm-u-boot.dtsi | 1 +
5 files changed, 5 insertions(+)
diff --git a/arch/arm/dts/am57xx-idk-common-u-boot.dtsi b/arch/arm/dts/am57xx-idk-common-u-boot.dtsi
index b07aea0048d5..d0ce469f9189 100644
--- a/arch/arm/dts/am57xx-idk-common-u-boot.dtsi
+++ b/arch/arm/dts/am57xx-idk-common-u-boot.dtsi
@@ -3,6 +3,7 @@
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
/ {
xtal25mhz: xtal25mhz {
diff --git a/arch/arm/dts/dra7-evm-u-boot.dtsi b/arch/arm/dts/dra7-evm-u-boot.dtsi
index f06c701dbd1f..5622512b2401 100644
--- a/arch/arm/dts/dra7-evm-u-boot.dtsi
+++ b/arch/arm/dts/dra7-evm-u-boot.dtsi
@@ -4,6 +4,7 @@
*/
#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
&pcf_gpio_21{
u-boot,i2c-offset-len = <0>;
diff --git a/arch/arm/dts/dra71-evm-u-boot.dtsi b/arch/arm/dts/dra71-evm-u-boot.dtsi
index b56d4fc9d896..40443da5c855 100644
--- a/arch/arm/dts/dra71-evm-u-boot.dtsi
+++ b/arch/arm/dts/dra71-evm-u-boot.dtsi
@@ -4,6 +4,7 @@
*/
#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
&pcf_gpio_21{
u-boot,i2c-offset-len = <0>;
diff --git a/arch/arm/dts/dra72-evm-revc-u-boot.dtsi b/arch/arm/dts/dra72-evm-revc-u-boot.dtsi
index b56d4fc9d896..40443da5c855 100644
--- a/arch/arm/dts/dra72-evm-revc-u-boot.dtsi
+++ b/arch/arm/dts/dra72-evm-revc-u-boot.dtsi
@@ -4,6 +4,7 @@
*/
#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
&pcf_gpio_21{
u-boot,i2c-offset-len = <0>;
diff --git a/arch/arm/dts/dra76-evm-u-boot.dtsi b/arch/arm/dts/dra76-evm-u-boot.dtsi
index a4dfbe7e601a..5fae6ba91936 100644
--- a/arch/arm/dts/dra76-evm-u-boot.dtsi
+++ b/arch/arm/dts/dra76-evm-u-boot.dtsi
@@ -4,6 +4,7 @@
*/
#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
&cpsw_emac0 {
phy-handle = <&dp83867_0>;
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 10/10] dts: am57xx*: Add ipu early boot DT changes
2021-09-30 16:21 [PATCH v2 00/10] dra7: bring up and support IPU load/start Amjad Ouled-Ameur
` (8 preceding siblings ...)
2021-09-30 16:21 ` [PATCH v2 09/10] arm: dts: dra7*/am57xx-idk-evm-u-boot: Add ipu early boot DT changes Amjad Ouled-Ameur
@ 2021-09-30 16:21 ` Amjad Ouled-Ameur
9 siblings, 0 replies; 13+ messages in thread
From: Amjad Ouled-Ameur @ 2021-09-30 16:21 UTC (permalink / raw)
To: u-boot; +Cc: khilman, Keerthy, Amjad Ouled-Ameur
From: Keerthy <j-keerthy@ti.com>
Add support for ipu early boot.
Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
---
(no changes since v1)
MAINTAINERS | 1 +
arch/arm/dts/am57xx-beagle-x15-revb1-u-boot.dtsi | 7 +++++++
arch/arm/dts/am57xx-beagle-x15-revc-u-boot.dtsi | 7 +++++++
arch/arm/dts/am57xx-beagle-x15-u-boot.dtsi | 7 +++++++
arch/arm/dts/am57xx-cl-som-am57x-u-boot.dtsi | 7 +++++++
arch/arm/dts/am57xx-sbc-am57x-u-boot.dtsi | 7 +++++++
6 files changed, 36 insertions(+)
create mode 100644 arch/arm/dts/am57xx-beagle-x15-revb1-u-boot.dtsi
create mode 100644 arch/arm/dts/am57xx-beagle-x15-revc-u-boot.dtsi
create mode 100644 arch/arm/dts/am57xx-beagle-x15-u-boot.dtsi
create mode 100644 arch/arm/dts/am57xx-cl-som-am57x-u-boot.dtsi
create mode 100644 arch/arm/dts/am57xx-sbc-am57x-u-boot.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index ffaf2015ca5f..13c6c6e65915 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -493,6 +493,7 @@ F: arch/arm/mach-omap2/
F: arch/arm/include/asm/arch-omap*/
F: arch/arm/include/asm/ti-common/
F: arch/arm/dts/dra7*
+F: arch/arm/dts/am57xx*
F: board/ti/
F: drivers/dma/ti*
F: drivers/firmware/ti_sci.*
diff --git a/arch/arm/dts/am57xx-beagle-x15-revb1-u-boot.dtsi b/arch/arm/dts/am57xx-beagle-x15-revb1-u-boot.dtsi
new file mode 100644
index 000000000000..49b16215e528
--- /dev/null
+++ b/arch/arm/dts/am57xx-beagle-x15-revb1-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
diff --git a/arch/arm/dts/am57xx-beagle-x15-revc-u-boot.dtsi b/arch/arm/dts/am57xx-beagle-x15-revc-u-boot.dtsi
new file mode 100644
index 000000000000..49b16215e528
--- /dev/null
+++ b/arch/arm/dts/am57xx-beagle-x15-revc-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
diff --git a/arch/arm/dts/am57xx-beagle-x15-u-boot.dtsi b/arch/arm/dts/am57xx-beagle-x15-u-boot.dtsi
new file mode 100644
index 000000000000..49b16215e528
--- /dev/null
+++ b/arch/arm/dts/am57xx-beagle-x15-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
diff --git a/arch/arm/dts/am57xx-cl-som-am57x-u-boot.dtsi b/arch/arm/dts/am57xx-cl-som-am57x-u-boot.dtsi
new file mode 100644
index 000000000000..49b16215e528
--- /dev/null
+++ b/arch/arm/dts/am57xx-cl-som-am57x-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
diff --git a/arch/arm/dts/am57xx-sbc-am57x-u-boot.dtsi b/arch/arm/dts/am57xx-sbc-am57x-u-boot.dtsi
new file mode 100644
index 000000000000..49b16215e528
--- /dev/null
+++ b/arch/arm/dts/am57xx-sbc-am57x-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "omap5-u-boot.dtsi"
+#include "dra7-ipu-common-early-boot.dtsi"
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread