From 9e004f97161d637d2dc82299be494bcfd07043bb Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 24 Sep 2018 16:45:25 -0700 Subject: remoteproc: qcom: Rename Hexagon v5 PAS driver The Hexagon v5 ADSP driver is used for more than only the ADSP and there's an upcoming non-PAS ADSP PIL for SDM845, so rename the driver to qcom_q6v5_pas in order to better suite this. Cc: Rohit kumar Reviewed-by: Niklas Cassel Signed-off-by: Bjorn Andersson --- drivers/remoteproc/Kconfig | 27 +-- drivers/remoteproc/Makefile | 2 +- drivers/remoteproc/qcom_adsp_pil.c | 386 ------------------------------------- drivers/remoteproc/qcom_q6v5_pas.c | 386 +++++++++++++++++++++++++++++++++++++ 4 files changed, 401 insertions(+), 400 deletions(-) delete mode 100644 drivers/remoteproc/qcom_adsp_pil.c create mode 100644 drivers/remoteproc/qcom_q6v5_pas.c (limited to 'drivers/remoteproc') diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 052d4dd347f9..425e502c6471 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -84,8 +84,16 @@ config KEYSTONE_REMOTEPROC 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. -config QCOM_ADSP_PIL - tristate "Qualcomm ADSP Peripheral Image Loader" +config QCOM_RPROC_COMMON + tristate + +config QCOM_Q6V5_COMMON + tristate + depends on ARCH_QCOM + depends on QCOM_SMEM + +config QCOM_Q6V5_PAS + tristate "Qualcomm Hexagon v5 Peripheral Authentication Service support" depends on OF && ARCH_QCOM depends on QCOM_SMEM depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) @@ -98,15 +106,7 @@ config QCOM_ADSP_PIL select QCOM_SCM help Say y here to support the TrustZone based Peripherial Image Loader - for the Qualcomm ADSP remote processors. - -config QCOM_RPROC_COMMON - tristate - -config QCOM_Q6V5_COMMON - tristate - depends on ARCH_QCOM - depends on QCOM_SMEM + for the Qualcomm Hexagon v5 based remote processors. config QCOM_Q6V5_PIL tristate "Qualcomm Hexagon V5 Peripherial Image Loader" @@ -120,8 +120,9 @@ config QCOM_Q6V5_PIL select QCOM_RPROC_COMMON select QCOM_SCM help - Say y here to support the Qualcomm Peripherial Image Loader for the - Hexagon V5 based remote processors. + Say y here to support the TrustZone based Peripherial Image Loader + 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 tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader" diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 03332fa7e2ee..eb86c8ba5a87 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -14,9 +14,9 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_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_Q6V5_COMMON) += qcom_q6v5.o +obj-$(CONFIG_QCOM_Q6V5_PAS) += qcom_q6v5_pas.o obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o obj-$(CONFIG_QCOM_Q6V5_WCSS) += qcom_q6v5_wcss.o obj-$(CONFIG_QCOM_SYSMON) += qcom_sysmon.o diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c deleted file mode 100644 index da2254ea1135..000000000000 --- a/drivers/remoteproc/qcom_adsp_pil.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996 - * - * Copyright (C) 2016 Linaro Ltd - * Copyright (C) 2014 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qcom_common.h" -#include "qcom_q6v5.h" -#include "remoteproc_internal.h" - -struct adsp_data { - int crash_reason_smem; - const char *firmware_name; - int pas_id; - bool has_aggre2_clk; - - const char *ssr_name; - const char *sysmon_name; - int ssctl_id; -}; - -struct qcom_adsp { - struct device *dev; - struct rproc *rproc; - - struct qcom_q6v5 q6v5; - - struct clk *xo; - struct clk *aggre2_clk; - - struct regulator *cx_supply; - struct regulator *px_supply; - - int pas_id; - int crash_reason_smem; - bool has_aggre2_clk; - - 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; - - struct qcom_rproc_glink glink_subdev; - struct qcom_rproc_subdev smd_subdev; - struct qcom_rproc_ssr ssr_subdev; - struct qcom_sysmon *sysmon; -}; - -static int adsp_load(struct rproc *rproc, const struct firmware *fw) -{ - struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; - - return qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id, - adsp->mem_region, adsp->mem_phys, adsp->mem_size, - &adsp->mem_reloc); - -} - -static int adsp_start(struct rproc *rproc) -{ - struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; - int ret; - - qcom_q6v5_prepare(&adsp->q6v5); - - ret = clk_prepare_enable(adsp->xo); - if (ret) - return ret; - - ret = clk_prepare_enable(adsp->aggre2_clk); - if (ret) - goto disable_xo_clk; - - ret = regulator_enable(adsp->cx_supply); - if (ret) - goto disable_aggre2_clk; - - ret = regulator_enable(adsp->px_supply); - if (ret) - goto disable_cx_supply; - - ret = qcom_scm_pas_auth_and_reset(adsp->pas_id); - if (ret) { - dev_err(adsp->dev, - "failed to authenticate image and release reset\n"); - goto disable_px_supply; - } - - ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000)); - if (ret == -ETIMEDOUT) { - dev_err(adsp->dev, "start timed out\n"); - qcom_scm_pas_shutdown(adsp->pas_id); - goto disable_px_supply; - } - - return 0; - -disable_px_supply: - regulator_disable(adsp->px_supply); -disable_cx_supply: - regulator_disable(adsp->cx_supply); -disable_aggre2_clk: - clk_disable_unprepare(adsp->aggre2_clk); -disable_xo_clk: - clk_disable_unprepare(adsp->xo); - - return ret; -} - -static void qcom_pas_handover(struct qcom_q6v5 *q6v5) -{ - struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); - - regulator_disable(adsp->px_supply); - regulator_disable(adsp->cx_supply); - clk_disable_unprepare(adsp->aggre2_clk); - clk_disable_unprepare(adsp->xo); -} - -static int adsp_stop(struct rproc *rproc) -{ - struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; - int handover; - int ret; - - ret = qcom_q6v5_request_stop(&adsp->q6v5); - if (ret == -ETIMEDOUT) - dev_err(adsp->dev, "timed out on wait\n"); - - ret = qcom_scm_pas_shutdown(adsp->pas_id); - if (ret) - dev_err(adsp->dev, "failed to shutdown: %d\n", ret); - - handover = qcom_q6v5_unprepare(&adsp->q6v5); - if (handover) - qcom_pas_handover(&adsp->q6v5); - - return ret; -} - -static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len) -{ - struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; - int offset; - - offset = da - adsp->mem_reloc; - if (offset < 0 || offset + len > adsp->mem_size) - return NULL; - - return adsp->mem_region + offset; -} - -static const struct rproc_ops adsp_ops = { - .start = adsp_start, - .stop = adsp_stop, - .da_to_va = adsp_da_to_va, - .parse_fw = qcom_register_dump_segments, - .load = adsp_load, -}; - -static int adsp_init_clock(struct qcom_adsp *adsp) -{ - int ret; - - adsp->xo = devm_clk_get(adsp->dev, "xo"); - if (IS_ERR(adsp->xo)) { - ret = PTR_ERR(adsp->xo); - if (ret != -EPROBE_DEFER) - dev_err(adsp->dev, "failed to get xo clock"); - return ret; - } - - if (adsp->has_aggre2_clk) { - adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2"); - if (IS_ERR(adsp->aggre2_clk)) { - ret = PTR_ERR(adsp->aggre2_clk); - if (ret != -EPROBE_DEFER) - dev_err(adsp->dev, - "failed to get aggre2 clock"); - return ret; - } - } - - return 0; -} - -static int adsp_init_regulator(struct qcom_adsp *adsp) -{ - adsp->cx_supply = devm_regulator_get(adsp->dev, "cx"); - if (IS_ERR(adsp->cx_supply)) - return PTR_ERR(adsp->cx_supply); - - regulator_set_load(adsp->cx_supply, 100000); - - adsp->px_supply = devm_regulator_get(adsp->dev, "px"); - return PTR_ERR_OR_ZERO(adsp->px_supply); -} - -static int adsp_alloc_memory_region(struct qcom_adsp *adsp) -{ - struct device_node *node; - struct resource r; - int ret; - - node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0); - if (!node) { - dev_err(adsp->dev, "no memory-region specified\n"); - return -EINVAL; - } - - ret = of_address_to_resource(node, 0, &r); - if (ret) - return ret; - - adsp->mem_phys = adsp->mem_reloc = r.start; - adsp->mem_size = resource_size(&r); - adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size); - if (!adsp->mem_region) { - dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n", - &r.start, adsp->mem_size); - return -EBUSY; - } - - return 0; -} - -static int adsp_probe(struct platform_device *pdev) -{ - const struct adsp_data *desc; - struct qcom_adsp *adsp; - struct rproc *rproc; - int ret; - - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; - - if (!qcom_scm_is_available()) - return -EPROBE_DEFER; - - rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, - desc->firmware_name, sizeof(*adsp)); - if (!rproc) { - dev_err(&pdev->dev, "unable to allocate remoteproc\n"); - return -ENOMEM; - } - - adsp = (struct qcom_adsp *)rproc->priv; - adsp->dev = &pdev->dev; - adsp->rproc = rproc; - adsp->pas_id = desc->pas_id; - adsp->has_aggre2_clk = desc->has_aggre2_clk; - platform_set_drvdata(pdev, adsp); - - ret = adsp_alloc_memory_region(adsp); - if (ret) - goto free_rproc; - - ret = adsp_init_clock(adsp); - if (ret) - goto free_rproc; - - ret = adsp_init_regulator(adsp); - if (ret) - goto free_rproc; - - ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, - qcom_pas_handover); - if (ret) - goto free_rproc; - - qcom_add_glink_subdev(rproc, &adsp->glink_subdev); - qcom_add_smd_subdev(rproc, &adsp->smd_subdev); - qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); - adsp->sysmon = qcom_add_sysmon_subdev(rproc, - desc->sysmon_name, - desc->ssctl_id); - - ret = rproc_add(rproc); - if (ret) - goto free_rproc; - - return 0; - -free_rproc: - rproc_free(rproc); - - return ret; -} - -static int adsp_remove(struct platform_device *pdev) -{ - struct qcom_adsp *adsp = platform_get_drvdata(pdev); - - rproc_del(adsp->rproc); - - qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); - qcom_remove_sysmon_subdev(adsp->sysmon); - qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev); - qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); - rproc_free(adsp->rproc); - - return 0; -} - -static const struct adsp_data adsp_resource_init = { - .crash_reason_smem = 423, - .firmware_name = "adsp.mdt", - .pas_id = 1, - .has_aggre2_clk = false, - .ssr_name = "lpass", - .sysmon_name = "adsp", - .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 = { - .crash_reason_smem = 424, - .firmware_name = "slpi.mdt", - .pas_id = 12, - .has_aggre2_clk = true, - .ssr_name = "dsps", - .sysmon_name = "slpi", - .ssctl_id = 0x16, -}; - -static const struct of_device_id adsp_of_match[] = { - { .compatible = "qcom,msm8974-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,sdm845-adsp-pas", .data = &adsp_resource_init}, - { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, - { }, -}; -MODULE_DEVICE_TABLE(of, adsp_of_match); - -static struct platform_driver adsp_driver = { - .probe = adsp_probe, - .remove = adsp_remove, - .driver = { - .name = "qcom_adsp_pil", - .of_match_table = adsp_of_match, - }, -}; - -module_platform_driver(adsp_driver); -MODULE_DESCRIPTION("Qualcomm MSM8974/MSM8996 ADSP Peripherial Image Loader"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c new file mode 100644 index 000000000000..03edf08c8a2f --- /dev/null +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -0,0 +1,386 @@ +/* + * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996 + * + * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2014 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qcom_common.h" +#include "qcom_q6v5.h" +#include "remoteproc_internal.h" + +struct adsp_data { + int crash_reason_smem; + const char *firmware_name; + int pas_id; + bool has_aggre2_clk; + + const char *ssr_name; + const char *sysmon_name; + int ssctl_id; +}; + +struct qcom_adsp { + struct device *dev; + struct rproc *rproc; + + struct qcom_q6v5 q6v5; + + struct clk *xo; + struct clk *aggre2_clk; + + struct regulator *cx_supply; + struct regulator *px_supply; + + int pas_id; + int crash_reason_smem; + bool has_aggre2_clk; + + 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; + + struct qcom_rproc_glink glink_subdev; + struct qcom_rproc_subdev smd_subdev; + struct qcom_rproc_ssr ssr_subdev; + struct qcom_sysmon *sysmon; +}; + +static int adsp_load(struct rproc *rproc, const struct firmware *fw) +{ + struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; + + return qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id, + adsp->mem_region, adsp->mem_phys, adsp->mem_size, + &adsp->mem_reloc); + +} + +static int adsp_start(struct rproc *rproc) +{ + struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; + int ret; + + qcom_q6v5_prepare(&adsp->q6v5); + + ret = clk_prepare_enable(adsp->xo); + if (ret) + return ret; + + ret = clk_prepare_enable(adsp->aggre2_clk); + if (ret) + goto disable_xo_clk; + + ret = regulator_enable(adsp->cx_supply); + if (ret) + goto disable_aggre2_clk; + + ret = regulator_enable(adsp->px_supply); + if (ret) + goto disable_cx_supply; + + ret = qcom_scm_pas_auth_and_reset(adsp->pas_id); + if (ret) { + dev_err(adsp->dev, + "failed to authenticate image and release reset\n"); + goto disable_px_supply; + } + + ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000)); + if (ret == -ETIMEDOUT) { + dev_err(adsp->dev, "start timed out\n"); + qcom_scm_pas_shutdown(adsp->pas_id); + goto disable_px_supply; + } + + return 0; + +disable_px_supply: + regulator_disable(adsp->px_supply); +disable_cx_supply: + regulator_disable(adsp->cx_supply); +disable_aggre2_clk: + clk_disable_unprepare(adsp->aggre2_clk); +disable_xo_clk: + clk_disable_unprepare(adsp->xo); + + return ret; +} + +static void qcom_pas_handover(struct qcom_q6v5 *q6v5) +{ + struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); + + regulator_disable(adsp->px_supply); + regulator_disable(adsp->cx_supply); + clk_disable_unprepare(adsp->aggre2_clk); + clk_disable_unprepare(adsp->xo); +} + +static int adsp_stop(struct rproc *rproc) +{ + struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; + int handover; + int ret; + + ret = qcom_q6v5_request_stop(&adsp->q6v5); + if (ret == -ETIMEDOUT) + dev_err(adsp->dev, "timed out on wait\n"); + + ret = qcom_scm_pas_shutdown(adsp->pas_id); + if (ret) + dev_err(adsp->dev, "failed to shutdown: %d\n", ret); + + handover = qcom_q6v5_unprepare(&adsp->q6v5); + if (handover) + qcom_pas_handover(&adsp->q6v5); + + return ret; +} + +static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len) +{ + struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; + int offset; + + offset = da - adsp->mem_reloc; + if (offset < 0 || offset + len > adsp->mem_size) + return NULL; + + return adsp->mem_region + offset; +} + +static const struct rproc_ops adsp_ops = { + .start = adsp_start, + .stop = adsp_stop, + .da_to_va = adsp_da_to_va, + .parse_fw = qcom_register_dump_segments, + .load = adsp_load, +}; + +static int adsp_init_clock(struct qcom_adsp *adsp) +{ + int ret; + + adsp->xo = devm_clk_get(adsp->dev, "xo"); + if (IS_ERR(adsp->xo)) { + ret = PTR_ERR(adsp->xo); + if (ret != -EPROBE_DEFER) + dev_err(adsp->dev, "failed to get xo clock"); + return ret; + } + + if (adsp->has_aggre2_clk) { + adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2"); + if (IS_ERR(adsp->aggre2_clk)) { + ret = PTR_ERR(adsp->aggre2_clk); + if (ret != -EPROBE_DEFER) + dev_err(adsp->dev, + "failed to get aggre2 clock"); + return ret; + } + } + + return 0; +} + +static int adsp_init_regulator(struct qcom_adsp *adsp) +{ + adsp->cx_supply = devm_regulator_get(adsp->dev, "cx"); + if (IS_ERR(adsp->cx_supply)) + return PTR_ERR(adsp->cx_supply); + + regulator_set_load(adsp->cx_supply, 100000); + + adsp->px_supply = devm_regulator_get(adsp->dev, "px"); + return PTR_ERR_OR_ZERO(adsp->px_supply); +} + +static int adsp_alloc_memory_region(struct qcom_adsp *adsp) +{ + struct device_node *node; + struct resource r; + int ret; + + node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0); + if (!node) { + dev_err(adsp->dev, "no memory-region specified\n"); + return -EINVAL; + } + + ret = of_address_to_resource(node, 0, &r); + if (ret) + return ret; + + adsp->mem_phys = adsp->mem_reloc = r.start; + adsp->mem_size = resource_size(&r); + adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size); + if (!adsp->mem_region) { + dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n", + &r.start, adsp->mem_size); + return -EBUSY; + } + + return 0; +} + +static int adsp_probe(struct platform_device *pdev) +{ + const struct adsp_data *desc; + struct qcom_adsp *adsp; + struct rproc *rproc; + int ret; + + desc = of_device_get_match_data(&pdev->dev); + if (!desc) + return -EINVAL; + + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, + desc->firmware_name, sizeof(*adsp)); + if (!rproc) { + dev_err(&pdev->dev, "unable to allocate remoteproc\n"); + return -ENOMEM; + } + + adsp = (struct qcom_adsp *)rproc->priv; + adsp->dev = &pdev->dev; + adsp->rproc = rproc; + adsp->pas_id = desc->pas_id; + adsp->has_aggre2_clk = desc->has_aggre2_clk; + platform_set_drvdata(pdev, adsp); + + ret = adsp_alloc_memory_region(adsp); + if (ret) + goto free_rproc; + + ret = adsp_init_clock(adsp); + if (ret) + goto free_rproc; + + ret = adsp_init_regulator(adsp); + if (ret) + goto free_rproc; + + ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, + qcom_pas_handover); + if (ret) + goto free_rproc; + + qcom_add_glink_subdev(rproc, &adsp->glink_subdev); + qcom_add_smd_subdev(rproc, &adsp->smd_subdev); + qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); + adsp->sysmon = qcom_add_sysmon_subdev(rproc, + desc->sysmon_name, + desc->ssctl_id); + + ret = rproc_add(rproc); + if (ret) + goto free_rproc; + + return 0; + +free_rproc: + rproc_free(rproc); + + return ret; +} + +static int adsp_remove(struct platform_device *pdev) +{ + struct qcom_adsp *adsp = platform_get_drvdata(pdev); + + rproc_del(adsp->rproc); + + qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); + qcom_remove_sysmon_subdev(adsp->sysmon); + qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev); + qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); + rproc_free(adsp->rproc); + + return 0; +} + +static const struct adsp_data adsp_resource_init = { + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .pas_id = 1, + .has_aggre2_clk = false, + .ssr_name = "lpass", + .sysmon_name = "adsp", + .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 = { + .crash_reason_smem = 424, + .firmware_name = "slpi.mdt", + .pas_id = 12, + .has_aggre2_clk = true, + .ssr_name = "dsps", + .sysmon_name = "slpi", + .ssctl_id = 0x16, +}; + +static const struct of_device_id adsp_of_match[] = { + { .compatible = "qcom,msm8974-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,sdm845-adsp-pas", .data = &adsp_resource_init}, + { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, + { }, +}; +MODULE_DEVICE_TABLE(of, adsp_of_match); + +static struct platform_driver adsp_driver = { + .probe = adsp_probe, + .remove = adsp_remove, + .driver = { + .name = "qcom_q6v5_pas", + .of_match_table = adsp_of_match, + }, +}; + +module_platform_driver(adsp_driver); +MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b