[U-Boot] [PATCH 04/10] soc: ti: pruss: Add support for am33xx

Greg Leonberg greg.leonberg at sunhillo.com
Wed Jul 27 21:27:51 CEST 2022


In order to support the am33xx pruss, the KConfig needed to have the
depends updated to support either ARCH_K3 or ARCH_OMAP2PLUS. The
Makefile needed to be tweaked because when building for am33xx, the
SPL will not fit into SRAM if the pruss driver is built into it.

Logic was added to the pruss driver to bring the pruss out of reset on
am33xx and enable the clock to it during the probe.

This patch depends on patch 0003 of this patch series.

Signed-off-by: Greg Leonberg <greg.leonberg at sunhillo.com>
---
 drivers/soc/ti/Kconfig  | 10 +++---
 drivers/soc/ti/Makefile |  6 ++++
 drivers/soc/ti/pruss.c  | 84 +++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 86 insertions(+), 14 deletions(-)

diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 46e2d14..f8d448b 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -32,16 +32,16 @@ config TI_KEYSTONE_SERDES
 	 K2 platforms.
 
 config TI_PRUSS
-	bool "Support for TI's K3 based Pruss driver"
+	bool "Support for TI's Pruss driver"
 	depends on DM
-	depends on ARCH_K3
+	depends on ARCH_K3 || ARCH_OMAP2PLUS
 	depends on OF_CONTROL
 	depends on SYSCON
 	help
 
-	  Support for TI PRU-ICSSG subsystem.
+	  Support for TI PRU-ICSS(G) subsystem.
 
-          Currently supported on AM65xx SoCs Say Y here to support the
-	  Programmable Realtime Unit (PRU).
+	  Currently supported on AM65xx and AM33xx SoCs
+	  Say Y here to support the Programmable Realtime Unit (PRU).
 
 endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index 34f80aa..582c9ae 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -2,4 +2,10 @@
 
 obj-$(CONFIG_TI_K3_NAVSS_RINGACC)	+= k3-navss-ringacc.o
 obj-$(CONFIG_TI_KEYSTONE_SERDES)	+= keystone_serdes.o
+ifndef CONFIG_AM33XX
 obj-$(CONFIG_TI_PRUSS)	+= pruss.o
+else
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_TI_PRUSS)	+= pruss.o
+endif
+endif
\ No newline at end of file
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index cbd659a..f02efea 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dm/device.h>
 #include <dm/of_access.h>
 #include <errno.h>
 #include <clk.h>
@@ -17,10 +18,19 @@
 #include <asm/io.h>
 #include <power-domain.h>
 #include <ti-pruss.h>
+#ifdef CONFIG_AM33XX
+#include <asm/omap_common.h>
+#include <asm/arch-am33xx/clock.h>
+#include <asm/arch-am33xx/hardware_am33xx.h>
+#include <asm/arch-am33xx/cpu.h>
+#endif
 
 #define PRUSS_CFG_IEPCLK	0x30
 #define ICSSG_CFG_CORE_SYNC	0x3c
 
+#define SYSCFG_STANDBY_INIT	BIT(4)
+#define SYSCFG_SUB_MWAIT_READY	BIT(5)
+
 #define ICSSG_TASK_MGR_OFFSET	0x2a000
 
 /* PRUSS_IEPCLK register bits */
@@ -29,6 +39,14 @@
 /* ICSSG CORE_SYNC register bits */
 #define ICSSG_CORE_VBUSP_SYNC_EN		BIT(0)
 
