Merge "soc: qcom: pil: Allow the MBA memory to be dynamic or a carveout"
This commit is contained in:
commit
8443ddbedd
4 changed files with 80 additions and 23 deletions
|
@ -89,6 +89,13 @@ Optional properties:
|
|||
- qcom,cx-ipeak-vote: Boolean- Present if we need to set bit 5 of cxip_lm_vote_clear
|
||||
during modem shutdown
|
||||
|
||||
One child node to represent the MBA image may be specified, when the MBA image
|
||||
needs to be loaded in a specifically carved out memory region.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "qcom,pil-mba-mem"
|
||||
- memory-region: A phandle that points to a reserved memory where the MBA image will be loaded.
|
||||
|
||||
Example:
|
||||
qcom,mss@fc880000 {
|
||||
compatible = "qcom,pil-q6v5-mss";
|
||||
|
@ -128,4 +135,9 @@ Example:
|
|||
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
|
||||
qcom,ssctl-instance-id = <12>;
|
||||
qcom,sysmon-id = <0>;
|
||||
|
||||
qcom,mba-mem@0 {
|
||||
compatible = "qcom,pil-mba-mem";
|
||||
memory-region = <&peripheral_mem>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2017, 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 and
|
||||
|
@ -332,6 +332,7 @@ int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path)
|
|||
struct modem_data *drv = dev_get_drvdata(pil->dev);
|
||||
struct q6v5_data *q6_drv = container_of(pil, struct q6v5_data, desc);
|
||||
int ret = 0;
|
||||
struct device *dma_dev = drv->mba_mem_dev_fixed ?: &drv->mba_mem_dev;
|
||||
s32 status;
|
||||
u64 val = is_timeout_disabled() ? 0 : pbl_mba_boot_timeout_ms * 1000;
|
||||
|
||||
|
@ -360,7 +361,7 @@ int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path)
|
|||
if (pil->subsys_vmid > 0)
|
||||
pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys,
|
||||
drv->q6->mba_dp_size);
|
||||
dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size,
|
||||
dma_free_attrs(dma_dev, drv->q6->mba_dp_size,
|
||||
drv->q6->mba_dp_virt, drv->q6->mba_dp_phys,
|
||||
&drv->attrs_dma);
|
||||
drv->q6->mba_dp_virt = NULL;
|
||||
|
@ -552,6 +553,7 @@ int pil_mss_reset_load_mba(struct pil_desc *pil)
|
|||
dma_addr_t mba_dp_phys, mba_dp_phys_end;
|
||||
int ret, count;
|
||||
const u8 *data;
|
||||
struct device *dma_dev = md->mba_mem_dev_fixed ?: &md->mba_mem_dev;
|
||||
|
||||
fw_name_p = drv->non_elf_image ? fw_name_legacy : fw_name;
|
||||
ret = request_firmware(&fw, fw_name_p, pil->dev);
|
||||
|
@ -570,11 +572,12 @@ int pil_mss_reset_load_mba(struct pil_desc *pil)
|
|||
|
||||
drv->mba_dp_size = SZ_1M;
|
||||
|
||||
arch_setup_dma_ops(&md->mba_mem_dev, 0, 0, NULL, 0);
|
||||
arch_setup_dma_ops(dma_dev, 0, 0, NULL, 0);
|
||||
|
||||
dma_dev->coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
|
||||
|
||||
md->mba_mem_dev.coherent_dma_mask =
|
||||
DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
|
||||
init_dma_attrs(&md->attrs_dma);
|
||||
dma_set_attr(DMA_ATTR_SKIP_ZEROING, &md->attrs_dma);
|
||||
dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &md->attrs_dma);
|
||||
|
||||
ret = request_firmware(&dp_fw, dp_name, pil->dev);
|
||||
|
@ -591,10 +594,10 @@ int pil_mss_reset_load_mba(struct pil_desc *pil)
|
|||
drv->mba_dp_size += drv->dp_size;
|
||||
}
|
||||
|
||||
mba_dp_virt = dma_alloc_attrs(&md->mba_mem_dev, drv->mba_dp_size,
|
||||
&mba_dp_phys, GFP_KERNEL, &md->attrs_dma);
|
||||
mba_dp_virt = dma_alloc_attrs(dma_dev, drv->mba_dp_size, &mba_dp_phys,
|
||||
GFP_KERNEL, &md->attrs_dma);
|
||||
if (!mba_dp_virt) {
|
||||
dev_err(pil->dev, "%s MBA metadata buffer allocation %zx bytes failed\n",
|
||||
dev_err(pil->dev, "%s MBA/DP buffer allocation %zx bytes failed\n",
|
||||
__func__, drv->mba_dp_size);
|
||||
ret = -ENOMEM;
|
||||
goto err_invalid_fw;
|
||||
|
@ -651,7 +654,7 @@ err_mss_reset:
|
|||
pil_assign_mem_to_linux(pil, drv->mba_dp_phys,
|
||||
drv->mba_dp_size);
|
||||
err_mba_data:
|
||||
dma_free_attrs(&md->mba_mem_dev, drv->mba_dp_size, drv->mba_dp_virt,
|
||||
dma_free_attrs(dma_dev, drv->mba_dp_size, drv->mba_dp_virt,
|
||||
drv->mba_dp_phys, &md->attrs_dma);
|
||||
err_invalid_fw:
|
||||
if (dp_fw)
|
||||
|
@ -670,14 +673,16 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
|
|||
s32 status;
|
||||
int ret;
|
||||
u64 val = is_timeout_disabled() ? 0 : modem_auth_timeout_ms * 1000;
|
||||
struct device *dma_dev = drv->mba_mem_dev_fixed ?: &drv->mba_mem_dev;
|
||||
DEFINE_DMA_ATTRS(attrs);
|
||||
|
||||
drv->mba_mem_dev.coherent_dma_mask =
|
||||
DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
|
||||
|
||||
dma_dev->coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
|
||||
dma_set_attr(DMA_ATTR_SKIP_ZEROING, &attrs);
|
||||
dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &attrs);
|
||||
/* Make metadata physically contiguous and 4K aligned. */
|
||||
mdata_virt = dma_alloc_attrs(&drv->mba_mem_dev, size, &mdata_phys,
|
||||
GFP_KERNEL, &attrs);
|
||||
mdata_virt = dma_alloc_attrs(dma_dev, size, &mdata_phys, GFP_KERNEL,
|
||||
&attrs);
|
||||
if (!mdata_virt) {
|
||||
dev_err(pil->dev, "%s MBA metadata buffer allocation %zx bytes failed\n",
|
||||
__func__, size);
|
||||
|
@ -694,8 +699,8 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
|
|||
if (ret) {
|
||||
pr_err("scm_call to unprotect modem metadata mem failed(rc:%d)\n",
|
||||
ret);
|
||||
dma_free_attrs(&drv->mba_mem_dev, size, mdata_virt,
|
||||
mdata_phys, &attrs);
|
||||
dma_free_attrs(dma_dev, size, mdata_virt, mdata_phys,
|
||||
&attrs);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -721,7 +726,7 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
|
|||
if (pil->subsys_vmid > 0)
|
||||
pil_assign_mem_to_linux(pil, mdata_phys, ALIGN(size, SZ_4K));
|
||||
|
||||
dma_free_attrs(&drv->mba_mem_dev, size, mdata_virt, mdata_phys, &attrs);
|
||||
dma_free_attrs(dma_dev, size, mdata_virt, mdata_phys, &attrs);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
@ -733,7 +738,7 @@ fail:
|
|||
if (pil->subsys_vmid > 0)
|
||||
pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys,
|
||||
drv->q6->mba_dp_size);
|
||||
dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size,
|
||||
dma_free_attrs(dma_dev, drv->q6->mba_dp_size,
|
||||
drv->q6->mba_dp_virt, drv->q6->mba_dp_phys,
|
||||
&drv->attrs_dma);
|
||||
drv->q6->mba_dp_virt = NULL;
|
||||
|
@ -785,6 +790,7 @@ static int pil_msa_mba_auth(struct pil_desc *pil)
|
|||
struct modem_data *drv = dev_get_drvdata(pil->dev);
|
||||
struct q6v5_data *q6_drv = container_of(pil, struct q6v5_data, desc);
|
||||
int ret;
|
||||
struct device *dma_dev = drv->mba_mem_dev_fixed ?: &drv->mba_mem_dev;
|
||||
s32 status;
|
||||
u64 val = is_timeout_disabled() ? 0 : modem_auth_timeout_ms * 1000;
|
||||
|
||||
|
@ -806,9 +812,9 @@ static int pil_msa_mba_auth(struct pil_desc *pil)
|
|||
pil_assign_mem_to_linux(pil,
|
||||
drv->q6->mba_dp_phys,
|
||||
drv->q6->mba_dp_size);
|
||||
dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size,
|
||||
drv->q6->mba_dp_virt,
|
||||
drv->q6->mba_dp_phys, &drv->attrs_dma);
|
||||
dma_free_attrs(dma_dev, drv->q6->mba_dp_size,
|
||||
drv->q6->mba_dp_virt, drv->q6->mba_dp_phys,
|
||||
&drv->attrs_dma);
|
||||
|
||||
drv->q6->mba_dp_virt = NULL;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2017, 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 and
|
||||
|
@ -32,6 +32,7 @@ struct modem_data {
|
|||
struct clk *xo;
|
||||
struct pil_desc desc;
|
||||
struct device mba_mem_dev;
|
||||
struct device *mba_mem_dev_fixed;
|
||||
struct dma_attrs attrs_dma;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2017, 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 and
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/ioport.h>
|
||||
|
@ -394,6 +395,11 @@ static int pil_mss_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
init_completion(&drv->stop_ack);
|
||||
|
||||
/* Probe the MBA mem device if present */
|
||||
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return pil_subsys_init(drv, pdev);
|
||||
}
|
||||
|
||||
|
@ -407,6 +413,33 @@ static int pil_mss_driver_exit(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pil_mba_mem_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct modem_data *drv;
|
||||
|
||||
if (!pdev->dev.parent) {
|
||||
pr_err("No parent found.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
drv = dev_get_drvdata(pdev->dev.parent);
|
||||
drv->mba_mem_dev_fixed = &pdev->dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mba_mem_match_table[] = {
|
||||
{ .compatible = "qcom,pil-mba-mem" },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver pil_mba_mem_driver = {
|
||||
.probe = pil_mba_mem_driver_probe,
|
||||
.driver = {
|
||||
.name = "pil-mba-mem",
|
||||
.of_match_table = mba_mem_match_table,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_device_id mss_match_table[] = {
|
||||
{ .compatible = "qcom,pil-q6v5-mss" },
|
||||
{ .compatible = "qcom,pil-q6v55-mss" },
|
||||
|
@ -426,7 +459,12 @@ static struct platform_driver pil_mss_driver = {
|
|||
|
||||
static int __init pil_mss_init(void)
|
||||
{
|
||||
return platform_driver_register(&pil_mss_driver);
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&pil_mba_mem_driver);
|
||||
if (!ret)
|
||||
ret = platform_driver_register(&pil_mss_driver);
|
||||
return ret;
|
||||
}
|
||||
module_init(pil_mss_init);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue