~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/arm/mach-omap2/remoteproc44xx.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 for HIB/WD*/
41
 
        if (obj->timer_hib_id >= 0) {
42
 
                obj->dmtimer =
43
 
                        omap_dm_timer_request_specific(obj->timer_hib_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
 
        /* Enable the Timer that would be used by co-processor as Clock*/
54
 
        if (obj->timer_clk_id >= 0) {
55
 
                obj->dmtimer_clk =
56
 
                        omap_dm_timer_request_specific(obj->timer_clk_id);
57
 
                if (!obj->dmtimer_clk) {
58
 
                        ret = -EBUSY;
59
 
                        goto err_start;
60
 
                }
61
 
 
62
 
                omap_dm_timer_set_source(obj->dmtimer_clk,
63
 
                                                        OMAP_TIMER_SRC_SYS_CLK);
64
 
        }
65
 
 
66
 
        ret = omap_device_enable(pdev);
67
 
        if (ret)
68
 
                goto err_start;
69
 
 
70
 
        obj->state = OMAP_RPROC_RUNNING;
71
 
        return 0;
72
 
 
73
 
err_start:
74
 
        dev_err(dev, "%s error 0x%x\n", __func__, ret);
75
 
        return ret;
76
 
}
77
 
 
78
 
static inline int proc44x_stop(struct device *dev)
79
 
{
80
 
        struct platform_device *pdev = to_platform_device(dev);
81
 
        struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
82
 
                                                to_platform_device(dev));
83
 
        int ret = 0;
84
 
 
85
 
        if (obj->state == OMAP_RPROC_RUNNING) {
86
 
                ret = omap_device_shutdown(pdev);
87
 
                if (ret)
88
 
                        dev_err(dev, "%s err 0x%x\n", __func__, ret);
89
 
        }
90
 
 
91
 
        if (obj->dmtimer) {
92
 
                omap_dm_timer_free(obj->dmtimer);
93
 
                obj->dmtimer = NULL;
94
 
        }
95
 
 
96
 
        if (obj->dmtimer_clk) {
97
 
                        omap_dm_timer_free(obj->dmtimer_clk);
98
 
                        obj->dmtimer_clk = NULL;
99
 
        }
100
 
 
101
 
        obj->state = OMAP_RPROC_STOPPED;
102
 
        return ret;
103
 
}
104
 
 
105
 
static inline int proc44x_sleep(struct device *dev)
106
 
{
107
 
        struct platform_device *pdev = to_platform_device(dev);
108
 
        struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
109
 
                                                to_platform_device(dev));
110
 
        int ret = 0;
111
 
 
112
 
        if (obj->state == OMAP_RPROC_RUNNING) {
113
 
                ret = omap_device_shutdown(pdev);
114
 
                if (ret)
115
 
                        dev_err(dev, "%s err 0x%x\n", __func__, ret);
116
 
 
117
 
                if (obj->dmtimer)
118
 
                        omap_dm_timer_stop(obj->dmtimer);
119
 
                if (obj->dmtimer_clk)
120
 
                        omap_dm_timer_stop(obj->dmtimer_clk);
121
 
        }
122
 
 
123
 
        obj->state = OMAP_RPROC_HIBERNATING;
124
 
        return ret;
125
 
}
126
 
 
127
 
static inline int proc44x_wakeup(struct device *dev)
128
 
{
129
 
        struct platform_device *pdev = to_platform_device(dev);
130
 
        struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata(
131
 
                                                to_platform_device(dev));
132
 
        int ret = 0;
133
 
 
134
 
        if (obj->dmtimer)
135
 
                omap_dm_timer_start(obj->dmtimer);
136
 
        if (obj->dmtimer_clk)
137
 
                omap_dm_timer_start(obj->dmtimer_clk);
138
 
 
139
 
        ret = omap_device_enable(pdev);
140
 
        if (ret)
141
 
                goto err_start;
142
 
 
143
 
        obj->state = OMAP_RPROC_RUNNING;
144
 
        return 0;
145
 
 
146
 
err_start:
147
 
        dev_err(dev, "%s error 0x%x\n", __func__, ret);
148
 
        return ret;
149
 
}
150
 
 
151
 
 
152
 
static inline int omap4_rproc_get_state(struct device *dev)
153
 
{
154
 
        struct platform_device *pdev = to_platform_device(dev);
155
 
        struct omap_device *odev = to_omap_device(pdev);
156
 
 
157
 
        return odev->_state;
158
 
}
159
 
 
160
 
static struct omap_rproc_ops omap4_ducati0_ops = {
161
 
        .start = proc44x_start,
162
 
        .stop = proc44x_stop,
163
 
        .sleep = proc44x_sleep,
164
 
        .wakeup = proc44x_wakeup,
165
 
        .get_state = omap4_rproc_get_state,
166
 
};
167
 
 
168
 
