aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2019-03-04 10:21:56 -0600
committerSuman Anna2019-03-04 10:22:56 -0600
commit8a953aee290af1ad27ce85e258c09f4a109916bd (patch)
tree2ce20273f258ea14ef01b2dbb93fc22773e22efe
parente80509505068ed7649a88c021128b7895a90b340 (diff)
parentcb6320f7002078445ba5cebb5cdefca75136e052 (diff)
downloadafd-analog-8a953aee290af1ad27ce85e258c09f4a109916bd.tar.gz
afd-analog-8a953aee290af1ad27ce85e258c09f4a109916bd.tar.xz
afd-analog-8a953aee290af1ad27ce85e258c09f4a109916bd.zip
Merge branch 'rproc-linux-4.19.y' of git://git.ti.com/rpmsg/remoteproc into rpmsg-ti-linux-4.19.y
Pull in the updated remoteproc feature branch that adds the support for system suspend/resume and runtime auto-suspend/resume support on the IPU and DSP remote processors on OMAP4, OMAP5 and DRA7 SoCs. The feature branch merge also pulls in automatically the dependent OMAP iommu feature branch with suspend/resume support. OMAP mailbox driver already has the suspend/resume support in upstream 4.19 kernel. * 'rproc-linux-4.19.y' of git://git.ti.com/rpmsg/remoteproc: remoteproc: Fix sysfs interface to stop a suspended processor remoteproc/omap: add support for runtime auto-suspend/resume remoteproc/omap: add support for system suspend/resume ARM: dts: dra7: Add standby info for IPU & DSPs ARM: dts: omap5: Add standby info for IPU and DSP ARM: dts: omap4: Add standby info for IPU and DSP dt-bindings: remoteproc: Update omap remoteproc binding for suspend iommu/omap: introduce new API for runtime suspend/resume control iommu/omap: Add system suspend/resume support iommu/omap: add logic to save/restore locked TLBs iommu/omap: streamline enable/disable through runtime pm callbacks ARM: OMAP2+: add pdata-quirks for OMAP3 ISP IOMMU ARM: OMAP2+: Add iommu pdata-quirks for DRA7 DSP EDMA MMUs ARM: OMAP2+: plug in device_enable/idle ops for IOMMUs iommu/omap: add pdata ops for omap_device_enable/idle Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.txt8
-rw-r--r--arch/arm/boot/dts/dra7.dtsi3
-rw-r--r--arch/arm/boot/dts/dra74x.dtsi1
-rw-r--r--arch/arm/boot/dts/omap4.dtsi2
-rw-r--r--arch/arm/boot/dts/omap5.dtsi2
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c22
-rw-r--r--drivers/iommu/omap-iommu.c280
-rw-r--r--drivers/iommu/omap-iommu.h3
-rw-r--r--drivers/remoteproc/omap_remoteproc.c432
-rw-r--r--drivers/remoteproc/omap_remoteproc.h18
-rw-r--r--drivers/remoteproc/remoteproc_sysfs.c3
-rw-r--r--include/linux/omap-iommu.h15
-rw-r--r--include/linux/platform_data/iommu-omap.h2
13 files changed, 745 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.txt
index d5aeb1aa2784..873481b552a2 100644
--- a/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.txt
+++ b/Documentation/devicetree/bindings/remoteproc/ti,omap-remoteproc.txt
@@ -117,6 +117,11 @@ The following are the optional properties:
117 The timers to be used should match with the watchdog 117 The timers to be used should match with the watchdog
118 timers used in the firmware image. 118 timers used in the firmware image.
119 119
120- ti,rproc-standby-info: Standby data for the remote processor. This is
121 mandatory to support Power Management for the OMAP
122 remoteprocs, and should contain the address containing
123 the module standby status.
124
120Example: 125Example:
121-------- 126--------
122 127
@@ -141,6 +146,7 @@ Example:
141 ti,hwmods = "dsp"; 146 ti,hwmods = "dsp";
142 syscon-bootreg = <&scm_conf 0x304>; 147 syscon-bootreg = <&scm_conf 0x304>;
143 iommus = <&mmu_dsp>; 148 iommus = <&mmu_dsp>;
149 ti,rproc-standby-info = <0x4a004420>;
144 mboxes = <&mailbox &mbox_dsp>; 150 mboxes = <&mailbox &mbox_dsp>;
145 memory-region = <&dsp_memory_region>; 151 memory-region = <&dsp_memory_region>;
146 timers = <&timer5>; 152 timers = <&timer5>;
@@ -170,6 +176,7 @@ Example:
170 reg-names = "l2ram"; 176 reg-names = "l2ram";
171 ti,hwmods = "ipu"; 177 ti,hwmods = "ipu";
172 iommus = <&mmu_ipu>; 178 iommus = <&mmu_ipu>;
179 ti,rproc-standby-info = <0x4a008920>;
173 mboxes = <&mailbox &mbox_ipu>; 180 mboxes = <&mailbox &mbox_ipu>;
174 memory-region = <&ipu_memory_region>; 181 memory-region = <&ipu_memory_region>;
175 timers = <&timer3>, <&timer4>; 182 timers = <&timer3>, <&timer4>;
@@ -202,6 +209,7 @@ Example:
202 ti,hwmods = "dsp1"; 209 ti,hwmods = "dsp1";
203 syscon-bootreg = <&scm_conf 0x55c>; 210 syscon-bootreg = <&scm_conf 0x55c>;
204 iommus = <&mmu0_dsp1>, <&mmu1_dsp1>; 211 iommus = <&mmu0_dsp1>, <&mmu1_dsp1>;
212 ti,rproc-standby-info = <0x4a005420>;
205 mboxes = <&mailbox5 &mbox_dsp1_ipc3x>; 213 mboxes = <&mailbox5 &mbox_dsp1_ipc3x>;
206 memory-region = <&dsp1_memory_region>; 214 memory-region = <&dsp1_memory_region>;
207 timers = <&timer5>; 215 timers = <&timer5>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 1b37091d5fde..af178ac5e55b 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1064,6 +1064,7 @@
1064 reg-names = "l2ram"; 1064 reg-names = "l2ram";
1065 ti,hwmods = "ipu1"; 1065 ti,hwmods = "ipu1";
1066 iommus = <&mmu_ipu1>; 1066 iommus = <&mmu_ipu1>;
1067 ti,rproc-standby-info = <0x4a005520>;
1067 status = "disabled"; 1068 status = "disabled";
1068 }; 1069 };
1069 1070
@@ -1073,6 +1074,7 @@
1073 reg-names = "l2ram"; 1074 reg-names = "l2ram";
1074 ti,hwmods = "ipu2"; 1075 ti,hwmods = "ipu2";
1075 iommus = <&mmu_ipu2>; 1076 iommus = <&mmu_ipu2>;
1077 ti,rproc-standby-info = <0x4a008920>;
1076 status = "disabled"; 1078 status = "disabled";
1077 }; 1079 };
1078 1080
@@ -1085,6 +1087,7 @@
1085 ti,hwmods = "dsp1"; 1087 ti,hwmods = "dsp1";
1086 syscon-bootreg = <&scm_conf 0x55c>; 1088 syscon-bootreg = <&scm_conf 0x55c>;
1087 iommus = <&mmu0_dsp1>, <&mmu1_dsp1>; 1089 iommus = <&mmu0_dsp1>, <&mmu1_dsp1>;
1090 ti,rproc-standby-info = <0x4a005420>;
1088 status = "disabled"; 1091 status = "disabled";
1089 }; 1092 };
1090 1093
diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi
index 492ee7d355ef..5f7c8922a07c 100644
--- a/arch/arm/boot/dts/dra74x.dtsi
+++ b/arch/arm/boot/dts/dra74x.dtsi
@@ -102,6 +102,7 @@
102 ti,hwmods = "dsp2"; 102 ti,hwmods = "dsp2";
103 syscon-bootreg = <&scm_conf 0x560>; 103 syscon-bootreg = <&scm_conf 0x560>;
104 iommus = <&mmu0_dsp2>, <&mmu1_dsp2>; 104 iommus = <&mmu0_dsp2>, <&mmu1_dsp2>;
105 ti,rproc-standby-info = <0x4a005620>;
105 status = "disabled"; 106 status = "disabled";
106 }; 107 };
107 }; 108 };
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index f51870087ba5..ecc67a244d55 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -464,6 +464,7 @@
464 ti,hwmods = "dsp"; 464 ti,hwmods = "dsp";
465 syscon-bootreg = <&scm_conf 0x304>; 465 syscon-bootreg = <&scm_conf 0x304>;
466 iommus = <&mmu_dsp>; 466 iommus = <&mmu_dsp>;
467 ti,rproc-standby-info = <0x4a004420>;
467 mboxes = <&mailbox &mbox_dsp>; 468 mboxes = <&mailbox &mbox_dsp>;
468 status = "disabled"; 469 status = "disabled";
469 }; 470 };
@@ -474,6 +475,7 @@
474 reg-names = "l2ram"; 475 reg-names = "l2ram";
475 ti,hwmods = "ipu"; 476 ti,hwmods = "ipu";
476 iommus = <&mmu_ipu>; 477 iommus = <&mmu_ipu>;
478 ti,rproc-standby-info = <0x4a008920>;
477 mboxes = <&mailbox &mbox_ipu>; 479 mboxes = <&mailbox &mbox_ipu>;
478 status = "disabled"; 480 status = "disabled";
479 }; 481 };
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index d09180fb6fe3..51a8755689e5 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -901,6 +901,7 @@
901 ti,hwmods = "dsp"; 901 ti,hwmods = "dsp";
902 syscon-bootreg = <&scm_conf 0x304>; 902 syscon-bootreg = <&scm_conf 0x304>;
903 iommus = <&mmu_dsp>; 903 iommus = <&mmu_dsp>;
904 ti,rproc-standby-info = <0x4a004420>;
904 mboxes = <&mailbox &mbox_dsp>; 905 mboxes = <&mailbox &mbox_dsp>;
905 status = "disabled"; 906 status = "disabled";
906 }; 907 };
@@ -911,6 +912,7 @@
911 reg-names = "l2ram"; 912 reg-names = "l2ram";
912 ti,hwmods = "ipu"; 913 ti,hwmods = "ipu";
913 iommus = <&mmu_ipu>; 914 iommus = <&mmu_ipu>;
915 ti,rproc-standby-info = <0x4a008920>;
914 mboxes = <&mailbox &mbox_ipu>; 916 mboxes = <&mailbox &mbox_ipu>;
915 status = "disabled"; 917 status = "disabled";
916 }; 918 };
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 2271add0a661..9b6aec1fef88 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -104,6 +104,13 @@ static struct iommu_platform_data omap3_iommu_pdata = {
104 .reset_name = "mmu", 104 .reset_name = "mmu",
105 .assert_reset = omap_device_assert_hardreset, 105 .assert_reset = omap_device_assert_hardreset,
106 .deassert_reset = omap_device_deassert_hardreset, 106 .deassert_reset = omap_device_deassert_hardreset,
107 .device_enable = omap_device_enable,
108 .device_idle = omap_device_idle,
109};
110
111static struct iommu_platform_data omap3_iommu_isp_pdata = {
112 .device_enable = omap_device_enable,
113 .device_idle = omap_device_idle,
107}; 114};
108 115
109static int omap3_sbc_t3730_twl_callback(struct device *dev, 116static int omap3_sbc_t3730_twl_callback(struct device *dev,
@@ -438,6 +445,8 @@ static struct iommu_platform_data omap4_iommu_pdata = {
438 .reset_name = "mmu_cache", 445 .reset_name = "mmu_cache",
439 .assert_reset = omap_device_assert_hardreset, 446 .assert_reset = omap_device_assert_hardreset,
440 .deassert_reset = omap_device_deassert_hardreset, 447 .deassert_reset = omap_device_deassert_hardreset,
448 .device_enable = omap_device_enable,
449 .device_idle = omap_device_idle,
441}; 450};
442#endif 451#endif
443 452
@@ -466,9 +475,16 @@ static struct iommu_platform_data dra7_ipu1_dsp_iommu_pdata = {
466 .reset_name = "mmu_cache", 475 .reset_name = "mmu_cache",
467 .assert_reset = omap_device_assert_hardreset, 476 .assert_reset = omap_device_assert_hardreset,
468 .deassert_reset = omap_device_deassert_hardreset, 477 .deassert_reset = omap_device_deassert_hardreset,
478 .device_enable = omap_device_enable,
479 .device_idle = omap_device_idle,
469 .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint, 480 .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint,
470}; 481};
471 482
483static struct iommu_platform_data dra7_dsp_mmu_edma_pdata = {
484 .device_enable = omap_device_enable,
485 .device_idle = omap_device_idle,
486};
487
472static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1; 488static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1;
473static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2; 489static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2;
474static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3; 490static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3;
@@ -585,6 +601,8 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
585#ifdef CONFIG_ARCH_OMAP3 601#ifdef CONFIG_ARCH_OMAP3
586 OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", 602 OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
587 &omap3_iommu_pdata), 603 &omap3_iommu_pdata),
604 OF_DEV_AUXDATA("ti,omap2-iommu", 0x480bd400, "480bd400.mmu",
605 &omap3_iommu_isp_pdata),
588 OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000, 606 OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000,
589 "480cb000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]), 607 "480cb000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]),
590 OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000, 608 OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000,
@@ -644,6 +662,10 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
644 &dra7_ipu1_dsp_iommu_pdata), 662 &dra7_ipu1_dsp_iommu_pdata),
645 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu", 663 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu",
646 &dra7_ipu1_dsp_iommu_pdata), 664 &dra7_ipu1_dsp_iommu_pdata),
665 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x40d02000, "40d02000.mmu",
666 &dra7_dsp_mmu_edma_pdata),
667 OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41502000, "41502000.mmu",
668 &dra7_dsp_mmu_edma_pdata),
647 OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu", 669 OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu",
648 &omap4_iommu_pdata), 670 &omap4_iommu_pdata),
649 OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu", 671 OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu",
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index f623f76378a0..c69d86900520 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -69,6 +69,9 @@ static struct omap_iommu_domain *to_omap_domain(struct iommu_domain *dom)
69/** 69/**
70 * omap_iommu_save_ctx - Save registers for pm off-mode support 70 * omap_iommu_save_ctx - Save registers for pm off-mode support
71 * @dev: client device 71 * @dev: client device
72 *
73 * This should be treated as an deprecated API. It is preserved only
74 * to maintain existing functionality for OMAP3 ISP driver.
72 **/ 75 **/
73void omap_iommu_save_ctx(struct device *dev) 76void omap_iommu_save_ctx(struct device *dev)
74{ 77{
@@ -96,6 +99,9 @@ EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
96/** 99/**
97 * omap_iommu_restore_ctx - Restore registers for pm off-mode support 100 * omap_iommu_restore_ctx - Restore registers for pm off-mode support
98 * @dev: client device 101 * @dev: client device
102 *
103 * This should be treated as an deprecated API. It is preserved only
104 * to maintain existing functionality for OMAP3 ISP driver.
99 **/ 105 **/
100void omap_iommu_restore_ctx(struct device *dev) 106void omap_iommu_restore_ctx(struct device *dev)
101{ 107{
@@ -190,53 +196,18 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
190 196
191static int iommu_enable(struct omap_iommu *obj) 197static int iommu_enable(struct omap_iommu *obj)
192{ 198{
193 int err; 199 int ret;
194 struct platform_device *pdev = to_platform_device(obj->dev);
195 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
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
205 if (pdata && pdata->deassert_reset) {
206 err = pdata->deassert_reset(pdev, pdata->reset_name);
207 if (err) {
208 dev_err(obj->dev, "deassert_reset failed: %d\n", err);
209 return err;
210 }
211 }
212
213 pm_runtime_get_sync(obj->dev);
214 200
215 err = omap2_iommu_enable(obj); 201 ret = pm_runtime_get_sync(obj->dev);
202 if (ret < 0)
203 pm_runtime_put_noidle(obj->dev);
216 204
217 return err; 205 return ret < 0 ? ret : 0;
218} 206}
219 207
220static void iommu_disable(struct omap_iommu *obj) 208static void iommu_disable(struct omap_iommu *obj)
221{ 209{
222 struct platform_device *pdev = to_platform_device(obj->dev);
223 struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
224 int ret;
225
226 omap2_iommu_disable(obj);
227
228 pm_runtime_put_sync(obj->dev); 210 pm_runtime_put_sync(obj->dev);
229
230 if (pdata && pdata->assert_reset)
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 }
240} 211}
241 212
242/* 213/*
@@ -922,15 +893,219 @@ static void omap_iommu_detach(struct omap_iommu *obj)
922 893
923 dma_unmap_single(obj->dev, obj->pd_dma, IOPGD_TABLE_SIZE, 894 dma_unmap_single(obj->dev, obj->pd_dma, IOPGD_TABLE_SIZE,
924 DMA_TO_DEVICE); 895 DMA_TO_DEVICE);
925 iommu_disable(obj);
926 obj->pd_dma = 0; 896 obj->pd_dma = 0;
927 obj->iopgd = NULL; 897 obj->iopgd = NULL;
898 iommu_disable(obj);
928 899
929 spin_unlock(&obj->iommu_lock); 900 spin_unlock(&obj->iommu_lock);
930 901
931 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); 902 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
932} 903}
933 904
905static void omap_iommu_save_tlb_entries(struct omap_iommu *obj)
906{
907 struct iotlb_lock lock;
908 struct cr_regs cr;
909 struct cr_regs *tmp;
910 int i;
911
912 /* check if there are any locked tlbs to save */
913 iotlb_lock_get(obj, &lock);
914 obj->num_cr_ctx = lock.base;
915 if (!obj->num_cr_ctx)
916 return;
917
918 tmp = obj->cr_ctx;
919 for_each_iotlb_cr(obj, obj->num_cr_ctx, i, cr)
920 *tmp++ = cr;
921}
922
923static void omap_iommu_restore_tlb_entries(struct omap_iommu *obj)
924{
925 struct iotlb_lock l;
926 struct cr_regs *tmp;
927 int i;
928
929 /* no locked tlbs to restore */
930 if (!obj->num_cr_ctx)
931 return;
932
933 l.base = 0;
934 tmp = obj->cr_ctx;
935 for (i = 0; i < obj->num_cr_ctx; i++, tmp++) {
936 l.vict = i;
937 iotlb_lock_set(obj, &l);
938 iotlb_load_cr(obj, tmp);
939 }
940 l.base = obj->num_cr_ctx;
941 l.vict = i;
942 iotlb_lock_set(obj, &l);
943}
944
945/**
946 * omap_iommu_domain_deactivate - deactivate attached iommu devices
947 * @domain: iommu domain attached to the target iommu device
948 *
949 * This API allows the client devices of IOMMU devices to suspend
950 * the IOMMUs they control at runtime, after they are idled and
951 * suspended all activity. System Suspend will leverage the PM
952 * driver late callbacks.
953 **/
954int omap_iommu_domain_deactivate(struct iommu_domain *domain)
955{
956 struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
957 struct omap_iommu_device *iommu;
958 struct omap_iommu *oiommu;
959 int i;
960
961 if (!omap_domain->dev)
962 return 0;
963
964 iommu = omap_domain->iommus;
965 iommu += (omap_domain->num_iommus - 1);
966 for (i = 0; i < omap_domain->num_iommus; i++, iommu--) {
967 oiommu = iommu->iommu_dev;
968 pm_runtime_put_sync(oiommu->dev);
969 }
970
971 return 0;
972}
973EXPORT_SYMBOL_GPL(omap_iommu_domain_deactivate);
974
975/**
976 * omap_iommu_domain_activate - activate attached iommu devices
977 * @domain: iommu domain attached to the target iommu device
978 *
979 * This API allows the client devices of IOMMU devices to resume the
980 * IOMMUs they control at runtime, before they can resume operations.
981 * System Resume will leverage the PM driver late callbacks.
982 **/
983int omap_iommu_domain_activate(struct iommu_domain *domain)
984{
985 struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
986 struct omap_iommu_device *iommu;
987 struct omap_iommu *oiommu;
988 int i;
989
990 if (!omap_domain->dev)
991 return 0;
992
993 iommu = omap_domain->iommus;
994 for (i = 0; i < omap_domain->num_iommus; i++, iommu++) {
995 oiommu = iommu->iommu_dev;
996 pm_runtime_get_sync(oiommu->dev);
997 }
998
999 return 0;
1000}
1001EXPORT_SYMBOL_GPL(omap_iommu_domain_activate);
1002
1003/**
1004 * omap_iommu_runtime_suspend - disable an iommu device
1005 * @dev: iommu device
1006 *
1007 * This function performs all that is necessary to disable an
1008 * IOMMU device, either during final detachment from a client
1009 * device, or during system/runtime suspend of the device. This
1010 * includes programming all the appropriate IOMMU registers, and
1011 * managing the associated omap_hwmod's state and the device's
1012 * reset line. This function also saves the context of any
1013 * locked TLBs if suspending.
1014 **/
1015static int omap_iommu_runtime_suspend(struct device *dev)
1016{
1017 struct platform_device *pdev = to_platform_device(dev);
1018 struct iommu_platform_data *pdata = dev_get_platdata(dev);
1019 struct omap_iommu *obj = to_iommu(dev);
1020 int ret;
1021
1022 /* save the TLBs only during suspend, and not for power down */
1023 if (obj->domain && obj->iopgd)
1024 omap_iommu_save_tlb_entries(obj);
1025
1026 omap2_iommu_disable(obj);
1027
1028 if (pdata && pdata->device_idle)
1029 pdata->device_idle(pdev);
1030
1031 if (pdata && pdata->assert_reset)
1032 pdata->assert_reset(pdev, pdata->reset_name);
1033
1034 if (pdata && pdata->set_pwrdm_constraint) {
1035 ret = pdata->set_pwrdm_constraint(pdev, false, &obj->pwrst);
1036 if (ret) {
1037 dev_warn(obj->dev, "pwrdm_constraint failed to be reset, status = %d\n",
1038 ret);
1039 }
1040 }
1041
1042 return 0;
1043}
1044
1045/**
1046 * omap_iommu_runtime_resume - enable an iommu device
1047 * @dev: iommu device
1048 *
1049 * This function performs all that is necessary to enable an
1050 * IOMMU device, either during initial attachment to a client
1051 * device, or during system/runtime resume of the device. This
1052 * includes programming all the appropriate IOMMU registers, and
1053 * managing the associated omap_hwmod's state and the device's
1054 * reset line. The function also restores any locked TLBs if
1055 * resuming after a suspend.
1056 **/
1057static int omap_iommu_runtime_resume(struct device *dev)
1058{
1059 struct platform_device *pdev = to_platform_device(dev);
1060 struct iommu_platform_data *pdata = dev_get_platdata(dev);
1061 struct omap_iommu *obj = to_iommu(dev);
1062 int ret = 0;
1063
1064 if (pdata && pdata->set_pwrdm_constraint) {
1065 ret = pdata->set_pwrdm_constraint(pdev, true, &obj->pwrst);
1066 if (ret) {
1067 dev_warn(obj->dev, "pwrdm_constraint failed to be set, status = %d\n",
1068 ret);
1069 }
1070 }
1071
1072 if (pdata && pdata->deassert_reset) {
1073 ret = pdata->deassert_reset(pdev, pdata->reset_name);
1074 if (ret) {
1075 dev_err(dev, "deassert_reset failed: %d\n", ret);
1076 return ret;
1077 }
1078 }
1079
1080 if (pdata && pdata->device_enable)
1081 pdata->device_enable(pdev);
1082
1083 /* restore the TLBs only during resume, and not for power up */
1084 if (obj->domain)
1085 omap_iommu_restore_tlb_entries(obj);
1086
1087 ret = omap2_iommu_enable(obj);
1088
1089 return ret;
1090}
1091
1092/**
1093 * omap_iommu_suspend_prepare - prepare() dev_pm_ops implementation
1094 * @dev: iommu device
1095 *
1096 * This function performs the necessary checks to determine if the IOMMU
1097 * device needs suspending or not. The function checks if the runtime_pm
1098 * status of the device is suspended, and returns 1 in that case. This
1099 * results in the PM core to skip invoking any of the Sleep PM callbacks
1100 * (suspend, suspend_late, resume, resume_early etc).
1101 */
1102static int omap_iommu_prepare(struct device *dev)
1103{
1104 if (pm_runtime_status_suspended(dev))
1105 return 1;
1106 return 0;
1107}
1108
934static bool omap_iommu_can_register(struct platform_device *pdev) 1109static bool omap_iommu_can_register(struct platform_device *pdev)
935{ 1110{
936 struct device_node *np = pdev->dev.of_node; 1111 struct device_node *np = pdev->dev.of_node;
@@ -1005,6 +1180,15 @@ static int omap_iommu_probe(struct platform_device *pdev)
1005 if (!obj) 1180 if (!obj)
1006 return -ENOMEM; 1181 return -ENOMEM;
1007 1182
1183 /*
1184 * self-manage the ordering dependencies between omap_device_enable/idle
1185 * and omap_device_assert/deassert_hardreset API
1186 */
1187 if (pdev->dev.pm_domain) {
1188 dev_dbg(&pdev->dev, "device pm_domain is being reset\n");
1189 pdev->dev.pm_domain = NULL;
1190 }
1191
1008 obj->name = dev_name(&pdev->dev); 1192 obj->name = dev_name(&pdev->dev);
1009 obj->nr_tlb_entries = 32; 1193 obj->nr_tlb_entries = 32;
1010 err = of_property_read_u32(of, "ti,#tlb-entries", &obj->nr_tlb_entries); 1194 err = of_property_read_u32(of, "ti,#tlb-entries", &obj->nr_tlb_entries);
@@ -1017,6 +1201,11 @@ static int omap_iommu_probe(struct platform_device *pdev)
1017 1201
1018 obj->dev = &pdev->dev; 1202 obj->dev = &pdev->dev;
1019 obj->ctx = (void *)obj + sizeof(*obj); 1203 obj->ctx = (void *)obj + sizeof(*obj);
1204 obj->cr_ctx = devm_kzalloc(&pdev->dev,
1205 sizeof(*obj->cr_ctx) * obj->nr_tlb_entries,
1206 GFP_KERNEL);
1207 if (!obj->cr_ctx)
1208 return -ENOMEM;
1020 1209
1021 spin_lock_init(&obj->iommu_lock); 1210 spin_lock_init(&obj->iommu_lock);
1022 spin_lock_init(&obj->page_table_lock); 1211 spin_lock_init(&obj->page_table_lock);
@@ -1093,6 +1282,14 @@ static int omap_iommu_remove(struct platform_device *pdev)
1093 return 0; 1282 return 0;
1094} 1283}
1095 1284
1285static const struct dev_pm_ops omap_iommu_pm_ops = {
1286 .prepare = omap_iommu_prepare,
1287 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1288 pm_runtime_force_resume)
1289 SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend,
1290 omap_iommu_runtime_resume, NULL)
1291};
1292
1096static const struct of_device_id omap_iommu_of_match[] = { 1293static const struct of_device_id omap_iommu_of_match[] = {
1097 { .compatible = "ti,omap2-iommu" }, 1294 { .compatible = "ti,omap2-iommu" },
1098 { .compatible = "ti,omap4-iommu" }, 1295 { .compatible = "ti,omap4-iommu" },
@@ -1106,6 +1303,7 @@ static struct platform_driver omap_iommu_driver = {
1106 .remove = omap_iommu_remove, 1303 .remove = omap_iommu_remove,
1107 .driver = { 1304 .driver = {
1108 .name = "omap-iommu", 1305 .name = "omap-iommu",
1306 .pm = &omap_iommu_pm_ops,
1109 .of_match_table = of_match_ptr(omap_iommu_of_match), 1307 .of_match_table = of_match_ptr(omap_iommu_of_match),
1110 }, 1308 },
1111}; 1309};
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h
index 7766d5a4f3f1..ca07fbf287d0 100644
--- a/drivers/iommu/omap-iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -76,6 +76,9 @@ struct omap_iommu {
76 76
77 void *ctx; /* iommu context: registres saved area */ 77 void *ctx; /* iommu context: registres saved area */
78 78
79 struct cr_regs *cr_ctx;
80 u32 num_cr_ctx;
81
79 int has_bus_err_back; 82 int has_bus_err_back;
80 u32 id; 83 u32 id;
81 84
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 3e34778c2ceb..2016de9e650d 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -16,14 +16,17 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/io.h>
19#include <linux/of_device.h> 20#include <linux/of_device.h>
20#include <linux/of_address.h> 21#include <linux/of_address.h>
21#include <linux/of_reserved_mem.h> 22#include <linux/of_reserved_mem.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
23#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
24#include <linux/remoteproc.h> 26#include <linux/remoteproc.h>
25#include <linux/mailbox_client.h> 27#include <linux/mailbox_client.h>
26#include <linux/omap-mailbox.h> 28#include <linux/omap-mailbox.h>
29#include <linux/omap-iommu.h>
27#include <linux/regmap.h> 30#include <linux/regmap.h>
28#include <linux/mfd/syscon.h> 31#include <linux/mfd/syscon.h>
29#include <clocksource/timer-ti-dm.h> 32#include <clocksource/timer-ti-dm.h>
@@ -37,6 +40,9 @@
37#define OMAP_RPROC_DSP_LOCAL_MEM_OFFSET (0x00800000) 40#define OMAP_RPROC_DSP_LOCAL_MEM_OFFSET (0x00800000)
38#define OMAP_RPROC_IPU_L2RAM_DEV_ADDR (0x20000000) 41#define OMAP_RPROC_IPU_L2RAM_DEV_ADDR (0x20000000)
39 42
43/* default auto-suspend delay (ms) */
44#define DEFAULT_AUTOSUSPEND_DELAY 10000
45
40/** 46/**
41 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs 47 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs
42 * @syscon: regmap handle for the system control configuration module 48 * @syscon: regmap handle for the system control configuration module
@@ -83,7 +89,12 @@ struct omap_rproc_timer {
83 * @num_mems: number of internal memory regions 89 * @num_mems: number of internal memory regions
84 * @num_timers: number of rproc timer(s) 90 * @num_timers: number of rproc timer(s)
85 * @timers: timer(s) info used by rproc 91 * @timers: timer(s) info used by rproc
92 * @autosuspend_delay: auto-suspend delay value to be used for runtime pm
93 * @need_resume: if true a resume is needed in the system resume callback
86 * @rproc: rproc handle 94 * @rproc: rproc handle
95 * @pm_comp: completion primitive to sync for suspend response
96 * @standby_addr: kernel address of the register having module standby status
97 * @suspend_acked: state machine flag to store the suspend request ack
87 */ 98 */
88struct omap_rproc { 99struct omap_rproc {
89 struct mbox_chan *mbox; 100 struct mbox_chan *mbox;
@@ -93,17 +104,24 @@ struct omap_rproc {
93 int num_mems; 104 int num_mems;
94 int num_timers; 105 int num_timers;
95 struct omap_rproc_timer *timers; 106 struct omap_rproc_timer *timers;
107 int autosuspend_delay;
108 bool need_resume;
96 struct rproc *rproc; 109 struct rproc *rproc;
110 struct completion pm_comp;
111 void __iomem *standby_addr;
112 bool suspend_acked;
97}; 113};
98 114
99/** 115/**
100 * struct omap_rproc_dev_data - device data for the omap remote processor 116 * struct omap_rproc_dev_data - device data for the omap remote processor
101 * @device_name: device name of the remote processor 117 * @device_name: device name of the remote processor
102 * @fw_name: firmware name to use 118 * @fw_name: firmware name to use
119 * @autosuspend_delay: custom auto-suspend delay value in milliseconds
103 */ 120 */
104struct omap_rproc_dev_data { 121struct omap_rproc_dev_data {
105 const char *device_name; 122 const char *device_name;
106 const char *fw_name; 123 const char *fw_name;
124 int autosuspend_delay;
107}; 125};
108 126
109/** 127/**
@@ -344,6 +362,11 @@ static void omap_rproc_mbox_callback(struct mbox_client *client, void *data)
344 case RP_MBOX_ECHO_REPLY: 362 case RP_MBOX_ECHO_REPLY:
345 dev_info(dev, "received echo reply from %s\n", name); 363 dev_info(dev, "received echo reply from %s\n", name);
346 break; 364 break;
365 case RP_MBOX_SUSPEND_ACK:
366 case RP_MBOX_SUSPEND_CANCEL:
367 oproc->suspend_acked = msg == RP_MBOX_SUSPEND_ACK;
368 complete(&oproc->pm_comp);
369 break;
347 default: 370 default:
348 if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG) 371 if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
349 return; 372 return;
@@ -364,11 +387,23 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
364 struct device *dev = rproc->dev.parent; 387 struct device *dev = rproc->dev.parent;
365 int ret; 388 int ret;
366 389
390 /* wake up the rproc before kicking it */
391 ret = pm_runtime_get_sync(dev);
392 if (WARN_ON(ret < 0)) {
393 dev_err(dev, "pm_runtime_get_sync() failed during kick, ret = %d\n",
394 ret);
395 pm_runtime_put_noidle(dev);
396 return;
397 }
398
367 /* send the index of the triggered virtqueue in the mailbox payload */ 399 /* send the index of the triggered virtqueue in the mailbox payload */
368 ret = mbox_send_message(oproc->mbox, (void *)vqid); 400 ret = mbox_send_message(oproc->mbox, (void *)vqid);
369 if (ret < 0) 401 if (ret < 0)
370 dev_err(dev, "failed to send mailbox message, status = %d\n", 402 dev_err(dev, "failed to send mailbox message, status = %d\n",
371 ret); 403 ret);
404
405 pm_runtime_mark_last_busy(dev);
406 pm_runtime_put_autosuspend(dev);
372} 407}
373 408
374/** 409/**
@@ -461,6 +496,19 @@ static int omap_rproc_start(struct rproc *rproc)
461 goto reset_timers; 496 goto reset_timers;
462 } 497 }
463 498
499 /*
500 * remote processor is up, so update the runtime pm status and
501 * enable the auto-suspend. The device usage count is incremented
502 * manually for balancing it for auto-suspend
503 */
504 pm_runtime_set_active(dev);
505 pm_runtime_set_autosuspend_delay(dev, oproc->autosuspend_delay);
506 pm_runtime_use_autosuspend(dev);
507 pm_runtime_get_noresume(dev);
508 pm_runtime_enable(dev);
509 pm_runtime_mark_last_busy(dev);
510 pm_runtime_put_autosuspend(dev);
511
464 return 0; 512 return 0;
465 513
466reset_timers: 514reset_timers:
@@ -479,17 +527,49 @@ static int omap_rproc_stop(struct rproc *rproc)
479 struct omap_rproc *oproc = rproc->priv; 527 struct omap_rproc *oproc = rproc->priv;
480 int ret; 528 int ret;
481 529
530 /*
531 * cancel any possible scheduled runtime suspend by incrementing
532 * the device usage count, and resuming the device. The remoteproc
533 * also needs to be woken up if suspended, to avoid the remoteproc
534 * OS to continue to remember any context that it has saved, and
535 * avoid potential issues in misindentifying a subsequent device
536 * reboot as a power restore boot
537 */
538 ret = pm_runtime_get_sync(dev);
539 if (ret < 0) {
540 pm_runtime_put_noidle(dev);
541 return ret;
542 }
543
482 ret = pdata->device_shutdown(pdev); 544 ret = pdata->device_shutdown(pdev);
483 if (ret) 545 if (ret)
484 return ret; 546 goto out;
485 547
486 ret = omap_rproc_disable_timers(rproc, true); 548 ret = omap_rproc_disable_timers(rproc, true);
487 if (ret) 549 if (ret)
488 return ret; 550 goto enable_device;
489 551
490 mbox_free_channel(oproc->mbox); 552 mbox_free_channel(oproc->mbox);
491 553
554 /*
555 * update the runtime pm states and status now that the remoteproc
556 * has stopped
557 */
558 pm_runtime_disable(dev);
559 pm_runtime_dont_use_autosuspend(dev);
560 pm_runtime_put_noidle(dev);
561 pm_runtime_set_suspended(dev);
562
492 return 0; 563 return 0;
564
565enable_device:
566 pdata->device_enable(pdev);
567out:
568 /* schedule the next auto-suspend */
569 pm_runtime_mark_last_busy(dev);
570 pm_runtime_put_autosuspend(dev);
571 return ret;
572
493} 573}
494 574
495/* 575/*
@@ -534,6 +614,289 @@ static const struct rproc_ops omap_rproc_ops = {
534 .da_to_va = omap_rproc_da_to_va, 614 .da_to_va = omap_rproc_da_to_va,
535}; 615};
536 616
617#ifdef CONFIG_PM
618static bool _is_rproc_in_standby(struct omap_rproc *oproc)
619{
620 static int standby_mask = (1 << 18);
621
622 return readl(oproc->standby_addr) & standby_mask;
623}
624
625/* 1 sec is long enough time to let the remoteproc side suspend the device */
626#define DEF_SUSPEND_TIMEOUT 1000
627static int _omap_rproc_suspend(struct rproc *rproc, bool auto_suspend)
628{
629 struct device *dev = rproc->dev.parent;
630 struct platform_device *pdev = to_platform_device(dev);
631 struct omap_rproc_pdata *pdata = dev_get_platdata(dev);
632 struct omap_rproc *oproc = rproc->priv;
633 unsigned long to = msecs_to_jiffies(DEF_SUSPEND_TIMEOUT);
634 unsigned long ta = jiffies + to;
635 u32 suspend_msg = auto_suspend ?
636 RP_MBOX_SUSPEND_AUTO : RP_MBOX_SUSPEND_SYSTEM;
637 int ret;
638
639 reinit_completion(&oproc->pm_comp);
640 oproc->suspend_acked = false;
641 ret = mbox_send_message(oproc->mbox, (void *)suspend_msg);
642 if (ret < 0) {
643 dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
644 return ret;
645 }
646
647 ret = wait_for_completion_timeout(&oproc->pm_comp, to);
648 if (!oproc->suspend_acked)
649 return -EBUSY;
650
651 /*
652 * The remoteproc side is returning the ACK message before saving the
653 * context, because the context saving is performed within a SYS/BIOS
654 * function, and it cannot have any inter-dependencies against the IPC
655 * layer. Also, as the SYS/BIOS needs to preserve properly the processor
656 * register set, sending this ACK or signalling the completion of the
657 * context save through a shared memory variable can never be the
658 * absolute last thing to be executed on the remoteproc side, and the
659 * MPU cannot use the ACK message as a sync point to put the remoteproc
660 * into reset. The only way to ensure that the remote processor has
661 * completed saving the context is to check that the module has reached
662 * STANDBY state (after saving the context, the SYS/BIOS executes the
663 * appropriate target-specific WFI instruction causing the module to
664 * enter STANDBY).
665 */
666 while (!_is_rproc_in_standby(oproc)) {
667 if (time_after(jiffies, ta))
668 return -ETIME;
669 schedule();
670 }
671
672 ret = pdata->device_shutdown(pdev);
673 if (ret)
674 return ret;
675
676 ret = omap_rproc_disable_timers(rproc, false);
677 if (ret) {
678 dev_err(dev, "disabling timers during suspend failed %d\n",
679 ret);
680 goto enable_device;
681 }
682
683 /*
684 * IOMMUs would have to be disabled specifically for runtime suspend.
685 * They are handled automatically through System PM callbacks for
686 * regular system suspend
687 */
688 if (auto_suspend) {
689 ret = omap_iommu_domain_deactivate(rproc->domain);
690 if (ret) {
691 dev_err(dev, "iommu domain deactivate failed %d\n",
692 ret);
693 goto enable_timers;
694 }
695 }
696
697 return 0;
698
699enable_timers:
700 /* ignore errors on re-enabling code */
701 omap_rproc_enable_timers(rproc, false);
702enable_device:
703 pdata->device_enable(pdev);
704 return ret;
705}
706
707static int _omap_rproc_resume(struct rproc *rproc, bool auto_suspend)
708{
709 struct device *dev = rproc->dev.parent;
710 struct platform_device *pdev = to_platform_device(dev);
711 struct omap_rproc_pdata *pdata = dev_get_platdata(dev);
712 struct omap_rproc *oproc = rproc->priv;
713 int ret;
714
715 /*
716 * IOMMUs would have to be enabled specifically for runtime resume.
717 * They would have been already enabled automatically through System
718 * PM callbacks for regular system resume
719 */
720 if (auto_suspend) {
721 ret = omap_iommu_domain_activate(rproc->domain);
722 if (ret) {
723 dev_err(dev, "omap_iommu activate failed %d\n", ret);
724 goto out;
725 }
726 }
727
728 /* boot address could be lost after suspend, so restore it */
729 if (oproc->boot_data) {
730 ret = omap_rproc_write_dsp_boot_addr(rproc);
731 if (ret) {
732 dev_err(dev, "boot address restore failed %d\n", ret);
733 goto suspend_iommu;
734 }
735 }
736
737 ret = omap_rproc_enable_timers(rproc, false);
738 if (ret) {
739 dev_err(dev, "enabling timers during resume failed %d\n",
740 ret);
741 goto suspend_iommu;
742 }
743
744 ret = pdata->device_enable(pdev);
745 if (ret)
746 goto disable_timers;
747
748 return 0;
749
750disable_timers:
751 omap_rproc_disable_timers(rproc, false);
752suspend_iommu:
753 if (auto_suspend)
754 omap_iommu_domain_deactivate(rproc->domain);
755out:
756 return ret;
757}
758
759static int __maybe_unused omap_rproc_suspend(struct device *dev)
760{
761 struct platform_device *pdev = to_platform_device(dev);
762 struct rproc *rproc = platform_get_drvdata(pdev);
763 struct omap_rproc *oproc = rproc->priv;
764 int ret = 0;
765
766 mutex_lock(&rproc->lock);
767 if (rproc->state == RPROC_OFFLINE)
768 goto out;
769
770 if (rproc->state == RPROC_SUSPENDED)
771 goto out;
772
773 if (rproc->state != RPROC_RUNNING) {
774 ret = -EBUSY;
775 goto out;
776 }
777
778 ret = _omap_rproc_suspend(rproc, false);
779 if (ret) {
780 dev_err(dev, "suspend failed %d\n", ret);
781 goto out;
782 }
783
784 /*
785 * remoteproc is running at the time of system suspend, so remember
786 * it so as to wake it up during system resume
787 */
788 oproc->need_resume = 1;
789 rproc->state = RPROC_SUSPENDED;
790
791 /*
792 * update the runtime pm status to be suspended, without decrementing
793 * the device usage count
794 */
795 pm_runtime_disable(dev);
796 pm_runtime_set_suspended(dev);
797out:
798 mutex_unlock(&rproc->lock);
799 return ret;
800}
801
802static int __maybe_unused omap_rproc_resume(struct device *dev)
803{
804 struct platform_device *pdev = to_platform_device(dev);
805 struct rproc *rproc = platform_get_drvdata(pdev);
806 struct omap_rproc *oproc = rproc->priv;
807 int ret = 0;
808
809 mutex_lock(&rproc->lock);
810 if (rproc->state == RPROC_OFFLINE)
811 goto out;
812
813 if (rproc->state != RPROC_SUSPENDED) {
814 ret = -EBUSY;
815 goto out;
816 }
817
818 /*
819 * remoteproc was auto-suspended at the time of system suspend,
820 * so no need to wake-up the processor (leave it in suspended
821 * state, will be woken up during a subsequent runtime_resume)
822 */
823 if (!oproc->need_resume)
824 goto out;
825
826 ret = _omap_rproc_resume(rproc, false);
827 if (ret) {
828 dev_err(dev, "resume failed %d\n", ret);
829 goto out;
830 }
831 oproc->need_resume = false;
832
833 rproc->state = RPROC_RUNNING;
834
835 /*
836 * update the runtime pm status to be active, without incrementing
837 * the device usage count
838 */
839 pm_runtime_set_active(dev);
840 pm_runtime_enable(dev);
841 pm_runtime_mark_last_busy(dev);
842out:
843 mutex_unlock(&rproc->lock);
844 return ret;
845}
846
847static int omap_rproc_runtime_suspend(struct device *dev)
848{
849 struct rproc *rproc = dev_get_drvdata(dev);
850 struct omap_rproc *oproc = rproc->priv;
851 int ret;
852
853 if (WARN_ON(rproc->state != RPROC_RUNNING)) {
854 dev_err(dev, "rproc cannot be runtime suspended when not running!\n");
855 return -EBUSY;
856 }
857
858 /*
859 * do not even attempt suspend if the remote processor is not
860 * idled for runtime auto-suspend
861 */
862 if (!_is_rproc_in_standby(oproc)) {
863 ret = -EBUSY;
864 goto abort;
865 }
866
867 ret = _omap_rproc_suspend(rproc, true);
868 if (ret)
869 goto abort;
870
871 rproc->state = RPROC_SUSPENDED;
872 return 0;
873
874abort:
875 pm_runtime_mark_last_busy(dev);
876 return ret;
877}
878
879static int omap_rproc_runtime_resume(struct device *dev)
880{
881 struct rproc *rproc = dev_get_drvdata(dev);
882 int ret;
883
884 if (WARN_ON(rproc->state != RPROC_SUSPENDED)) {
885 dev_err(dev, "rproc cannot be runtime resumed if not suspended!\n");
886 return -EBUSY;
887 }
888
889 ret = _omap_rproc_resume(rproc, true);
890 if (ret) {
891 dev_err(dev, "runtime resume failed %d\n", ret);
892 return ret;
893 }
894
895 rproc->state = RPROC_RUNNING;
896 return 0;
897}
898#endif /* CONFIG_PM */
899
537static const struct omap_rproc_dev_data omap4_dsp_dev_data = { 900static const struct omap_rproc_dev_data omap4_dsp_dev_data = {
538 .device_name = "dsp", 901 .device_name = "dsp",
539 .fw_name = "omap4-dsp-fw.xe64T", 902 .fw_name = "omap4-dsp-fw.xe64T",
@@ -607,6 +970,33 @@ static const struct of_device_id omap_rproc_of_match[] = {
607}; 970};
608MODULE_DEVICE_TABLE(of, omap_rproc_of_match); 971MODULE_DEVICE_TABLE(of, omap_rproc_of_match);
609 972
973static int omap_rproc_get_autosuspend_delay(struct platform_device *pdev)
974{
975 struct device_node *np = pdev->dev.of_node;
976 const struct omap_rproc_dev_data *data;
977 int delay = -EINVAL;
978
979 data = of_device_get_match_data(&pdev->dev);
980 if (!data)
981 return -ENODEV;
982
983 if (!of_device_is_compatible(np, "ti,dra7-dsp") &&
984 !of_device_is_compatible(np, "ti,dra7-ipu")) {
985 delay = data->autosuspend_delay;
986 goto out;
987 }
988
989 for (; data && data->device_name; data++) {
990 if (!strcmp(dev_name(&pdev->dev), data->device_name)) {
991 delay = data->autosuspend_delay;
992 break;
993 }
994 }
995
996out:
997 return (delay > 0) ? delay : DEFAULT_AUTOSUSPEND_DELAY;
998}
999
610static const char *omap_rproc_get_firmware(struct platform_device *pdev) 1000static const char *omap_rproc_get_firmware(struct platform_device *pdev)
611{ 1001{
612 struct device_node *np = pdev->dev.of_node; 1002 struct device_node *np = pdev->dev.of_node;
@@ -754,6 +1144,7 @@ static int omap_rproc_probe(struct platform_device *pdev)
754 struct omap_rproc *oproc; 1144 struct omap_rproc *oproc;
755 struct rproc *rproc; 1145 struct rproc *rproc;
756 const char *firmware; 1146 const char *firmware;
1147 u32 standby_addr = 0;
757 int ret; 1148 int ret;
758 1149
759 if (!np) { 1150 if (!np) {
@@ -761,6 +1152,16 @@ static int omap_rproc_probe(struct platform_device *pdev)
761 return -ENODEV; 1152 return -ENODEV;
762 } 1153 }
763 1154
1155 /*
1156 * self-manage the ordering dependencies between omap_device_enable/idle
1157 * and omap_device_assert/deassert_hardreset API during runtime suspend
1158 * and resume, rather than relying on the order in omap_device layer.
1159 */
1160 if (pdev->dev.pm_domain) {
1161 dev_dbg(&pdev->dev, "device pm_domain is being reset for this remoteproc device\n");
1162 pdev->dev.pm_domain = NULL;
1163 }
1164
764 if (!pdata || !pdata->device_enable || !pdata->device_shutdown) { 1165 if (!pdata || !pdata->device_enable || !pdata->device_shutdown) {
765 dev_err(&pdev->dev, "platform data is either missing or incomplete\n"); 1166 dev_err(&pdev->dev, "platform data is either missing or incomplete\n");
766 return -ENODEV; 1167 return -ENODEV;
@@ -818,6 +1219,26 @@ static int omap_rproc_probe(struct platform_device *pdev)
818 oproc->num_timers); 1219 oproc->num_timers);
819 } 1220 }
820 1221
1222 init_completion(&oproc->pm_comp);
1223 oproc->autosuspend_delay = omap_rproc_get_autosuspend_delay(pdev);
1224 if (oproc->autosuspend_delay < 0) {
1225 ret = oproc->autosuspend_delay;
1226 goto free_rproc;
1227 }
1228
1229 ret = of_property_read_u32(np, "ti,rproc-standby-info", &standby_addr);
1230 if (ret || !standby_addr) {
1231 ret = !standby_addr ? -EINVAL : ret;
1232 goto free_rproc;
1233 }
1234
1235 oproc->standby_addr = devm_ioremap(&pdev->dev, standby_addr,
1236 sizeof(u32));
1237 if (!oproc->standby_addr) {
1238 ret = -ENOMEM;
1239 goto free_rproc;
1240 }
1241
821 ret = of_reserved_mem_device_init(&pdev->dev); 1242 ret = of_reserved_mem_device_init(&pdev->dev);
822 if (ret) { 1243 if (ret) {
823 dev_err(&pdev->dev, "device does not have specific CMA pool\n"); 1244 dev_err(&pdev->dev, "device does not have specific CMA pool\n");
@@ -853,11 +1274,18 @@ static int omap_rproc_remove(struct platform_device *pdev)
853 return 0; 1274 return 0;
854} 1275}
855 1276
1277static const struct dev_pm_ops omap_rproc_pm_ops = {
1278 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend, omap_rproc_resume)
1279 SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend,
1280 omap_rproc_runtime_resume, NULL)
1281};
1282
856static struct platform_driver omap_rproc_driver = { 1283static struct platform_driver omap_rproc_driver = {
857 .probe = omap_rproc_probe, 1284 .probe = omap_rproc_probe,
858 .remove = omap_rproc_remove, 1285 .remove = omap_rproc_remove,
859 .driver = { 1286 .driver = {
860 .name = "omap-rproc", 1287 .name = "omap-rproc",
1288 .pm = &omap_rproc_pm_ops,
861 .of_match_table = omap_rproc_of_match, 1289 .of_match_table = omap_rproc_of_match,
862 }, 1290 },
863}; 1291};
diff --git a/drivers/remoteproc/omap_remoteproc.h b/drivers/remoteproc/omap_remoteproc.h
index 18f522617683..b74d140cbbb6 100644
--- a/drivers/remoteproc/omap_remoteproc.h
+++ b/drivers/remoteproc/omap_remoteproc.h
@@ -2,7 +2,7 @@
2/* 2/*
3 * Remote processor messaging 3 * Remote processor messaging
4 * 4 *
5 * Copyright (C) 2011 Texas Instruments, Inc. 5 * Copyright (C) 2011-2019 Texas Instruments, Inc.
6 * Copyright (C) 2011 Google, Inc. 6 * Copyright (C) 2011 Google, Inc.
7 * All rights reserved. 7 * All rights reserved.
8 */ 8 */
@@ -32,6 +32,16 @@
32 * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the 32 * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the
33 * recovery mechanism (to some extent). 33 * recovery mechanism (to some extent).
34 * 34 *
35 * @RP_MBOX_SUSPEND_AUTO: auto suspend request for the remote processor
36 *
37 * @RP_MBOX_SUSPEND_SYSTEM: system suspend request for the remote processor
38 *
39 * @RP_MBOX_SUSPEND_ACK: successful response from remote processor for a
40 * suspend request
41 *
42 * @RP_MBOX_SUSPEND_CANCEL: a cancel suspend response from a remote processor
43 * on a suspend request
44 *
35 * Introduce new message definitions if any here. 45 * Introduce new message definitions if any here.
36 * 46 *
37 * @RP_MBOX_END_MSG: Indicates end of known/defined messages from remote core 47 * @RP_MBOX_END_MSG: Indicates end of known/defined messages from remote core
@@ -45,7 +55,11 @@ enum omap_rp_mbox_messages {
45 RP_MBOX_ECHO_REQUEST = 0xFFFFFF03, 55 RP_MBOX_ECHO_REQUEST = 0xFFFFFF03,
46 RP_MBOX_ECHO_REPLY = 0xFFFFFF04, 56 RP_MBOX_ECHO_REPLY = 0xFFFFFF04,
47 RP_MBOX_ABORT_REQUEST = 0xFFFFFF05, 57 RP_MBOX_ABORT_REQUEST = 0xFFFFFF05,
48 RP_MBOX_END_MSG = 0xFFFFFF06, 58 RP_MBOX_SUSPEND_AUTO = 0xFFFFFF10,
59 RP_MBOX_SUSPEND_SYSTEM = 0xFFFFFF11,
60 RP_MBOX_SUSPEND_ACK = 0xFFFFFF12,
61 RP_MBOX_SUSPEND_CANCEL = 0xFFFFFF13,
62 RP_MBOX_END_MSG = 0xFFFFFF14,
49}; 63};
50 64
51#endif /* _OMAP_RPMSG_H */ 65#endif /* _OMAP_RPMSG_H */
diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
index 6b7e8b2b43be..0c47bc0bb36a 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -100,7 +100,8 @@ static ssize_t state_store(struct device *dev,
100 module_put(dev->parent->driver->owner); 100 module_put(dev->parent->driver->owner);
101 } 101 }
102 } else if (sysfs_streq(buf, "stop")) { 102 } else if (sysfs_streq(buf, "stop")) {
103 if (rproc->state != RPROC_RUNNING) 103 if (rproc->state != RPROC_RUNNING &&
104 rproc->state != RPROC_SUSPENDED)
104 return -EINVAL; 105 return -EINVAL;
105 106
106 rproc_shutdown(rproc); 107 rproc_shutdown(rproc);
diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h
index ce1b7c6283ee..5b66325bc63c 100644
--- a/include/linux/omap-iommu.h
+++ b/include/linux/omap-iommu.h
@@ -13,12 +13,27 @@
13#ifndef _OMAP_IOMMU_H_ 13#ifndef _OMAP_IOMMU_H_
14#define _OMAP_IOMMU_H_ 14#define _OMAP_IOMMU_H_
15 15
16struct iommu_domain;
17
16#ifdef CONFIG_OMAP_IOMMU 18#ifdef CONFIG_OMAP_IOMMU
17extern void omap_iommu_save_ctx(struct device *dev); 19extern void omap_iommu_save_ctx(struct device *dev);
18extern void omap_iommu_restore_ctx(struct device *dev); 20extern void omap_iommu_restore_ctx(struct device *dev);
21
22int omap_iommu_domain_deactivate(struct iommu_domain *domain);
23int omap_iommu_domain_activate(struct iommu_domain *domain);
19#else 24#else
20static inline void omap_iommu_save_ctx(struct device *dev) {} 25static inline void omap_iommu_save_ctx(struct device *dev) {}
21static inline void omap_iommu_restore_ctx(struct device *dev) {} 26static inline void omap_iommu_restore_ctx(struct device *dev) {}
27
28static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain)
29{
30 return -ENOTSUP;
31}
32
33static inline int omap_iommu_domain_activate(struct iommu_domain *domain)
34{
35 return -ENOTSUP;
36}
22#endif 37#endif
23 38
24#endif 39#endif
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h
index 1a0aa46a5ad6..6669dc9394da 100644
--- a/include/linux/platform_data/iommu-omap.h
+++ b/include/linux/platform_data/iommu-omap.h
@@ -16,6 +16,8 @@ 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 (*device_enable)(struct platform_device *pdev);
20 int (*device_idle)(struct platform_device *pdev);
19 int (*set_pwrdm_constraint)(struct platform_device *pdev, bool request, 21 int (*set_pwrdm_constraint)(struct platform_device *pdev, bool request,
20 u8 *pwrst); 22 u8 *pwrst);
21}; 23};