]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/commitdiff
soc: ti: pruss: Add support for PRU-ICSS subsystems on 66AK2G SoC
authorSuman Anna <s-anna@ti.com>
Fri, 15 Feb 2019 18:38:35 +0000 (12:38 -0600)
committerSuman Anna <s-anna@ti.com>
Sun, 24 Feb 2019 01:20:49 +0000 (19:20 -0600)
The 66AK2G SoC supports two PRU-ICSS instances, named PRUSS0 and PRUSS1,
each of which has two PRU processor cores. The two PRU-ICSS instances
are identical to each other with few minor SoC integration differences,
and are very similar to the PRU-ICSS1 of AM57xx/AM43xx. The Shared Data
RAM size is larger and the number of interrupts coming into MPU INTC
is like the instances on AM437x. There are also few other differences
attributing to integration in Keystone architecture (like no SYSCFG
register or PRCM handshake protocols). Other IP level differences
include different constant table, differences in system event interrupt
input sources etc. They also do not have a programmable module reset
line like those present on AM33xx/AM43xx SoCs. The modules are reset
just like any other IP with the SoC's global cold/warm resets.

The existing PRUSS platform drivers have been enhanced to support
these 66AK2G PRU-ICSS instances through new 66AK2G specific compatibles
for properly probing and booting all the different PRU cores in each
PRU-ICSS processor subsystem. The SoC-level integration differences
are dealt with using match data within the PRUSS INTC and PRUSS SoC
bus drivers. A build dependency with ARCH_KEYSTONE is added to enable
the driver to be built in K2G-only configuration. The initial names
for the firmware images for each PRU core are retrieved from DT nodes,
and can be adjusted through sysfs if required.

Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/irqchip/irq-pruss-intc.c
drivers/remoteproc/pru_rproc.c
drivers/soc/ti/Kconfig
drivers/soc/ti/pruss.c
drivers/soc/ti/pruss_soc_bus.c

index 1ccae683a18cff939ff087169340463f377a7007..022b4cfa811a87e1b7a3188aa2dac2f10cac14b9 100644 (file)
@@ -600,6 +600,10 @@ static const struct pruss_intc_match_data am437x_pruss_intc_data = {
        .no_host7_intr = true,
 };
 
