Skip to content

Commit 1250337

Browse files
Hari KanigeriLuis Henriques
authored andcommitted
omap:remoteproc-Initial support for remote proc
This patch provides the inital series of commits for remote proc on omap omap:remoteproc-add remoteproc support Add remote proc support Signed-off-by: Hari Kanigeri <[email protected]> Signed-off-by: Ohad Ben-Cohen <[email protected]> Singed-off-by: Angela Stegmaier <[email protected]> omap:remoteproc-provide multi-omap support This patch resolves the build issues when trying to build with multi-omap configuration. Signed-off-by: Hari Kanigeri <[email protected]> omap:remoteproc-add mechanism to enable bios timer BIOS requires the GPTimer for handling the OS activities. This is to configuer the GPTimers that are required for the remote processors. Signed-off-by: Hari Kanigeri <[email protected]> Signed-off-by: Fernando Guzman Lugo <[email protected]> syslink: rproc - add support for START and STOP events Now apps can wait for remote proc START and STOP events Signed-off-by: Fernando Guzman Lugo <[email protected]> rproc: fix missing common proc args to match userspace Add the common proc args structure to store the status of the api in order to match userspace side. Signed-off-by: Fernando Guzman Lugo <[email protected]> rproc: add protection to rproc_eventdf_ntfy The list of fd handles most be protected while traversing Signed-off-by: Fernando Guzman Lugo <[email protected]> omap:remoteproc: disable gpt3&4 as bios timer source Each core sys/app were requesting gpt3/4, respectively, as bios timer source clock. This patch is disabling the use of those timers as bios timer source since now the internal M3 timers are set for this purpose. Anyway the mechanism to set any timer as bios timer source was kept. If a gptimer is set as bios timer source changes in Ducati side are needed. Signed-off-by: Miguel Vadillo <[email protected]> omap:remoteproc: enable gpt3&4 for ipu hibernation gptimer 3/4 are set to be use at the hibernation timers for IPU, both clocks are enabled and configured in rproc_start and disable in rproc_stop. When mpu is hibernating IPU the iommu and mbox context will be saved and then rproc_sleep will be called to disable each core and also the associated gptimer needed to allowed retention. Whenever a message is sent to IPU the ipu_pm_restore will check and wake up ipu, if needed, restoring the iommu and mbox context and calling rproc_wake that will enable ipu and the associated gptimer again. When disable, the hibernating process will only happen if the system suspend/resume path is sent, IPU self hibernation wont be executed. Also gpt3/4 won't be requested at all. Signed-off-by: Miguel Vadillo <[email protected]> Signed-off-by: Juan Gutierrez <[email protected]> Signed-off-by: Paul Hunt <[email protected]> omap: remoteproc - fix sparse warnings in remote proc about static This patch fixes these warnings: arch/arm/plat-omap/remoteproc.c:45:6: warning: symbol 'rproc_eventfd_ntfy' was not declared. Should it be static? arch/arm/plat-omap/remoteproc.c:180:5: warning: symbol 'rproc_reg_user_event' was not declared. Should it be static? arch/arm/plat-omap/remoteproc.c:227:5: warning: symbol 'rproc_unreg_user_event' was not declared. Should it be static? Change-Id: Ie822bbf97dc9dbf4b76bff8e115b3e9063037710 Signed-off-by: Fernando Guzman Lugo <[email protected]> omap: remoteproc: CONFIG flag for self hibernation A new CONFIG flag is introduce to control IPU self hibernation the name of the new flag is CONFIG_SYSLINK_IPU_SELF_HIBERNATION when disable the timers used by IPU to hibernate and the flag in sh mem to allow hibernation of IPU are not set and IPU will hibernate only when sending the system suspend. On the other hand if the flag is set after N seconds of inactivity and if there is no resource requested by IPU (using ipu_pm) IPU will hibernate. Change-Id: I3f14257930a861c8784d7159a821228111b3ba37 Signed-off-by: Miguel Vadillo <[email protected]>
1 parent 88d15fe commit 1250337

File tree

3 files changed

+988
-0
lines changed

3 files changed

+988
-0
lines changed

