Commit 929e134c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rproc-v4.20' of git://github.com/andersson/remoteproc

Pull remoteproc updates from Bjorn Andersson:
 "This contains a series of patches that reworks the memory carveout
  handling in remoteproc, in order to allow this to be reused for
  statically allocated memory regions to be used for e.g. firmware.

  It adds support for audio DSP (both TZ-assisted and non-TZ assisted)
  and compute DSP on Qualcomm SDM845, TZ-assisted audio DSP, compute DSP
  and WiFi processor on Qualcomm QCS404 and through some renaming of the
  drivers cleans up the naming situation.

  Finally support for custom coreudmp segment handlers is added and is
  used in the Qualcomm modem remoteproc driver to gather memory dumps of
  the firmware"

* tag 'rproc-v4.20' of git://github.com/andersson/remoteproc: (36 commits)
  remoteproc: qcom: q6v5-mss: Register segments/dumpfn for coredump
  remoteproc: qcom: q6v5-mss: Add custom dump function for modem
  remoteproc: qcom: q6v5-mss: Refactor mba load/unload sequence
  remoteproc: Add mechanism for custom dump function assignment
  remoteproc: Introduce custom dump function for each remoteproc segment
  remoteproc: modify vring allocation to rely on centralized carveout allocator
  remoteproc: qcom: q6v5: shore up resource probe handling
  remoteproc: qcom: qcom_q6v5_adsp: Fix some return value check
  remoteproc: modify rproc_handle_carveout to support pre-registered region
  remoteproc: add helper function to check carveout device address
  remoteproc: add helper function to allocate rproc_mem_entry from reserved memory
  remoteproc: add alloc ops in rproc_mem_entry struct
  remoteproc: introduce rproc_find_carveout_by_name function
  remoteproc: introduce rproc_add_carveout function
  remoteproc: add helper function to allocate and init rproc_mem_entry struct
  remoteproc: add name in rproc_mem_entry struct
  remoteproc: add release ops in rproc_mem_entry struct
  remoteproc: add rproc_va_to_pa function
  remoteproc: configure IOMMU only if device address requested
  remoteproc: qcom: q6v5-mss: add SCM probe dependency
  ...
