Add support for sc7280 WPSS PIL loading
v9 cover Add support for sc7280 WPSS PIL loading
Add support for PIL loading of WPSS co-processor for SC7280 SOCs.
Changes from v8:
- Disallow num_proxy_pds to be more than the max allowed
- Add "additionalProperties: false" for glink-edge property in wpss dt-bindings.
Changes from v7:
- Use "interrupts" instead of "interrupts-extended" in DT bindings.
- Add glink-edge properties in DT bindings.
- Use size_t for "proxy_pd_count" in wpss remoteproc driver
Changes from v6:
- Fixed the dt-bindings check in qcom,sc7280-wpss-pil.yaml
- Fixed CDSP dt-bindings example node (compatible, glink-edge)
- Fixed the clock-names used in wpss driver
- Add support to get firmware-name from DTSI entry for wpss.
Changes from v4/v5:
- Add yaml conversion for adsp/cdsp dt-bindings
- Change clock names in wpss dt-bindings
- Correct mistake in signed-off enail ID
Rakesh Pillai (3):
dt-bindings: remoteproc: qcom: adsp: Convert binding to YAML
dt-bindings: remoteproc: qcom: Add SC7280 WPSS support
remoteproc: qcom: q6v5_wpss: Add support for sc7280 WPSS
.../bindings/remoteproc/qcom,hexagon-v56.txt | 140 ------------- .../bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml | 161 +++++++++++++++ .../bindings/remoteproc/qcom,sc7280-wpss-pil.yaml | 219 ++++++++++++++++++++ .../bindings/remoteproc/qcom,sdm845-adsp-pil.yaml | 160 +++++++++++++++ drivers/remoteproc/qcom_q6v5_adsp.c | 222 +++++++++++++++++++-- 5 files changed, 746 insertions(+), 156 deletions(-) delete mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,hexagon-v56.txt create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,sdm845-adsp-pil.yaml
Signature · 1 line
2.7.4
PATCH v9 1/3 dt-bindings: remoteproc: qcom: adsp: Convert binding to YAML
Convert Qualcomm ADSP/CDSP Remoteproc devicetree
binding to YAML.
--- .../bindings/remoteproc/qcom,hexagon-v56.txt | 140 ------------------ .../bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml | 161 +++++++++++++++++++++ .../bindings/remoteproc/qcom,sdm845-adsp-pil.yaml | 160 ++++++++++++++++++++ 3 files changed, 321 insertions(+), 140 deletions(-) delete mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,hexagon-v56.txt create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,sdm845-adsp-pil.yaml
Documentation/devicetree/bindings/remoteproc/qcom,hexagon-v56.txt deleted +0 -140
@@ -1,140 +0,0 @@ -Qualcomm Technology Inc. Hexagon v56 Peripheral Image Loader - -This document defines the binding for a component that loads and boots firmware -on the Qualcomm Technology Inc. Hexagon v56 core. - -- compatible: - Usage: required - Value type: <string> - Definition: must be one of: - "qcom,qcs404-cdsp-pil", - "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 phandles and clock specifier pairs for the Hexagon, - per clock-names below. - -- clock-names: - Usage: required for SDM845 ADSP - 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_ahbs_aon_cbcr", - "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep" - and "qdsp6ss_core". - -- clock-names: - Usage: required for QCS404 CDSP - Value type: <stringlist> - Definition: List of clock input name strings sorted in the same - order as the clocks property. Definition must have - "xo", "sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", - "q6ss_master", "q6_axim". - -- 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 resets for the Hexagon. - -- reset-names: - Usage: required for SDM845 ADSP - Value type: <stringlist> - Definition: must be "pdc_sync" and "cc_lpass" - -- reset-names: - Usage: required for QCS404 CDSP - Value type: <stringlist> - Definition: must be "restart" - -- 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 Hexagon halt register. - -- memory-region: - Usage: required - Value type: <phandle> - Definition: reference to the reserved-memory for the firmware - -- qcom,smem-states: - Usage: required - Value type: <phandle> - Definition: reference to the smem state for requesting the Hexagon 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 Hexagon. -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_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_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"; - };
Documentation/devicetree/bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml new file +161 -0
161 lines not on this page · raw message
Documentation/devicetree/bindings/remoteproc/qcom,sdm845-adsp-pil.yaml new file +160 -0
160 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v9 2/3 dt-bindings: remoteproc: qcom: Add SC7280 WPSS support
In reply to Rakesh PillaiAdd WPSS PIL loading support for SC7280 SoCs.
--- .../bindings/remoteproc/qcom,sc7280-wpss-pil.yaml | 219 +++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml
Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml new file +219 -0
@@ -0,0 +1,219 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/remoteproc/qcom,sc7280-wpss-pil.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SC7280 WPSS Peripheral Image Loader + +maintainers: + - Bjorn Andersson <[email protected]> + +description: + This document defines the binding for a component that loads and boots firmware + on the Qualcomm Technology Inc. WPSS. + +properties: + compatible: + enum: + - qcom,sc7280-wpss-pil + + reg: + maxItems: 1 + description: + The base address and size of the qdsp6ss register + + interrupts: + items: + - description: Watchdog interrupt + - description: Fatal interrupt + - description: Ready interrupt + - description: Handover interrupt + - description: Stop acknowledge interrupt + - description: Shutdown acknowledge interrupt + + interrupt-names: + items: + - const: wdog + - const: fatal + - const: ready + - const: handover + - const: stop-ack + - const: shutdown-ack + + clocks: + items: + - description: GCC WPSS AHB BDG Master clock + - description: GCC WPSS AHB clock + - description: GCC WPSS RSCP clock + - description: XO clock + + clock-names: + items: + - const: ahb_bdg + - const: ahb + - const: rscp + - const: xo + + power-domains: + items: + - description: CX power domain + - description: MX power domain + + power-domain-names: + items: + - const: cx + - const: mx + + resets: + items: + - description: AOSS restart + - description: PDC SYNC + + reset-names: + items: + - const: restart + - const: pdc_sync + + memory-region: + $ref: /schemas/types.yaml#/definitions/phandle + description: Reference to the reserved-memory for the Hexagon core + + firmware-name: + $ref: /schemas/types.yaml#/definitions/string + description: + The name of the firmware which should be loaded for this remote + processor. + + qcom,halt-regs: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + Phandle reference to a syscon representing TCSR followed by the + three offsets within syscon for q6, modem and nc halt registers. + + qcom,qmp: + $ref: /schemas/types.yaml#/definitions/phandle + description: Reference to the AOSS side-channel message RAM. + + qcom,smem-states: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: States used by the AP to signal the Hexagon core + items: + - description: Stop the modem + + qcom,smem-state-names: + $ref: /schemas/types.yaml#/definitions/string + description: The names of the state bits used for SMP2P output + items: + - const: stop + + glink-edge: + type: object + description: | + Qualcomm G-Link subnode which represents communication edge, channels + and devices related to the ADSP. + + properties: + interrupts: + items: + - description: IRQ from WPSS to GLINK + + mboxes: + items: + - description: Mailbox for communication between APPS and WPSS + + label: + description: The names of the state bits used for SMP2P output + items: + - const: wpss + + qcom,remote-pid: + $ref: /schemas/types.yaml#/definitions/uint32 + description: ID of the shared memory used by GLINK for communication with WPSS + maxItems: 1 + + required: + - interrupts + - mboxes + - label + - qcom,remote-pid + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - power-domains + - power-domain-names + - resets + - reset-names + - qcom,halt-regs + - memory-region + - qcom,qmp + - qcom,smem-states + - qcom,smem-state-names + - glink-edge + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/clock/qcom,gcc-sc7280.h> + #include <dt-bindings/clock/qcom,rpmh.h> + #include <dt-bindings/power/qcom-rpmpd.h> + #include <dt-bindings/reset/qcom,sdm845-aoss.h> + #include <dt-bindings/reset/qcom,sdm845-pdc.h> + #include <dt-bindings/mailbox/qcom-ipcc.h> + remoteproc@8a00000 { + compatible = "qcom,sc7280-wpss-pil"; + reg = <0x08a00000 0x10000>; + + interrupts-extended = <&intc GIC_SPI 587 IRQ_TYPE_EDGE_RISING>, + <&wpss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&wpss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&wpss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&wpss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, + <&wpss_smp2p_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", "handover", + "stop-ack", "shutdown-ack"; + + clocks = <&gcc GCC_WPSS_AHB_BDG_MST_CLK>, + <&gcc GCC_WPSS_AHB_CLK>, + <&gcc GCC_WPSS_RSCP_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ahb_bdg", "ahb", + "rscp", "xo"; + + power-domains = <&rpmhpd SC7280_CX>, + <&rpmhpd SC7280_MX>; + power-domain-names = "cx", "mx"; + + memory-region = <&wpss_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&wpss_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + resets = <&aoss_reset AOSS_CC_WCSS_RESTART>, + <&pdc_reset PDC_WPSS_SYNC_RESET>; + reset-names = "restart", "pdc_sync"; + + qcom,halt-regs = <&tcsr_mutex 0x37000>; + + glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_WPSS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_WPSS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "wpss"; + qcom,remote-pid = <13>; + }; + };
Signature · 1 line
2.7.4
PATCH v9 3/3 remoteproc: qcom: q6v5_wpss: Add support for sc7280 WPSS
In reply to Rakesh PillaiAdd support for PIL loading of WPSS processor for SC7280
- WPSS boot will be requested by the wifi driver and hence disable auto-boot for WPSS.
- Add a separate shutdown sequence handler for WPSS.
- Add multiple power-domain voting support
- Parse firmware-name from dtsi entry
--- drivers/remoteproc/qcom_q6v5_adsp.c | 222 +++++++++++++++++++++++++++++++++--- 1 file changed, 206 insertions(+), 16 deletions(-)
drivers/remoteproc/qcom_q6v5_adsp.c +206 -16
@@ -32,6 +32,7 @@/* time out value */ #define ACK_TIMEOUT 1000 +#define ACK_TIMEOUT_US 1000000#define BOOT_FSM_TIMEOUT 10000/* mask values */ #define EVB_MASK GENMASK(27, 4)
@@ -51,6 +52,8 @@#define QDSP6SS_CORE_CBCR 0x20#define QDSP6SS_SLEEP_CBCR 0x3c +#define QCOM_Q6V5_RPROC_PROXY_PD_MAX 3 +struct adsp_pil_data {int crash_reason_smem;const char *firmware_name;
@@ -58,9 +61,13 @@ struct adsp_pil_data {const char *ssr_name;const char *sysmon_name;int ssctl_id; +bool is_wpss; +bool auto_boot;const char **clk_ids;int num_clks; +const char **proxy_pd_names; +const char *load_state; };struct qcom_adsp {
@@ -93,11 +100,146 @@ struct qcom_adsp {void *mem_region;size_t mem_size; +struct device *proxy_pds[QCOM_Q6V5_RPROC_PROXY_PD_MAX ]; +size_t proxy_pd_count; +struct qcom_rproc_glink glink_subdev;struct qcom_rproc_ssr ssr_subdev;struct qcom_sysmon *sysmon; + +int (*shutdown)(struct qcom_adsp *adsp); }; +static int qcom_rproc_pds_attach (struct device *dev,struct device **devs, +const char **pd_names) +{ +size_t num_pds =0 ; +int ret; +int i; + +if (!pd_names) +return 0 ; + +/* Handle single power domain */ +if (dev->pm_domain) { + devs[0 ] = dev; +pm_runtime_enable (dev); +return 1 ; + } + +while (pd_names[num_pds]) + num_pds++; + +if (num_pds >QCOM_Q6V5_RPROC_PROXY_PD_MAX ) +return -E2BIG ; + +for (i =0 ; i < num_pds; i++) { + devs[i] =dev_pm_domain_attach_by_name (dev, pd_names[i]); +if (IS_ERR_OR_NULL (devs[i])) { + ret =PTR_ERR (devs[i]) ? : -ENODATA ; + goto unroll_attach; + } + } + +return num_pds; + +unroll_attach: +for (i--; i >=0 ; i--) +dev_pm_domain_detach (devs[i], false); + +return ret; +} + +static void qcom_rproc_pds_detach (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +struct device *dev = adsp->dev; +int i; + +/* Handle single power domain */ +if (dev->pm_domain && pd_count) { +pm_runtime_disable (dev); +return ; + } + +for (i =0 ; i < pd_count; i++) +dev_pm_domain_detach (pds[i], false); +} + +static int qcom_rproc_pds_enable (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +int ret; +int i; + +for (i =0 ; i < pd_count; i++) { +dev_pm_genpd_set_performance_state (pds[i],INT_MAX ); + ret =pm_runtime_get_sync (pds[i]); +if (ret <0 ) { +pm_runtime_put_noidle (pds[i]); +dev_pm_genpd_set_performance_state (pds[i],0 ); + goto unroll_pd_votes; + } + } + +return 0 ; + +unroll_pd_votes: +for (i--; i >=0 ; i--) { +dev_pm_genpd_set_performance_state (pds[i],0 ); +pm_runtime_put (pds[i]); + } + +return ret; +} + +static void qcom_rproc_pds_disable (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +int i; + +for (i =0 ; i < pd_count; i++) { +dev_pm_genpd_set_performance_state (pds[i],0 ); +pm_runtime_put (pds[i]); + } +} + +static int qcom_wpss_shutdown (struct qcom_adsp *adsp) +{ +unsigned int val; + +regmap_write (adsp->halt_map, adsp->halt_lpass +LPASS_HALTREQ_REG ,1 ); + +/* Wait for halt ACK from QDSP6 */ +regmap_read_poll_timeout (adsp->halt_map, + adsp->halt_lpass +LPASS_HALTACK_REG , val, + val,1000 ,ACK_TIMEOUT_US ); + +/* Assert the WPSS PDC Reset */ +reset_control_assert (adsp->pdc_sync_reset); +/* Place the WPSS processor into reset */ +reset_control_assert (adsp->restart); +/* wait after asserting subsystem restart from AOSS */ +usleep_range (200 ,205 ); +/* Remove the WPSS reset */ +reset_control_deassert (adsp->restart); +/* De-assert the WPSS PDC Reset */ +reset_control_deassert (adsp->pdc_sync_reset); + +usleep_range (100 ,105 ); + +clk_bulk_disable_unprepare (adsp->num_clks, adsp->clks); + +regmap_write (adsp->halt_map, adsp->halt_lpass +LPASS_HALTREQ_REG ,0 ); + +/* Wait for halt ACK from QDSP6 */ +regmap_read_poll_timeout (adsp->halt_map, + adsp->halt_lpass +LPASS_HALTACK_REG , val, + !val,1000 ,ACK_TIMEOUT_US ); + +return 0 ; +} +static int qcom_adsp_shutdown (struct qcom_adsp *adsp) {unsigned long timeout;
@@ -193,12 +335,10 @@ static int adsp_start(struct rproc *rproc)if (ret) goto disable_irqs; -dev_pm_genpd_set_performance_state (adsp->dev,INT_MAX ); - ret =pm_runtime_get_sync (adsp->dev); -if (ret) { -pm_runtime_put_noidle (adsp->dev); + ret =qcom_rproc_pds_enable (adsp, adsp->proxy_pds, + adsp->proxy_pd_count); +if (ret <0 ) goto disable_xo_clk; - } ret =clk_bulk_prepare_enable (adsp->num_clks, adsp->clks);if (ret) {
@@ -243,8 +383,7 @@ static int adsp_start(struct rproc *rproc) disable_adsp_clks:clk_bulk_disable_unprepare (adsp->num_clks, adsp->clks); disable_power_domain: -dev_pm_genpd_set_performance_state (adsp->dev,0 ); -pm_runtime_put (adsp->dev); +qcom_rproc_pds_disable (adsp, adsp->proxy_pds, adsp->proxy_pd_count); disable_xo_clk:clk_disable_unprepare (adsp->xo); disable_irqs:
@@ -258,8 +397,7 @@ static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5) struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);clk_disable_unprepare (adsp->xo); -dev_pm_genpd_set_performance_state (adsp->dev,0 ); -pm_runtime_put (adsp->dev); +qcom_rproc_pds_disable (adsp, adsp->proxy_pds, adsp->proxy_pd_count); }static int adsp_stop (struct rproc *rproc)
@@ -272,7 +410,7 @@ static int adsp_stop(struct rproc *rproc)if (ret == -ETIMEDOUT )dev_err (adsp->dev,"timed out on wait\n" ); - ret =qcom_adsp_shutdown (adsp); + ret = adsp->shutdown (adsp);if (ret)dev_err (adsp->dev,"failed to shutdown: %d\n" , ret);
@@ -427,6 +565,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)static int adsp_probe (struct platform_device *pdev) {const struct adsp_pil_data *desc; +const char *firmware_name;struct qcom_adsp *adsp;struct rproc *rproc;int ret;
@@ -435,12 +574,22 @@ static int adsp_probe(struct platform_device *pdev)if (!desc)return -EINVAL ; + firmware_name = desc->firmware_name; + ret =of_property_read_string (pdev->dev.of_node,"firmware-name" , + &firmware_name); +if (ret <0 && ret != -EINVAL ) { +dev_err (&pdev->dev,"unable to read firmware-name\n" ); +return ret; + } + rproc =rproc_alloc (&pdev->dev, pdev->name, &adsp_ops, - desc->firmware_name,sizeof (*adsp)); + firmware_name,sizeof (*adsp));if (!rproc) {dev_err (&pdev->dev,"unable to allocate remoteproc\n" );return -ENOMEM ; } + + rproc->auto_boot = desc->auto_boot;rproc_coredump_set_elf_info (rproc,ELFCLASS32 ,EM_NONE ); adsp = (struct qcom_adsp *)rproc->priv;
@@ -449,6 +598,11 @@ static int adsp_probe(struct platform_device *pdev) adsp->info_name = desc->sysmon_name;platform_set_drvdata (pdev, adsp); +if (desc->is_wpss) + adsp->shutdown = qcom_wpss_shutdown; +else + adsp->shutdown = qcom_adsp_shutdown; + ret =adsp_alloc_memory_region (adsp);if (ret) goto free_rproc;
@@ -457,7 +611,13 @@ static int adsp_probe(struct platform_device *pdev)if (ret) goto free_rproc; -pm_runtime_enable (adsp->dev); + ret =qcom_rproc_pds_attach (adsp->dev, adsp->proxy_pds, + desc->proxy_pd_names); +if (ret <0 ) { +dev_err (&pdev->dev,"Failed to attach proxy power domains\n" ); + goto free_rproc; + } + adsp->proxy_pd_count = ret; ret =adsp_init_reset (adsp);if (ret)
@@ -467,8 +627,8 @@ static int adsp_probe(struct platform_device *pdev)if (ret) goto disable_pm; - ret =qcom_q6v5_init (&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,NULL , - qcom_adsp_pil_handover); + ret =qcom_q6v5_init (&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, + desc->load_state, qcom_adsp_pil_handover);if (ret) goto disable_pm;
@@ -489,7 +649,8 @@ static int adsp_probe(struct platform_device *pdev)return 0 ; disable_pm: -pm_runtime_disable (adsp->dev); +qcom_rproc_pds_detach (adsp, adsp->proxy_pds, adsp->proxy_pd_count); + free_rproc:rproc_free (rproc);
@@ -506,7 +667,7 @@ static int adsp_remove(struct platform_device *pdev)qcom_remove_glink_subdev (adsp->rproc, &adsp->glink_subdev);qcom_remove_sysmon_subdev (adsp->sysmon);qcom_remove_ssr_subdev (adsp->rproc, &adsp->ssr_subdev); -pm_runtime_disable (adsp->dev); +qcom_rproc_pds_detach (adsp, adsp->proxy_pds, adsp->proxy_pd_count);rproc_free (adsp->rproc);return 0 ;
@@ -518,11 +679,16 @@ static const struct adsp_pil_data adsp_resource_init = { .ssr_name = "lpass", .sysmon_name = "adsp", .ssctl_id = 0x14, + .is_wpss = false, + .auto_boot = true, .clk_ids = (const char *[]) {"sway_cbcr" ,"lpass_ahbs_aon_cbcr" ,"lpass_ahbm_aon_cbcr" ,"qdsp6ss_xo" ,"qdsp6ss_sleep" ,"qdsp6ss_core" ,NULL }, .num_clks = 7, + .proxy_pd_names = (const char *[]) { +"cx" ,NULL + }, };static const struct adsp_pil_data cdsp_resource_init = {
@@ -531,15 +697,39 @@ static const struct adsp_pil_data cdsp_resource_init = { .ssr_name = "cdsp", .sysmon_name = "cdsp", .ssctl_id = 0x17, + .is_wpss = false, + .auto_boot = true, .clk_ids = (const char *[]) {"sway" ,"tbu" ,"bimc" ,"ahb_aon" ,"q6ss_slave" ,"q6ss_master" ,"q6_axim" ,NULL }, .num_clks = 7, + .proxy_pd_names = (const char *[]) { +"cx" ,NULL + }, +}; + +static const struct adsp_pil_data wpss_resource_init = { + .crash_reason_smem =626 , + .firmware_name ="wpss.mdt" , + .ssr_name ="wpss" , + .sysmon_name ="wpss" , + .ssctl_id =0x19 , + .is_wpss = true, + .auto_boot = false, + .load_state ="wpss" , + .clk_ids = (const char *[]) { +"ahb_bdg" ,"ahb" ,"rscp" ,NULL + }, + .num_clks =3 , + .proxy_pd_names = (const char *[]) { +"cx" ,"mx" ,NULL + }, };static const struct of_device_id adsp_of_match[] = { { .compatible ="qcom,qcs404-cdsp-pil" , .data = &cdsp_resource_init }, + { .compatible ="qcom,sc7280-wpss-pil" , .data = &wpss_resource_init }, { .compatible ="qcom,sdm845-adsp-pil" , .data = &adsp_resource_init }, { }, };
Signature · 1 line
2.7.4
Re: [PATCH v9 3/3] remoteproc: qcom: q6v5_wpss: Add support for sc7280 WPSS
Quoting Rakesh Pillai (2021-11-18 07:50:20)
Quoted 9 lines
Add support for PIL loading of WPSS processor for SC7280
- WPSS boot will be requested by the wifi driver and hence disable auto-boot for WPSS.
- Add a separate shutdown sequence handler for WPSS.
- Add multiple power-domain voting support
- Parse firmware-name from dtsi entrySigned-off-by Rakesh Pillai <[email protected]>---
Just a couple nitpicks. Otherwise looks good to me.
Quoted 43 lines
drivers/remoteproc/qcom_q6v5_adsp.c | 222 +++++++++++++++++++++++++++++++++--- 1 file changed, 206 insertions(+), 16 deletions(-)drivers/remoteproc/qcom_q6v5_adsp.c +8
-0@@ -32,6 +32,7 @@/* time out value */ #define ACK_TIMEOUT 1000 +#define ACK_TIMEOUT_US 1000000#define BOOT_FSM_TIMEOUT 10000/* mask values */ #define EVB_MASK GENMASK(27, 4)@@ -51,6 +52,8 @@#define QDSP6SS_CORE_CBCR 0x20#define QDSP6SS_SLEEP_CBCR 0x3c +#define QCOM_Q6V5_RPROC_PROXY_PD_MAX 3 +struct adsp_pil_data {int crash_reason_smem;const char *firmware_name;@@ -58,9 +61,13 @@ struct adsp_pil_data {const char *ssr_name;const char *sysmon_name;int ssctl_id; +bool is_wpss; +bool auto_boot;const char **clk_ids;int num_clks; +const char **proxy_pd_names; +const char *load_state; };struct qcom_adsp {@@ -93,11 +100,146 @@ struct qcom_adsp {void *mem_region;size_t mem_size; +struct device *proxy_pds[QCOM_Q6V5_RPROC_PROXY_PD_MAX ];
drivers/remoteproc/qcom_q6v5_adsp.c struct qcom_adsp { · line 113
Quoted 10 lines
drivers/remoteproc/qcom_q6v5_adsp.c +5
-0+size_t proxy_pd_count; +struct qcom_rproc_glink glink_subdev;struct qcom_rproc_ssr ssr_subdev;struct qcom_sysmon *sysmon; + +int (*shutdown)(struct qcom_adsp *adsp); }; +static int qcom_rproc_pds_attach(struct device *dev, struct device **devs,
Can 'devs' be replaced by 'struct qcom_adsp'? And then we can compare the size against ARRAY_SIZE(adsp->proxy_pds) instead of the #define.
Quoted 104 lines
drivers/remoteproc/qcom_q6v5_adsp.c +104
-0+ const char **pd_names) +{ +size_t num_pds =0 ; +int ret; +int i; + +if (!pd_names) +return 0 ; + +/* Handle single power domain */ +if (dev->pm_domain) { + devs[0 ] = dev; +pm_runtime_enable (dev); +return 1 ; + } + +while (pd_names[num_pds]) + num_pds++; + +if (num_pds >QCOM_Q6V5_RPROC_PROXY_PD_MAX ) +return -E2BIG ; + +for (i =0 ; i < num_pds; i++) { + devs[i] =dev_pm_domain_attach_by_name (dev, pd_names[i]); +if (IS_ERR_OR_NULL (devs[i])) { + ret =PTR_ERR (devs[i]) ? : -ENODATA ; + goto unroll_attach; + } + } + +return num_pds; + +unroll_attach: +for (i--; i >=0 ; i--) +dev_pm_domain_detach (devs[i], false); + +return ret; +} + +static void qcom_rproc_pds_detach (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +struct device *dev = adsp->dev; +int i; + +/* Handle single power domain */ +if (dev->pm_domain && pd_count) { +pm_runtime_disable (dev); +return ; + } + +for (i =0 ; i < pd_count; i++) +dev_pm_domain_detach (pds[i], false); +} + +static int qcom_rproc_pds_enable (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +int ret; +int i; + +for (i =0 ; i < pd_count; i++) { +dev_pm_genpd_set_performance_state (pds[i],INT_MAX ); + ret =pm_runtime_get_sync (pds[i]); +if (ret <0 ) { +pm_runtime_put_noidle (pds[i]); +dev_pm_genpd_set_performance_state (pds[i],0 ); + goto unroll_pd_votes; + } + } + +return 0 ; + +unroll_pd_votes: +for (i--; i >=0 ; i--) { +dev_pm_genpd_set_performance_state (pds[i],0 ); +pm_runtime_put (pds[i]); + } + +return ret; +} + +static void qcom_rproc_pds_disable (struct qcom_adsp *adsp,struct device **pds, +size_t pd_count) +{ +int i; + +for (i =0 ; i < pd_count; i++) { +dev_pm_genpd_set_performance_state (pds[i],0 ); +pm_runtime_put (pds[i]); + } +} + +static int qcom_wpss_shutdown (struct qcom_adsp *adsp) +{ +unsigned int val; + +regmap_write (adsp->halt_map, adsp->halt_lpass +LPASS_HALTREQ_REG ,1 ); + +/* Wait for halt ACK from QDSP6 */ +regmap_read_poll_timeout (adsp->halt_map, + adsp->halt_lpass +LPASS_HALTACK_REG , val, + val,1000 ,ACK_TIMEOUT_US ); +
drivers/remoteproc/qcom_q6v5_adsp.c struct qcom_adsp { · line 227
Quoted 10 lines
drivers/remoteproc/qcom_q6v5_adsp.c +10
-0+/* Assert the WPSS PDC Reset */ +reset_control_assert (adsp->pdc_sync_reset); +/* Place the WPSS processor into reset */ +reset_control_assert (adsp->restart); +/* wait after asserting subsystem restart from AOSS */ +usleep_range (200 ,205 ); +/* Remove the WPSS reset */ +reset_control_deassert (adsp->restart); +/* De-assert the WPSS PDC Reset */ +reset_control_deassert (adsp->pdc_sync_reset);
Please add newlines between comments and previous code. The above chunk is really hard to read.
Quoted 18 lines
drivers/remoteproc/qcom_q6v5_adsp.c +15
-0+ +usleep_range (100 ,105 ); + +clk_bulk_disable_unprepare (adsp->num_clks, adsp->clks); + +regmap_write (adsp->halt_map, adsp->halt_lpass +LPASS_HALTREQ_REG ,0 ); + +/* Wait for halt ACK from QDSP6 */ +regmap_read_poll_timeout (adsp->halt_map, + adsp->halt_lpass +LPASS_HALTACK_REG , val, + !val,1000 ,ACK_TIMEOUT_US ); + +return 0 ; +} +static int qcom_adsp_shutdown (struct qcom_adsp *adsp) {unsigned long timeout;