summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuanyuan Liu <yuanliu@codeaurora.org>2016-04-13 17:14:48 -0700
committerKyle Yan <kyan@codeaurora.org>2016-04-28 16:40:11 -0700
commitf02bb95a6ee8c2159885dca9d9ae981451f0a9f0 (patch)
treeffdbc103f9e9e59859e16484d2edb00fabd6b3ca
parent53c1ac8bc76c1a34064392f237638b6a3f55561a (diff)
icnss: Reset Adrastea before executing cold boot
Program MPM_CONFIG bit 0 to release reset to Adrastea before executing cold boot. CRs-Fixed: 986579 Change-Id: Ic9605be675c10ea2973e57ea5aae0e8ee2f893f2 Signed-off-by: Yuanyuan Liu <yuanliu@codeaurora.org>
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi5
-rw-r--r--drivers/soc/qcom/icnss.c54
2 files changed, 52 insertions, 7 deletions
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index 7c0eb08547a2..78c99ee81a12 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -2141,8 +2141,9 @@
qcom,icnss@18800000 {
compatible = "qcom,icnss";
- reg = <0x18800000 0x800000>;
- reg-names = "membase";
+ reg = <0x18800000 0x800000>,
+ <0x10AC000 0x20>;
+ reg-names = "membase", "mpm_config";
interrupts = <0 413 0 /* CE0 */ >,
<0 414 0 /* CE1 */ >,
<0 415 0 /* CE2 */ >,
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 84b47f789214..887e49e3beb6 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -68,6 +68,8 @@ struct icnss_qmi_event {
} while (0)
#endif
+#define MPM2_MPM_WCSSAON_CONFIG_OFFSET 0x18
+
struct ce_irq_list {
int irq;
irqreturn_t (*handler)(int, void *);
@@ -80,6 +82,8 @@ static struct {
u32 ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];
phys_addr_t mem_base_pa;
void __iomem *mem_base_va;
+ phys_addr_t mpm_config_pa;
+ void __iomem *mpm_config_va;
struct qmi_handle *wlfw_clnt;
struct list_head qmi_event_list;
spinlock_t qmi_event_lock;
@@ -163,11 +167,26 @@ out:
}
+static void icnss_adrastea_reset(void)
+{
+ uint32_t rdata = 0;
+
+ if (penv->mpm_config_va) {
+ writel_relaxed(0x1,
+ penv->mpm_config_va +
+ MPM2_MPM_WCSSAON_CONFIG_OFFSET);
+ while (rdata != 0x1)
+ rdata = readl_relaxed(penv->mpm_config_va +
+ MPM2_MPM_WCSSAON_CONFIG_OFFSET);
+ }
+}
+
static int icnss_adrastea_power_on(void)
{
int ret = 0;
- /* TZ API of power on adrastea */
+ /* Top level adrastea reset */
+ icnss_adrastea_reset();
return ret;
}
@@ -1176,17 +1195,32 @@ static int icnss_probe(struct platform_device *pdev)
penv->mem_base_pa = res->start;
penv->mem_base_va = ioremap(penv->mem_base_pa, resource_size(res));
if (!penv->mem_base_va) {
- pr_err("icnss: ioremap failed\n");
+ pr_err("%s: mem_base ioremap failed\n", __func__);
ret = -EINVAL;
goto out;
}
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "mpm_config");
+ if (!res) {
+ pr_err("%s: mpm_config not found\n", __func__);
+ ret = -EINVAL;
+ goto unmap_mem_base;
+ }
+ penv->mpm_config_pa = res->start;
+ penv->mpm_config_va = ioremap(penv->mpm_config_pa, resource_size(res));
+ if (!penv->mpm_config_va) {
+ pr_err("%s: mpm_config ioremap failed\n", __func__);
+ ret = -EINVAL;
+ goto unmap_mem_base;
+ }
+
for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
if (!res) {
pr_err("icnss: Fail to get IRQ-%d\n", i);
ret = -ENODEV;
- goto out;
+ goto unmap_mpm_config;
} else {
penv->ce_irqs[i] = res->start;
}
@@ -1202,7 +1236,7 @@ static int icnss_probe(struct platform_device *pdev)
if (!penv->msa_va) {
pr_err("%s: DMA alloc failed\n", __func__);
ret = -EINVAL;
- goto out;
+ goto unmap_mpm_config;
}
pr_debug("%s: MAS va: %p, MSA pa: %pa\n",
__func__, penv->msa_va, &penv->msa_pa);
@@ -1210,7 +1244,7 @@ static int icnss_probe(struct platform_device *pdev)
} else {
pr_err("%s: Fail to get MSA Memory Size\n", __func__);
ret = -ENODEV;
- goto out;
+ goto unmap_mpm_config;
}
penv->skip_qmi = of_property_read_bool(dev->of_node,
@@ -1258,6 +1292,12 @@ err_wlan_mode:
if (penv->msa_va)
dma_free_coherent(&pdev->dev, penv->msa_mem_size,
penv->msa_va, penv->msa_pa);
+unmap_mpm_config:
+ if (penv->mpm_config_va)
+ iounmap(penv->mpm_config_va);
+unmap_mem_base:
+ if (penv->mem_base_va)
+ iounmap(penv->mem_base_va);
out:
return ret;
}
@@ -1274,6 +1314,10 @@ static int icnss_remove(struct platform_device *pdev)
if (penv->msa_va)
dma_free_coherent(&pdev->dev, penv->msa_mem_size,
penv->msa_va, penv->msa_pa);
+ if (penv->mpm_config_va)
+ iounmap(penv->mpm_config_va);
+ if (penv->mem_base_va)
+ iounmap(penv->mem_base_va);
return 0;
}