From patchwork Fri Aug 21 14:42:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grzegorz Jaszczyk X-Patchwork-Id: 248125 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:522:0:0:0:0 with SMTP id h2csp413116ils; Fri, 21 Aug 2020 07:44:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxmA+GzSGNEbzinzq+ExpM8Ad7ugs2Y97NsOlkjSTFiRXKMcFKvadwqHXXRR502ZT0bbOiJ X-Received: by 2002:aa7:de15:: with SMTP id h21mr3226403edv.23.1598021081062; Fri, 21 Aug 2020 07:44:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598021081; cv=none; d=google.com; s=arc-20160816; b=KwPf+YLTN8FyIeGWN5BlQG2qJo25xnixKPS/53TrHzumrvzxmIys5XQxic75hkZEQ7 Shws3BAZ3fG2lKXch73/R9fg5Ck1gwyT8+FghpwqPJteAXSa2E9OqkpWhQ2aA6SsKuLL +j0Rf2xcFeattAQS/Owbmfy+czFmTcM/KPnD9vQO1CeEFEygD28Cc+wgp2X54syihYFF vOufhsHGkc+X+BTn8sPTBh9nF8q4IDmz49tSOty7+mH2nNR1yo2MqiSt8HPEq5qqkH+r VhfMJ2FhqXc116o/BwVMu2O/wSvZjT9+HR5s3/CvlbuB5gsAUpSBAcq/gV2XtNBHGK1I ucmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=9m2MB1HdAM+HhlpLZuuBQdVjZ/8l/n1l2gHBVtQjwDo=; b=OizNPw3xj/PiTe8xALZ8W8p0lL/0Qr7Sz3D13kVDVzE0tZvYoW3TDAYH2KtEvahubw P8+BqowDFiTIjXN11DWOOprNgtyd84D1ZWtLFZ/QFOxp7D3kJ/vV1PzwiIZRQIvEyEyq YZqyaWn7SHZ0D2NgR49+7RXMJSLSt57GYnHKkvts9Men82fzxQcCNO4lRUbcXPRrgy9G a5ByoQMQHV50Q4+DhMSZaLj4lE+QKNY0kxYLoWWJtc2qGGGgWEmaDlk5JPjeLlTX611z azX6cK3G0L9IHoRsqfunN6NAOPN3NH5nuWQwTGA4/UsSre8SERiwn9UDrx9qeyq53Yft ky7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uakkZE7B; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q8si1293071ejm.507.2020.08.21.07.44.40; Fri, 21 Aug 2020 07:44:41 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uakkZE7B; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727945AbgHUOoh (ORCPT + 6 others); Fri, 21 Aug 2020 10:44:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726847AbgHUOo0 (ORCPT ); Fri, 21 Aug 2020 10:44:26 -0400 Received: from mail-lj1-x243.google.com (mail-lj1-x243.google.com [IPv6:2a00:1450:4864:20::243]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5630CC061574 for ; Fri, 21 Aug 2020 07:44:26 -0700 (PDT) Received: by mail-lj1-x243.google.com with SMTP id f26so2112787ljc.8 for ; Fri, 21 Aug 2020 07:44:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9m2MB1HdAM+HhlpLZuuBQdVjZ/8l/n1l2gHBVtQjwDo=; b=uakkZE7BhaDcwZlDuShp0vlXoDZ9XN+arg5WuVzEtVViMFuSA2z9yOaQlVmmwNfQJF uOSOygY9QYWcWvceVPNrSWVOMw5GhKF56FVz8aseRTATbXV02wbNLw4qHQuFtTXgU9xV fLrz/gdXN99Nte4wlmj6AM3qAypuJ8CsVXO7iTbYDzsMiYGRAShF+xi/SudqfqFKAEiB jfRtCBIaYJYEIsMibQhp2jghiX9sY4bOmArwNn5+VwHUWRlRW8NFT17iqXjX9tYKf3H1 5+nYSBb+2sX+qomKMuVH24PU3dY+Sj/fGgYQQDWRb05dERpTX0ECAnnvVH/cjXlAnW3f rvdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9m2MB1HdAM+HhlpLZuuBQdVjZ/8l/n1l2gHBVtQjwDo=; b=SpxY9TutZdpP25G7dH7XBTSbZFnB7yZl9TYDzvBTfpF3KzYDXkKb8uBofOjYOeGwdC vDXU/gWgZ6tom0G0BV0HQdt+5OhlLuEMnvL6RHeJ435HYn+bc36Qi1XkP25jHNtWSoD2 OhrVp00KJ0lm1QId4Ks5v7B8z9rqfwGIyVaAkYAiGU5n/wx3pMyM20D9BQ4bvSVF1TY5 A6G8YTfaMbwSPynws8IH7A/XtCWyzbdDrv2X/dgbsSuByj4pwC+ktZU88oHjcnfadmhO nuzhkQTu/JDWucvTHRKCczE3hXHMnlOuq7l0LJgr97LDMaKzsc1BQuJF7kpy36MfyZmF Gmow== X-Gm-Message-State: AOAM5315Ah+DlKI8V4c/G10OUNeW1CJY/2yS2ycczvQrEngzCpppZoO3 fsc3i26bnRGPgNK0iyS92O4par3wUjNj5w== X-Received: by 2002:a2e:99cc:: with SMTP id l12mr1582537ljj.235.1598021064408; Fri, 21 Aug 2020 07:44:24 -0700 (PDT) Received: from gilgamesh.semihalf.com (193-106-246-138.noc.fibertech.net.pl. [193.106.246.138]) by smtp.gmail.com with ESMTPSA id u10sm425301lfo.39.2020.08.21.07.44.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Aug 2020 07:44:23 -0700 (PDT) From: Grzegorz Jaszczyk To: ssantosh@kernel.org, s-anna@ti.com Cc: grzegorz.jaszczyk@linaro.org, santosh.shilimkar@oracle.com, robh+dt@kernel.org, lee.jones@linaro.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, praneeth@ti.com, tony@atomide.com, "Andrew F . Davis" , Tero Kristo Subject: [PATCH v2 2/7] soc: ti: pruss: Add a platform driver for PRUSS in TI SoCs Date: Fri, 21 Aug 2020 16:42:39 +0200 Message-Id: <1598020964-29877-3-git-send-email-grzegorz.jaszczyk@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1598020964-29877-1-git-send-email-grzegorz.jaszczyk@linaro.org> References: <1598020964-29877-1-git-send-email-grzegorz.jaszczyk@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Suman Anna The Programmable Real-Time Unit - Industrial Communication Subsystem (PRU-ICSS) is present on various TI SoCs such as AM335x or AM437x or the Keystone 66AK2G. Each SoC can have one or more PRUSS instances that may or may not be identical. For example, AM335x SoCs have a single PRUSS, while AM437x has two PRUSS instances PRUSS1 and PRUSS0, with the PRUSS0 being a cut-down version of the PRUSS1. The PRUSS consists of dual 32-bit RISC cores called the Programmable Real-Time Units (PRUs), some shared, data and instruction memories, some internal peripheral modules, and an interrupt controller. The programmable nature of the PRUs provide flexibility to implement custom peripheral interfaces, fast real-time responses, or specialized data handling. The PRU-ICSS functionality is achieved through three different platform drivers addressing a specific portion of the PRUSS. Some sub-modules of the PRU-ICSS IP reuse some of the existing drivers (like davinci mdio driver or the generic syscon driver). 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 PRUSS platform driver deals with the overall PRUSS and is used for managing the subsystem level resources like various memories and the CFG module. It is responsible for the creation and deletion of the platform devices for the child PRU devices and other child devices (like Interrupt Controller, MDIO node and some syscon nodes) so that they can be managed by specific platform drivers. The PRUSS interrupt controller is managed by an irqchip driver, while the individual PRU RISC cores are managed by a PRU remoteproc driver. The driver currently supports the AM335x SoC, and support for other TI SoCs will be added in subsequent patches. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Tero Kristo Signed-off-by: Grzegorz Jaszczyk --- v1->v2: - No changes. --- drivers/soc/ti/Kconfig | 11 ++++ drivers/soc/ti/Makefile | 1 + drivers/soc/ti/pruss.c | 147 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pruss_driver.h | 48 ++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 drivers/soc/ti/pruss.c create mode 100644 include/linux/pruss_driver.h -- 2.7.4 diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig index e192fb7..b934bc3 100644 --- a/drivers/soc/ti/Kconfig +++ b/drivers/soc/ti/Kconfig @@ -101,6 +101,17 @@ config TI_K3_SOCINFO platforms to provide information about the SoC family and variant to user space. +config TI_PRUSS + tristate "TI PRU-ICSS Subsystem Platform drivers" + depends on SOC_AM33XX + select MFD_SYSCON + help + TI PRU-ICSS Subsystem platform specific support. + + Say Y or M here to support the Programmable Realtime Unit (PRU) + processors on various TI SoCs. It's safe to say N here if you're + not interested in the PRU or if you are unsure. + endif # SOC_TI config TI_SCI_INTA_MSI_DOMAIN diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile index 1110e5c..18129aa 100644 --- a/drivers/soc/ti/Makefile +++ b/drivers/soc/ti/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN) += ti_sci_inta_msi.o obj-$(CONFIG_TI_K3_RINGACC) += k3-ringacc.o obj-$(CONFIG_TI_K3_SOCINFO) += k3-socinfo.o +obj-$(CONFIG_TI_PRUSS) += pruss.o diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c new file mode 100644 index 0000000..c071bb2 --- /dev/null +++ b/drivers/soc/ti/pruss.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PRU-ICSS platform driver for various TI SoCs + * + * Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/ + * Author(s): + * Suman Anna + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int pruss_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev_of_node(dev); + struct device_node *child; + struct pruss *pruss; + struct resource res; + int ret, i, index; + const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" }; + + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(dev, "failed to set the DMA coherent mask"); + return ret; + } + + pruss = devm_kzalloc(dev, sizeof(*pruss), GFP_KERNEL); + if (!pruss) + return -ENOMEM; + + pruss->dev = dev; + + child = of_get_child_by_name(np, "memories"); + if (!child) { + dev_err(dev, "%pOF is missing its 'memories' node\n", child); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(mem_names); i++) { + index = of_property_match_string(child, "reg-names", + mem_names[i]); + if (index < 0) { + of_node_put(child); + return index; + } + + if (of_address_to_resource(child, index, &res)) { + of_node_put(child); + 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(child); + 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(child); + + platform_set_drvdata(pdev, pruss); + + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "couldn't enable module\n"); + pm_runtime_put_noidle(dev); + goto rpm_disable; + } + + child = of_get_child_by_name(np, "cfg"); + if (!child) { + dev_err(dev, "%pOF is missing its 'cfg' node\n", child); + ret = -ENODEV; + goto rpm_put; + } + + pruss->cfg_regmap = syscon_node_to_regmap(child); + of_node_put(child); + if (IS_ERR(pruss->cfg_regmap)) { + ret = -ENODEV; + goto rpm_put; + } + + ret = devm_of_platform_populate(dev); + if (ret) { + dev_err(dev, "failed to register child devices\n"); + goto rpm_put; + } + + return 0; + +rpm_put: + pm_runtime_put_sync(dev); +rpm_disable: + pm_runtime_disable(dev); + return ret; +} + +static int pruss_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + devm_of_platform_depopulate(dev); + + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + + return 0; +} + +static const struct of_device_id pruss_of_match[] = { + { .compatible = "ti,am3356-pruss" }, + {}, +}; +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 "); +MODULE_DESCRIPTION("PRU-ICSS Subsystem Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h new file mode 100644 index 0000000..0701fe1 --- /dev/null +++ b/include/linux/pruss_driver.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * PRU-ICSS sub-system specific definitions + * + * Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/ + * Suman Anna + */ + +#ifndef _PRUSS_DRIVER_H_ +#define _PRUSS_DRIVER_H_ + +#include + +/* + * 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 + * @cfg_regmap: regmap for config region + * @mem_regions: data for each of the PRUSS memory regions + */ +struct pruss { + struct device *dev; + struct regmap *cfg_regmap; + struct pruss_mem_region mem_regions[PRUSS_MEM_MAX]; +}; + +#endif /* _PRUSS_DRIVER_H_ */