static struct omap_rproc_ops omap4_ducati1_ops = {
169
 
        .start = proc44x_start,
170
 
        .stop = proc44x_stop,
171
 
        .sleep = proc44x_sleep,
172
 
        .wakeup = proc44x_wakeup,
173
 
        .get_state = omap4_rproc_get_state,
174
 
};
175
 
 
176
 
static struct omap_rproc_ops omap4_tesla_ops = {
177
 
        .start = proc44x_start,
178
 
        .stop = proc44x_stop,
179
 
        .sleep = proc44x_sleep,
180
 
        .wakeup = proc44x_wakeup,
181
 
        .get_state = omap4_rproc_get_state,
182
 
};
183
 
 
184
 
static struct omap_rproc_platform_data omap4_rproc_data[] = {
185
 
        {
186
 
                .name = "tesla",
187
 
                .ops = &omap4_tesla_ops,
188
 
                .oh_name = "dsp_c0",
189
 
                .timer_clk_id = 5,
190
 
                .timer_hib_id = -1,
191
 
        },
192
 
        {
193
 
                .name = "ducati-proc0",
194
 
                .ops = &omap4_ducati0_ops,
195
 
                .oh_name = "ipu_c0",
196
 
                .timer_clk_id = 4,
197
 
#ifdef CONFIG_SYSLINK_IPU_SELF_HIBERNATION
198
 
                .timer_hib_id = 3,
199
 
#else
200
 
                .timer_hib_id = -1,
201
 
#endif
202
 
        },
203
 
        {
204
 
                .name = "ducati-proc1",
205
 
                .ops = &omap4_ducati1_ops,
206
 
                .oh_name = "ipu_c1",
207
 
                .timer_clk_id = 9,
208
 
                .timer_hib_id = -1,
209
 
 
210
 
        },
211
 
};
212
 
 
213
 
static struct omap_device_pm_latency omap_rproc_latency[] = {
214
 
        {
215
 
                .deactivate_func = omap_device_idle_hwmods,
216
 
                .activate_func   = omap_device_enable_hwmods,
217
 
                .deactivate_lat = 1,
218
 
                .activate_lat = 1,
219
 
        },
220
 
};
221
 
 
222
 
struct omap_rproc_platform_data *omap4_get_rproc_data(void)
223
 
{
224
 
        return omap4_rproc_data;
225
 
}
226
 
 
227
 
 
228
 
#define NR_RPROC_DEVICES ARRAY_SIZE(omap4_rproc_data)
229
 
 
230
 
static struct omap_device *omap4_rproc_pdev[NR_RPROC_OMAP4_DEVICES];
231
 
 
232
 
static int __init omap4_rproc_init(void)
233
 
{
234
 
        struct omap_hwmod *oh;
235
 
        struct omap_device_pm_latency *ohl;
236
 
        char *oh_name, *pdev_name;
237
 
        int ohl_cnt = 0, i;
238
 
        int rproc_data_size;
239
 
        struct omap_rproc_platform_data *rproc_data;
240
 
 
241
 
        pdev_name = "omap-remoteproc";
242
 
        ohl = omap_rproc_latency;
243
 
        ohl_cnt = ARRAY_SIZE(omap_rproc_latency);
244
 
 
245
 
 
246
 
        rproc_data = omap4_get_rproc_data();
247
 
        rproc_data_size = NR_RPROC_OMAP4_DEVICES;
248
 
 
249
 
        for (i = 0; i < rproc_data_size; i++) {
250
 
                oh_name = rproc_data[i].oh_name;
251
 
                oh = omap_hwmod_lookup(oh_name);
252
 
                if (!oh) {
253
 
                        pr_err("%s: could not look up %s\n", __func__, oh_name);
254
 
                        continue;
255
 
                }
256
 
                omap4_rproc_pdev[i] = omap_device_build(pdev_name, i, oh,
257
 
                                        &rproc_data[i],
258
 
                                        sizeof(struct omap_rproc_platform_data),
259
 
                                        ohl, ohl_cnt, false);
260
 
                WARN(IS_ERR(omap4_rproc_pdev[i]), "Could not build omap_device"
261
 
                                "for %s %s\n", pdev_name, oh_name);
262
 
        }
263
 
        return 0;
264
 
}
265
 
module_init(omap4_rproc_init);
266
 
 
267
 
static void __exit omap4_rproc_exit(void)
268
 
{
269
 
 
270
 
}
271
 
module_exit(omap4_rproc_exit);
272
 
 
273
 
MODULE_LICENSE("GPL v2");
274
 
MODULE_DESCRIPTION("OMAP4 Remote Processor module");
275
 
MODULE_AUTHOR("Ohad Ben-Cohen <ohad@wizery.com>");
276
 
MODULE_AUTHOR("Hari Kanigeri <h-kanigeri2@ti.com>");