aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishal Mahaveer2016-03-11 14:02:35 -0600
committerVishal Mahaveer2016-03-11 14:02:35 -0600
commitca6c33ac51398de6b6b7860f4b35fb2db6e5b915 (patch)
tree98acdaa4063e6b95160294e686aed302954f1b15
parent70212583ae2b5572b5f27fb7806606e504cbbd52 (diff)
parentc22b04c9c6c436fbc14f6c812643a7cf64ebcd18 (diff)
downloadkernel-video-ca6c33ac51398de6b6b7860f4b35fb2db6e5b915.tar.gz
kernel-video-ca6c33ac51398de6b6b7860f4b35fb2db6e5b915.tar.xz
kernel-video-ca6c33ac51398de6b6b7860f4b35fb2db6e5b915.zip
Merge branch 'p-ti-linux-3.14.y-common' into p-ti-linux-3.14.y-android
* p-ti-linux-3.14.y-common: arm: dtsi: jamr3: Adjusting DSP SR0 range remoteproc/omap: Fix DSP recovery issues with EDMA Change-Id: I2d1d6f6124643a4a8d81cd1077e8e4bbe10574bd Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
-rw-r--r--arch/arm/boot/dts/dra7xx-jamr3.dtsi4
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c2
-rw-r--r--arch/arm/mach-omap2/remoteproc.c144
-rw-r--r--arch/arm/mach-omap2/remoteproc.h4
-rw-r--r--drivers/remoteproc/omap_remoteproc.c3
-rw-r--r--include/linux/platform_data/remoteproc-omap.h2
6 files changed, 156 insertions, 3 deletions
diff --git a/arch/arm/boot/dts/dra7xx-jamr3.dtsi b/arch/arm/boot/dts/dra7xx-jamr3.dtsi
index 69ac557998c..c83fd339029 100644
--- a/arch/arm/boot/dts/dra7xx-jamr3.dtsi
+++ b/arch/arm/boot/dts/dra7xx-jamr3.dtsi
@@ -70,8 +70,8 @@
70 status = "okay"; 70 status = "okay";
71 }; 71 };
72 72
73 dsp1_sr0: dsp1_sr0@bfd00000 { 73 dsp1_sr0: dsp1_sr0@bfb00000 {
74 reg = <0xbfd00000 0x100000>; 74 reg = <0xbfb00000 0x100000>;
75 no-map; 75 no-map;
76 status = "okay"; 76 status = "okay";
77 }; 77 };
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index e151ce47dc6..d7f4c6d9b44 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -294,6 +294,7 @@ static struct omap_rproc_pdata dra7_dsp1_pdata = {
294 .device_shutdown = omap_rproc_device_shutdown, 294 .device_shutdown = omap_rproc_device_shutdown,
295 .set_bootaddr = dra7_ctrl_write_dsp1_boot_addr, 295 .set_bootaddr = dra7_ctrl_write_dsp1_boot_addr,
296 .timer_ops = &omap_rproc_dmtimer_ops, 296 .timer_ops = &omap_rproc_dmtimer_ops,
297 .pre_shutdown = dra7_dsp1_pre_shutdown,
297}; 298};
298 299
299static struct omap_rproc_pdata dra7_dsp2_pdata = { 300static struct omap_rproc_pdata dra7_dsp2_pdata = {
@@ -301,6 +302,7 @@ static struct omap_rproc_pdata dra7_dsp2_pdata = {
301 .device_shutdown = omap_rproc_device_shutdown, 302 .device_shutdown = omap_rproc_device_shutdown,
302 .set_bootaddr = dra7_ctrl_write_dsp2_boot_addr, 303 .set_bootaddr = dra7_ctrl_write_dsp2_boot_addr,
303 .timer_ops = &omap_rproc_dmtimer_ops, 304 .timer_ops = &omap_rproc_dmtimer_ops,
305 .pre_shutdown = dra7_dsp2_pre_shutdown,
304}; 306};
305#endif 307#endif
306 308
diff --git a/arch/arm/mach-omap2/remoteproc.c b/arch/arm/mach-omap2/remoteproc.c
index 9e91ef09cf7..d39f5f63276 100644
--- a/arch/arm/mach-omap2/remoteproc.c
+++ b/arch/arm/mach-omap2/remoteproc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Remote processor machine-specific module for OMAP4+ SoCs 2 * Remote processor machine-specific module for OMAP4+ SoCs
3 * 3 *
4 * Copyright (C) 2011-2014 Texas Instruments, Inc. 4 * Copyright (C) 2011-2016 Texas Instruments, Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -22,6 +22,23 @@
22#include "omap_device.h" 22#include "omap_device.h"
23#include "control.h" 23#include "control.h"
24#include "remoteproc.h" 24#include "remoteproc.h"
25#include "soc.h"
26
27#define DSP1_EDMA_TPCC 0x40D10000
28#define DSP2_EDMA_TPCC 0x41510000
29#define DSP1_EDMA_TPTC0 0x40D05000
30#define DSP2_EDMA_TPTC0 0x41505000
31#define EDMA_TPCC_CCSTAT_OFFSET 0x640
32#define EDMA_TPCC_EECR_OFFSET 0x1028
33#define EDMA_TPCC_EECRH_OFFSET 0x102C
34#define EDMA_TPCC_QEECR_OFFSET 0x1088
35#define EDMA_DSP_TPTC1_OFFSET 0x1000
36#define EDMA_TPTC_TCSTAT0_OFFSET 0x100
37#define EDMA_TPTC_TCSTAT1_OFFSET (EDMA_DSP_TPTC1_OFFSET + \
38 EDMA_TPTC_TCSTAT0_OFFSET)
39
40#define CTRL_CORE_DMA_DSP1_DREQ 0x4A002CF8
41#define CTRL_CORE_DMA_DSP2_DREQ 0x4A002D20
25 42
26void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr) 43void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr)
27{ 44{
@@ -33,6 +50,131 @@ void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr)
33 dra7_ctrl_write_dsp_boot_addr(bootaddr, 1); 50 dra7_ctrl_write_dsp_boot_addr(bootaddr, 1);
34} 51}
35 52
53static void dra7_wait_dsp_edma_compl(u32 inst)
54{
55 u32 dsp_edma_tpcc_base, dsp_edma_tptc_base;
56 int timeout;
57 void __iomem *tpcc_base, *tptc_base;
58
59 if (!soc_is_dra7xx())
60 return;
61
62 dsp_edma_tpcc_base = inst ? DSP2_EDMA_TPCC : DSP1_EDMA_TPCC;
63 dsp_edma_tptc_base = inst ? DSP2_EDMA_TPTC0 : DSP1_EDMA_TPTC0;
64
65 tpcc_base = ioremap(dsp_edma_tpcc_base, SZ_16K);
66 if (!tpcc_base) {
67 pr_err("DSP EDMA TPCC ioremap failed\n");
68 goto map_err1;
69 }
70
71 tptc_base = ioremap(dsp_edma_tptc_base, SZ_8K);
72 if (!tptc_base) {
73 pr_err("DSP EDMA TPTC ioremap failed\n");
74 goto map_err2;
75 }
76
77 /* Disable all future EDMA and QDMA events to DSPx EDMA TPCC */
78 writel_relaxed(0xFFFFFFFF, tpcc_base + EDMA_TPCC_EECR_OFFSET);
79 writel_relaxed(0xFFFFFFFF, tpcc_base + EDMA_TPCC_EECRH_OFFSET);
80 writel_relaxed(0xFFFFFFFF, tpcc_base + EDMA_TPCC_QEECR_OFFSET);
81
82 /*
83 * Poll CCSTAT to ensure all actively serviced or queued events have
84 * been completed.
85 *
86 * The timeout is based on the duration which the EDMA CC queue will
87 * drain based on the slowest typical application. This is chosen to
88 * be 1.0625ms, which assumes a full event queue with transfers for
89 * an 8kHz audio stream, plus one extra transfer for safe measure.
90 */
91 timeout = 1063;
92 pr_warn("waiting for DSP%d EDMA traffic on TPCC to complete\n",
93 inst+1);
94 while (((readl_relaxed(tpcc_base + EDMA_TPCC_CCSTAT_OFFSET))
95 != 0x0) && --timeout)
96 udelay(1);
97 if (timeout == 0)
98 pr_warn("DSP%d EDMA transaction may be ongoing during shutdown! TPCC is active!\n",
99 inst + 1);
100
101 /*
102 * Check that PROGBUSY SRCACTV WSACTV, and DSTACTV bits of TCSTAT
103 * registers for DSP TPTC0 and TPTC1 are cleared prior to shutdown.
104 *
105 * The timeout is based on the duration of the EDMA transfer expected
106 * by the slowest typical application, which is chosen as 125us. This
107 * would be the transfer request rate of an 8kHz audio stream, with one
108 * extra transfer for safe measure.
109 */
110 timeout = 125;
111 pr_warn("waiting for DSP%d EDMA traffic on TPTC0 to complete\n",
112 inst+1);
113 while (((readl_relaxed(tptc_base + EDMA_TPTC_TCSTAT0_OFFSET) & 0x77)
114 != 0x0) && --timeout)
115 udelay(1);
116 if (timeout == 0)
117 pr_warn("DSP%d EDMA transaction may be ongoing during shutdown! TPTC0 is active!\n",
118 inst + 1);
119
120 timeout = 125;
121 pr_warn("waiting for DSP%d EDMA traffic on TPTC1 to complete\n",
122 inst+1);
123 while (((readl_relaxed(tptc_base + EDMA_TPTC_TCSTAT1_OFFSET) & 0x77)
124 != 0x0) && --timeout)
125 udelay(1);
126 if (timeout == 0)
127 pr_warn("DSP%d EDMA transaction may be ongoing during shutdown! TPTC1 is active!\n",
128 inst + 1);
129 iounmap(tptc_base);
130map_err2:
131 iounmap(tpcc_base);
132map_err1:
133 return;
134}
135
136static void dra7_clear_dsp_edma_xbar(u32 inst)
137{
138 u32 dsp_dreq_base;
139 void __iomem *iomem_base;
140 u8 offset;
141
142 if (!soc_is_dra7xx())
143 return;
144
145 dsp_dreq_base = inst ? CTRL_CORE_DMA_DSP2_DREQ :
146 CTRL_CORE_DMA_DSP1_DREQ;
147
148 iomem_base = ioremap(dsp_dreq_base, SZ_64);
149 if (!iomem_base) {
150 pr_err("DSP EDMA ioremap failed\n");
151 return;
152 }
153
154 pr_warn("Clearing all EDMA XBAR routings to DSP%d\n", inst+1);
155
156 /*
157 * Clear all connections to DSPx EDMA crossbar, from
158 * CTRL_CORE_DMA_DSPx_DREQ_0_1 to CTRL_CORE_DMA_DSPx_DREQ_18_19.
159 */
160 for (offset = 0x0; offset <= 0x24; offset += 0x4)
161 writel_relaxed(0x0, iomem_base + offset);
162
163 iounmap(iomem_base);
164}
165
166void dra7_dsp1_pre_shutdown(void)
167{
168 dra7_clear_dsp_edma_xbar(0);
169 dra7_wait_dsp_edma_compl(0);
170}
171
172void dra7_dsp2_pre_shutdown(void)
173{
174 dra7_clear_dsp_edma_xbar(1);
175 dra7_wait_dsp_edma_compl(1);
176}
177
36/** 178/**
37 * omap_rproc_device_enable - enable the remoteproc device 179 * omap_rproc_device_enable - enable the remoteproc device
38 * @pdev: the rproc platform device 180 * @pdev: the rproc platform device
diff --git a/arch/arm/mach-omap2/remoteproc.h b/arch/arm/mach-omap2/remoteproc.h
index 43a5658449b..020454e3d83 100644
--- a/arch/arm/mach-omap2/remoteproc.h
+++ b/arch/arm/mach-omap2/remoteproc.h
@@ -24,6 +24,8 @@ struct omap_dm_timer;
24#if IS_ENABLED(CONFIG_OMAP_REMOTEPROC) 24#if IS_ENABLED(CONFIG_OMAP_REMOTEPROC)
25void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr); 25void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr);
26void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr); 26void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr);
27void dra7_dsp1_pre_shutdown(void);
28void dra7_dsp2_pre_shutdown(void);
27int omap_rproc_device_enable(struct platform_device *pdev); 29int omap_rproc_device_enable(struct platform_device *pdev);
28int omap_rproc_device_shutdown(struct platform_device *pdev); 30int omap_rproc_device_shutdown(struct platform_device *pdev);
29struct omap_dm_timer *omap_rproc_request_timer(struct device_node *np); 31struct omap_dm_timer *omap_rproc_request_timer(struct device_node *np);
@@ -35,6 +37,8 @@ void omap_rproc_ack_timer_irq(struct omap_dm_timer *timer);
35#else 37#else
36static inline void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr) { } 38static inline void dra7_ctrl_write_dsp1_boot_addr(u32 bootaddr) { }
37static inline void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr) { } 39static inline void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr) { }
40static inline void dra7_dsp1_pre_shutdown(void) { }
41static inline void dra7_dsp2_pre_shutdown(void) { }
38static inline int omap_rproc_device_enable(struct platform_device *pdev) 42static inline int omap_rproc_device_enable(struct platform_device *pdev)
39{ 43{
40 return 0; 44 return 0;
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 231dc8f3920..87eed5d1356 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -459,6 +459,9 @@ static int omap_rproc_stop(struct rproc *rproc)
459 return ret; 459 return ret;
460 } 460 }
461 461
462 if (pdata->pre_shutdown)
463 pdata->pre_shutdown();
464
462 ret = pdata->device_shutdown(pdev); 465 ret = pdata->device_shutdown(pdev);
463 if (ret) 466 if (ret)
464 goto out; 467 goto out;
diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h
index 4384eb9ced5..b98acb8c71c 100644
--- a/include/linux/platform_data/remoteproc-omap.h
+++ b/include/linux/platform_data/remoteproc-omap.h
@@ -47,12 +47,14 @@ struct omap_rproc_timer_ops {
47 * @device_enable: omap-specific handler for enabling a device 47 * @device_enable: omap-specific handler for enabling a device
48 * @device_shutdown: omap-specific handler for shutting down a device 48 * @device_shutdown: omap-specific handler for shutting down a device
49 * @set_bootaddr: omap-specific handler for setting the rproc boot address 49 * @set_bootaddr: omap-specific handler for setting the rproc boot address
50 * @pre_shutdown: omap-specific handler for performing pre-shutdown cleanup
50 * @timer_ops: platform data ops for OMAP dmtimer handlers 51 * @timer_ops: platform data ops for OMAP dmtimer handlers
51 */ 52 */
52struct omap_rproc_pdata { 53struct omap_rproc_pdata {
53 int (*device_enable)(struct platform_device *pdev); 54 int (*device_enable)(struct platform_device *pdev);
54 int (*device_shutdown)(struct platform_device *pdev); 55 int (*device_shutdown)(struct platform_device *pdev);
55 void (*set_bootaddr)(u32); 56 void (*set_bootaddr)(u32);
57 void (*pre_shutdown)(void);
56 58
57 struct omap_rproc_timer_ops *timer_ops; 59 struct omap_rproc_timer_ops *timer_ops;
58}; 60};