lkml.org 
[lkml]   [2020]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/6] soc: ti: pruss: Add support for PRU-ICSSs on AM437x SoCs
    Date
    From: Suman Anna <s-anna@ti.com>

    The AM437x SoCs have two different PRU-ICSS subsystems: PRU-ICSS1
    and a smaller PRU-ICSS0. Enhance the PRUSS platform driver to support
    both the PRU-ICSS sub-systems on these SoCs.

    The PRU-ICSS1 on AM437x is very similar to the PRU-ICSS on AM33xx
    except for few minor differences - increased Instruction RAM, increased
    Shared Data RAM2, and 1 less interrupt (PRUSS host interrupt 7 which is
    redirected to the other PRUSS) towards the MPU INTC. The PRU-ICSS0 is
    a cut-down version of the IP, with less DRAM per PRU, no Shared DRAM etc.
    It also does not have direct access to L3 bus regions, there is a single
    interface to L3 for both PRUSS0 and PRUSS1, and it would have to go
    through the PRUSS1's interface. The PRUSS_SYSCFG register is reserved on
    PRUSS0, so any external access requires the programming the corresponding
    PRUSS_SYSCFG register in PRUSS1. It does have its own dedicated I/O lines
    though. Note that this instance does not support any PRU Ethernet related
    use cases.

    The adaptation uses SoC-specific compatibles in the driver and uses
    a newly introduced pruss_match_private_data structure and the
    pruss_get_private_data() function to retrieve a PRUSS instance specific
    data using a device-name based lookup logic. The reset and the L3 external
    access are managed by the parent interconnect ti-sysc bus driver so that
    PRUSS1 and PRUSS0 can be independently supported.

    Signed-off-by: Suman Anna <s-anna@ti.com>
    Signed-off-by: Andrew F. Davis <afd@ti.com>
    Signed-off-by: Grzegorz Jaszczyk <grzegorz.jaszczyk@linaro.org>
    ---
    drivers/soc/ti/Kconfig | 2 +-
    drivers/soc/ti/pruss.c | 35 ++++++++++++++++++++++++++++++++++-
    2 files changed, 35 insertions(+), 2 deletions(-)

    diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
    index b934bc3..40d6a22 100644
    --- a/drivers/soc/ti/Kconfig
    +++ b/drivers/soc/ti/Kconfig
    @@ -103,7 +103,7 @@ config TI_K3_SOCINFO

    config TI_PRUSS
    tristate "TI PRU-ICSS Subsystem Platform drivers"
    - depends on SOC_AM33XX
    + depends on SOC_AM33XX || SOC_AM43XX
    select MFD_SYSCON
    help
    TI PRU-ICSS Subsystem platform specific support.
    diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
    index c071bb2..04938ba 100644
    --- a/drivers/soc/ti/pruss.c
    +++ b/drivers/soc/ti/pruss.c
    @@ -17,6 +17,14 @@
    #include <linux/pm_runtime.h>
    #include <linux/pruss_driver.h>

    +/**
    + * struct pruss_private_data - PRUSS driver private data
    + * @has_no_sharedram: flag to indicate the absence of PRUSS Shared Data RAM
    + */
    +struct pruss_private_data {
    + bool has_no_sharedram;
    +};
    +
    static int pruss_probe(struct platform_device *pdev)
    {
    struct device *dev = &pdev->dev;
    @@ -25,8 +33,15 @@ static int pruss_probe(struct platform_device *pdev)
    struct pruss *pruss;
    struct resource res;
    int ret, i, index;
    + const struct pruss_private_data *data;
    const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };

    + data = of_device_get_match_data(&pdev->dev);
    + if (IS_ERR(data)) {
    + dev_err(dev, "missing private data\n");
    + return -ENODEV;
    + }
    +
    ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
    if (ret) {
    dev_err(dev, "failed to set the DMA coherent mask");
    @@ -45,7 +60,14 @@ static int pruss_probe(struct platform_device *pdev)
    return -ENODEV;
    }

    - for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
    + for (i = 0; i < PRUSS_MEM_MAX; i++) {
    + /*
    + * On AM437x one of two PRUSS units don't contain Shared RAM,
    + * skip it
    + */
    + if (data && data->has_no_sharedram && i == PRUSS_MEM_SHRD_RAM2)
    + continue;
    +
    index = of_property_match_string(child, "reg-names",
    mem_names[i]);
    if (index < 0) {
    @@ -126,8 +148,19 @@ static int pruss_remove(struct platform_device *pdev)
    return 0;
    }

    +/* instance-specific driver private data */
    +static const struct pruss_private_data am437x_pruss1_data = {
    + .has_no_sharedram = false,
    +};
    +
    +static const struct pruss_private_data am437x_pruss0_data = {
    + .has_no_sharedram = true,
    +};
    +
    static const struct of_device_id pruss_of_match[] = {
    { .compatible = "ti,am3356-pruss" },
    + { .compatible = "ti,am4376-pruss0", .data = &am437x_pruss0_data, },
    + { .compatible = "ti,am4376-pruss1", .data = &am437x_pruss1_data, },
    {},
    };
    MODULE_DEVICE_TABLE(of, pruss_of_match);
    --
    2.7.4
    \
     
     \ /
      Last update: 2020-07-29 13:03    [W:2.306 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site