+/**
+ * struct pruss_private_data - PRUSS driver private data
+ * @is_icssg: flag to indicate if icss is icss or icssg
+ */
+struct pruss_private_data {
+	bool is_icssg;
+};
+
 /*
  * pruss_request_tm_region() - Request pruss for task manager region
  * @dev:	corresponding k3 device
@@ -44,6 +62,9 @@ int pruss_request_tm_region(struct udevice *dev, phys_addr_t *loc)
 	if (!priv || !priv->mem_regions[PRUSS_MEM_DRAM0].pa)
 		return -EINVAL;
 
+	if (!device_is_compatible(dev, "ti,am654-icssg"))
+		return -1;
+
 	*loc = priv->mem_regions[PRUSS_MEM_DRAM0].pa + ICSSG_TASK_MGR_OFFSET;
 
 	return 0;
@@ -64,7 +85,7 @@ int pruss_request_tm_region(struct udevice *dev, phys_addr_t *loc)
  * error otherwise
  */
 int pruss_request_mem_region(struct udevice *dev, enum pruss_mem mem_id,
-			     struct pruss_mem_region *region)
+				struct pruss_mem_region *region)
 {
 	struct pruss *pruss;
 
@@ -96,7 +117,7 @@ int pruss_request_mem_region(struct udevice *dev, enum pruss_mem mem_id,
  * Returns 0 on success, an error code otherwise
  */
 int pruss_release_mem_region(struct udevice *dev,
-			     struct pruss_mem_region *region)
+				struct pruss_mem_region *region)
 {
 	int id;
 	struct pruss *pruss;
@@ -131,7 +152,7 @@ int pruss_release_mem_region(struct udevice *dev,
  * Returns 0 on success, or an error code otherwise
  */
 int pruss_cfg_update(struct udevice *dev, unsigned int reg,
-		     unsigned int mask, unsigned int val)
+			unsigned int mask, unsigned int val)
 {
 	struct pruss *pruss;
 
@@ -156,6 +177,16 @@ static int pruss_probe(struct udevice *dev)
 	struct udevice *syscon;
 	const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };
 	int i;
+	const struct pruss_private_data *data;
+#ifdef CONFIG_AM33XX
+	struct prm_per *prmper;
+#endif
+
+	data = (const struct pruss_private_data *)dev_get_driver_data(dev);
+	if (IS_ERR(data)) {
+		dev_err(dev, "missing private data\n");
+		return -ENODEV;
+	}
 
 	priv = dev_get_priv(dev);
 	node = dev_ofnode(dev);
@@ -163,14 +194,16 @@ static int pruss_probe(struct udevice *dev)
 	memories = ofnode_find_subnode(node, "memories");
 
 	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
-		idx = ofnode_stringlist_search(memories, "reg-names", mem_names[i]);
-		priv->mem_regions[i].pa = ofnode_get_addr_size_index(memories, idx,
-						       (u64 *)&priv->mem_regions[i].size);
+		idx = ofnode_stringlist_search(memories, "reg-names",
+					       mem_names[i]);
+		priv->mem_regions[i].pa = ofnode_get_addr_size_index(memories,
+								     idx,
+				(fdt_size_t *)(&priv->mem_regions[i].size));
 	}
 
 	sub_node = ofnode_find_subnode(node, "cfg");
 	ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, sub_node,
-					  &syscon);
+						&syscon);
 
 	priv->cfg = syscon_get_regmap(syscon);
 	if (IS_ERR(priv->cfg)) {
@@ -179,6 +212,27 @@ static int pruss_probe(struct udevice *dev)
 		return -ENODEV;
 	}
 
+#ifdef CONFIG_AM33XX
+	prmper = (struct prm_per *)PRM_PER;
+	writel(readl(&prmper->prm_per_rstctrl) | PRM_PER_RSTCTRL_RESET,
+	       &prmper->prm_per_rstctrl);
+	writel(readl(&prmper->prm_per_rstctrl) & ~PRM_PER_RSTCTRL_RESET,
+	       &prmper->prm_per_rstctrl);
+#endif
+
+	if (!data->is_icssg) {
+		u32 *const clk_domains[] = { 0 };
+		u32 *const clk_modules_specific_am33xx[] = {
+		#ifdef CONFIG_AM33XX
+			&(((struct cm_perpll *)CM_PER)->pruicssclkctrl),
+		#endif
+			0
+		};
+
+		do_enable_clocks(clk_domains, clk_modules_specific_am33xx, 1);
+		goto skip_coreclk_mux;
+	}
+
 	/*
 	 * The CORE block uses two multiplexers to allow software to
 	 * select one of three source clocks (ICSSGn_CORE_CLK, ICSSGn_ICLK or
@@ -192,19 +246,31 @@ static int pruss_probe(struct udevice *dev)
 				 ICSSG_CORE_VBUSP_SYNC_EN);
 	if (ret)
 		return ret;
+
 	ret = regmap_update_bits(priv->cfg, PRUSS_CFG_IEPCLK,
 				 PRUSS_IEPCLK_IEP_OCP_CLK_EN,
 				 PRUSS_IEPCLK_IEP_OCP_CLK_EN);
 	if (ret)
 		return ret;
 
+skip_coreclk_mux:
 	dev_dbg(dev, "pruss successfully probed %s\n", dev->name);
-
 	return 0;
 }
 
+static const struct pruss_private_data am33xx_priv_data = {
+	.is_icssg = false
+};
+
+static const struct pruss_private_data k2g_am65x_j7_priv_data = {
+	.is_icssg = true
+};
+
 static const struct udevice_id pruss_ids[] = {
-	{ .compatible = "ti,am654-icssg"},
+	{	.compatible = "ti,am654-icssg",
+		.data = (unsigned long)&k2g_am65x_j7_priv_data},
+	{	.compatible = "ti,am3356-pruss",
+		.data = (unsigned long)&am33xx_priv_data},
 	{}
 };
 
-- 
1.8.3.1



More information about the U-Boot mailing list