aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2019-03-04 10:09:10 -0600
committerSuman Anna2019-03-04 10:09:10 -0600
commit06fe96b926cc076c8b3df0ade3e42b67a6390aae (patch)
treec000d4377efd59864a0bcebfc52564fb1f31b8f8
parent0b6cc121175c83e3a2fc6209f04c6551ffea9280 (diff)
parentd2fb19c469aa8799ba32b2aabb154703a0e69ed1 (diff)
downloadremoteproc-06fe96b926cc076c8b3df0ade3e42b67a6390aae.tar.gz
remoteproc-06fe96b926cc076c8b3df0ade3e42b67a6390aae.tar.xz
remoteproc-06fe96b926cc076c8b3df0ade3e42b67a6390aae.zip
Merge branch 'iommu-linux-4.19.y' of git://git.ti.com/rpmsg/iommu into rproc-linux-4.19.y
Merge in the updated iommu feature branch into remoteproc tree to pull in the necessary support to fix the DRA7 IPU1 boot issue and couple of DRA7 DSP idle issues with HW_AUTO setting. The DSP idle status is achieved across all the DSPs and boards only with the fix for errata i879. * 'iommu-linux-4.19.y' of git://git.ti.com/rpmsg/iommu: ARM: OMAP2+: Add workaround for DRA7 DSP MStandby errata i879 ARM: OMAP2+: Extend DRA7 IPU1 MMU pdata quirks to DSP MDMA MMUs ARM: OMAP2+: Use separate IOMMU pdata to fix DRA7 IPU1 boot iommu/omap: Fix boot issue on remoteprocs with AMMU/Unicache Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c80
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c24
-rw-r--r--drivers/iommu/omap-iommu.c17
-rw-r--r--drivers/iommu/omap-iommu.h2
-rw-r--r--include/linux/platform_data/iommu-omap.h2
6 files changed, 123 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index eeb1e8377d82..359c9b11d44b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -244,6 +244,7 @@ include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORC
244 244
245$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h 245$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h
246 246
247obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
247ifneq ($(CONFIG_OMAP_REMOTEPROC),) 248ifneq ($(CONFIG_OMAP_REMOTEPROC),)
248obj-y += remoteproc.o 249obj-y += remoteproc.o
249endif 250endif
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
new file mode 100644
index 000000000000..65e7d6ec8b27
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -0,0 +1,80 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * OMAP IOMMU quirks for various TI SoCs
4 *
5 * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/
6 * Suman Anna <s-anna@ti.com>
7 */
8
9#include <linux/platform_device.h>
10#include <linux/err.h>
11
12#include "omap_hwmod.h"
13#include "omap_device.h"
14#include "clockdomain.h"
15#include "powerdomain.h"
16
17static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
18 bool enable)
19{
20 static struct clockdomain *emu_clkdm;
21 static DEFINE_SPINLOCK(emu_lock);
22 static atomic_t count;
23 struct device_node *np = pdev->dev.of_node;
24
25 if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
26 return;
27
28 if (!emu_clkdm) {
29 emu_clkdm = clkdm_lookup("emu_clkdm");
30 if (WARN_ON_ONCE(!emu_clkdm))
31 return;
32 }
33
34 spin_lock(&emu_lock);
35
36 if (enable && (atomic_inc_return(&count) == 1))
37 clkdm_deny_idle(emu_clkdm);
38 else if (!enable && (atomic_dec_return(&count) == 0))
39 clkdm_allow_idle(emu_clkdm);
40
41 spin_unlock(&emu_lock);
42}
43
44int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
45 u8 *pwrst)
46{
47 struct powerdomain *pwrdm;
48 struct omap_device *od;
49 u8 next_pwrst;
50 int ret = 0;
51
52 od = to_omap_device(pdev);
53 if (!od)
54 return -ENODEV;
55
56 if (od->hwmods_cnt != 1)
57 return -EINVAL;
58
59 pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
60 if (!pwrdm)
61 return -EINVAL;
62
63 if (request) {
64 *pwrst = pwrdm_read_next_pwrst(pwrdm);
65 omap_iommu_dra7_emu_swsup_config(pdev, true);
66 }
67
68 if (*pwrst > PWRDM_POWER_RET)
69 goto out;
70
71 next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
72
73 ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
74
75out:
76 if (!request)
77 omap_iommu_dra7_emu_swsup_config(pdev, false);
78
79 return ret;
80}
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 268113a63c85..2271add0a661 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -49,6 +49,17 @@ struct pdata_init {
49static struct of_dev_auxdata omap_auxdata_lookup[]; 49static struct of_dev_auxdata omap_auxdata_lookup[];
50static struct twl4030_gpio_platform_data twl_gpio_auxdata; 50static struct twl4030_gpio_platform_data twl_gpio_auxdata;
51 51
52#if IS_ENABLED(CONFIG_OMAP_IOMMU)
53int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
54 u8 *pwrst);
55#else
56static inline int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev,
57 bool request, u8 *pwrst)
58{
59 return 0;
60}
61#endif
62
52#ifdef CONFIG_MACH_NOKIA_N8X0 63#ifdef CONFIG_MACH_NOKIA_N8X0
53static void __init omap2420_n8x0_legacy_init(void) 64static void __init omap2420_n8x0_legacy_init(void)
54{ 65{
@@ -451,6 +462,13 @@ static void __init omap5_uevm_legacy_init(void)
451#endif 462#endif
452 463
453#ifdef CONFIG_SOC_DRA7XX 464#ifdef CONFIG_SOC_DRA7XX
465static struct iommu_platform_data dra7_ipu1_dsp_iommu_pdata = {
466 .reset_name = "mmu_cache",
467 .assert_reset = omap_device_assert_hardreset,
468 .deassert_reset = omap_device_deassert_hardreset,
469 .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint,
470};
471
454static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1; 472static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1;
455static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2; 473static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2;
456static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3; 474static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3;
@@ -623,13 +641,13 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
623 OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc", 641 OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc",
624 &dra7_hsmmc_data_mmc3), 642 &dra7_hsmmc_data_mmc3),
625 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x40d01000, "40d01000.mmu", 643 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x40d01000, "40d01000.mmu",
626 &omap4_iommu_pdata), 644 &dra7_ipu1_dsp_iommu_pdata),
627 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu", 645 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu",
628 &omap4_iommu_pdata), 646 &dra7_ipu1_dsp_iommu_pdata),
629 OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu", 647 OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu",
630 &omap4_iommu_pdata), 648 &omap4_iommu_pdata),
631 OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu", 649 OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu",
632 &omap4_iommu_pdata), 650 &dra7_ipu1_dsp_iommu_pdata),
633 OF_DEV_AUXDATA("ti,dra7-ipu", 0x55020000, "55020000.ipu", 651 OF_DEV_AUXDATA("ti,dra7-ipu", 0x55020000, "55020000.ipu",
634 &omap4_ipu_dsp_pdata), 652 &omap4_ipu_dsp_pdata),
635 OF_DEV_AUXDATA("ti,dra7-ipu", 0x58820000, "58820000.ipu", 653 OF_DEV_AUXDATA("ti,dra7-ipu", 0x58820000, "58820000.ipu",
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index a3d0184e24f6..f623f76378a0 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -194,6 +194,14 @@ static int iommu_enable(struct omap_iommu *obj)
194 struct platform_device *pdev = to_platform_device(obj->dev); 194 struct platform_device *pdev = to_platform_device(obj->dev);
195 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev); 195 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
196 196
197 if (pdata && pdata->set_pwrdm_constraint) {
198 err = pdata->set_pwrdm_constraint(pdev, true, &obj->pwrst);
199 if (err) {
200 dev_warn(obj->dev, "pwrdm_constraint failed to be set, status = %d\n",
201 err);
202 }
203 }
204
197 if (pdata && pdata->deassert_reset) { 205 if (pdata && pdata->deassert_reset) {
198 err = pdata->deassert_reset(pdev, pdata->reset_name); 206 err = pdata->deassert_reset(pdev, pdata->reset_name);
199 if (err) { 207 if (err) {
@@ -213,6 +221,7 @@ static void iommu_disable(struct omap_iommu *obj)
213{ 221{
214 struct platform_device *pdev = to_platform_device(obj->dev); 222 struct platform_device *pdev = to_platform_device(obj->dev);
215 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev); 223 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
224 int ret;
216 225
217 omap2_iommu_disable(obj); 226 omap2_iommu_disable(obj);
218 227
@@ -220,6 +229,14 @@ static void iommu_disable(struct omap_iommu *obj)
220 229
221 if (pdata && pdata->assert_reset) 230 if (pdata && pdata->assert_reset)
222 pdata->assert_reset(pdev, pdata->reset_name); 231 pdata->assert_reset(pdev, pdata->reset_name);
232
233 if (pdata && pdata->set_pwrdm_constraint) {
234 ret = pdata->set_pwrdm_constraint(pdev, false, &obj->pwrst);
235 if (ret) {
236 dev_warn(obj->dev, "pwrdm_constraint failed to be reset, status = %d\n",
237 ret);
238 }
239 }
223} 240}
224 241
225/* 242/*
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h
index 1703159ef5af..7766d5a4f3f1 100644
--- a/drivers/iommu/omap-iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -81,6 +81,8 @@ struct omap_iommu {
81 81
82 struct iommu_device iommu; 82 struct iommu_device iommu;
83 struct iommu_group *group; 83 struct iommu_group *group;
84
85 u8 pwrst;
84}; 86};
85 87
86/** 88/**
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h
index e8b12dbf6170..1a0aa46a5ad6 100644
--- a/include/linux/platform_data/iommu-omap.h
+++ b/include/linux/platform_data/iommu-omap.h
@@ -16,4 +16,6 @@ struct iommu_platform_data {
16 const char *reset_name; 16 const char *reset_name;
17 int (*assert_reset)(struct platform_device *pdev, const char *name); 17 int (*assert_reset)(struct platform_device *pdev, const char *name);
18 int (*deassert_reset)(struct platform_device *pdev, const char *name); 18 int (*deassert_reset)(struct platform_device *pdev, const char *name);
19 int (*set_pwrdm_constraint)(struct platform_device *pdev, bool request,
20 u8 *pwrst);
19}; 21};