Embed resources specific to version of hexagon chip in device structure to avoid conditional check for manipulation of those resources in driver code. Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@xxxxxxxxxxxxxx> --- .../devicetree/bindings/remoteproc/qcom,q6v5.txt | 1 + drivers/remoteproc/qcom_q6v5_pil.c | 148 +++++++++++++++++---- 2 files changed, 126 insertions(+), 23 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt index 57cb49e..cbc165c 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -8,6 +8,7 @@ on the Qualcomm Hexagon core. Value type: <string> Definition: must be one of: "qcom,q6v5-pil" + "qcom,q6v56-pil" - reg: Usage: required diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c index 2e0caaa..b60dff3 100644 --- a/drivers/remoteproc/qcom_q6v5_pil.c +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -30,13 +30,13 @@ #include <linux/reset.h> #include <linux/soc/qcom/smem.h> #include <linux/soc/qcom/smem_state.h> +#include <linux/of_device.h> #include "remoteproc_internal.h" #include "qcom_mdt_loader.h" #include <linux/qcom_scm.h> -#define MBA_FIRMWARE_NAME "mba.b00" #define MPSS_FIRMWARE_NAME "modem.mdt" #define MPSS_CRASH_REASON_SMEM 421 @@ -93,13 +93,32 @@ #define QDSS_BHS_ON BIT(21) #define QDSS_LDO_BYP BIT(22) +struct q6_rproc_res { + char **proxy_clks; + int proxy_clk_cnt; + char **active_clks; + int active_clk_cnt; + char **proxy_regs; + int proxy_reg_cnt; + char **active_regs; + int active_reg_cnt; + int **proxy_reg_action; + int **active_reg_action; + int *proxy_reg_load; + int *active_reg_load; + int *proxy_reg_voltage; + int *active_reg_voltage; + char *q6_version; + char *q6_mba_image; + int (*q6_reset_init)(void *q, void *p); +}; struct q6v5 { struct device *dev; struct rproc *rproc; void __iomem *reg_base; void __iomem *rmb_base; - + void __iomem *restart_reg; struct regmap *halt_map; u32 halt_q6; u32 halt_modem; @@ -111,7 +130,7 @@ struct q6v5 { unsigned stop_bit; struct regulator_bulk_data supply[4]; - + const struct q6_rproc_res *q6_rproc_res; struct clk *ahb_clk; struct clk *axi_clk; struct clk *rom_clk; @@ -198,7 +217,7 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw) return 0; } -static const struct rproc_fw_ops q6v5_fw_ops = { +static const struct rproc_fw_ops q6_fw_ops = { .find_rsc_table = qcom_mdt_find_rsc_table, .load = q6v5_load, }; @@ -599,7 +618,7 @@ static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len) return qproc->mpss_region + offset; } -static const struct rproc_ops q6v5_ops = { +static const struct rproc_ops q6_ops = { .start = q6v5_start, .stop = q6v5_stop, .da_to_va = q6v5_da_to_va, @@ -725,17 +744,36 @@ static int q6v5_init_clocks(struct q6v5 *qproc) return 0; } -static int q6v5_init_reset(struct q6v5 *qproc) +static int q6v5_init_reset(void *q, void *p) { - qproc->mss_restart = devm_reset_control_get(qproc->dev, NULL); + struct q6v5 *qproc = q; + struct platform_device *pdev = p; + + qproc->mss_restart = devm_reset_control_get(&pdev->dev, NULL); if (IS_ERR(qproc->mss_restart)) { - dev_err(qproc->dev, "failed to acquire mss restart\n"); + dev_err(&pdev->dev, "failed to acquire mss restart\n"); return PTR_ERR(qproc->mss_restart); } return 0; } +static int q6v56_init_reset(void *q, void *p) +{ + struct resource *res; + struct q6v5 *qproc = q; + struct platform_device *pdev = p; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg"); + qproc->restart_reg = devm_ioremap(qproc->dev, res->start, + resource_size(res)); + if (IS_ERR(qproc->restart_reg)) { + dev_err(qproc->dev, "failed to get restart_reg\n"); + return PTR_ERR(qproc->restart_reg); + } + + return 0; +} static int q6v5_request_irq(struct q6v5 *qproc, struct platform_device *pdev, const char *name, @@ -803,20 +841,25 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) return 0; } -static int q6v5_probe(struct platform_device *pdev) +static int q6_probe(struct platform_device *pdev) { struct q6v5 *qproc; struct rproc *rproc; + const struct q6_rproc_res *desc; int ret; - rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, - MBA_FIRMWARE_NAME, sizeof(*qproc)); + desc = of_device_get_match_data(&pdev->dev); + if (!desc) + return -EINVAL; + + rproc = rproc_alloc(&pdev->dev, pdev->name, &q6_ops, + desc->q6_mba_image, sizeof(*qproc)); if (!rproc) { dev_err(&pdev->dev, "failed to allocate rproc\n"); return -ENOMEM; } - rproc->fw_ops = &q6v5_fw_ops; + rproc->fw_ops = &q6_fw_ops; qproc = (struct q6v5 *)rproc->priv; qproc->dev = &pdev->dev; @@ -826,6 +869,7 @@ static int q6v5_probe(struct platform_device *pdev) init_completion(&qproc->start_done); init_completion(&qproc->stop_done); + qproc->q6_rproc_res = desc; ret = q6v5_init_mem(qproc, pdev); if (ret) goto free_rproc; @@ -842,7 +886,7 @@ static int q6v5_probe(struct platform_device *pdev) if (ret) goto free_rproc; - ret = q6v5_init_reset(qproc); + ret = qproc->q6_rproc_res->q6_reset_init(qproc, pdev); if (ret) goto free_rproc; @@ -873,14 +917,12 @@ static int q6v5_probe(struct platform_device *pdev) goto free_rproc; return 0; - free_rproc: rproc_free(rproc); - return ret; } -static int q6v5_remove(struct platform_device *pdev) +static int q6_remove(struct platform_device *pdev) { struct q6v5 *qproc = platform_get_drvdata(pdev); @@ -890,20 +932,80 @@ static int q6v5_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id q6v5_of_match[] = { - { .compatible = "qcom,q6v5-pil", }, +char *proxy_8x96_reg_str[] = {"mx", "cx", "vdd_pll"}; +int proxy_8x96_reg_action[3][2] = { {0, 1}, {1, 1}, {1, 0} }; +int proxy_8x96_reg_load[] = {0, 100000, 100000}; +int proxy_8x96_reg_min_voltage[] = {1050000, 1250000, 0}; +char *proxy_8x96_clk_str[] = {"xo", "pnoc", "qdss"}; +char *active_8x96_clk_str[] = {"iface", "bus", "mem", "gpll0_mss_clk", + "snoc_axi_clk", "mnoc_axi_clk"}; + +static const struct q6_rproc_res msm_8996_res = { + .proxy_clks = proxy_8x96_clk_str, + .proxy_clk_cnt = 3, + .active_clks = active_8x96_clk_str, + .active_clk_cnt = 6, + .proxy_regs = proxy_8x96_reg_str, + .active_regs = NULL, + .proxy_reg_action = (int **)proxy_8x96_reg_action, + .proxy_reg_load = (int *)proxy_8x96_reg_load, + .active_reg_action = NULL, + .active_reg_load = NULL, + .proxy_reg_voltage = (int *)proxy_8x96_reg_min_voltage, + .active_reg_voltage = NULL, + .proxy_reg_cnt = 3, + .active_reg_cnt = 0, + .q6_reset_init = q6v56_init_reset, + .q6_version = "v56", + .q6_mba_image = "mba.mbn", +}; + +char *proxy_8x16_reg_str[] = {"mx", "cx", "pll"}; +char *active_8x16_reg_str[] = {"mss"}; +int proxy_8x16_reg_action[4][2] = { {0, 1}, {1, 0}, {1, 0} }; +int active_8x16_reg_action[1][2] = { {1, 1} }; +int proxy_8x16_reg_load[] = {100000, 0, 100000, 100000}; +int active_8x16_reg_load[] = {100000}; +int proxy_8x16_reg_min_voltage[] = {1050000, 0, 0}; +int active_8x16_reg_min_voltage[] = {1000000}; +char *proxy_8x16_clk_str[] = {"xo"}; +char *active_8x16_clk_str[] = {"iface", "bus", "mem"}; + +static const struct q6_rproc_res msm_8916_res = { + .proxy_clks = proxy_8x16_clk_str, + .proxy_clk_cnt = 1, + .active_clks = active_8x16_clk_str, + .active_clk_cnt = 3, + .proxy_regs = proxy_8x16_reg_str, + .active_regs = active_8x16_reg_str, + .proxy_reg_action = (int **)proxy_8x16_reg_action, + .proxy_reg_load = (int *)proxy_8x16_reg_load, + .active_reg_action = (int **)active_8x16_reg_action, + .active_reg_load = (int *)active_8x16_reg_load, + .proxy_reg_voltage = (int *)proxy_8x16_reg_min_voltage, + .active_reg_voltage = active_8x16_reg_min_voltage, + .proxy_reg_cnt = 3, + .active_reg_cnt = 1, + .q6_reset_init = q6v5_init_reset, + .q6_version = "v5", + .q6_mba_image = "mba.b00", +}; + +static const struct of_device_id q6_of_match[] = { + { .compatible = "qcom,q6v5-pil", .data = &msm_8916_res}, + { .compatible = "qcom,q6v56-pil", .data = &msm_8996_res}, { }, }; -static struct platform_driver q6v5_driver = { - .probe = q6v5_probe, - .remove = q6v5_remove, +static struct platform_driver q6_driver = { + .probe = q6_probe, + .remove = q6_remove, .driver = { .name = "qcom-q6v5-pil", - .of_match_table = q6v5_of_match, + .of_match_table = q6_of_match, }, }; -module_platform_driver(q6v5_driver); +module_platform_driver(q6_driver); MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon"); 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. -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html