parents 4b427452 f18b7e91
Qualcomm Technology Inc. ADSP Peripheral Image Loader
This document defines the binding for a component that loads and boots firmware
on the Qualcomm Technology Inc. ADSP Hexagon core.
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,sdm845-adsp-pil"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: must specify the base address and size of the qdsp6ss register
- 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: List of 8 phandle and clock specifier pairs for the adsp.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: List of clock input name strings sorted in the same
order as the clocks property. Definition must have
"xo", "sway_cbcr", "lpass_aon", "lpass_ahbs_aon_cbcr",
"lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep"
and "qdsp6ss_core".
- power-domains:
Usage: required
Value type: <phandle>
Definition: reference to cx power domain node.
- resets:
Usage: required
Value type: <phandle>
Definition: reference to the list of 2 reset-controller for the adsp.
- reset-names:
Usage: required
Value type: <stringlist>
Definition: must be "pdc_sync" and "cc_lpass"
- qcom,halt-regs:
Usage: required
Value type: <prop-encoded-array>
Definition: a phandle reference to a syscon representing TCSR followed
by the offset within syscon for lpass halt register.
- memory-region:
Usage: required
Value type: <phandle>
Definition: reference to the reserved-memory for the ADSP
- qcom,smem-states:
Usage: required
Value type: <phandle>
Definition: reference to the smem state for requesting the ADSP to
shut down
- qcom,smem-state-names:
Usage: required
Value type: <stringlist>
Definition: must be "stop"
= SUBNODES
The adsp node may have an subnode named "glink-edge" that describes the
communication edge, channels and devices related to the ADSP.
See ../soc/qcom/qcom,glink.txt for details on how to describe these.
= EXAMPLE
The following example describes the resources needed to boot control the
ADSP, as it is found on SDM845 boards.
remoteproc@17300000 {
compatible = "qcom,sdm845-adsp-pil";
reg = <0x17300000 0x40c>;
interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
<&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
<&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
<&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
<&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "wdog", "fatal", "ready",
"handover", "stop-ack";
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_LPASS_SWAY_CLK>,
<&lpasscc LPASS_AUDIO_WRAPPER_AON_CLK>,
<&lpasscc LPASS_Q6SS_AHBS_AON_CLK>,
<&lpasscc LPASS_Q6SS_AHBM_AON_CLK>,
<&lpasscc LPASS_QDSP6SS_XO_CLK>,
<&lpasscc LPASS_QDSP6SS_SLEEP_CLK>,
<&lpasscc LPASS_QDSP6SS_CORE_CLK>;
clock-names = "xo", "sway_cbcr", "lpass_aon",
"lpass_ahbs_aon_cbcr",
"lpass_ahbm_aon_cbcr", "qdsp6ss_xo",
"qdsp6ss_sleep", "qdsp6ss_core";
power-domains = <&rpmhpd SDM845_CX>;
resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>,
<&aoss_reset AOSS_CC_LPASS_RESTART>;
reset-names = "pdc_sync", "cc_lpass";
qcom,halt-regs = <&tcsr_mutex_regs 0x22000>;
memory-region = <&pil_adsp_mem>;
qcom,smem-states = <&adsp_smp2p_out 0>;
qcom,smem-state-names = "stop";
};
...@@ -10,6 +10,11 @@ on the Qualcomm ADSP Hexagon core. ...@@ -10,6 +10,11 @@ on the Qualcomm ADSP Hexagon core.
"qcom,msm8974-adsp-pil" "qcom,msm8974-adsp-pil"
"qcom,msm8996-adsp-pil" "qcom,msm8996-adsp-pil"
"qcom,msm8996-slpi-pil" "qcom,msm8996-slpi-pil"
"qcom,qcs404-adsp-pas"
"qcom,qcs404-cdsp-pas"
"qcom,qcs404-wcss-pas"
"qcom,sdm845-adsp-pas"
"qcom,sdm845-cdsp-pas"
- interrupts-extended: - interrupts-extended:
Usage: required Usage: required
......
...@@ -53,13 +53,17 @@ on the Qualcomm Hexagon core. ...@@ -53,13 +53,17 @@ on the Qualcomm Hexagon core.
Definition: reference to the reset-controller for the modem sub-system Definition: reference to the reset-controller for the modem sub-system
reference to the list of 3 reset-controllers for the reference to the list of 3 reset-controllers for the
wcss sub-system wcss sub-system
reference to the list of 2 reset-controllers for the modem
sub-system on SDM845 SoCs
- reset-names: - reset-names:
Usage: required Usage: required
Value type: <stringlist> Value type: <stringlist>
Definition: must be "mss_restart" for the modem sub-system Definition: must be "mss_restart" for the modem sub-system
Definition: must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset" must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset"
for the wcss syb-system for the wcss sub-system
must be "mss_restart", "pdc_reset" for the modem
sub-system on SDM845 SoCs
- cx-supply: - cx-supply:
- mss-supply: - mss-supply:
......
...@@ -84,8 +84,16 @@ config KEYSTONE_REMOTEPROC ...@@ -84,8 +84,16 @@ config KEYSTONE_REMOTEPROC
It's safe to say N here if you're not interested in the Keystone It's safe to say N here if you're not interested in the Keystone
DSPs or just want to use a bare minimum kernel. DSPs or just want to use a bare minimum kernel.
config QCOM_ADSP_PIL config QCOM_RPROC_COMMON
tristate "Qualcomm ADSP Peripheral Image Loader" tristate
config QCOM_Q6V5_COMMON
tristate
depends on ARCH_QCOM
depends on QCOM_SMEM
config QCOM_Q6V5_ADSP
tristate "Qualcomm Technology Inc ADSP Peripheral Image Loader"
depends on OF && ARCH_QCOM depends on OF && ARCH_QCOM
depends on QCOM_SMEM depends on QCOM_SMEM
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
...@@ -95,33 +103,41 @@ config QCOM_ADSP_PIL ...@@ -95,33 +103,41 @@ config QCOM_ADSP_PIL
select QCOM_MDT_LOADER select QCOM_MDT_LOADER
select QCOM_Q6V5_COMMON select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON select QCOM_RPROC_COMMON
select QCOM_SCM
help help
Say y here to support the TrustZone based Peripherial Image Loader Say y here to support the Peripheral Image Loader
for the Qualcomm ADSP remote processors. for the Qualcomm Technology Inc. ADSP remote processors.
config QCOM_RPROC_COMMON config QCOM_Q6V5_MSS
tristate tristate "Qualcomm Hexagon V5 self-authenticating modem subsystem support"
depends on OF && ARCH_QCOM
config QCOM_Q6V5_COMMON
tristate
depends on ARCH_QCOM
depends on QCOM_SMEM depends on QCOM_SMEM
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON
select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON
select QCOM_SCM
help
Say y here to support the Qualcomm self-authenticating modem
subsystem based on Hexagon V5.
config QCOM_Q6V5_PIL config QCOM_Q6V5_PAS
tristate "Qualcomm Hexagon V5 Peripherial Image Loader" tristate "Qualcomm Hexagon v5 Peripheral Authentication Service support"
depends on OF && ARCH_QCOM depends on OF && ARCH_QCOM
depends on QCOM_SMEM depends on QCOM_SMEM
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
depends on QCOM_SYSMON || QCOM_SYSMON=n depends on QCOM_SYSMON || QCOM_SYSMON=n
select MFD_SYSCON select MFD_SYSCON
select QCOM_MDT_LOADER
select QCOM_Q6V5_COMMON select QCOM_Q6V5_COMMON
select QCOM_RPROC_COMMON select QCOM_RPROC_COMMON
select QCOM_SCM select QCOM_SCM
help help
Say y here to support the Qualcomm Peripherial Image Loader for the Say y here to support the TrustZone based Peripherial Image Loader
Hexagon V5 based remote processors. for the Qualcomm Hexagon v5 based remote processors. This is commonly
used to control subsystems such as ADSP, Compute and Sensor.
config QCOM_Q6V5_WCSS config QCOM_Q6V5_WCSS
tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader" tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader"
......
...@@ -14,10 +14,11 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o ...@@ -14,10 +14,11 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o
obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
obj-$(CONFIG_KEYSTONE_REMOTEPROC) += keystone_remoteproc.o obj-$(CONFIG_KEYSTONE_REMOTEPROC) += keystone_remoteproc.o
obj-$(CONFIG_QCOM_ADSP_PIL) += qcom_adsp_pil.o
obj-$(CONFIG_QCOM_RPROC_COMMON) += qcom_common.o obj-$(CONFIG_QCOM_RPROC_COMMON) += qcom_common.o
obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o
obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o obj-$(CONFIG_QCOM_Q6V5_ADSP) += qcom_q6v5_adsp.o
obj-$(CONFIG_QCOM_Q6V5_MSS) += qcom_q6v5_mss.o
obj-$(CONFIG_QCOM_Q6V5_PAS) += qcom_q6v5_pas.o
obj-$(CONFIG_QCOM_Q6V5_WCSS) += qcom_q6v5_wcss.o obj-$(CONFIG_QCOM_Q6V5_WCSS) += qcom_q6v5_wcss.o
obj-$(CONFIG_QCOM_SYSMON) += qcom_sysmon.o obj-$(CONFIG_QCOM_SYSMON) += qcom_sysmon.o
obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss_pil.o obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss_pil.o
......
...@@ -226,7 +226,7 @@ static int da8xx_rproc_get_internal_memories(struct platform_device *pdev, ...@@ -226,7 +226,7 @@ static int da8xx_rproc_get_internal_memories(struct platform_device *pdev,
res->start & DA8XX_RPROC_LOCAL_ADDRESS_MASK; res->start & DA8XX_RPROC_LOCAL_ADDRESS_MASK;
drproc->mem[i].size = resource_size(res); drproc->mem[i].size = resource_size(res);
dev_dbg(dev, "memory %8s: bus addr %pa size 0x%x va %p da 0x%x\n", dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
mem_names[i], &drproc->mem[i].bus_addr, mem_names[i], &drproc->mem[i].bus_addr,
drproc->mem[i].size, drproc->mem[i].cpu_addr, drproc->mem[i].size, drproc->mem[i].cpu_addr,
drproc->mem[i].dev_addr); drproc->mem[i].dev_addr);
......
...@@ -84,6 +84,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *data) ...@@ -84,6 +84,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *data)
else else
dev_err(q6v5->dev, "fatal error without message\n"); dev_err(q6v5->dev, "fatal error without message\n");
q6v5->running = false;
rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR); rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -150,8 +151,6 @@ int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5) ...@@ -150,8 +151,6 @@ int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5)
{ {
int ret; int ret;
q6v5->running = false;
qcom_smem_state_update_bits(q6v5->state, qcom_smem_state_update_bits(q6v5->state,
BIT(q6v5->stop_bit), BIT(q6v5->stop_bit)); BIT(q6v5->stop_bit), BIT(q6v5->stop_bit));
...@@ -188,6 +187,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, ...@@ -188,6 +187,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
init_completion(&q6v5->stop_done); init_completion(&q6v5->stop_done);
q6v5->wdog_irq = platform_get_irq_byname(pdev, "wdog"); q6v5->wdog_irq = platform_get_irq_byname(pdev, "wdog");
if (q6v5->wdog_irq < 0) {
if (q6v5->wdog_irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to retrieve wdog IRQ: %d\n",
q6v5->wdog_irq);
return q6v5->wdog_irq;
}
ret = devm_request_threaded_irq(&pdev->dev, q6v5->wdog_irq, ret = devm_request_threaded_irq(&pdev->dev, q6v5->wdog_irq,
NULL, q6v5_wdog_interrupt, NULL, q6v5_wdog_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
...@@ -198,6 +205,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, ...@@ -198,6 +205,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
} }
q6v5->fatal_irq = platform_get_irq_byname(pdev, "fatal"); q6v5->fatal_irq = platform_get_irq_byname(pdev, "fatal");
if (q6v5->fatal_irq < 0) {
if (q6v5->fatal_irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to retrieve fatal IRQ: %d\n",
q6v5->fatal_irq);
return q6v5->fatal_irq;
}
ret = devm_request_threaded_irq(&pdev->dev, q6v5->fatal_irq, ret = devm_request_threaded_irq(&pdev->dev, q6v5->fatal_irq,
NULL, q6v5_fatal_interrupt, NULL, q6v5_fatal_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
...@@ -208,6 +223,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, ...@@ -208,6 +223,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
} }
q6v5->ready_irq = platform_get_irq_byname(pdev, "ready"); q6v5->ready_irq = platform_get_irq_byname(pdev, "ready");
if (q6v5->ready_irq < 0) {
if (q6v5->ready_irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to retrieve ready IRQ: %d\n",
q6v5->ready_irq);
return q6v5->ready_irq;
}
ret = devm_request_threaded_irq(&pdev->dev, q6v5->ready_irq, ret = devm_request_threaded_irq(&pdev->dev, q6v5->ready_irq,
NULL, q6v5_ready_interrupt, NULL, q6v5_ready_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
...@@ -218,6 +241,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, ...@@ -218,6 +241,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
} }
q6v5->handover_irq = platform_get_irq_byname(pdev, "handover"); q6v5->handover_irq = platform_get_irq_byname(pdev, "handover");
if (q6v5->handover_irq < 0) {
if (q6v5->handover_irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to retrieve handover IRQ: %d\n",
q6v5->handover_irq);
return q6v5->handover_irq;
}
ret = devm_request_threaded_irq(&pdev->dev, q6v5->handover_irq, ret = devm_request_threaded_irq(&pdev->dev, q6v5->handover_irq,
NULL, q6v5_handover_interrupt, NULL, q6v5_handover_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
...@@ -229,6 +260,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, ...@@ -229,6 +260,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
disable_irq(q6v5->handover_irq); disable_irq(q6v5->handover_irq);
q6v5->stop_irq = platform_get_irq_byname(pdev, "stop-ack"); q6v5->stop_irq = platform_get_irq_byname(pdev, "stop-ack");
if (q6v5->stop_irq < 0) {
if (q6v5->stop_irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to retrieve stop-ack IRQ: %d\n",
q6v5->stop_irq);
return q6v5->stop_irq;
}
ret = devm_request_threaded_irq(&pdev->dev, q6v5->stop_irq, ret = devm_request_threaded_irq(&pdev->dev, q6v5->stop_irq,
NULL, q6v5_stop_interrupt, NULL, q6v5_stop_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
......
This diff is collapsed.
...@@ -342,6 +342,16 @@ static const struct adsp_data adsp_resource_init = { ...@@ -342,6 +342,16 @@ static const struct adsp_data adsp_resource_init = {
.ssctl_id = 0x14, .ssctl_id = 0x14,
}; };
static const struct adsp_data cdsp_resource_init = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
.pas_id = 18,
.has_aggre2_clk = false,
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
};
static const struct adsp_data slpi_resource_init = { static const struct adsp_data slpi_resource_init = {
.crash_reason_smem = 424, .crash_reason_smem = 424,
.firmware_name = "slpi.mdt", .firmware_name = "slpi.mdt",
...@@ -352,10 +362,24 @@ static const struct adsp_data slpi_resource_init = { ...@@ -352,10 +362,24 @@ static const struct adsp_data slpi_resource_init = {
.ssctl_id = 0x16, .ssctl_id = 0x16,
}; };
static const struct adsp_data wcss_resource_init = {
.crash_reason_smem = 421,
.firmware_name = "wcnss.mdt",
.pas_id = 6,
.ssr_name = "mpss",
.sysmon_name = "wcnss",
.ssctl_id = 0x12,
};
static const struct of_device_id adsp_of_match[] = { static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
{ .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
{ .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init}, { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
{ .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
{ .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, adsp_of_match); MODULE_DEVICE_TABLE(of, adsp_of_match);
...@@ -364,11 +388,11 @@ static struct platform_driver adsp_driver = { ...@@ -364,11 +388,11 @@ static struct platform_driver adsp_driver = {
.probe = adsp_probe, .probe = adsp_probe,
.remove = adsp_remove, .remove = adsp_remove,
.driver = { .driver = {
.name = "qcom_adsp_pil", .name = "qcom_q6v5_pas",
.of_match_table = adsp_of_match, .of_match_table = adsp_of_match,
}, },
}; };
module_platform_driver(adsp_driver); module_platform_driver(adsp_driver);
MODULE_DESCRIPTION("Qualcomm MSM8974/MSM8996 ADSP Peripherial Image Loader"); MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
This diff is collapsed.
...@@ -260,6 +260,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p) ...@@ -260,6 +260,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p)
list_for_each_entry(carveout, &rproc->carveouts, node) { list_for_each_entry(carveout, &rproc->carveouts, node) {
seq_puts(seq, "Carveout memory entry:\n"); seq_puts(seq, "Carveout memory entry:\n");
seq_printf(seq, "\tName: %s\n", carveout->name);
seq_printf(seq, "\tVirtual address: %pK\n", carveout->va); seq_printf(seq, "\tVirtual address: %pK\n", carveout->va);
seq_printf(seq, "\tDMA address: %pad\n", &carveout->dma); seq_printf(seq, "\tDMA address: %pad\n", &carveout->dma);
seq_printf(seq, "\tDevice address: 0x%x\n", carveout->da); seq_printf(seq, "\tDevice address: 0x%x\n", carveout->da);
......
...@@ -60,6 +60,8 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw); ...@@ -60,6 +60,8 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw);
int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw); int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw);
struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
const struct firmware *fw); const struct firmware *fw);
struct rproc_mem_entry *
rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);
static inline static inline
int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw) int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
......
...@@ -48,6 +48,11 @@ static ssize_t firmware_store(struct device *dev, ...@@ -48,6 +48,11 @@ static ssize_t firmware_store(struct device *dev,
} }
len = strcspn(buf, "\n"); len = strcspn(buf, "\n");
if (!len) {
dev_err(dev, "can't provide a NULL firmware\n");
err = -EINVAL;
goto out;
}
p = kstrndup(buf, len, GFP_KERNEL); p = kstrndup(buf, len, GFP_KERNEL);
if (!p) { if (!p) {
......
...@@ -76,7 +76,9 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, ...@@ -76,7 +76,9 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct rproc *rproc = vdev_to_rproc(vdev); struct rproc *rproc = vdev_to_rproc(vdev);
struct device *dev = &rproc->dev; struct device *dev = &rproc->dev;
struct rproc_mem_entry *mem;
struct rproc_vring *rvring; struct rproc_vring *rvring;
struct fw_rsc_vdev *rsc;
struct virtqueue *vq; struct virtqueue *vq;
void *addr; void *addr;
int len, size; int len, size;
...@@ -88,8 +90,14 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, ...@@ -88,8 +90,14 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
if (!name) if (!name)
return NULL; return NULL;
/* Search allocated memory region by name */
mem = rproc_find_carveout_by_name(rproc, "vdev%dvring%d", rvdev->index,
id);
if (!mem || !mem->va)
return ERR_PTR(-ENOMEM);
rvring = &rvdev->vring[id]; rvring = &rvdev->vring[id];
addr = rvring->va; addr = mem->va;
len = rvring->len; len = rvring->len;
/* zero vring */ /* zero vring */
...@@ -114,6 +122,10 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, ...@@ -114,6 +122,10 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
rvring->vq = vq; rvring->vq = vq;
vq->priv = rvring; vq->priv = rvring;
/* Update vring in resource table */
rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
rsc->vring[id].da = mem->da;
return vq; return vq;
} }
......
...@@ -305,14 +305,22 @@ struct fw_rsc_vdev { ...@@ -305,14 +305,22 @@ struct fw_rsc_vdev {
struct fw_rsc_vdev_vring vring[0]; struct fw_rsc_vdev_vring vring[0];
} __packed; } __packed;
struct rproc;
/** /**
* struct rproc_mem_entry - memory entry descriptor * struct rproc_mem_entry - memory entry descriptor
* @va: virtual address * @va: virtual address
* @dma: dma address * @dma: dma address
* @len: length, in bytes * @len: length, in bytes
* @da: device address * @da: device address
* @release: release associated memory
* @priv: associated data * @priv: associated data
* @name: associated memory region name (optional)
* @node: list node * @node: list node
* @rsc_offset: offset in resource table
* @flags: iommu protection flags
* @of_resm_idx: reserved memory phandle index
* @alloc: specific memory allocator function
*/ */
struct rproc_mem_entry { struct rproc_mem_entry {
void *va; void *va;
...@@ -320,10 +328,15 @@ struct rproc_mem_entry { ...@@ -320,10 +328,15 @@ struct rproc_mem_entry {
int len; int len;
u32 da; u32 da;
void *priv; void *priv;
char name[32];
struct list_head node; struct list_head node;
u32 rsc_offset;
u32 flags;
u32 of_resm_idx;
int (*alloc)(struct rproc *rproc, struct rproc_mem_entry *mem);
int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem);
}; };
struct rproc;
struct firmware; struct firmware;
/** /**
...@@ -399,6 +412,9 @@ enum rproc_crash_type { ...@@ -399,6 +412,9 @@ enum rproc_crash_type {
* @node: list node related to the rproc segment list * @node: list node related to the rproc segment list
* @da: device address of the segment * @da: device address of the segment
* @size: size of the segment * @size: size of the segment
* @priv: private data associated with the dump_segment
* @dump: custom dump function to fill device memory segment associated
* with coredump
*/ */
struct rproc_dump_segment { struct rproc_dump_segment {
struct list_head node; struct list_head node;
...@@ -406,6 +422,9 @@ struct rproc_dump_segment { ...@@ -406,6 +422,9 @@ struct rproc_dump_segment {
dma_addr_t da; dma_addr_t da;
size_t size; size_t size;
void *priv;
void (*dump)(struct rproc *rproc, struct rproc_dump_segment *segment,
void *dest);
loff_t offset; loff_t offset;
}; };
...@@ -439,7 +458,9 @@ struct rproc_dump_segment { ...@@ -439,7 +458,9 @@ struct rproc_dump_segment {
* @cached_table: copy of the resource table * @cached_table: copy of the resource table
* @table_sz: size of @cached_table * @table_sz: size of @cached_table
* @has_iommu: flag to indicate if remote processor is behind an MMU * @has_iommu: flag to indicate if remote processor is behind an MMU
* @auto_boot: flag to indicate if remote processor should be auto-started
* @dump_segments: list of segments in the firmware * @dump_segments: list of segments in the firmware
* @nb_vdev: number of vdev currently handled by rproc
*/ */
struct rproc { struct rproc {
struct list_head node; struct list_head node;
...@@ -472,6 +493,7 @@ struct rproc { ...@@ -472,6 +493,7 @@ struct rproc {
bool has_iommu; bool has_iommu;
bool auto_boot; bool auto_boot;
struct list_head dump_segments; struct list_head dump_segments;
int nb_vdev;
}; };
/** /**
...@@ -499,7 +521,6 @@ struct rproc_subdev { ...@@ -499,7 +521,6 @@ struct rproc_subdev {
/** /**
* struct rproc_vring - remoteproc vring state * struct rproc_vring - remoteproc vring state
* @va: virtual address * @va: virtual address
* @dma: dma address
* @len: length, in bytes * @len: length, in bytes
* @da: device address * @da: device address
* @align: vring alignment * @align: vring alignment
...@@ -509,7 +530,6 @@ struct rproc_subdev { ...@@ -509,7 +530,6 @@ struct rproc_subdev {
*/ */
struct rproc_vring { struct rproc_vring {
void *va; void *va;
dma_addr_t dma;
int len; int len;
u32 da; u32 da;
u32 align; u32 align;
...@@ -528,6 +548,7 @@ struct rproc_vring { ...@@ -528,6 +548,7 @@ struct rproc_vring {
* @vdev: the virio device * @vdev: the virio device
* @vring: the vrings for this vdev * @vring: the vrings for this vdev
* @rsc_offset: offset of the vdev's resource entry * @rsc_offset: offset of the vdev's resource entry
* @index: vdev position versus other vdev declared in resource table
*/ */
struct rproc_vdev { struct rproc_vdev {
struct kref refcount; struct kref refcount;
...@@ -540,6 +561,7 @@ struct rproc_vdev { ...@@ -540,6 +561,7 @@ struct rproc_vdev {
struct virtio_device vdev; struct virtio_device vdev;
struct rproc_vring vring[RVDEV_NUM_VRINGS]; struct rproc_vring vring[RVDEV_NUM_VRINGS];
u32 rsc_offset; u32 rsc_offset;
u32 index;
}; };
struct rproc *rproc_get_by_phandle(phandle phandle); struct rproc *rproc_get_by_phandle(phandle phandle);
...@@ -553,10 +575,29 @@ int rproc_add(struct rproc *rproc); ...@@ -553,10 +575,29 @@ int rproc_add(struct rproc *rproc);
int rproc_del(struct rproc *rproc); int rproc_del(struct rproc *rproc);
void rproc_free(struct rproc *rproc); void rproc_free(struct rproc *rproc);
void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
struct rproc_mem_entry *
rproc_mem_entry_init(struct device *dev,
void *va, dma_addr_t dma, int len, u32 da,
int (*alloc)(struct rproc *, struct rproc_mem_entry *),
int (*release)(struct rproc *, struct rproc_mem_entry *),
const char *name, ...);
struct rproc_mem_entry *
rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, int len,
u32 da, const char *name, ...);
int rproc_boot(struct rproc *rproc); int rproc_boot(struct rproc *rproc);
void rproc_shutdown(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc);
void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size);
int rproc_coredump_add_custom_segment(struct rproc *rproc,
dma_addr_t da, size_t size,
void (*dumpfn)(struct rproc *rproc,
struct rproc_dump_segment *segment,
void *dest),
void *priv);
static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev) static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment