summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 492f8ff)
raw | patch | inline | side by side (parent: 492f8ff)
author | Suman Anna <s-anna@ti.com> | |
Fri, 15 Feb 2019 02:09:59 +0000 (20:09 -0600) | ||
committer | Suman Anna <s-anna@ti.com> | |
Sat, 23 Feb 2019 17:15:08 +0000 (11:15 -0600) |
The PRUSS platform driver deals with the overall PRUSS and is
used for managing the subsystem level resources like various
memories. It is responsible for the creation and deletion of
the platform devices for the child PRU devices and other child
devices (Interrupt Controller or MDIO node or some syscon nodes)
so that they can be managed by specific platform drivers.
This design provides flexibility in representing the different
modules of PRUSS accordingly, and at the same time allowing the
PRUSS driver to add some instance specific configuration within
an SoC.
The driver currently supports the AM335x SoC, and support for
other TI SoCs will be added in subsequent patches.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Andrew F. Davis <afd@ti.com>
used for managing the subsystem level resources like various
memories. It is responsible for the creation and deletion of
the platform devices for the child PRU devices and other child
devices (Interrupt Controller or MDIO node or some syscon nodes)
so that they can be managed by specific platform drivers.
This design provides flexibility in representing the different
modules of PRUSS accordingly, and at the same time allowing the
PRUSS driver to add some instance specific configuration within
an SoC.
The driver currently supports the AM335x SoC, and support for
other TI SoCs will be added in subsequent patches.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Andrew F. Davis <afd@ti.com>
drivers/soc/ti/Makefile | patch | blob | history | |
drivers/soc/ti/pruss.c | [new file with mode: 0644] | patch | blob |
include/linux/pruss_driver.h | [new file with mode: 0644] | patch | blob |
index ca6549e8d1883ee36ace9e68b442d343dd91affb..b69beb059b60721eeb219064754b67a0fe06dd95 100644 (file)
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
obj-$(CONFIG_AMX3_PM) += pm33xx.o
obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o
obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
-obj-$(CONFIG_TI_PRUSS) += pruss_soc_bus.o
+obj-$(CONFIG_TI_PRUSS) += pruss_soc_bus.o pruss.o
diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
--- /dev/null
+++ b/drivers/soc/ti/pruss.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PRU-ICSS platform driver for various TI SoCs
+ *
+ * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Suman Anna <s-anna@ti.com>
+ * Andrew F. Davis <afd@ti.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pruss_driver.h>
+
+static int pruss_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct device_node *np;
+ struct pruss *pruss;
+ struct resource res;
+ int ret, i, index;
+ const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };
+
+ if (!node) {
+ dev_err(dev, "Non-DT platform device not supported\n");
+ return -ENODEV;
+ }
+
+ ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(dev, "dma_set_coherent_mask: %d\n", ret);
+ return ret;
+ }
+
+ pruss = devm_kzalloc(dev, sizeof(*pruss), GFP_KERNEL);
+ if (!pruss)
+ return -ENOMEM;
+
+ pruss->dev = dev;
+
+ np = of_get_child_by_name(node, "memories");
+ if (!np) {
+ dev_err(dev, "%pOF is missing memories node\n", np);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
+ index = of_property_match_string(np, "reg-names", mem_names[i]);
+ if (index < 0) {
+ of_node_put(np);
+ return index;
+ }
+
+ if (of_address_to_resource(np, index, &res)) {
+ of_node_put(np);
+ return -EINVAL;
+ }
+
+ pruss->mem_regions[i].va = devm_ioremap(dev, res.start,
+ resource_size(&res));
+ if (!pruss->mem_regions[i].va) {
+ dev_err(dev, "failed to parse and map memory resource %d %s\n",
+ i, mem_names[i]);
+ of_node_put(np);
+ return -ENOMEM;
+ }
+ pruss->mem_regions[i].pa = res.start;
+ pruss->mem_regions[i].size = resource_size(&res);
+
+ dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n",
+ mem_names[i], &pruss->mem_regions[i].pa,
+ pruss->mem_regions[i].size, pruss->mem_regions[i].va);
+ }
+ of_node_put(np);
+
+ platform_set_drvdata(pdev, pruss);
+
+ dev_dbg(&pdev->dev, "creating PRU cores and other child platform devices\n");
+ ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ if (ret)
+ dev_err(dev, "of_platform_populate failed\n");
+
+ return ret;
+}
+
+static int pruss_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ dev_dbg(dev, "remove PRU cores and other child platform devices\n");
+ of_platform_depopulate(dev);
+
+ return 0;
+}
+
+static const struct of_device_id pruss_of_match[] = {
+ { .compatible = "ti,am3356-pruss", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, pruss_of_match);
+
+static struct platform_driver pruss_driver = {
+ .driver = {
+ .name = "pruss",
+ .of_match_table = pruss_of_match,
+ },
+ .probe = pruss_probe,
+ .remove = pruss_remove,
+};
+module_platform_driver(pruss_driver);
+
+MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
+MODULE_DESCRIPTION("PRU-ICSS Subsystem Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PRU-ICSS sub-system specific definitions
+ *
+ * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Suman Anna <s-anna@ti.com>
+ */
+
+#ifndef _PRUSS_DRIVER_H_
+#define _PRUSS_DRIVER_H_
+
+/**
+ * enum pruss_mem - PRUSS memory range identifiers
+ */
+enum pruss_mem {
+ PRUSS_MEM_DRAM0 = 0,
+ PRUSS_MEM_DRAM1,
+ PRUSS_MEM_SHRD_RAM2,
+ PRUSS_MEM_MAX,
+};
+
+/**
+ * struct pruss_mem_region - PRUSS memory region structure
+ * @va: kernel virtual address of the PRUSS memory region
+ * @pa: physical (bus) address of the PRUSS memory region
+ * @size: size of the PRUSS memory region
+ */
+struct pruss_mem_region {
+ void __iomem *va;
+ phys_addr_t pa;
+ size_t size;
+};
+
+/**
+ * struct pruss - PRUSS parent structure
+ * @dev: pruss device pointer
+ * @mem_regions: data for each of the PRUSS memory regions
+ */
+struct pruss {
+ struct device *dev;
+ struct pruss_mem_region mem_regions[PRUSS_MEM_MAX];
+};
+
+#endif /* _PRUSS_DRIVER_H_ */