All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] remoteproc: Introducing Qualcomm SLPI rproc driver
@ 2017-01-12 13:53 Avaneesh Kumar Dwivedi
  2017-01-12 13:53 ` [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader Avaneesh Kumar Dwivedi
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Avaneesh Kumar Dwivedi @ 2017-01-12 13:53 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc,
	Avaneesh Kumar Dwivedi

SLPI is low pass sensor controller subsystem.
This patch has:
	1- slpi rproc driver source file.
	2- DT-Binding documentation
	3- slpi smp2p DT node 

This patch is tested on MSM8996 MTP platform with modification in regulator code.

Avaneesh Kumar Dwivedi (3):
  remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral
    loader.
  dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi
    subsystem.
  arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver.

 .../devicetree/bindings/remoteproc/qcom,slpi.txt   |  88 ++++
 arch/arm64/boot/dts/qcom/msm8996.dtsi              |  24 ++
 drivers/remoteproc/Kconfig                         |  12 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/qcom_slpi_pil.c                 | 445 +++++++++++++++++++++
 5 files changed, 570 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt
 create mode 100644 drivers/remoteproc/qcom_slpi_pil.c

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-12 13:53 [RFC 0/3] remoteproc: Introducing Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
@ 2017-01-12 13:53 ` Avaneesh Kumar Dwivedi
  2017-01-12 20:41   ` Sarangdhar Joshi
  2017-01-12 13:53 ` [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem Avaneesh Kumar Dwivedi
  2017-01-12 13:53 ` [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
  2 siblings, 1 reply; 13+ messages in thread
From: Avaneesh Kumar Dwivedi @ 2017-01-12 13:53 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc,
	Avaneesh Kumar Dwivedi

This patch is to load and boot slpi core on Qualcomm plateforms. It is
used for loading the firmware images of the subsystems into memory
and preparing the subsystem's processor to execute code.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 drivers/remoteproc/Kconfig         |  12 +
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/qcom_slpi_pil.c | 445 +++++++++++++++++++++++++++++++++++++
 3 files changed, 458 insertions(+)
 create mode 100644 drivers/remoteproc/qcom_slpi_pil.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 8f9cf0b..9622fb9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -95,6 +95,18 @@ config QCOM_Q6V5_PIL
 	  Say y here to support the Qualcomm Peripherial Image Loader for the
 	  Hexagon V5 based remote processors.
 
+config QCOM_SLPI_PIL
+	tristate "Qualcomm SLPI Peripheral Image Loader"
+	depends on OF && ARCH_QCOM
+	depends on QCOM_SMEM
+	depends on REMOTEPROC
+	select MFD_SYSCON
+	select QCOM_MDT_LOADER
+	select QCOM_SCM
+	help
+	  Say y here to support the TrustZone based Peripherial Image Loader
+	  for the Qualcomm Sensor remote processors.
+
 config QCOM_WCNSS_PIL
 	tristate "Qualcomm WCNSS Peripheral Image Loader"
 	depends on OF && ARCH_QCOM
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 0938ea3..16e742a 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
 obj-$(CONFIG_QCOM_ADSP_PIL)		+= qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_MDT_LOADER)		+= qcom_mdt_loader.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)		+= qcom_q6v5_pil.o
+obj-$(CONFIG_QCOM_SLPI_PIL)		+= qcom_slpi_pil.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)		+= qcom_wcnss_pil.o
 qcom_wcnss_pil-y			+= qcom_wcnss.o
 qcom_wcnss_pil-y			+= qcom_wcnss_iris.o
diff --git a/drivers/remoteproc/qcom_slpi_pil.c b/drivers/remoteproc/qcom_slpi_pil.c
new file mode 100644
index 0000000..106c617
--- /dev/null
+++ b/drivers/remoteproc/qcom_slpi_pil.c
@@ -0,0 +1,445 @@
+/*
+ * Qualcomm slpi Peripheral Image Loader for MSM8974 and MSM8996
+ *
+ * Copyright (C) 2016-2017, Linaro Ltd
+ * Copyright (C) 2014-2017, Sony Mobile Communications AB
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/qcom_scm.h>
+#include <linux/regulator/consumer.h>
+#include <linux/remoteproc.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/smem_state.h>
+
+#include "qcom_mdt_loader.h"
+#include "remoteproc_internal.h"
+
+#define SLPI_CRASH_REASON_SMEM		424
+#define SLPI_FIRMWARE_NAME		"slpi.mdt"
+#define SLPI_PAS_ID			12
+
+struct qcom_slpi {
+	struct device *dev;
+	struct rproc *rproc;
+
+	int wdog_irq;
+	int fatal_irq;
+	int ready_irq;
+	int handover_irq;
+	int stop_ack_irq;
+
+	struct qcom_smem_state *state;
+	unsigned int stop_bit;
+
+	struct clk *xo;
+	struct clk *aggre2_noc;
+	struct regulator *cx;
+	struct regulator *px;
+
+	struct completion start_done;
+	struct completion stop_done;
+
+	phys_addr_t mem_phys;
+	phys_addr_t mem_reloc;
+	void *mem_region;
+	size_t mem_size;
+};
+
+static int slpi_load(struct rproc *rproc, const struct firmware *fw)
+{
+	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
+	phys_addr_t fw_addr;
+	size_t fw_size;
+	bool relocate;
+	int ret;
+
+	ret = qcom_scm_pas_init_image(SLPI_PAS_ID, fw->data, fw->size);
+	if (ret) {
+		dev_err(&rproc->dev, "invalid firmware metadata\n");
+		return ret;
+	}
+	ret = qcom_mdt_parse(fw, &fw_addr, &fw_size, &relocate);
+	if (ret) {
+		dev_err(&rproc->dev, "failed to parse mdt header\n");
+		return ret;
+	}
+
+	if (relocate) {
+		slpi->mem_reloc = fw_addr;
+
+		ret = qcom_scm_pas_mem_setup(SLPI_PAS_ID,
+					slpi->mem_phys, fw_size);
+		if (ret) {
+			dev_err(&rproc->dev,
+				"unable to setup memory for image\n");
+			return ret;
+		}
+	}
+
+	return qcom_mdt_load(rproc, fw, rproc->firmware);
+}
+
+static const struct rproc_fw_ops slpi_fw_ops = {
+	.find_rsc_table = qcom_mdt_find_rsc_table,
+	.load = slpi_load,
+};
+
+static int slpi_start(struct rproc *rproc)
+{
+	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
+	int ret;
+
+	ret = clk_prepare_enable(slpi->xo);
+	if (ret)
+		return ret;
+	ret = clk_prepare_enable(slpi->aggre2_noc);
+	if (ret)
+		goto disable_xo;
+	ret = regulator_enable(slpi->cx);
+	if (ret)
+		goto disable_aggr2;
+	ret = regulator_enable(slpi->px);
+	if (ret)
+		goto disable_cx;
+	ret = qcom_scm_pas_auth_and_reset(SLPI_PAS_ID);
+	if (ret) {
+		dev_err(slpi->dev,
+			"failed to authenticate image and release reset\n");
+		goto disable_px;
+	}
+	ret = wait_for_completion_timeout(&slpi->start_done,
+					  msecs_to_jiffies(10000));
+	if (!ret) {
+		dev_err(slpi->dev, "start timed out\n");
+		qcom_scm_pas_shutdown(SLPI_PAS_ID);
+		ret = -ETIMEDOUT;
+		goto disable_px;
+	}
+	ret = 0;
+	return ret;
+disable_px:
+	regulator_disable(slpi->px);
+disable_cx:
+	regulator_disable(slpi->cx);
+disable_aggr2:
+	clk_disable_unprepare(slpi->xo);
+disable_xo:
+	clk_disable_unprepare(slpi->aggre2_noc);
+
+	return ret;
+}
+
+static int slpi_stop(struct rproc *rproc)
+{
+	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
+	int ret;
+
+	qcom_smem_state_update_bits(slpi->state,
+				    BIT(slpi->stop_bit),
+				    BIT(slpi->stop_bit));
+
+	ret = wait_for_completion_timeout(&slpi->stop_done,
+					  msecs_to_jiffies(5000));
+	if (ret == 0)
+		dev_err(slpi->dev, "timed out on wait\n");
+
+	qcom_smem_state_update_bits(slpi->state,
+				    BIT(slpi->stop_bit),
+				    0);
+
+	ret = qcom_scm_pas_shutdown(SLPI_PAS_ID);
+	if (ret)
+		dev_err(slpi->dev, "failed to shutdown: %d\n", ret);
+	return ret;
+}
+
+static void *slpi_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
+	int offset;
+
+	offset = da - slpi->mem_reloc;
+	if (offset < 0 || offset + len > slpi->mem_size)
+		return NULL;
+
+	return slpi->mem_region + offset;
+}
+
+static const struct rproc_ops slpi_ops = {
+	.start = slpi_start,
+	.stop = slpi_stop,
+	.da_to_va = slpi_da_to_va,
+};
+
+static irqreturn_t slpi_wdog_interrupt(int irq, void *dev)
+{
+	struct qcom_slpi *slpi = dev;
+
+	rproc_report_crash(slpi->rproc, RPROC_WATCHDOG);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t slpi_fatal_interrupt(int irq, void *dev)
+{
+	struct qcom_slpi *slpi = dev;
+	size_t len;
+	char *msg;
+
+	msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, SLPI_CRASH_REASON_SMEM, &len);
+	if (!IS_ERR(msg) && len > 0 && msg[0])
+		dev_err(slpi->dev, "fatal error received: %s\n", msg);
+
+	rproc_report_crash(slpi->rproc, RPROC_FATAL_ERROR);
+	if (!IS_ERR(msg))
+		msg[0] = '\0';
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t slpi_ready_interrupt(int irq, void *dev)
+{
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t slpi_handover_interrupt(int irq, void *dev)
+{
+	struct qcom_slpi *slpi = dev;
+
+	complete(&slpi->start_done);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t slpi_stop_ack_interrupt(int irq, void *dev)
+{
+	struct qcom_slpi *slpi = dev;
+
+	complete(&slpi->stop_done);
+	return IRQ_HANDLED;
+}
+
+static int slpi_init_clock(struct qcom_slpi *slpi)
+{
+	int ret;
+
+	slpi->xo  = devm_clk_get(slpi->dev, "xo");
+	if (IS_ERR(slpi->xo)) {
+		ret = PTR_ERR(slpi->xo);
+		if (ret != -EPROBE_DEFER)
+			dev_err(slpi->dev, "failed to get xo clock");
+		return ret;
+	}
+
+	slpi->aggre2_noc = devm_clk_get(slpi->dev, "aggre2");
+	if (IS_ERR(slpi->aggre2_noc)) {
+		ret = PTR_ERR(slpi->aggre2_noc);
+		if (ret != -EPROBE_DEFER)
+			dev_err(slpi->dev, "failed to get aggre2 clock");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int slpi_init_regulator(struct qcom_slpi *slpi)
+{
+	int ret;
+
+	slpi->cx = devm_regulator_get(slpi->dev, "vdd_cx");
+	if (IS_ERR(slpi->cx))
+		return PTR_ERR(slpi->cx);
+	ret = regulator_set_voltage(slpi->cx, 5, INT_MAX);
+	if (ret) {
+		dev_err(slpi->dev,
+			"Failed to request voltage(ret:%d)\n", ret);
+		return ret;
+	}
+
+	slpi->px = devm_regulator_get(slpi->dev, "vdd_px");
+	if (IS_ERR(slpi->px))
+		return PTR_ERR(slpi->px);
+
+	return 0;
+}
+
+static int slpi_request_irq(struct qcom_slpi *slpi,
+			     struct platform_device *pdev,
+			     const char *name,
+			     irq_handler_t thread_fn)
+{
+	int ret;
+
+	ret = platform_get_irq_byname(pdev, name);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no %s IRQ defined\n", name);
+		return ret;
+	}
+	ret = devm_request_threaded_irq(&pdev->dev, ret,
+					NULL, thread_fn,
+					IRQF_ONESHOT,
+					"slpi", slpi);
+	if (ret)
+		dev_err(&pdev->dev, "request %s IRQ failed\n", name);
+
+	return ret;
+}
+
+static int slpi_alloc_memory_region(struct qcom_slpi *slpi)
+{
+	struct device_node *node;
+	struct resource r;
+	int ret;
+
+	node = of_parse_phandle(slpi->dev->of_node, "memory-region", 0);
+	if (!node) {
+		dev_err(slpi->dev, "no memory-region specified\n");
+		return -EINVAL;
+	}
+
+	ret = of_address_to_resource(node, 0, &r);
+	if (ret)
+		return ret;
+
+	slpi->mem_phys = slpi->mem_reloc = r.start;
+	slpi->mem_size = resource_size(&r);
+	slpi->mem_region = devm_ioremap_wc(slpi->dev,
+				slpi->mem_phys, slpi->mem_size);
+	if (!slpi->mem_region) {
+		dev_err(slpi->dev, "unable to map memory region: %pa+%zx\n",
+			&r.start, slpi->mem_size);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int slpi_probe(struct platform_device *pdev)
+{
+	struct qcom_slpi *slpi;
+	struct rproc *rproc;
+	int ret;
+
+	if (!qcom_scm_is_available())
+		return -EPROBE_DEFER;
+
+	if (!qcom_scm_pas_supported(SLPI_PAS_ID)) {
+		dev_err(&pdev->dev, "PAS is not available for slpi\n");
+		return -ENXIO;
+	}
+	rproc = rproc_alloc(&pdev->dev, pdev->name, &slpi_ops,
+			    SLPI_FIRMWARE_NAME, sizeof(*slpi));
+	if (!rproc) {
+		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
+		return -ENOMEM;
+	}
+
+	rproc->fw_ops = &slpi_fw_ops;
+
+	slpi = (struct qcom_slpi *)rproc->priv;
+	slpi->dev = &pdev->dev;
+	slpi->rproc = rproc;
+	platform_set_drvdata(pdev, slpi);
+
+	init_completion(&slpi->start_done);
+	init_completion(&slpi->stop_done);
+
+	ret = slpi_alloc_memory_region(slpi);
+	if (ret)
+		goto free_rproc;
+
+	ret = slpi_init_clock(slpi);
+	if (ret)
+		goto free_rproc;
+
+	ret = slpi_init_regulator(slpi);
+	if (ret)
+		goto free_rproc;
+
+	ret = slpi_request_irq(slpi, pdev, "wdog", slpi_wdog_interrupt);
+	if (ret < 0)
+		goto free_rproc;
+	slpi->wdog_irq = ret;
+
+	ret = slpi_request_irq(slpi, pdev, "fatal", slpi_fatal_interrupt);
+	if (ret < 0)
+		goto free_rproc;
+	slpi->fatal_irq = ret;
+
+	ret = slpi_request_irq(slpi, pdev, "ready", slpi_ready_interrupt);
+	if (ret < 0)
+		goto free_rproc;
+	slpi->ready_irq = ret;
+
+	ret = slpi_request_irq(slpi, pdev, "handover", slpi_handover_interrupt);
+	if (ret < 0)
+		goto free_rproc;
+	slpi->handover_irq = ret;
+
+	ret = slpi_request_irq(slpi, pdev, "stop-ack", slpi_stop_ack_interrupt);
+	if (ret < 0)
+		goto free_rproc;
+	slpi->stop_ack_irq = ret;
+
+	slpi->state = qcom_smem_state_get(&pdev->dev, "stop",
+					  &slpi->stop_bit);
+	if (IS_ERR(slpi->state)) {
+		ret = PTR_ERR(slpi->state);
+		goto free_rproc;
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+
+	return ret;
+}
+
+static int slpi_remove(struct platform_device *pdev)
+{
+	struct qcom_slpi *slpi = platform_get_drvdata(pdev);
+
+	qcom_smem_state_put(slpi->state);
+	rproc_del(slpi->rproc);
+	rproc_put(slpi->rproc);
+
+	return 0;
+}
+
+static const struct of_device_id slpi_of_match[] = {
+	{ .compatible = "qcom,msm8996-slpi-pil" },
+	{ },
+};
+
+static struct platform_driver slpi_driver = {
+	.probe = slpi_probe,
+	.remove = slpi_remove,
+	.driver = {
+		.name = "qcom_slpi_pil",
+		.of_match_table = slpi_of_match,
+	},
+};
+
+module_platform_driver(slpi_driver);
+MODULE_DESCRIPTION("Qualcomm MSM8996 slpi Peripherial Image Loader");
+MODULE_LICENSE("GPL v2");
+
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem.
  2017-01-12 13:53 [RFC 0/3] remoteproc: Introducing Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
  2017-01-12 13:53 ` [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader Avaneesh Kumar Dwivedi
@ 2017-01-12 13:53 ` Avaneesh Kumar Dwivedi
  2017-01-12 18:39   ` Bjorn Andersson
  2017-01-12 13:53 ` [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
  2 siblings, 1 reply; 13+ messages in thread
From: Avaneesh Kumar Dwivedi @ 2017-01-12 13:53 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc,
	Avaneesh Kumar Dwivedi

This document defines the binding for a component that loads firmware
and control the life cycle of the Qualcomm slpi core.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 .../devicetree/bindings/remoteproc/qcom,slpi.txt   | 88 ++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt b/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt
new file mode 100644
index 0000000..51dc64f
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt
@@ -0,0 +1,88 @@
+Qualcomm SLPI Peripheral Image Loader
+
+This document defines the binding for a component that loads and boots firmware
+on the Qualcomm ADSP Hexagon core.
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: must be:
+		    "qcom,msm8996-adsp-pil"
+
+- interrupts-extended:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: must list the watchdog, fatal IRQs ready, handover and
+		    stop-ack IRQs
+
+- interrupt-names:
+	Usage: required
+	Value type: <stringlist>
+	Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+
+- clocks:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: reference to the xo and aggre2_noc clock to be held on behalf of the
+		    booting slpi core
+
+- clock-names:
+	Usage: required
+	Value type: <stringlist>
+	Definition: must be "xo" and "aggre2_noc"
+
+- cx-supply:
+- px-supply:
+	Usage: required
+	Value type: <phandle>
+	Definition: reference to the regulators to be held on behalf of the
+		    booting slpi core
+
+- memory-region:
+	Usage: required
+	Value type: <phandle>
+	Definition: reference to the reserved-memory for the SLPI
+
+- qcom,smem-states:
+	Usage: required
+	Value type: <phandle>
+	Definition: reference to the smem state for requesting the SLPI to
+		    shut down
+
+- qcom,smem-state-names:
+	Usage: required
+	Value type: <stringlist>
+	Definition: must be "stop"
+
+
+= EXAMPLE
+The following example describes the resources needed to boot control the
+SLPI, as it is found on MSM8996 boards.
+
+	adsp {
+		compatible = "qcom,msm8996-slpi-pil";
+
+		interrupts-extended = <&intc 0 390 IRQ_TYPE_EDGE_RISING>,
+				      <&slpi_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+				      <&slpi_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+				      <&slpi_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+				      <&slpi_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "wdog",
+				  "fatal",
+				  "ready",
+				  "handover",
+				  "stop-ack";
+
+		clocks = <&rpmcc MSM8996_RPM_SMD_XO_CLK_SRC>,
+				<&rpmcc MSM8996_RPM_SMD_AGGR2_NOC_CLK>;
+		clock-names = "xo",
+					"aggre2";
+
+		vdd_cx-supply = <&pm8994_l26_corner>;
+		vdd_px-supply = <&pm8994_lvs2>;
+
+		memory-region = <&slpi_region>;
+
+		qcom,smem-states = <&slpi_smp2p_out 0>;
+		qcom,smem-state-names = "stop";
+	};
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver.
  2017-01-12 13:53 [RFC 0/3] remoteproc: Introducing Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
  2017-01-12 13:53 ` [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader Avaneesh Kumar Dwivedi
  2017-01-12 13:53 ` [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem Avaneesh Kumar Dwivedi
@ 2017-01-12 13:53 ` Avaneesh Kumar Dwivedi
  2017-01-12 18:24   ` Bjorn Andersson
  2 siblings, 1 reply; 13+ messages in thread
From: Avaneesh Kumar Dwivedi @ 2017-01-12 13:53 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc,
	Avaneesh Kumar Dwivedi

Add SMP2P DT nodes required for Qualcomm SLPI Peripheral Image Loader.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 9d1d7ad..2457b20 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -541,5 +541,29 @@
 			#interrupt-cells = <2>;
 		};
 	};
+
+	smp2p-slpi {
+		compatible = "qcom,smp2p";
+		qcom,smem = <481>, <430>;
+
+		interrupts = <0 178 1>;
+
+		qcom,ipc = <&apcs 4 8>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <3>;
+
+		slpi_smp2p_in: slave-kernel {
+				qcom,entry-name = "slave-kernel";
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+		slpi_smp2p_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,state-cells = <1>;
+		};
+	};
+
 };
 #include "msm8996-pins.dtsi"
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver.
  2017-01-12 13:53 ` [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
@ 2017-01-12 18:24   ` Bjorn Andersson
  2017-01-16  6:03     ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Andersson @ 2017-01-12 18:24 UTC (permalink / raw)
  To: Avaneesh Kumar Dwivedi
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc

On Thu 12 Jan 05:53 PST 2017, Avaneesh Kumar Dwivedi wrote:
> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> index 9d1d7ad..2457b20 100644
> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> @@ -541,5 +541,29 @@
>  			#interrupt-cells = <2>;
>  		};
>  	};
> +
> +	smp2p-slpi {
> +		compatible = "qcom,smp2p";
> +		qcom,smem = <481>, <430>;
> +
> +		interrupts = <0 178 1>;

Please use <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;

> +
> +		qcom,ipc = <&apcs 4 8>;

Looking at qcom,smp2p-dsps downstream I get this to <&apcs 16 26>;

> +
> +		qcom,local-pid = <0>;
> +		qcom,remote-pid = <3>;
> +
> +		slpi_smp2p_in: slave-kernel {
> +				qcom,entry-name = "slave-kernel";
> +				interrupt-controller;
> +				#interrupt-cells = <2>;
> +			};

Please correct the indentation of this block.

> +
> +		slpi_smp2p_out: master-kernel {
> +			qcom,entry-name = "master-kernel";
> +			#qcom,state-cells = <1>;
> +		};
> +	};

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem.
  2017-01-12 13:53 ` [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem Avaneesh Kumar Dwivedi
@ 2017-01-12 18:39   ` Bjorn Andersson
  2017-01-16  6:01     ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Andersson @ 2017-01-12 18:39 UTC (permalink / raw)
  To: Avaneesh Kumar Dwivedi
  Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc

On Thu 12 Jan 05:53 PST 2017, Avaneesh Kumar Dwivedi wrote:

> This document defines the binding for a component that loads firmware
> and control the life cycle of the Qualcomm slpi core.

Rather than duplicating the adsp binding I think we should just amend
the adsp binding - and probably rename the file.

> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt b/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt
[..]
> += EXAMPLE
[..]
> +		clocks = <&rpmcc MSM8996_RPM_SMD_XO_CLK_SRC>,
> +				<&rpmcc MSM8996_RPM_SMD_AGGR2_NOC_CLK>;
> +		clock-names = "xo",
> +					"aggre2";
> +

I still haven't managed to acquire the block diagram for this chip and
we have ongoing msm_bus discussions, but I believe we want something
representing a bus to control this clock.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-12 13:53 ` [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader Avaneesh Kumar Dwivedi
@ 2017-01-12 20:41   ` Sarangdhar Joshi
  2017-01-16  5:15     ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 1 reply; 13+ messages in thread
From: Sarangdhar Joshi @ 2017-01-12 20:41 UTC (permalink / raw)
  To: Avaneesh Kumar Dwivedi, bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, linux-remoteproc

Hi Avaneesh,

On 01/12/2017 05:53 AM, Avaneesh Kumar Dwivedi wrote:
> This patch is to load and boot slpi core on Qualcomm plateforms. It is
> used for loading the firmware images of the subsystems into memory
> and preparing the subsystem's processor to execute code.

Can't we modify qcom_adsp_pil.c to use SLPI as well?

Thanks,
Sarang

>
> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
> ---
>  drivers/remoteproc/Kconfig         |  12 +
>  drivers/remoteproc/Makefile        |   1 +
>  drivers/remoteproc/qcom_slpi_pil.c | 445 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 458 insertions(+)
>  create mode 100644 drivers/remoteproc/qcom_slpi_pil.c
>
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 8f9cf0b..9622fb9 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -95,6 +95,18 @@ config QCOM_Q6V5_PIL
>  	  Say y here to support the Qualcomm Peripherial Image Loader for the
>  	  Hexagon V5 based remote processors.
>
> +config QCOM_SLPI_PIL
> +	tristate "Qualcomm SLPI Peripheral Image Loader"
> +	depends on OF && ARCH_QCOM
> +	depends on QCOM_SMEM
> +	depends on REMOTEPROC
> +	select MFD_SYSCON
> +	select QCOM_MDT_LOADER
> +	select QCOM_SCM
> +	help
> +	  Say y here to support the TrustZone based Peripherial Image Loader
> +	  for the Qualcomm Sensor remote processors.
> +
>  config QCOM_WCNSS_PIL
>  	tristate "Qualcomm WCNSS Peripheral Image Loader"
>  	depends on OF && ARCH_QCOM
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 0938ea3..16e742a 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
>  obj-$(CONFIG_QCOM_ADSP_PIL)		+= qcom_adsp_pil.o
>  obj-$(CONFIG_QCOM_MDT_LOADER)		+= qcom_mdt_loader.o
>  obj-$(CONFIG_QCOM_Q6V5_PIL)		+= qcom_q6v5_pil.o
> +obj-$(CONFIG_QCOM_SLPI_PIL)		+= qcom_slpi_pil.o
>  obj-$(CONFIG_QCOM_WCNSS_PIL)		+= qcom_wcnss_pil.o
>  qcom_wcnss_pil-y			+= qcom_wcnss.o
>  qcom_wcnss_pil-y			+= qcom_wcnss_iris.o
> diff --git a/drivers/remoteproc/qcom_slpi_pil.c b/drivers/remoteproc/qcom_slpi_pil.c
> new file mode 100644
> index 0000000..106c617
> --- /dev/null
> +++ b/drivers/remoteproc/qcom_slpi_pil.c
> @@ -0,0 +1,445 @@
> +/*
> + * Qualcomm slpi Peripheral Image Loader for MSM8974 and MSM8996
> + *
> + * Copyright (C) 2016-2017, Linaro Ltd
> + * Copyright (C) 2014-2017, Sony Mobile Communications AB
> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include <linux/clk.h>
> +#include <linux/firmware.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/qcom_scm.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/remoteproc.h>
> +#include <linux/soc/qcom/smem.h>
> +#include <linux/soc/qcom/smem_state.h>
> +
> +#include "qcom_mdt_loader.h"
> +#include "remoteproc_internal.h"
> +
> +#define SLPI_CRASH_REASON_SMEM		424
> +#define SLPI_FIRMWARE_NAME		"slpi.mdt"
> +#define SLPI_PAS_ID			12
> +
> +struct qcom_slpi {
> +	struct device *dev;
> +	struct rproc *rproc;
> +
> +	int wdog_irq;
> +	int fatal_irq;
> +	int ready_irq;
> +	int handover_irq;
> +	int stop_ack_irq;
> +
> +	struct qcom_smem_state *state;
> +	unsigned int stop_bit;
> +
> +	struct clk *xo;
> +	struct clk *aggre2_noc;
> +	struct regulator *cx;
> +	struct regulator *px;
> +
> +	struct completion start_done;
> +	struct completion stop_done;
> +
> +	phys_addr_t mem_phys;
> +	phys_addr_t mem_reloc;
> +	void *mem_region;
> +	size_t mem_size;
> +};
> +
> +static int slpi_load(struct rproc *rproc, const struct firmware *fw)
> +{
> +	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
> +	phys_addr_t fw_addr;
> +	size_t fw_size;
> +	bool relocate;
> +	int ret;
> +
> +	ret = qcom_scm_pas_init_image(SLPI_PAS_ID, fw->data, fw->size);
> +	if (ret) {
> +		dev_err(&rproc->dev, "invalid firmware metadata\n");
> +		return ret;
> +	}
> +	ret = qcom_mdt_parse(fw, &fw_addr, &fw_size, &relocate);
> +	if (ret) {
> +		dev_err(&rproc->dev, "failed to parse mdt header\n");
> +		return ret;
> +	}
> +
> +	if (relocate) {
> +		slpi->mem_reloc = fw_addr;
> +
> +		ret = qcom_scm_pas_mem_setup(SLPI_PAS_ID,
> +					slpi->mem_phys, fw_size);
> +		if (ret) {
> +			dev_err(&rproc->dev,
> +				"unable to setup memory for image\n");
> +			return ret;
> +		}
> +	}
> +
> +	return qcom_mdt_load(rproc, fw, rproc->firmware);
> +}
> +
> +static const struct rproc_fw_ops slpi_fw_ops = {
> +	.find_rsc_table = qcom_mdt_find_rsc_table,
> +	.load = slpi_load,
> +};
> +
> +static int slpi_start(struct rproc *rproc)
> +{
> +	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
> +	int ret;
> +
> +	ret = clk_prepare_enable(slpi->xo);
> +	if (ret)
> +		return ret;
> +	ret = clk_prepare_enable(slpi->aggre2_noc);
> +	if (ret)
> +		goto disable_xo;
> +	ret = regulator_enable(slpi->cx);
> +	if (ret)
> +		goto disable_aggr2;
> +	ret = regulator_enable(slpi->px);
> +	if (ret)
> +		goto disable_cx;
> +	ret = qcom_scm_pas_auth_and_reset(SLPI_PAS_ID);
> +	if (ret) {
> +		dev_err(slpi->dev,
> +			"failed to authenticate image and release reset\n");
> +		goto disable_px;
> +	}
> +	ret = wait_for_completion_timeout(&slpi->start_done,
> +					  msecs_to_jiffies(10000));
> +	if (!ret) {
> +		dev_err(slpi->dev, "start timed out\n");
> +		qcom_scm_pas_shutdown(SLPI_PAS_ID);
> +		ret = -ETIMEDOUT;
> +		goto disable_px;
> +	}
> +	ret = 0;
> +	return ret;
> +disable_px:
> +	regulator_disable(slpi->px);
> +disable_cx:
> +	regulator_disable(slpi->cx);
> +disable_aggr2:
> +	clk_disable_unprepare(slpi->xo);
> +disable_xo:
> +	clk_disable_unprepare(slpi->aggre2_noc);
> +
> +	return ret;
> +}
> +
> +static int slpi_stop(struct rproc *rproc)
> +{
> +	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
> +	int ret;
> +
> +	qcom_smem_state_update_bits(slpi->state,
> +				    BIT(slpi->stop_bit),
> +				    BIT(slpi->stop_bit));
> +
> +	ret = wait_for_completion_timeout(&slpi->stop_done,
> +					  msecs_to_jiffies(5000));
> +	if (ret == 0)
> +		dev_err(slpi->dev, "timed out on wait\n");
> +
> +	qcom_smem_state_update_bits(slpi->state,
> +				    BIT(slpi->stop_bit),
> +				    0);
> +
> +	ret = qcom_scm_pas_shutdown(SLPI_PAS_ID);
> +	if (ret)
> +		dev_err(slpi->dev, "failed to shutdown: %d\n", ret);
> +	return ret;
> +}
> +
> +static void *slpi_da_to_va(struct rproc *rproc, u64 da, int len)
> +{
> +	struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
> +	int offset;
> +
> +	offset = da - slpi->mem_reloc;
> +	if (offset < 0 || offset + len > slpi->mem_size)
> +		return NULL;
> +
> +	return slpi->mem_region + offset;
> +}
> +
> +static const struct rproc_ops slpi_ops = {
> +	.start = slpi_start,
> +	.stop = slpi_stop,
> +	.da_to_va = slpi_da_to_va,
> +};
> +
> +static irqreturn_t slpi_wdog_interrupt(int irq, void *dev)
> +{
> +	struct qcom_slpi *slpi = dev;
> +
> +	rproc_report_crash(slpi->rproc, RPROC_WATCHDOG);
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t slpi_fatal_interrupt(int irq, void *dev)
> +{
> +	struct qcom_slpi *slpi = dev;
> +	size_t len;
> +	char *msg;
> +
> +	msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, SLPI_CRASH_REASON_SMEM, &len);
> +	if (!IS_ERR(msg) && len > 0 && msg[0])
> +		dev_err(slpi->dev, "fatal error received: %s\n", msg);
> +
> +	rproc_report_crash(slpi->rproc, RPROC_FATAL_ERROR);
> +	if (!IS_ERR(msg))
> +		msg[0] = '\0';
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t slpi_ready_interrupt(int irq, void *dev)
> +{
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t slpi_handover_interrupt(int irq, void *dev)
> +{
> +	struct qcom_slpi *slpi = dev;
> +
> +	complete(&slpi->start_done);
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t slpi_stop_ack_interrupt(int irq, void *dev)
> +{
> +	struct qcom_slpi *slpi = dev;
> +
> +	complete(&slpi->stop_done);
> +	return IRQ_HANDLED;
> +}
> +
> +static int slpi_init_clock(struct qcom_slpi *slpi)
> +{
> +	int ret;
> +
> +	slpi->xo  = devm_clk_get(slpi->dev, "xo");
> +	if (IS_ERR(slpi->xo)) {
> +		ret = PTR_ERR(slpi->xo);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(slpi->dev, "failed to get xo clock");
> +		return ret;
> +	}
> +
> +	slpi->aggre2_noc = devm_clk_get(slpi->dev, "aggre2");
> +	if (IS_ERR(slpi->aggre2_noc)) {
> +		ret = PTR_ERR(slpi->aggre2_noc);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(slpi->dev, "failed to get aggre2 clock");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int slpi_init_regulator(struct qcom_slpi *slpi)
> +{
> +	int ret;
> +
> +	slpi->cx = devm_regulator_get(slpi->dev, "vdd_cx");
> +	if (IS_ERR(slpi->cx))
> +		return PTR_ERR(slpi->cx);
> +	ret = regulator_set_voltage(slpi->cx, 5, INT_MAX);
> +	if (ret) {
> +		dev_err(slpi->dev,
> +			"Failed to request voltage(ret:%d)\n", ret);
> +		return ret;
> +	}
> +
> +	slpi->px = devm_regulator_get(slpi->dev, "vdd_px");
> +	if (IS_ERR(slpi->px))
> +		return PTR_ERR(slpi->px);
> +
> +	return 0;
> +}
> +
> +static int slpi_request_irq(struct qcom_slpi *slpi,
> +			     struct platform_device *pdev,
> +			     const char *name,
> +			     irq_handler_t thread_fn)
> +{
> +	int ret;
> +
> +	ret = platform_get_irq_byname(pdev, name);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "no %s IRQ defined\n", name);
> +		return ret;
> +	}
> +	ret = devm_request_threaded_irq(&pdev->dev, ret,
> +					NULL, thread_fn,
> +					IRQF_ONESHOT,
> +					"slpi", slpi);
> +	if (ret)
> +		dev_err(&pdev->dev, "request %s IRQ failed\n", name);
> +
> +	return ret;
> +}
> +
> +static int slpi_alloc_memory_region(struct qcom_slpi *slpi)
> +{
> +	struct device_node *node;
> +	struct resource r;
> +	int ret;
> +
> +	node = of_parse_phandle(slpi->dev->of_node, "memory-region", 0);
> +	if (!node) {
> +		dev_err(slpi->dev, "no memory-region specified\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_address_to_resource(node, 0, &r);
> +	if (ret)
> +		return ret;
> +
> +	slpi->mem_phys = slpi->mem_reloc = r.start;
> +	slpi->mem_size = resource_size(&r);
> +	slpi->mem_region = devm_ioremap_wc(slpi->dev,
> +				slpi->mem_phys, slpi->mem_size);
> +	if (!slpi->mem_region) {
> +		dev_err(slpi->dev, "unable to map memory region: %pa+%zx\n",
> +			&r.start, slpi->mem_size);
> +		return -EBUSY;
> +	}
> +
> +	return 0;
> +}
> +
> +static int slpi_probe(struct platform_device *pdev)
> +{
> +	struct qcom_slpi *slpi;
> +	struct rproc *rproc;
> +	int ret;
> +
> +	if (!qcom_scm_is_available())
> +		return -EPROBE_DEFER;
> +
> +	if (!qcom_scm_pas_supported(SLPI_PAS_ID)) {
> +		dev_err(&pdev->dev, "PAS is not available for slpi\n");
> +		return -ENXIO;
> +	}
> +	rproc = rproc_alloc(&pdev->dev, pdev->name, &slpi_ops,
> +			    SLPI_FIRMWARE_NAME, sizeof(*slpi));
> +	if (!rproc) {
> +		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
> +		return -ENOMEM;
> +	}
> +
> +	rproc->fw_ops = &slpi_fw_ops;
> +
> +	slpi = (struct qcom_slpi *)rproc->priv;
> +	slpi->dev = &pdev->dev;
> +	slpi->rproc = rproc;
> +	platform_set_drvdata(pdev, slpi);
> +
> +	init_completion(&slpi->start_done);
> +	init_completion(&slpi->stop_done);
> +
> +	ret = slpi_alloc_memory_region(slpi);
> +	if (ret)
> +		goto free_rproc;
> +
> +	ret = slpi_init_clock(slpi);
> +	if (ret)
> +		goto free_rproc;
> +
> +	ret = slpi_init_regulator(slpi);
> +	if (ret)
> +		goto free_rproc;
> +
> +	ret = slpi_request_irq(slpi, pdev, "wdog", slpi_wdog_interrupt);
> +	if (ret < 0)
> +		goto free_rproc;
> +	slpi->wdog_irq = ret;
> +
> +	ret = slpi_request_irq(slpi, pdev, "fatal", slpi_fatal_interrupt);
> +	if (ret < 0)
> +		goto free_rproc;
> +	slpi->fatal_irq = ret;
> +
> +	ret = slpi_request_irq(slpi, pdev, "ready", slpi_ready_interrupt);
> +	if (ret < 0)
> +		goto free_rproc;
> +	slpi->ready_irq = ret;
> +
> +	ret = slpi_request_irq(slpi, pdev, "handover", slpi_handover_interrupt);
> +	if (ret < 0)
> +		goto free_rproc;
> +	slpi->handover_irq = ret;
> +
> +	ret = slpi_request_irq(slpi, pdev, "stop-ack", slpi_stop_ack_interrupt);
> +	if (ret < 0)
> +		goto free_rproc;
> +	slpi->stop_ack_irq = ret;
> +
> +	slpi->state = qcom_smem_state_get(&pdev->dev, "stop",
> +					  &slpi->stop_bit);
> +	if (IS_ERR(slpi->state)) {
> +		ret = PTR_ERR(slpi->state);
> +		goto free_rproc;
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret)
> +		goto free_rproc;
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_put(rproc);
> +
> +	return ret;
> +}
> +
> +static int slpi_remove(struct platform_device *pdev)
> +{
> +	struct qcom_slpi *slpi = platform_get_drvdata(pdev);
> +
> +	qcom_smem_state_put(slpi->state);
> +	rproc_del(slpi->rproc);
> +	rproc_put(slpi->rproc);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id slpi_of_match[] = {
> +	{ .compatible = "qcom,msm8996-slpi-pil" },
> +	{ },
> +};
> +
> +static struct platform_driver slpi_driver = {
> +	.probe = slpi_probe,
> +	.remove = slpi_remove,
> +	.driver = {
> +		.name = "qcom_slpi_pil",
> +		.of_match_table = slpi_of_match,
> +	},
> +};
> +
> +module_platform_driver(slpi_driver);
> +MODULE_DESCRIPTION("Qualcomm MSM8996 slpi Peripherial Image Loader");
> +MODULE_LICENSE("GPL v2");
> +
>


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-12 20:41   ` Sarangdhar Joshi
@ 2017-01-16  5:15     ` Dwivedi, Avaneesh Kumar (avani)
  2017-01-17 19:30       ` Sarangdhar Joshi
  2017-01-18 23:34       ` Bjorn Andersson
  0 siblings, 2 replies; 13+ messages in thread
From: Dwivedi, Avaneesh Kumar (avani) @ 2017-01-16  5:15 UTC (permalink / raw)
  To: Sarangdhar Joshi, bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, linux-remoteproc



On 1/13/2017 2:11 AM, Sarangdhar Joshi wrote:
> Hi Avaneesh,
>
> On 01/12/2017 05:53 AM, Avaneesh Kumar Dwivedi wrote:
>> This patch is to load and boot slpi core on Qualcomm plateforms. It is
>> used for loading the firmware images of the subsystems into memory
>> and preparing the subsystem's processor to execute code.
>
> Can't we modify qcom_adsp_pil.c to use SLPI as well?

clocks, regulators, PAS_ID, firmware name, crash reason smem id these 
are few driver specific resource/variable, if it is ok to initialize 
these variables  based on compatible string, i think we can have single 
driver for adsp and slpi. let me know your further comment.
>
> Thanks,
> Sarang
>
>>
>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>> ---
>>  drivers/remoteproc/Kconfig         |  12 +
>>  drivers/remoteproc/Makefile        |   1 +
>>  drivers/remoteproc/qcom_slpi_pil.c | 445 
>> +++++++++++++++++++++++++++++++++++++
>>  3 files changed, 458 insertions(+)
>>  create mode 100644 drivers/remoteproc/qcom_slpi_pil.c
>>
>> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
>> index 8f9cf0b..9622fb9 100644
>> --- a/drivers/remoteproc/Kconfig
>> +++ b/drivers/remoteproc/Kconfig
>> @@ -95,6 +95,18 @@ config QCOM_Q6V5_PIL
>>        Say y here to support the Qualcomm Peripherial Image Loader 
>> for the
>>        Hexagon V5 based remote processors.
>>
>> +config QCOM_SLPI_PIL
>> +    tristate "Qualcomm SLPI Peripheral Image Loader"
>> +    depends on OF && ARCH_QCOM
>> +    depends on QCOM_SMEM
>> +    depends on REMOTEPROC
>> +    select MFD_SYSCON
>> +    select QCOM_MDT_LOADER
>> +    select QCOM_SCM
>> +    help
>> +      Say y here to support the TrustZone based Peripherial Image 
>> Loader
>> +      for the Qualcomm Sensor remote processors.
>> +
>>  config QCOM_WCNSS_PIL
>>      tristate "Qualcomm WCNSS Peripheral Image Loader"
>>      depends on OF && ARCH_QCOM
>> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
>> index 0938ea3..16e742a 100644
>> --- a/drivers/remoteproc/Makefile
>> +++ b/drivers/remoteproc/Makefile
>> @@ -14,6 +14,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)        += 
>> da8xx_remoteproc.o
>>  obj-$(CONFIG_QCOM_ADSP_PIL)        += qcom_adsp_pil.o
>>  obj-$(CONFIG_QCOM_MDT_LOADER)        += qcom_mdt_loader.o
>>  obj-$(CONFIG_QCOM_Q6V5_PIL)        += qcom_q6v5_pil.o
>> +obj-$(CONFIG_QCOM_SLPI_PIL)        += qcom_slpi_pil.o
>>  obj-$(CONFIG_QCOM_WCNSS_PIL)        += qcom_wcnss_pil.o
>>  qcom_wcnss_pil-y            += qcom_wcnss.o
>>  qcom_wcnss_pil-y            += qcom_wcnss_iris.o
>> diff --git a/drivers/remoteproc/qcom_slpi_pil.c 
>> b/drivers/remoteproc/qcom_slpi_pil.c
>> new file mode 100644
>> index 0000000..106c617
>> --- /dev/null
>> +++ b/drivers/remoteproc/qcom_slpi_pil.c
>> @@ -0,0 +1,445 @@
>> +/*
>> + * Qualcomm slpi Peripheral Image Loader for MSM8974 and MSM8996
>> + *
>> + * Copyright (C) 2016-2017, Linaro Ltd
>> + * Copyright (C) 2014-2017, Sony Mobile Communications AB
>> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * version 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +#include <linux/clk.h>
>> +#include <linux/firmware.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/qcom_scm.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/remoteproc.h>
>> +#include <linux/soc/qcom/smem.h>
>> +#include <linux/soc/qcom/smem_state.h>
>> +
>> +#include "qcom_mdt_loader.h"
>> +#include "remoteproc_internal.h"
>> +
>> +#define SLPI_CRASH_REASON_SMEM        424
>> +#define SLPI_FIRMWARE_NAME        "slpi.mdt"
>> +#define SLPI_PAS_ID            12
>> +
>> +struct qcom_slpi {
>> +    struct device *dev;
>> +    struct rproc *rproc;
>> +
>> +    int wdog_irq;
>> +    int fatal_irq;
>> +    int ready_irq;
>> +    int handover_irq;
>> +    int stop_ack_irq;
>> +
>> +    struct qcom_smem_state *state;
>> +    unsigned int stop_bit;
>> +
>> +    struct clk *xo;
>> +    struct clk *aggre2_noc;
>> +    struct regulator *cx;
>> +    struct regulator *px;
>> +
>> +    struct completion start_done;
>> +    struct completion stop_done;
>> +
>> +    phys_addr_t mem_phys;
>> +    phys_addr_t mem_reloc;
>> +    void *mem_region;
>> +    size_t mem_size;
>> +};
>> +
>> +static int slpi_load(struct rproc *rproc, const struct firmware *fw)
>> +{
>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>> +    phys_addr_t fw_addr;
>> +    size_t fw_size;
>> +    bool relocate;
>> +    int ret;
>> +
>> +    ret = qcom_scm_pas_init_image(SLPI_PAS_ID, fw->data, fw->size);
>> +    if (ret) {
>> +        dev_err(&rproc->dev, "invalid firmware metadata\n");
>> +        return ret;
>> +    }
>> +    ret = qcom_mdt_parse(fw, &fw_addr, &fw_size, &relocate);
>> +    if (ret) {
>> +        dev_err(&rproc->dev, "failed to parse mdt header\n");
>> +        return ret;
>> +    }
>> +
>> +    if (relocate) {
>> +        slpi->mem_reloc = fw_addr;
>> +
>> +        ret = qcom_scm_pas_mem_setup(SLPI_PAS_ID,
>> +                    slpi->mem_phys, fw_size);
>> +        if (ret) {
>> +            dev_err(&rproc->dev,
>> +                "unable to setup memory for image\n");
>> +            return ret;
>> +        }
>> +    }
>> +
>> +    return qcom_mdt_load(rproc, fw, rproc->firmware);
>> +}
>> +
>> +static const struct rproc_fw_ops slpi_fw_ops = {
>> +    .find_rsc_table = qcom_mdt_find_rsc_table,
>> +    .load = slpi_load,
>> +};
>> +
>> +static int slpi_start(struct rproc *rproc)
>> +{
>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>> +    int ret;
>> +
>> +    ret = clk_prepare_enable(slpi->xo);
>> +    if (ret)
>> +        return ret;
>> +    ret = clk_prepare_enable(slpi->aggre2_noc);
>> +    if (ret)
>> +        goto disable_xo;
>> +    ret = regulator_enable(slpi->cx);
>> +    if (ret)
>> +        goto disable_aggr2;
>> +    ret = regulator_enable(slpi->px);
>> +    if (ret)
>> +        goto disable_cx;
>> +    ret = qcom_scm_pas_auth_and_reset(SLPI_PAS_ID);
>> +    if (ret) {
>> +        dev_err(slpi->dev,
>> +            "failed to authenticate image and release reset\n");
>> +        goto disable_px;
>> +    }
>> +    ret = wait_for_completion_timeout(&slpi->start_done,
>> +                      msecs_to_jiffies(10000));
>> +    if (!ret) {
>> +        dev_err(slpi->dev, "start timed out\n");
>> +        qcom_scm_pas_shutdown(SLPI_PAS_ID);
>> +        ret = -ETIMEDOUT;
>> +        goto disable_px;
>> +    }
>> +    ret = 0;
>> +    return ret;
>> +disable_px:
>> +    regulator_disable(slpi->px);
>> +disable_cx:
>> +    regulator_disable(slpi->cx);
>> +disable_aggr2:
>> +    clk_disable_unprepare(slpi->xo);
>> +disable_xo:
>> +    clk_disable_unprepare(slpi->aggre2_noc);
>> +
>> +    return ret;
>> +}
>> +
>> +static int slpi_stop(struct rproc *rproc)
>> +{
>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>> +    int ret;
>> +
>> +    qcom_smem_state_update_bits(slpi->state,
>> +                    BIT(slpi->stop_bit),
>> +                    BIT(slpi->stop_bit));
>> +
>> +    ret = wait_for_completion_timeout(&slpi->stop_done,
>> +                      msecs_to_jiffies(5000));
>> +    if (ret == 0)
>> +        dev_err(slpi->dev, "timed out on wait\n");
>> +
>> +    qcom_smem_state_update_bits(slpi->state,
>> +                    BIT(slpi->stop_bit),
>> +                    0);
>> +
>> +    ret = qcom_scm_pas_shutdown(SLPI_PAS_ID);
>> +    if (ret)
>> +        dev_err(slpi->dev, "failed to shutdown: %d\n", ret);
>> +    return ret;
>> +}
>> +
>> +static void *slpi_da_to_va(struct rproc *rproc, u64 da, int len)
>> +{
>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>> +    int offset;
>> +
>> +    offset = da - slpi->mem_reloc;
>> +    if (offset < 0 || offset + len > slpi->mem_size)
>> +        return NULL;
>> +
>> +    return slpi->mem_region + offset;
>> +}
>> +
>> +static const struct rproc_ops slpi_ops = {
>> +    .start = slpi_start,
>> +    .stop = slpi_stop,
>> +    .da_to_va = slpi_da_to_va,
>> +};
>> +
>> +static irqreturn_t slpi_wdog_interrupt(int irq, void *dev)
>> +{
>> +    struct qcom_slpi *slpi = dev;
>> +
>> +    rproc_report_crash(slpi->rproc, RPROC_WATCHDOG);
>> +    return IRQ_HANDLED;
>> +}
>> +
>> +static irqreturn_t slpi_fatal_interrupt(int irq, void *dev)
>> +{
>> +    struct qcom_slpi *slpi = dev;
>> +    size_t len;
>> +    char *msg;
>> +
>> +    msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, SLPI_CRASH_REASON_SMEM, 
>> &len);
>> +    if (!IS_ERR(msg) && len > 0 && msg[0])
>> +        dev_err(slpi->dev, "fatal error received: %s\n", msg);
>> +
>> +    rproc_report_crash(slpi->rproc, RPROC_FATAL_ERROR);
>> +    if (!IS_ERR(msg))
>> +        msg[0] = '\0';
>> +    return IRQ_HANDLED;
>> +}
>> +
>> +static irqreturn_t slpi_ready_interrupt(int irq, void *dev)
>> +{
>> +    return IRQ_HANDLED;
>> +}
>> +
>> +static irqreturn_t slpi_handover_interrupt(int irq, void *dev)
>> +{
>> +    struct qcom_slpi *slpi = dev;
>> +
>> +    complete(&slpi->start_done);
>> +    return IRQ_HANDLED;
>> +}
>> +
>> +static irqreturn_t slpi_stop_ack_interrupt(int irq, void *dev)
>> +{
>> +    struct qcom_slpi *slpi = dev;
>> +
>> +    complete(&slpi->stop_done);
>> +    return IRQ_HANDLED;
>> +}
>> +
>> +static int slpi_init_clock(struct qcom_slpi *slpi)
>> +{
>> +    int ret;
>> +
>> +    slpi->xo  = devm_clk_get(slpi->dev, "xo");
>> +    if (IS_ERR(slpi->xo)) {
>> +        ret = PTR_ERR(slpi->xo);
>> +        if (ret != -EPROBE_DEFER)
>> +            dev_err(slpi->dev, "failed to get xo clock");
>> +        return ret;
>> +    }
>> +
>> +    slpi->aggre2_noc = devm_clk_get(slpi->dev, "aggre2");
>> +    if (IS_ERR(slpi->aggre2_noc)) {
>> +        ret = PTR_ERR(slpi->aggre2_noc);
>> +        if (ret != -EPROBE_DEFER)
>> +            dev_err(slpi->dev, "failed to get aggre2 clock");
>> +        return ret;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int slpi_init_regulator(struct qcom_slpi *slpi)
>> +{
>> +    int ret;
>> +
>> +    slpi->cx = devm_regulator_get(slpi->dev, "vdd_cx");
>> +    if (IS_ERR(slpi->cx))
>> +        return PTR_ERR(slpi->cx);
>> +    ret = regulator_set_voltage(slpi->cx, 5, INT_MAX);
>> +    if (ret) {
>> +        dev_err(slpi->dev,
>> +            "Failed to request voltage(ret:%d)\n", ret);
>> +        return ret;
>> +    }
>> +
>> +    slpi->px = devm_regulator_get(slpi->dev, "vdd_px");
>> +    if (IS_ERR(slpi->px))
>> +        return PTR_ERR(slpi->px);
>> +
>> +    return 0;
>> +}
>> +
>> +static int slpi_request_irq(struct qcom_slpi *slpi,
>> +                 struct platform_device *pdev,
>> +                 const char *name,
>> +                 irq_handler_t thread_fn)
>> +{
>> +    int ret;
>> +
>> +    ret = platform_get_irq_byname(pdev, name);
>> +    if (ret < 0) {
>> +        dev_err(&pdev->dev, "no %s IRQ defined\n", name);
>> +        return ret;
>> +    }
>> +    ret = devm_request_threaded_irq(&pdev->dev, ret,
>> +                    NULL, thread_fn,
>> +                    IRQF_ONESHOT,
>> +                    "slpi", slpi);
>> +    if (ret)
>> +        dev_err(&pdev->dev, "request %s IRQ failed\n", name);
>> +
>> +    return ret;
>> +}
>> +
>> +static int slpi_alloc_memory_region(struct qcom_slpi *slpi)
>> +{
>> +    struct device_node *node;
>> +    struct resource r;
>> +    int ret;
>> +
>> +    node = of_parse_phandle(slpi->dev->of_node, "memory-region", 0);
>> +    if (!node) {
>> +        dev_err(slpi->dev, "no memory-region specified\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    ret = of_address_to_resource(node, 0, &r);
>> +    if (ret)
>> +        return ret;
>> +
>> +    slpi->mem_phys = slpi->mem_reloc = r.start;
>> +    slpi->mem_size = resource_size(&r);
>> +    slpi->mem_region = devm_ioremap_wc(slpi->dev,
>> +                slpi->mem_phys, slpi->mem_size);
>> +    if (!slpi->mem_region) {
>> +        dev_err(slpi->dev, "unable to map memory region: %pa+%zx\n",
>> +            &r.start, slpi->mem_size);
>> +        return -EBUSY;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int slpi_probe(struct platform_device *pdev)
>> +{
>> +    struct qcom_slpi *slpi;
>> +    struct rproc *rproc;
>> +    int ret;
>> +
>> +    if (!qcom_scm_is_available())
>> +        return -EPROBE_DEFER;
>> +
>> +    if (!qcom_scm_pas_supported(SLPI_PAS_ID)) {
>> +        dev_err(&pdev->dev, "PAS is not available for slpi\n");
>> +        return -ENXIO;
>> +    }
>> +    rproc = rproc_alloc(&pdev->dev, pdev->name, &slpi_ops,
>> +                SLPI_FIRMWARE_NAME, sizeof(*slpi));
>> +    if (!rproc) {
>> +        dev_err(&pdev->dev, "unable to allocate remoteproc\n");
>> +        return -ENOMEM;
>> +    }
>> +
>> +    rproc->fw_ops = &slpi_fw_ops;
>> +
>> +    slpi = (struct qcom_slpi *)rproc->priv;
>> +    slpi->dev = &pdev->dev;
>> +    slpi->rproc = rproc;
>> +    platform_set_drvdata(pdev, slpi);
>> +
>> +    init_completion(&slpi->start_done);
>> +    init_completion(&slpi->stop_done);
>> +
>> +    ret = slpi_alloc_memory_region(slpi);
>> +    if (ret)
>> +        goto free_rproc;
>> +
>> +    ret = slpi_init_clock(slpi);
>> +    if (ret)
>> +        goto free_rproc;
>> +
>> +    ret = slpi_init_regulator(slpi);
>> +    if (ret)
>> +        goto free_rproc;
>> +
>> +    ret = slpi_request_irq(slpi, pdev, "wdog", slpi_wdog_interrupt);
>> +    if (ret < 0)
>> +        goto free_rproc;
>> +    slpi->wdog_irq = ret;
>> +
>> +    ret = slpi_request_irq(slpi, pdev, "fatal", slpi_fatal_interrupt);
>> +    if (ret < 0)
>> +        goto free_rproc;
>> +    slpi->fatal_irq = ret;
>> +
>> +    ret = slpi_request_irq(slpi, pdev, "ready", slpi_ready_interrupt);
>> +    if (ret < 0)
>> +        goto free_rproc;
>> +    slpi->ready_irq = ret;
>> +
>> +    ret = slpi_request_irq(slpi, pdev, "handover", 
>> slpi_handover_interrupt);
>> +    if (ret < 0)
>> +        goto free_rproc;
>> +    slpi->handover_irq = ret;
>> +
>> +    ret = slpi_request_irq(slpi, pdev, "stop-ack", 
>> slpi_stop_ack_interrupt);
>> +    if (ret < 0)
>> +        goto free_rproc;
>> +    slpi->stop_ack_irq = ret;
>> +
>> +    slpi->state = qcom_smem_state_get(&pdev->dev, "stop",
>> +                      &slpi->stop_bit);
>> +    if (IS_ERR(slpi->state)) {
>> +        ret = PTR_ERR(slpi->state);
>> +        goto free_rproc;
>> +    }
>> +
>> +    ret = rproc_add(rproc);
>> +    if (ret)
>> +        goto free_rproc;
>> +
>> +    return 0;
>> +
>> +free_rproc:
>> +    rproc_put(rproc);
>> +
>> +    return ret;
>> +}
>> +
>> +static int slpi_remove(struct platform_device *pdev)
>> +{
>> +    struct qcom_slpi *slpi = platform_get_drvdata(pdev);
>> +
>> +    qcom_smem_state_put(slpi->state);
>> +    rproc_del(slpi->rproc);
>> +    rproc_put(slpi->rproc);
>> +
>> +    return 0;
>> +}
>> +
>> +static const struct of_device_id slpi_of_match[] = {
>> +    { .compatible = "qcom,msm8996-slpi-pil" },
>> +    { },
>> +};
>> +
>> +static struct platform_driver slpi_driver = {
>> +    .probe = slpi_probe,
>> +    .remove = slpi_remove,
>> +    .driver = {
>> +        .name = "qcom_slpi_pil",
>> +        .of_match_table = slpi_of_match,
>> +    },
>> +};
>> +
>> +module_platform_driver(slpi_driver);
>> +MODULE_DESCRIPTION("Qualcomm MSM8996 slpi Peripherial Image Loader");
>> +MODULE_LICENSE("GPL v2");
>> +
>>
>
>

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem.
  2017-01-12 18:39   ` Bjorn Andersson
@ 2017-01-16  6:01     ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 0 replies; 13+ messages in thread
From: Dwivedi, Avaneesh Kumar (avani) @ 2017-01-16  6:01 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc



On 1/13/2017 12:09 AM, Bjorn Andersson wrote:
> On Thu 12 Jan 05:53 PST 2017, Avaneesh Kumar Dwivedi wrote:
>
>> This document defines the binding for a component that loads firmware
>> and control the life cycle of the Qualcomm slpi core.
> Rather than duplicating the adsp binding I think we should just amend
> the adsp binding - and probably rename the file.
Yes, missed to amend the mention of adsp core, some places.
>
>> diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt b/Documentation/devicetree/bindings/remoteproc/qcom,slpi.txt
> [..]
>> += EXAMPLE
> [..]
>> +		clocks = <&rpmcc MSM8996_RPM_SMD_XO_CLK_SRC>,
>> +				<&rpmcc MSM8996_RPM_SMD_AGGR2_NOC_CLK>;
>> +		clock-names = "xo",
>> +					"aggre2";
>> +
> I still haven't managed to acquire the block diagram for this chip and
> we have ongoing msm_bus discussions, but I believe we want something
> representing a bus to control this clock.
Do you mean any "NOC clock" need to be separately turned on by a bus 
driver not by the device driver itself?
>
> Regards,
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver.
  2017-01-12 18:24   ` Bjorn Andersson
@ 2017-01-16  6:03     ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 0 replies; 13+ messages in thread
From: Dwivedi, Avaneesh Kumar (avani) @ 2017-01-16  6:03 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: sboyd, agross, linux-arm-msm, spjoshi, linux-remoteproc



On 1/12/2017 11:54 PM, Bjorn Andersson wrote:
> On Thu 12 Jan 05:53 PST 2017, Avaneesh Kumar Dwivedi wrote:
>> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
>> index 9d1d7ad..2457b20 100644
>> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
>> @@ -541,5 +541,29 @@
>>   			#interrupt-cells = <2>;
>>   		};
>>   	};
>> +
>> +	smp2p-slpi {
>> +		compatible = "qcom,smp2p";
>> +		qcom,smem = <481>, <430>;
>> +
>> +		interrupts = <0 178 1>;
> Please use <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
OK,
>
>> +
>> +		qcom,ipc = <&apcs 4 8>;
> Looking at qcom,smp2p-dsps downstream I get this to <&apcs 16 26>;
I think i missed it, during validation it was working with <&apcs 4 8> 
and so did not realize to verify its validity.
will check and update.
>
>> +
>> +		qcom,local-pid = <0>;
>> +		qcom,remote-pid = <3>;
>> +
>> +		slpi_smp2p_in: slave-kernel {
>> +				qcom,entry-name = "slave-kernel";
>> +				interrupt-controller;
>> +				#interrupt-cells = <2>;
>> +			};
> Please correct the indentation of this block.
OK.
>
>> +
>> +		slpi_smp2p_out: master-kernel {
>> +			qcom,entry-name = "master-kernel";
>> +			#qcom,state-cells = <1>;
>> +		};
>> +	};
> Regards,
> Bjorn

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-16  5:15     ` Dwivedi, Avaneesh Kumar (avani)
@ 2017-01-17 19:30       ` Sarangdhar Joshi
  2017-01-18 23:34       ` Bjorn Andersson
  1 sibling, 0 replies; 13+ messages in thread
From: Sarangdhar Joshi @ 2017-01-17 19:30 UTC (permalink / raw)
  To: Dwivedi, Avaneesh Kumar (avani), bjorn.andersson
  Cc: sboyd, agross, linux-arm-msm, linux-remoteproc

On 01/15/2017 09:15 PM, Dwivedi, Avaneesh Kumar (avani) wrote:
>
>
> On 1/13/2017 2:11 AM, Sarangdhar Joshi wrote:
>> Hi Avaneesh,
>>
>> On 01/12/2017 05:53 AM, Avaneesh Kumar Dwivedi wrote:
>>> This patch is to load and boot slpi core on Qualcomm plateforms. It is
>>> used for loading the firmware images of the subsystems into memory
>>> and preparing the subsystem's processor to execute code.
>>
>> Can't we modify qcom_adsp_pil.c to use SLPI as well?
>
> clocks, regulators, PAS_ID, firmware name, crash reason smem id these
> are few driver specific resource/variable, if it is ok to initialize
> these variables  based on compatible string, i think we can have single
> driver for adsp and slpi. let me know your further comment.

Yes, single driver seems fine here.

Regards,
Sarang

>>
>> Thanks,
>> Sarang
>>
>>>
>>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>>> ---
>>>  drivers/remoteproc/Kconfig         |  12 +
>>>  drivers/remoteproc/Makefile        |   1 +
>>>  drivers/remoteproc/qcom_slpi_pil.c | 445
>>> +++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 458 insertions(+)
>>>  create mode 100644 drivers/remoteproc/qcom_slpi_pil.c
>>>
>>> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
>>> index 8f9cf0b..9622fb9 100644
>>> --- a/drivers/remoteproc/Kconfig
>>> +++ b/drivers/remoteproc/Kconfig
>>> @@ -95,6 +95,18 @@ config QCOM_Q6V5_PIL
>>>        Say y here to support the Qualcomm Peripherial Image Loader
>>> for the
>>>        Hexagon V5 based remote processors.
>>>
>>> +config QCOM_SLPI_PIL
>>> +    tristate "Qualcomm SLPI Peripheral Image Loader"
>>> +    depends on OF && ARCH_QCOM
>>> +    depends on QCOM_SMEM
>>> +    depends on REMOTEPROC
>>> +    select MFD_SYSCON
>>> +    select QCOM_MDT_LOADER
>>> +    select QCOM_SCM
>>> +    help
>>> +      Say y here to support the TrustZone based Peripherial Image
>>> Loader
>>> +      for the Qualcomm Sensor remote processors.
>>> +
>>>  config QCOM_WCNSS_PIL
>>>      tristate "Qualcomm WCNSS Peripheral Image Loader"
>>>      depends on OF && ARCH_QCOM
>>> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
>>> index 0938ea3..16e742a 100644
>>> --- a/drivers/remoteproc/Makefile
>>> +++ b/drivers/remoteproc/Makefile
>>> @@ -14,6 +14,7 @@ obj-$(CONFIG_DA8XX_REMOTEPROC)        +=
>>> da8xx_remoteproc.o
>>>  obj-$(CONFIG_QCOM_ADSP_PIL)        += qcom_adsp_pil.o
>>>  obj-$(CONFIG_QCOM_MDT_LOADER)        += qcom_mdt_loader.o
>>>  obj-$(CONFIG_QCOM_Q6V5_PIL)        += qcom_q6v5_pil.o
>>> +obj-$(CONFIG_QCOM_SLPI_PIL)        += qcom_slpi_pil.o
>>>  obj-$(CONFIG_QCOM_WCNSS_PIL)        += qcom_wcnss_pil.o
>>>  qcom_wcnss_pil-y            += qcom_wcnss.o
>>>  qcom_wcnss_pil-y            += qcom_wcnss_iris.o
>>> diff --git a/drivers/remoteproc/qcom_slpi_pil.c
>>> b/drivers/remoteproc/qcom_slpi_pil.c
>>> new file mode 100644
>>> index 0000000..106c617
>>> --- /dev/null
>>> +++ b/drivers/remoteproc/qcom_slpi_pil.c
>>> @@ -0,0 +1,445 @@
>>> +/*
>>> + * Qualcomm slpi Peripheral Image Loader for MSM8974 and MSM8996
>>> + *
>>> + * Copyright (C) 2016-2017, Linaro Ltd
>>> + * Copyright (C) 2014-2017, Sony Mobile Communications AB
>>> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * version 2 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + */
>>> +#include <linux/clk.h>
>>> +#include <linux/firmware.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of_address.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/qcom_scm.h>
>>> +#include <linux/regulator/consumer.h>
>>> +#include <linux/remoteproc.h>
>>> +#include <linux/soc/qcom/smem.h>
>>> +#include <linux/soc/qcom/smem_state.h>
>>> +
>>> +#include "qcom_mdt_loader.h"
>>> +#include "remoteproc_internal.h"
>>> +
>>> +#define SLPI_CRASH_REASON_SMEM        424
>>> +#define SLPI_FIRMWARE_NAME        "slpi.mdt"
>>> +#define SLPI_PAS_ID            12
>>> +
>>> +struct qcom_slpi {
>>> +    struct device *dev;
>>> +    struct rproc *rproc;
>>> +
>>> +    int wdog_irq;
>>> +    int fatal_irq;
>>> +    int ready_irq;
>>> +    int handover_irq;
>>> +    int stop_ack_irq;
>>> +
>>> +    struct qcom_smem_state *state;
>>> +    unsigned int stop_bit;
>>> +
>>> +    struct clk *xo;
>>> +    struct clk *aggre2_noc;
>>> +    struct regulator *cx;
>>> +    struct regulator *px;
>>> +
>>> +    struct completion start_done;
>>> +    struct completion stop_done;
>>> +
>>> +    phys_addr_t mem_phys;
>>> +    phys_addr_t mem_reloc;
>>> +    void *mem_region;
>>> +    size_t mem_size;
>>> +};
>>> +
>>> +static int slpi_load(struct rproc *rproc, const struct firmware *fw)
>>> +{
>>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>>> +    phys_addr_t fw_addr;
>>> +    size_t fw_size;
>>> +    bool relocate;
>>> +    int ret;
>>> +
>>> +    ret = qcom_scm_pas_init_image(SLPI_PAS_ID, fw->data, fw->size);
>>> +    if (ret) {
>>> +        dev_err(&rproc->dev, "invalid firmware metadata\n");
>>> +        return ret;
>>> +    }
>>> +    ret = qcom_mdt_parse(fw, &fw_addr, &fw_size, &relocate);
>>> +    if (ret) {
>>> +        dev_err(&rproc->dev, "failed to parse mdt header\n");
>>> +        return ret;
>>> +    }
>>> +
>>> +    if (relocate) {
>>> +        slpi->mem_reloc = fw_addr;
>>> +
>>> +        ret = qcom_scm_pas_mem_setup(SLPI_PAS_ID,
>>> +                    slpi->mem_phys, fw_size);
>>> +        if (ret) {
>>> +            dev_err(&rproc->dev,
>>> +                "unable to setup memory for image\n");
>>> +            return ret;
>>> +        }
>>> +    }
>>> +
>>> +    return qcom_mdt_load(rproc, fw, rproc->firmware);
>>> +}
>>> +
>>> +static const struct rproc_fw_ops slpi_fw_ops = {
>>> +    .find_rsc_table = qcom_mdt_find_rsc_table,
>>> +    .load = slpi_load,
>>> +};
>>> +
>>> +static int slpi_start(struct rproc *rproc)
>>> +{
>>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>>> +    int ret;
>>> +
>>> +    ret = clk_prepare_enable(slpi->xo);
>>> +    if (ret)
>>> +        return ret;
>>> +    ret = clk_prepare_enable(slpi->aggre2_noc);
>>> +    if (ret)
>>> +        goto disable_xo;
>>> +    ret = regulator_enable(slpi->cx);
>>> +    if (ret)
>>> +        goto disable_aggr2;
>>> +    ret = regulator_enable(slpi->px);
>>> +    if (ret)
>>> +        goto disable_cx;
>>> +    ret = qcom_scm_pas_auth_and_reset(SLPI_PAS_ID);
>>> +    if (ret) {
>>> +        dev_err(slpi->dev,
>>> +            "failed to authenticate image and release reset\n");
>>> +        goto disable_px;
>>> +    }
>>> +    ret = wait_for_completion_timeout(&slpi->start_done,
>>> +                      msecs_to_jiffies(10000));
>>> +    if (!ret) {
>>> +        dev_err(slpi->dev, "start timed out\n");
>>> +        qcom_scm_pas_shutdown(SLPI_PAS_ID);
>>> +        ret = -ETIMEDOUT;
>>> +        goto disable_px;
>>> +    }
>>> +    ret = 0;
>>> +    return ret;
>>> +disable_px:
>>> +    regulator_disable(slpi->px);
>>> +disable_cx:
>>> +    regulator_disable(slpi->cx);
>>> +disable_aggr2:
>>> +    clk_disable_unprepare(slpi->xo);
>>> +disable_xo:
>>> +    clk_disable_unprepare(slpi->aggre2_noc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int slpi_stop(struct rproc *rproc)
>>> +{
>>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>>> +    int ret;
>>> +
>>> +    qcom_smem_state_update_bits(slpi->state,
>>> +                    BIT(slpi->stop_bit),
>>> +                    BIT(slpi->stop_bit));
>>> +
>>> +    ret = wait_for_completion_timeout(&slpi->stop_done,
>>> +                      msecs_to_jiffies(5000));
>>> +    if (ret == 0)
>>> +        dev_err(slpi->dev, "timed out on wait\n");
>>> +
>>> +    qcom_smem_state_update_bits(slpi->state,
>>> +                    BIT(slpi->stop_bit),
>>> +                    0);
>>> +
>>> +    ret = qcom_scm_pas_shutdown(SLPI_PAS_ID);
>>> +    if (ret)
>>> +        dev_err(slpi->dev, "failed to shutdown: %d\n", ret);
>>> +    return ret;
>>> +}
>>> +
>>> +static void *slpi_da_to_va(struct rproc *rproc, u64 da, int len)
>>> +{
>>> +    struct qcom_slpi *slpi = (struct qcom_slpi *)rproc->priv;
>>> +    int offset;
>>> +
>>> +    offset = da - slpi->mem_reloc;
>>> +    if (offset < 0 || offset + len > slpi->mem_size)
>>> +        return NULL;
>>> +
>>> +    return slpi->mem_region + offset;
>>> +}
>>> +
>>> +static const struct rproc_ops slpi_ops = {
>>> +    .start = slpi_start,
>>> +    .stop = slpi_stop,
>>> +    .da_to_va = slpi_da_to_va,
>>> +};
>>> +
>>> +static irqreturn_t slpi_wdog_interrupt(int irq, void *dev)
>>> +{
>>> +    struct qcom_slpi *slpi = dev;
>>> +
>>> +    rproc_report_crash(slpi->rproc, RPROC_WATCHDOG);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static irqreturn_t slpi_fatal_interrupt(int irq, void *dev)
>>> +{
>>> +    struct qcom_slpi *slpi = dev;
>>> +    size_t len;
>>> +    char *msg;
>>> +
>>> +    msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, SLPI_CRASH_REASON_SMEM,
>>> &len);
>>> +    if (!IS_ERR(msg) && len > 0 && msg[0])
>>> +        dev_err(slpi->dev, "fatal error received: %s\n", msg);
>>> +
>>> +    rproc_report_crash(slpi->rproc, RPROC_FATAL_ERROR);
>>> +    if (!IS_ERR(msg))
>>> +        msg[0] = '\0';
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static irqreturn_t slpi_ready_interrupt(int irq, void *dev)
>>> +{
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static irqreturn_t slpi_handover_interrupt(int irq, void *dev)
>>> +{
>>> +    struct qcom_slpi *slpi = dev;
>>> +
>>> +    complete(&slpi->start_done);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static irqreturn_t slpi_stop_ack_interrupt(int irq, void *dev)
>>> +{
>>> +    struct qcom_slpi *slpi = dev;
>>> +
>>> +    complete(&slpi->stop_done);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int slpi_init_clock(struct qcom_slpi *slpi)
>>> +{
>>> +    int ret;
>>> +
>>> +    slpi->xo  = devm_clk_get(slpi->dev, "xo");
>>> +    if (IS_ERR(slpi->xo)) {
>>> +        ret = PTR_ERR(slpi->xo);
>>> +        if (ret != -EPROBE_DEFER)
>>> +            dev_err(slpi->dev, "failed to get xo clock");
>>> +        return ret;
>>> +    }
>>> +
>>> +    slpi->aggre2_noc = devm_clk_get(slpi->dev, "aggre2");
>>> +    if (IS_ERR(slpi->aggre2_noc)) {
>>> +        ret = PTR_ERR(slpi->aggre2_noc);
>>> +        if (ret != -EPROBE_DEFER)
>>> +            dev_err(slpi->dev, "failed to get aggre2 clock");
>>> +        return ret;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int slpi_init_regulator(struct qcom_slpi *slpi)
>>> +{
>>> +    int ret;
>>> +
>>> +    slpi->cx = devm_regulator_get(slpi->dev, "vdd_cx");
>>> +    if (IS_ERR(slpi->cx))
>>> +        return PTR_ERR(slpi->cx);
>>> +    ret = regulator_set_voltage(slpi->cx, 5, INT_MAX);
>>> +    if (ret) {
>>> +        dev_err(slpi->dev,
>>> +            "Failed to request voltage(ret:%d)\n", ret);
>>> +        return ret;
>>> +    }
>>> +
>>> +    slpi->px = devm_regulator_get(slpi->dev, "vdd_px");
>>> +    if (IS_ERR(slpi->px))
>>> +        return PTR_ERR(slpi->px);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int slpi_request_irq(struct qcom_slpi *slpi,
>>> +                 struct platform_device *pdev,
>>> +                 const char *name,
>>> +                 irq_handler_t thread_fn)
>>> +{
>>> +    int ret;
>>> +
>>> +    ret = platform_get_irq_byname(pdev, name);
>>> +    if (ret < 0) {
>>> +        dev_err(&pdev->dev, "no %s IRQ defined\n", name);
>>> +        return ret;
>>> +    }
>>> +    ret = devm_request_threaded_irq(&pdev->dev, ret,
>>> +                    NULL, thread_fn,
>>> +                    IRQF_ONESHOT,
>>> +                    "slpi", slpi);
>>> +    if (ret)
>>> +        dev_err(&pdev->dev, "request %s IRQ failed\n", name);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int slpi_alloc_memory_region(struct qcom_slpi *slpi)
>>> +{
>>> +    struct device_node *node;
>>> +    struct resource r;
>>> +    int ret;
>>> +
>>> +    node = of_parse_phandle(slpi->dev->of_node, "memory-region", 0);
>>> +    if (!node) {
>>> +        dev_err(slpi->dev, "no memory-region specified\n");
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    ret = of_address_to_resource(node, 0, &r);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    slpi->mem_phys = slpi->mem_reloc = r.start;
>>> +    slpi->mem_size = resource_size(&r);
>>> +    slpi->mem_region = devm_ioremap_wc(slpi->dev,
>>> +                slpi->mem_phys, slpi->mem_size);
>>> +    if (!slpi->mem_region) {
>>> +        dev_err(slpi->dev, "unable to map memory region: %pa+%zx\n",
>>> +            &r.start, slpi->mem_size);
>>> +        return -EBUSY;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int slpi_probe(struct platform_device *pdev)
>>> +{
>>> +    struct qcom_slpi *slpi;
>>> +    struct rproc *rproc;
>>> +    int ret;
>>> +
>>> +    if (!qcom_scm_is_available())
>>> +        return -EPROBE_DEFER;
>>> +
>>> +    if (!qcom_scm_pas_supported(SLPI_PAS_ID)) {
>>> +        dev_err(&pdev->dev, "PAS is not available for slpi\n");
>>> +        return -ENXIO;
>>> +    }
>>> +    rproc = rproc_alloc(&pdev->dev, pdev->name, &slpi_ops,
>>> +                SLPI_FIRMWARE_NAME, sizeof(*slpi));
>>> +    if (!rproc) {
>>> +        dev_err(&pdev->dev, "unable to allocate remoteproc\n");
>>> +        return -ENOMEM;
>>> +    }
>>> +
>>> +    rproc->fw_ops = &slpi_fw_ops;
>>> +
>>> +    slpi = (struct qcom_slpi *)rproc->priv;
>>> +    slpi->dev = &pdev->dev;
>>> +    slpi->rproc = rproc;
>>> +    platform_set_drvdata(pdev, slpi);
>>> +
>>> +    init_completion(&slpi->start_done);
>>> +    init_completion(&slpi->stop_done);
>>> +
>>> +    ret = slpi_alloc_memory_region(slpi);
>>> +    if (ret)
>>> +        goto free_rproc;
>>> +
>>> +    ret = slpi_init_clock(slpi);
>>> +    if (ret)
>>> +        goto free_rproc;
>>> +
>>> +    ret = slpi_init_regulator(slpi);
>>> +    if (ret)
>>> +        goto free_rproc;
>>> +
>>> +    ret = slpi_request_irq(slpi, pdev, "wdog", slpi_wdog_interrupt);
>>> +    if (ret < 0)
>>> +        goto free_rproc;
>>> +    slpi->wdog_irq = ret;
>>> +
>>> +    ret = slpi_request_irq(slpi, pdev, "fatal", slpi_fatal_interrupt);
>>> +    if (ret < 0)
>>> +        goto free_rproc;
>>> +    slpi->fatal_irq = ret;
>>> +
>>> +    ret = slpi_request_irq(slpi, pdev, "ready", slpi_ready_interrupt);
>>> +    if (ret < 0)
>>> +        goto free_rproc;
>>> +    slpi->ready_irq = ret;
>>> +
>>> +    ret = slpi_request_irq(slpi, pdev, "handover",
>>> slpi_handover_interrupt);
>>> +    if (ret < 0)
>>> +        goto free_rproc;
>>> +    slpi->handover_irq = ret;
>>> +
>>> +    ret = slpi_request_irq(slpi, pdev, "stop-ack",
>>> slpi_stop_ack_interrupt);
>>> +    if (ret < 0)
>>> +        goto free_rproc;
>>> +    slpi->stop_ack_irq = ret;
>>> +
>>> +    slpi->state = qcom_smem_state_get(&pdev->dev, "stop",
>>> +                      &slpi->stop_bit);
>>> +    if (IS_ERR(slpi->state)) {
>>> +        ret = PTR_ERR(slpi->state);
>>> +        goto free_rproc;
>>> +    }
>>> +
>>> +    ret = rproc_add(rproc);
>>> +    if (ret)
>>> +        goto free_rproc;
>>> +
>>> +    return 0;
>>> +
>>> +free_rproc:
>>> +    rproc_put(rproc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int slpi_remove(struct platform_device *pdev)
>>> +{
>>> +    struct qcom_slpi *slpi = platform_get_drvdata(pdev);
>>> +
>>> +    qcom_smem_state_put(slpi->state);
>>> +    rproc_del(slpi->rproc);
>>> +    rproc_put(slpi->rproc);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static const struct of_device_id slpi_of_match[] = {
>>> +    { .compatible = "qcom,msm8996-slpi-pil" },
>>> +    { },
>>> +};
>>> +
>>> +static struct platform_driver slpi_driver = {
>>> +    .probe = slpi_probe,
>>> +    .remove = slpi_remove,
>>> +    .driver = {
>>> +        .name = "qcom_slpi_pil",
>>> +        .of_match_table = slpi_of_match,
>>> +    },
>>> +};
>>> +
>>> +module_platform_driver(slpi_driver);
>>> +MODULE_DESCRIPTION("Qualcomm MSM8996 slpi Peripherial Image Loader");
>>> +MODULE_LICENSE("GPL v2");
>>> +
>>>
>>
>>
>


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-16  5:15     ` Dwivedi, Avaneesh Kumar (avani)
  2017-01-17 19:30       ` Sarangdhar Joshi
@ 2017-01-18 23:34       ` Bjorn Andersson
  2017-01-19  5:00         ` Dwivedi, Avaneesh Kumar (avani)
  1 sibling, 1 reply; 13+ messages in thread
From: Bjorn Andersson @ 2017-01-18 23:34 UTC (permalink / raw)
  To: Dwivedi, Avaneesh Kumar (avani)
  Cc: Sarangdhar Joshi, sboyd, agross, linux-arm-msm, linux-remoteproc

On Sun 15 Jan 21:15 PST 2017, Dwivedi, Avaneesh Kumar (avani) wrote:

> 
> 
> On 1/13/2017 2:11 AM, Sarangdhar Joshi wrote:
> > Hi Avaneesh,
> > 
> > On 01/12/2017 05:53 AM, Avaneesh Kumar Dwivedi wrote:
> > > This patch is to load and boot slpi core on Qualcomm plateforms. It is
> > > used for loading the firmware images of the subsystems into memory
> > > and preparing the subsystem's processor to execute code.
> > 
> > Can't we modify qcom_adsp_pil.c to use SLPI as well?
> 
> clocks, regulators, PAS_ID, firmware name, crash reason smem id these are
> few driver specific resource/variable, if it is ok to initialize these
> variables  based on compatible string, i think we can have single driver for
> adsp and slpi. let me know your further comment.

I would prefer this too.

The only thing that stands out is that you're not allowed to
regulator_set_voltage(5), because that's not how we will do corners
upstream - which tells us that we need to get corner voltages sorted
out.


I'm still undecided on aggre2_noc being handled in this driver or in a
aggre2_noc bus surrounding the device, but that's a smaller issue than
the corners.

Regardless of these two issues we want a common adsp + slpi driver, so
please submit a patch where you add the slpi support to the existing
adsp driver.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader.
  2017-01-18 23:34       ` Bjorn Andersson
@ 2017-01-19  5:00         ` Dwivedi, Avaneesh Kumar (avani)
  0 siblings, 0 replies; 13+ messages in thread
From: Dwivedi, Avaneesh Kumar (avani) @ 2017-01-19  5:00 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Sarangdhar Joshi, sboyd, agross, linux-arm-msm, linux-remoteproc



On 1/19/2017 5:04 AM, Bjorn Andersson wrote:
> On Sun 15 Jan 21:15 PST 2017, Dwivedi, Avaneesh Kumar (avani) wrote:
>
>>
>> On 1/13/2017 2:11 AM, Sarangdhar Joshi wrote:
>>> Hi Avaneesh,
>>>
>>> On 01/12/2017 05:53 AM, Avaneesh Kumar Dwivedi wrote:
>>>> This patch is to load and boot slpi core on Qualcomm plateforms. It is
>>>> used for loading the firmware images of the subsystems into memory
>>>> and preparing the subsystem's processor to execute code.
>>> Can't we modify qcom_adsp_pil.c to use SLPI as well?
>> clocks, regulators, PAS_ID, firmware name, crash reason smem id these are
>> few driver specific resource/variable, if it is ok to initialize these
>> variables  based on compatible string, i think we can have single driver for
>> adsp and slpi. let me know your further comment.
> I would prefer this too.
>
> The only thing that stands out is that you're not allowed to
> regulator_set_voltage(5), because that's not how we will do corners
> upstream - which tells us that we need to get corner voltages sorted
> out.
>
>
> I'm still undecided on aggre2_noc being handled in this driver or in a
> aggre2_noc bus surrounding the device, but that's a smaller issue than
> the corners.
>
> Regardless of these two issues we want a common adsp + slpi driver, so
> please submit a patch where you add the slpi support to the existing
> adsp driver.
OK, sure today i will try to submitt this.
but i need your comments on two things.
1- if we are going to have single driver, can we rename also this common 
driver so that it doesnt sound like only loading and booting adsp.
2- this was(using regulator API to enable supply) what even i was 
hesitant to submit slpi driver, so any comment on? how to go till time 
we dont have alternative?
>
> Regards,
> Bjorn

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-01-19  5:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-12 13:53 [RFC 0/3] remoteproc: Introducing Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
2017-01-12 13:53 ` [RFC 1/3] remoteproc: qcom: Introduce Qualcomm low pass sensor peripheral loader Avaneesh Kumar Dwivedi
2017-01-12 20:41   ` Sarangdhar Joshi
2017-01-16  5:15     ` Dwivedi, Avaneesh Kumar (avani)
2017-01-17 19:30       ` Sarangdhar Joshi
2017-01-18 23:34       ` Bjorn Andersson
2017-01-19  5:00         ` Dwivedi, Avaneesh Kumar (avani)
2017-01-12 13:53 ` [RFC 2/3] dt-binding: remoteproc: Introduce DT binding for Qualcomm slpi subsystem Avaneesh Kumar Dwivedi
2017-01-12 18:39   ` Bjorn Andersson
2017-01-16  6:01     ` Dwivedi, Avaneesh Kumar (avani)
2017-01-12 13:53 ` [RFC 3/3] arm64: dts: msm8996: Add SMP2P node for Qualcomm SLPI rproc driver Avaneesh Kumar Dwivedi
2017-01-12 18:24   ` Bjorn Andersson
2017-01-16  6:03     ` Dwivedi, Avaneesh Kumar (avani)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.