+static const struct pruss_intc_match_data k2g_pruss_intc_data = {
+       .no_host7_intr = true,
+};
+
 static const struct of_device_id pruss_intc_of_match[] = {
        {
                .compatible = "ti,am3356-pruss-intc",
@@ -613,6 +617,10 @@ static const struct of_device_id pruss_intc_of_match[] = {
                .compatible = "ti,am5728-pruss-intc",
                .data = NULL,
        },
+       {
+               .compatible = "ti,k2g-pruss-intc",
+               .data = &k2g_pruss_intc_data,
+       },
        { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, pruss_intc_of_match);
index 46c4dfec2f2d840252be706154a785e72e6be6fe..af53b975f7aa45e94d9699ce85f208383805fc10 100644 (file)
@@ -595,6 +595,7 @@ static const struct of_device_id pru_rproc_match[] = {
        { .compatible = "ti,am3356-pru", },
        { .compatible = "ti,am4376-pru", },
        { .compatible = "ti,am5728-pru", },
+       { .compatible = "ti,k2g-pru",    },
        {},
 };
 MODULE_DEVICE_TABLE(of, pru_rproc_match);
index db0177d5d69442caf3066ddec9aa57fe2a89b956..35574ecef8cae15b972a61d95842a885fff523f7 100644 (file)
@@ -86,7 +86,7 @@ config TI_SCI_PM_DOMAINS
 
 config TI_PRUSS
        tristate "TI PRU-ICSS Subsystem Platform drivers"
-       depends on SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX
+       depends on SOC_AM33XX || SOC_AM43XX || SOC_DRA7XX || ARCH_KEYSTONE
        select MFD_SYSCON
        help
          TI PRU-ICSS Subsystem platform specific support.
index f81b1612dde1e7220eb2750679ae313c8d3e70cd..656739b4a2042fb0e159d5b030dcaf7558104971 100644 (file)
@@ -203,6 +203,7 @@ static const struct of_device_id pruss_of_match[] = {
        { .compatible = "ti,am3356-pruss", .data = NULL, },
        { .compatible = "ti,am4376-pruss", .data = &am437x_match_data, },
        { .compatible = "ti,am5728-pruss", .data = NULL, },
+       { .compatible = "ti,k2g-pruss", .data = NULL, },
        { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, pruss_of_match);
index ff1e0d0f59efed3ae75e2fff94c39061242bc04d..89711993cdddcc0f9d6b79cc966ba8b3a90ee5dd 100644 (file)
  * @syscfg: kernel mapped address for SYSCFG register
  * @in_standby: flag for storing standby status
  * @has_reset: cached variable for storing global module reset flag
+ * @skip_syscfg: flag to indicate if PRCM master standby/slave idle is needed
  */
 struct pruss_soc_bus {
        void __iomem *syscfg;
        bool in_standby;
        bool has_reset;
+       bool skip_syscfg;
 };
 
 /**
  * struct pruss_soc_bus_match_data - PRUSS SoC bus driver match data
  * @has_reset: flag to indicate the presence of global module reset
+ * @uses_prcm: flag to indicate the usage of PRCM master standby/slave idle
+ *            protocol
  */
 struct pruss_soc_bus_match_data {
        bool has_reset;
+       bool uses_prcm;
 };
 
 static inline void pruss_soc_bus_rmw(void __iomem *reg, u32 mask, u32 set)
@@ -98,6 +103,9 @@ static int __maybe_unused pruss_soc_bus_suspend(struct device *dev)
        struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev);
        u32 syscfg_val;
 
+       if (psoc_bus->skip_syscfg)
+               return 0;
+
        syscfg_val = readl_relaxed(psoc_bus->syscfg);
        psoc_bus->in_standby = syscfg_val & SYSCFG_STANDBY_INIT;
 
@@ -116,7 +124,7 @@ static int __maybe_unused pruss_soc_bus_resume(struct device *dev)
        int ret = 0;
 
        /* re-enable OCP master ports/disable MStandby */
-       if (!psoc_bus->in_standby) {
+       if (!psoc_bus->skip_syscfg && !psoc_bus->in_standby) {
                ret = pruss_soc_bus_enable_ocp_master_ports(dev);
                if (ret)
                        dev_err(dev, "%s failed\n", __func__);
@@ -130,6 +138,9 @@ static void pruss_disable_module(struct device *dev)
 {
        struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev);
 
+       if (psoc_bus->skip_syscfg)
+               goto put_sync;
+
        /* configure Smart Standby */
        pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_MODE_MASK,
                          SYSCFG_STANDBY_MODE_SMART);
@@ -138,7 +149,8 @@ static void pruss_disable_module(struct device *dev)
        pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_INIT,
                          SYSCFG_STANDBY_INIT);
 
-       /* tell PRCM to initiate IDLE request */
+put_sync:
+       /* initiate IDLE request, disable clocks */
        pm_runtime_put_sync(dev);
 }
 
@@ -147,13 +159,16 @@ static int pruss_enable_module(struct device *dev)
        struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev);
        int ret;
 
-       /* tell PRCM to de-assert IDLE request */
+       /* enable clocks, de-assert IDLE request */
        ret = pm_runtime_get_sync(dev);
        if (ret < 0) {
                pm_runtime_put_noidle(dev);
                return ret;
        }
 
+       if (psoc_bus->skip_syscfg)
+               return ret;
+
        /* configure for Smart Idle & Smart Standby */
        pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_IDLE_MODE_MASK,
                          SYSCFG_IDLE_MODE_SMART);
@@ -192,6 +207,7 @@ static int pruss_soc_bus_probe(struct platform_device *pdev)
                return -ENODEV;
        }
        psoc_bus->has_reset = data->has_reset;
+       psoc_bus->skip_syscfg = !data->uses_prcm;
        platform_set_drvdata(pdev, psoc_bus);
 
        if (psoc_bus->has_reset) {
@@ -247,20 +263,29 @@ static int pruss_soc_bus_remove(struct platform_device *pdev)
 /* instance-specific driver private data */
 static const struct pruss_soc_bus_match_data am335x_data = {
        .has_reset = true,
+       .uses_prcm = true,
 };
 
 static const struct pruss_soc_bus_match_data am437x_data = {
        .has_reset = true,
+       .uses_prcm = true,
 };
 
 static const struct pruss_soc_bus_match_data am57xx_data = {
        .has_reset = false,
+       .uses_prcm = true,
+};
+
+static const struct pruss_soc_bus_match_data k2g_data = {
+       .has_reset = false,
+       .uses_prcm = false,
 };
 
 static const struct of_device_id pruss_soc_bus_of_match[] = {
        { .compatible = "ti,am3356-pruss-soc-bus", .data = &am335x_data, },
        { .compatible = "ti,am4376-pruss-soc-bus", .data = &am437x_data, },
        { .compatible = "ti,am5728-pruss-soc-bus", .data = &am57xx_data, },
+       { .compatible = "ti,k2g-pruss-soc-bus", .data = &k2g_data, },
        { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, pruss_soc_bus_of_match);