arch/arm/mach-omap2/remoteproc44xx.c

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/*
2+
* Remote Processor machine-specific module for OMAP3
3+
*
4+
* Copyright (C) 2010 Texas Instruments Inc.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* version 2 as published by the Free Software Foundation.
9+
*
10+
* This program is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18+
* 02110-1301 USA
19+
*
20+
*/
21+
#include <linux/kernel.h>
22+
#include <linux/clk.h>
23+
#include <linux/err.h>
24+
#include <linux/platform_device.h>
25+
#include <linux/io.h>
26+
#include <plat/remoteproc.h>
27+
#include <plat/dmtimer.h>
28+
29+
#include <plat/omap_device.h>
30+
#include <plat/omap_hwmod.h>
31+
32+
33+
static inline int proc44x_start(struct device *dev, u32 start_addr)
34+
{
35+
struct platform_device *pdev = to_platform_device(dev);
36+
struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
37+
to_platform_device(dev));
38+
int ret = 0;
39+
40+
/* Enable the Timer that would be used by co-processor */
41+
if (obj->timer_id >= 0) {
42+
obj->dmtimer =
43+
omap_dm_timer_request_specific(obj->timer_id);
44+
if (!obj->dmtimer) {
45+
ret = -EBUSY;
46+
goto err_start;
47+
}
48+
omap_dm_timer_set_int_enable(obj->dmtimer,
49+
OMAP_TIMER_INT_OVERFLOW);
50+
omap_dm_timer_set_source(obj->dmtimer, OMAP_TIMER_SRC_SYS_CLK);
51+
}
52+
53+
ret = omap_device_enable(pdev);
54+
if (ret)
55+
goto err_start;
56+
57+
obj->state = OMAP_RPROC_RUNNING;
58+
return 0;
59+
60+
err_start:
61+
dev_err(dev, "%s error 0x%x\n", __func__, ret);
62+
return ret;
63+
}
64+
65+
static inline int proc44x_stop(struct device *dev)
66+
{
67+
struct platform_device *pdev = to_platform_device(dev);
68+
struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
69+
to_platform_device(dev));
70+
int ret = 0;
71+
72+
if (obj->state == OMAP_RPROC_RUNNING) {
73+
ret = omap_device_shutdown(pdev);
74+
if (ret)
75+
dev_err(dev, "%s err 0x%x\n", __func__, ret);
76+
77+
if (obj->dmtimer) {
78+
omap_dm_timer_free(obj->dmtimer);
79+
obj->dmtimer = NULL;
80+
}
81+
}
82+
83+
obj->state = OMAP_RPROC_STOPPED;
84+
return ret;
85+
}
86+
87+
static inline int proc44x_sleep(struct device *dev)
88+
{
89+
struct platform_device *pdev = to_platform_device(dev);
90+
struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
91+
to_platform_device(dev));
92+
int ret = 0;
93+
94+
if (obj->state == OMAP_RPROC_RUNNING) {
95+
ret = omap_device_shutdown(pdev);
96+
if (ret)
97+
dev_err(dev, "%s err 0x%x\n", __func__, ret);
98+
99+
if (obj->dmtimer)
100+
omap_dm_timer_disable(obj->dmtimer);
101+
}
102+
103+
obj->state = OMAP_RPROC_HIBERNATING;
104+
return ret;
105+
}
106+
107+
static inline int proc44x_wakeup(struct device *dev)
108+
{
109+
struct platform_device *pdev = to_platform_device(dev);
110+
struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
111+
to_platform_device(dev));
112+
int ret = 0;
113+
114+
if (obj->dmtimer)
115+
omap_dm_timer_enable(obj->dmtimer);
116+
117+
ret = omap_device_enable(pdev);
118+
if (ret)
119+
goto err_start;
120+
121+
obj->state = OMAP_RPROC_RUNNING;
122+
return 0;
123+
124+
err_start:
125+
dev_err(dev, "%s error 0x%x\n", __func__, ret);
126+
return ret;
127+
}
128+
129+
130+
static inline int omap4_rproc_get_state(struct device *dev)
131+
{
132+
struct platform_device *pdev = to_platform_device(dev);
133+
struct omap_device *odev = to_omap_device(pdev);
134+
135+
return odev->_state;
136+
}
137+
138+
static struct omap_rproc_ops omap4_ducati0_ops = {
139+
.start = proc44x_start,
140+
.stop = proc44x_stop,
141+
.sleep = proc44x_sleep,
142+
.wakeup = proc44x_wakeup,
143+
.get_state = omap4_rproc_get_state,
144+
};
145+
146+
static struct omap_rproc_ops omap4_ducati1_ops = {
147+
.start = proc44x_start,
148+
.stop = proc44x_stop,
149+
.sleep = proc44x_sleep,
150+
.wakeup = proc44x_wakeup,
151+
.get_state = omap4_rproc_get_state,
152+
};
153+
154+
static struct omap_rproc_ops omap4_tesla_ops = {
155+
.start = proc44x_start,
156+
.stop = proc44x_stop,
157+
.sleep = proc44x_sleep,
158+
.wakeup = proc44x_wakeup,
159+
.get_state = omap4_rproc_get_state,
160+
};
161+
162+
static struct omap_rproc_platform_data omap4_rproc_data[] = {
163+
{
164+
.name = "tesla",
165+
.ops = &omap4_tesla_ops,
166+
.oh_name = "dsp_c0",
167+
.timer_id = 5,
168+
},
169+
{
170+
.name = "ducati-proc0",
171+
.ops = &omap4_ducati0_ops,
172+
.oh_name = "ipu_c0",
173+
#ifdef CONFIG_SYSLINK_IPU_SELF_HIBERNATION
174+
.timer_id = 3,
175+
#else
176+
.timer_id = -1,
177+
#endif
178+
},
179+
{
180+
.name = "ducati-proc1",
181+
.ops = &omap4_ducati1_ops,
182+
.oh_name = "ipu_c1",
183+
#ifdef CONFIG_SYSLINK_IPU_SELF_HIBERNATION
184+
.timer_id = 4,
185+
#else
186+
.timer_id = -1,
187+
#endif
188+
189+
},
190+
};
191+
192+
static struct omap_device_pm_latency omap_rproc_latency[] = {
193+
{
194+
.deactivate_func = omap_device_idle_hwmods,
195+
.activate_func = omap_device_enable_hwmods,
196+
.deactivate_lat = 1,
197+
.activate_lat = 1,
198+
},
199+
};
200+
201+
struct omap_rproc_platform_data *omap4_get_rproc_data(void)
202+
{
203+
return omap4_rproc_data;
204+
}
205+
206+
207+
#define NR_RPROC_DEVICES ARRAY_SIZE(omap4_rproc_data)
208+
209+
static struct omap_device *omap4_rproc_pdev[NR_RPROC_OMAP4_DEVICES];
210+
211+
static int __init omap4_rproc_init(void)
212+
{
213+
struct omap_hwmod *oh;
214+
struct omap_device_pm_latency *ohl;
215+
char *oh_name, *pdev_name;
216+
int ohl_cnt = 0, i;
217+
int rproc_data_size;
218+
struct omap_rproc_platform_data *rproc_data;
219+
220+
pdev_name = "omap-remoteproc";
221+
ohl = omap_rproc_latency;
222+
ohl_cnt = ARRAY_SIZE(omap_rproc_latency);
223+
224+
225+
rproc_data = omap4_get_rproc_data();
226+
rproc_data_size = NR_RPROC_OMAP4_DEVICES;
227+
228+
for (i = 0; i < rproc_data_size; i++) {
229+
oh_name = rproc_data[i].oh_name;
230+
oh = omap_hwmod_lookup(oh_name);
231+
if (!oh) {
232+
pr_err("%s: could not look up %s\n", __func__, oh_name);
233+
continue;
234+
}
235+
omap4_rproc_pdev[i] = omap_device_build(pdev_name, i, oh,
236+
&rproc_data[i],
237+
sizeof(struct omap_rproc_platform_data),
238+
ohl, ohl_cnt, false);
239+
WARN(IS_ERR(omap4_rproc_pdev[i]), "Could not build omap_device"
240+
"for %s %s\n", pdev_name, oh_name);
241+
}
242+
return 0;
243+
}
244+
module_init(omap4_rproc_init);
245+
246+
static void __exit omap4_rproc_exit(void)
247+
{
248+
249+
}
250+
module_exit(omap4_rproc_exit);
251+
252+
MODULE_LICENSE("GPL v2");
253+
MODULE_DESCRIPTION("OMAP4 Remote Processor module");
254+
MODULE_AUTHOR("Ohad Ben-Cohen <[email protected]>");
255+
MODULE_AUTHOR("Hari Kanigeri <[email protected]>");

0 commit comments

Comments
 (0)